Compare commits
1715 Commits
estimate-i
...
master
Author | SHA1 | Date |
---|---|---|
Stéphane Adjemian | 4f2b9b3e62 | |
Johannes Pfeifer | 5d47ac2aa9 | |
Sébastien Villemot | 1ce40d4df5 | |
Sébastien Villemot | 6820edd614 | |
Sébastien Villemot | 4a8c78f703 | |
Sébastien Villemot | 3000e6d691 | |
Johannes Pfeifer | 73d54cea04 | |
Willi Mutschler | 1b3c1c33ce | |
Sébastien Villemot | dd03d51112 | |
Johannes Pfeifer | 4a2724959d | |
Stéphane Adjemian (Argos) | 24fbc0d923 | |
Sébastien Villemot | fd76ce53af | |
Johannes Pfeifer | 6975aaef43 | |
Sébastien Villemot | ab7d741bf1 | |
Sébastien Villemot | 6f2af6943f | |
Sébastien Villemot | 0d9857e737 | |
Sébastien Villemot | adc42bb4cb | |
Sébastien Villemot | 641cf6a95c | |
Sébastien Villemot | a623cb1d12 | |
Sébastien Villemot | 28fc9e7c78 | |
Sébastien Villemot | d5cffba8fc | |
Sébastien Villemot | 3ebf824f3f | |
Sébastien Villemot | ec48980e1e | |
Sébastien Villemot | ebfd2aa0a1 | |
Sébastien Villemot | 433f00e224 | |
Sébastien Villemot | d61cb124ba | |
Sébastien Villemot | 05d82796c2 | |
Sébastien Villemot | cfa978b39e | |
Sébastien Villemot | 99883d4ca6 | |
Sébastien Villemot | 3053f9b7df | |
Sébastien Villemot | c125d35347 | |
Johannes Pfeifer | a40b0c146d | |
Johannes Pfeifer | 8e91841a39 | |
Stéphane Adjemian (Argos) | f5a5ebb910 | |
Sébastien Villemot | 6145bf9b31 | |
Stéphane Adjemian (Argos) | 415a86d1d9 | |
Stéphane Adjemian (Argos) | 8eab48aa5e | |
Stéphane Adjemian (Argos) | 9f9f4a99ba | |
Stéphane Adjemian (Argos) | a48a03bc67 | |
Stéphane Adjemian (Argos) | 942d8846e4 | |
Johannes Pfeifer | 2ed416532b | |
Sébastien Villemot | 60e3b6a19f | |
Sébastien Villemot | 505084f20b | |
Sébastien Villemot | b956a2253e | |
Sébastien Villemot | 00bba09986 | |
Sébastien Villemot | 6a0ee900a4 | |
Sébastien Villemot | 8954a682c7 | |
Sébastien Villemot | 13c9acba57 | |
Sébastien Villemot | aee581fd0b | |
Sébastien Villemot | 855e44cb17 | |
Sébastien Villemot | 881f5f2e62 | |
Johannes Pfeifer | b1cb309a73 | |
Sébastien Villemot | 330542a79f | |
Sébastien Villemot | b2f603091a | |
Sébastien Villemot | 88236b1cc0 | |
Sébastien Villemot | c14d410699 | |
Johannes Pfeifer | 619de017d6 | |
Sébastien Villemot | 85c637d3d1 | |
Sébastien Villemot | 6fe43545d8 | |
Sébastien Villemot | 6b6b648255 | |
Sébastien Villemot | aa76e06099 | |
Sébastien Villemot | e68be9ec55 | |
Sébastien Villemot | 2c6df2b668 | |
Sébastien Villemot | c6c179d8dd | |
Sébastien Villemot | aceebe9769 | |
Johannes Pfeifer | 28df34df06 | |
Johannes Pfeifer | d7242c056d | |
Johannes Pfeifer | 6ba9cb06e7 | |
Johannes Pfeifer | bcd57142c6 | |
Sébastien Villemot | 6868e2f27e | |
Johannes Pfeifer | 248d8ae84f | |
Sébastien Villemot | 6780b9a009 | |
Sébastien Villemot | 6235de3a82 | |
Sébastien Villemot | e1833c475d | |
Johannes Pfeifer | e5951650d9 | |
Johannes Pfeifer | 1b181fca57 | |
Johannes Pfeifer | 45e8ab14dc | |
Johannes Pfeifer | 6bb973a0fa | |
Johannes Pfeifer | 23225aca1b | |
Sébastien Villemot | 2d90ef9890 | |
Sébastien Villemot | 5d169d658e | |
Sébastien Villemot | 4683b9aeb6 | |
Sébastien Villemot | cb7bd0778b | |
Sébastien Villemot | 2fd4a6fac4 | |
Sébastien Villemot | 2bfa311636 | |
Sébastien Villemot | 3ab9be71c8 | |
Johannes Pfeifer | 0187ebe0a2 | |
Johannes Pfeifer | 6ff924550c | |
Sébastien Villemot | 346ee01107 | |
Sébastien Villemot | cc02690acf | |
Sébastien Villemot | ffb578276e | |
Johannes Pfeifer | 4a7851b069 | |
Johannes Pfeifer | 46d7e155d9 | |
Sébastien Villemot | f9cd465fea | |
Sébastien Villemot | 53d8278d8a | |
Sébastien Villemot | 049006a1bf | |
Sébastien Villemot | e7cd6eb408 | |
Sébastien Villemot | 0679da4cba | |
Sébastien Villemot | a99beac083 | |
Sébastien Villemot | 44044904c1 | |
Sébastien Villemot | b89e79862a | |
Sébastien Villemot | 3249d74220 | |
Sébastien Villemot | 8a7440c6ac | |
Johannes Pfeifer | 90266c0bfc | |
Johannes Pfeifer | 02d1e8d3ed | |
Johannes Pfeifer | a6ad26788e | |
Johannes Pfeifer | 8f07f37138 | |
Johannes Pfeifer | e9d79796cf | |
Johannes Pfeifer | b7e9d69874 | |
Sébastien Villemot | 7bf0395a27 | |
Willi Mutschler | ee2545f84d | |
Sébastien Villemot | dd1669082e | |
Johannes Pfeifer | 9c28f5feaf | |
Sébastien Villemot | 31ce155852 | |
Sébastien Villemot | c36b695cd9 | |
Sébastien Villemot | 6cad684980 | |
Marco Ratto | a4e6531420 | |
Sébastien Villemot | d09a206c7c | |
Marco Ratto | fbf62255c6 | |
Marco Ratto | e918589e02 | |
Sébastien Villemot | 368c93214e | |
Johannes Pfeifer | 8deeaa7252 | |
Johannes Pfeifer | e3e6f4c9b4 | |
Sébastien Villemot | 5216cec249 | |
Sébastien Villemot | cae5a00e80 | |
Sébastien Villemot | 42e2f77e4a | |
Sébastien Villemot | 7a5684bf4b | |
Willi Mutschler | c4bf6d079f | |
Willi Mutschler | c46eef685d | |
Willi Mutschler | 2f07fa2921 | |
Willi Mutschler | f14bbc73b1 | |
Willi Mutschler | 329f0d2d54 | |
Willi Mutschler | 68b92a1ab9 | |
Willi Mutschler | 8987576ff5 | |
Willi Mutschler | 9148b5b210 | |
Willi Mutschler | 0b839467e6 | |
Willi Mutschler | 547bdcc99b | |
Willi Mutschler | 0787589479 | |
Willi Mutschler | 37efafe475 | |
Willi Mutschler | 7f60674dae | |
Willi Mutschler | bd3ca58727 | |
Willi Mutschler | 65f8b56fb0 | |
Willi Mutschler | 2521314c39 | |
Willi Mutschler | 378e38c8c2 | |
Willi Mutschler | c59daa6139 | |
Willi Mutschler | 937ee0ef77 | |
Willi Mutschler | 8515a195ab | |
Willi Mutschler | 8a29933c6e | |
Willi Mutschler | f210ffa3ae | |
Willi Mutschler | 20ec0a6c97 | |
Willi Mutschler | e9871d7d47 | |
Willi Mutschler | 459842e4f6 | |
Willi Mutschler | 2d8bcd6918 | |
Willi Mutschler | c45c0efeba | |
Willi Mutschler | 613b3869e1 | |
Willi Mutschler | 95bfb84014 | |
Willi Mutschler | 37c7ca2d97 | |
Willi Mutschler | dedbb3be57 | |
Sébastien Villemot | d7850a2bbe | |
Willi Mutschler | b435aa7f27 | |
Willi Mutschler | f8a6020d2b | |
Willi Mutschler | 5f1ae3bb19 | |
Sébastien Villemot | bc69f6a102 | |
Sébastien Villemot | 8b9d1d1346 | |
Sébastien Villemot | 38d1c0538a | |
Johannes Pfeifer | 774cb18aac | |
Johannes Pfeifer | b215eedb4b | |
Sébastien Villemot | fb18777e58 | |
Sébastien Villemot | 311808db0a | |
Sébastien Villemot | 52b92ce64d | |
Johannes Pfeifer | ba52789020 | |
Johannes Pfeifer | c52c21ca24 | |
Sébastien Villemot | e649fa5494 | |
Sébastien Villemot | 346d2acbdf | |
Johannes Pfeifer | 278e767ea1 | |
Johannes Pfeifer | 90ced5ca47 | |
Sébastien Villemot | c9db9809d0 | |
Sébastien Villemot | 70b9d9277a | |
Johannes Pfeifer | 78abd68c9f | |
Johannes Pfeifer | 4512e85cb2 | |
Johannes Pfeifer | d7ae0d0039 | |
Marco Ratto | ac346ef83d | |
Marco Ratto | 9b165d7785 | |
Johannes Pfeifer | 7b94310fd4 | |
Marco Ratto | 8348cf009a | |
Marco Ratto | 75f5a463df | |
Marco Ratto | e8d82ad840 | |
Johannes Pfeifer | ab6ea60967 | |
Marco Ratto | 90fbb9559e | |
Marco Ratto | 3f1a37614f | |
Marco Ratto | ee5faf0783 | |
Marco Ratto | cf7be44257 | |
Sébastien Villemot | c363355dbf | |
Sébastien Villemot | d50330aad3 | |
Sébastien Villemot | 380e78be53 | |
Sébastien Villemot | 84a7b4b2cf | |
Johannes Pfeifer | 48380a1370 | |
Johannes Pfeifer | 3faaffacc6 | |
Sébastien Villemot | e9ffb16ec6 | |
Stéphane Adjemian (Ryûk) | 4982ce06b4 | |
Johannes Pfeifer | 37e4d68264 | |
Johannes Pfeifer | 4d6d4953e7 | |
Stéphane Adjemian (Ryûk) | c399f54581 | |
Stéphane Adjemian (Ryûk) | 735bd66d4d | |
Stéphane Adjemian (Ryûk) | 7468a903b7 | |
Stéphane Adjemian (Ryûk) | c841f1474c | |
Stéphane Adjemian (Ryûk) | b6619b342b | |
Stéphane Adjemian (Ryûk) | fef466ef34 | |
Stéphane Adjemian (Ryûk) | 52be9d08c1 | |
Stéphane Adjemian (Ryûk) | 5d8861ff29 | |
Stéphane Adjemian (Ryûk) | 743de7da5c | |
Stéphane Adjemian (Ryûk) | e962cb4dba | |
Stéphane Adjemian (Ryûk) | cf4c6cdf14 | |
Stéphane Adjemian (Guts) | 7915b91fdb | |
Johannes Pfeifer | 72a8d53df8 | |
Stéphane Adjemian (Guts) | 23af7f64b6 | |
Stéphane Adjemian (Guts) | 0249ea2116 | |
Stéphane Adjemian (Guts) | 44119077db | |
Stéphane Adjemian (Guts) | 47af0cde16 | |
Sébastien Villemot | eb043406e6 | |
Sébastien Villemot | ae082cffbe | |
Sébastien Villemot | febd39713e | |
Sébastien Villemot | 20b2c79ffb | |
Sébastien Villemot | 458926b17b | |
Sébastien Villemot | 162ca815bc | |
Sébastien Villemot | ff7cc9267e | |
Sébastien Villemot | 56e97e29aa | |
Sébastien Villemot | adddcf6197 | |
Sébastien Villemot | 79959aa587 | |
Sébastien Villemot | a0bafbcb95 | |
Sébastien Villemot | 2005f292e5 | |
Stéphane Adjemian (Guts) | 4a6783c690 | |
Johannes Pfeifer | 3e7291b573 | |
Sébastien Villemot | 9225e6b6df | |
Sébastien Villemot | d8f1e49221 | |
Sébastien Villemot | 1239842909 | |
Marco Ratto | 281f01f29e | |
Johannes Pfeifer | 8710ce0898 | |
Johannes Pfeifer | 74ac072549 | |
Marco Ratto | 8ddd35ddd8 | |
Marco Ratto | 3ee963c908 | |
Johannes Pfeifer | d25d95b3b5 | |
Marco Ratto | 2898407764 | |
Marco Ratto | 3931451250 | |
Marco Ratto | e1e79d3177 | |
Sébastien Villemot | d94e5bd7b9 | |
Sébastien Villemot | 66bc9fd9c2 | |
Sébastien Villemot | 19dcd4a0f2 | |
Johannes Pfeifer | f05a2de89e | |
Johannes Pfeifer | c3268c0279 | |
Johannes Pfeifer | 2e73856f5a | |
Sébastien Villemot | 565667c6b7 | |
Johannes Pfeifer | 75cd1042c8 | |
Sébastien Villemot | fd0d93ba13 | |
Sébastien Villemot | 668f6de5df | |
Johannes Pfeifer | 0c07460f3b | |
Johannes Pfeifer | dbcc0aeb9f | |
Stéphane Adjemian (Guts) | 1983dc13a3 | |
Johannes Pfeifer | 162813225d | |
Johannes Pfeifer | 1b2e1d2856 | |
Sébastien Villemot | 81cd0f1cb5 | |
Sébastien Villemot | 441ef7e102 | |
Johannes Pfeifer | 2df08f88c7 | |
Marco Ratto | f102a992aa | |
Marco Ratto | 53b57da8ba | |
Marco Ratto | aad5c36081 | |
Marco Ratto | de152a3de3 | |
Marco Ratto | 8f73564634 | |
Marco Ratto | 0c4b59b19e | |
Marco Ratto | 9b71845b87 | |
Marco Ratto | 91a2cd2496 | |
Sébastien Villemot | 858b534c22 | |
Johannes Pfeifer | e17bf15042 | |
Sébastien Villemot | ea28fcb4b4 | |
Sébastien Villemot | a7f5fd571d | |
Sébastien Villemot | 05cb10f8f7 | |
Sébastien Villemot | 594facdb03 | |
Sébastien Villemot | 7ba1fc1c63 | |
Sébastien Villemot | 63d5569cf4 | |
Sébastien Villemot | 00434c595d | |
Stéphane Adjemian (Ryûk) | 60c0ed0180 | |
Johannes Pfeifer | 42fc1ec40a | |
Johannes Pfeifer | 1b4fb46c75 | |
Stéphane Adjemian (Ryûk) | 2fbbe66c0a | |
Stéphane Adjemian (Ryûk) | 61498e644a | |
Stéphane Adjemian (Ryûk) | 3606b10f05 | |
Stéphane Adjemian (Ryûk) | 5077969aad | |
Stéphane Adjemian (Ryûk) | 3d50844ae4 | |
Stéphane Adjemian (Ryûk) | 3c3353b7ed | |
Stéphane Adjemian (Ryûk) | 03a68ddb89 | |
Sébastien Villemot | b1aa88e8da | |
Sébastien Villemot | d3aac5e2d7 | |
Sébastien Villemot | 62b31aa279 | |
Sébastien Villemot | 9d6a25e368 | |
Sébastien Villemot | 43b24facb9 | |
Sébastien Villemot | cc15281b1f | |
Sébastien Villemot | c99230825f | |
Sébastien Villemot | b7805cc667 | |
Johannes Pfeifer | ec76bda254 | |
Johannes Pfeifer | 021b9dbb25 | |
Johannes Pfeifer | daecd1f720 | |
Johannes Pfeifer | 5a3d545db2 | |
Johannes Pfeifer | ed80c4ff3f | |
Johannes Pfeifer | 678bd7aca9 | |
Johannes Pfeifer | 97f6a4219b | |
Johannes Pfeifer | 31c91080e1 | |
Johannes Pfeifer | 62e8b275a0 | |
Johannes Pfeifer | 435b103cf5 | |
Sébastien Villemot | d844043877 | |
Sébastien Villemot | a31c76403d | |
Sébastien Villemot | 4ef9245a95 | |
Sébastien Villemot | 91c677ca7f | |
Sébastien Villemot | 56289c72d0 | |
Sébastien Villemot | 1f5f668313 | |
Johannes Pfeifer | 54c4e9df09 | |
Stéphane Adjemian (Guts) | 8d8176fc30 | |
Sébastien Villemot | 40ef192e37 | |
Johannes Pfeifer | 1e5a04c2c5 | |
Johannes Pfeifer | f3a1ba56e3 | |
Johannes Pfeifer | af53c65172 | |
Johannes Pfeifer | c3b9c499ba | |
Johannes Pfeifer | 7f027d8f5e | |
Johannes Pfeifer | 9efb784763 | |
Johannes Pfeifer | 19b2619d06 | |
Johannes Pfeifer | 5d07ff9f8b | |
Johannes Pfeifer | fca782f8e4 | |
Johannes Pfeifer | 43fc6263af | |
Johannes Pfeifer | 37ab539a10 | |
Johannes Pfeifer | 6adf1c2639 | |
Johannes Pfeifer | 709ef9230f | |
Johannes Pfeifer | 0ba91259d8 | |
Johannes Pfeifer | dce0967deb | |
Johannes Pfeifer | 392721097c | |
Johannes Pfeifer | e68793030c | |
Johannes Pfeifer | bf6d88a472 | |
Sébastien Villemot | 6a58316a3e | |
Sébastien Villemot | 91f2dcdfe1 | |
Sébastien Villemot | de476ad5ac | |
Sébastien Villemot | 123f909b67 | |
Sébastien Villemot | fd9a89ab38 | |
Sébastien Villemot | 15b6e6e6b3 | |
Sébastien Villemot | 9d98811cfc | |
Sébastien Villemot | 8953007440 | |
Sébastien Villemot | d82eecfd39 | |
Sébastien Villemot | 3df4856259 | |
Sébastien Villemot | 11c1f6175e | |
Sébastien Villemot | 7864370bfb | |
Sébastien Villemot | 911437378c | |
Sébastien Villemot | 6f38dcd1d5 | |
Sébastien Villemot | bc6840ff6f | |
Sébastien Villemot | aeec4494b0 | |
Sébastien Villemot | 857e5b00f5 | |
Sébastien Villemot | bd7703d160 | |
Sébastien Villemot | a5445c52be | |
Sébastien Villemot | 403f20a7f3 | |
Johannes Pfeifer | 53f12e81fa | |
Sébastien Villemot | bea87aafad | |
Johannes Pfeifer | 526e6841b1 | |
Johannes Pfeifer | c21199a3e9 | |
Johannes Pfeifer | 36a4ad0fbc | |
Johannes Pfeifer | f218127220 | |
Stéphane Adjemian (Ryûk) | edaf938582 | |
Stéphane Adjemian (Ryûk) | dadcd9a2bf | |
Sébastien Villemot | c6a7801ba8 | |
Sébastien Villemot | 7edf01a2a9 | |
Sébastien Villemot | cb56dcc569 | |
Sébastien Villemot | f0420fa219 | |
Sébastien Villemot | ed332e3ba1 | |
Sébastien Villemot | ca16f7f848 | |
Sébastien Villemot | 847f940f78 | |
Johannes Pfeifer | d5f7fbe96a | |
Johannes Pfeifer | d29228bb5f | |
Johannes Pfeifer | 152991864d | |
Johannes Pfeifer | f8a0a99683 | |
Johannes Pfeifer | 5060f246ea | |
Johannes Pfeifer | 4199f57788 | |
Johannes Pfeifer | 94c1343671 | |
Johannes Pfeifer | a80ead7d94 | |
Johannes Pfeifer | da438d5099 | |
Johannes Pfeifer | ffaf6c8559 | |
Sébastien Villemot | 54e72a4d35 | |
Sébastien Villemot | c3d91d5ce8 | |
Sébastien Villemot | c6c6f4f549 | |
Sébastien Villemot | b0197da05f | |
Sébastien Villemot | ccff7d3560 | |
Johannes Pfeifer | e718402357 | |
Johannes Pfeifer | 59c9f70a7d | |
Sébastien Villemot | 6ccc7fd69e | |
Sébastien Villemot | b220be6d3e | |
Sébastien Villemot | f21fda7dfa | |
Sébastien Villemot | c0e39d40a7 | |
Johannes Pfeifer | d0e99daf9a | |
Sébastien Villemot | f62d76cbcf | |
Sébastien Villemot | 56410be973 | |
Johannes Pfeifer | 07d859d018 | |
Sébastien Villemot | b513214570 | |
Sébastien Villemot | 9545dcc8d9 | |
Sébastien Villemot | 08c9eca8ee | |
Sébastien Villemot | 701afd2c7c | |
Sébastien Villemot | 1d5a442fe5 | |
Sébastien Villemot | d55b6c68f9 | |
Sébastien Villemot | 72ac69eb97 | |
Sébastien Villemot | ec7a4ba84f | |
Sébastien Villemot | 3bfe2c5500 | |
Sébastien Villemot | 7f58e819c6 | |
Sébastien Villemot | 0efe0c9844 | |
Sébastien Villemot | dd5049cd4c | |
Sébastien Villemot | 627bbb0a91 | |
Johannes Pfeifer | eb8444889a | |
Johannes Pfeifer | 37f747bb3b | |
Sébastien Villemot | e15fba807f | |
Sébastien Villemot | d8ebdf916c | |
Sébastien Villemot | 56ed5bff43 | |
Sébastien Villemot | 742a3101b1 | |
Sébastien Villemot | 50a53a22ee | |
Sébastien Villemot | 8a54d10389 | |
Johannes Pfeifer | b053b96f6a | |
Johannes Pfeifer | 0e08dd287b | |
Sébastien Villemot | 551060ae27 | |
Johannes Pfeifer | e27ab153d7 | |
Sébastien Villemot | 4b4cfba2dc | |
Sébastien Villemot | 0e5f9defbc | |
Sébastien Villemot | b535763e56 | |
Johannes Pfeifer | 50ed6b2387 | |
Sébastien Villemot | e1d4c81531 | |
Johannes Pfeifer | b1519b8c3c | |
Normann Rion | a900f74cf3 | |
Sébastien Villemot | eb591b1299 | |
Sébastien Villemot | 6599800f88 | |
Stéphane Adjemian (Argos) | 666aa46dfb | |
Stéphane Adjemian (Argos) | b863c309bd | |
Stéphane Adjemian (Argos) | 9c61422a75 | |
Normann Rion | 3a461c996c | |
Sébastien Villemot | 0c83453a0c | |
Sébastien Villemot | 0e201b2928 | |
Sébastien Villemot | 77a7d5c3de | |
Sébastien Villemot | be648d350b | |
Sébastien Villemot | 0839ff78ae | |
Sébastien Villemot | 4bee919c31 | |
Sébastien Villemot | 158b7462bf | |
Sébastien Villemot | b36507d005 | |
Sébastien Villemot | 8556043c9a | |
Sébastien Villemot | 7dc90654ab | |
Sébastien Villemot | 93ab67acab | |
Sébastien Villemot | 7e512af074 | |
Stéphane Adjemian (Argos) | 368a7e2478 | |
Sébastien Villemot | 79a655261b | |
Sébastien Villemot | fd0e175fe4 | |
Sébastien Villemot | f6adb1d9ad | |
Sébastien Villemot | 25000ca693 | |
Stéphane Adjemian (Argos) | 33f2456acf | |
Johannes Pfeifer | 5103d55cb4 | |
Stéphane Adjemian (Argos) | 12cca117bc | |
Stéphane Adjemian (Argos) | b0a84bd6f8 | |
Stéphane Adjemian (Argos) | 76a2203b50 | |
Stéphane Adjemian (Argos) | cdd842cc19 | |
Sébastien Villemot | b1b76f7783 | |
Sébastien Villemot | 4701dfd158 | |
Johannes Pfeifer | 0561200f1c | |
Sébastien Villemot | aca148e8ef | |
Sébastien Villemot | ff2b8512b9 | |
Sébastien Villemot | 0295e5ede8 | |
Sébastien Villemot | 218a1f2d58 | |
Johannes Pfeifer | b3ce518433 | |
Johannes Pfeifer | c19469f01a | |
Johannes Pfeifer | 879d92fbf8 | |
Sébastien Villemot | 04ea0d0659 | |
Sébastien Villemot | caaa70ab7e | |
Sébastien Villemot | 17b016d983 | |
Johannes Pfeifer | a5383fdf65 | |
Sébastien Villemot | af20512476 | |
Sébastien Villemot | 88ce107466 | |
Sébastien Villemot | 1334ae045a | |
Sébastien Villemot | f40e7cfc68 | |
Sébastien Villemot | e3b346094b | |
Sébastien Villemot | 896c48eba7 | |
Sébastien Villemot | c475109648 | |
Sébastien Villemot | ff5ca80bbc | |
Stéphane Adjemian (Argos) | d95154ffa9 | |
Sébastien Villemot | 8c3429bb0f | |
Sébastien Villemot | df9c7d85b8 | |
Sébastien Villemot | 7449d26e51 | |
Sébastien Villemot | 6027d31da2 | |
Sébastien Villemot | b17ff164fc | |
Sébastien Villemot | 753848ab4b | |
Sébastien Villemot | 12a0781bc4 | |
Sébastien Villemot | 8573c6d06a | |
Sébastien Villemot | 8305afc6b3 | |
Sébastien Villemot | ed45b2092f | |
Sébastien Villemot | 9964de1c5f | |
Sébastien Villemot | 1492073669 | |
Sébastien Villemot | 9b9c87e09f | |
Sébastien Villemot | 4d13d73c58 | |
Sébastien Villemot | 401fbd25a6 | |
Sébastien Villemot | 853b195432 | |
Sébastien Villemot | 2617f5a4be | |
Sébastien Villemot | c132817780 | |
Sébastien Villemot | 6c3325cc5e | |
Sébastien Villemot | d5618a61d9 | |
Sébastien Villemot | f47507395d | |
Johannes Pfeifer | 643face6ed | |
Johannes Pfeifer | fb8ff758f9 | |
Sébastien Villemot | 9eaf1510f6 | |
Sébastien Villemot | 093a547684 | |
Sébastien Villemot | 0bfcc6d2f5 | |
Sébastien Villemot | 860285b8b8 | |
Sébastien Villemot | 233d0815a6 | |
Sébastien Villemot | dc6a84196a | |
Sébastien Villemot | 88a0f67585 | |
Sébastien Villemot | 24fc3854e2 | |
Sébastien Villemot | 115a0a8e5d | |
Sébastien Villemot | e5bf3f79b3 | |
Sébastien Villemot | 197347c870 | |
Sébastien Villemot | e104318e6b | |
Sébastien Villemot | 68cee02eb5 | |
Sébastien Villemot | fdb3cd0623 | |
Sébastien Villemot | 8e74322325 | |
Sébastien Villemot | af1985d569 | |
Sébastien Villemot | fd16bbe493 | |
Sébastien Villemot | 6809819961 | |
Sébastien Villemot | bbcbcd1eed | |
Sébastien Villemot | b747eff473 | |
Sébastien Villemot | a9c581e2bc | |
Sébastien Villemot | 846ed7e829 | |
Sébastien Villemot | 654b4e57a2 | |
Sébastien Villemot | 06ac452459 | |
Sébastien Villemot | ed4824f956 | |
Sébastien Villemot | 9ef3f7d0ed | |
Willi Mutschler | da4bc40e66 | |
Sébastien Villemot | 5145bd0708 | |
Sébastien Villemot | d78dea3086 | |
Sébastien Villemot | daa6b5569d | |
Sébastien Villemot | 357076feb4 | |
Willi Mutschler | e03d6f3c1f | |
Sébastien Villemot | 39f9d4352a | |
Sébastien Villemot | 66ccb3b3d3 | |
Sébastien Villemot | 113cfb9c47 | |
Sébastien Villemot | 9a0462a8a6 | |
Sébastien Villemot | 06a7acf19b | |
Sébastien Villemot | 651fed87be | |
Sébastien Villemot | b0fa610357 | |
Willi Mutschler | fb63a8eadb | |
Sébastien Villemot | eae9902cb8 | |
Sébastien Villemot | 3e5591d41f | |
Sébastien Villemot | 4875554a39 | |
Sébastien Villemot | 2ae485705e | |
Sébastien Villemot | 4f74ceb937 | |
Sébastien Villemot | cc7c024389 | |
Sébastien Villemot | 9ebd8a8372 | |
Sébastien Villemot | e26f3f5d06 | |
Sébastien Villemot | a6eb943aae | |
Sébastien Villemot | cd17a2dd6d | |
Sébastien Villemot | 20e1540892 | |
Sébastien Villemot | e4a4d2d8e6 | |
Sébastien Villemot | b59dc2cf1a | |
Sébastien Villemot | 88146bcc6f | |
Sébastien Villemot | a241aa2bd7 | |
Sébastien Villemot | f94e7ae9a6 | |
Sébastien Villemot | b4e2a0be48 | |
Stéphane Adjemian (Ryûk) | 2c923c613b | |
Willi Mutschler | 16be379493 | |
Willi Mutschler | 987c6f2e00 | |
Willi Mutschler | a3b05f6d74 | |
Willi Mutschler | 6d2958625d | |
Willi Mutschler | 3d057a6605 | |
Willi Mutschler | 5213adc0ad | |
Willi Mutschler | cb0ece6d82 | |
Willi Mutschler | d5649a53fa | |
Willi Mutschler | bb3aa0a206 | |
Willi Mutschler | cc9102248c | |
Willi Mutschler | 6e98e9849f | |
Willi Mutschler | cdd632ed07 | |
Willi Mutschler | 01c1df6c93 | |
Willi Mutschler | 81b2fe4c88 | |
Willi Mutschler | 158abbd0fd | |
Willi Mutschler | 83910ddae3 | |
Willi Mutschler | d480bbdcac | |
Willi Mutschler | de5b37fca7 | |
Sébastien Villemot | 9d95dadb13 | |
Sébastien Villemot | c1a46fed91 | |
Stéphane Adjemian (Argos) | 06926e0153 | |
Sébastien Villemot | cfb8a1d15a | |
Sébastien Villemot | cf9ea686ef | |
Johannes Pfeifer | a00eb5e1de | |
Johannes Pfeifer | cbf57b1af6 | |
Johannes Pfeifer | 328f6f3229 | |
Johannes Pfeifer | 36a2a41e35 | |
Johannes Pfeifer | 6f8fc22d57 | |
Johannes Pfeifer | 0e468103d9 | |
Johannes Pfeifer | 7f5d8b81c2 | |
Johannes Pfeifer | f0b10ca9df | |
Johannes Pfeifer | d5f8d3fffe | |
Johannes Pfeifer | 94207ab851 | |
Johannes Pfeifer | a67cd58d1f | |
Johannes Pfeifer | 5a3ae27b13 | |
Johannes Pfeifer | 2eb9475e0e | |
Willi Mutschler | 0a3f4220df | |
Sébastien Villemot | 8cc646fbf6 | |
Sébastien Villemot | 03433112a4 | |
Sébastien Villemot | dcdbd85b10 | |
Sébastien Villemot | 9525dbe3a8 | |
Sébastien Villemot | c329b4ff11 | |
Sébastien Villemot | d584317a6a | |
Sébastien Villemot | 5e7b7ec7b0 | |
Sébastien Villemot | e5b7ddbb33 | |
Sébastien Villemot | 2e3fbfc040 | |
Sébastien Villemot | 6b44e08daa | |
Sébastien Villemot | 7f6f66c1c9 | |
Sébastien Villemot | 82ea15e5e7 | |
Sébastien Villemot | 727f925f01 | |
Sébastien Villemot | d4b6e61497 | |
Sébastien Villemot | c3680b9f85 | |
Sébastien Villemot | 4dea001d8d | |
Sébastien Villemot | 068070d336 | |
Sébastien Villemot | 375f65c213 | |
Johannes Pfeifer | 32d5bc05a1 | |
Sébastien Villemot | d77561e241 | |
Sébastien Villemot | e4afa5eee0 | |
Sébastien Villemot | da9789038d | |
Johannes Pfeifer | 7ff7561280 | |
Johannes Pfeifer | 3a115d4fcc | |
Johannes Pfeifer | 268a668f32 | |
Johannes Pfeifer | ab61f79c9e | |
Johannes Pfeifer | f34653b0f7 | |
Johannes Pfeifer | fa29689b13 | |
Johannes Pfeifer | acb9518dec | |
Johannes Pfeifer | 7da5ff4fad | |
Johannes Pfeifer | c5ab1c7f11 | |
Johannes Pfeifer | 776c247b9b | |
Johannes Pfeifer | e65662151f | |
Sébastien Villemot | f2abdb6ec8 | |
Sébastien Villemot | 285c1ef244 | |
Sébastien Villemot | 0e5bba7567 | |
Sébastien Villemot | 2600a878da | |
Stéphane Adjemian (Argos) | 85e9ec7fdc | |
Stéphane Adjemian (Ryûk) | de626fb4e8 | |
Sébastien Villemot | b4a34f8ebc | |
Sébastien Villemot | ceff825ed4 | |
Sébastien Villemot | befe645728 | |
Sébastien Villemot | 432fd2d1b1 | |
Sébastien Villemot | 2993c79a85 | |
Sébastien Villemot | 50319b7620 | |
Willi Mutschler | e6aff20142 | |
Sébastien Villemot | b65f641b72 | |
Willi Mutschler | 2c2d93f36b | |
Sébastien Villemot | 64f47723bf | |
Sébastien Villemot | 01833b8a76 | |
Sébastien Villemot | 82a2aeaae4 | |
Sébastien Villemot | c4a5c36c52 | |
Johannes Pfeifer | 9b86dd4c33 | |
Johannes Pfeifer | 13bf261088 | |
Johannes Pfeifer | 710a5fba52 | |
Johannes Pfeifer | 6d8927775b | |
Johannes Pfeifer | bf7ac27fd7 | |
Johannes Pfeifer | dc9560e610 | |
Johannes Pfeifer | b4104584a2 | |
Johannes Pfeifer | 71b63c6e8e | |
Johannes Pfeifer | 8da98057b9 | |
Sébastien Villemot | 7557dfb70d | |
Johannes Pfeifer | 4fa5df0c24 | |
Johannes Pfeifer | 22c0f2279f | |
Johannes Pfeifer | 01f29784d7 | |
Johannes Pfeifer | b5880e0e56 | |
Johannes Pfeifer | 5231fc04c1 | |
Johannes Pfeifer | 782a2e8d69 | |
Stéphane Adjemian (Ryûk) | 6417520c09 | |
Stéphane Adjemian (Ryûk) | 8d7a5e69d7 | |
Sébastien Villemot | bdb385d17c | |
Sébastien Villemot | 9a1f150e38 | |
Sébastien Villemot | b8412aba10 | |
Sébastien Villemot | b117e2a540 | |
Sébastien Villemot | bf9434f95f | |
Sébastien Villemot | 9f3f1b00c6 | |
Sébastien Villemot | 1e290daa44 | |
Sébastien Villemot | f4bcecc0d2 | |
Sébastien Villemot | 4f1e5e1bc2 | |
Sébastien Villemot | 4a68cfcbd6 | |
Sébastien Villemot | c424366440 | |
Sébastien Villemot | 5ae5102f89 | |
Sébastien Villemot | 7eb1959f66 | |
Sébastien Villemot | 491c8785a9 | |
Sébastien Villemot | d36b82e47c | |
Sébastien Villemot | a54b29a384 | |
Sébastien Villemot | 605ed45811 | |
Sébastien Villemot | 70866c7b70 | |
Sébastien Villemot | f23dd8c981 | |
Sébastien Villemot | e0bc9f29a1 | |
Sébastien Villemot | 6dd55726e6 | |
Sébastien Villemot | 83e1b307d2 | |
Sébastien Villemot | 7984e08f99 | |
Sébastien Villemot | 3845f965ba | |
Sébastien Villemot | 834b04bcb4 | |
Sébastien Villemot | e549bbba7a | |
Johannes Pfeifer | 1f723ebd7e | |
Johannes Pfeifer | 552e6575cc | |
Sébastien Villemot | 01ae836a99 | |
Sébastien Villemot | ba0fef9879 | |
Sébastien Villemot | d731cb18e9 | |
Sébastien Villemot | 6f5e346bf6 | |
Sébastien Villemot | 7f2483ed38 | |
Sébastien Villemot | 14a71a6d98 | |
Sébastien Villemot | 44f307ce45 | |
Johannes Pfeifer | 87ce652088 | |
Johannes Pfeifer | f6a8473144 | |
Sébastien Villemot | c2897c8f14 | |
Sébastien Villemot | a252daee51 | |
Johannes Pfeifer | 8032aa6e7e | |
Sébastien Villemot | bb55e9ec2f | |
Willi Mutschler | 330b10ec85 | |
Willi Mutschler | 649f668dd1 | |
Willi Mutschler | 66e7233018 | |
Willi Mutschler | c8be1a3274 | |
Willi Mutschler | a41fbdefbc | |
Willi Mutschler | 9a4e022eb7 | |
Willi Mutschler | 268d511e29 | |
Willi Mutschler | 80ce86baf8 | |
Willi Mutschler | 8f650a9cca | |
Johannes Pfeifer | 7df3ff5059 | |
Johannes Pfeifer | b0358b9939 | |
Johannes Pfeifer | 62c3a14026 | |
Johannes Pfeifer | dafe3fbdb2 | |
Johannes Pfeifer | 757b6e10ec | |
Johannes Pfeifer | 624eabe2e8 | |
Johannes Pfeifer | 68ff5c4110 | |
Sébastien Villemot | e335fed27b | |
Sébastien Villemot | d573ff1507 | |
Sébastien Villemot | 049609cbbb | |
Sébastien Villemot | db677f1bab | |
Sébastien Villemot | 7072776a60 | |
Sébastien Villemot | 63333fe041 | |
Sébastien Villemot | d57ff73763 | |
Sébastien Villemot | 3e0999a0fb | |
Sébastien Villemot | 8c5d6f5eae | |
Sébastien Villemot | 9e7e069aa8 | |
Sébastien Villemot | 8a79899189 | |
Sébastien Villemot | 755138fb84 | |
Johannes Pfeifer | ff83c4aea7 | |
Sébastien Villemot | db331c53d4 | |
Sébastien Villemot | bea2d7905b | |
Johannes Pfeifer | 14634946dc | |
Johannes Pfeifer | 2b313b0308 | |
Sébastien Villemot | 126a1b74ea | |
Johannes Pfeifer | 838bb2f4b5 | |
Sébastien Villemot | e86b372464 | |
Sébastien Villemot | a375cb5575 | |
Sébastien Villemot | 43af789eda | |
Sébastien Villemot | eb16bb4373 | |
Johannes Pfeifer | 885fda0e20 | |
Sébastien Villemot | 46a34aaa6c | |
Sébastien Villemot | 53089ad6e5 | |
Johannes Pfeifer | 2473b57782 | |
Johannes Pfeifer | ac0ecde1d9 | |
Sébastien Villemot | 6af9b5f268 | |
Sébastien Villemot | e67ca64d4b | |
Johannes Pfeifer | b8a1b63572 | |
Johannes Pfeifer | 3895da48a1 | |
Johannes Pfeifer | 497c6bd1b1 | |
Sébastien Villemot | a57f81b3aa | |
Johannes Pfeifer | 8cc5ecf6ec | |
Sébastien Villemot | 6037b9f096 | |
Johannes Pfeifer | 2b240210d0 | |
Sébastien Villemot | a0ea6005e8 | |
Johannes Pfeifer | 4598dba40c | |
Sébastien Villemot | f26a469208 | |
Sébastien Villemot | 890c6b2e1d | |
Sébastien Villemot | 8d29d7b8d3 | |
Sébastien Villemot | 4a0b87fdaf | |
Sébastien Villemot | dee66e8351 | |
Johannes Pfeifer | 91dd4d9a83 | |
Johannes Pfeifer | 7eaa974484 | |
Johannes Pfeifer | baf8243fac | |
Johannes Pfeifer | 825763b18f | |
Sébastien Villemot | d601ca4a2e | |
Johannes Pfeifer | af274aec3f | |
Johannes Pfeifer | 3a851dd8f3 | |
Johannes Pfeifer | c72763501e | |
Johannes Pfeifer | 290f19c705 | |
Johannes Pfeifer | 74399f0728 | |
Johannes Pfeifer | 5ac11449ce | |
Johannes Pfeifer | bd905360e0 | |
Johannes Pfeifer | 842bf3d687 | |
Sébastien Villemot | cb0f0e6701 | |
Willi Mutschler | 2e742462b3 | |
Johannes Pfeifer | cd05bfb8a2 | |
Johannes Pfeifer | c43308a07b | |
Johannes Pfeifer | 2fa6c437f7 | |
Johannes Pfeifer | 420cbc8202 | |
Johannes Pfeifer | 4e58e22bdd | |
Johannes Pfeifer | c063d53646 | |
Johannes Pfeifer | f2f1c48baf | |
Johannes Pfeifer | 3dd1ffb8fe | |
Johannes Pfeifer | 41ac891f80 | |
Willi Mutschler | a0b443b9f8 | |
Willi Mutschler | 777ec76536 | |
Willi Mutschler | 55dc4a00d5 | |
Willi Mutschler | e025d56a59 | |
Willi Mutschler | 07b62fe554 | |
Willi Mutschler | 9dc4878f9f | |
Willi Mutschler | e52c007d8b | |
Willi Mutschler | fb326638f9 | |
Willi Mutschler | e170b64713 | |
Willi Mutschler | b737d46d61 | |
Willi Mutschler | 9914d764c2 | |
Willi Mutschler | c0cae0ebaa | |
Willi Mutschler | 0cd65df72a | |
Willi Mutschler | 017b4f05f6 | |
Willi Mutschler | 1ef026dc9d | |
Willi Mutschler | 180b92cb1e | |
Willi Mutschler | c3327e000c | |
Willi Mutschler | 0487dd4a77 | |
Willi Mutschler | f25188cf2f | |
Willi Mutschler | 3c0f3c1c24 | |
Willi Mutschler | 23f6019cdf | |
Willi Mutschler | 6941bd5516 | |
Willi Mutschler | c356db4531 | |
Willi Mutschler | aa99eff81d | |
Willi Mutschler | 7f22414843 | |
Willi Mutschler | 688d847489 | |
Willi Mutschler | c21f75887d | |
Willi Mutschler | dd2c816df0 | |
Willi Mutschler | d8105a3237 | |
Willi Mutschler | 960c075420 | |
Sébastien Villemot | 6551b88fc8 | |
Sébastien Villemot | 9e2b387d0a | |
Johannes Pfeifer | 8f79e848f0 | |
Johannes Pfeifer | 9afd75ca9b | |
Johannes Pfeifer | 7283838a0f | |
Johannes Pfeifer | 02b4242c75 | |
Johannes Pfeifer | 5f68504919 | |
Johannes Pfeifer | d60a19ce49 | |
Sébastien Villemot | 16f921ed62 | |
Sébastien Villemot | b0503ce994 | |
Sébastien Villemot | 6747f2130e | |
Sébastien Villemot | bd9943a695 | |
Sébastien Villemot | 9e5bd75611 | |
Sébastien Villemot | 7e92438601 | |
Johannes Pfeifer | c70f2f1e4b | |
Sébastien Villemot | 0d21927381 | |
Sébastien Villemot | 01011cb849 | |
Sébastien Villemot | 38f36258ed | |
Sébastien Villemot | 8888711266 | |
Sébastien Villemot | bda2b1a1e9 | |
Sébastien Villemot | 1bbfcf426e | |
Sébastien Villemot | 14bd989134 | |
Johannes Pfeifer | e70b2fdfcf | |
Johannes Pfeifer | 183e6fbb3b | |
Johannes Pfeifer | 9e53bd9967 | |
Stéphane Adjemian | 4024ad7e99 | |
Johannes Pfeifer | 0729ee72af | |
Johannes Pfeifer | a85a00bfcf | |
Sébastien Villemot | b4f260aa01 | |
Sébastien Villemot | b1db895dee | |
Sébastien Villemot | 0442fe785e | |
Sébastien Villemot | 33719e69f2 | |
Sébastien Villemot | 9ff1d8556c | |
Sébastien Villemot | 801b774bcd | |
Stéphane Adjemian (Argos) | 91825d4b5b | |
Sébastien Villemot | d9ff8dfeee | |
Normann Rion | 710589eb5b | |
Stéphane Adjemian (Ryûk) | c02e550582 | |
Sébastien Villemot | 5b8b63924d | |
Sébastien Villemot | 661e5c7e9f | |
Sébastien Villemot | d52aceeb16 | |
Johannes Pfeifer | d2fecdc5d3 | |
Sébastien Villemot | 4f4dc0e4f4 | |
Sébastien Villemot | 89376b188e | |
Johannes Pfeifer | 8532d6abd7 | |
Johannes Pfeifer | e6c43c2a29 | |
Stéphane Adjemian (Ryûk) | b5a74b96e5 | |
Sébastien Villemot | 7457c6d3db | |
Stéphane Adjemian (Ryûk) | 21dcc911bc | |
Willi Mutschler | b23c394972 | |
Willi Mutschler | d4a8d0fc50 | |
Stéphane Adjemian (Argos) | 6265a6d2b1 | |
Stéphane Adjemian (Argos) | bd0493d135 | |
Stéphane Adjemian (Argos) | 5e869669a0 | |
Sébastien Villemot | 175662a75e | |
Johannes Pfeifer | 9b2c0fb94d | |
Sébastien Villemot | ffdeccc05d | |
Sébastien Villemot | ae67b4a145 | |
William Gatt | eb5eefdcf0 | |
Sébastien Villemot | 3b9c515674 | |
Normann Rion | 23dbb2b4b9 | |
Sébastien Villemot | a044ec45b1 | |
Sébastien Villemot | 3bdbfef301 | |
Sébastien Villemot | 8b945dfd64 | |
Normann Rion | d2c324eeee | |
Johannes Pfeifer | d386bb9f76 | |
Johannes Pfeifer | ed7fe89bfa | |
Willi Mutschler | e6920a60a1 | |
Johannes Pfeifer | 050679cd56 | |
Sébastien Villemot | 20f04d3749 | |
Johannes Pfeifer | 782368eb9b | |
Sébastien Villemot | b88a779c82 | |
Johannes Pfeifer | ec55e6b7c6 | |
Sébastien Villemot | 01007e3776 | |
Sébastien Villemot | d5a3a8e16a | |
Sébastien Villemot | 3a789ca780 | |
Sébastien Villemot | ec336e9c95 | |
Sébastien Villemot | 39c2cba1b6 | |
Sébastien Villemot | a8de0f56f3 | |
Sébastien Villemot | 86ef9f2924 | |
Sébastien Villemot | 8fa37a0439 | |
Sébastien Villemot | d4b5e156d1 | |
Sébastien Villemot | 018f69b69b | |
Sébastien Villemot | 396267260a | |
Sébastien Villemot | c1b78e26ac | |
Sébastien Villemot | 30c17ad346 | |
Sébastien Villemot | c7b4ea40f8 | |
Sébastien Villemot | d6ea315a18 | |
Stéphane Adjemian (Ryûk) | a541e1e6d0 | |
Sébastien Villemot | 192f136b96 | |
Sébastien Villemot | 277c5d4c4f | |
Sébastien Villemot | 7c9e261355 | |
Sébastien Villemot | dcf56b89cd | |
Sébastien Villemot | 73b1850cb5 | |
Sébastien Villemot | d81e3992c3 | |
Sébastien Villemot | 4431a89e87 | |
Sébastien Villemot | 73ae1ac8ce | |
Sébastien Villemot | 08d378c244 | |
Sébastien Villemot | 8cf8731c65 | |
Sébastien Villemot | 90d790f1c3 | |
Sébastien Villemot | d814a4090b | |
Sébastien Villemot | 3ef833ac5f | |
Sébastien Villemot | c0294bb343 | |
Sébastien Villemot | 4459f9a488 | |
Sébastien Villemot | 9c88bab247 | |
Sébastien Villemot | 37870e4a40 | |
Sébastien Villemot | 5931e3aa46 | |
Sébastien Villemot | 6df56e7485 | |
Sébastien Villemot | 9fd6515f29 | |
Sébastien Villemot | 7722e8e36b | |
Sébastien Villemot | 6ed90b3dbf | |
Sébastien Villemot | fe142b663e | |
Sébastien Villemot | 1cf83dc278 | |
Sébastien Villemot | 4210618dba | |
Stéphane Adjemian (Argos) | 8e42f6d137 | |
Stéphane Adjemian (Ryûk) | b1933d58dd | |
Sébastien Villemot | d9cdcf3766 | |
Johannes Pfeifer | 37eb10971b | |
Sébastien Villemot | 37bc08eb5b | |
Sébastien Villemot | d41501bc6d | |
Sébastien Villemot | 5a6d03a2e7 | |
Sébastien Villemot | e14c59384d | |
Stéphane Adjemian (Argos) | 399532a201 | |
Johannes Pfeifer | 5c9f02634c | |
Sébastien Villemot | e86aeaf787 | |
Sébastien Villemot | 0f7ab97e69 | |
Johannes Pfeifer | ad2d986c5e | |
Stéphane Adjemian (Ryûk) | 03db691ab3 | |
Sébastien Villemot | 702ad871d4 | |
Johannes Pfeifer | df018ab14d | |
Sébastien Villemot | eaba71e24c | |
Sébastien Villemot | 3c35f34a79 | |
Stéphane Adjemian (Guts) | 43cb9b01c3 | |
Stéphane Adjemian (Guts) | 93137310dd | |
Sébastien Villemot | 4fa6101456 | |
Stéphane Adjemian (Ryûk) | 15027db136 | |
Stéphane Adjemian (Ryûk) | 1f60657d99 | |
Sébastien Villemot | 1b02026d1c | |
Sébastien Villemot | aeff2bf48d | |
Sébastien Villemot | 792aa64e76 | |
Stéphane Adjemian (Ryûk) | 015513380f | |
Sébastien Villemot | 339ba7102e | |
Sébastien Villemot | 8bb9a398aa | |
Sébastien Villemot | 79477e5ba6 | |
Willi Mutschler | 7ce2c1d5c2 | |
Willi Mutschler | b8352b251d | |
Stéphane Adjemian (Ryûk) | 084e64cdac | |
Willi Mutschler | 5d335501d7 | |
Johannes Pfeifer | be28ab1cbe | |
Sébastien Villemot | 74076b4615 | |
Johannes Pfeifer | b876cf0259 | |
Sébastien Villemot | bee75c2fd5 | |
Sébastien Villemot | 0c17d656e1 | |
Sébastien Villemot | 030316f2d8 | |
Sébastien Villemot | afe147d88d | |
Sébastien Villemot | e22972849b | |
Sébastien Villemot | 4313640f80 | |
Sébastien Villemot | d71db85c71 | |
Sébastien Villemot | 36e8062e25 | |
Sébastien Villemot | d789e6a4c5 | |
Sébastien Villemot | d0864689d2 | |
Sébastien Villemot | c6ce5856e9 | |
Sébastien Villemot | 73e4ced39a | |
Sébastien Villemot | 99cd06c9fd | |
Sébastien Villemot | e413696277 | |
Sébastien Villemot | 873685e7e6 | |
Sébastien Villemot | ebee041d1c | |
Sébastien Villemot | 36db88c56c | |
Sébastien Villemot | 85351d751c | |
Sébastien Villemot | 9dff1ff28e | |
Sébastien Villemot | e9ecce8293 | |
Sébastien Villemot | 3bf40d92f8 | |
Sébastien Villemot | 80a6967827 | |
Sébastien Villemot | 1faeaf892e | |
Sébastien Villemot | 640be269af | |
Sébastien Villemot | 62c2881bc2 | |
Sébastien Villemot | 0923187938 | |
Sébastien Villemot | 91fa8d079e | |
Sébastien Villemot | 7e1c25d775 | |
Sébastien Villemot | ed75e4c176 | |
Sébastien Villemot | 66b648157f | |
Sébastien Villemot | 34e82f9697 | |
Sébastien Villemot | 170a4dce0e | |
Sébastien Villemot | 5f42e84b0b | |
Sébastien Villemot | 4a793f89ff | |
Sébastien Villemot | 942c6f9a20 | |
Sébastien Villemot | 9deb1e6049 | |
Sébastien Villemot | bc68915dfa | |
Stéphane Adjemian (Ryûk) | 4f3a0df884 | |
Sébastien Villemot | 5c3e291483 | |
Sébastien Villemot | 90a408e3c3 | |
Sébastien Villemot | c56e7cef51 | |
Sébastien Villemot | 6938080951 | |
Sébastien Villemot | 9f29e2f292 | |
Sébastien Villemot | 2740bdee58 | |
Sébastien Villemot | 1622c74a53 | |
Sébastien Villemot | f27c3abd2f | |
Sébastien Villemot | fbaa051489 | |
Sébastien Villemot | 421eb1482c | |
Stéphane Adjemian (Ryûk) | 51ffe77fb7 | |
Stéphane Adjemian (Ryûk) | b8c70eba3b | |
Sébastien Villemot | c4bc6316d0 | |
Sébastien Villemot | 8128fd4cc3 | |
Sébastien Villemot | c4ad1d58e8 | |
Sébastien Villemot | 19afc087cc | |
Sébastien Villemot | d3afa980aa | |
Sébastien Villemot | d078810625 | |
Sébastien Villemot | a45b00fa69 | |
Sébastien Villemot | f0888468e6 | |
Sébastien Villemot | 5a1abb1b87 | |
Sébastien Villemot | 8dae5393f5 | |
Sébastien Villemot | 403db2cc64 | |
Sébastien Villemot | d5ee4dcb75 | |
Sébastien Villemot | ec908386b6 | |
Sébastien Villemot | cdb786017b | |
Sébastien Villemot | 534515dc66 | |
Sébastien Villemot | ffe6eb4d40 | |
Sébastien Villemot | 674ebce84b | |
Sébastien Villemot | 4291b4f07e | |
Sébastien Villemot | 69d0aa670b | |
Sébastien Villemot | 9fa64ee0d4 | |
Sébastien Villemot | abd24ed609 | |
Sébastien Villemot | 369782b603 | |
Sébastien Villemot | 66b1724678 | |
Sébastien Villemot | 02510e37d3 | |
Sébastien Villemot | 43190b001f | |
Johannes Pfeifer | 89fc53716e | |
Johannes Pfeifer | 64c69b4cd2 | |
Sébastien Villemot | 4f52ba0dbc | |
Sébastien Villemot | 13908ee068 | |
Sébastien Villemot | 5642e994fc | |
Sébastien Villemot | 647ff5cd20 | |
Johannes Pfeifer | 4837a4d444 | |
Sébastien Villemot | f07d73e63e | |
Sébastien Villemot | 9a71beffb3 | |
Sébastien Villemot | 22c1d4a520 | |
Sébastien Villemot | 816e94e9f9 | |
Sébastien Villemot | 060c694066 | |
Sébastien Villemot | 441173ec5a | |
Sébastien Villemot | b7477ac0b6 | |
Sébastien Villemot | 56ffc87e1c | |
Sébastien Villemot | 704f3596cb | |
Stéphane Adjemian (Ryûk) | 6e0a09f5fa | |
Sébastien Villemot | 996ab9613c | |
Johannes Pfeifer | c8045e2c5e | |
Sébastien Villemot | 6dbc7c2a17 | |
Sébastien Villemot | 62f608eb80 | |
Sébastien Villemot | 9c5604c30d | |
Sébastien Villemot | 12008bc6eb | |
Sébastien Villemot | dd93aa3cd8 | |
Sébastien Villemot | 9527624b8c | |
Sébastien Villemot | cf0c285870 | |
Johannes Pfeifer | 82bd6829a6 | |
Sébastien Villemot | ff318d1163 | |
Sébastien Villemot | 4c1af7890b | |
Sébastien Villemot | 7159a293d6 | |
Johannes Pfeifer | 39ae080997 | |
Stéphane Adjemian (Ryûk) | 7583790851 | |
Stéphane Adjemian (Ryûk) | a3b249c375 | |
Stéphane Adjemian (Ryûk) | cc0d22cf4c | |
Stéphane Adjemian (Ryûk) | cae7feeefb | |
Stéphane Adjemian (Ryûk) | a9ee96d441 | |
Stéphane Adjemian (Ryûk) | ae085b9add | |
Stéphane Adjemian (Ryûk) | 0d39cab9e1 | |
Stéphane Adjemian (Ryûk) | c006645c7f | |
Stéphane Adjemian (Ryûk) | 2ab19c1aa9 | |
Stéphane Adjemian (Ryûk) | 656a7bf867 | |
Stéphane Adjemian (Ryûk) | f6a76066f9 | |
Stéphane Adjemian (Ryûk) | 0b9141fdca | |
Stéphane Adjemian (Ryûk) | a0d53277c1 | |
Sébastien Villemot | 66abd09b87 | |
Sébastien Villemot | b669d5c0dc | |
Sébastien Villemot | 9598afcc46 | |
Sébastien Villemot | f02d66ce7c | |
Sébastien Villemot | a2591c474e | |
Sébastien Villemot | c51223466c | |
Sébastien Villemot | 7fcbef5293 | |
Sébastien Villemot | c7d2ea0a62 | |
Sébastien Villemot | 325e6487d4 | |
Sébastien Villemot | 17df930eb9 | |
Sébastien Villemot | 0e1678c13a | |
Sébastien Villemot | 13b3208cdb | |
Sébastien Villemot | aaab993ccf | |
Sébastien Villemot | 895ce96c61 | |
Sébastien Villemot | 1ad6b29936 | |
Sébastien Villemot | 24b2976ac2 | |
Sébastien Villemot | 845eac99d3 | |
Sébastien Villemot | f5523c7bab | |
Sébastien Villemot | 62805b7183 | |
Sébastien Villemot | f938014e84 | |
Sébastien Villemot | 24f689b2de | |
Sébastien Villemot | 6bddbca01d | |
Sébastien Villemot | 05ba2970be | |
Sébastien Villemot | aee39d54ef | |
Sébastien Villemot | 2a25119bb3 | |
Sébastien Villemot | fc453a6e2f | |
Sébastien Villemot | 2a4f850996 | |
Sébastien Villemot | 0da73f6415 | |
Sébastien Villemot | 39a9b221b9 | |
Sébastien Villemot | 1a421d93dd | |
Sébastien Villemot | def25a1fd3 | |
Sébastien Villemot | dbcaa2abfa | |
Sébastien Villemot | 659474bd99 | |
Sébastien Villemot | a1cdd287e5 | |
Sébastien Villemot | 4a150efb22 | |
Sébastien Villemot | 2c44923384 | |
Sébastien Villemot | 05db89cb8c | |
Sébastien Villemot | 3e6b6c87c3 | |
Sébastien Villemot | 65053667cf | |
Sébastien Villemot | 7e3b83a135 | |
Sébastien Villemot | d6370a6d28 | |
Sébastien Villemot | c3524d33d0 | |
Sébastien Villemot | be698d5f98 | |
Marco Ratto | 63a299f64e | |
Marco Ratto | f565a0a84a | |
Marco Ratto | f0aa2fb86f | |
Marco Ratto | b886de92dc | |
Marco Ratto | cdd195576e | |
Marco Ratto | 783c237d17 | |
Marco Ratto | 035db8b8c4 | |
Marco Ratto | 77e87be48b | |
Marco Ratto | 22e6fb1814 | |
Marco Ratto | 7132cb593e | |
Marco Ratto | 50aa20c742 | |
Marco Ratto | e51a30eaf5 | |
Marco Ratto | a4dc58db8e | |
Marco Ratto | a346639020 | |
Marco Ratto | 6598d615d1 | |
Marco Ratto | a91c36f920 | |
Marco Ratto | 74acb2d1f5 | |
Marco Ratto | 21443e0988 | |
Marco Ratto | 21c9d59e8c | |
Marco Ratto | 0622f01f4e | |
Marco Ratto | b90dff1986 | |
Sébastien Villemot | ef7dc09b8e | |
Sébastien Villemot | 0c06ab1cc1 | |
Sébastien Villemot | cef1ce33ed | |
Sébastien Villemot | 5aca770931 | |
Sébastien Villemot | 35b32ded34 | |
Sébastien Villemot | 5093264b8a | |
Sébastien Villemot | fa7839ea39 | |
Sébastien Villemot | c3e1480a52 | |
Sébastien Villemot | 7922fc011e | |
Sébastien Villemot | 538f38d269 | |
Johannes Pfeifer | 4307711c60 | |
Sébastien Villemot | cfaf5a685d | |
Sébastien Villemot | 8200c356a7 | |
Sébastien Villemot | fcdd810eb4 | |
Sébastien Villemot | 8aabdaee9c | |
Sébastien Villemot | 7b6058509f | |
Sébastien Villemot | 005769210a | |
Sébastien Villemot | 5342476196 | |
Sébastien Villemot | 023afc7ebb | |
Sébastien Villemot | 4ecc78a931 | |
Sébastien Villemot | 0c5c96e724 | |
Sébastien Villemot | 2bdc185f1d | |
Sébastien Villemot | e30314e75d | |
Sébastien Villemot | 1b47c8a5e5 | |
Sébastien Villemot | 1c5c1639e1 | |
Sébastien Villemot | e5f100b152 | |
Sébastien Villemot | c187d0ead9 | |
Sébastien Villemot | 8f1a4cb363 | |
Sébastien Villemot | 3a5e38f49c | |
Sébastien Villemot | 58e98a78c6 | |
Normann Rion | 7721ea041c | |
Normann Rion | 7fac60f5f6 | |
Normann Rion | ea01f8f22a | |
Sébastien Villemot | 9540313b93 | |
Sébastien Villemot | 550e48884a | |
Sébastien Villemot | 542e30d417 | |
Sébastien Villemot | eb6becfa82 | |
Sébastien Villemot | 8a0dba1f88 | |
Sébastien Villemot | 90484edb0e | |
Sébastien Villemot | 62ff3f3194 | |
Frédéric Karamé | 773cbd2f38 | |
Sébastien Villemot | 84562f3568 | |
Sébastien Villemot | 6cf56ec86c | |
Johannes Pfeifer | 43dc073192 | |
Sébastien Villemot | 95ce62b2f7 | |
Sébastien Villemot | 8ee74d84b0 | |
Sébastien Villemot | 13538155cc | |
Sébastien Villemot | ef84d0270d | |
Sébastien Villemot | dc3aff7e1e | |
Sébastien Villemot | acd04951e3 | |
Johannes Pfeifer | c03862e71b | |
Sébastien Villemot | 91736d3d8b | |
Johannes Pfeifer | e544f1d860 | |
Stéphane Adjemian (Ryuk) | 3da7ded1da | |
Stéphane Adjemian (Ryuk) | 35ff1c0261 | |
Stéphane Adjemian (Ryuk) | fb8301d87e | |
Stéphane Adjemian (Ryuk) | a4ef4676d1 | |
Sébastien Villemot | 8a4b75bc5c | |
Sébastien Villemot | e3138abef8 | |
Sébastien Villemot | 19d7e2ce86 | |
Sébastien Villemot | 9b3d061f98 | |
Stéphane Adjemian | 8d0c555627 | |
Johannes Pfeifer | e953ba562c | |
Johannes Pfeifer | e49cdefac3 | |
Johannes Pfeifer | 0c6151df7a | |
Stéphane Adjemian (Charybdis) | d1ff573c67 | |
Sébastien Villemot | d1ea4e75e5 | |
Sébastien Villemot | 173d5d9270 | |
Johannes Pfeifer | 5714ebf298 | |
Sébastien Villemot | 68ae83c25c | |
Sébastien Villemot | b7996a0610 | |
Johannes Pfeifer | 389bdc23f2 | |
Johannes Pfeifer | 6f3a0298e3 | |
Sébastien Villemot | 909025639c | |
Stéphane Adjemian (Charybdis) | 5a9ddc405e | |
Stéphane Adjemian (Charybdis) | e6f75e4b18 | |
Stéphane Adjemian (Charybdis) | 7d8c922b78 | |
Stéphane Adjemian (Charybdis) | ae23c01d1c | |
Stéphane Adjemian (Charybdis) | 8cd20070d2 | |
Stéphane Adjemian (Charybdis) | 6e27946a04 | |
Stéphane Adjemian (Charybdis) | b8180f3328 | |
Houtan Bastani | 9988ba358d | |
Houtan Bastani | 48c58cd6c0 | |
Houtan Bastani | 080f90119c | |
Houtan Bastani | cd483463b5 | |
Houtan Bastani | 0c1569db72 | |
Houtan Bastani | 1c7b3b09f5 | |
Houtan Bastani | 87f815d701 | |
Houtan Bastani | 6fe23556f6 | |
Houtan Bastani | bc55bdb2a6 | |
Houtan Bastani | ce1c8c5bc2 | |
Houtan Bastani | b70a5269ee | |
Houtan Bastani | a717cc2ad4 | |
Houtan Bastani | 7e47f128d9 | |
Houtan Bastani | 933c1eeb72 | |
Houtan Bastani | 388f92b607 | |
Houtan Bastani | 09b59aa321 | |
Sébastien Villemot | 6a2a1c9266 | |
Sébastien Villemot | bbe24ad987 | |
Houtan Bastani | 5d882351d0 | |
Houtan Bastani | edf1472f1b | |
Houtan Bastani | 41a2072862 | |
Houtan Bastani | ccd4a416f7 | |
Houtan Bastani | 87ddce0dc3 | |
Houtan Bastani | 835be14b33 | |
Houtan Bastani | 30689dd1c8 | |
Houtan Bastani | d64ecf22b6 | |
Houtan Bastani | 1b8c2d4c48 | |
Houtan Bastani | 3183d806e3 | |
Houtan Bastani | 35e97799c4 | |
Houtan Bastani | 48d73ecb0c | |
Houtan Bastani | 8909f01b13 | |
Houtan Bastani | 543e973042 | |
Houtan Bastani | b397002973 | |
Houtan Bastani | 245a11d547 | |
Sébastien Villemot | cbed396604 | |
Sébastien Villemot | 6f48a2857a | |
Houtan Bastani | df9d6c35de | |
Houtan Bastani | 04eabc587f | |
Houtan Bastani | a2d9d20a9d | |
Houtan Bastani | 7c68e6709b | |
Houtan Bastani | 0e935918c6 | |
Stéphane Adjemian (Charybdis) | bc1c173988 | |
Frédéric Karamé | 2aed30d686 | |
Houtan Bastani | cac8231f48 | |
Houtan Bastani | 4cea90a156 | |
Sébastien Villemot | fcfde3bc0b | |
Sébastien Villemot | fd977f79f7 | |
Sébastien Villemot | 0ece9d3062 | |
Sébastien Villemot | f9e85d3c80 | |
Frédéric Karamé | 713e3ffcfb | |
Frédéric Karamé | a299c04d7e | |
Frédéric Karamé | 6e89a1ff9e | |
Frédéric Karamé | 4de28e10c0 | |
Frédéric Karamé | 801d175890 | |
Frédéric Karamé | b66d78d434 | |
Frédéric Karamé | cecc11c73f | |
Frédéric Karamé | b7597b5060 | |
Frédéric Karamé | be31310838 | |
Frédéric Karamé | d3d6a037b1 | |
Houtan Bastani | eeccf4021c | |
Houtan Bastani | c094e38927 | |
Houtan Bastani | e5fb0efd7b | |
Houtan Bastani | 2abe25e3aa | |
Stéphane Adjemian (Charybdis) | e71343cb79 | |
Sébastien Villemot | 3178cb0c44 | |
Sébastien Villemot | 3575db6100 | |
Houtan Bastani | c05d3a5cb9 | |
Houtan Bastani | aa3fdcf262 | |
Houtan Bastani | 136588fcef | |
Stéphane Adjemian (Charybdis) | 53d38e7833 | |
Stéphane Adjemian (Charybdis) | 3d0abed99a | |
Stéphane Adjemian (Charybdis) | 1eee8eb3f2 | |
Stéphane Adjemian (Charybdis) | a812a00b17 | |
Houtan Bastani | 046a1b3804 | |
Houtan Bastani | 7ba160e898 | |
Houtan Bastani | 9166579b46 | |
Houtan Bastani | b5802808e3 | |
Houtan Bastani | 3b6540951b | |
Houtan Bastani | e1941ca4a7 | |
Houtan Bastani | 215245758d | |
Stéphane Adjemian (Charybdis) | a4158ad306 | |
Houtan Bastani | ce79dbe420 | |
Stéphane Adjemian | 0c28a29392 | |
Johannes Pfeifer | bd8e804435 | |
Houtan Bastani | 21bbf12999 | |
Houtan Bastani | 60def33fa7 | |
Houtan Bastani | 8118eb0c49 | |
Frédéric Karamé | 814cb693f6 | |
Frédéric Karamé | bdd519a5f5 | |
Houtan Bastani | 4644a31291 | |
Frédéric Karamé | e6d081d58a | |
Frédéric Karamé | 8221d5c780 | |
Frédéric Karamé | 0141b34310 | |
Stéphane Adjemian (Charybdis) | 005b0907c0 | |
Stéphane Adjemian (Charybdis) | 8f4fe9b341 | |
Houtan Bastani | e16102fbf6 | |
Houtan Bastani | 332054cdc1 | |
Houtan Bastani | 33c8426ca3 | |
Frédéric Karamé | 75b17ce780 | |
Frédéric Karamé | 394df6f537 | |
Frédéric Karamé | 9a366d6576 | |
Frédéric Karamé | df842aa542 | |
Frédéric Karamé | 3c18bf1f6b | |
Houtan Bastani | af52282be0 | |
Houtan Bastani | b1e8790ff5 | |
Houtan Bastani | bac8ef8520 | |
ferhat | 3e040087e8 | |
Houtan Bastani | b94839f83b | |
Houtan Bastani | de6e1faae8 | |
Frédéric Karamé | e6d627396a | |
Houtan Bastani | 42797082ec | |
Houtan Bastani | 905c3b9c40 | |
Houtan Bastani | d204b44434 | |
Houtan Bastani | b0fc52dca1 | |
Houtan Bastani | 8050deee0e | |
Houtan Bastani | 6c3719280e | |
Houtan Bastani | 428ead788c | |
Houtan Bastani | 9f8eb4e30d | |
Houtan Bastani | 1aca7bb7e3 | |
ferhat | bae1f89c02 | |
ferhat | 0af48c4ac9 | |
Frédéric Karamé | 7816397856 | |
Frédéric Karamé | 46f367b299 | |
Frédéric Karamé | 8b79fb562b | |
Frédéric Karamé | bf956f9bb0 | |
Frédéric Karamé | ce9dace8ef | |
Frédéric Karamé | 57f4f5b157 | |
Frédéric Karamé | a64073ec3c | |
Stéphane Adjemian | c4b465a2c4 | |
Johannes Pfeifer | d5ef4962bd | |
Houtan Bastani | a037e3177c | |
Houtan Bastani | 2cb0bc27dc | |
Houtan Bastani | cb2571b158 | |
Houtan Bastani | 2464865b88 | |
Houtan Bastani | b4bbd49b7f | |
Houtan Bastani | 3a303fcb6f | |
Houtan Bastani | 9cd10285ec | |
Houtan Bastani | 33aba204d8 | |
Houtan Bastani | ce891a5e3d | |
Houtan Bastani | b15cfd1404 | |
Houtan Bastani | cea37a15e5 | |
Houtan Bastani | ca59274c87 | |
Houtan Bastani | 9e9f746469 | |
Houtan Bastani | 08eeb0fd1e | |
Houtan Bastani | ac811378c7 | |
Houtan Bastani | bf6fa900db | |
Houtan Bastani | 7a8467c13a | |
Houtan Bastani | 5f41bb3264 | |
Houtan Bastani | 17d5b639f1 | |
Stéphane Adjemian (Hermes) | 042303da68 | |
Frédéric Karamé | 47bfcece40 | |
Frédéric Karamé | 6ab142a75b | |
Houtan Bastani | 67f6f59e7f | |
Houtan Bastani | 0f4e3d2888 | |
Houtan Bastani | 84d1933143 | |
Houtan Bastani | f2002669e4 | |
Houtan Bastani | c620943245 | |
Houtan Bastani | 523c0c7864 | |
Houtan Bastani | ec6a4e92b0 | |
Frédéric Karamé | 34cf8ca284 | |
Houtan Bastani | c2a3e40178 | |
Houtan Bastani | 6980669d6e | |
Houtan Bastani | 761c07cdb2 | |
Houtan Bastani | 1c1681ac3c | |
Houtan Bastani | e436add816 | |
Frédéric Karamé | 19858696bf | |
Houtan Bastani | 29587b7f2a | |
Frédéric Karamé | 49d25782bb | |
Frédéric Karamé | 2b0a83ca91 | |
Frédéric Karamé | 3300a448f2 | |
Frédéric Karamé | bcb09ee14d | |
Houtan Bastani | b3a7e49464 | |
Houtan Bastani | eab8089e16 | |
Frédéric Karamé | f3a4bd8a63 | |
Frédéric Karamé | 81c02a58d8 | |
Frédéric Karamé | 29db2fe060 | |
Frédéric Karamé | d5735c9585 | |
Houtan Bastani | 135ae323d5 | |
Houtan Bastani | 224f2ed793 | |
Houtan Bastani | 814ff2a835 | |
Houtan Bastani | 94533d213b | |
Frédéric Karamé | d476a195e0 | |
Stéphane Adjemian | 86ebce712f | |
Stéphane Adjemian (Charybdis) | 3c345e1d45 | |
Stéphane Adjemian (Charybdis) | 5c3a4841b8 | |
Stéphane Adjemian (Charybdis) | cca16be513 | |
Stéphane Adjemian (Charybdis) | bebcba0a7d | |
Stéphane Adjemian (Charybdis) | c0cfc640c4 | |
Stéphane Adjemian (Charybdis) | e803fdbc88 | |
Stéphane Adjemian (Charybdis) | 5610856478 | |
Stéphane Adjemian (Charybdis) | dd0cc89ef3 | |
Frédéric Karamé | d533b826c1 | |
Frédéric Karamé | d4e4ea4ad8 | |
Stéphane Adjemian (Telemachus) | 459d02febf | |
Stéphane Adjemian (Telemachus) | deef89316c | |
Stéphane Adjemian (Telemachus) | 4c71e9b4ab | |
Stéphane Adjemian (Telemachus) | 27f5f298f4 | |
Stéphane Adjemian (Telemachus) | 0514b3949c | |
Stéphane Adjemian (Telemachus) | 9bb61c33bf | |
Houtan Bastani | 387a9b87b1 | |
Houtan Bastani | 2cbe1c34d9 | |
Houtan Bastani | 54adbb1e69 | |
Houtan Bastani | 13dc0e3538 | |
Houtan Bastani | 4fa89e2fc4 | |
Houtan Bastani | 3adc7826db | |
Houtan Bastani | 310b081c41 | |
Houtan Bastani | d6a37e8fcc | |
Houtan Bastani | 7a529bc973 | |
Houtan Bastani | b0bd8d62c0 | |
Houtan Bastani | 4487e41580 | |
Houtan Bastani | 9aef6eede7 | |
Houtan Bastani | 8a89b63cea | |
Houtan Bastani | 2f4540d36c | |
Houtan Bastani | 27764e5c4e | |
Houtan Bastani | ff97205474 | |
Houtan Bastani | 7c7a8a5bb9 | |
Houtan Bastani | a1d4284e7c | |
Houtan Bastani | 52dacc673d | |
Houtan Bastani | 128a6c6d95 | |
Houtan Bastani | 4fd0daee45 | |
Houtan Bastani | 36332da071 | |
Houtan Bastani | a269940940 | |
Houtan Bastani | 544b4c5a57 | |
Houtan Bastani | ee1e47883c | |
Houtan Bastani | dcd151a713 | |
Houtan Bastani | afa2f03db5 | |
Houtan Bastani | d038a6c9f3 | |
Houtan Bastani | f2e0ce6af8 | |
Houtan Bastani | 2a490eaa80 | |
Houtan Bastani | 914b81d830 | |
Houtan Bastani | 656d74436b | |
Houtan Bastani | 0f3c1b1537 | |
Houtan Bastani | cd6074b5d1 | |
Houtan Bastani | 0059a1bd4b | |
Houtan Bastani | bd5ba5e73d | |
Houtan Bastani | fac17ab6e7 | |
Houtan Bastani | 92e8c9340a | |
Houtan Bastani | 5b29f183b3 | |
Houtan Bastani | 120aa7ede7 | |
Houtan Bastani | dc8763a810 | |
Houtan Bastani | 62f8189a25 | |
Houtan Bastani | d40498fea1 | |
Houtan Bastani | f3cdc4ff79 | |
Houtan Bastani | 905bb8a3b6 | |
Houtan Bastani | 927bc3b9c9 | |
Houtan Bastani | cb90f5e72d | |
Houtan Bastani | 7576ba2e03 | |
Houtan Bastani | c0174131f6 | |
Houtan Bastani | 1d4fe68f4d | |
Houtan Bastani | 9829a5e213 | |
Houtan Bastani | 8222d4254d | |
Houtan Bastani | 41d86fca9e | |
Houtan Bastani | 2dd68d4ecd | |
Houtan Bastani | 56d284d30a | |
Houtan Bastani | c783bcfccf | |
Houtan Bastani | 5a35c9d54a | |
Houtan Bastani | 75f4994d04 | |
Houtan Bastani | 01e6c2a971 | |
Houtan Bastani | bb3e2fdff8 | |
Houtan Bastani | f035fabb14 | |
Houtan Bastani | 7dfe38198c | |
Houtan Bastani | eacea6d66d | |
Houtan Bastani | f877285c3b | |
Houtan Bastani | 84faa840c0 | |
Houtan Bastani | c693f745fa | |
Houtan Bastani | 68a8e42933 | |
Houtan Bastani | 2e8ef3ad5f | |
Houtan Bastani | 414ef860ab | |
Houtan Bastani | 96cd971f66 | |
Houtan Bastani | 7cfedcd2f6 | |
Houtan Bastani | a71b8808df | |
Houtan Bastani | a4b45bae37 | |
Houtan Bastani | 5f82248caf | |
Houtan Bastani | 3751fd9f39 | |
Houtan Bastani | d71878e327 | |
Houtan Bastani | 4c0cbaceff | |
Houtan Bastani | f92e714000 | |
Houtan Bastani | ed80ed12fb | |
Houtan Bastani | a940a028c6 | |
Houtan Bastani | 97da5d9ae3 | |
Houtan Bastani | 7f199ee114 | |
Houtan Bastani | 95f9c37726 | |
Houtan Bastani | 7cf2d46463 | |
Houtan Bastani | 67360a1711 | |
Houtan Bastani | fb7def044a | |
Houtan Bastani | 0d364975db | |
Houtan Bastani | 2a38a2615d | |
Houtan Bastani | 27fea2633a | |
Houtan Bastani | 1d76ad5496 | |
Houtan Bastani | 53d249cd88 | |
Houtan Bastani | f90a6836e7 | |
Houtan Bastani | 617db5ba64 | |
Houtan Bastani | adda7d8604 | |
Houtan Bastani | 1cfc233633 | |
Houtan Bastani | 24f550a2e9 | |
Houtan Bastani | 33d22eaf9b | |
Houtan Bastani | c21044ba87 | |
Houtan Bastani | fa020902a0 | |
Houtan Bastani | c862fdfbb7 | |
Houtan Bastani | ef6935fe96 | |
Houtan Bastani | f3be3f811c | |
Houtan Bastani | 21895669db | |
Houtan Bastani | 956a7644b0 | |
Houtan Bastani | b642de2343 | |
Houtan Bastani | 48d077cd4e | |
Houtan Bastani | 2070610fe2 | |
Houtan Bastani | 5e96706727 | |
Houtan Bastani | ae92cca4a2 | |
Houtan Bastani | f776f5c5cd | |
Houtan Bastani | ba6336dddc | |
Houtan Bastani | 60e292b70b | |
Houtan Bastani | c0372ab81f | |
Houtan Bastani | 1581202772 | |
Houtan Bastani | fbcc6830f2 | |
Houtan Bastani | 86bb71888f | |
Houtan Bastani | c8b147c0c0 | |
Houtan Bastani | ce6fa17483 | |
Houtan Bastani | 0678b98eca | |
Houtan Bastani | 764b31de99 | |
Houtan Bastani | f47555a92f | |
Houtan Bastani | 91f408b6b9 | |
Sébastien Villemot | d21738853c | |
Houtan Bastani | 49fc522b27 | |
Houtan Bastani | a3a6e7e7b9 | |
Houtan Bastani | 6a0d9b3d59 | |
Houtan Bastani | 517d242059 | |
Houtan Bastani | 2b23bcac46 | |
Houtan Bastani | 7fa3ab3999 | |
Houtan Bastani | da83298e46 | |
Houtan Bastani | 8315ae52a4 | |
Houtan Bastani | 94fc7382ca | |
Houtan Bastani | 664fa0d5e8 | |
Houtan Bastani | ab2fa28ea6 | |
Houtan Bastani | 913612e604 | |
Stéphane Adjemian (Charybdis) | d4e903e665 | |
Stéphane Adjemian (Charybdis) | 2174190e49 | |
Stéphane Adjemian (Charybdis) | cb9732a609 | |
Houtan Bastani | 64a5ab28a9 | |
Houtan Bastani | 1e62b4e77e | |
Houtan Bastani | 4cef528e56 | |
Stéphane Adjemian (Charybdis) | 2bb645ec70 | |
Houtan Bastani | 3dbb9bd6a2 | |
Houtan Bastani | 151c3c328b | |
Houtan Bastani | 376c605499 | |
Houtan Bastani | f10dbf60c6 | |
Houtan Bastani | 43504f9d64 | |
Houtan Bastani | 07fc0307ab | |
Houtan Bastani | 5fd2a4755c | |
Houtan Bastani | d22ebccf2c | |
Houtan Bastani | 493525e14a | |
Houtan Bastani | c4540358db | |
Houtan Bastani | 56a79d353d | |
Houtan Bastani | 9b2a8d12e0 | |
Houtan Bastani | df05b5204e | |
Houtan Bastani | 704e72a0f2 | |
Houtan Bastani | b8d4650074 | |
Houtan Bastani | f1c8147d91 | |
Houtan Bastani | a96b3d5074 | |
Houtan Bastani | 8ece1f1245 | |
Houtan Bastani | 17081da6e1 | |
Houtan Bastani | 68e4b22348 | |
Houtan Bastani | 48e5541bce | |
Houtan Bastani | 184167b404 | |
Houtan Bastani | 7a56e7ab7a | |
Houtan Bastani | dc3792f8b3 | |
Houtan Bastani | 35f1724f42 | |
Houtan Bastani | 5981d2a9d6 | |
Houtan Bastani | cc5a6f0ff0 | |
Houtan Bastani | f4ae8dbeab | |
Houtan Bastani | 9b67b92ece | |
Houtan Bastani | 3d0b2f49e3 | |
Houtan Bastani | c1f73901b5 | |
Houtan Bastani | 01f1474c56 | |
Houtan Bastani | b0ea699799 | |
Houtan Bastani | 12a5950394 | |
Houtan Bastani | c4b529ce2b | |
Houtan Bastani | 2e3326b3b4 | |
Houtan Bastani | 201178d7e0 | |
Houtan Bastani | f9f9d7de0d | |
Houtan Bastani | 0f48b7dce3 | |
Houtan Bastani | 7b97c358f3 | |
Houtan Bastani | b521b6adee | |
Houtan Bastani | 8e20b98d98 | |
Houtan Bastani | 02ca95e811 | |
Houtan Bastani | ec49704822 | |
Houtan Bastani | d3cf432e30 | |
Houtan Bastani | 95bed0fd57 | |
Houtan Bastani | 8d645b642f | |
Houtan Bastani | e74412249e | |
Houtan Bastani | 8a7c0d5611 | |
Houtan Bastani | 7e0c50421e | |
Houtan Bastani | aad042ec27 | |
Houtan Bastani | af11f6449f | |
Houtan Bastani | bb7d6c750c | |
Houtan Bastani | d98687aacf | |
Houtan Bastani | 3c8164f101 | |
Houtan Bastani | b7df250525 | |
Houtan Bastani | aaf0cc48f7 | |
Houtan Bastani | 145fcfdd19 | |
Houtan Bastani | 515ee0d9af | |
Houtan Bastani | 74a8e9bcc1 | |
Houtan Bastani | a8c9f2afdd | |
Houtan Bastani | 12c94e6881 | |
Houtan Bastani | 17a2c4000d | |
Houtan Bastani | 85ea29e1a8 | |
Houtan Bastani | 91162e9eb0 | |
Houtan Bastani | 9143a805fa | |
Houtan Bastani | 2cb40a658d | |
Houtan Bastani | 8947c52c1f | |
Houtan Bastani | ef7bb4f04f | |
Houtan Bastani | 60ee6c08b3 | |
Houtan Bastani | 90b164d288 | |
Houtan Bastani | 628f1fef43 | |
Houtan Bastani | ad2b5fed3e | |
Houtan Bastani | 4841f700eb | |
Houtan Bastani | 22962be7c1 | |
Houtan Bastani | dd987523c8 | |
Houtan Bastani | ec0dc6148c | |
Houtan Bastani | 540c59ee85 | |
Houtan Bastani | 2921f91ca3 | |
Houtan Bastani | 11e90492df | |
Houtan Bastani | cec93b6b37 | |
Houtan Bastani | d1b4a10ffe | |
Houtan Bastani | c983d99169 | |
Houtan Bastani | 8ac9ac6f68 | |
Houtan Bastani | d78e491278 | |
Houtan Bastani | cc6d29c5fc | |
Houtan Bastani | d0be97c4e4 | |
Houtan Bastani | ee7f2fb7d0 | |
Houtan Bastani | 57c10f5ff8 | |
Houtan Bastani | 7280ec13a7 | |
Houtan Bastani | 7b14bdafe9 | |
Houtan Bastani | 7068bc4f80 | |
Houtan Bastani | 33e80b5816 | |
Houtan Bastani | c94f1b98b1 | |
Houtan Bastani | 1f988bcdf4 | |
Houtan Bastani | 0d33a12d5b | |
Houtan Bastani | 922c0066c7 | |
Houtan Bastani | 03e306785c | |
Houtan Bastani | 6e9be0feb4 | |
Houtan Bastani | 953dab0358 | |
Houtan Bastani | 2529b12660 | |
Houtan Bastani | 258acc58ad | |
Houtan Bastani | 1b25e97051 | |
Houtan Bastani | 7c7ff24ebe | |
Houtan Bastani | 6b3b92d7dd | |
Houtan Bastani | edf643af6b | |
Houtan Bastani | a9ff5c74d3 | |
Houtan Bastani | 85d4bd69a3 | |
Houtan Bastani | 5c82fcc87f | |
Houtan Bastani | 3ba1dcd408 | |
Houtan Bastani | 6d0cd7ba5a | |
Houtan Bastani | 1f73c74211 | |
Houtan Bastani | 59ef4b9e68 | |
Houtan Bastani | ce65626a68 | |
Houtan Bastani | 5d5f394eb1 | |
Houtan Bastani | 94c37bcf96 | |
Houtan Bastani | d905c6ad84 | |
Houtan Bastani | faf2d3be3f | |
Houtan Bastani | c09f1d02d0 | |
Houtan Bastani | 9158ad5b8e | |
Houtan Bastani | 13d82d94ed | |
Houtan Bastani | 7efaaea364 | |
Houtan Bastani | 59a190a282 | |
Houtan Bastani | fb8cf54f08 | |
Houtan Bastani | 33b76367ab | |
Houtan Bastani | 263c84e985 | |
Houtan Bastani | b400fea376 | |
Houtan Bastani | 2230380a35 | |
Houtan Bastani | 1d8fdfd31d | |
Stéphane Adjemian (Ulysses) | 3b8b6f82cf | |
Houtan Bastani | fbf807ad0f | |
Houtan Bastani | 51f83a118d | |
Houtan Bastani | 16aebf892c | |
Houtan Bastani | 1c371389df | |
Houtan Bastani | ff4a155f07 | |
Houtan Bastani | 95e2dd079e | |
Houtan Bastani | 218c1655a1 |
|
@ -0,0 +1,27 @@
|
|||
# NB: whenever the present file is modified, the same modification should be
|
||||
# applied to the copy in preprocessor.git
|
||||
|
||||
# For general information about our coding style, and the specific version
|
||||
# of clang-format used, see:
|
||||
# https://git.dynare.org/Dynare/dynare/-/wikis/CodingGuidelines#c-code
|
||||
# For the list of options of clang-format, see:
|
||||
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||
# Effective configuration can be obtained with:
|
||||
# clang-format --dump-config
|
||||
Language: Cpp
|
||||
Standard: c++20
|
||||
ColumnLimit: 100
|
||||
BasedOnStyle: GNU
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BreakConstructorInitializers: AfterColon
|
||||
BreakInheritanceList: AfterColon
|
||||
Cpp11BracedListStyle: true
|
||||
DeriveLineEnding: false
|
||||
IndentPPDirectives: AfterHash
|
||||
PackConstructorInitializers: NextLine
|
||||
PPIndentWidth: 1
|
||||
PointerAlignment: Left
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeCpp11BracedList: true
|
|
@ -0,0 +1,8 @@
|
|||
# NB: to use clang-tidy on the MEX source code, make sure that you have
|
||||
# libomp-dev installed (the LLVM implementation of OpenMP)
|
||||
|
||||
# TODO: add the following check families:
|
||||
# - bugprone-*
|
||||
# - cppcoreguidelines-
|
||||
|
||||
Checks: 'performance-*,modernize-*,-modernize-use-trailing-return-type,-clang-diagnostic-unqualified-std-cast-call'
|
|
@ -1,6 +1,8 @@
|
|||
((c-mode . ((indent-tabs-mode . nil)
|
||||
(fill-column . 100)
|
||||
(c-file-style . "gnu")))
|
||||
(c++-mode . ((indent-tabs-mode . nil)
|
||||
(fill-column . 100)
|
||||
(c-file-style . "gnu")))
|
||||
(makefile-mode . ((indent-tabs-mode . t)))
|
||||
(octave-mode . ((indent-tabs-mode . nil)
|
||||
|
|
|
@ -1,159 +1,35 @@
|
|||
# For checking that no file has been unduly ignored, run:
|
||||
# $ git ls-files -i --exclude-per-directory=.gitignore
|
||||
# $ git ls-files -i -c --exclude-per-directory=.gitignore
|
||||
# Any file that is displayed should be removed from the ignore list
|
||||
# (possibly by an exclusion rule beginning with an exclamation mark)
|
||||
|
||||
# Generic ignore rules
|
||||
*~
|
||||
*.o
|
||||
*.a
|
||||
*.fig
|
||||
\#*\#
|
||||
TAGS
|
||||
*.mat
|
||||
|
||||
# Build system rules
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
confdefs.h
|
||||
configure
|
||||
config.log
|
||||
config.status
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
config.guess
|
||||
config.sub
|
||||
depcomp
|
||||
install-sh
|
||||
/missing
|
||||
/mex/build/matlab/missing
|
||||
/mex/build/octave/missing
|
||||
/compile
|
||||
/mex/build/matlab/compile
|
||||
/mex/build/octave/compile
|
||||
ylwrap
|
||||
ar-lib
|
||||
|
||||
# checksum associated with fast option
|
||||
checksum
|
||||
|
||||
# Make Check Rules
|
||||
*.trs
|
||||
*.tls
|
||||
|
||||
# Doc rules
|
||||
*.pdf
|
||||
*.aux
|
||||
*.log
|
||||
*.out
|
||||
*.toc
|
||||
*.idx
|
||||
*.scn
|
||||
*.nav
|
||||
*.snm
|
||||
*.vrb
|
||||
*.bbl
|
||||
*.blg
|
||||
*.lof
|
||||
/doc/manual/build
|
||||
/doc/manual/utils/version.py
|
||||
# Created when building the reference manual
|
||||
/doc/manual/utils/__pycache__/*
|
||||
!/doc/guide.bbl
|
||||
!/doc/parallel/AvenueParadigm.pdf
|
||||
!/doc/parallel/iVaNo_*.pdf
|
||||
!/doc/parallel/netbook_*.pdf
|
||||
!/doc/parallel/quest_*.pdf
|
||||
!/doc/parallel/RWMH_quest1_*.pdf
|
||||
!/doc/parallel/waitbars*.pdf
|
||||
doc/internals/*.html
|
||||
doc/internals/ltxpng
|
||||
|
||||
# MATLAB dir
|
||||
# Created by the Windows package build script
|
||||
/windows/deps/lib64/
|
||||
/windows/deps/lib64-msys2/
|
||||
/windows/deps/matlab64/
|
||||
/windows/deps/mingw64/
|
||||
/windows/deps/octave64/
|
||||
/windows/deps/sources64/
|
||||
/windows/deps/tarballs/
|
||||
/windows/exe/
|
||||
/windows/7z/
|
||||
/windows/zip/
|
||||
/matlab/preprocessor64/
|
||||
/matlab/dynare_version.m
|
||||
/matlab/supported_octave_version.m
|
||||
|
||||
# DLL rules
|
||||
*.mex
|
||||
*.oct
|
||||
*.mexglx
|
||||
*.mexa64
|
||||
*.mexw32
|
||||
*.mexw64
|
||||
*.mexmaci
|
||||
*.mexmaci64
|
||||
/mex/matlab/
|
||||
/mex/octave/
|
||||
|
||||
# Symbolic links created for building MEX files
|
||||
/mex/build/matlab/*/*.c
|
||||
/mex/build/matlab/*/*.cc
|
||||
/mex/build/matlab/*/*.f08
|
||||
/mex/build/matlab/*/*.F08
|
||||
/mex/build/octave/*/*.c
|
||||
/mex/build/octave/*/*.cc
|
||||
/mex/build/octave/*/*.f08
|
||||
/mex/build/octave/*/*.F08
|
||||
|
||||
# Fortran modules
|
||||
/mex/build/matlab/*/*.mod
|
||||
/mex/build/octave/*/*.mod
|
||||
|
||||
# Extra rules for trust_region MEX testfiles
|
||||
/mex/sources/block_trust_region/test/*.mod
|
||||
/mex/sources/block_trust_region/test/dulmage_mendelsohn_test
|
||||
/mex/sources/block_trust_region/test/trust_region_test
|
||||
!/mex/sources/block_trust_region/test/Makefile
|
||||
|
||||
# Windows
|
||||
!/windows/Makefile
|
||||
!/windows/deps/Makefile
|
||||
windows/deps/lib32/
|
||||
windows/deps/lib64/
|
||||
windows/deps/lib32-msys2/
|
||||
windows/deps/lib64-msys2/
|
||||
windows/deps/matlab32/
|
||||
windows/deps/matlab64/
|
||||
windows/deps/mingw32/
|
||||
windows/deps/mingw64/
|
||||
windows/deps/octave32/
|
||||
windows/deps/octave64/
|
||||
windows/deps/sources32/
|
||||
windows/deps/sources64/
|
||||
windows/deps/tarballs/
|
||||
windows/exe/
|
||||
windows/7z/
|
||||
windows/zip/
|
||||
|
||||
# MacOS stuff
|
||||
.DS_Store
|
||||
macOS/pkg/
|
||||
macOS/deps/sources64/
|
||||
macOS/deps/tarballs/
|
||||
macOS/deps/lib64/
|
||||
# Created by the macOS package build script
|
||||
/macOS/deps/arm64/sources64/
|
||||
/macOS/deps/x86_64/sources64/
|
||||
/macOS/deps/tarballs/
|
||||
/macOS/deps/arm64/lib64/
|
||||
/macOS/deps/x86_64/lib64/
|
||||
build-doc
|
||||
|
||||
# Emacs stuff
|
||||
TAGS
|
||||
scripts/dynare.elc
|
||||
|
||||
# MS-Sbvar
|
||||
/contrib/ms-sbvar/*.prn
|
||||
/contrib/ms-sbvar/*.dat
|
||||
/contrib/ms-sbvar/sbvar_commandline
|
||||
/contrib/ms-sbvar/sbvar_init_file
|
||||
!/contrib/ms-sbvar/Makefile
|
||||
/tests/ms-sbvar/*.tmp
|
||||
|
||||
# Reporting
|
||||
*synctex.gz
|
||||
tests/reporting/tmpRepDir
|
||||
|
||||
# Julia Tests
|
||||
tests/julia/rbc/rbc*.jl
|
||||
|
||||
# Octave variables saved when Octave crashes
|
||||
octave-workspace
|
||||
|
||||
# VERSION generated file
|
||||
VERSION
|
||||
|
||||
matlab/supported_octave_version.m
|
||||
|
|
209
.gitlab-ci.yml
209
.gitlab-ci.yml
|
@ -1,83 +1,99 @@
|
|||
variables:
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
TERM: linux
|
||||
MATLAB_VERSION: R2022b
|
||||
OLD_MATLAB_VERSION: R2014a
|
||||
OCTAVE_VERSION: 7.3.0
|
||||
MATLAB_VERSION: R2023b
|
||||
OLD_MATLAB_VERSION: R2018b
|
||||
# To ensure that "false && true" fails, see https://gitlab.com/gitlab-org/gitlab-runner/-/issues/25394#note_412609647
|
||||
FF_ENABLE_BASH_EXIT_CODE_CHECK: 'true'
|
||||
|
||||
# The next stanza creates the version number used for the source tarball and the
|
||||
# binary packages. Here are the following possible cases:
|
||||
# - if VERSION was already set (when manually running a pipeline), use it
|
||||
# - if we are in the official Dynare repository:
|
||||
# + if on a tag: use the tag
|
||||
# + if on master: use 6-unstable-$TIMESTAMP-$COMMIT
|
||||
# + if on master: use 7-unstable-$TIMESTAMP-$COMMIT
|
||||
# + on another branch: use $BRANCH-$TIMESTAMP-$COMMIT
|
||||
# - if in a personal repository: use $USER-$TIMESTAMP-$COMMIT
|
||||
before_script:
|
||||
- '[[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]] && [[ -n $CI_COMMIT_TAG ]] && export VERSION=$CI_COMMIT_TAG'
|
||||
- '[[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]] && [[ $CI_COMMIT_REF_NAME == master ]] && export VERSION=6-unstable-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA'
|
||||
- '[[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]] && export VERSION=$CI_COMMIT_REF_NAME-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA'
|
||||
- '[[ -z $VERSION ]] && export VERSION=$CI_PROJECT_NAMESPACE-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA'
|
||||
- 'if [[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]] && [[ -n $CI_COMMIT_TAG ]]; then export VERSION=$CI_COMMIT_TAG; fi'
|
||||
- 'if [[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]] && [[ $CI_COMMIT_REF_NAME == master ]]; then export VERSION=7-unstable-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA; fi'
|
||||
- 'if [[ -z $VERSION ]] && [[ $CI_PROJECT_NAMESPACE == Dynare ]]; then export VERSION=$CI_COMMIT_REF_NAME-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA; fi'
|
||||
- 'if [[ -z $VERSION ]]; then export VERSION=$CI_PROJECT_NAMESPACE-$(date +%F-%H%M)-$CI_COMMIT_SHORT_SHA; fi'
|
||||
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
- pkg
|
||||
- sign
|
||||
- deploy
|
||||
|
||||
build_binaries:
|
||||
build_matlab:
|
||||
stage: build
|
||||
script:
|
||||
- autoreconf -si
|
||||
- ./configure --with-matlab=/usr/local/MATLAB/$MATLAB_VERSION --with-octave=/usr/local/octave/$OCTAVE_VERSION PACKAGE_VERSION=$VERSION PACKAGE_STRING="dynare $VERSION"
|
||||
- make -j $(nproc) LN_S="cp -p"
|
||||
- meson setup -Dbuild_for=matlab -Dmatlab_path=/opt/MATLAB/$MATLAB_VERSION -Dbuildtype=release build-matlab
|
||||
- meson compile -v -C build-matlab
|
||||
artifacts:
|
||||
paths:
|
||||
- preprocessor/dynare-preprocessor
|
||||
- mex/octave/
|
||||
- mex/matlab/
|
||||
- build-matlab/
|
||||
expire_in: 3 days
|
||||
|
||||
build_octave:
|
||||
stage: build
|
||||
script:
|
||||
- meson setup -Dbuild_for=octave -Dbuildtype=release build-octave
|
||||
- meson compile -v -C build-octave
|
||||
artifacts:
|
||||
paths:
|
||||
- build-octave/
|
||||
expire_in: 3 days
|
||||
|
||||
build_doc:
|
||||
stage: build
|
||||
script:
|
||||
- autoreconf -si
|
||||
- ./configure --disable-matlab --disable-octave PACKAGE_VERSION=$VERSION PACKAGE_STRING="dynare $VERSION"
|
||||
- make -j $(nproc) pdf html
|
||||
- meson rewrite kwargs set project / version "$VERSION"
|
||||
# Use a local copy of MathJax to avoid using CDN (which are a privacy issue)
|
||||
# NB: Debian 12 “Bookworm” has MathJax 2. The following needs to be updated
|
||||
# when Debian moves to MathJax 3.
|
||||
- meson setup -Dbuild_for=octave -Dmathjax_path=mathjax/MathJax.js?config=TeX-AMS-MML_HTMLorMML build-doc
|
||||
- meson compile -v -C build-doc doc
|
||||
- cp -dR /usr/share/javascript/mathjax build-doc/dynare-manual.html/_static/
|
||||
artifacts:
|
||||
paths:
|
||||
- doc/manual/build/
|
||||
- doc/**/*.pdf
|
||||
- preprocessor/doc/*/*.pdf
|
||||
- build-doc/
|
||||
expire_in: 3 days
|
||||
|
||||
pkg_source:
|
||||
stage: pkg
|
||||
script:
|
||||
- rm doc/manual/source/_static/mathjax && sed -i "/^mathjax_path *=/d" doc/manual/source/conf.py
|
||||
- 'for f in configure.ac preprocessor/configure.ac mex/build/matlab/configure.ac mex/build/octave/configure.ac; do sed -i "s/^AC_INIT(\[\(.*\)\],\s*\[\(.*\)\])/AC_INIT([\1], [$VERSION])/" $f; done'
|
||||
- autoreconf -si
|
||||
- ./configure --with-matlab=/usr/local/MATLAB/$MATLAB_VERSION --with-octave=/usr/local/octave/$OCTAVE_VERSION
|
||||
- make dist
|
||||
- meson rewrite kwargs set project / version "$VERSION"
|
||||
- git commit -a -m "Source for $VERSION"
|
||||
- meson setup -Dbuild_for=octave build-src
|
||||
- meson dist -C build-src --no-tests
|
||||
artifacts:
|
||||
paths:
|
||||
- dynare-*.tar.xz
|
||||
- build-src/meson-dist/dynare-*.tar.xz
|
||||
expire_in: 3 days
|
||||
needs: []
|
||||
|
||||
pkg_windows:
|
||||
stage: pkg
|
||||
script:
|
||||
- ln -s ~/tarballs windows/deps/
|
||||
- meson rewrite kwargs set project / version "$VERSION"
|
||||
- mkdir -p windows/deps/tarballs && cp /usr/lib/dynare-runner/matlab64-* windows/deps/tarballs/
|
||||
- make -C windows
|
||||
- rm windows/deps/tarballs/matlab64-* # No need to cache these files
|
||||
cache:
|
||||
key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||
paths:
|
||||
- windows/deps/sources64/
|
||||
- windows/deps/lib64/
|
||||
# We do not cache lib64-msys2, mingw64, octave64 and
|
||||
# matlab64, because those are simply extracted from a tarball. It
|
||||
# would be a waste of space and of (re-compression) time.
|
||||
- key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||
paths:
|
||||
- windows/deps/sources64/
|
||||
- windows/deps/lib64/
|
||||
# We do not cache lib64-msys2, mingw64, octave64 and
|
||||
# matlab64, because those are simply extracted from a tarball. It
|
||||
# would be a waste of space and of (re-compression) time.
|
||||
- key: $CI_JOB_NAME
|
||||
# This cache is shared between all branches, to save space
|
||||
paths:
|
||||
- windows/deps/tarballs/
|
||||
artifacts:
|
||||
paths:
|
||||
- windows/exe/*
|
||||
|
@ -86,16 +102,18 @@ pkg_windows:
|
|||
expire_in: 3 days
|
||||
needs: [ "build_doc" ]
|
||||
|
||||
pkg_macOS:
|
||||
pkg_macOS_x86_64:
|
||||
stage: pkg
|
||||
script:
|
||||
- ln -s ~/tarballs macOS/deps/
|
||||
- make -C macOS
|
||||
# Enforce the arm64 meson for rewrite, as a workaround to https://github.com/mesonbuild/meson/issues/12282
|
||||
- env PATH="/opt/homebrew/bin:$PATH" meson rewrite kwargs set project / version "$VERSION"
|
||||
- ln -s ~/tarballs macOS/deps/x86_64
|
||||
- make -C macOS build-x86_64
|
||||
cache:
|
||||
key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||
paths:
|
||||
- macOS/deps/sources64/
|
||||
- macOS/deps/lib64/
|
||||
- macOS/deps/x86_64/sources64/
|
||||
- macOS/deps/x86_64/lib64/
|
||||
tags:
|
||||
- macOS
|
||||
artifacts:
|
||||
|
@ -104,32 +122,46 @@ pkg_macOS:
|
|||
expire_in: 3 days
|
||||
needs: [ "build_doc" ]
|
||||
|
||||
.test_matlab_template:
|
||||
stage: test
|
||||
pkg_macOS_arm64:
|
||||
stage: pkg
|
||||
script:
|
||||
# Enforce the arm64 meson for rewrite, as a workaround to https://github.com/mesonbuild/meson/issues/12282
|
||||
- env PATH="/opt/homebrew/bin:$PATH" meson rewrite kwargs set project / version "$VERSION"
|
||||
- ln -s ~/tarballs macOS/deps/arm64
|
||||
- make -C macOS build-arm64
|
||||
cache:
|
||||
key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||
paths:
|
||||
- macOS/deps/arm64/sources64/
|
||||
- macOS/deps/arm64/lib64/
|
||||
tags:
|
||||
- macOS
|
||||
artifacts:
|
||||
paths:
|
||||
- tests/**/*.m.log
|
||||
- tests/**/*.m.trs
|
||||
- tests/**/*.jnl
|
||||
- tests/run_test_matlab_output.txt
|
||||
when: always
|
||||
needs: [ "build_binaries" ]
|
||||
- macOS/pkg/*
|
||||
expire_in: 3 days
|
||||
needs: [ "build_doc" ]
|
||||
|
||||
test_matlab:
|
||||
extends: .test_matlab_template
|
||||
stage: test
|
||||
script:
|
||||
- autoreconf -si
|
||||
- ./configure --disable-octave --with-matlab=/usr/local/MATLAB/$MATLAB_VERSION
|
||||
- make -j $(($(nproc) * 3 / 4)) -C tests check-matlab
|
||||
- meson test -C build-matlab --no-rebuild --num-processes $(($(nproc) * 3 / 4))
|
||||
artifacts:
|
||||
paths:
|
||||
- build-matlab/meson-logs/testlog.txt
|
||||
when: always
|
||||
needs: [ "build_matlab" ]
|
||||
|
||||
test_old_matlab:
|
||||
extends: .test_matlab_template
|
||||
stage: test
|
||||
script:
|
||||
- autoreconf -si
|
||||
- ./configure --disable-octave --with-matlab=/usr/local/MATLAB/$OLD_MATLAB_VERSION
|
||||
- make -C mex/build/matlab clean
|
||||
- make -j $(nproc) -C mex/build/matlab
|
||||
- make -j $(($(nproc) * 3 / 4)) -C tests check-matlab
|
||||
- meson setup -Dbuild_for=matlab -Dmatlab_path=/opt/MATLAB/$OLD_MATLAB_VERSION -Dbuildtype=release build-old-matlab
|
||||
- meson compile -v -C build-old-matlab
|
||||
- meson test -C build-old-matlab --num-processes $(($(nproc) * 3 / 4))
|
||||
artifacts:
|
||||
paths:
|
||||
- build-old-matlab/meson-logs/testlog.txt
|
||||
when: always
|
||||
when: manual
|
||||
|
||||
test_octave:
|
||||
|
@ -137,22 +169,41 @@ test_octave:
|
|||
variables:
|
||||
OPENBLAS_NUM_THREADS: 1
|
||||
script:
|
||||
- autoreconf -si
|
||||
- ./configure --disable-matlab --with-octave=/usr/local/octave/$OCTAVE_VERSION
|
||||
- make -j $(nproc) -C tests check-octave
|
||||
- meson test -C build-octave --no-rebuild
|
||||
artifacts:
|
||||
paths:
|
||||
- tests/**/*.o.log
|
||||
- tests/**/*.o.trs
|
||||
- tests/**/*.jnl
|
||||
- tests/run_test_octave_output.txt
|
||||
- build-octave/meson-logs/testlog.txt
|
||||
when: always
|
||||
needs: [ "build_binaries" ]
|
||||
needs: [ "build_octave" ]
|
||||
when: manual
|
||||
|
||||
# For the deploy jobs, we don’t use the “needs” keyword, since we don’t want
|
||||
# those jobs to start before the “test” and “pkg” stages have succeeded. Hence
|
||||
# we stick to the “dependencies” keyword.
|
||||
test_clang_format:
|
||||
stage: test
|
||||
script:
|
||||
- meson setup -Dbuild_for=octave build-clang-format
|
||||
- ninja -C build-clang-format clang-format-check
|
||||
needs: []
|
||||
|
||||
# For the sign and deploy jobs, we don’t use the “needs” keyword, since we
|
||||
# don’t want those jobs to start before the “test” and “pkg” stages have
|
||||
# succeeded. Hence we stick to the “dependencies” keyword.
|
||||
|
||||
sign_windows:
|
||||
stage: sign
|
||||
rules:
|
||||
- if: '$CI_PROJECT_NAMESPACE == "Dynare" && $CI_COMMIT_REF_NAME == "master"'
|
||||
when: on_success
|
||||
- when: never
|
||||
tags:
|
||||
- sign
|
||||
dependencies:
|
||||
- pkg_windows
|
||||
script:
|
||||
- f=(windows/exe/*) && mkdir -p windows/exe-signed/ && osslsigncode sign -pkcs11module /usr/lib/x86_64-linux-gnu/libykcs11.so.2 -key "pkcs11:id=%01;type=private;pin-value=$YUBIKEY_PIN" -certs ~/cepremap-code-signing-comodo-sectigo.pem -n Dynare -i https://www.dynare.org -t http://timestamp.comodoca.com -in ${f[0]} -out windows/exe-signed/${f[0]##*/}
|
||||
artifacts:
|
||||
paths:
|
||||
- windows/exe-signed/*
|
||||
expire_in: 3 days
|
||||
|
||||
deploy_manual_unstable:
|
||||
stage: deploy
|
||||
|
@ -161,13 +212,11 @@ deploy_manual_unstable:
|
|||
when: on_success
|
||||
- when: never
|
||||
tags:
|
||||
- restricted
|
||||
- deploy
|
||||
dependencies:
|
||||
- build_doc
|
||||
script:
|
||||
- rm -rf doc/manual/build/html/_static/mathjax
|
||||
- ln -s /usr/share/javascript/mathjax doc/manual/build/html/_static/mathjax
|
||||
- rsync --recursive --links --delete doc/manual/build/html/ /srv/www.dynare.org/manual-unstable/
|
||||
- rsync --recursive --links --delete build-doc/dynare-manual.html/ /srv/www.dynare.org/manual-unstable/
|
||||
|
||||
deploy_snapshot_unstable:
|
||||
stage: deploy
|
||||
|
@ -176,17 +225,19 @@ deploy_snapshot_unstable:
|
|||
when: on_success
|
||||
- when: never
|
||||
tags:
|
||||
- restricted
|
||||
- deploy
|
||||
dependencies:
|
||||
- pkg_source
|
||||
- pkg_windows
|
||||
- pkg_macOS
|
||||
- sign_windows
|
||||
- pkg_macOS_arm64
|
||||
- pkg_macOS_x86_64
|
||||
script:
|
||||
- f=(windows/exe/*) && osslsigncode sign -pkcs12 ~/cepremap-comodo-sectigo-code-signing.p12 -n Dynare -i https://www.dynare.org -t http://timestamp.comodoca.com -in ${f[0]} -out ${f[0]}.signed && mv ${f[0]}.signed ${f[0]}
|
||||
- cp *.tar.xz /srv/www.dynare.org/snapshot/source/ && ln -sf *.tar.xz /srv/www.dynare.org/snapshot/source/dynare-latest-src.tar.xz
|
||||
- f=(windows/exe/*) && cp ${f[0]} /srv/www.dynare.org/snapshot/windows/ && ln -sf ${f[0]##*/} /srv/www.dynare.org/snapshot/windows/dynare-latest-win.exe
|
||||
- cp build-src/meson-dist/*.tar.xz /srv/www.dynare.org/snapshot/source/ && ln -sf *.tar.xz /srv/www.dynare.org/snapshot/source/dynare-latest-src.tar.xz
|
||||
- f=(windows/exe-signed/*) && cp ${f[0]} /srv/www.dynare.org/snapshot/windows/ && ln -sf ${f[0]##*/} /srv/www.dynare.org/snapshot/windows/dynare-latest-win.exe
|
||||
- f=(windows/7z/*) && cp ${f[0]} /srv/www.dynare.org/snapshot/windows-7z/ && ln -sf ${f[0]##*/} /srv/www.dynare.org/snapshot/windows-7z/dynare-latest-win.7z
|
||||
- f=(windows/zip/*) && cp ${f[0]} /srv/www.dynare.org/snapshot/windows-zip/ && ln -sf ${f[0]##*/} /srv/www.dynare.org/snapshot/windows-zip/dynare-latest-win.zip
|
||||
- f=(macOS/pkg/*) && cp ${f[0]} /srv/www.dynare.org/snapshot/macos/ && ln -sf ${f[0]##*/} /srv/www.dynare.org/snapshot/macos/dynare-latest-macos.pkg
|
||||
- f=(macOS/pkg/*-arm64.pkg) && cp ${f[0]} /srv/www.dynare.org/snapshot/macos-arm64/ && ln -sf ${f[0]##*/} /srv/www.dynare.org/snapshot/macos-arm64/dynare-latest-macos-arm64.pkg
|
||||
- f=(macOS/pkg/*-x86_64.pkg) && cp ${f[0]} /srv/www.dynare.org/snapshot/macos-x86_64/ && ln -sf ${f[0]##*/} /srv/www.dynare.org/snapshot/macos-x86_64/dynare-latest-macos-x86_64.pkg
|
||||
- ~/update-snapshot-list.sh
|
||||
- curl -X POST -F token="$WEBSITE_PIPELINE_TRIGGER_TOKEN" -F ref=master https://git.dynare.org/api/v4/projects/40/trigger/pipeline
|
||||
|
|
|
@ -10,19 +10,10 @@
|
|||
[submodule "matlab/utilities/tests"]
|
||||
path = matlab/utilities/tests
|
||||
url = ../../Dynare/m-unit-tests.git
|
||||
[submodule "matlab/particles"]
|
||||
path = matlab/particles
|
||||
url = ../../Dynare/particles.git
|
||||
[submodule "matlab/modules/dseries"]
|
||||
path = matlab/modules/dseries
|
||||
path = matlab/dseries
|
||||
url = ../../Dynare/dseries.git
|
||||
branch = master
|
||||
[submodule "matlab/modules/reporting"]
|
||||
path = matlab/modules/reporting
|
||||
url = ../../Dynare/reporting.git
|
||||
[submodule "contrib/jsonlab"]
|
||||
path = contrib/jsonlab
|
||||
url = https://github.com/fangq/jsonlab.git
|
||||
[submodule "preprocessor"]
|
||||
path = preprocessor
|
||||
url = ../../Dynare/preprocessor.git
|
||||
|
|
|
@ -2,31 +2,29 @@
|
|||
|
||||
## Introduction
|
||||
|
||||
Hello from the Dynare Team! We're happy you're on this page because hopefully that means you're thinking of getting directly involved with the Dynare project. Herein, we outline how you can contribute to Dynare. Please read this document all the way through before contributing.
|
||||
Hello from the Dynare Team! We’re happy you’re on this page because hopefully that means you’re thinking of getting directly involved with the Dynare project. Herein, we outline how you can contribute to Dynare. Please read this document all the way through before contributing.
|
||||
|
||||
Please follow the steps in the sections below in order. Note that, though we'd love for you to contribute code, you don't need to be a programmer to contribute to Dynare. You can report bugs, ask for enhancements, fix typos in the manual, contribute tests to the test suite, or do something we haven't thought of yet!
|
||||
Please follow the steps in the sections below in order. Note that, though we’d love for you to contribute code, you don’t need to be a programmer to contribute to Dynare. You can report bugs, ask for enhancements, fix typos in the manual, contribute tests to the test suite, or do something we haven’t thought of yet!
|
||||
|
||||
If something is not clear, don't hesitate to ask if you can't find the answer online. You can contact us directly at [dev@dynare.org](mailto:dev@dynare.org).
|
||||
If something is not clear, don’t hesitate to ask if you can’t find the answer online. You can contact us directly at [dev@dynare.org](mailto:dev@dynare.org).
|
||||
|
||||
Please note that the repositories under the purview of this page are:
|
||||
|
||||
* [Dynare](https://git.dynare.org/Dynare/dynare)
|
||||
* [Preprocessor](https://git.dynare.org/Dynare/preprocessor)
|
||||
* [Particles](https://git.dynare.org/Dynare/particles)
|
||||
* [Dseries](https://git.dynare.org/Dynare/dseries)
|
||||
* [Reporting](https://git.dynare.org/Dynare/reporting)
|
||||
* [Testsuite](https://git.dynare.org/Dynare/testsuite)
|
||||
* [M-unit-tests](https://git.dynare.org/Dynare/m-unit-tests)
|
||||
|
||||
## Making your Intentions Known
|
||||
|
||||
Before making changes to the codebase, it'd be helpful if you communicated your intentions with us. This will avoid double work and ensure that you don't contribute code that won't be included in Dynare for one reason or another.
|
||||
Before making changes to the codebase, it’d be helpful if you communicated your intentions with us. This will avoid double work and ensure that you don’t contribute code that won’t be included in Dynare for one reason or another.
|
||||
|
||||
### Create your account on our GitLab instance
|
||||
|
||||
All the development of Dynare happens in [GitLab](https://about.gitlab.com/), which is an integrated environment for storing code under git, keeping track of issues and milestones, and perform testing. The Dynare Team has its own instance of GitLab.
|
||||
|
||||
In order to work with us, you need to create your account on our GitLab instance on the [register page](https://git.dynare.org/users/sign_in).
|
||||
In order to work with us, you need to create your account on our GitLab instance on the [register page](https://git.dynare.org/users/sign_in). Note that account requests are manually validated, so be prepared to wait for a couple of hours or days before your account is created; if your account request is rejected, do not hesitate to contact us directly.
|
||||
|
||||
You will also need to register your SSH key in your GitLab profile if you want to contribute code.
|
||||
|
||||
|
@ -36,7 +34,7 @@ You can report bugs in both the stable and unstable versions of Dynare. Before r
|
|||
|
||||
To report a bug in Dynare, simply open a Gitlab issue in the repository where the bug resides. For example, to report a bug in Dynare itself, go to the [Dynare repository issue page](https://git.dynare.org/Dynare/dynare/issues) and click on "New Issue."
|
||||
|
||||
The minimal information to add is a subject and a description of the steps needed to reproduce the bug. However, the most helpful description would also provide the code to reproduce the bug (often times a `.mod` file). The most helpful `.mod` file is a minimal, quick-running example that reproduces the bug, but we'll take anything that will help us squash a bug.
|
||||
The minimal information to add is a subject and a description of the steps needed to reproduce the bug. However, the most helpful description would also provide the code to reproduce the bug (often times a `.mod` file). The most helpful `.mod` file is a minimal, quick-running example that reproduces the bug, but we’ll take anything that will help us squash a bug.
|
||||
|
||||
To include short amounts of code, please paste it into the description box, using the appropriate [GitLab Flavored Markdown](https://docs.gitlab.com/ee/user/markdown.html) code. For larger amounds of code like `.mod` files, please create a new [GitLab snippet](https://git.dynare.org/dashboard/snippets) and provide the link in the description box.
|
||||
|
||||
|
@ -44,13 +42,13 @@ To include short amounts of code, please paste it into the description box, usin
|
|||
|
||||
Issues are not only used to report bugs. They are also used to ask for improvements to the codebase or new features to Dynare in general. Please be descriptive when asking for improvements or new features. Links or references to papers or detailed examples are helpful.
|
||||
|
||||
Though our development priorities lay with those who finance Dynare and with what we think may most benefit the Dynare community, this does not mean we are closed to outside ideas for enhancements. On the contrary: we invite them! Moreover, if you are willing to program the enhancement you want, the odds of it being included in Dynare are much higher than if you needed us to do it. That said, it is best to create an issue with an enhancement idea **before** beginning the work. As stated above, this is important to avoid duplication of work and also because we wouldn't want you to take the time to work on something that would not end up being included in Dynare.
|
||||
Though our development priorities lay with those who finance Dynare and with what we think may most benefit the Dynare community, this does not mean we are closed to outside ideas for enhancements. On the contrary: we invite them! Moreover, if you are willing to program the enhancement you want, the odds of it being included in Dynare are much higher than if you needed us to do it. That said, it is best to create an issue with an enhancement idea **before** beginning the work. As stated above, this is important to avoid duplication of work and also because we wouldn’t want you to take the time to work on something that would not end up being included in Dynare.
|
||||
|
||||
## Get to Coding!
|
||||
|
||||
So, now you've reported the bug or asked for an enhancemnt by creating a GitLab issue. That's already a great help. Thank you!
|
||||
So, now you’ve reported the bug or asked for an enhancemnt by creating a GitLab issue. That’s already a great help. Thank you!
|
||||
|
||||
Now, if you want to go the extra mile, you'll volunteer to contribute code to fix the GitLab issue you created above. Once we've agreed that you'll do it, please do the following:
|
||||
Now, if you want to go the extra mile, you’ll volunteer to contribute code to fix the GitLab issue you created above. Once we’ve agreed that you’ll do it, please do the following:
|
||||
|
||||
1. Clone the Dynare repository:
|
||||
* `git clone --recurse-submodules https://git.dynare.org/Dynare/dynare.git`
|
||||
|
@ -63,7 +61,7 @@ Now, if you want to go the extra mile, you'll volunteer to contribute code to fi
|
|||
1. Do your work, all the while respecting the [Dynare Coding Guidelines](https://git.dynare.org/Dynare/dynare/-/wikis/CodingGuidelines)
|
||||
1. You may also want to have a look at the [coding resources](https://git.dynare.org/Dynare/dynare/-/wikis/CodingResources)
|
||||
|
||||
As you work, your forked repository will likely fall out of sync with the main Dynare repository as we'll be working in parallel. No matter. Follow these steps to ensure your changes will be merge-able when they're done:
|
||||
As you work, your forked repository will likely fall out of sync with the main Dynare repository as we’ll be working in parallel. No matter. Follow these steps to ensure your changes will be merge-able when they’re done:
|
||||
|
||||
1. Get the changes from the main Dynare repository:
|
||||
* `git checkout master`
|
||||
|
@ -74,7 +72,7 @@ As you work, your forked repository will likely fall out of sync with the main D
|
|||
* `git rebase origin/master`
|
||||
* This last command may cause a conflict. It is up to you to resolve this conflict.
|
||||
|
||||
Once you've made the changes necessary to fix the bug or add an enhancement, ensure that it has been rebased on the master branch (following the steps above), commit it, push it to your forked Dynare repository, and create a pull request:
|
||||
Once you’ve made the changes necessary to fix the bug or add an enhancement, ensure that it has been rebased on the master branch (following the steps above), commit it, push it to your forked Dynare repository, and create a pull request:
|
||||
|
||||
1. Get the latest changes from Dynare and rebase your branch on top of them (see above)
|
||||
1. Commit your changes:
|
||||
|
@ -86,17 +84,17 @@ Once you've made the changes necessary to fix the bug or add an enhancement, ens
|
|||
|
||||
## Tests
|
||||
|
||||
The Dynare testsuite runs every time a commit is pushed, either in the official repository or in your personal repository, through [GitLab Continuous Integration](https://docs.gitlab.com/ee/ci/). It's how we quickly catch bugs that may have been introduced by changes made.
|
||||
The Dynare testsuite runs every time a commit is pushed, either in the official repository or in your personal repository, through [GitLab Continuous Integration](https://docs.gitlab.com/ee/ci/). It’s how we quickly catch bugs that may have been introduced by changes made.
|
||||
|
||||
The output from the latest run of the test suite can be found in the `test_matlab` job associated to the [latest pipeline](https://git.dynare.org/Dynare/dynare/pipelines). This is also a good place to start fixing bugs. If you see a `.mod` file that doesn't run in the test suite and think you can fix it, create an issue and once you have the go ahead, go for it!
|
||||
The output from the latest run of the test suite can be found in the `test_matlab` job associated to the [latest pipeline](https://git.dynare.org/Dynare/dynare/pipelines). This is also a good place to start fixing bugs. If you see a `.mod` file that doesn’t run in the test suite and think you can fix it, create an issue and once you have the go ahead, go for it!
|
||||
|
||||
### Integration tests
|
||||
|
||||
It's useful to contribute `.mod` files that test some aspect of Dynare that is not currently tested. A `.mod` file that runs into a bug is perfect. As the test suite currently takes several hours to run, we prefer you modify a current test to also create the bug you've found. If you can't do that, please add a new test that runs as quickly as possible. It will contain only those commands necessary to create the bug, nothing more. To contribute a test, after having made an issue and cloned and forked the repository as described above, do the following:
|
||||
It’s useful to contribute `.mod` files that test some aspect of Dynare that is not currently tested. A `.mod` file that runs into a bug is perfect. As the test suite currently takes several hours to run, we prefer you modify a current test to also create the bug you’ve found. If you can’t do that, please add a new test that runs as quickly as possible. It will contain only those commands necessary to create the bug, nothing more. To contribute a test, after having made an issue and cloned and forked the repository as described above, do the following:
|
||||
|
||||
1. Modify the `MODFILES` variable in `tests/Makefile.am` with a line containing your test file name
|
||||
1. If any ancillary files are needed to run your test, please include them in the `EXTRA_DIST` variable in `tests/Makefile.am`
|
||||
1. Add and commit your test file and `tests/Makefile.am` as described above
|
||||
1. Modify the `mod_and_m_tests` variable in `meson.build` with a entry containing your test file name
|
||||
1. If any ancillary files are needed to run your test, please include them in the `'extra'` field
|
||||
1. Add and commit your test file and `meson.build` as described above
|
||||
1. Push and create a pull request as described above
|
||||
|
||||
### Unit tests
|
||||
|
|
68
Makefile.am
68
Makefile.am
|
@ -1,68 +0,0 @@
|
|||
SUBDIRS = preprocessor doc tests mex/sources
|
||||
|
||||
if ENABLE_MATLAB
|
||||
SUBDIRS += mex/build/matlab
|
||||
endif
|
||||
if ENABLE_OCTAVE
|
||||
SUBDIRS += mex/build/octave
|
||||
endif
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
EXTRA_DIST = \
|
||||
matlab \
|
||||
dynare++ \
|
||||
contrib \
|
||||
NEWS.md \
|
||||
license.txt \
|
||||
README.md \
|
||||
COPYING \
|
||||
CONTRIBUTING.md \
|
||||
windows \
|
||||
macOS \
|
||||
examples \
|
||||
scripts \
|
||||
.dir-locals.el
|
||||
|
||||
all-local:
|
||||
# Create top-level preprocessor symlink needed by matlab/dynare.m (when Dynare is run
|
||||
# from the locally-built copy)
|
||||
$(LN_S) -f $(abs_builddir)/preprocessor/src/dynare-preprocessor$(EXEEXT) $(abs_builddir)/preprocessor/dynare-preprocessor$(EXEEXT)
|
||||
# Create backward-compatibility symlink for old location of preprocessor
|
||||
$(MKDIR_P) matlab/preprocessor64/
|
||||
$(LN_S) -f $(abs_builddir)/preprocessor/src/dynare-preprocessor$(EXEEXT) $(abs_srcdir)/matlab/preprocessor64/dynare_m$(EXEEXT)
|
||||
|
||||
clean-local:
|
||||
rm -f preprocessor/dynare-preprocessor$(EXEEXT)
|
||||
rm -rf matlab/preprocessor64/
|
||||
|
||||
dist-hook:
|
||||
rm -rf `find $(distdir)/matlab $(distdir)/examples -name *~`
|
||||
rm -f $(distdir)/matlab/dynare_version.m
|
||||
rm -rf $(distdir)/matlab/preprocessor64/
|
||||
$(MKDIR_P) $(distdir)/mex/matlab $(distdir)/mex/octave
|
||||
rm -rf `find $(distdir) -name '.git*'`
|
||||
|
||||
install-exec-local:
|
||||
$(MKDIR_P) $(DESTDIR)$(pkglibdir)/preprocessor
|
||||
# The following will break under Windows, but we don’t use the install rule there
|
||||
$(LN_S) -f $(bindir)/dynare-preprocessor$(EXEEXT) $(DESTDIR)$(pkglibdir)/preprocessor/dynare-preprocessor$(EXEEXT)
|
||||
$(MKDIR_P) $(DESTDIR)$(pkglibdir)/contrib/ms-sbvar/TZcode
|
||||
cp -r contrib/ms-sbvar/TZcode/MatlabFiles $(DESTDIR)$(pkglibdir)/contrib/ms-sbvar/TZcode
|
||||
$(MKDIR_P) $(DESTDIR)$(pkglibdir)/contrib/jsonlab
|
||||
cp -r contrib/jsonlab $(DESTDIR)$(pkglibdir)/contrib/jsonlab
|
||||
cp -r examples $(DESTDIR)$(pkglibdir)
|
||||
cp -r matlab $(DESTDIR)$(pkglibdir)
|
||||
find $(DESTDIR)$(pkglibdir) -name LICENSE.md -delete
|
||||
# Recreate backward-compatibility symlink
|
||||
rm -f $(DESTDIR)$(pkglibdir)/matlab/preprocessor64/dynare_m$(EXEEXT)
|
||||
$(LN_S) -f $(bindir)/dynare-preprocessor$(EXEEXT) $(DESTDIR)$(pkglibdir)/matlab/preprocessor64/dynare_m$(EXEEXT)
|
||||
# We don’t fail over doc install rules, since the user may deliberately not have compiled them
|
||||
# (e.g. with the “nodoc” option under Debian)
|
||||
$(MKDIR_P) $(DESTDIR)$(docdir)
|
||||
-cp doc/*.pdf doc/gsa/gsa.pdf doc/parallel/parallel.pdf doc/dseries-and-reporting/dseriesReporting.pdf preprocessor/doc/preprocessor/preprocessor.pdf preprocessor/doc/macroprocessor/macroprocessor.pdf doc/manual/build/latex/dynare-manual.pdf $(DESTDIR)$(docdir)
|
||||
-cp -r doc/manual/build/html $(DESTDIR)$(docdir)/dynare-manual.html
|
||||
|
||||
uninstall-local:
|
||||
rm -rf $(DESTDIR)$(pkglibdir)
|
||||
rm -rf $(DESTDIR)$(docdir)
|
519
NEWS.md
519
NEWS.md
|
@ -1,3 +1,521 @@
|
|||
Announcement for Dynare 6.0 (on 2024-02-02)
|
||||
===========================================
|
||||
|
||||
We are pleased to announce the release of Dynare 6.0.
|
||||
|
||||
This major release adds new features and fixes various bugs.
|
||||
|
||||
The Windows, macOS, MATLAB Online and source packages are already available for
|
||||
download at [the Dynare website](https://www.dynare.org/download/).
|
||||
|
||||
This release is compatible with MATLAB versions ranging from 9.5 (R2018b) to
|
||||
23.2 (R2023b), and with GNU Octave versions ranging from 7.1.0 to 8.4.0 (NB:
|
||||
the Windows package requires version 8.4.0 specifically).
|
||||
|
||||
Major user-visible changes
|
||||
--------------------------
|
||||
|
||||
- The Sequential Monte Carlo sampler as described by Herbst and Schorfheide
|
||||
(2014) is now available under value `hssmc` for option
|
||||
`posterior_sampling_method`.
|
||||
|
||||
- New routines for perfect foresight simulation with expectation errors. In
|
||||
such a scenario, agents make expectation errors in that the path they had
|
||||
anticipated in period 1 is not realized exactly. More precisely, in some
|
||||
simulation periods, they may receive new information that makes them revise
|
||||
their anticipation for the path of future shocks. Also, under this scenario,
|
||||
it is assumed that agents behave as under perfect foresight, *i.e.* they
|
||||
make their decisions as if there were no uncertainty and they knew exactly
|
||||
the path of future shocks; the new information that they may receive comes
|
||||
as a total surprise to them. Available under new
|
||||
`perfect_foresight_with_expectation_errors_setup` and
|
||||
`perfect_foresight_with_expectation_errors_solver` commands, and
|
||||
`shocks(learnt_in=…)`, `mshocks(learnt_in=…)` and `endval(learnt_in=…)`
|
||||
blocks.
|
||||
|
||||
- New routines for IRF matching with stochastic simulations:
|
||||
|
||||
- Both frequentist (as in Christiano, Eichenbaum, and Evans, 2005) and
|
||||
Bayesian (as in Christiano, Trabandt, and Walentin, 2010) IRF matching
|
||||
approaches are implemented. The core idea of IRF matching is to treat
|
||||
empirical impulse responses (*e.g.* given from an SVAR or local projection
|
||||
estimation) as data and select model parameters that align the model’s
|
||||
IRFs closely with their empirical counterparts.
|
||||
|
||||
- Available under option `mom_method = irf_matching` option to the
|
||||
`method_of_moments` command.
|
||||
|
||||
- New blocks `matched_irfs` and `matched_irfs_weights` for specifying the
|
||||
values and weights of the empirical impulse response functions.
|
||||
|
||||
- Pruning à la Andreasen et al. (2018) is now available at an arbitrary
|
||||
approximation order when performing stochastic simulations with
|
||||
`stoch_simul`, and at 3rd order when performing particle filtering.
|
||||
|
||||
- New `log` option to the `var` statement. In addition to the endogenous
|
||||
variable(s) thus declared, this option also triggers the creation of
|
||||
auxiliary variable(s) equal to the log of the corresponding endogenous
|
||||
variable(s). For example, given a `var(log) y;` statement, two endogenous
|
||||
will be created (`y` and `LOG_y`), and an auxiliary equation linking the two
|
||||
will also be added (equal to `y = exp(LOG_y);`). Moreover, every occurrence
|
||||
of `y` in the model will be replaced by `exp(LOG_y)`. This option is, for
|
||||
example, useful for performing a loglinear approximation of some variable(s)
|
||||
in the context of a first-order stochastic approximation; or for ensuring
|
||||
that the variable(s) stay(s) in the definition domain of the function
|
||||
defining the steady state or the dynamic residuals when the nonlinear solver
|
||||
is used.
|
||||
|
||||
- New model editing features
|
||||
|
||||
- Multiple `model` blocks are now supported (this was already working but
|
||||
not explicitly documented).
|
||||
|
||||
- Multiple `estimated_params` blocks now concatenate their contents (instead
|
||||
of overwriting previous ones, which was the former undocumented behavior);
|
||||
an `overwrite` option has been added to provide the old behavior.
|
||||
|
||||
- New `model_options` statement to set model options in a global fashion.
|
||||
|
||||
- New `model_remove` command to remove equations.
|
||||
|
||||
- New `model_replace` block to replace equations.
|
||||
|
||||
- New `var_remove` command to remove variables (or parameters).
|
||||
|
||||
- New `estimated_params_remove` block to remove estimated parameters.
|
||||
|
||||
- Stochastic simulations
|
||||
|
||||
- Performance improvements for simulation of the solution under perturbation
|
||||
and for particle filtering at higher order (⩾ 3).
|
||||
|
||||
- Performance improvement for the first order perturbation solution using
|
||||
either cycle reduction (`dr=cycle_reduction` option) or logarithmic
|
||||
reduction (`dr=logarithmic_reduction`).
|
||||
|
||||
- New `nomodelsummary` option to the `stoch_simul` command, to suppress the
|
||||
printing of the model summary and the covariance of the exogenous shocks.
|
||||
|
||||
- Estimation
|
||||
|
||||
- A truncated normal distribution can now be specified as a prior, using the
|
||||
3rd and 4th parameters of the `estimated_params` block as the bounds.
|
||||
|
||||
- New `conditional_likelihood` option to the `estimation` command. When the
|
||||
option is set, instead of using the Kalman filter to evaluate the
|
||||
likelihood, Dynare will evaluate the conditional likelihood based on the
|
||||
first-order reduced form of the model by assuming that the initial state
|
||||
vector is at its steady state.
|
||||
|
||||
- New `additional_optimizer_steps` option to the `estimation` command to
|
||||
trigger the sequential execution of several optimizers when looking for
|
||||
the posterior mode.
|
||||
|
||||
- The `generate_trace_plots` command now allows comparing multiple chains.
|
||||
|
||||
- The Geweke and Raftery-Lewis convergence diagnostics will now also be
|
||||
displayed when `mh_nblocks>1`.
|
||||
|
||||
- New `robust`, `TolGstep`, and `TolGstepRel` options to the optimizer
|
||||
available under `mode_compute=5` (“newrat”).
|
||||
|
||||
- New `brooks_gelman_plotrows` option to the `estimation` command for
|
||||
controlling the number of parameters to depict along the rows of the
|
||||
figures depicting the Brooks and Gelman (1998) convergence diagnostics.
|
||||
|
||||
- New `mh_init_scale_factor` option to the `estimation` command tor govern
|
||||
the overdispersion of the starting draws when initializing several Monte
|
||||
Carlo Markov Chains. This option supersedes the `mh_init_scale` option,
|
||||
which is now deprecated.
|
||||
|
||||
- Steady state computation
|
||||
|
||||
- Steady state computation now accounts for occasionally-binding constraints
|
||||
of mixed-complementarity problems (as defined by `mcp` tags).
|
||||
|
||||
- New `tolx` option to the `steady` command for governing the termination
|
||||
based on the step tolerance.
|
||||
|
||||
- New `fsolve_options` option to the `steady` command for passing options to
|
||||
`fsolve` (in conjunction with the `solve_algo=0` option).
|
||||
|
||||
- New option `from_initval_to_endval` option to the `homotopy_setup` block,
|
||||
for easily computing homotopy from initial to terminal steady state (when
|
||||
the former is already computed).
|
||||
|
||||
- New `non_zero` option to `resid` command to restrict display to non-zero
|
||||
residuals.
|
||||
|
||||
- Perfect foresight
|
||||
|
||||
- Significant performance improvement of the `stack_solve_algo=1` option to
|
||||
the `perfect_foresight_solver` command (Laffargue-Boucekkine-Juillard
|
||||
algorithm) when used in conjunction with options `block` and/or `bytecode`
|
||||
of the `model` block.
|
||||
|
||||
- New `relative_to_initval` option to the `mshocks` block, to use the
|
||||
initial steady state as a basis for the multiplication when there is an
|
||||
`endval` block.
|
||||
|
||||
- New `static_mfs` option to the `model` block (and to the `model_options`
|
||||
command), for controlling the minimum feedback set computation for the
|
||||
static model. It defaults to `0` (corresponding to the behavior in Dynare
|
||||
version 5).
|
||||
|
||||
- Various improvements to homotopy
|
||||
|
||||
- New `endval_steady` option to the `perfect_foresight_setup` command for
|
||||
computing the terminal steady state at the same time as the transitory
|
||||
dynamics (and new options `steady_solve_algo`, `steady_tolf`,
|
||||
`steady_tolx`, `steady_maxit` and `steady_markowitz` for controlling the
|
||||
steady state nonlinear solver).
|
||||
|
||||
- New `homotopy_linearization_fallback` and
|
||||
`homotopy_marginal_linearization_fallback` options to the
|
||||
`perfect_foresight_solver` command to get an approximate solution when
|
||||
homotopy fails to go to 100%.
|
||||
|
||||
- New `homotopy_initial_step_size`, `homotopy_min_step_size`,
|
||||
`homotopy_step_size_increase_success_count` and
|
||||
`homotopy_max_completion_share` options to the
|
||||
`perfect_foresight_solver` command to fine tune the homotopy behavior.
|
||||
|
||||
- Purely backward, forward and static models are now supported by the
|
||||
homotopy procedure.
|
||||
|
||||
- The `stack_solve_algo=1` and `stack_solve_algo=6` options of the
|
||||
`perfect_foresight_solver` command were merged and are now synonymous.
|
||||
They both provide the Laffargue-Boucekkine-Juillard algorithm and work
|
||||
with and without the `block` and `bytecode` options of the `model` block.
|
||||
Using `stack_solve_algo=1` is now recommended, but `stack_solve_algo=6` is
|
||||
kept for backward compatibility.
|
||||
|
||||
- OccBin
|
||||
|
||||
- New `simul_reset_check_ahead_periods` option to the `occbin_setup` and
|
||||
`occbin_solver` commands, for resetting `check_ahead_periods` in each
|
||||
simulation period.
|
||||
|
||||
- new `simul_max_check_ahead_periods`, `likelihood_max_check_ahead_periods`,
|
||||
and `smoother_max_check_ahead_periods` options to the `occbin_setup`
|
||||
command, for truncating the number of periods for which agents check ahead
|
||||
which regime is present.
|
||||
|
||||
- Optimal policy
|
||||
|
||||
- The `osr` command now accepts the `analytic_derivation` and
|
||||
`analytic_derivation_mode` options.
|
||||
|
||||
- The `evaluate_planner_objective` command now computes the unconditional
|
||||
welfare for higher-order approximations (⩾ 3).
|
||||
|
||||
- New `periods` and `drop` options to the `evaluate_planner_objective`
|
||||
command.
|
||||
|
||||
- Semi-structural models
|
||||
|
||||
- New `pac_target_info` block for decomposing the PAC target into an
|
||||
arbitrary number of components. Furthermore, in the presence of such a
|
||||
block, the new `pac_target_nonstationary` operator can be used to select
|
||||
the non stationary part of the target (typically useful in the error
|
||||
correction term of the PAC equation).
|
||||
|
||||
- New `kind` option to the `pac_model` command. This option allows the user
|
||||
to select the formula used to compute the weights on the VAR companion
|
||||
matrix variables that are used to form PAC expectations.
|
||||
|
||||
- Performance improvement to `solve_algo=12` and `solve_algo=14`, which
|
||||
significantly accelerates the simulation of purely backward, forward and
|
||||
static models with the `perfect_foresight_solver` command and the routines
|
||||
for semi-structural models.
|
||||
|
||||
- dseries classes
|
||||
|
||||
- The `remove` and `remove_` methods now accept a list of variables (they
|
||||
would previously only accept a single variable).
|
||||
|
||||
- New MATLAB/Octave command `dplot` to plot mathematical expressions
|
||||
generated from variables fetched from (different) dseries objects.
|
||||
|
||||
- Misc
|
||||
|
||||
- New `display_parameter_values` command to print the parameter values in
|
||||
the command window.
|
||||
|
||||
- New `collapse_figures_in_tabgroup` command to dock all figures.
|
||||
|
||||
- Performance improvement for the `use_dll` option of the `model` block. The
|
||||
preprocessor now takes advantage of parallelization when compiling the MEX
|
||||
files.
|
||||
|
||||
- New mathematical primitives available: complementary error function
|
||||
(`erfc`), hyperbolic functions (`cosh`, `sinh`, `tanh`, `acosh`, `asinh`,
|
||||
`atanh`).
|
||||
|
||||
- New `last_simulation_period` option to the `initval_file` command.
|
||||
|
||||
- The `calib_smoother` command now accepts the `nobs` and
|
||||
`heteroskedastic_filter` options.
|
||||
|
||||
- Under the MATLAB Desktop, autocompletion is now available for the `dynare`
|
||||
command and other CLI commands (thanks to Eduard Benet Cerda from
|
||||
MathWorks).
|
||||
|
||||
- Model debugging: The preprocessor now creates files for evaluating the
|
||||
left- and right-hand sides of model equations separately. For a model file
|
||||
called `ramst.mod`, you can call
|
||||
`[lhs,rhs]=ramst.debug.static_resid(y,x,params);` (for the static model)
|
||||
and `[lhs,rhs]=ramst.debug.dynamic_resid(y,x,params,steady_state);` (for
|
||||
the dynamic model), where `y` are the endogenous, `x` the exogenous,
|
||||
`params` the parameters, and `steady_state` is self-explanatory. NB: In
|
||||
the dynamic case, the vector `y` of endogenous must have 3n elements
|
||||
where n is the number of endogenous (including auxiliary ones); the
|
||||
first n elements correspond to the lagged values, the middle n
|
||||
elements to the contemporaneous values, and the last n elements to the
|
||||
lead values.
|
||||
|
||||
- New interactive MATLAB/Octave command `search` for listing the equations
|
||||
in which given variable(s) appear (requires `json` command line option).
|
||||
|
||||
- The `model_info` command allows to print the block decomposition even if
|
||||
the `block` option of the `model` block has not been used, by specifying
|
||||
the new options `block_static` and `block_dynamic`.
|
||||
|
||||
- There is now a default value for the global initialization file
|
||||
(`GlobalInitFile` option of the configuration file): the `global_init.m`
|
||||
in the Dynare configuration directory (typically
|
||||
`$HOME/.config/dynare/global_init.m` under Linux and macOS, and
|
||||
`c:\Users\USERNAME\AppData\Roaming\dynare\global_init.m` under Windows).
|
||||
|
||||
- For those compiling Dynare from source, the build system has been entirely
|
||||
rewritten and now uses Meson; as a consequence, it is now faster and
|
||||
easier to understand.
|
||||
|
||||
- References:
|
||||
|
||||
- Andreasen, Martin M., Jesús Fernández-Villaverde, and Juan Rubio-Ramírez
|
||||
(2018): “The Pruned State-Space System for Non-Linear DSGE Models: Theory
|
||||
and Empirical Applications,” *Review of Economic Studies*, 85(1), 1-49.
|
||||
- Brooks, Stephen P., and Andrew Gelman (1998): “General methods for
|
||||
monitoring convergence of iterative simulations,” *Journal of Computational
|
||||
and Graphical Statistics*, 7, pp. 434–455.
|
||||
- Christiano, Eichenbaum and Charles L. Evans (2005): “Nominal Rigidities and
|
||||
the Dynamic Effects of a Shock to Monetary Policy,” *Journal of Political
|
||||
Economy*, 113(1), 1–45.
|
||||
- Christiano, Lawrence J., Mathias Trabandt, and Karl Walentin (2010): “DSGE
|
||||
Models for Monetary Policy Analysis,” In: *Handbook of Monetary Economics
|
||||
3*, 285–367.
|
||||
- Herbst, Edward and Schorfheide, Frank (2014): "Sequential Monte Carlo
|
||||
Sampling for DSGE Models," *Journal of Applied Econometrics*, 29,
|
||||
1073-1098.
|
||||
|
||||
Incompatible changes
|
||||
--------------------
|
||||
|
||||
- The default value of the `mode_compute` option of the `estimation` command
|
||||
has been changed to `5` (it was previously `4`).
|
||||
|
||||
- When using block decomposition (with the `block` option of the `model`
|
||||
block), the option `mfs` now defaults to `1`. This setting should deliver
|
||||
better performance in perfect foresight simulation on most models.
|
||||
|
||||
- The default location for the configuration file has changed. On Linux and
|
||||
macOS, the configuration file is now searched by default under
|
||||
`dynare/dynare.ini` in the configuration directories defined by the XDG
|
||||
specification (typically `$HOME/.config/dynare/dynare.ini` for the
|
||||
user-specific configuration and `/etc/xdg/dynare/dynare.ini` for the
|
||||
system-wide configuration, the former having precedence over the latter).
|
||||
Under Windows, the configuration file is now searched by default in
|
||||
`%APPDATA%\dynare\dynare.ini` (typically
|
||||
`c:\Users\USERNAME\AppData\Roaming\dynare\dynare.ini`).
|
||||
|
||||
- The information stored in `oo_.endo_simul, oo_.exo_simul`, and `oo_.irfs` is
|
||||
no longer duplicated in the base workspace. New helper functions
|
||||
`send_endogenous_variables_to_workspace`,
|
||||
`send_exogenous_variables_to_workspace`, and `send_irfs_to_workspace` have
|
||||
been introduced to explicitly request these outputs and to mimic the old
|
||||
behavior.
|
||||
|
||||
- The `dynare_sensitivity` command has been renamed `sensitivity`. The old
|
||||
name is still accepted but triggers a warning.
|
||||
|
||||
- The syntax `resid(1)` is no longer supported.
|
||||
|
||||
- The `mode_compute=6` option to the `estimation` command now recursively
|
||||
updates the covariance matrix across the `NumberOfMh` Metropolis-Hastings
|
||||
runs, starting with the `InitialCovarianceMatrix` in the first run, instead
|
||||
of computing it from scratch in every Metropolis-Hastings run.
|
||||
|
||||
- The `periods` command has been removed.
|
||||
|
||||
- The `Sigma_e` command has been removed.
|
||||
|
||||
- The `block` option of the `model` block no longer has an effect when used in
|
||||
conjunction with `stoch_simul` or `estimation` commands.
|
||||
|
||||
- The Dynare++ executable is no longer distributed since almost all of its
|
||||
functionalities have been integrated inside Dynare for MATLAB/Octave.
|
||||
|
||||
- A macro-processor variable defined without a value (such as `@#define var`
|
||||
in the `.mod` file or alternatively `-Dvar` on the `dynare` command line) is
|
||||
now assigned the `true` logical value (it was previously assigned `1`).
|
||||
|
||||
- The `parallel_slave_open_mode` option of the `dynare` command has been
|
||||
renamed `parallel_follower_open_mode`.
|
||||
|
||||
- The `static` option of the `model_info` command is now deprecated and is
|
||||
replaced by the `block_static` option.
|
||||
|
||||
Bugs that were present in 5.5 and that have been fixed in 6.0
|
||||
-------------------------------------------------------------
|
||||
|
||||
* The `mh_initialize_from_previous_mcmc` option of the `estimation` command
|
||||
would not work if estimation was conducted with a different prior and the
|
||||
last draw in the previous MCMC fell outside the new prior bounds
|
||||
* When specifying a generalized inverse Gamma prior, the hyperparameter
|
||||
computation would erroneously ignore the resulting mean shift
|
||||
* When using the `mh_recover` option of the `estimation` command, the status
|
||||
bar always started at zero instead of showing the overall progress of the
|
||||
recovered chain
|
||||
* The `model_diagnostics` command would fail to check the correctness of
|
||||
user-defined steady state files
|
||||
* GSA: LaTeX output was not working as expected
|
||||
* Forecasts and filtered variables could not be retrieved with the
|
||||
`heteroskedastic_shocks` block
|
||||
* The OccBin smoother would potentially not display all smoothed shocks with
|
||||
`heteroskedastic_filter` option
|
||||
* The OccBin smoother would crash if the number of requested periods was
|
||||
smaller than the data length
|
||||
* The multivariate OccBin smoother would return wrong results if the constraint
|
||||
was binding in the first period
|
||||
* The `plot_shock_decomposition` command would fail with the `init2shocks`
|
||||
block if the `initial_condition_decomposition` was not run before
|
||||
* LaTeX output under Windows failed to compile for `plot_priors=1` option of
|
||||
the `estimation` command and Brooks and Gelman (1998) convergence diagnostics
|
||||
* The plot produced by the `shock_decomposition` command was too big, making
|
||||
the close button inaccessible
|
||||
* Monthly dates for October, November and December (*i.e.* with a 2-digit month
|
||||
number) were not properly interpreted by the preprocessor
|
||||
* Theoretical moments computed by `stoch_simul` at `order=2` with `pruning`
|
||||
would not contain unconditional and conditional variance decomposition
|
||||
|
||||
|
||||
Announcement for Dynare 5.5 (on 2023-10-23)
|
||||
===========================================
|
||||
|
||||
We are pleased to announce the release of Dynare 5.5.
|
||||
|
||||
This maintenance release fixes various bugs.
|
||||
|
||||
The Windows, macOS and source packages are already available for download at
|
||||
[the Dynare website](https://www.dynare.org/download/).
|
||||
|
||||
All users are strongly encouraged to upgrade.
|
||||
|
||||
This release is compatible with MATLAB versions ranging from 8.3 (R2014a) to
|
||||
23.2 (R2023b), and with GNU Octave version 8.3.0 (under Windows).
|
||||
|
||||
Note for macOS users with an Apple Silicon processor: this is the first Dynare
|
||||
release that comes with native Apple Silicon (arm64) support under MATLAB.
|
||||
Please download the corresponding package, to be used with MATLAB R2023b for
|
||||
Apple Silicon.
|
||||
|
||||
Here is a list of the problems identified in version 5.4 and that have been
|
||||
fixed in version 5.5:
|
||||
|
||||
* In a stochastic context, results could be incorrect if an endogenous with a
|
||||
lead ⩾ 2 or an exogenous with a lead ⩾ 1 appeared in the argument(s) of a
|
||||
call to a (nonlinear) external function
|
||||
* With the `use_dll` option of the `model` block, the expression `sign(x)`
|
||||
would evaluate to ±1 instead of 0 if `x=0`
|
||||
* If the guess value given to the `steady` command was such that the residuals
|
||||
were all below tolerance, except some that are `NaN`, then this guess value
|
||||
was incorrectly accepted as the solution to the steady state problem
|
||||
* The `method_of_moments` command with GMM was ignoring the
|
||||
`analytic_standard_errors` option when using `mode_compute=4`
|
||||
* Homotopy with the `extended_path` command at `order=0` was broken
|
||||
* The `parallel_use_psexec` command-line option was ignored
|
||||
* With the `bytecode` option of the `model` block, using the operators `abs()`,
|
||||
`cbrt()` and `sign()` would lead to a crash
|
||||
* The `fast` command-line option was broken under MATLAB with Windows
|
||||
* Ramsey steady state computation could fail if an `expectation` or `diff`
|
||||
operator was present in the model
|
||||
* A crash could occur if some external function call was present in an
|
||||
auxiliary variable
|
||||
* The `endogenous_prior` option of the `estimation` command could erroneously
|
||||
display a warning message about missing observations
|
||||
* The `model_comparison` command would crash if the `.mod` file name had less
|
||||
than four characters
|
||||
* The `shock_decomposition` command would overwrite previously stored smoother
|
||||
results
|
||||
* The `x13` interface in dseries did not handle missing values, particularly at
|
||||
the beginning of a series
|
||||
* The `x13` interface in dseries would occasionally crash under Windows with
|
||||
segmentation violations
|
||||
* OccBin: estimation would crash if a previous `shocks(surprise)` simulation
|
||||
was conducted
|
||||
* The `internals` command would not find the location of the `_results.mat`
|
||||
file
|
||||
* The `prior optimize` command would not work with `mode_compute=5`
|
||||
|
||||
|
||||
Announcement for Dynare 5.4 (on 2023-03-22)
|
||||
===========================================
|
||||
|
||||
We are pleased to announce the release of Dynare 5.4.
|
||||
|
||||
This maintenance release fixes various bugs.
|
||||
|
||||
The Windows, macOS and source packages are already available for download at
|
||||
[the Dynare website](https://www.dynare.org/download/).
|
||||
|
||||
All users are strongly encouraged to upgrade.
|
||||
|
||||
This release is compatible with MATLAB versions ranging from 8.3 (R2014a) to
|
||||
9.14 (R2023a), and with GNU Octave version 8.1.0 (under Windows).
|
||||
|
||||
Note for macOS users with an Apple Silicon processor, and who are also MATLAB
|
||||
users: the official MATLAB version for use on those processors is still the
|
||||
Intel version (running through Rosetta 2), so the official Dynare package for
|
||||
download on our website is built for Intel only. However, since Mathworks has
|
||||
released a beta version of MATLAB for Apple Silicon, we created a beta package
|
||||
of Dynare that you can try with it. See this forum thread for more details:
|
||||
https://forum.dynare.org/t/testers-wanted-release-of-dynare-5-x-beta-for-apple-silicon-m1-m2-chips/20499
|
||||
|
||||
Here is a list of the problems identified in version 5.3 and that have been
|
||||
fixed in version 5.4:
|
||||
|
||||
* Files installed through the Windows installer had too weak permissions and
|
||||
could be modified by unpriviledged local users, if the default installation
|
||||
location (`c:\dynare\`) had been chosen
|
||||
* Estimation:
|
||||
+ the `load_results_after_load_mh` option would not find the location of the
|
||||
results file
|
||||
+ the computation of prior/posterior statistics would crash if the value of
|
||||
the `filter step_ahead` option was greater than 1 without requesting a
|
||||
`forecast` or the `smoother`
|
||||
+ NaN or complex parameters returned by steady state files were not correctly
|
||||
handled
|
||||
+ `analytical_derivation` could be triggered with `endogenous_prior` but
|
||||
would not take the endogenous prior into account for the Jacobian and
|
||||
Hessian
|
||||
* OccBin:
|
||||
+ running the `calib_smoother` command with `smoother_inversion_filter` would
|
||||
crash unless `likelihood_inversion_filter` was also specified
|
||||
+ running the piecewise Kalman smoother would crash if an error was
|
||||
encountered during computation of the decision rules
|
||||
* PAC equation estimation through iterative OLS would crash if the auxiliary
|
||||
model contained a constant
|
||||
* The variable label was incorrect for leads and lags of exogenous variables in
|
||||
the display of decision rules and in the `model_info` command
|
||||
* Declaring a `trend_var` variable while not having a `var(deflator=...)`
|
||||
statement would cause the preprocessor to crash
|
||||
* Macro processor: error messages following a `@#define`, `@#include` or
|
||||
`@#includepath` directive could in some cases point to a line number off by 1
|
||||
* Perfect foresight simulations: the `debug` option would not preserve
|
||||
sparsity, causing out of memory errors
|
||||
|
||||
|
||||
Announcement for Dynare 5.3 (on 2022-11-21)
|
||||
===========================================
|
||||
|
||||
|
@ -45,7 +563,6 @@ fixed in version 5.3:
|
|||
* Problems related to Bayesian or ML estimation:
|
||||
+ `mh_recover` and `load_mh_file` would not find the saved proposal density
|
||||
and had to rely on the `_mode` file
|
||||
+ `load_results_after_load_mh` would not find the location of the `_results` file
|
||||
+ When requesting `bayesian_irf` together with `loglinear`, the resulting
|
||||
IRFs would be incorrect
|
||||
+ the diffuse Kalman smoother initialization (`lik_init=3`) was wrong when
|
||||
|
|
392
README.md
392
README.md
|
@ -33,8 +33,6 @@ This source can be retrieved in three forms:
|
|||
- using the stable source archive of the latest Dynare version from <https://www.dynare.org/download/>
|
||||
- using a source snapshot of the unstable version, also from <https://www.dynare.org/download/>
|
||||
|
||||
Note that if you obtain the source code via git, you will need to install more tools (see below).
|
||||
|
||||
The first section of this page gives general instructions, which apply to all platforms. Then some specific platforms are discussed.
|
||||
|
||||
**Note:** Here, when we refer to 32-bit or 64-bit, we refer to the type of
|
||||
|
@ -45,8 +43,8 @@ determine the type of your MATLAB/Octave installation, type:
|
|||
```matlab
|
||||
>> computer
|
||||
```
|
||||
at the MATLAB/Octave prompt. Under MATLAB, if it returns `PCWIN64`, `GLNX64` or
|
||||
`MACI64`, then it is a 64-bit MATLAB; if it returns `PCWIN`, `MACI` or `GLNX`,
|
||||
at the MATLAB/Octave prompt. Under MATLAB, if it returns `PCWIN64`, `GLNX64`,
|
||||
`MACI64` or `MACA64` then it is a 64-bit MATLAB; if it returns `PCWIN`, `MACI` or `GLNX`,
|
||||
then it is a 32-bit MATLAB. Under Octave, if it returns a string that begins
|
||||
with `x86_64`, it is a 64-bit Octave; if the strings begins with `i686`, it is
|
||||
a 32-bit Octave.
|
||||
|
@ -58,6 +56,7 @@ a 32-bit Octave.
|
|||
1. [**Fedora, CentOS or RHEL**](#fedora-centos-or-rhel)
|
||||
1. [**Windows**](#windows)
|
||||
1. [**macOS**](#macos)
|
||||
1. [**Docker**](#docker)
|
||||
|
||||
## General Instructions
|
||||
|
||||
|
@ -65,28 +64,27 @@ a 32-bit Octave.
|
|||
|
||||
A number of tools and libraries are needed in order to recompile everything. You don't necessarily need to install everything, depending on what you want to compile.
|
||||
|
||||
- A POSIX compliant shell and an implementation of Make (mandatory)
|
||||
- The [GNU Compiler Collection](https://gcc.gnu.org/), version 10 or later, with
|
||||
gcc, g++ and gfortran (mandatory)
|
||||
gcc, g++ and gfortran
|
||||
- [MATLAB](https://mathworks.com) (if you want to compile the MEX for MATLAB)
|
||||
- [GNU Octave](https://www.octave.org) with
|
||||
- the development headers (if you want to compile the MEX for Octave)
|
||||
- the development libraries corresponding to the [UMFPACK](https://people.engr.tamu.edu/davis/suitesparse.html) packaged with Octave
|
||||
- Optionally, the [Control](https://octave.sourceforge.io/control/), [IO](https://octave.sourceforge.io/io/), [Optimization](https://octave.sourceforge.io/optim/) and [Statistics](https://octave.sourceforge.io/statistics/) package either installed via your package manager or through [Octave Forge](https://octave.sourceforge.io/).
|
||||
- the development libraries corresponding to the [UMFPACK](https://people.engr.tamu.edu/davis/suitesparse.html) packaged with Octave (if you want to compile the MEX for Octave)
|
||||
- the [statistics](https://octave.sourceforge.io/statistics/) package and, optionally, the [control](https://octave.sourceforge.io/control/), [io](https://octave.sourceforge.io/io/) and [optimization](https://octave.sourceforge.io/optim/) packages, either installed via your package manager or through [Octave Forge](https://octave.sourceforge.io/)
|
||||
- [Meson](https://mesonbuild.com), version 0.64.0 or later
|
||||
- [Pkgconf](http://pkgconf.org/), or another pkg-config implementation
|
||||
- [Bash](https://www.gnu.org/software/bash/)
|
||||
- [Boost libraries](https://www.boost.org), version 1.36 or later
|
||||
- [Bison](https://www.gnu.org/software/bison/), version 3.2 or later (only if you get the source through Git)
|
||||
- [Flex](https://github.com/westes/flex), version 2.5.4 or later (only if you get the source through Git)
|
||||
- [Autoconf](https://www.gnu.org/software/autoconf/), version 2.62 or later (only if you get the source through Git)
|
||||
- [Automake](https://www.gnu.org/software/automake/), version 1.11.2 or later (only if you get the source through Git)
|
||||
- [MAT File I/O library](https://sourceforge.net/projects/matio/), version 1.5 or later (if you want to compile Markov-Switching code, the estimation DLL, and the k-order DLL)
|
||||
- [SLICOT](http://www.slicot.org) (if you want to compile the Kalman steady state DLL)
|
||||
- [GSL library](https://www.gnu.org/software/gsl/) (if you want to compile Markov-Switching code)
|
||||
- [Bison](https://www.gnu.org/software/bison/), version 3.2 or later
|
||||
- [Flex](https://github.com/westes/flex), version 2.5.4 or later
|
||||
- [MAT File I/O library](https://sourceforge.net/projects/matio/), version 1.5 or later (only when compiling for Octave)
|
||||
- [SLICOT](http://www.slicot.org)
|
||||
- [GSL library](https://www.gnu.org/software/gsl/)
|
||||
- A decent LaTeX distribution (if you want to compile PDF documentation),
|
||||
ideally with Beamer
|
||||
- For building the reference manual:
|
||||
- [Sphinx](https://www.sphinx-doc.org/)
|
||||
- [MathJax](https://www.mathjax.org/)
|
||||
- [Doxygen](https://www.doxygen.nl) (if you want to build Dynare preprocessor source documentation)
|
||||
- [X-13ARIMA-SEATS Seasonal Adjustment Program](https://www.census.gov/data/software/x13as.html)
|
||||
|
||||
### Preparing the sources
|
||||
|
@ -98,107 +96,78 @@ have the [Git LFS](https://git-lfs.github.com/) extension installed):
|
|||
```sh
|
||||
git clone --recurse-submodules https://git.dynare.org/Dynare/dynare.git
|
||||
cd dynare
|
||||
autoreconf -si
|
||||
```
|
||||
The last line runs Autoconf and Automake in order to prepare the build environment (this is not necessary if you got the sources from an official source archive or the source snapshot). If you want a certain version (e.g. 5.x) , then add `--single-branch --branch 5.x` to the git clone command.
|
||||
If you want a certain version (e.g. 5.x) , then add `--single-branch --branch 5.x` to the git clone command.
|
||||
|
||||
### Configuring the build tree
|
||||
### Configuring the build directory
|
||||
|
||||
Simply launch the configure script from a terminal:
|
||||
If you want to compile for MATLAB, please run the following (after adapting the path to MATLAB):
|
||||
```sh
|
||||
./configure --with-matlab=<…>
|
||||
meson setup -Dmatlab_path=/usr/local/MATLAB/R2023b -Dbuildtype=debugoptimized build-matlab
|
||||
```
|
||||
where the path to MATLAB is specified.
|
||||
The build directory will thus be `build-matlab`.
|
||||
|
||||
Some important options:
|
||||
|
||||
- `--disable-matlab`: skip the compilation of MEX files for MATLAB
|
||||
- `--disable-octave`: skip the compilation of MEX files for Octave
|
||||
- `--disable-doc`: skip the compilation of the documentation (PDF and HTML)
|
||||
|
||||
You may need to specify additional options to the configure script, see the output of the `--help` option, and also the platform specific instructions below. If the configuration goes well, the script will tell you which components are correctly configured and will be built.
|
||||
|
||||
Note that it is possible that some MEX files cannot be compiled, due to missing
|
||||
build dependencies. If you find no way of installing the missing dependencies,
|
||||
a workaround can be to give up on compiling these MEX files and rather use
|
||||
slower implementations (in the MATLAB/Octave language) that are available under
|
||||
the `matlab/missing/mex/` subdirectories. For example, if you fail to compile
|
||||
the gensylv MEX, you can type the following at the MATLAB/Octave prompt before
|
||||
running Dynare:
|
||||
```matlab
|
||||
addpath <DYNARE_ROOT>/matlab/missing/mex/gensylv
|
||||
Or for Octave:
|
||||
```sh
|
||||
meson setup -Dbuild_for=octave -Dbuildtype=debugoptimized build-octave
|
||||
```
|
||||
(where you need to replace `<DYNARE_ROOT>` with the full path to your Dynare copy).
|
||||
The build directory will thus be `build-octave`.
|
||||
|
||||
Note that if you do not chose `build-matlab` (under MATLAB) or `build-octave`
|
||||
(under Octave) as the build directory, you will need to set the environment
|
||||
variable `DYNARE_BUILD_DIR` to the full path of your build tree, before running
|
||||
MATLAB or Octave, if you want Dynare to be able to find the preprocessor and
|
||||
the MEX files.
|
||||
|
||||
It is possible to specify various Meson options, see the Meson documentation
|
||||
for more details. Modifying options of an existing build directory can be
|
||||
done using the `meson configure` command.
|
||||
|
||||
### Building
|
||||
|
||||
Binaries are built with:
|
||||
For compiling the preprocessor and the MEX files:
|
||||
```sh
|
||||
make
|
||||
meson compile -C <builddir>
|
||||
```
|
||||
PDF and HTML documentation are respectively built with:
|
||||
where `<builddir>` is the build directory, typically either `build-matlab` or `build-octave`.
|
||||
|
||||
PDF and HTML documentation can be built with:
|
||||
```sh
|
||||
make pdf
|
||||
make html
|
||||
meson compile -C <builddir> doc
|
||||
```
|
||||
|
||||
### Check
|
||||
|
||||
The Git source comes with unit tests (in the MATLAB functions) and integration tests (under the `tests` subfolder). All the tests can be run with:
|
||||
Dynare comes with unit tests (in the MATLAB functions) and integration tests (under the `tests` subfolder). All the tests can be run with:
|
||||
```sh
|
||||
make check
|
||||
```
|
||||
in the `tests` subfolder. If Dynare has been compiled against MATLAB and Octave, the tests will be run with both MATLAB and Octave. Depending on the performance of your machine, this can take several hours. It is possible to run the tests only with MATLAB:
|
||||
```sh
|
||||
make check-matlab
|
||||
```
|
||||
or only with Octave:
|
||||
```sh
|
||||
make check-octave
|
||||
meson test -C <builddir>
|
||||
```
|
||||
|
||||
Depending on the performance of your machine, this can take several hours.
|
||||
|
||||
Note that running the testsuite with Octave requires the additional packages `pstoedit`, `epstool`, `xfig`, and `gnuplot`.
|
||||
|
||||
A summary of the results is available in `tests/run_test_matlab_output.txt` or `tests/run_test_octave_output.txt`. Often, it does not make sense to run the complete testsuite. For instance, if you modify codes only related to the perfect foresight model solver, you can decide to run only a subset of the integration tests, with:
|
||||
Often, it does not make sense to run the complete testsuite. For instance, if you modify codes only related to the perfect foresight model solver, you can decide to run only a subset of the integration tests, with:
|
||||
```sh
|
||||
make deterministic_simulations
|
||||
meson test -C <builddir> --suite deterministic_simulations
|
||||
```
|
||||
This will run all the integration tests in `tests/deterministic_simulations` with MATLAB and Octave. Again, it is possible to do this only with MATLAB:
|
||||
This will run all the integration tests in `tests/deterministic_simulations`.
|
||||
This syntax also works with a nested directory (e.g. `--suite deterministic_simulations/purely_forward`).
|
||||
|
||||
Finally if you want to run a single integration test, e.g. `deterministic_simulations/lbj/rbc.mod`:
|
||||
```sh
|
||||
make m/deterministic_simulations
|
||||
meson test -C <builddir> deterministic_simulations/lbj/rbc.mod
|
||||
```
|
||||
or with Octave:
|
||||
```sh
|
||||
make o/deterministic_simulations
|
||||
```
|
||||
Finally if you want to run a single integration test, e.g. `deterministic_simulations/lbj/rbc.mod` with MATLAB:
|
||||
```sh
|
||||
make deterministic_simulations/lbj/rbc.m.trs
|
||||
```
|
||||
or with Octave:
|
||||
```sh
|
||||
make deterministic_simulations/lbj/rbc.o.trs
|
||||
```
|
||||
The result of the test (`PASSED` or `FAILED`) will be printed in the terminal, the produced log can be displayed with:
|
||||
```sh
|
||||
make deterministic_simulations/lbj/rbc.m.drs
|
||||
```
|
||||
or
|
||||
```sh
|
||||
make deterministic_simulations/lbj/rbc.o.drs
|
||||
```
|
||||
Note that only tests will be executed where the `m.trs/o.trs` does not yet exist. You can run
|
||||
```sh
|
||||
make clean
|
||||
```
|
||||
in the `tests` folder to delete files that were created by the run of the testsuite. You can also manually delete the desired `m.trs/o.trs` file(s).
|
||||
NB: Some individual tests cannot be run using that syntax, if they are a dependency in a chain of tests (see the `mod_and_m_tests` variable `meson.build`); in that case, you should use the name of the last `.mod` file in the chain as the test name to be passed to `meson test`.
|
||||
|
||||
## Debian or Ubuntu
|
||||
|
||||
All the prerequisites are packaged:
|
||||
|
||||
- `build-essential` (for gcc, g++ and make)
|
||||
- `gcc`
|
||||
- `g++`
|
||||
- `gfortran`
|
||||
- `liboctave-dev`
|
||||
- `octave-dev` (or `liboctave-dev` on older Debian/Ubuntu releases)
|
||||
- `libboost-graph-dev`
|
||||
- `libgsl-dev`
|
||||
- `libmatio-dev`
|
||||
|
@ -206,40 +175,31 @@ All the prerequisites are packaged:
|
|||
- `libsuitesparse-dev`
|
||||
- `flex` and `libfl-dev`
|
||||
- `bison`
|
||||
- `autoconf`
|
||||
- `automake`
|
||||
- `meson`
|
||||
- `pkgconf`
|
||||
- `texlive`
|
||||
- `texlive-publishers` (for Econometrica bibliographic style)
|
||||
- `texlive-latex-extra` (for fullpage.sty)
|
||||
- `texlive-fonts-extra` (for ccicons)
|
||||
- `texlive-latex-recommended`
|
||||
- `texlive-science` (for amstex)
|
||||
- `texlive-plain-generic`
|
||||
- `lmodern` (for macroprocessor PDF)
|
||||
- `python3-sphinx`
|
||||
- `tex-gyre`
|
||||
- `latexmk`
|
||||
- `libjs-mathjax`
|
||||
- `doxygen`
|
||||
- `x13as`
|
||||
|
||||
You can install them all at once with:
|
||||
```sh
|
||||
apt install build-essential gfortran liboctave-dev libboost-graph-dev libgsl-dev libmatio-dev libslicot-dev libslicot-pic libsuitesparse-dev flex libfl-dev bison autoconf automake texlive texlive-publishers texlive-latex-extra texlive-fonts-extra texlive-latex-recommended texlive-science texlive-plain-generic lmodern python3-sphinx tex-gyre latexmk libjs-mathjax doxygen x13as
|
||||
apt install gcc g++ gfortran octave-dev libboost-graph-dev libgsl-dev libmatio-dev libslicot-dev libslicot-pic libsuitesparse-dev flex libfl-dev bison meson pkgconf texlive texlive-publishers texlive-latex-extra texlive-fonts-extra texlive-science lmodern python3-sphinx make tex-gyre latexmk libjs-mathjax x13as
|
||||
```
|
||||
If you use MATLAB, we strongly advise to also `apt install matlab-support` and confirm to rename the GCC libraries shipped with MATLAB to avoid possible conflicts with GCC libraries shipped by your distribution.
|
||||
|
||||
Tested on
|
||||
- Debian “Buster” 10
|
||||
- Debian “Bullseye” 11
|
||||
- Ubuntu 20.04
|
||||
- Ubuntu 20.10
|
||||
|
||||
## Fedora, CentOS or RHEL
|
||||
|
||||
Almost all prerequisites are packaged:
|
||||
|
||||
- `gcc`, `gcc-c++`, `make`
|
||||
- `gcc`, `gcc-c++`
|
||||
- `gcc-gfortran`
|
||||
- `boost-devel`
|
||||
- `gsl-devel`
|
||||
|
@ -247,24 +207,23 @@ Almost all prerequisites are packaged:
|
|||
- `suitesparse-devel`
|
||||
- `flex`
|
||||
- `bison`
|
||||
- `autoconf`
|
||||
- `automake`
|
||||
- `meson`
|
||||
- `redhat-rpm-config`
|
||||
- `octave`, `octave-devel`, `octave-statistics`, `octave-io`, `octave-optim`, `octave-control`
|
||||
- `texlive-scheme-minimal`, `texlive-collection-publishers`, `texlive-collection-latexextra`, `texlive-collection-fontsextra`, `texlive-collection-latexrecommended`, `texlive-collection-science`, `texlive-collection-plaingeneric`, `texlive-lm`
|
||||
- `python3-sphinx`
|
||||
- `latexmk`
|
||||
- `mathjax`
|
||||
- `doxygen`
|
||||
- `make` (for building Slicot)
|
||||
|
||||
You can install them all at once with:
|
||||
```sh
|
||||
# Minimal packages (use --disable-doc and --disable-octave flags)
|
||||
dnf install -y gcc gcc-c++ make gcc-gfortran boost-devel gsl-devel matio-devel suitesparse-devel flex bison autoconf automake redhat-rpm-config
|
||||
# Octave packages (use --disable-doc flag)
|
||||
# Minimal packages
|
||||
dnf install -y gcc gcc-c++ make gcc-gfortran boost-devel gsl-devel matio-devel suitesparse-devel flex bison meson redhat-rpm-config
|
||||
# Octave packages
|
||||
dnf install octave octave-devel octave-statistics octave-io octave-optim octave-control
|
||||
# Documentation packages
|
||||
dnf install texlive-scheme-minimal texlive-collection-publishers texlive-collection-latexextra texlive-collection-fontsextra texlive-collection-latexrecommended texlive-collection-science texlive-collection-plaingeneric texlive-lm python3-sphinx latexmk mathjax doxygen
|
||||
# Documentation packages (only needed if you build documentation)
|
||||
dnf install texlive-scheme-minimal texlive-collection-publishers texlive-collection-latexextra texlive-collection-fontsextra texlive-collection-latexrecommended texlive-collection-science texlive-collection-plaingeneric texlive-lm python3-sphinx latexmk mathjax
|
||||
```
|
||||
In Fedora these are available from the default repositories; whereas for CentOS and RHEL you need to enable the [Extra Packages for Enterprise Linux (EPEL)](https://fedoraproject.org/wiki/EPEL) repository and either the PowerTools repository for CentOS or the CodeReady Linux Builder repository for RHEL:
|
||||
```sh
|
||||
|
@ -275,7 +234,7 @@ dnf config-manager --set-enabled PowerTools
|
|||
ARCH=$( /bin/arch )
|
||||
subscription-manager repos --enable "codeready-builder-for-rhel-8-${ARCH}-rpms"
|
||||
```
|
||||
The documentation packages have slightly different names in CentOS and RHEL, you can also choose to pass the `--disable-doc` flag to your configure script to skip these dependencies.
|
||||
The documentation packages have slightly different names in CentOS and RHEL, but this should only impact you if you build the documentation.
|
||||
|
||||
`Slicot` and `x13as` need to be compiled from source:
|
||||
|
||||
|
@ -286,16 +245,19 @@ cd /home/$USER/dynare/slicot
|
|||
wget https://deb.debian.org/debian/pool/main/s/slicot/slicot_5.0+20101122.orig.tar.gz
|
||||
tar xf slicot_5.0+20101122.orig.tar.gz
|
||||
cd slicot-5.0+20101122
|
||||
make FORTRAN=gfortran OPTS="-O2 -fPIC -fdefault-integer-8" LOADER=gfortran lib
|
||||
mkdir -p /home/$USER/dynare/slicot/lib
|
||||
cp slicot.a /home/$USER/dynare/slicot/lib/libslicot64_pic.a #for matlab
|
||||
cp slicot.a /home/$USER/dynare/slicot/lib/libslicot_pic.a #for octave
|
||||
# The following two lines are only for MATLAB
|
||||
make FORTRAN=gfortran OPTS="-O2 -fPIC -fdefault-integer-8" LOADER=gfortran lib
|
||||
cp slicot.a /home/$USER/dynare/slicot/lib/libslicot64_pic.a
|
||||
# The following two lines are only for Octave
|
||||
make FORTRAN=gfortran OPTS="-O2 -fPIC" LOADER=gfortran lib
|
||||
cp slicot.a /home/$USER/dynare/slicot/lib/libslicot_pic.a
|
||||
|
||||
# compile x13as from source and put it into /usr/bin/
|
||||
mkdir -p /home/$USER/dynare/x13as
|
||||
cd /home/$USER/dynare/x13as
|
||||
wget https://www2.census.gov/software/x-13arima-seats/x13as/unix-linux/program-archives/x13as_asciisrc-v1-1-b58.tar.gz
|
||||
tar xf x13as_asciisrc-v1-1-b58.tar.gz
|
||||
wget https://www2.census.gov/software/x-13arima-seats/x13as/unix-linux/program-archives/x13as_asciisrc-v1-1-b60.tar.gz
|
||||
tar xf x13as_asciisrc-v1-1-b60.tar.gz
|
||||
sed -i "s|-static| |" makefile.gf # this removes '-static' in the makefile.gf
|
||||
make -f makefile.gf FFLAGS="-O2 -std=legacy" PROGRAM=x13as
|
||||
sudo cp x13as /usr/bin/
|
||||
|
@ -303,17 +265,16 @@ sudo cp x13as /usr/bin/
|
|||
|
||||
If you use MATLAB, we strongly advise to also rename or exclude the GCC libraries shipped with MATLAB to avoid possible conflicts with GCC libraries shipped by Fedora, see e.g. [Matlab on Fedora 33](https://mutschler.eu/linux/install-guides/fedora-post-install/#matlab) or [MATLAB-ArchWiki](https://wiki.archlinux.org/index.php/MATLAB) for instructions.
|
||||
|
||||
Keep in mind to use the `--with-slicot` option to the configure command, e.g.:
|
||||
Now use the following commands if using MATLAB (adapt them for Octave, see above):
|
||||
```sh
|
||||
cd /home/$USER/dynare
|
||||
git clone --recurse-submodules https://git.dynare.org/dynare/dynare.git unstable
|
||||
cd unstable
|
||||
autoreconf -si
|
||||
./configure --with-slicot=/home/$USER/dynare/slicot --with-matlab=/usr/local/MATLAB/R2020b
|
||||
make -j$(($(nproc)+1)) #rule of thumb: one more than CPUs as shown by e.g. lscpu
|
||||
meson setup -Dmatlab_path=/usr/local/MATLAB/R2023b -Dfortran_args="[ '-B', '/home/$USER/dynare/slicot']" -Dbuildtype=debugoptimized build-matlab
|
||||
meson compile -C build-matlab
|
||||
```
|
||||
|
||||
If your distribution ships an older version of `bison`, compile it from source and append it *temporarily* to your path before calling the configure script:
|
||||
If your distribution ships an older version of `bison`, compile it from source and append it *temporarily* to your path before running meson:
|
||||
```sh
|
||||
bison --version # bison (GNU Bison) 3.0.4
|
||||
mkdir -p /home/$USER/dynare/bison
|
||||
|
@ -329,12 +290,6 @@ bison --version # bison (GNU Bison) 3.6.4
|
|||
```
|
||||
Now configure dynare as above.
|
||||
|
||||
Tested on
|
||||
- CentOS 8
|
||||
- Fedora Workstation 32
|
||||
- Fedora Workstation 33
|
||||
- Red Hat Enterprise Linux 8
|
||||
|
||||
## Windows
|
||||
|
||||
- Install [MSYS2](http://www.msys2.org)
|
||||
|
@ -348,9 +303,9 @@ pacman -Syu
|
|||
window to complete the upgrade.
|
||||
- Install all needed dependencies:
|
||||
```sh
|
||||
pacman -S git autoconf automake-wrapper bison flex make tar texinfo mingw-w64-x86_64-gcc mingw-w64-x86_64-gcc-fortran mingw-w64-x86_64-boost mingw-w64-x86_64-gsl mingw-w64-x86_64-matio
|
||||
pacman -S git bison flex make tar mingw-w64-x86_64-meson mingw-w64-x86_64-gcc mingw-w64-x86_64-gcc-fortran mingw-w64-x86_64-boost mingw-w64-x86_64-gsl mingw-w64-x86_64-matio mingw-w64-x86_64-pkgconf
|
||||
```
|
||||
- Compile and install SLICOT, needed for the `kalman_steady_state` MEX file
|
||||
- Compile and install SLICOT
|
||||
```sh
|
||||
wget https://deb.debian.org/debian/pool/main/s/slicot/slicot_5.0+20101122.orig.tar.gz
|
||||
tar xf slicot_5.0+20101122.orig.tar.gz
|
||||
|
@ -364,11 +319,10 @@ cd ..
|
|||
```sh
|
||||
git clone --recurse-submodules https://git.dynare.org/Dynare/dynare.git
|
||||
cd dynare
|
||||
autoreconf -si
|
||||
```
|
||||
- Configure Dynare from the source directory:
|
||||
```sh
|
||||
./configure --with-slicot=/usr/local --with-matlab=<…> --disable-octave --disable-doc
|
||||
meson setup -Dmatlab_path=<…> -Dbuildtype=debugoptimized -Dprefer_static=true -Dfortran_args="['-B','/usr/local/lib']" build-matlab
|
||||
```
|
||||
where the path of MATLAB is specified. Note that you should use
|
||||
the MSYS2 notation and not put spaces in the MATLAB path, so you probably want
|
||||
|
@ -378,11 +332,11 @@ does not have short filenames (8dot3), then you can run `mkdir -p
|
|||
then pass `/usr/local/MATLAB/…` as MATLAB path to the configure script.
|
||||
- Compile:
|
||||
```sh
|
||||
make
|
||||
meson compile -C build-matlab
|
||||
```
|
||||
- Run the testsuite:
|
||||
```sh
|
||||
make -C tests check-matlab
|
||||
meson test -C build-matlab
|
||||
```
|
||||
|
||||
**Note:** The above assumes that you have a 64-bit version of MATLAB. It can be
|
||||
|
@ -397,118 +351,168 @@ adapted to a 32-bit MATLAB with the following modifications:
|
|||
currently not supported.
|
||||
|
||||
## macOS
|
||||
|
||||
Dynare supports both Intel and Apple Silicon chips and is compiled from source
|
||||
using a [Homebrew](https://brew.sh/) toolchain. However, if you have a *M1*, *M1 PRO*
|
||||
or *M1 MAX* processor, you need to make sure that you are not using the ARM
|
||||
Homebrew packages. This is due to the fact that although MATLAB runs natively on
|
||||
Intel, it is not yet available in an ARM version and therefore must be run with the
|
||||
Intel compatibility layer called Rosetta 2. Accordingly, if you are on Apple Silicon
|
||||
you need to compile Dynare under Rosetta 2 as well and use the Intel packages from
|
||||
Homebrew. You can check this by e.g. running `which brew` which should point to
|
||||
`/usr/local/bin/brew` and not to `/opt/homebrew/bin/brew`. In the steps below, we
|
||||
create a temporary alias to ensure that `brew` points to the Intel packages.
|
||||
using a [Homebrew](https://brew.sh/) toolchain. If you have an Apple silicon processor
|
||||
(*M1/M2 PRO/MAX/ULTRA*), you can compile Dynare both for Intel's `x86_64` (using Rosetta 2)
|
||||
as well as Apple's native `arm64` platform by using the corresponding Homebrew packages.
|
||||
If you have an Intel chip you can only compile for `x86_64`.
|
||||
|
||||
For the following steps open Terminal.app and enter the commands listed below.
|
||||
You can check the platform of your current Homebrew installation by e.g. running
|
||||
`which brew` which should point to `/opt/homebrew/bin/brew` for `arm64` and to
|
||||
`/usr/local/bin/brew` for `x86_64` systems. In the steps below, we
|
||||
create a temporary environment variable `BREWDIR` to ensure that the correct packages are used.
|
||||
|
||||
The following commands install all requirements and Dynare from source.
|
||||
They should be entered at the command prompt in Terminal.app.
|
||||
|
||||
### Preparatory work
|
||||
|
||||
- Install Rosetta 2 (Apple Silicon only):
|
||||
```sh
|
||||
softwareupdate --install-rosetta --agree-to-license
|
||||
```
|
||||
|
||||
- Install the Xcode Command Line Tools:
|
||||
```sh
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
- Install Rosetta 2 (Apple Silicon only):
|
||||
```sh
|
||||
softwareupdate --install-rosetta --agree-to-license
|
||||
```
|
||||
|
||||
- Install [Homebrew](https://brew.sh/):
|
||||
```sh
|
||||
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
```
|
||||
The prefix `arch -x86_64` makes sure that you are using Rosetta 2 to install Homebrew.
|
||||
Create environment variables for which platform you want to compile for, i.e. either `arm64` or `x86_64`:
|
||||
|
||||
- Apple Silicon only: Make a (temporary) alias to run `brew` under Rosetta 2:
|
||||
For `arm64` run the following commands:
|
||||
```sh
|
||||
alias brew='arch -x86_64 /usr/local/bin/brew'
|
||||
which brew
|
||||
#brew: aliased to arch -x86_64 /usr/local/bin/brew
|
||||
export ARCH=arm64
|
||||
export BREWDIR=/opt/homebrew
|
||||
```
|
||||
|
||||
- Install required Homebrew packages and link sphinx-doc:
|
||||
For `x86_64` run the following commands:
|
||||
```sh
|
||||
brew install automake bison flex boost gcc gsl libmatio veclibfort octave sphinx-doc wget
|
||||
brew link --force sphinx-doc
|
||||
export ARCH=x86_64
|
||||
export BREWDIR=/usr/local
|
||||
```
|
||||
|
||||
- Install [MacTeX](http://www.tug.org/mactex/index.html) using the universal installer. MacTeX runs natively on both ARM and Intel machines. On Apple Silicon, we need to put `pdflatex` and `bibtex` into our path:
|
||||
Install Homebrew using the environment variables:
|
||||
```sh
|
||||
ln -s /Library/TeX/texbin/pdflatex /usr/local/bin/pdflatex
|
||||
ln -s /Library/TeX/texbin/bibtex /usr/local/bin/bibtex
|
||||
arch -$ARCH /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
```
|
||||
Alternatively, if you don’t want to install MacTeX, you should pass the `--disable-doc` flag to the `configure` command below.
|
||||
The prefix `arch -arm64` or `arch -x86_64` makes sure that you are installing the correct packages.
|
||||
Don't forget to run the displayed commands (**Next steps**) in the terminal to add Homebrew to your PATH.
|
||||
|
||||
- Install MATLAB and additional toolboxes. We recommend, but don't require, the following: Optimization, Global Optimization, Statistics and Machine Learning, Econometrics, and Control System. As there is no ARM version of MATLAB yet, Rosetta 2 will be used on Apple Silicon machines. Don't forget to run MATLAB at least once to make sure you have a valid license.
|
||||
|
||||
- Compile and install SLICOT, needed for the `kalman_steady_state` MEX file.
|
||||
If you have both Homebrew installations installed, make sure that you are accessing the correct packages by temporarily (!) prepending it to the path:
|
||||
```sh
|
||||
mkdir -p $HOME/dynare/slicot
|
||||
cd $HOME/dynare/slicot
|
||||
wget https://deb.debian.org/debian/pool/main/s/slicot/slicot_5.0+20101122.orig.tar.gz
|
||||
export PATH="$BREWDIR/bin:$PATH"
|
||||
```
|
||||
|
||||
|
||||
- Install required Homebrew packages:
|
||||
```sh
|
||||
arch -$ARCH $BREWDIR/bin/brew install meson bison flex boost gcc gsl libmatio veclibfort octave sphinx-doc docutils wget pkg-config git-lfs
|
||||
```
|
||||
If you are installing `git-lfs` for the first time, you need to run `git lfs install` once after installing it.
|
||||
|
||||
- Link the sphinx-doc package to be able to compile the documentation:
|
||||
```sh
|
||||
arch -$ARCH $BREWDIR/bin/brew link --force sphinx-doc
|
||||
```
|
||||
|
||||
- Install [MacTeX](http://www.tug.org/mactex/index.html) using the universal installer, if you want to build the documentation. MacTeX runs natively on both ARM and Intel machines. On Apple Silicon, it is advised to symlink `pdflatex`, `bibtex` and `latexmk` into `/usr/local/bin`:
|
||||
```sh
|
||||
sudo ln -s /Library/TeX/texbin/pdflatex /usr/local/bin/pdflatex
|
||||
sudo ln -s /Library/TeX/texbin/bibtex /usr/local/bin/bibtex
|
||||
sudo ln -s /Library/TeX/texbin/latexmk /usr/local/bin/latexmk
|
||||
```
|
||||
If you don't have admin privileges, then you can also symlink them into `$HOME/.local/bin` and add this folder to your PATH.
|
||||
|
||||
- Install MATLAB and additional toolboxes.
|
||||
We recommend, but don't require, the following: Optimization, Global Optimization, Statistics and Machine Learning, Econometrics, and Control System.
|
||||
For Apple Silicon: MATLAB offers a native Apple silicon version (arm64) as of version R2023b, see [the official instructions](https://de.mathworks.com/support/requirements/apple-silicon.html) how to install it.
|
||||
You can also run the Intel version (x86_64) under Rosetta 2.
|
||||
Don't forget to run MATLAB at least once to make sure you have a valid license.
|
||||
|
||||
- Create a folder for Dynare and its dependencies
|
||||
```sh
|
||||
export DYNAREDIR=$HOME/dynare
|
||||
```
|
||||
|
||||
- Compile and install SLICOT
|
||||
```sh
|
||||
mkdir -p $DYNAREDIR/slicot/lib
|
||||
cd $DYNAREDIR/slicot
|
||||
curl -O https://deb.debian.org/debian/pool/main/s/slicot/slicot_5.0+20101122.orig.tar.gz
|
||||
tar xf slicot_5.0+20101122.orig.tar.gz
|
||||
cd slicot-5.0+20101122
|
||||
make -j$(sysctl -n hw.physicalcpu) FORTRAN=gfortran OPTS="-O2" LOADER=gfortran lib
|
||||
cp slicot.a /usr/local/lib/libslicot_pic.a
|
||||
make -j$(sysctl -n hw.ncpu) FORTRAN=$BREWDIR/bin/gfortran OPTS="-O2" LOADER=gfortran lib
|
||||
cp slicot.a $DYNAREDIR/slicot/lib/libslicot_pic.a
|
||||
make clean
|
||||
make -j$(sysctl -n hw.physicalcpu) FORTRAN=gfortran OPTS="-O2 -fdefault-integer-8" LOADER=gfortran lib
|
||||
cp slicot.a /usr/local/lib/libslicot64_pic.a
|
||||
cd $HOME/dynare
|
||||
make -j$(sysctl -n hw.ncpu) FORTRAN=$BREWDIR/bin/gfortran OPTS="-O2 -fdefault-integer-8" LOADER=gfortran lib
|
||||
cp slicot.a $DYNAREDIR/slicot/lib/libslicot64_pic.a
|
||||
```
|
||||
|
||||
- Compile and install the X-13ARIMA-SEATS Seasonal Adjustment Program
|
||||
```sh
|
||||
mkdir -p $HOME/dynare/x13as
|
||||
cd $HOME/dynare/x13as
|
||||
wget https://www2.census.gov/software/x-13arima-seats/x13as/unix-linux/program-archives/x13as_asciisrc-v1-1-b58.tar.gz
|
||||
tar xf x13as_asciisrc-v1-1-b58.tar.gz
|
||||
mkdir -p $DYNAREDIR/x13as
|
||||
cd $DYNAREDIR/x13as
|
||||
curl -O https://www2.census.gov/software/x-13arima-seats/x13as/unix-linux/program-archives/x13as_asciisrc-v1-1-b60.tar.gz
|
||||
tar xf x13as_asciisrc-v1-1-b60.tar.gz
|
||||
sed -i '' 's/-static//g' makefile.gf
|
||||
make -j$(sysctl -n hw.physicalcpu) -f makefile.gf FC=gfortran LINKER=gfortran FFLAGS="-O2 -std=legacy" PROGRAM=x13as
|
||||
cp x13as /usr/local/bin/x13as
|
||||
cd ;
|
||||
make -j$(sysctl -n hw.ncpu) -f makefile.gf FC=$BREWDIR/bin/gfortran LINKER=$BREWDIR/bin/gcc-13 FFLAGS="-O2 -std=legacy" LDFLAGS=-static-libgcc LIBS="$BREWDIR/lib/gcc/current/libgfortran.a /$BREWDIR/lib/gcc/current/libquadmath.a" PROGRAM=x13as
|
||||
sudo cp $DYNAREDIR/x13as/x13as /usr/local/bin/x13as
|
||||
cd $DYNAREDIR
|
||||
x13as
|
||||
```
|
||||
Alternatively, if you don't have admin privileges you can install it into `$HOME/.local/bin` and add this folder to your PATH.
|
||||
|
||||
### Compile Dynare from source
|
||||
The following commands will download the Dynare source code and compile
|
||||
it. They should be entered at the command prompt in Terminal.app from the
|
||||
folder where you want Dynare installed. Apple Silicon: make sure `brew`
|
||||
points towards `/usr/local/bin/brew` (see above).
|
||||
folder where you want Dynare installed.
|
||||
|
||||
- Prepare the Dynare sources for the unstable version:
|
||||
```sh
|
||||
mkdir -p $HOME/dynare/unstable
|
||||
git clone --recurse-submodules https://git.dynare.org/Dynare/dynare.git $HOME/dynare/unstable
|
||||
cd $HOME/dynare/unstable
|
||||
arch -x86_64 autoreconf -si
|
||||
git clone --recurse-submodules https://git.dynare.org/Dynare/dynare.git $DYNAREDIR/unstable
|
||||
cd $DYNAREDIR/unstable
|
||||
```
|
||||
You can also choose a specific version of Dynare by checking out the corresponding branch or a specific tag with git.
|
||||
If you want a certain version (e.g. 5.x) , then add `--single-branch --branch 5.x` to the git clone command.
|
||||
|
||||
- Configure Dynare from the source directory:
|
||||
```sh
|
||||
arch -x86_64 ./configure CC=gcc-12 CXX=g++-12 CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib LEX=/usr/local/opt/flex/bin/flex YACC=/usr/local/opt/bison/bin/bison --with-matlab=/Applications/MATLAB_R2021b.app
|
||||
export BUILDDIR=build-matlab
|
||||
export MATLABPATH=/Applications/MATLAB_R2023b.app
|
||||
arch -$ARCH meson setup --native-file macOS/homebrew-native-$ARCH.ini -Dmatlab_path=$MATLABPATH -Dbuildtype=debugoptimized -Dfortran_args="['-B','$DYNAREDIR/slicot/lib']" $BUILDDIR
|
||||
```
|
||||
where you need to adapt the path to MATLAB. If you don’t have MATLAB, simply replace `--with-matlab=<…>` by `--disable-matlab`. Check the output of the command whether Dynare is configured for building everything except the internal docs of Dynare and M2HTML.
|
||||
where you need to adapt the path to MATLAB.
|
||||
Similarly, if you want to compile for Octave, replace the `-Dmatlab_path` option by `-Dbuild_for=octave`, and change the build directory to `build-octave`.
|
||||
|
||||
- Compile:
|
||||
```sh
|
||||
arch -x86_64 make -j$(sysctl -n hw.physicalcpu)
|
||||
arch -$ARCH meson compile -C $BUILDDIR
|
||||
```
|
||||
If no errors occured, you are done. Dynare is now ready to use.
|
||||
|
||||
- If you additionally want to compile the documentation run:
|
||||
```sh
|
||||
arch -$ARCH meson compile -C $BUILDDIR doc
|
||||
```
|
||||
|
||||
### Optional: pass the full PATH to MATLAB to run system commands
|
||||
If you start MATLAB from a terminal, you will get the PATH inherited from the shell. However, when you click on the icon in macOS, you are not running at the terminal: the program is run by launcher, which does not go through a shell login session. You get the system default PATH which includes `/usr/bin:/bin:/usr/sbin:/sbin`, but not `/usr/local/bin` or `$HOME/.local/bin`. So if you want to use system commands like `pdflatex` or `x13as` you should either call them by their full path (e.g `/Library/TeX/texbin/pdflatex`) or append the PATH in MATLAB by running `setenv('PATH', [getenv('PATH') ':/usr/local/bin:$HOME/.local/bin:/Library/TeX/texbin']);`. Alternatively, you can create a `startup.m` file or change the system default PATH in the `/etc/paths` file.
|
||||
- Optionally, run the testsuite:
|
||||
```sh
|
||||
arch -$ARCH meson test -C $BUILDDIR --num-processes=$(sysctl -n hw.perflevel0.physicalcpu)
|
||||
```
|
||||
where `--num-processes` specifies the number of parallel processes to use for the testsuite (here set to the number of performance cores on your mac).
|
||||
|
||||
Tested on
|
||||
- macOS Monterey 12.1 (Apple M1 Virtual Machine)
|
||||
- macOS Monterey 12.1 (MacBook Air Intel)
|
||||
- macOS Monterey 12.1 (MacBook Air M1)
|
||||
### Optional: pass the full PATH to MATLAB to run system commands
|
||||
If you start MATLAB from a terminal, you will get the PATH inherited from the shell.
|
||||
However, when you click on the application icon in macOS, you are not running at the terminal level:
|
||||
the program is run by launcher, which does not go through a shell login session.
|
||||
In other words, you get the system default PATH which includes `/usr/bin:/bin:/usr/sbin:/sbin`, but not `/usr/local/bin` or `$HOME/.local/bin`.
|
||||
So if you want to use system commands like `pdflatex`, `latexmk` or `x13as` you should either call them by their full path (e.g `/Library/TeX/texbin/pdflatex`)
|
||||
or append the PATH by running `setenv('PATH', [getenv('PATH') ':/usr/local/bin:$HOME/.local/bin:/Library/TeX/texbin']);` in your MATLAB command line once,
|
||||
e.g. by adding this to your mod file. Alternatively, you can create a `startup.m` file or change the system default PATH in the `/etc/paths` file.
|
||||
|
||||
|
||||
## Docker
|
||||
We offer a variety of pre-configured Docker containers for Dynare, pre-configured with Octave and MATLAB including all recommended toolboxes.
|
||||
These are readily available for your convenience on [Docker Hub](https://hub.docker.com/r/dynare/dynare).
|
||||
The `scripts/docker` folder contains [information and instructions](scripts/docker/README.md) to interact, built and customize the containers.
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
@PACKAGE_VERSION@
|
151
configure.ac
151
configure.ac
|
@ -1,151 +0,0 @@
|
|||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
dnl Copyright © 2009-2023 Dynare Team
|
||||
dnl
|
||||
dnl This file is part of Dynare.
|
||||
dnl
|
||||
dnl Dynare is free software: you can redistribute it and/or modify
|
||||
dnl it under the terms of the GNU General Public License as published by
|
||||
dnl the Free Software Foundation, either version 3 of the License, or
|
||||
dnl (at your option) any later version.
|
||||
dnl
|
||||
dnl Dynare is distributed in the hope that it will be useful,
|
||||
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
dnl GNU General Public License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License
|
||||
dnl along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
AC_PREREQ([2.62])
|
||||
AC_INIT([dynare], [6-unstable])
|
||||
AC_CONFIG_SRCDIR([preprocessor/src/DynareMain.cc])
|
||||
AM_INIT_AUTOMAKE([1.11 -Wall -Wno-portability foreign no-dist-gzip dist-xz tar-pax])
|
||||
|
||||
AC_CONFIG_SUBDIRS([preprocessor])
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
case ${host_os} in
|
||||
*cygwin*)
|
||||
AC_MSG_WARN([You are compiling for the Cygwin target. This means that the preprocessor will])
|
||||
AC_MSG_WARN([not run from MATLAB unless you add the Cygwin DLL to the path.])
|
||||
AC_MSG_WARN([This is probably not what you want. Consider using a MinGW cross-compiler.])
|
||||
if test -z "$F77"; then
|
||||
# On Cygwin 1.7, g77 comes has version 3, and is not compatible with default gcc/g++ which has version 4
|
||||
# And by default, the AC_PROG_F77 will pick up g77 if it is present (even if gfortran is also here)
|
||||
F77=gfortran
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# Use C++ for testing headers
|
||||
AC_LANG([C++])
|
||||
|
||||
AM_CXXFLAGS="-std=gnu++20 -Wall -Wno-dangling-else -Wextra -Wno-unused-parameter -Wold-style-cast"
|
||||
AC_SUBST([AM_CXXFLAGS])
|
||||
|
||||
# If default 'ar' is not available, try to find one with a host prefix (see ticket #145)
|
||||
AC_CHECK_PROGS([AR], [ar ${host_alias}-ar])
|
||||
|
||||
AC_PROG_RANLIB
|
||||
AM_PROG_AR
|
||||
|
||||
AX_PROG_LN_S
|
||||
|
||||
AC_PROG_MKDIR_P
|
||||
|
||||
# Define optional components and their corresponding flags and Automake conditionals
|
||||
AC_ARG_ENABLE([doc], AS_HELP_STRING([--disable-doc], [disable compilation of documentation]), [], [enable_doc=yes])
|
||||
AM_CONDITIONAL([ENABLE_DOC], [test "$enable_doc" = yes])
|
||||
|
||||
AC_ARG_ENABLE([matlab], AS_HELP_STRING([--disable-matlab], [disable compilation of MEX files for MATLAB]), [], [enable_matlab=yes])
|
||||
AM_CONDITIONAL([ENABLE_MATLAB], [test "$enable_matlab" = yes])
|
||||
|
||||
AC_ARG_ENABLE([octave], AS_HELP_STRING([--disable-octave], [disable compilation of MEX files for Octave]), [], [enable_octave=yes])
|
||||
AM_CONDITIONAL([ENABLE_OCTAVE], [test "$enable_octave" = yes])
|
||||
|
||||
AC_ARG_ENABLE([org-export], AS_HELP_STRING([--enable-org-export], [enable exporting of Org files (requires Emacs, org-mode and other external programs)]))
|
||||
AM_CONDITIONAL([ENABLE_ORG_EXPORT], [test -n "$enable_org_export"])
|
||||
|
||||
# Check utilities needed for documentation
|
||||
if test "$enable_doc" = yes; then
|
||||
AC_CHECK_PROG([PDFLATEX], [pdflatex], [pdflatex], [no])
|
||||
test "$PDFLATEX" = no && AC_MSG_ERROR([pdflatex cannot be found. If you want to skip the compilation of the documentation, pass the --disable-doc flag.])
|
||||
AC_CHECK_PROG([BIBTEX], [bibtex], [bibtex], [no])
|
||||
test "$BIBTEX" = no && AC_MSG_ERROR([bibtex cannot be found. If you want to skip the compilation of the documentation, pass the --disable-doc flag.])
|
||||
AC_CHECK_PROG([SPHINXBUILD], [sphinx-build], [sphinx-build], [no])
|
||||
test "$SPHINXBUILD" = no && AC_MSG_ERROR([sphinx-build cannot be found. If you want to skip the compilation of the documentation, pass the --disable-doc flag.])
|
||||
AX_LATEX_CLASS([beamer], [ax_latex_have_beamer], [], [AC_MSG_ERROR([beamer cannot be found. If you want to skip the compilation of the documentation, pass the --disable-doc flag.])])
|
||||
fi
|
||||
|
||||
# Check for MATLAB
|
||||
if test "$enable_matlab" = yes; then
|
||||
AC_CONFIG_SUBDIRS([mex/build/matlab])
|
||||
AX_MATLAB
|
||||
AX_MATLAB_BATCH_OPTIONS
|
||||
test "$ax_enable_matlab" != yes && AC_MSG_ERROR([MATLAB cannot be found. If you want to compile Dynare without MATLAB support, pass the --disable-matlab flag.])
|
||||
fi
|
||||
|
||||
# Check for Octave
|
||||
if test "$enable_octave" = yes; then
|
||||
AC_CONFIG_SUBDIRS([mex/build/octave])
|
||||
AX_OCTAVE
|
||||
test "$ax_enable_octave" != yes && AC_MSG_ERROR([Octave cannot be found. If you want to compile Dynare without Octave support, pass the --disable-octave flag.])
|
||||
fi
|
||||
|
||||
# Construct final output message
|
||||
if test "$enable_doc" = yes; then
|
||||
BUILD_DOC="yes"
|
||||
else
|
||||
BUILD_DOC="no"
|
||||
fi
|
||||
|
||||
if test -n "$enable_org_export"; then
|
||||
BUILD_INTERNAL_DOC="yes"
|
||||
else
|
||||
BUILD_INTERNAL_DOC="no"
|
||||
fi
|
||||
|
||||
if test "$enable_matlab" = yes; then
|
||||
TESTSUITE_MATLAB="yes"
|
||||
else
|
||||
TESTSUITE_MATLAB="no"
|
||||
fi
|
||||
|
||||
if test "$enable_octave" = yes; then
|
||||
TESTSUITE_OCTAVE="yes"
|
||||
else
|
||||
TESTSUITE_OCTAVE="no"
|
||||
fi
|
||||
|
||||
AC_MSG_NOTICE([
|
||||
|
||||
Dynare is now configured for building the following components...
|
||||
|
||||
Documentation (with "make html pdf"):
|
||||
Manual and other documents $BUILD_DOC
|
||||
Dynare internal doc: $BUILD_INTERNAL_DOC
|
||||
|
||||
Testsuites (run with "make check"):
|
||||
Dynare for MATLAB: $TESTSUITE_MATLAB
|
||||
Dynare for Octave: $TESTSUITE_OCTAVE
|
||||
])
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
VERSION
|
||||
doc/Makefile
|
||||
doc/manual/Makefile
|
||||
doc/manual/utils/version.py
|
||||
doc/parallel/Makefile
|
||||
doc/internals/Makefile
|
||||
doc/gsa/Makefile
|
||||
doc/dseries-and-reporting/Makefile
|
||||
tests/Makefile
|
||||
matlab/dynare_version.m
|
||||
mex/sources/Makefile
|
||||
])
|
||||
|
||||
AC_OUTPUT
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 5a58fafdca239e61be4d7b2270307b2445bb571a
|
|
@ -1 +1 @@
|
|||
Subproject commit f1d0fd61ea6d9c4f8694b373780d6c372e344f6e
|
||||
Subproject commit 391689d9f1bea4bd68ef6641dc2dc4a1bd867850
|
|
@ -1 +1 @@
|
|||
Subproject commit 216abedb9ab4df5dd4dca07c721f7c07392801e9
|
||||
Subproject commit ac6d0ae1b69cda26aa9486188d54c8c010f115c4
|
|
@ -1,26 +0,0 @@
|
|||
SUBDIRS = parallel internals gsa dseries-and-reporting
|
||||
|
||||
if ENABLE_DOC
|
||||
SUBDIRS += manual
|
||||
pdf-local: guide.pdf bvar-a-la-sims.pdf dr.pdf
|
||||
endif
|
||||
|
||||
EXTRA_DIST = guide.tex guide.bbl bibmad.sty bvar-a-la-sims.tex dr.tex dr.bib dynare.plots
|
||||
|
||||
guide.pdf: guide.tex guide.bbl bibmad.sty
|
||||
$(PDFLATEX) guide
|
||||
$(PDFLATEX) guide
|
||||
|
||||
bvar-a-la-sims.pdf: bvar-a-la-sims.tex
|
||||
$(PDFLATEX) bvar-a-la-sims
|
||||
$(PDFLATEX) bvar-a-la-sims
|
||||
|
||||
dr.pdf: dr.tex
|
||||
$(PDFLATEX) dr
|
||||
$(BIBTEX) dr
|
||||
$(PDFLATEX) dr
|
||||
$(PDFLATEX) dr
|
||||
|
||||
clean-local:
|
||||
# Do not delete guide.bbl which is not autogenerated
|
||||
rm -f *~ *.pdf *.log *.aux *.out *.blg dr.bbl
|
105
doc/bibmad.sty
105
doc/bibmad.sty
|
@ -1,105 +0,0 @@
|
|||
\message{harvard bibliography,}
|
||||
|
||||
\def\@hiteml[#1]#2#3#4{\item[]\if@filesw%
|
||||
{ \def\protect##1{\string ##1\space}\immediate%
|
||||
\write\@auxout{\string\harvardcite{#4}{#2}{#1}{#3}}}\fi%
|
||||
\protect\hspace*{-\labelwidth}\protect\hspace*{-\labelsep}\ignorespaces}
|
||||
|
||||
\def\@hitem#1#2#3{\item[]\if@filesw%
|
||||
{ \def\protect##1{\string ##1\space}\immediate%
|
||||
\write\@auxout{\string\harvardcite{#3}{#1}{#1}{#2}}}\fi%
|
||||
\protect\hspace*{-\labelwidth}\protect\hspace*{-\labelsep}\ignorespaces}
|
||||
|
||||
\def\harvarditem{\@ifnextchar [{\@hiteml}{\@hitem}}
|
||||
|
||||
\def\harvardcite#1#2#3#4{
|
||||
\global\@namedef{bhf@#1}{#2}
|
||||
\global\@namedef{bha@#1}{#3}
|
||||
\global\@namedef{bhy@#1}{#4}\global\@namedef{b@#1}{\csname bhf@#1\endcsname}
|
||||
}
|
||||
|
||||
\def\citeasnoun{\@ifnextchar [{\@tempswatrue\@citex}{\@tempswafalse\@citex[]}}
|
||||
\def\cite{\@ifnextchar [{\@tempswatrue\@citexasnoun}
|
||||
{\@tempswafalse\@citexasnoun[]}
|
||||
}
|
||||
\def\citeyear{\@ifnextchar [{\@tempswatrue\@citexyear}
|
||||
{\@tempswafalse\@citexyear[]}
|
||||
}
|
||||
\def\citename{\@ifnextchar [{\@tempswatrue\@citexname}
|
||||
{\@tempswafalse\@citexname[]}
|
||||
}
|
||||
|
||||
% \def\@enamedef#1{\expandafter\edef\csname #1\endcsname}
|
||||
% Previous line should be replaced by the following to prevent
|
||||
% problems with the NFSS. Solution by Bernd Raichle.
|
||||
\def\@enamedef#1{\expandafter\def\csname #1\expandafter\endcsname\expandafter}
|
||||
|
||||
\def\@citex[#1]#2{\if@filesw\immediate\write\@auxout{\string\citation{#2}}\fi
|
||||
\def\@citea{}\@cite{\@for\@citeb:=#2\do
|
||||
{\@citea\def\@citea{\@hisep\penalty\@m\ }\@ifundefined
|
||||
{b@\@citeb}{{\bf ?}\@warning
|
||||
{Citation `\@citeb' on page \thepage \space undefined}}%
|
||||
{{\csname b@\@citeb\endcsname\@hysep\csname bhy@\@citeb\endcsname}%
|
||||
\global\@enamedef{b@\@citeb}{\csname bha@\@citeb\endcsname}}%
|
||||
}}{#1}}
|
||||
|
||||
\def\@citexasnoun[#1]#2{%
|
||||
\if@filesw\immediate\write\@auxout{\string\citation{#2}}\fi%
|
||||
\@citeasnoun{{\@ifundefined%
|
||||
{b@#2}%
|
||||
{[{\bf ?}\@warning{Citation `#2' on page \thepage \space undefined}}%
|
||||
{{\csname b@#2\endcsname\ [\csname bhy@#2\endcsname}%
|
||||
\global\@namedef{b@#2}{\csname bha@#2\endcsname}}%
|
||||
}}{#1}}
|
||||
|
||||
\def\@citexname[#1]#2{%
|
||||
\if@filesw\immediate\write\@auxout{\string\citation{#2}}\fi%
|
||||
\@citename{{\@ifundefined%
|
||||
{b@#2}%
|
||||
{{\bf ?}\@warning{Citation `#2' on page \thepage \space undefined}}%
|
||||
{{\csname bhf@#2\endcsname}}%
|
||||
}}{#1}}
|
||||
|
||||
\def\@citexyear[#1]#2{\if@filesw\immediate\write\@auxout{\string\citation{#2}}\fi
|
||||
\def\@citeayear{}\@cite{\@for\@citebyear:=#2\do
|
||||
{\@citeayear\def\@citeayear{\@hisep\penalty\@m\ }\@ifundefined
|
||||
{b@\@citebyear}{{\bf ?}\@warning
|
||||
{Citation `\@citebyear' on page \thepage \space undefined}}%
|
||||
{{\csname bhy@\@citebyear\endcsname}%
|
||||
}%
|
||||
}}{#1}}
|
||||
|
||||
\gdef\hysep@agsm{\ }\gdef\hisep@agsm{,}%
|
||||
\gdef\hysep@dcu{, }\gdef\hisep@dcu{;}%
|
||||
\let\@hysep\hysep@agsm \let\@hisep\hisep@agsm
|
||||
\def\citationstyle#1{%
|
||||
\global\@namedef{@hysep}{\csname hysep@#1\endcsname}%
|
||||
\global\@namedef{@hisep}{\csname hisep@#1\endcsname}}
|
||||
|
||||
%DEFAULT DEFINITIONS
|
||||
\def\@cite#1#2{({#1\if@tempswa , #2\fi})}
|
||||
\def\@citeasnoun#1#2{{#1\if@tempswa , #2\fi]}}
|
||||
\def\@citename#1#2{{#1\if@tempswa \ (#2)\fi}}
|
||||
|
||||
% CHANGE \end{document} - to handle double definitions
|
||||
\def\enddocument{\@checkend{document}\clearpage\begingroup
|
||||
\if@filesw \immediate\closeout\@mainaux
|
||||
\def\global\@namedef##1##2{}\def\newlabel{\@testdef r}%
|
||||
\def\bibcite{\@testdef b}%
|
||||
\def\harvardcite{\@testbibh}\@tempswafalse \makeatletter\input \jobname.aux
|
||||
\if@tempswa \@warning{Label(s) may have changed. Rerun to get
|
||||
cross-references right}\fi\fi\endgroup\deadcycles\z@\@@end}
|
||||
|
||||
\def\@testbibh #1#2#3{
|
||||
\def\@tempa{#2}\expandafter
|
||||
\ifx \csname bhf@#1\endcsname \@tempa
|
||||
\def\@tempa{#3}\expandafter
|
||||
\ifx \csname bha@#1\endcsname \@tempa
|
||||
\else \@tempswatrue
|
||||
\fi
|
||||
\else
|
||||
\@tempswatrue
|
||||
\fi
|
||||
}
|
||||
|
||||
%
|
|
@ -26,7 +26,7 @@
|
|||
}}
|
||||
|
||||
\author{S\'ebastien Villemot\thanks{Paris School of Economics and
|
||||
CEPREMAP.} \and Johannes Pfeifer\thanks{Universität der Bundeswehr München. E-mail: \href{mailto:johannes.pfeifer@unibw.de}{\texttt{johannes.pfeifer@unibw.de}}.}}
|
||||
CEPREMAP.} \and Johannes Pfeifer\thanks{University of the Bundeswehr Munich. E-mail: \href{mailto:johannes.pfeifer@unibw.de}{\texttt{johannes.pfeifer@unibw.de}}.}}
|
||||
\date{First version: September 2007 \hspace{1cm} This version: May 2017}
|
||||
|
||||
\maketitle
|
||||
|
|
|
@ -650,7 +650,7 @@ equation is:
|
|||
In the general case, this equation is a specialized Sylvester equation, which
|
||||
can be solved using the algorithm proposed by
|
||||
\citet{kamenik:2004}\footnote{This paper is distributed with Dynare, in the
|
||||
\texttt{sylvester.pdf} file under the Dynare++ documentation directory.}.
|
||||
\texttt{sylvester.pdf} file under the documentation directory.}.
|
||||
|
||||
\bibliographystyle{elsarticle-harv}
|
||||
\bibliography{dr}
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
if ENABLE_DOC
|
||||
pdf-local: dseriesReporting.pdf
|
||||
endif
|
||||
|
||||
SRC = dseriesReporting.tex
|
||||
|
||||
EXTRA_DIST = $(SRC)
|
||||
|
||||
dseriesReporting.pdf: $(SRC)
|
||||
$(PDFLATEX) dseriesReporting
|
||||
$(PDFLATEX) dseriesReporting
|
||||
|
||||
clean-local:
|
||||
rm -f dseriesReporting.pdf *.toc *.aux *.log *.nav *.snm *.vrb *.out *~
|
|
@ -1,16 +0,0 @@
|
|||
if ENABLE_DOC
|
||||
pdf-local: gsa.pdf
|
||||
endif
|
||||
|
||||
SRC = gsa.tex marco.bib
|
||||
|
||||
EXTRA_DIST = $(SRC)
|
||||
|
||||
gsa.pdf: $(SRC)
|
||||
$(PDFLATEX) gsa
|
||||
$(BIBTEX) gsa
|
||||
$(PDFLATEX) gsa
|
||||
$(PDFLATEX) gsa
|
||||
|
||||
clean-local:
|
||||
rm -f *.pdf *.log *.aux *.toc *.lof *.blg *.bbl *.out *~
|
139
doc/gsa/gsa.tex
139
doc/gsa/gsa.tex
|
@ -22,7 +22,7 @@
|
|||
\begin{document}
|
||||
|
||||
% ----------------------------------------------------------------
|
||||
\title{Sensitivity Analysis Toolbox for DYNARE\thanks{Copyright \copyright~2012 Dynare
|
||||
\title{Sensitivity Analysis Toolbox for Dynare\thanks{Copyright \copyright~2012-2024 Dynare
|
||||
Team. Permission is granted to copy, distribute and/or modify
|
||||
this document under the terms of the GNU Free Documentation
|
||||
License, Version 1.3 or any later version published by the Free
|
||||
|
@ -32,9 +32,9 @@
|
|||
|
||||
\author{Marco Ratto\\
|
||||
European Commission, Joint Research Centre \\
|
||||
TP361, IPSC, \\21027 Ispra
|
||||
TP581\\21027 Ispra
|
||||
(VA) Italy\\
|
||||
\texttt{marco.ratto@jrc.ec.europa.eu}
|
||||
\texttt{Marco.Ratto@ec.europa.eu}
|
||||
\thanks{The author gratefully thanks Christophe Planas, Kenneth Judd, Michel Juillard,
|
||||
Alessandro Rossi, Frank Schorfheide and the participants to the
|
||||
Courses on Global Sensitivity Analysis for Macroeconomic
|
||||
|
@ -52,21 +52,21 @@ helpful suggestions.}}
|
|||
|
||||
%-----------------------------------------------------------------------
|
||||
\begin{abstract}
|
||||
\noindent The Sensitivity Analysis Toolbox for DYNARE is a set of
|
||||
\noindent The Sensitivity Analysis Toolbox for Dynare is a set of
|
||||
MATLAB routines for the analysis of DSGE models with global
|
||||
sensitivity analysis. The routines are thought to be used within
|
||||
the DYNARE v4 environment.
|
||||
the Dynare 6 environment.
|
||||
|
||||
|
||||
\begin{description}
|
||||
\item \textbf{Keywords}: Stability Mapping , Reduced form solution, DSGE models,
|
||||
Monte Carlo filtering, Global Sensitivity Analysis.
|
||||
Monte Carlo filtering, Global Sensitivity Analysis.
|
||||
\end{description}
|
||||
\end{abstract}
|
||||
\newpage
|
||||
% ----------------------------------------------------------------
|
||||
\section{Introduction} \label{s:intro}
|
||||
The Sensitivity Analysis Toolbox for DYNARE is a collection of
|
||||
The Sensitivity Analysis Toolbox for Dynare is a collection of
|
||||
MATLAB routines implemented to answer the following questions: (i)
|
||||
Which is the domain of structural coefficients assuring the
|
||||
stability and determinacy of a DSGE model? (ii) Which parameters
|
||||
|
@ -81,20 +81,18 @@ described in \cite{Ratto_CompEcon_2008}.
|
|||
|
||||
|
||||
\section{Use of the Toolbox}
|
||||
The DYNARE parser now recognizes sensitivity analysis commands.
|
||||
The Dynare parser now recognizes sensitivity analysis commands.
|
||||
The syntax is based on a single command:
|
||||
\vspace{0.5cm}
|
||||
|
||||
\verb"dynare_sensitivity(option1=<opt1_val>,option2=<opt2_val>,...)"
|
||||
\verb"sensitivity(option1=<opt1_val>,option2=<opt2_val>,...)"
|
||||
|
||||
\vspace{0.5cm} \noindent with a list of options described in the
|
||||
next section.
|
||||
|
||||
With respect to the previous version of the toolbox, in order to
|
||||
work properly, the sensitivity analysis Toolbox \emph{no longer}
|
||||
needs that the DYNARE estimation environment is set-up.
|
||||
|
||||
Therefore, \verb"dynare_sensitivity" is the only command to run to
|
||||
In order to work properly, the sensitivity analysis Toolbox does not need
|
||||
a Dynare estimation environment to be set up. Rather, \verb"sensitivity"
|
||||
is the only command to run to
|
||||
make a sensitivity analysis on a DSGE model\footnote{Of course,
|
||||
when the user needs to perform the mapping of the fit with a
|
||||
posterior sample, a Bayesian estimation has to be performed
|
||||
|
@ -208,16 +206,17 @@ a multivariate normal MC sample, with covariance matrix based on
|
|||
the inverse Hessian at the optimum: this analysis is useful when
|
||||
ML estimation is done (i.e. no Bayesian estimation);
|
||||
\item when \verb"ppost=1" the Toolbox analyses
|
||||
the RMSE's for the posterior sample obtained by DYNARE's
|
||||
the RMSE's for the posterior sample obtained by Dynare's
|
||||
Metropolis procedure.
|
||||
\end{enumerate}
|
||||
|
||||
The use of cases 2. and 3. requires an estimation step beforehand!
|
||||
The use of cases 2. and 3. require an estimation step beforehand!
|
||||
To facilitate the sensitivity analysis after estimation, the
|
||||
\verb"dynare_sensitivity" command also allows to indicate some
|
||||
options of \verb"dynare_estimation". These are:
|
||||
\verb"sensitivity" command also allows to indicate some
|
||||
options of \verb"estimation". These are:
|
||||
\begin{itemize}
|
||||
\item \verb"datafile"
|
||||
\item \verb"diffuse_filter"
|
||||
\item \verb"mode_file"
|
||||
\item \verb"first_obs"
|
||||
\item \verb"lik_init"
|
||||
|
@ -278,10 +277,10 @@ identifiable.
|
|||
\end{tabular}
|
||||
|
||||
\vspace{1cm}
|
||||
\noindent For example, the following commands in the DYNARE model file
|
||||
\noindent For example, the following commands in the Dynare model file
|
||||
|
||||
\vspace{1cm}
|
||||
\noindent\verb"dynare_sensitivity(identification=1, morris=2);"
|
||||
\noindent\verb"sensitivity(identification=1, morris=2);"
|
||||
|
||||
\vspace{1cm}
|
||||
\noindent trigger the identification analysis using \cite{Iskrev2010,Iskrev2011}, jointly with the mapping of the acceptable region.
|
||||
|
@ -293,75 +292,75 @@ Sensitivity analysis results are saved on the hard-disk of the
|
|||
computer. The Toolbox uses a dedicated folder called \verb"GSA",
|
||||
located in \\
|
||||
\\
|
||||
\verb"<DYNARE_file>\GSA", \\
|
||||
\verb"<Dynare_file>\GSA", \\
|
||||
\\
|
||||
where \verb"<DYNARE_file>.mod" is the name of the DYNARE model
|
||||
where \verb"<Dynare_file>.mod" is the name of the Dynare model
|
||||
file.
|
||||
|
||||
\subsection{Binary data files}
|
||||
A set of binary data files is saved in the \verb"GSA" folder:
|
||||
\begin{description}
|
||||
\item[]\verb"<DYNARE_file>_prior.mat": this file stores
|
||||
\item[]\verb"<Dynare_file>_prior.mat": this file stores
|
||||
information about the analyses performed sampling from the prior
|
||||
ranges, i.e. \verb"pprior=1" and \verb"ppost=0";
|
||||
\item[]\verb"<DYNARE_file>_mc.mat": this file stores
|
||||
\item[]\verb"<Dynare_file>_mc.mat": this file stores
|
||||
information about the analyses performed sampling from
|
||||
multivariate normal, i.e. \verb"pprior=0" and \verb"ppost=0";
|
||||
\item[]\verb"<DYNARE_file>_post.mat": this file stores information
|
||||
\item[]\verb"<Dynare_file>_post.mat": this file stores information
|
||||
about analyses performed using the Metropolis posterior sample,
|
||||
i.e. \verb"ppost=1".
|
||||
\end{description}
|
||||
|
||||
\begin{description}
|
||||
\item[]\verb"<DYNARE_file>_prior_*.mat": these files store
|
||||
\item[]\verb"<Dynare_file>_prior_*.mat": these files store
|
||||
the filtered and smoothed variables for the prior MC sample,
|
||||
generated when doing RMSE analysis (\verb"pprior=1" and
|
||||
\verb"ppost=0");
|
||||
\item[]\verb"<DYNARE_file>_mc_*.mat": these files store
|
||||
\item[]\verb"<Dynare_file>_mc_*.mat": these files store
|
||||
the filtered and smoothed variables for the multivariate normal MC
|
||||
sample, generated when doing RMSE analysis (\verb"pprior=0" and
|
||||
\verb"ppost=0").
|
||||
\end{description}
|
||||
|
||||
\subsection{Stability analysis}
|
||||
Figure files \verb"<DYNARE_file>_prior_*.fig" store results for
|
||||
Figure files \verb"<Dynare_file>_prior_*.fig" store results for
|
||||
the stability mapping from prior MC samples:
|
||||
\begin{description}
|
||||
\item[]\verb"<DYNARE_file>_prior_stab_SA_*.fig": plots of the Smirnov
|
||||
test analyses confronting the cdf of the sample fulfilling
|
||||
Blanchard-Kahn conditions with the cdf of the rest of the sample;
|
||||
\item[]\verb"<DYNARE_file>_prior_stab_indet_SA_*.fig": plots of the Smirnov
|
||||
test analyses confronting the cdf of the sample producing
|
||||
indeterminacy with the cdf of the original prior sample;
|
||||
\item[]\verb"<DYNARE_file>_prior_stab_unst_SA_*.fig": plots of the Smirnov
|
||||
test analyses confronting the cdf of the sample producing unstable
|
||||
(explosive roots) behaviour with the cdf of the original prior
|
||||
\item[]\verb"<Dynare_file>_prior_stab_SA_*.fig": plots of the Smirnov
|
||||
test analyses confronting the CDF of the sample fulfilling
|
||||
Blanchard-Kahn conditions with the CDF of the rest of the sample;
|
||||
\item[]\verb"<Dynare_file>_prior_stab_indet_SA_*.fig": plots of the Smirnov
|
||||
test analyses confronting the CDF of the sample producing
|
||||
indeterminacy with the CDF of the original prior sample;
|
||||
\item[]\verb"<Dynare_file>_prior_stab_unst_SA_*.fig": plots of the Smirnov
|
||||
test analyses confronting the CDF of the sample producing unstable
|
||||
(explosive roots) behaviour with the CDF of the original prior
|
||||
sample;
|
||||
\item[]\verb"<DYNARE_file>_prior_stable_corr_*.fig": plots of
|
||||
\item[]\verb"<Dynare_file>_prior_stable_corr_*.fig": plots of
|
||||
bivariate projections of the sample fulfilling Blanchard-Kahn
|
||||
conditions;
|
||||
\item[]\verb"<DYNARE_file>_prior_indeterm_corr_*.fig": plots of
|
||||
\item[]\verb"<Dynare_file>_prior_indeterm_corr_*.fig": plots of
|
||||
bivariate projections of the sample producing indeterminacy;
|
||||
\item[]\verb"<DYNARE_file>_prior_unstable_corr_*.fig": plots of
|
||||
\item[]\verb"<Dynare_file>_prior_unstable_corr_*.fig": plots of
|
||||
bivariate projections of the sample producing instability;
|
||||
\item[]\verb"<DYNARE_file>_prior_unacceptable_corr_*.fig": plots of
|
||||
\item[]\verb"<Dynare_file>_prior_unacceptable_corr_*.fig": plots of
|
||||
bivariate projections of the sample producing unacceptable
|
||||
solutions, i.e. either instability or indeterminacy or the
|
||||
solution could not be found (e.g. the steady state solution could
|
||||
not be found by the solver).
|
||||
\end{description}
|
||||
Similar conventions apply for \verb"<DYNARE_file>_mc_*.fig" files,
|
||||
Similar conventions apply for \verb"<Dynare_file>_mc_*.fig" files,
|
||||
obtained when samples from multivariate normal are used.
|
||||
|
||||
\subsection{RMSE analysis}
|
||||
Figure files \verb"<DYNARE_file>_rmse_*.fig" store results for the
|
||||
Figure files \verb"<Dynare_file>_rmse_*.fig" store results for the
|
||||
RMSE analysis.
|
||||
\begin{description}
|
||||
\item[]\verb"<DYNARE_file>_rmse_prior*.fig": save results for
|
||||
\item[]\verb"<Dynare_file>_rmse_prior*.fig": save results for
|
||||
the analysis using prior MC samples;
|
||||
\item[]\verb"<DYNARE_file>_rmse_mc*.fig": save results for
|
||||
\item[]\verb"<Dynare_file>_rmse_mc*.fig": save results for
|
||||
the analysis using multivariate normal MC samples;
|
||||
\item[]\verb"<DYNARE_file>_rmse_post*.fig": save results for
|
||||
\item[]\verb"<Dynare_file>_rmse_post*.fig": save results for
|
||||
the analysis using Metropolis posterior samples.
|
||||
\end{description}
|
||||
|
||||
|
@ -369,33 +368,33 @@ The following types of figures are saved (we show prior sample to
|
|||
fix ideas, but the same conventions are used for multivariate
|
||||
normal and posterior):
|
||||
\begin{description}
|
||||
\item[]\verb"<DYNARE_file>_rmse_prior_*.fig": for each parameter, plots the cdf's
|
||||
\item[]\verb"<Dynare_file>_rmse_prior_*.fig": for each parameter, plots the CDF's
|
||||
corresponding to the best 10\% RMES's of each observed series;
|
||||
\item[]\verb"<DYNARE_file>_rmse_prior_dens_*.fig": for each parameter, plots the pdf's
|
||||
\item[]\verb"<Dynare_file>_rmse_prior_dens_*.fig": for each parameter, plots the pdf's
|
||||
corresponding to the best 10\% RMES's of each observed series;
|
||||
\item[]\verb"<DYNARE_file>_rmse_prior_<name of observedseries>_corr_*.fig": for each observed series plots the
|
||||
\item[]\verb"<Dynare_file>_rmse_prior_<name of observedseries>_corr_*.fig": for each observed series plots the
|
||||
bi-dimensional projections of samples with the best 10\% RMSE's,
|
||||
when the correlation is significant;
|
||||
\item[]\verb"<DYNARE_file>_rmse_prior_lnlik*.fig": for each observed
|
||||
series, plots \emph{in red} the cdf of the log-likelihood
|
||||
corresponding to the best 10\% RMSE's, \emph{in green} the cdf of
|
||||
the rest of the sample and \emph{in blue }the cdf of the full
|
||||
\item[]\verb"<Dynare_file>_rmse_prior_lnlik*.fig": for each observed
|
||||
series, plots \emph{in red} the CDF of the log-likelihood
|
||||
corresponding to the best 10\% RMSE's, \emph{in green} the CDF of
|
||||
the rest of the sample and \emph{in blue }the CDF of the full
|
||||
sample; this allows to see the presence of some idiosyncratic
|
||||
behaviour;
|
||||
\item[]\verb"<DYNARE_file>_rmse_prior_lnpost*.fig": for each observed
|
||||
series, plots \emph{in red} the cdf of the log-posterior
|
||||
corresponding to the best 10\% RMSE's, \emph{in green} the cdf of
|
||||
the rest of the sample and \emph{in blue }the cdf of the full
|
||||
\item[]\verb"<Dynare_file>_rmse_prior_lnpost*.fig": for each observed
|
||||
series, plots \emph{in red} the CDF of the log-posterior
|
||||
corresponding to the best 10\% RMSE's, \emph{in green} the CDF of
|
||||
the rest of the sample and \emph{in blue }the CDF of the full
|
||||
sample; this allows to see idiosyncratic behaviour;
|
||||
\item[]\verb"<DYNARE_file>_rmse_prior_lnprior*.fig": for each observed
|
||||
series, plots \emph{in red} the cdf of the log-prior corresponding
|
||||
to the best 10\% RMSE's, \emph{in green} the cdf of the rest of
|
||||
the sample and \emph{in blue }the cdf of the full sample; this
|
||||
\item[]\verb"<Dynare_file>_rmse_prior_lnprior*.fig": for each observed
|
||||
series, plots \emph{in red} the CDF of the log-prior corresponding
|
||||
to the best 10\% RMSE's, \emph{in green} the CDF of the rest of
|
||||
the sample and \emph{in blue }the CDF of the full sample; this
|
||||
allows to see idiosyncratic behaviour;
|
||||
\item[]\verb"<DYNARE_file>_rmse_prior_lik_SA_*.fig": when
|
||||
\item[]\verb"<Dynare_file>_rmse_prior_lik_SA_*.fig": when
|
||||
\verb"lik_only=1", this shows the Smirnov tests for the filtering
|
||||
of the best 10\% log-likelihood values;
|
||||
\item[]\verb"<DYNARE_file>_rmse_prior_post_SA_*.fig": when
|
||||
\item[]\verb"<Dynare_file>_rmse_prior_post_SA_*.fig": when
|
||||
\verb"lik_only=1", this shows the Smirnov test for the filtering
|
||||
of the best 10\% log-posterior values.
|
||||
\end{description}
|
||||
|
@ -405,19 +404,19 @@ In the case of the mapping of the reduced form solution, synthetic
|
|||
figures are saved in the \verb"\GSA" folder:
|
||||
|
||||
\begin{description}
|
||||
\item[]\verb"<DYNARE_file>_redform_<endo name>_vs_lags_*.fig":
|
||||
\item[]\verb"<Dynare_file>_redform_<endo name>_vs_lags_*.fig":
|
||||
shows bar charts of the sensitivity indices for the \emph{ten most
|
||||
important} parameters driving the reduced form coefficients of the
|
||||
selected endogenous variables (\verb"namendo") versus lagged
|
||||
endogenous variables (\verb"namlagendo"); suffix \verb"log"
|
||||
indicates the results for log-transformed entries;
|
||||
\item[]\verb"<DYNARE_file>_redform_<endo name>_vs_shocks_*.fig":
|
||||
\item[]\verb"<Dynare_file>_redform_<endo name>_vs_shocks_*.fig":
|
||||
shows bar charts of the sensitivity indices for the \emph{ten most
|
||||
important} parameters driving the reduced form coefficients of the
|
||||
selected endogenous variables (\verb"namendo") versus exogenous
|
||||
variables (\verb"namexo"); suffix \verb"log" indicates the results
|
||||
for log-transformed entries;
|
||||
\item[]\verb"<DYNARE_file>_redform_GSA(_log).fig": shows bar chart of
|
||||
\item[]\verb"<Dynare_file>_redform_GSA(_log).fig": shows bar chart of
|
||||
all sensitivity indices for each parameter: this allows to notice
|
||||
parameters that have a minor effect for \emph{any} of the reduced
|
||||
form coefficients,
|
||||
|
@ -449,24 +448,24 @@ without the need of any user's intervention.
|
|||
\subsection{Screening analysis}
|
||||
The results of the screening analysis with Morris sampling design
|
||||
are stored in the subfolder \verb"\GSA\SCREEN". The data file
|
||||
\verb"<DYNARE_file>_prior" stores all the information of the
|
||||
\verb"<Dynare_file>_prior" stores all the information of the
|
||||
analysis (Morris sample, reduced form coefficients, etc.).
|
||||
|
||||
Screening analysis merely concerns reduced form coefficients.
|
||||
Similar synthetic bar charts as for the reduced form analysis with
|
||||
MC samples are saved:
|
||||
\begin{description}
|
||||
\item[]\verb"<DYNARE_file>_redform_<endo name>_vs_lags_*.fig":
|
||||
\item[]\verb"<Dynare_file>_redform_<endo name>_vs_lags_*.fig":
|
||||
shows bar charts of the elementary effect tests for the \emph{ten
|
||||
most important} parameters driving the reduced form coefficients
|
||||
of the selected endogenous variables (\verb"namendo") versus
|
||||
lagged endogenous variables (\verb"namlagendo");
|
||||
\item[]\verb"<DYNARE_file>_redform_<endo name>_vs_shocks_*.fig":
|
||||
\item[]\verb"<Dynare_file>_redform_<endo name>_vs_shocks_*.fig":
|
||||
shows bar charts of the elementary effect tests for the \emph{ten
|
||||
most important} parameters driving the reduced form coefficients
|
||||
of the selected endogenous variables (\verb"namendo") versus
|
||||
exogenous variables (\verb"namexo");
|
||||
\item[]\verb"<DYNARE_file>_redform_screen.fig": shows bar chart of
|
||||
\item[]\verb"<Dynare_file>_redform_screen.fig": shows bar chart of
|
||||
all elementary effect tests for each parameter: this allows to
|
||||
identify parameters that have a minor effect for \emph{any} of the
|
||||
reduced form coefficients.
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
\ifx\undefined\bysame
|
||||
\newcommand{\bysame}{\leavevmode\hbox to\leftmargin{\hrulefill\,\,}}
|
||||
\fi
|
||||
\begin{thebibliography}{xx}
|
||||
|
||||
\harvarditem[Collard and Juillard]{Collard and Juillard}{2001}{COLL/JUIL/01a}
|
||||
{ Collard, F. and M.~Juillard}, Accuracy of stochastic perturbation methods:
|
||||
The case of asset pricing models, {\it Journal of Economic Dynamics and
|
||||
Control}, 2001, {\it 25}, 979--999.
|
||||
|
||||
\harvarditem[Schmitt-Grohe and Uribe]{Schmitt-Grohe and Uribe}{2002}{SGU/02}
|
||||
{ Schmitt-Grohe, S. and M.~Uribe}, {\it Solving Dynamic General Equilibrium
|
||||
Models Using a Second-Order Approximation to the Policy Function}, technical
|
||||
working paper, Rutgers Univsersity 2002.
|
||||
|
||||
\end{thebibliography}
|
|
@ -1,9 +0,0 @@
|
|||
EXTRA_DIST = dynare-internals.org
|
||||
|
||||
if ENABLE_ORG_EXPORT
|
||||
html-local:
|
||||
emacs --batch --visit=dynare-internals.org --funcall org-html-export-to-html
|
||||
endif
|
||||
|
||||
clean-local:
|
||||
rm -rf *.html ltxpng
|
|
@ -2,7 +2,6 @@ function build_internal_documentation()
|
|||
% The name of the function should be explicit...
|
||||
|
||||
datafiles = [];
|
||||
datafiles = [ datafiles ; {'../../matlab/utilities/dataset'}, {'initialize_dataset'}];
|
||||
datafiles = [ datafiles ; {'../../matlab/utilities/dataset'}, {'descriptive_statistics'}];
|
||||
datafiles = [ datafiles ; {'../../matlab/utilities/dataset'}, {'compute_stdv'}];
|
||||
datafiles = [ datafiles ; {'../../matlab/utilities/dataset'}, {'compute_cova'}];
|
||||
|
@ -81,4 +80,4 @@ if rows(miscfiles)
|
|||
fprintf(fid,'\n\n\n');
|
||||
end
|
||||
end
|
||||
fclose(fid);
|
||||
fclose(fid);
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
EXTRA_DIST = source \
|
||||
utils/dynare_dom.py \
|
||||
utils/dynare_lex.py
|
||||
|
||||
SRC = $(wildcard source/*.rst)
|
||||
|
||||
html-local: build/html/index.html
|
||||
|
||||
build/html/index.html: $(SRC) source/conf.py
|
||||
$(SPHINXBUILD) -M html source build
|
||||
|
||||
pdf-local: build/latex/dynare-manual.pdf
|
||||
|
||||
build/latex/dynare-manual.pdf: $(SRC) source/conf.py
|
||||
$(SPHINXBUILD) -M latexpdf source build
|
||||
|
||||
clean-local:
|
||||
rm -rf build
|
||||
rm -rf utils/__pycache__
|
|
@ -1,61 +1,53 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="86.514pt" height="34.182pt" viewBox="0 0 86.514 34.182" version="1.1">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="87.89pt" height="34.182pt" viewBox="0 0 87.89 34.182" version="1.1">
|
||||
<defs>
|
||||
<g>
|
||||
<symbol overflow="visible" id="glyph0-0">
|
||||
<path style="stroke:none;" d="M 3.09375 -14.140625 L 3.6875 -13.203125 C 3.78125 -13.015625 3.921875 -12.921875 4.140625 -12.921875 C 4.21875 -12.921875 4.328125 -12.953125 4.453125 -13.03125 C 4.5625 -13.109375 4.703125 -13.1875 4.875 -13.28125 C 5.03125 -13.375 5.234375 -13.453125 5.46875 -13.53125 C 5.6875 -13.609375 5.96875 -13.640625 6.3125 -13.640625 C 6.796875 -13.640625 7.171875 -13.515625 7.46875 -13.265625 C 7.765625 -13.015625 7.9375 -12.6875 7.9375 -12.265625 C 7.9375 -11.9375 7.859375 -11.640625 7.734375 -11.40625 C 7.59375 -11.15625 7.4375 -10.953125 7.234375 -10.765625 C 7.03125 -10.5625 6.8125 -10.390625 6.59375 -10.234375 C 6.375 -10.0625 6.15625 -9.890625 5.96875 -9.71875 C 5.78125 -9.546875 5.640625 -9.34375 5.53125 -9.125 C 5.421875 -8.921875 5.390625 -8.671875 5.421875 -8.40625 L 5.578125 -6.953125 L 7.09375 -6.953125 L 7.296875 -8.25 C 7.328125 -8.4375 7.40625 -8.609375 7.5625 -8.765625 C 7.703125 -8.90625 7.875 -9.0625 8.078125 -9.234375 C 8.28125 -9.375 8.484375 -9.546875 8.703125 -9.734375 C 8.9375 -9.90625 9.125 -10.109375 9.3125 -10.359375 C 9.5 -10.609375 9.671875 -10.890625 9.78125 -11.21875 C 9.90625 -11.546875 9.96875 -11.9375 9.96875 -12.40625 C 9.96875 -12.859375 9.890625 -13.28125 9.71875 -13.65625 C 9.546875 -14.03125 9.3125 -14.34375 9.015625 -14.625 C 8.703125 -14.875 8.34375 -15.078125 7.921875 -15.234375 C 7.5 -15.375 7.03125 -15.453125 6.5 -15.453125 C 6.125 -15.453125 5.765625 -15.40625 5.4375 -15.34375 C 5.125 -15.265625 4.8125 -15.171875 4.53125 -15.046875 C 4.25 -14.9375 3.984375 -14.796875 3.75 -14.640625 C 3.515625 -14.484375 3.296875 -14.3125 3.09375 -14.140625 Z M 4.90625 -3.625 C 4.90625 -3.21875 5.03125 -2.90625 5.296875 -2.640625 C 5.53125 -2.375 5.875 -2.25 6.265625 -2.25 C 6.4375 -2.25 6.609375 -2.28125 6.796875 -2.359375 C 6.953125 -2.421875 7.09375 -2.53125 7.21875 -2.65625 C 7.328125 -2.78125 7.421875 -2.90625 7.5 -3.078125 C 7.578125 -3.25 7.609375 -3.421875 7.609375 -3.625 C 7.609375 -3.796875 7.578125 -3.984375 7.5 -4.15625 C 7.421875 -4.328125 7.328125 -4.46875 7.21875 -4.59375 C 7.09375 -4.71875 6.953125 -4.8125 6.796875 -4.875 C 6.609375 -4.953125 6.4375 -5 6.265625 -5 C 5.875 -5 5.53125 -4.859375 5.296875 -4.59375 C 5.03125 -4.328125 4.90625 -4 4.90625 -3.625 Z M 0.5625 -17.75 L 0.5625 0 L 12.625 0 L 12.625 -17.75 Z M 1.171875 -0.671875 L 1.171875 -17.078125 L 11.921875 -17.078125 L 11.921875 -0.671875 Z M 1.171875 -0.671875 "/>
|
||||
<path style="stroke:none;" d="M 3.09375 -14.140625 L 3.6875 -13.203125 C 3.78125 -13.015625 3.921875 -12.921875 4.140625 -12.921875 C 4.21875 -12.921875 4.34375 -12.953125 4.453125 -13.03125 C 4.5625 -13.109375 4.703125 -13.203125 4.875 -13.28125 C 5.03125 -13.375 5.234375 -13.453125 5.46875 -13.53125 C 5.703125 -13.609375 5.984375 -13.640625 6.3125 -13.640625 C 6.796875 -13.640625 7.171875 -13.515625 7.484375 -13.265625 C 7.78125 -13.015625 7.9375 -12.6875 7.9375 -12.265625 C 7.9375 -11.9375 7.875 -11.640625 7.734375 -11.40625 C 7.59375 -11.171875 7.4375 -10.953125 7.234375 -10.765625 C 7.03125 -10.578125 6.828125 -10.390625 6.59375 -10.234375 C 6.375 -10.078125 6.171875 -9.90625 5.96875 -9.71875 C 5.796875 -9.546875 5.65625 -9.34375 5.53125 -9.140625 C 5.421875 -8.921875 5.390625 -8.6875 5.421875 -8.40625 L 5.578125 -6.953125 L 7.09375 -6.953125 L 7.296875 -8.25 C 7.328125 -8.4375 7.421875 -8.609375 7.5625 -8.765625 C 7.703125 -8.921875 7.875 -9.0625 8.078125 -9.234375 C 8.28125 -9.390625 8.484375 -9.546875 8.703125 -9.734375 C 8.9375 -9.90625 9.140625 -10.125 9.3125 -10.359375 C 9.515625 -10.609375 9.671875 -10.890625 9.78125 -11.21875 C 9.90625 -11.5625 9.96875 -11.9375 9.96875 -12.40625 C 9.96875 -12.859375 9.890625 -13.28125 9.71875 -13.65625 C 9.546875 -14.03125 9.3125 -14.359375 9.015625 -14.625 C 8.703125 -14.875 8.34375 -15.09375 7.9375 -15.234375 C 7.5 -15.375 7.03125 -15.453125 6.5 -15.453125 C 6.125 -15.453125 5.78125 -15.40625 5.453125 -15.34375 C 5.125 -15.28125 4.8125 -15.171875 4.53125 -15.0625 C 4.25 -14.9375 3.984375 -14.8125 3.765625 -14.640625 C 3.515625 -14.484375 3.3125 -14.328125 3.09375 -14.140625 Z M 4.90625 -3.625 C 4.90625 -3.234375 5.03125 -2.90625 5.296875 -2.65625 C 5.546875 -2.375 5.875 -2.25 6.265625 -2.25 C 6.453125 -2.25 6.625 -2.296875 6.796875 -2.359375 C 6.953125 -2.421875 7.09375 -2.53125 7.21875 -2.65625 C 7.328125 -2.78125 7.4375 -2.921875 7.515625 -3.078125 C 7.578125 -3.25 7.609375 -3.4375 7.609375 -3.625 C 7.609375 -3.796875 7.578125 -3.984375 7.515625 -4.15625 C 7.4375 -4.328125 7.328125 -4.46875 7.21875 -4.59375 C 7.09375 -4.71875 6.953125 -4.8125 6.796875 -4.875 C 6.625 -4.953125 6.453125 -5 6.265625 -5 C 5.875 -5 5.546875 -4.859375 5.296875 -4.59375 C 5.03125 -4.34375 4.90625 -4 4.90625 -3.625 Z M 0.5625 -17.75 L 0.5625 0 L 12.625 0 L 12.625 -17.75 Z M 1.171875 -0.671875 L 1.171875 -17.078125 L 11.921875 -17.078125 L 11.921875 -0.671875 Z M 1.171875 -0.671875 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-1">
|
||||
<path style="stroke:none;" d="M 17.65625 -8.875 C 17.65625 -10.203125 17.453125 -11.40625 17.03125 -12.5 C 16.609375 -13.59375 16.015625 -14.515625 15.234375 -15.296875 C 14.46875 -16.078125 13.546875 -16.6875 12.46875 -17.109375 C 11.390625 -17.53125 10.203125 -17.75 8.890625 -17.75 L 2.265625 -17.75 L 2.265625 0 L 8.890625 0 C 10.203125 0 11.390625 -0.203125 12.46875 -0.625 C 13.546875 -1.046875 14.46875 -1.65625 15.234375 -2.4375 C 16.015625 -3.203125 16.609375 -4.15625 17.03125 -5.234375 C 17.453125 -6.328125 17.65625 -7.53125 17.65625 -8.875 Z M 15.1875 -8.875 C 15.1875 -7.78125 15.046875 -6.796875 14.75 -5.953125 C 14.453125 -5.078125 14.03125 -4.359375 13.484375 -3.765625 C 12.9375 -3.171875 12.265625 -2.71875 11.5 -2.421875 C 10.71875 -2.09375 9.84375 -1.953125 8.890625 -1.953125 L 4.671875 -1.953125 L 4.671875 -15.8125 L 8.890625 -15.8125 C 9.84375 -15.8125 10.71875 -15.65625 11.5 -15.34375 C 12.265625 -15.015625 12.9375 -14.578125 13.484375 -13.984375 C 14.03125 -13.375 14.453125 -12.65625 14.75 -11.796875 C 15.046875 -10.921875 15.1875 -9.96875 15.1875 -8.875 Z M 15.1875 -8.875 "/>
|
||||
<path style="stroke:none;" d="M 17.546875 -8.875 C 17.546875 -10.203125 17.328125 -11.40625 16.90625 -12.5 C 16.484375 -13.59375 15.890625 -14.515625 15.125 -15.3125 C 14.359375 -16.078125 13.4375 -16.6875 12.359375 -17.125 C 11.28125 -17.546875 10.09375 -17.75 8.796875 -17.75 L 2.15625 -17.75 L 2.15625 0 L 8.796875 0 C 10.09375 0 11.28125 -0.203125 12.359375 -0.640625 C 13.4375 -1.0625 14.359375 -1.65625 15.125 -2.4375 C 15.890625 -3.21875 16.484375 -4.15625 16.90625 -5.234375 C 17.328125 -6.328125 17.546875 -7.546875 17.546875 -8.875 Z M 15.078125 -8.875 C 15.078125 -7.78125 14.9375 -6.796875 14.640625 -5.953125 C 14.34375 -5.09375 13.921875 -4.359375 13.375 -3.765625 C 12.828125 -3.1875 12.171875 -2.71875 11.390625 -2.421875 C 10.609375 -2.109375 9.75 -1.953125 8.796875 -1.953125 L 4.578125 -1.953125 L 4.578125 -15.8125 L 8.796875 -15.8125 C 9.75 -15.8125 10.609375 -15.65625 11.390625 -15.34375 C 12.171875 -15.03125 12.828125 -14.578125 13.375 -13.984375 C 13.921875 -13.375 14.34375 -12.65625 14.640625 -11.796875 C 14.9375 -10.9375 15.078125 -9.96875 15.078125 -8.875 Z M 15.078125 -8.875 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-2">
|
||||
<path style="stroke:none;" d="M 12.578125 -12.546875 L 10.828125 -12.546875 C 10.6875 -12.546875 10.546875 -12.5 10.421875 -12.421875 C 10.296875 -12.328125 10.21875 -12.21875 10.171875 -12.09375 L 6.90625 -4.203125 C 6.78125 -3.859375 6.65625 -3.484375 6.546875 -3.09375 C 6.4375 -3.46875 6.328125 -3.84375 6.203125 -4.1875 L 2.84375 -12.09375 C 2.796875 -12.203125 2.71875 -12.296875 2.609375 -12.40625 C 2.5 -12.5 2.359375 -12.546875 2.171875 -12.546875 L 0.265625 -12.546875 L 5.4375 -0.734375 L 3.140625 4.25 L 4.78125 4.25 C 5 4.25 5.171875 4.203125 5.296875 4.09375 C 5.40625 4 5.5 3.875 5.578125 3.703125 Z M 12.578125 -12.546875 "/>
|
||||
<path style="stroke:none;" d="M 5.484375 3.703125 L 12.484375 -12.546875 L 10.734375 -12.546875 C 10.59375 -12.546875 10.453125 -12.515625 10.328125 -12.421875 C 10.21875 -12.34375 10.140625 -12.234375 10.09375 -12.09375 L 6.828125 -4.203125 C 6.75 -4.015625 6.6875 -3.828125 6.625 -3.640625 C 6.5625 -3.453125 6.515625 -3.265625 6.453125 -3.078125 C 6.421875 -3.265625 6.375 -3.453125 6.3125 -3.640625 C 6.25 -3.828125 6.1875 -4 6.125 -4.1875 L 2.765625 -12.09375 C 2.71875 -12.203125 2.640625 -12.3125 2.53125 -12.421875 C 2.421875 -12.5 2.265625 -12.546875 2.078125 -12.546875 L 0.171875 -12.546875 L 5.359375 -0.734375 L 3.0625 4.25 L 4.703125 4.25 C 4.9375 4.25 5.109375 4.203125 5.203125 4.09375 C 5.328125 4 5.421875 3.859375 5.484375 3.703125 Z M 5.484375 3.703125 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-3">
|
||||
<path style="stroke:none;" d="M 3.828125 -10.734375 L 3.65625 -12.09375 C 3.578125 -12.390625 3.375 -12.546875 3.078125 -12.546875 L 1.75 -12.546875 L 1.75 0 L 3.96875 0 L 3.96875 -9.25 C 4.4375 -9.78125 4.953125 -10.203125 5.53125 -10.515625 C 6.09375 -10.828125 6.703125 -10.984375 7.359375 -10.984375 C 8.234375 -10.984375 8.890625 -10.71875 9.328125 -10.203125 C 9.765625 -9.671875 9.984375 -8.9375 9.984375 -7.984375 L 9.984375 0 L 12.203125 0 L 12.203125 -7.984375 C 12.203125 -8.703125 12.109375 -9.34375 11.9375 -9.9375 C 11.75 -10.515625 11.46875 -11.015625 11.125 -11.4375 C 10.78125 -11.859375 10.328125 -12.1875 9.8125 -12.40625 C 9.296875 -12.625 8.6875 -12.75 8 -12.75 C 7.5625 -12.75 7.140625 -12.703125 6.75 -12.59375 C 6.375 -12.5 6.015625 -12.359375 5.65625 -12.1875 C 5.3125 -12.015625 5 -11.8125 4.703125 -11.5625 C 4.390625 -11.3125 4.09375 -11.03125 3.828125 -10.734375 Z M 3.828125 -10.734375 "/>
|
||||
<path style="stroke:none;" d="M 1.8125 0 L 4.015625 0 L 4.015625 -9.25 C 4.5 -9.78125 5.015625 -10.203125 5.578125 -10.515625 C 6.140625 -10.828125 6.75 -10.984375 7.40625 -10.984375 C 8.296875 -10.984375 8.96875 -10.734375 9.390625 -10.203125 C 9.84375 -9.671875 10.046875 -8.953125 10.046875 -7.984375 L 10.046875 0 L 12.25 0 L 12.25 -7.984375 C 12.25 -8.703125 12.171875 -9.359375 11.984375 -9.9375 C 11.796875 -10.515625 11.53125 -11.03125 11.171875 -11.453125 C 10.828125 -11.859375 10.390625 -12.1875 9.859375 -12.421875 C 9.34375 -12.640625 8.734375 -12.75 8.046875 -12.75 C 7.171875 -12.75 6.390625 -12.5625 5.71875 -12.1875 C 5.046875 -11.828125 4.4375 -11.34375 3.890625 -10.734375 L 3.71875 -12.09375 C 3.625 -12.40625 3.4375 -12.546875 3.125 -12.546875 L 1.8125 -12.546875 Z M 1.8125 0 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-4">
|
||||
<path style="stroke:none;" d="M 8.546875 -5.65625 L 8.546875 -3.046875 C 8.296875 -2.78125 8.046875 -2.546875 7.78125 -2.34375 C 7.515625 -2.125 7.25 -1.953125 6.96875 -1.8125 C 6.671875 -1.65625 6.375 -1.53125 6.0625 -1.46875 C 5.734375 -1.390625 5.375 -1.34375 5 -1.34375 C 4.703125 -1.34375 4.421875 -1.375 4.171875 -1.453125 C 3.921875 -1.53125 3.703125 -1.640625 3.515625 -1.78125 C 3.328125 -1.9375 3.1875 -2.125 3.078125 -2.375 C 2.96875 -2.609375 2.921875 -2.90625 2.921875 -3.234375 C 2.921875 -3.578125 3.015625 -3.890625 3.21875 -4.171875 C 3.421875 -4.453125 3.75 -4.703125 4.203125 -4.90625 C 4.640625 -5.109375 5.234375 -5.28125 5.953125 -5.40625 C 6.671875 -5.53125 7.53125 -5.609375 8.546875 -5.65625 Z M 1.421875 -10.78125 L 1.828125 -10.078125 C 1.890625 -9.953125 1.984375 -9.84375 2.09375 -9.78125 C 2.1875 -9.703125 2.328125 -9.671875 2.484375 -9.671875 C 2.65625 -9.671875 2.84375 -9.734375 3.046875 -9.859375 C 3.25 -10 3.46875 -10.140625 3.734375 -10.328125 C 4.015625 -10.5 4.328125 -10.640625 4.703125 -10.78125 C 5.0625 -10.921875 5.53125 -10.984375 6.078125 -10.984375 C 6.875 -10.984375 7.5 -10.734375 7.921875 -10.234375 C 8.34375 -9.734375 8.546875 -9 8.546875 -8.03125 L 8.546875 -7.046875 C 7.109375 -7.015625 5.90625 -6.875 4.9375 -6.65625 C 3.9375 -6.4375 3.140625 -6.140625 2.546875 -5.78125 C 1.921875 -5.421875 1.484375 -5.015625 1.21875 -4.5625 C 0.9375 -4.09375 0.8125 -3.625 0.8125 -3.140625 C 0.8125 -2.5625 0.890625 -2.0625 1.078125 -1.640625 C 1.265625 -1.234375 1.515625 -0.890625 1.828125 -0.625 C 2.15625 -0.34375 2.53125 -0.140625 2.96875 0 C 3.375 0.140625 3.84375 0.203125 4.34375 0.203125 C 4.8125 0.203125 5.234375 0.15625 5.640625 0.078125 C 6.03125 -0.015625 6.40625 -0.140625 6.75 -0.296875 C 7.09375 -0.453125 7.421875 -0.65625 7.75 -0.890625 C 8.046875 -1.125 8.375 -1.40625 8.703125 -1.703125 L 8.953125 -0.515625 C 9.015625 -0.3125 9.109375 -0.171875 9.234375 -0.09375 C 9.34375 -0.03125 9.5 0 9.734375 0 L 10.703125 0 L 10.703125 -8.03125 C 10.703125 -8.71875 10.609375 -9.375 10.421875 -9.96875 C 10.21875 -10.546875 9.953125 -11.046875 9.578125 -11.46875 C 9.203125 -11.875 8.75 -12.1875 8.203125 -12.421875 C 7.65625 -12.65625 7.03125 -12.78125 6.328125 -12.78125 C 5.359375 -12.78125 4.453125 -12.59375 3.671875 -12.28125 C 2.859375 -11.9375 2.125 -11.453125 1.421875 -10.78125 Z M 1.421875 -10.78125 "/>
|
||||
<path style="stroke:none;" d="M 11.03125 0 L 11.03125 -8.03125 C 11.03125 -8.734375 10.921875 -9.375 10.75 -9.96875 C 10.5625 -10.546875 10.265625 -11.046875 9.90625 -11.46875 C 9.53125 -11.875 9.0625 -12.1875 8.53125 -12.421875 C 7.984375 -12.65625 7.359375 -12.78125 6.65625 -12.78125 C 5.671875 -12.78125 4.796875 -12.609375 3.984375 -12.28125 C 3.1875 -11.9375 2.4375 -11.453125 1.75 -10.78125 L 2.140625 -10.078125 C 2.203125 -9.96875 2.296875 -9.859375 2.40625 -9.78125 C 2.53125 -9.703125 2.65625 -9.671875 2.796875 -9.671875 C 2.984375 -9.671875 3.1875 -9.734375 3.375 -9.859375 C 3.5625 -10.015625 3.796875 -10.15625 4.0625 -10.328125 C 4.34375 -10.5 4.65625 -10.65625 5.03125 -10.78125 C 5.390625 -10.921875 5.84375 -10.984375 6.375 -10.984375 C 7.203125 -10.984375 7.8125 -10.75 8.234375 -10.234375 C 8.65625 -9.734375 8.859375 -9.015625 8.859375 -8.03125 L 8.859375 -7.046875 C 7.4375 -7.015625 6.234375 -6.890625 5.25 -6.671875 C 4.28125 -6.4375 3.46875 -6.140625 2.875 -5.78125 C 2.25 -5.421875 1.828125 -5.03125 1.546875 -4.5625 C 1.28125 -4.109375 1.140625 -3.625 1.140625 -3.140625 C 1.140625 -2.5625 1.234375 -2.0625 1.40625 -1.65625 C 1.609375 -1.234375 1.859375 -0.890625 2.171875 -0.625 C 2.484375 -0.34375 2.84375 -0.15625 3.265625 0 C 3.703125 0.125 4.15625 0.203125 4.640625 0.203125 C 5.125 0.203125 5.5625 0.15625 5.953125 0.078125 C 6.34375 -0.015625 6.71875 -0.125 7.0625 -0.296875 C 7.40625 -0.453125 7.75 -0.640625 8.046875 -0.890625 C 8.359375 -1.109375 8.6875 -1.390625 9.015625 -1.6875 L 9.265625 -0.515625 C 9.3125 -0.3125 9.390625 -0.15625 9.53125 -0.09375 C 9.671875 -0.03125 9.84375 0 10.046875 0 Z M 5.296875 -1.34375 C 5.015625 -1.34375 4.75 -1.390625 4.5 -1.46875 C 4.25 -1.53125 4.046875 -1.640625 3.859375 -1.78125 C 3.671875 -1.953125 3.53125 -2.140625 3.421875 -2.375 C 3.3125 -2.609375 3.265625 -2.90625 3.265625 -3.234375 C 3.265625 -3.578125 3.359375 -3.890625 3.5625 -4.171875 C 3.765625 -4.453125 4.09375 -4.703125 4.53125 -4.90625 C 4.984375 -5.125 5.5625 -5.28125 6.265625 -5.40625 C 6.96875 -5.53125 7.84375 -5.609375 8.859375 -5.65625 L 8.859375 -3.03125 C 8.609375 -2.78125 8.34375 -2.546875 8.109375 -2.328125 C 7.828125 -2.125 7.5625 -1.953125 7.28125 -1.8125 C 6.984375 -1.65625 6.6875 -1.546875 6.375 -1.46875 C 6.046875 -1.390625 5.6875 -1.34375 5.296875 -1.34375 Z M 5.296875 -1.34375 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-5">
|
||||
<path style="stroke:none;" d="M 3.84375 -10.03125 L 3.6875 -11.9375 C 3.65625 -12.171875 3.59375 -12.3125 3.5 -12.421875 C 3.40625 -12.5 3.25 -12.546875 3.015625 -12.546875 L 1.75 -12.546875 L 1.75 0 L 3.96875 0 L 3.96875 -7.9375 C 4.109375 -8.34375 4.28125 -8.734375 4.484375 -9.0625 C 4.6875 -9.40625 4.890625 -9.6875 5.140625 -9.90625 C 5.390625 -10.140625 5.65625 -10.3125 5.96875 -10.4375 C 6.28125 -10.546875 6.640625 -10.609375 7.03125 -10.609375 C 7.3125 -10.609375 7.578125 -10.578125 7.796875 -10.53125 C 8.015625 -10.484375 8.171875 -10.453125 8.296875 -10.453125 C 8.5 -10.453125 8.625 -10.5625 8.671875 -10.765625 L 8.828125 -12.421875 C 8.640625 -12.546875 8.421875 -12.625 8.171875 -12.6875 C 7.9375 -12.734375 7.6875 -12.78125 7.421875 -12.78125 C 6.578125 -12.78125 5.875 -12.53125 5.296875 -12.046875 C 4.71875 -11.5625 4.234375 -10.890625 3.84375 -10.03125 Z M 3.84375 -10.03125 "/>
|
||||
<path style="stroke:none;" d="M 1.8125 0 L 4.015625 0 L 4.015625 -7.984375 C 4.359375 -8.84375 4.796875 -9.484375 5.296875 -9.9375 C 5.828125 -10.390625 6.46875 -10.609375 7.234375 -10.609375 C 7.671875 -10.609375 8 -10.5625 8.234375 -10.484375 C 8.46875 -10.40625 8.65625 -10.375 8.765625 -10.375 C 8.96875 -10.375 9.09375 -10.46875 9.15625 -10.6875 L 9.4375 -12.328125 C 9.203125 -12.46875 8.953125 -12.578125 8.65625 -12.65625 C 8.375 -12.734375 8.0625 -12.78125 7.71875 -12.78125 C 6.859375 -12.78125 6.125 -12.53125 5.5 -12.046875 C 4.859375 -11.546875 4.34375 -10.859375 3.90625 -9.984375 L 3.75 -11.9375 C 3.71875 -12.171875 3.65625 -12.328125 3.5625 -12.421875 C 3.484375 -12.5 3.3125 -12.546875 3.078125 -12.546875 L 1.8125 -12.546875 Z M 1.8125 0 "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-6">
|
||||
<path style="stroke:none;" d="M 10.140625 -7.640625 L 3.28125 -7.640625 C 3.4375 -8.734375 3.796875 -9.578125 4.421875 -10.203125 C 5.046875 -10.8125 5.875 -11.125 6.9375 -11.125 C 7.4375 -11.125 7.890625 -11.046875 8.296875 -10.859375 C 8.6875 -10.6875 9.015625 -10.453125 9.296875 -10.140625 C 9.5625 -9.84375 9.78125 -9.46875 9.921875 -9.046875 C 10.078125 -8.625 10.140625 -8.15625 10.140625 -7.640625 Z M 11.9375 -1.765625 L 11.3125 -2.5625 C 11.21875 -2.703125 11.0625 -2.78125 10.890625 -2.78125 C 10.75 -2.78125 10.578125 -2.703125 10.390625 -2.578125 C 10.1875 -2.453125 9.953125 -2.3125 9.671875 -2.171875 C 9.375 -2.015625 9.015625 -1.875 8.625 -1.75 C 8.234375 -1.625 7.75 -1.5625 7.203125 -1.5625 C 6.609375 -1.5625 6.0625 -1.640625 5.59375 -1.84375 C 5.109375 -2.046875 4.703125 -2.328125 4.34375 -2.71875 C 4 -3.125 3.734375 -3.609375 3.53125 -4.203125 C 3.328125 -4.78125 3.234375 -5.484375 3.203125 -6.265625 L 11.59375 -6.265625 C 11.796875 -6.265625 11.9375 -6.3125 12.015625 -6.4375 C 12.09375 -6.546875 12.125 -6.796875 12.125 -7.140625 C 12.125 -8.03125 12 -8.828125 11.734375 -9.515625 C 11.46875 -10.203125 11.109375 -10.796875 10.625 -11.28125 C 10.15625 -11.75 9.609375 -12.125 8.96875 -12.359375 C 8.328125 -12.609375 7.625 -12.75 6.890625 -12.75 C 5.96875 -12.75 5.15625 -12.59375 4.4375 -12.265625 C 3.703125 -11.9375 3.078125 -11.515625 2.59375 -10.953125 C 2.078125 -10.390625 1.703125 -9.734375 1.421875 -8.984375 C 1.15625 -8.21875 1.03125 -7.390625 1.03125 -6.53125 C 1.03125 -5.4375 1.171875 -4.484375 1.46875 -3.65625 C 1.765625 -2.8125 2.1875 -2.125 2.71875 -1.546875 C 3.25 -0.984375 3.875 -0.5625 4.609375 -0.265625 C 5.34375 0.03125 6.140625 0.171875 7.015625 0.171875 C 7.453125 0.171875 7.921875 0.140625 8.390625 0.0625 C 8.84375 -0.015625 9.296875 -0.140625 9.734375 -0.296875 C 10.15625 -0.453125 10.5625 -0.640625 10.953125 -0.890625 C 11.328125 -1.140625 11.65625 -1.421875 11.9375 -1.765625 Z M 11.9375 -1.765625 "/>
|
||||
<path style="stroke:none;" d="M 6.78125 -12.75 C 5.875 -12.75 5.0625 -12.59375 4.328125 -12.265625 C 3.59375 -11.953125 2.984375 -11.515625 2.484375 -10.953125 C 1.96875 -10.40625 1.59375 -9.734375 1.3125 -8.984375 C 1.046875 -8.234375 0.921875 -7.40625 0.921875 -6.53125 C 0.921875 -5.453125 1.0625 -4.484375 1.359375 -3.65625 C 1.65625 -2.828125 2.078125 -2.125 2.609375 -1.5625 C 3.140625 -0.984375 3.765625 -0.5625 4.515625 -0.265625 C 5.234375 0.03125 6.03125 0.171875 6.90625 0.171875 C 7.359375 0.171875 7.8125 0.140625 8.28125 0.046875 C 8.734375 -0.03125 9.1875 -0.140625 9.609375 -0.296875 C 10.0625 -0.453125 10.453125 -0.65625 10.84375 -0.890625 C 11.21875 -1.140625 11.546875 -1.421875 11.828125 -1.765625 L 11.203125 -2.5625 C 11.109375 -2.703125 10.96875 -2.78125 10.78125 -2.78125 C 10.640625 -2.78125 10.46875 -2.71875 10.28125 -2.578125 C 10.09375 -2.453125 9.84375 -2.3125 9.546875 -2.171875 C 9.265625 -2.015625 8.921875 -1.890625 8.53125 -1.765625 C 8.109375 -1.625 7.640625 -1.5625 7.09375 -1.5625 C 6.5 -1.5625 5.953125 -1.65625 5.484375 -1.859375 C 5 -2.046875 4.578125 -2.34375 4.234375 -2.71875 C 3.890625 -3.125 3.625 -3.625 3.421875 -4.203125 C 3.21875 -4.78125 3.109375 -5.484375 3.09375 -6.265625 L 11.453125 -6.265625 C 11.65625 -6.265625 11.796875 -6.328125 11.875 -6.4375 C 11.9375 -6.546875 11.984375 -6.796875 11.984375 -7.140625 C 11.984375 -8.03125 11.84375 -8.828125 11.59375 -9.515625 C 11.328125 -10.21875 10.96875 -10.796875 10.5 -11.28125 C 10.046875 -11.765625 9.484375 -12.125 8.859375 -12.359375 C 8.234375 -12.625 7.53125 -12.75 6.78125 -12.75 Z M 6.828125 -11.125 C 7.328125 -11.125 7.78125 -11.046875 8.171875 -10.875 C 8.5625 -10.703125 8.890625 -10.453125 9.171875 -10.15625 C 9.4375 -9.84375 9.65625 -9.484375 9.78125 -9.046875 C 9.921875 -8.625 10 -8.15625 10 -7.640625 L 3.171875 -7.640625 C 3.328125 -8.734375 3.703125 -9.59375 4.3125 -10.203125 C 4.921875 -10.8125 5.765625 -11.125 6.828125 -11.125 Z M 6.828125 -11.125 "/>
|
||||
</symbol>
|
||||
</g>
|
||||
<clipPath id="clip1">
|
||||
<path d="M 0 6 L 21 6 L 21 34.183594 L 0 34.183594 Z M 0 6 "/>
|
||||
<path d="M 0 6 L 22 6 L 22 34.183594 L 0 34.183594 Z M 0 6 "/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g id="surface1">
|
||||
<g style="fill:rgb(67.059326%,70.196533%,72.941589%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-1" x="3.32" y="24.072"/>
|
||||
<use xlink:href="#glyph0-1" x="3.321" y="24.097"/>
|
||||
<use xlink:href="#glyph0-2" x="21.985686" y="24.097"/>
|
||||
<use xlink:href="#glyph0-3" x="34.676682" y="24.097"/>
|
||||
<use xlink:href="#glyph0-4" x="48.458309" y="24.097"/>
|
||||
<use xlink:href="#glyph0-5" x="61.025369" y="24.097"/>
|
||||
<use xlink:href="#glyph0-6" x="71.01457" y="24.097"/>
|
||||
</g>
|
||||
<g style="fill:rgb(67.059326%,70.196533%,72.941589%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-2" x="22.096228" y="24.072"/>
|
||||
<use xlink:href="#glyph0-3" x="34.873978" y="24.072"/>
|
||||
<use xlink:href="#glyph0-4" x="48.70518" y="24.072"/>
|
||||
<use xlink:href="#glyph0-5" x="61.024369" y="24.072"/>
|
||||
</g>
|
||||
<g style="fill:rgb(67.059326%,70.196533%,72.941589%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-6" x="69.551131" y="24.072"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:0.79701;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(49.412537%,80.784607%,99.215698%);stroke-opacity:1;stroke-miterlimit:10;" d="M -13.322906 -17.010156 C -13.322906 -17.010156 0.782563 14.802344 5.384125 15.591406 C 9.985688 16.376563 16.891938 -8.35 19.841156 -11.338281 C 22.794281 -14.326562 24.798188 -6.029687 26.645844 -5.951562 C 28.4935 -5.873437 31.434906 -10.455469 33.165375 -10.771875 C 34.895844 -11.088281 37.505219 -8.299219 39.1185 -8.221094 C 40.731781 -8.142969 43.216156 -10.127344 44.786469 -10.205469 C 46.360687 -10.283594 48.884125 -8.865625 50.458344 -8.7875 C 52.028656 -8.709375 54.552094 -9.6 56.126312 -9.639062 C 57.700531 -9.678125 60.302094 -9.111719 61.794281 -9.072656 C 63.290375 -9.033594 66.89975 -9.353906 66.89975 -9.353906 " transform="matrix(1,0,0,-1,15.194,16.775)"/>
|
||||
<path style="fill:none;stroke-width:0.79701;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(100%,49.804688%,39.99939%);stroke-opacity:1;stroke-miterlimit:10;" d="M -13.323406 -17.010156 C -13.323406 -17.010156 0.785969 14.802344 5.387531 15.591406 C 9.989094 16.376563 16.891437 -8.35 19.844562 -11.338281 C 22.793781 -14.326562 24.797687 -6.029687 26.645344 -5.951562 C 28.493 -5.873437 31.434406 -10.455469 33.164875 -10.771875 C 34.895344 -11.088281 37.504719 -8.299219 39.118 -8.221094 C 40.731281 -8.142969 43.215656 -10.127344 44.789875 -10.205469 C 46.360187 -10.283594 48.883625 -8.865625 50.457844 -8.7875 C 52.032062 -8.709375 54.551594 -9.6 56.125812 -9.639062 C 57.700031 -9.678125 60.301594 -9.111719 61.797687 -9.072656 C 63.289875 -9.033594 66.89925 -9.353906 66.89925 -9.353906 " transform="matrix(1,0,0,-1,15.882,16.775)"/>
|
||||
<g style="fill:rgb(12.940979%,52.157593%,77.253723%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-1" x="3.888" y="23.505"/>
|
||||
</g>
|
||||
<g style="fill:rgb(12.940979%,52.157593%,77.253723%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-2" x="22.664228" y="23.505"/>
|
||||
<use xlink:href="#glyph0-3" x="35.441978" y="23.505"/>
|
||||
<use xlink:href="#glyph0-4" x="49.27318" y="23.505"/>
|
||||
<use xlink:href="#glyph0-5" x="61.592369" y="23.505"/>
|
||||
</g>
|
||||
<g style="fill:rgb(12.940979%,52.157593%,77.253723%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-6" x="70.094344" y="23.505"/>
|
||||
<use xlink:href="#glyph0-1" x="3.888" y="23.53"/>
|
||||
<use xlink:href="#glyph0-2" x="22.552686" y="23.53"/>
|
||||
<use xlink:href="#glyph0-3" x="35.243681" y="23.53"/>
|
||||
<use xlink:href="#glyph0-4" x="49.025309" y="23.53"/>
|
||||
<use xlink:href="#glyph0-5" x="61.592369" y="23.53"/>
|
||||
<use xlink:href="#glyph0-6" x="71.58157" y="23.53"/>
|
||||
</g>
|
||||
<g clip-path="url(#clip1)" clip-rule="nonzero">
|
||||
<path style="fill:none;stroke-width:0.79701;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(49.412537%,80.784607%,99.215698%);stroke-opacity:1;stroke-miterlimit:10;" d="M -9.127594 -7.935937 C -9.127594 -7.935937 -5.752594 -1.135156 -5.752594 -1.135156 " transform="matrix(1,0,0,-1,15.194,16.775)"/>
|
||||
<path style="fill:none;stroke-width:0.79701;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(100%,49.804688%,39.99939%);stroke-opacity:1;stroke-miterlimit:10;" d="M -9.128094 -7.935937 C -9.128094 -7.935937 -5.753094 -1.135156 -5.753094 -1.135156 " transform="matrix(1,0,0,-1,15.882,16.775)"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
@ -1 +0,0 @@
|
|||
/usr/share/javascript/mathjax/
|
|
@ -13,20 +13,23 @@ Bibliography
|
|||
* Andrews, Donald W.K (1991): “Heteroskedasticity and autocorrelation consistent covariance matrix estimation”, *Econometrica*, 59(3), 817–858.
|
||||
* Backus, David K., Patrick J. Kehoe, and Finn E. Kydland (1992): “International Real Business Cycles,” *Journal of Political Economy*, 100(4), 745–775.
|
||||
* Baxter, Marianne and Robert G. King (1999): “Measuring Business Cycles: Approximate Band-pass Filters for Economic Time Series,” *Review of Economics and Statistics*, 81(4), 575–593.
|
||||
* Bini, Dario A., Guy Latouche, and Beatrice Meini (2002): “Solving matrix polynomial equations arising in queueing problems,” *Linear Algebra and its Applications*, 340, 225–244.
|
||||
* Born, Benjamin and Johannes Pfeifer (2014): “Policy risk and the business cycle”, *Journal of Monetary Economics*, 68, 68-85.
|
||||
* Boucekkine, Raouf (1995): “An alternative methodology for solving nonlinear forward-looking models,” *Journal of Economic Dynamics and Control*, 19, 711–734.
|
||||
* Brayton, Flint and Peter Tinsley (1996): "A Guide to FRB/US: A Macroeconomic Model of the United States", *Finance and Economics Discussion Series*, 1996-42.
|
||||
* Brayton, Flint, Morris Davis and Peter Tulip (2000): "Polynomial Adjustment Costs in FRB/US", *Unpublished manuscript*.
|
||||
* Brayton, Flint and Peter Tinsley (1996): “A Guide to FRB/US: A Macroeconomic Model of the United States,” *Finance and Economics Discussion Series*, 1996-42.
|
||||
* Brayton, Flint, Morris Davis and Peter Tulip (2000): “Polynomial Adjustment Costs in FRB/US,” *Unpublished manuscript*.
|
||||
* Brooks, Stephen P., and Andrew Gelman (1998): “General methods for monitoring convergence of iterative simulations,” *Journal of Computational and Graphical Statistics*, 7, pp. 434–455.
|
||||
* Cardoso, Margarida F., R. L. Salcedo and S. Feyo de Azevedo (1996): “The simplex simulated annealing approach to continuous non-linear optimization,” *Computers & Chemical Engineering*, 20(9), 1065-1080.
|
||||
* Chib, Siddhartha and Srikanth Ramamurthy (2010): “Tailored randomized block MCMC methods with application to DSGE models,” *Journal of Econometrics*, 155, 19–38.
|
||||
* Christiano, Lawrence J., Martin Eichenbaum and Charles L. Evans (2005): “Nominal Rigidities and the Dynamic Effects of a Shock to Monetary Policy,” *Journal of Political Economy*, 113(1), 1–45.
|
||||
* Christiano, Lawrence J., Mathias Trabandt, and Karl Walentin (2010): “DSGE Models for Monetary Policy Analysis,” In: *Handbook of Monetary Economics 3*, 285–367.
|
||||
* Christiano, Lawrence J., Mathias Trabandt and Karl Walentin (2011): “Introducing financial frictions and unemployment into a small open economy model,” *Journal of Economic Dynamics and Control*, 35(12), 1999–2041.
|
||||
* Christoffel, Kai, Günter Coenen and Anders Warne (2010): “Forecasting with DSGE models,” *ECB Working Paper Series*, 1185.
|
||||
* Collard, Fabrice (2001): “Stochastic simulations with Dynare: A practical guide”.
|
||||
* Collard, Fabrice and Michel Juillard (2001a): “Accuracy of stochastic perturbation methods: The case of asset pricing models,” *Journal of Economic Dynamics and Control*, 25, 979–999.
|
||||
* Collard, Fabrice and Michel Juillard (2001b): “A Higher-Order Taylor Expansion Approach to Simulation of Stochastic Forward-Looking Models with an Application to a Non-Linear Phillips Curve,” *Computational Economics*, 17, 125–139.
|
||||
* Corana, Angelo, M. Marchesi, Claudio Martini, and Sandro Ridella (1987): “Minimizing multimodal functions of continuous variables with the “simulated annealing” algorithm”, *ACM Transactions on Mathematical Software*, 13(3), 262–280.
|
||||
* Cuba-Borda, Pablo, Luca Guerrieri, Matteo Iacoviello, and Molin Zhong (2019): "Likelihood evaluation of models with occasionally binding constraints", Journal of Applied Econometrics, 34(7), 1073-1085
|
||||
* Cuba-Borda, Pablo, Luca Guerrieri, Matteo Iacoviello, and Molin Zhong (2019): “Likelihood evaluation of models with occasionally binding constraints,” Journal of Applied Econometrics, 34(7), 1073-1085
|
||||
* Del Negro, Marco and Frank Schorfheide (2004): “Priors from General Equilibrium Models for VARs”, *International Economic Review*, 45(2), 643–673.
|
||||
* Dennis, Richard (2007): “Optimal Policy In Rational Expectations Models: New Solution Algorithms”, *Macroeconomic Dynamics*, 11(1), 31–55.
|
||||
* Duffie, Darrel and Kenneth J. Singleton (1993): “Simulated Moments Estimation of Markov Models of Asset Prices”, *Econometrica*, 61(4), 929-952.
|
||||
|
@ -46,6 +49,7 @@ Bibliography
|
|||
* Hansen, Lars P. (1982): “Large sample properties of generalized method of moments estimators,” Econometrica, 50(4), 1029–1054.
|
||||
* Hansen, Nikolaus and Stefan Kern (2004): “Evaluating the CMA Evolution Strategy on Multimodal Test Functions”. In: *Eighth International Conference on Parallel Problem Solving from Nature PPSN VIII*, Proceedings, Berlin: Springer, 282–291.
|
||||
* Harvey, Andrew C. and Garry D.A. Phillips (1979): “Maximum likelihood estimation of regression models with autoregressive-moving average disturbances,” *Biometrika*, 66(1), 49–58.
|
||||
* Herbst, Edward and Schorfheide, Frank (2014): “Sequential Monte Carlo Sampling for DSGE Models,” *Journal of Applied Econometrics*, 29, 1073-1098.
|
||||
* Herbst, Edward (2015): “Using the “Chandrasekhar Recursions” for Likelihood Evaluation of DSGE Models,” *Computational Economics*, 45(4), 693–705.
|
||||
* Ireland, Peter (2004): “A Method for Taking Models to the Data,” *Journal of Economic Dynamics and Control*, 28, 1205–26.
|
||||
* Iskrev, Nikolay (2010): “Local identification in DSGE models,” *Journal of Monetary Economics*, 57(2), 189–202.
|
||||
|
@ -82,5 +86,5 @@ Bibliography
|
|||
* Smets, Frank and Rafael Wouters (2003): “An Estimated Dynamic Stochastic General Equilibrium Model of the Euro Area,” *Journal of the European Economic Association*, 1(5), 1123–1175.
|
||||
* Stock, James H. and Mark W. Watson (1999). “Forecasting Inflation,”, *Journal of Monetary Economics*, 44(2), 293–335.
|
||||
* Uhlig, Harald (2001): “A Toolkit for Analysing Nonlinear Dynamic Stochastic Models Easily,” in *Computational Methods for the Study of Dynamic Economies*, Eds. Ramon Marimon and Andrew Scott, Oxford University Press, 30–61.
|
||||
* U.S. Census Bureau (2017): “X-13 ARIMA-SEATS Reference Manual”.
|
||||
* U.S. Census Bureau (2020): “X-13 ARIMA-SEATS Reference Manual, Version 1.1”, Center for Statistical Research and Methodology, U.S. Census Bureau, https://www.census.gov/data/software/x13as.html
|
||||
* Villemot, Sébastien (2011): “Solving rational expectations models at first order: what Dynare does,” *Dynare Working Papers*, 2, CEPREMAP.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright © 2018-2022 Dynare Team
|
||||
# Copyright © 2018-2024 Dynare Team
|
||||
#
|
||||
# This file is part of Dynare.
|
||||
#
|
||||
|
@ -31,20 +31,14 @@ templates_path = ['_templates']
|
|||
|
||||
html_static_path = ['_static']
|
||||
|
||||
mathjax_path = 'mathjax/MathJax.js?config=TeX-AMS-MML_HTMLorMML'
|
||||
|
||||
master_doc = 'index'
|
||||
|
||||
project = u'Dynare'
|
||||
copyright = u'1996–2022 Dynare Team'
|
||||
copyright = u'1996–2024 Dynare Team'
|
||||
author = u'Dynare Team'
|
||||
|
||||
add_function_parentheses = False
|
||||
|
||||
# See ../utils/version.py, which is generated by autoconf
|
||||
from version import version
|
||||
from version import release
|
||||
|
||||
language = 'en'
|
||||
|
||||
exclude_patterns = []
|
||||
|
@ -77,12 +71,11 @@ latex_elements = {
|
|||
warningBorderColor={RGB}{255,50,50},OuterLinkColor={RGB}{34,139,34}, \
|
||||
InnerLinkColor={RGB}{51,51,255},TitleColor={RGB}{51,51,255}',
|
||||
'papersize': 'a4paper',
|
||||
'preamble': r'\DeclareUnicodeCharacter{200B}{}', # Part of the workaround for #1707
|
||||
}
|
||||
|
||||
latex_documents = [
|
||||
(master_doc, 'dynare-manual.tex', u'Dynare Reference Manual',
|
||||
u'Dynare team', 'manual'),
|
||||
u'Dynare Team', 'manual'),
|
||||
]
|
||||
|
||||
man_pages = [
|
||||
|
|
|
@ -8,11 +8,25 @@
|
|||
Dynare misc commands
|
||||
####################
|
||||
|
||||
.. matcomm:: send_endogenous_variables_to_workspace ;
|
||||
|
||||
Puts the simulation results for the endogenous variables stored in ``oo_.endo_simul``
|
||||
into vectors with the same name as the respective variables into the base workspace.
|
||||
|
||||
.. matcomm:: send_exogenous_variables_to_workspace ;
|
||||
|
||||
Puts the simulation results for the exogenous variables stored in ``oo_.exo_simul``
|
||||
into vectors with the same name as the respective variables into the base workspace.
|
||||
|
||||
.. matcomm:: send_irfs_to_workspace ;
|
||||
|
||||
Puts the IRFs stored in ``oo_.irfs`` into vectors with the same name into the base workspace.
|
||||
|
||||
.. command:: prior_function(OPTIONS);
|
||||
|
||||
|br| Executes a user-defined function on parameter draws from the prior
|
||||
Executes a user-defined function on parameter draws from the prior
|
||||
distribution. Dynare returns the results of the computations for
|
||||
all draws in an $ndraws$ by $n$ cell array named
|
||||
all draws in an `ndraws` by :math:`n` cell array named
|
||||
``oo_.prior_function_results``.
|
||||
|
||||
*Options*
|
||||
|
@ -30,9 +44,11 @@ Dynare misc commands
|
|||
|
||||
Number of draws used for sampling. Default: 500.
|
||||
|
||||
|br|
|
||||
|
||||
.. command:: posterior_function(OPTIONS);
|
||||
|
||||
|br| Same as the :comm:`prior_function` command but for the
|
||||
Same as the :comm:`prior_function` command but for the
|
||||
posterior distribution. Results returned in
|
||||
``oo_.posterior_function_results``.
|
||||
|
||||
|
@ -46,23 +62,28 @@ Dynare misc commands
|
|||
|
||||
See :opt:`prior_function_sampling_draws <sampling_draws = INTEGER>`.
|
||||
|
||||
|br|
|
||||
|
||||
.. command:: generate_trace_plots(CHAIN_NUMBER);
|
||||
|
||||
|br| Generates trace plots of the MCMC draws for all estimated
|
||||
parameters and the posterior density in the specified Markov Chain
|
||||
``CHAIN_NUMBER``.
|
||||
Generates trace plots of the MCMC draws for all estimated
|
||||
parameters and the posterior density for the specified Markov Chain(s)
|
||||
``CHAIN_NUMBER``. If ``CHAIN_NUMBER`` is a vector of integers, the trace plots
|
||||
will plot contains separate lines for each chain.
|
||||
|
||||
|br|
|
||||
|
||||
.. matcomm:: internals FLAG ROUTINENAME[.m]|MODFILENAME
|
||||
|
||||
|br| Depending on the value of ``FLAG``, the ``internals`` command
|
||||
can be used to run unitary tests specific to a MATLAB/Octave
|
||||
routine (if available), to display documentation about a
|
||||
MATLAB/Octave routine, or to extract some informations about the
|
||||
state of Dynare.
|
||||
Depending on the value of ``FLAG``, the ``internals`` command
|
||||
can be used to run unitary tests specific to a MATLAB/Octave
|
||||
routine (if available), to display documentation about a
|
||||
MATLAB/Octave routine, or to extract some informations about the
|
||||
state of Dynare.
|
||||
|
||||
*Flags*
|
||||
*Flags*
|
||||
|
||||
``--test``
|
||||
``--test``
|
||||
|
||||
Performs the unitary test associated to ROUTINENAME (if this
|
||||
routine exists and if the matlab/octave ``.m`` file has
|
||||
|
@ -79,28 +100,7 @@ Dynare misc commands
|
|||
|
||||
>> internals --test ../matlab/fr/ROUTINENAME
|
||||
|
||||
``--info``
|
||||
|
||||
Prints on screen the internal documentation of ROUTINENAME (if
|
||||
this routine exists and if this routine has a texinfo internal
|
||||
documentation header). The path to ``ROUTINENAME`` has to be
|
||||
provided, if the routine is not in the current directory.
|
||||
|
||||
*Example*
|
||||
|
||||
::
|
||||
|
||||
>> internals --doc ../matlab/fr/ROUTINENAME
|
||||
|
||||
At this time, will work properly for only a small number
|
||||
of routines. At the top of the (available) MATLAB/Octave
|
||||
routines a commented block for the internal documentation
|
||||
is written in the GNU texinfo documentation format. This
|
||||
block is processed by calling texinfo from
|
||||
MATLAB. Consequently, texinfo has to be installed on your
|
||||
machine.
|
||||
|
||||
``--display-mh-history``
|
||||
``--display-mh-history``
|
||||
|
||||
Displays information about the previously saved MCMC draws
|
||||
generated by a ``.mod`` file named MODFILENAME. This file must
|
||||
|
@ -112,9 +112,9 @@ Dynare misc commands
|
|||
|
||||
>> internals --display-mh-history MODFILENAME
|
||||
|
||||
``--load-mh-history``
|
||||
``--load-mh-history``
|
||||
|
||||
|br| Loads into the MATLAB/Octave’s workspace informations
|
||||
Loads into the MATLAB/Octave’s workspace informations
|
||||
about the previously saved MCMC draws generated by a ``.mod``
|
||||
file named MODFILENAME.
|
||||
|
||||
|
@ -167,56 +167,160 @@ Dynare misc commands
|
|||
|
||||
A ``1*Nblck`` array of doubles. Current acceptance ratios.
|
||||
|
||||
.. matcomm:: prior [OPTIONS[, ...]];
|
||||
|br|
|
||||
|
||||
Prints information about the prior distribution given the provided
|
||||
options. If no options are provided, the command returns the list of
|
||||
available options.
|
||||
.. matcomm:: prior [OPTIONS[ ...]];
|
||||
|
||||
*Options*
|
||||
Prints information about the prior distribution given the provided
|
||||
options. If no options are provided, the command returns the list of
|
||||
available options.
|
||||
|
||||
.. option:: table
|
||||
*Options*
|
||||
|
||||
Prints a table describing the marginal prior distributions
|
||||
(mean, mode, std., lower and upper bounds, HPD interval).
|
||||
.. option:: table
|
||||
|
||||
.. option:: moments
|
||||
Prints a table describing the marginal prior distributions
|
||||
(mean, mode, std., lower and upper bounds, HPD interval).
|
||||
|
||||
Computes and displays first and second order moments of the
|
||||
endogenous variables at the prior mode (considering the
|
||||
linearized version of the model).
|
||||
.. option:: moments
|
||||
|
||||
.. option:: moments(distribution)
|
||||
Computes and displays first and second order moments of the
|
||||
endogenous variables at the prior mode (considering the
|
||||
linearized version of the model).
|
||||
|
||||
Computes and displays the prior mean and prior standard
|
||||
deviation of the first and second moments of the endogenous
|
||||
variables (considering the linearized version of the model) by
|
||||
randomly sampling from the prior. The results will also be
|
||||
stored in the ``prior`` subfolder in a
|
||||
``_endogenous_variables_prior_draws.mat`` file.
|
||||
.. option:: moments(distribution)
|
||||
|
||||
.. option:: optimize
|
||||
Computes and displays the prior mean and prior standard
|
||||
deviation of the first and second moments of the endogenous
|
||||
variables (considering the linearized version of the model) by
|
||||
randomly sampling from the prior. The results will also be
|
||||
stored in the ``prior`` subfolder in a
|
||||
``_endogenous_variables_prior_draws.mat`` file.
|
||||
|
||||
Optimizes the prior density (starting from a random initial
|
||||
guess). The parameters such that the steady state does not
|
||||
exist or does not satisfy the Blanchard and Kahn conditions
|
||||
are penalized, as they would be when maximizing the posterior
|
||||
density. If a significant proportion of the prior mass is
|
||||
defined over such regions, the optimization algorithm may fail
|
||||
to converge to the true solution (the prior mode).
|
||||
.. option:: optimize
|
||||
|
||||
.. option:: simulate
|
||||
Optimizes the prior density (starting from a random initial
|
||||
guess). The parameters such that the steady state does not
|
||||
exist or does not satisfy the Blanchard and Kahn conditions
|
||||
are penalized, as they would be when maximizing the posterior
|
||||
density. If a significant proportion of the prior mass is
|
||||
defined over such regions, the optimization algorithm may fail
|
||||
to converge to the true solution (the prior mode).
|
||||
|
||||
Computes the effective prior mass using a Monte-Carlo. Ideally
|
||||
the effective prior mass should be equal to 1, otherwise
|
||||
problems may arise when maximising the posterior density and
|
||||
model comparison based on marginal densities may be
|
||||
unfair. When comparing models, say :math:`A` and :math:`B`,
|
||||
the marginal densities, :math:`m_A` and :math:`m_B`, should be
|
||||
corrected for the estimated effective prior mass
|
||||
:math:`p_A\neq p_B \leq 1` so that the prior mass of the
|
||||
compared models are identical.
|
||||
.. option:: simulate
|
||||
|
||||
.. option:: plot
|
||||
Computes the effective prior mass using a Monte-Carlo. Ideally
|
||||
the effective prior mass should be equal to 1, otherwise
|
||||
problems may arise when maximising the posterior density and
|
||||
model comparison based on marginal densities may be
|
||||
unfair. When comparing models, say :math:`A` and :math:`B`,
|
||||
the marginal densities, :math:`m_A` and :math:`m_B`, should be
|
||||
corrected for the estimated effective prior mass
|
||||
:math:`p_A\neq p_B \leq 1` so that the prior mass of the
|
||||
compared models are identical.
|
||||
|
||||
Plots the marginal prior density.
|
||||
.. option:: plot
|
||||
|
||||
Plots the marginal prior density.
|
||||
|
||||
|br|
|
||||
|
||||
.. matcomm:: search VARIABLENAME[ OPTION]
|
||||
|
||||
Searches all occurrences of a variable in a model, and prints the
|
||||
equations where the variable appear in the command line window. If OPTION is
|
||||
set to `withparamvalues`, the values of the parameters (if available) are
|
||||
displayed instead of the name of the parameters. Requires the `json` command
|
||||
line option to be set.
|
||||
|
||||
*Example*
|
||||
|
||||
Assuming that we already ran a `.mod` file and that the workspace has not
|
||||
been cleaned after, we can search for all the equations containing variable `X`
|
||||
|
||||
::
|
||||
|
||||
>> search X
|
||||
|
||||
Y = alpha*X/(1-X)+e;
|
||||
|
||||
diff(X) = beta*(X(-1)-mX) + gamma1*Z + gamma2*R + u;
|
||||
|
||||
To replace the parameters with estimated or calibrated parameters:
|
||||
|
||||
::
|
||||
|
||||
>> search X withparamvalues
|
||||
|
||||
Y = 1.254634*X/(1-X)+e;
|
||||
|
||||
diff(X) = -0.031459*(X(-1)-mX) + 0.1*Z - 0.2*R + u;
|
||||
|
||||
|br|
|
||||
|
||||
|
||||
.. matcomm:: dplot [OPTION VALUE[ ...]]
|
||||
|
||||
Plot expressions extracting data from different dseries objects.
|
||||
|
||||
*Options*
|
||||
|
||||
.. option:: --expression EXPRESSION
|
||||
|
||||
``EXPRESSION`` is a mathematical expression involving variables
|
||||
available in the dseries objects, dseries methods, numbers or
|
||||
parameters. All the referenced objects are supposed to be
|
||||
available in the calling workspace.
|
||||
|
||||
.. option:: --dseries NAME
|
||||
|
||||
``NAME`` is the name of a dseries object from which the
|
||||
variables involved in ``EXPRESSION`` will be extracted.
|
||||
|
||||
.. option:: --range DATE1:DATE2
|
||||
|
||||
This option is not mandatory and allows to plot the expressions
|
||||
only over a sub-range. ``DATE1`` and ``DATE2`` must be dates as
|
||||
defined in :ref:`dates in a mod file`.
|
||||
|
||||
.. option:: --style MATLAB_SCRIPT_NAME
|
||||
|
||||
Name of a Matlab script (without extension) containing Matlab
|
||||
commands to customize the produced figure.
|
||||
|
||||
.. option:: --title MATLAB_STRING
|
||||
|
||||
Adds a title to the figure.
|
||||
|
||||
.. option:: --with-legend
|
||||
|
||||
Prints a legend below the produced plot.
|
||||
|
||||
*Remarks*
|
||||
|
||||
- More than one --expression argument is allowed, and they must come first.
|
||||
|
||||
- For each dseries object we plot all the expressions. We use two
|
||||
nested loops, the outer loop is over the dseries objects and the
|
||||
inner loop over the expressions. This determines the ordering of
|
||||
the plotted lines.
|
||||
|
||||
- All dseries objects must be defined in the calling workspace, if a
|
||||
dseries object is missing the routine throws a warning (we only
|
||||
build the plots for the available dseries objects), if all dseries
|
||||
objects are missing the routine throws an error.
|
||||
|
||||
- If the range is not provided, the expressions cannot involve leads or lags.
|
||||
|
||||
*Example*
|
||||
|
||||
::
|
||||
|
||||
>> toto = dseries(randn(100,3), dates('2000Q1'), {'x','y','z'});
|
||||
>> noddy = dseries(randn(100,3), dates('2000Q1'), {'x','y','z'});
|
||||
>> b = 3;
|
||||
>> dplot --expression 2/b*cumsum(x/y(-1)-1) --dseries toto --dseries noddy --range 2001Q1:2024Q1 --title 'This is my plot'
|
||||
|
||||
will produce plots for ``2/b*cumsum(x/y(-1)-1)``, where ``x`` and
|
||||
``y`` are variables in dseries objects ``toto`` and ``noddy``, in
|
||||
the same figure.
|
||||
|
|
|
@ -5,13 +5,13 @@ Currently the development team of Dynare is composed of:
|
|||
|
||||
* Stéphane Adjemian (Le Mans Université, Gains)
|
||||
* Michel Juillard (Banque de France)
|
||||
* Sumudu Kankanamge (Toulouse School of Economics and CEPREMAP)
|
||||
* Sumudu Kankanamge (Le Mans Université and CEPREMAP)
|
||||
* Frédéric Karamé (Le Mans Université, Gains and CEPREMAP)
|
||||
* Junior Maih (Norges Bank)
|
||||
* Willi Mutschler (University of Tübingen)
|
||||
* Johannes Pfeifer (Universität der Bundeswehr München)
|
||||
* Johannes Pfeifer (University of the Bundeswehr Munich)
|
||||
* Marco Ratto (European Commission, Joint Research Centre - JRC)
|
||||
* Normann Rion (CY Cergy Paris Université and CEPREMAP)
|
||||
* Normann Rion (CEPREMAP)
|
||||
* Sébastien Villemot (CEPREMAP)
|
||||
|
||||
The following people used to be members of the team:
|
||||
|
@ -26,7 +26,7 @@ The following people used to be members of the team:
|
|||
* Ferhat Mihoubi
|
||||
* George Perendia
|
||||
|
||||
Copyright © 1996-2023, Dynare Team.
|
||||
Copyright © 1996-2024, Dynare Team.
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
|
||||
|
||||
|
|
|
@ -8,14 +8,14 @@ Software requirements
|
|||
=====================
|
||||
|
||||
Packaged versions of Dynare are available for Windows (10 and 11), several
|
||||
GNU/Linux distributions (Debian, Ubuntu, Linux Mint, Arch Linux), macOS (12
|
||||
“Monterey”), and FreeBSD. Dynare should work on other systems, but some
|
||||
GNU/Linux distributions (Debian, Ubuntu, Linux Mint, Arch Linux), macOS (13
|
||||
Ventura), and FreeBSD. Dynare should work on other systems, but some
|
||||
compilation steps are necessary in that case.
|
||||
|
||||
In order to run Dynare, you need one of the following:
|
||||
|
||||
* MATLAB, any version ranging from 8.3 (R2014a) to 9.13 (R2022b);
|
||||
* GNU Octave, any version ranging from 6.2.0 to 7.3.0, with the statistics package
|
||||
* MATLAB, any version ranging from 9.5 (R2018b) to 23.2 (R2023b);
|
||||
* GNU Octave, any version ranging from 7.1.0 to 8.4.0, with the ``statistics`` package
|
||||
from `Octave-Forge`_. Note however that the Dynare installer for Windows
|
||||
requires a more specific version of Octave, as indicated on the download
|
||||
page.
|
||||
|
@ -26,8 +26,8 @@ extra features, but are in no way required:
|
|||
* If under MATLAB: the Optimization Toolbox, the Statistics Toolbox,
|
||||
the Control System Toolbox;
|
||||
|
||||
* If under Octave, the following `Octave-Forge`_ packages: ``optim, io,
|
||||
control``.
|
||||
* If under Octave, the following `Octave-Forge`_ packages: ``optim``, ``io``,
|
||||
``control``.
|
||||
|
||||
|
||||
Installation of Dynare
|
||||
|
@ -80,8 +80,12 @@ On Arch Linux, the Dynare package is not in the official repositories, but is
|
|||
available in the `Arch User Repository`_. The needed sources can be
|
||||
downloaded from the `package status in Arch Linux`_.
|
||||
|
||||
Dynare will be installed under ``/usr/lib/dynare``. Documentation will
|
||||
be under ``/usr/share/doc/dynare`` (only on Debian, Ubuntu and Linux Mint).
|
||||
There is also a Dynare package for openSUSE, see the `package status in
|
||||
openSUSE`_.
|
||||
|
||||
Dynare will be installed under ``/usr/lib/dynare`` (or ``/usr/lib64/dynare`` on
|
||||
openSUSE). Documentation will be under ``/usr/share/doc/dynare`` (only on
|
||||
Debian, Ubuntu and Linux Mint).
|
||||
|
||||
|
||||
On macOS
|
||||
|
@ -91,29 +95,23 @@ With MATLAB
|
|||
^^^^^^^^^^^
|
||||
|
||||
To install Dynare for use with MATLAB, execute the automated installer called
|
||||
``dynare-x.y.pkg`` (where *x.y* is the version number), and follow the
|
||||
instructions. The default installation directory is
|
||||
``/Applications/Dynare/x.y``. After installation, this directory will contain
|
||||
several sub-directories, among which are ``matlab``, ``mex``, and ``doc``.
|
||||
``dynare-x.y-arch.pkg`` (where *x.y* is the version number and *arch* is either arm64 for Apple Silicon or x86_64 for Intel architectures),
|
||||
and follow the instructions.
|
||||
This installation does not require administrative privileges.
|
||||
If for some reason admin rights are requested, use *Change Install Location* and select *Install for me only*.
|
||||
The default installation directory is ``/Applications/Dynare/x.y-arch``.
|
||||
Installing into ``/Applications/dynare`` might fail if you have older versions of Dynare already installed in ``/Applications/Dynare``.
|
||||
To fix this, modify the ownership by executing the following command in Terminal.app::
|
||||
|
||||
Note that several versions of Dynare can coexist (by default in
|
||||
``/Applications/Dynare``), as long as you correctly adjust your path
|
||||
settings (see :ref:`words-warning`).
|
||||
sudo chown -R "$USER":staff /Applications/Dynare
|
||||
|
||||
By default, the installer installs a version of GCC (for use with :opt:`use_dll`)
|
||||
in the installation directory, under the ``.brew`` folder. To do so, it also
|
||||
installs a version of Homebrew_ in the same folder and
|
||||
Xcode Command Line Tools (this is an Apple product) in a system folder.
|
||||
Alternatively, you can modify the installation path in the automated installed using *Customize* and *Location*.
|
||||
After installation, the folder will contain several sub-directories, among which are ``matlab``, ``mex``, and ``doc``.
|
||||
Several versions of Dynare can coexist (by default in ``/Applications/Dynare``),
|
||||
as long as you correctly adjust your path settings (see :ref:`words-warning`).
|
||||
|
||||
All of this requires a bit of time and hard disk space. The amount of time it
|
||||
takes will depend on your computing power and internet connection. To reduce
|
||||
the time the Dynare installer takes, you can install Xcode Command Line Tools
|
||||
yourself (see :ref:`prerequisites-macos`). Dynare, Homebrew, and GCC use
|
||||
about 600 MB of disk space while the Xcode Command Line Tools require about 400
|
||||
MB.
|
||||
|
||||
If you do not use the :opt:`use_dll` option, you have the choice to forgo the
|
||||
installation of GCC and hence Dynare will only take about 50 MB of disk space.
|
||||
It is recommended to install the Xcode Command Line Tools (this is an Apple product)
|
||||
and GCC via Homebrew_ (see :ref:`prerequisites-macos`).
|
||||
|
||||
With Octave
|
||||
^^^^^^^^^^^
|
||||
|
@ -188,15 +186,33 @@ Dynare now ships a compilation environment that can be used with the
|
|||
:opt:`use_dll` option. To install this environment correctly, the Dynare
|
||||
installer ensures that the Xcode Command Line Tools (an Apple product) have
|
||||
been installed on a system folder. To install the Xcode Command Line Tools
|
||||
yourself, simply type ``xcode-select --install`` into the Terminal
|
||||
yourself, simply type ``xcode-select --install`` into the terminal
|
||||
(``/Applications/Utilities/Terminal.app``) prompt.
|
||||
Additionally, to make MATLAB aware that you agree to the terms of Xcode, run the following two commands in the Terminal prompt::
|
||||
|
||||
CLT_VERSION=$(pkgutil --pkg-info=com.apple.pkg.CLTools_Executables | grep version | awk '{print $2}' | cut -d'.' -f1-2)
|
||||
defaults write com.apple.dt.Xcode IDEXcodeVersionForAgreedToGMLicense "${CLT_VERSION}"
|
||||
defaults read com.apple.dt.Xcode IDEXcodeVersionForAgreedToGMLicense
|
||||
|
||||
Otherwise you will see a warning that Xcode is installed, but its license has not been accepted.
|
||||
You can check this e.g. by running the following command in the MATLAB command window::
|
||||
|
||||
mex -setup
|
||||
|
||||
Moreover, we recommend making use of optimized compilation flags when using :opt:`use_dll` and for this you need to install GCC via Homebrew_::
|
||||
|
||||
brew install gcc
|
||||
|
||||
If you already have installed GCC, Dynare will automatically prefer it for :opt:`use_dll`
|
||||
if the binaries are either in ``/opt/homebrew/bin`` on Apple Silicon (arm64) or in ``/usr/local/bin`` on Intel (x86_64) systems.
|
||||
Otherwise, it will fall back to Clang in ``/usr/bin/clang``, which works both on arm64 and x86_64 systems.
|
||||
|
||||
With Octave
|
||||
^^^^^^^^^^^
|
||||
|
||||
The compiler can be installed via Homebrew_. In a terminal, run::
|
||||
|
||||
brew install gcc-12
|
||||
brew install gcc
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
@ -303,6 +319,7 @@ Dynare unusable.
|
|||
.. _Package status in Ubuntu: https://launchpad.net/ubuntu/+source/dynare
|
||||
.. _Package status in Linux Mint: https://community.linuxmint.com/software/view/dynare
|
||||
.. _Package status in Arch Linux: https://aur.archlinux.org/packages/dynare/
|
||||
.. _Package status in openSUSE: https://software.opensuse.org/package/dynare
|
||||
.. _Arch User Repository: https://wiki.archlinux.org/index.php/Arch_User_Repository
|
||||
.. _Dynare website: https://www.dynare.org/
|
||||
.. _Dynare wiki: https://git.dynare.org/Dynare/dynare/wikis
|
||||
|
|
|
@ -94,26 +94,24 @@ Citing Dynare in your research
|
|||
You should cite Dynare if you use it in your research. The
|
||||
recommended way todo this is to cite the present manual, as:
|
||||
|
||||
Stéphane Adjemian, Houtan Bastani, Michel Juillard, Frédéric Karamé,
|
||||
Ferhat Mihoubi, Willi Mutschler, Johannes Pfeifer, Marco Ratto,
|
||||
Normann Rion and Sébastien Villemot (2022), “Dynare: Reference Manual,
|
||||
Version 5,” *Dynare Working Papers*, 72, CEPREMAP
|
||||
Stéphane Adjemian, Michel Juillard, Frédéric Karamé, Willi Mutschler,
|
||||
Johannes Pfeifer, Marco Ratto, Normann Rion and Sébastien Villemot (2024),
|
||||
“Dynare: Reference Manual, Version 6,” *Dynare Working Papers*, 80, CEPREMAP
|
||||
|
||||
For convenience, you can copy and paste the following into your BibTeX file:
|
||||
|
||||
.. code-block:: bibtex
|
||||
|
||||
@TechReport{Adjemianetal2022,
|
||||
author = {Adjemian, St\'ephane and Bastani, Houtan and
|
||||
Juillard, Michel and Karam\'e, Fr\'ederic and
|
||||
Mihoubi, Ferhat and Mutschler, Willi
|
||||
and Pfeifer, Johannes and Ratto, Marco and
|
||||
@TechReport{Adjemianetal2024,
|
||||
author = {Adjemian, St\'ephane and Juillard, Michel and
|
||||
Karam\'e, Fr\'ederic and Mutschler, Willi and
|
||||
Pfeifer, Johannes and Ratto, Marco and
|
||||
Rion, Normann and Villemot, S\'ebastien},
|
||||
title = {Dynare: Reference Manual Version 5},
|
||||
year = {2022},
|
||||
title = {Dynare: Reference Manual, Version 6},
|
||||
year = {2024},
|
||||
institution = {CEPREMAP},
|
||||
type = {Dynare Working Papers},
|
||||
number = {72},
|
||||
number = {80},
|
||||
}
|
||||
|
||||
If you want to give a URL, use the address of the Dynare website:
|
||||
|
|
|
@ -204,7 +204,7 @@ by the ``dynare`` command.
|
|||
.. option:: params_derivs_order=0|1|2
|
||||
|
||||
When :comm:`identification`, :comm:`dynare_sensitivity` (with
|
||||
identification), or :ref:`estimation_cmd <estim-comm>` are
|
||||
identification), or :ref:`estimation <estim-comm>` are
|
||||
present, this option is used to limit the order of the
|
||||
derivatives with respect to the parameters that are calculated
|
||||
by the preprocessor. 0 means no derivatives, 1 means first
|
||||
|
@ -315,7 +315,7 @@ by the ``dynare`` command.
|
|||
Prevent Dynare from printing the output of the steps leading up to the
|
||||
preprocessor as well as the preprocessor output itself.
|
||||
|
||||
.. option:: mexext=mex|mexw32|mexw64|mexmaci64|mexa64
|
||||
.. option:: mexext=mex|mexw64|mexmaci64|mexmaca64|mexa64
|
||||
|
||||
The mex extension associated with your platform to be used
|
||||
when compiling output associated with :opt:`use_dll`.
|
||||
|
@ -363,7 +363,8 @@ by the ``dynare`` command.
|
|||
For local execution under Windows operating system,
|
||||
set ``parallel_use_psexec=false`` to use ``start``
|
||||
instead of ``psexec``, to properly allocate affinity when there are
|
||||
more than 32 cores in the local machine. [default=true]
|
||||
more than 32 cores in the local machine. This option is also helpful if
|
||||
``psexec`` cannot be executed due to missing admininstrator privileges. [default=true]
|
||||
|
||||
.. option:: -DMACRO_VARIABLE[=MACRO_EXPRESSION]
|
||||
|
||||
|
@ -408,9 +409,11 @@ by the ``dynare`` command.
|
|||
|
||||
.. option:: fast
|
||||
|
||||
Only useful with model option :opt:`use_dll`. Don’t recompile the
|
||||
MEX files when running again the same model file and the lists
|
||||
of variables and the equations haven’t changed. We use a 32
|
||||
Don’t rewrite the output files otherwise written to the disk by the preprocessor
|
||||
when re-running the same model file while the lists of variables and the equations
|
||||
haven’t changed. Note that the whole model still needs to be preprocessed. This option
|
||||
is most useful with model option :opt:`use_dll`, because
|
||||
the time-consuming compilation of the MEX files will be skipped. We use a 32
|
||||
bit checksum, stored in ``<model filename>/checksum``. There
|
||||
is a very small probability that the preprocessor misses a
|
||||
change in the model. In case of doubt, re-run without the fast
|
||||
|
@ -551,13 +554,13 @@ by the ``dynare`` command.
|
|||
executing the ``dynare`` command will leave variables containing
|
||||
results in the workspace available for further processing. More
|
||||
details are given under the relevant computing tasks. The
|
||||
``M_``,``oo_``, and ``options_`` structures are saved in a file
|
||||
``M_``, ``oo_``, and ``options_`` structures are saved in a file
|
||||
called ``FILENAME_results.mat`` located in the ``MODFILENAME/Output`` folder.
|
||||
If they exist, ``estim_params_``,
|
||||
``bayestopt_``, ``dataset_``, ``oo_recursive_`` and
|
||||
``estimation_info`` are saved in the same file. Note that Matlab
|
||||
by default only allows ``.mat``-files up to 2GB. You can lift this
|
||||
restriction by enabling the ``save -v7.3``-option in
|
||||
``estimation_info`` are saved in the same file. Note that MATLAB
|
||||
by default only allows ``.mat`` files up to 2GB. You can lift this
|
||||
restriction by enabling the ``save -v7.3`` option in
|
||||
``Preferences -> General -> MAT-Files``.
|
||||
|
||||
.. matvar:: M_
|
||||
|
@ -672,7 +675,7 @@ parser would continue processing.
|
|||
|
||||
It is also helpful to keep in mind that any piece of code that does not violate
|
||||
Dynare syntax, but at the same time is not recognized by the parser, is interpreted
|
||||
as native MATLAB code. This code will be directly passed to the ``driver`` script.
|
||||
Investigating ``driver.m`` file then helps with debugging. Such problems most often
|
||||
as native MATLAB code. This code will be directly passed to the driver script.
|
||||
Investigating the ``driver.m`` file then helps with debugging. Such problems most often
|
||||
occur when defined variable or parameter names have been misspelled so that Dynare's
|
||||
parser is unable to recognize them.
|
||||
|
|
|
@ -15,11 +15,16 @@ related to the model (and hence not placed in the model file). At the
|
|||
moment, it is only used when using Dynare to run parallel
|
||||
computations.
|
||||
|
||||
On Linux and macOS, the default location of the configuration file is
|
||||
``$HOME/.dynare``, while on Windows it is ``%APPDATA%\dynare.ini``
|
||||
(typically ``c:\Users\USERNAME\AppData\dynare.ini``). You
|
||||
can specify a non standard location using the ``conffile`` option of
|
||||
the ``dynare`` command (see :ref:`dyn-invoc`).
|
||||
On Linux and macOS, the configuration file is searched by default under
|
||||
``dynare/dynare.ini`` in the configuration directories defined by the XDG
|
||||
specification (typically ``$HOME/.config/dynare/dynare.ini`` for the
|
||||
user-specific configuration and ``/etc/xdg/dynare/dynare.ini`` for the
|
||||
system-wide configuration, the former having precedence over the latter). Under
|
||||
Windows, the configuration file is searched by default in
|
||||
``%APPDATA%\dynare\dynare.ini`` (typically
|
||||
``c:\Users\USERNAME\AppData\Roaming\dynare\dynare.ini``). You can specify a non
|
||||
standard location using the ``conffile`` option of the ``dynare`` command (see
|
||||
:ref:`dyn-invoc`).
|
||||
|
||||
The parsing of the configuration file is case-sensitive and it should
|
||||
take the following form, with each option/choice pair placed on a
|
||||
|
@ -54,7 +59,7 @@ conventions such as ``USER_NAME`` have been excluded for concision):
|
|||
``PATH_AND_FILE``
|
||||
|
||||
Indicates a valid path to a file in the underlying operating
|
||||
system (e.g. ``/usr/local/MATLAB/R2010b/bin/matlab``).
|
||||
system (e.g. ``/usr/local/MATLAB/R2023b/bin/matlab``).
|
||||
|
||||
``BOOLEAN``
|
||||
|
||||
|
@ -76,8 +81,15 @@ processing. Currently, there is only one option available.
|
|||
|
||||
.. option:: GlobalInitFile = PATH_AND_FILE
|
||||
|
||||
The location of the global initialization file to be run at
|
||||
the end of ``global_initialization.m``.
|
||||
The location of a global initialization file that can be used to
|
||||
customize some Dynare internals (typically default option values). This
|
||||
is a MATLAB/Octave script.
|
||||
|
||||
If this option is not specified, Dynare will look for a
|
||||
``global_init.m`` file in its configuration directory (typically
|
||||
``$HOME/.config/dynare/global_init.m`` under Linux and macOS, and
|
||||
``c:\Users\USERNAME\AppData\Roaming\dynare\global_init.m`` under
|
||||
Windows).
|
||||
|
||||
*Example*
|
||||
|
||||
|
@ -270,18 +282,42 @@ lines starting with a hashtag (#).
|
|||
.. option:: MatlabOctavePath = PATH_AND_FILE
|
||||
|
||||
The path to the MATLAB or Octave executable. The default value
|
||||
is ``matlab``.
|
||||
is ``matlab`` as MATLAB’s executable is typically in the %PATH% environment
|
||||
variable. When using full paths on Windows, you may need to enclose the path
|
||||
in quoted strings, e.g. ``MatlabOctavePath="C:\Program Files\MATLAB\R2023b\bin\matlab.exe"``
|
||||
|
||||
.. option:: NumberOfThreadsPerJob = INTEGER
|
||||
|
||||
For Windows nodes, sets the number of threads assigned to each
|
||||
remote MATLAB/Octave run. The default value is 1.
|
||||
This option controls the distribution of jobs (e.g. MCMC chains) across additional MATLAB instances that are run in parallel.
|
||||
Needs to be an exact divisor of the number of cores.
|
||||
The formula :opt:`CPUnbr <CPUnbr = INTEGER | [INTEGER:INTEGER]>` divided by :opt:`NumberOfThreadsPerJob <NumberOfThreadsPerJob = INTEGER>`
|
||||
calculates the number of MATLAB/Octave instances that will be launched in parallel,
|
||||
where each instance will then execute a certain number of jobs sequentially.
|
||||
For example, if you run a MCMC estimation with 24 chains on a 12 core machine, setting ``CPUnbr = 12`` and ``NumberOfThreadsPerJob = 4``
|
||||
will launch 3 MATLAB instances in parallel, each of which will compute 8 chains sequentially.
|
||||
Note that this option does not dictate the number of maximum threads utilized by each MATLAB/Octave instance,
|
||||
see related option :opt:`SingleCompThread <SingleCompThread = BOOLEAN>` for this.
|
||||
Particularly for very large models, setting this option to 2 might distribute the workload in a
|
||||
more efficient manner, depending on your hardware and task specifics.
|
||||
It’s advisable to experiment with different values to achieve optimal performance.
|
||||
The default value is ``1``.
|
||||
|
||||
|
||||
.. option:: SingleCompThread = BOOLEAN
|
||||
|
||||
Whether or not to disable MATLAB’s native multithreading. The
|
||||
default value is ``false``. Option meaningless under Octave.
|
||||
This option allows you to enable or disable MATLAB’s native multithreading capability. When set to ``true``,
|
||||
the additional MATLAB instances are initiated in single thread mode utilizing the ``-singleCompThread`` startup option,
|
||||
thereby disabling MATLAB’s native multithreading. When set to ``false``, MATLAB’s native multithreading
|
||||
is enabled, e.g. the actual number of threads utilized by each MATLAB instance is usually determined by the number of CPU cores
|
||||
(you can check this by running ``maxNumCompThreads`` in MATLAB’s command window).
|
||||
Note: While MATLAB aims to accelerate calculations by distributing them across your computer’s threads,
|
||||
certain tasks, like MCMC estimations, may exhibit slowdowns with MATLAB’s multitasking especially when Dynare’s parallel computing is turned on
|
||||
as we do not use MATLAB’s parallel toolbox.
|
||||
So in many cases it is advisable to set this setting to ``true``.
|
||||
If you want to have more control, you can manually add the MATLAB command `maxNumCompThreads(N)` at the beginning of `fParallel.m`.
|
||||
The default value is ``false``. This option is ineffective under Octave.
|
||||
|
||||
|
||||
.. option:: OperatingSystem = OPERATING_SYSTEM
|
||||
|
||||
The operating system associated with a node. Only necessary
|
||||
|
@ -323,7 +359,9 @@ Windows Step-by-Step Guide
|
|||
==========================
|
||||
|
||||
This section outlines the steps necessary on most Windows systems to
|
||||
set up Dynare for parallel execution.
|
||||
set up Dynare for parallel execution. Note that the steps 3 to 6 are
|
||||
required unless parallel execution is confined to a local pool
|
||||
with the ``parallel_use_psexec=false`` option.
|
||||
|
||||
1. Write a configuration file containing the options you want. A
|
||||
mimimum working example setting up a cluster consisting of two
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,13 +15,15 @@ class and methods for dates. Below, you will first find the class and
|
|||
methods used for creating and dealing with dates and then the class
|
||||
used for using time series. Dynare also provides an interface to the
|
||||
X-13 ARIMA-SEATS seasonal adjustment program produced, distributed, and
|
||||
maintained by the US Census Bureau (2017).
|
||||
maintained by the U.S. Census Bureau (2020).
|
||||
|
||||
|
||||
Dates
|
||||
=====
|
||||
.. highlight:: matlab
|
||||
|
||||
.. _dates in a mod file:
|
||||
|
||||
Dates in a mod file
|
||||
-------------------
|
||||
|
||||
|
@ -717,7 +719,7 @@ The dates class
|
|||
|
||||
|br| Overloads the MATLAB/Octave ``mtimes`` operator
|
||||
(``*``). ``A`` and ``B`` are respectively expected to be a
|
||||
``dseries`` object and a scalar integer. Returns ``dates``
|
||||
``dates`` object and a scalar integer. Returns ``dates``
|
||||
object ``A`` replicated ``B`` times.
|
||||
|
||||
*Example*
|
||||
|
@ -1025,7 +1027,7 @@ The dseries class
|
|||
``.xls/.xlsx`` (Octave only supports ``.xlsx`` files and the
|
||||
`io <https://octave.sourceforge.io/io/>`__ package from
|
||||
Octave-Forge must be installed). The extension of the file
|
||||
should be explicitly provided.
|
||||
should be explicitly provided.
|
||||
|
||||
A typical ``.m`` file will have the following form::
|
||||
|
||||
|
@ -1052,10 +1054,10 @@ The dseries class
|
|||
typically usefull if ``INIT__`` is not provided in the data
|
||||
file.
|
||||
|
||||
If an ``.xlsx`` file is used, the first row should be a header
|
||||
containing the variable names. The first column may contain date
|
||||
information that must correspond to a valid date format recognized
|
||||
by Dynare. If such date information is specified in the first column,
|
||||
If an ``.xlsx`` file is used, the first row should be a header
|
||||
containing the variable names. The first column may contain date
|
||||
information that must correspond to a valid date format recognized
|
||||
by Dynare. If such date information is specified in the first column,
|
||||
its header name must be left empty.
|
||||
|
||||
.. construct:: dseries (DATA_MATRIX[,INITIAL_DATE[,LIST_OF_NAMES[,TEX_NAMES]]])
|
||||
|
@ -1963,6 +1965,13 @@ The dseries class
|
|||
|br| Returns the last period where all the variables in ``dseries`` object ``A`` are observed (non NaN).
|
||||
|
||||
|
||||
.. dseriesmethod:: f = lastobservedperiods (A)
|
||||
|
||||
|br| Returns for each variable the last period without missing
|
||||
observations in ``dseries`` object ``A``. Output argument ``f`` is a
|
||||
structure, each field name is the name of a variable in ``A``, each field
|
||||
content is a singleton ``date`` object.
|
||||
|
||||
.. dseriesmethod:: B = lead (A[, p])
|
||||
lead_ (A[, p])
|
||||
|
||||
|
@ -2591,8 +2600,10 @@ The dseries class
|
|||
.. dseriesmethod:: C = remove (A, B)
|
||||
remove_ (A, B)
|
||||
|
||||
|br| Alias for the ``pop`` method with two arguments. Removes
|
||||
variable ``B`` from ``dseries`` object ``A``.
|
||||
|br| If ``B`` is a row char array, the name of a variable, these methods
|
||||
are aliases for ``pop`` and ``pop_`` methods with two arguments. They
|
||||
remove variable ``B`` from ``dseries`` object ``A``. To remove more than
|
||||
one variable, one can pass a cell of row char arrays for ``B``.
|
||||
|
||||
*Example*
|
||||
|
||||
|
@ -2946,8 +2957,8 @@ X-13 ARIMA-SEATS interface
|
|||
|
||||
|br| The x13 class provides a method for each X-13 command as
|
||||
documented in the X-13 ARIMA-SEATS reference manual (`x11`,
|
||||
`automdl`, `estimate`, ...), options can then be passed by
|
||||
key/value pairs. The ``x13`` class has 22 members:
|
||||
`automdl`, `estimate`, ...). The respective options (see Chapter 7 of U.S. Census Bureau (2020))
|
||||
can then be passed by key/value pairs. The ``x13`` class has 22 members:
|
||||
|
||||
:arg y: ``dseries`` object with a single variable.
|
||||
:arg x: ``dseries`` object with an arbitrary number of variables (to be used in the REGRESSION block).
|
||||
|
@ -2991,7 +3002,7 @@ X-13 ARIMA-SEATS interface
|
|||
same time span.
|
||||
|
||||
|
||||
The Following methods allow to set sequence of X-13 commands, write an `.spc` file and run the X-13 binary:
|
||||
The following methods allow to set sequence of X-13 commands, write an `.spc` file, and run the X-13 binary:
|
||||
|
||||
|
||||
.. x13method:: A = arima (A, key, value[, key, value[, [...]]])
|
||||
|
@ -3026,7 +3037,10 @@ X-13 ARIMA-SEATS interface
|
|||
|
||||
Interface to the ``transform`` command, see the X-13
|
||||
ARIMA-SEATS reference manual. All the options must be passed
|
||||
by key/value pairs.
|
||||
by key/value pairs. For example, the key/value pair ``function,log``
|
||||
instructs the use of a multiplicative instead of an additive seasonal pattern,
|
||||
while ``function,auto`` triggers an automatic selection between the two based
|
||||
on their fit.
|
||||
|
||||
|
||||
.. x13method:: A = outlier (A, key, value[, key, value[, [...]]])
|
||||
|
@ -3134,6 +3148,11 @@ X-13 ARIMA-SEATS interface
|
|||
``A.results``. When it makes sense these results are saved in
|
||||
``dseries`` objects (*e.g.* for forecasts or filtered variables).
|
||||
|
||||
.. x13method:: clean (A)
|
||||
|
||||
Removes the temporary files created by an x13 run that store the intermediate
|
||||
results. This method allows keeping the main folder clean but will also
|
||||
delete potentially important debugging information.
|
||||
|
||||
*Example*
|
||||
|
||||
|
@ -3151,6 +3170,57 @@ X-13 ARIMA-SEATS interface
|
|||
|
||||
>> o.run();
|
||||
|
||||
The above example shows a run of X13 with various commands an options specified.
|
||||
|
||||
|
||||
*Example*
|
||||
|
||||
::
|
||||
|
||||
% 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960
|
||||
y = [112 115 145 171 196 204 242 284 315 340 360 417 ... % Jan
|
||||
118 126 150 180 196 188 233 277 301 318 342 391 ... % Feb
|
||||
132 141 178 193 236 235 267 317 356 362 406 419 ... % Mar
|
||||
129 135 163 181 235 227 269 313 348 348 396 461 ... % Apr
|
||||
121 125 172 183 229 234 270 318 355 363 420 472 ... % May
|
||||
135 149 178 218 243 264 315 374 422 435 472 535 ... % Jun
|
||||
148 170 199 230 264 302 364 413 465 491 548 622 ... % Jul
|
||||
148 170 199 242 272 293 347 405 467 505 559 606 ... % Aug
|
||||
136 158 184 209 237 259 312 355 404 404 463 508 ... % Sep
|
||||
119 133 162 191 211 229 274 306 347 359 407 461 ... % Oct
|
||||
104 114 146 172 180 203 237 271 305 310 362 390 ... % Nov
|
||||
118 140 166 194 201 229 278 306 336 337 405 432 ]'; % Dec
|
||||
|
||||
ts = dseries(y,'1949M1');
|
||||
o = x13(ts);
|
||||
o.transform('function','auto','savelog','atr');
|
||||
o.automdl('savelog','all');
|
||||
o.x11('save','(d11 d10)');
|
||||
o.run();
|
||||
o.clean();
|
||||
|
||||
y_SA=o.results.d11;
|
||||
y_seasonal_pattern=o.results.d10;
|
||||
|
||||
figure('Name','Comparison raw data and SAed data');
|
||||
plot(ts.dates,log(o.y.data),ts.dates,log(y_SA.data),ts.dates,log(y_seasonal_pattern.data))
|
||||
|
||||
|
||||
The above example shows how to remove a seasonal pattern from a time series.
|
||||
``o.transform('function','auto','savelog','atr')`` instructs the subsequent
|
||||
``o.automdl()`` command to check whether an additional or a multiplicative
|
||||
pattern fits the data better and to save the result. The result is saved in
|
||||
`o.results.autotransform`, which in the present example indicates that a
|
||||
log transformation, i.e. a multiplicative model was preferred. The ``o.automdl('savelog','all')`` automatically selects a fitting
|
||||
ARIMA model and saves all relevant output to the .log-file. The ``o.x11('save','(d11, d10)')`` instructs
|
||||
``x11`` to save both the final seasonally adjusted series ``d11`` and the final seasonal factor ``d10``
|
||||
into ``dseries`` with the respective names in the output structure ``o.results``. ``o.clean()`` removes the
|
||||
temporary files created by ``o.run()``. Among these are the ``.log``-file storing
|
||||
summary information, the ``.err``-file storing information on problems encountered,
|
||||
the ``.out``-file storing the raw output, and the `.spc`-file storing the specification for the `x11` run.
|
||||
There may be further files depending on the output requested. The last part of the example reads out the
|
||||
results and plots a comparison of the logged raw data and its log-additive decomposition into a
|
||||
seasonal pattern and the seasonally adjusted series.
|
||||
|
||||
Miscellaneous
|
||||
=============
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright © 2018-2019 Dynare Team
|
||||
# Copyright © 2018-2024 Dynare Team
|
||||
#
|
||||
# This file is part of Dynare.
|
||||
#
|
||||
|
@ -80,9 +80,7 @@ class DynObject(ObjectDescription):
|
|||
signode += addnodes.desc_name(name, name)
|
||||
|
||||
if self.has_arguments:
|
||||
if not arglist:
|
||||
signode += addnodes.desc_parameterlist()
|
||||
else:
|
||||
if arglist:
|
||||
signode += addnodes.desc_addname(arglist,arglist)
|
||||
return fullname, prefix
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ class DynareLexer(RegexLexer):
|
|||
"addSeries","addParagraph","addVspace","write","compile")
|
||||
|
||||
operators = (
|
||||
"STEADY_STATE","EXPECTATION","var_expectation","pac_expectation")
|
||||
"STEADY_STATE","EXPECTATION","var_expectation","pac_expectation","pac_target_nonstationary")
|
||||
|
||||
macro_dirs = (
|
||||
"@#includepath", "@#include", "@#define", "@#if",
|
||||
|
@ -83,7 +83,8 @@ class DynareLexer(RegexLexer):
|
|||
'osr_params_bounds','ramsey_constraints','irf_calibration',
|
||||
'moment_calibration','identification','svar_identification',
|
||||
'matched_moments','occbin_constraints','surprise','overwrite','bind','relax',
|
||||
'verbatim','end','node','cluster','paths','hooks'), prefix=r'\b', suffix=r'\s*\b'),Keyword.Reserved),
|
||||
'verbatim','end','node','cluster','paths','hooks','target','pac_target_info','auxname_target_nonstationary',
|
||||
'component', 'growth', 'auxname', 'kind'), prefix=r'\b', suffix=r'\s*\b'),Keyword.Reserved),
|
||||
|
||||
# FIXME: Commands following multiline comments are not highlighted properly.
|
||||
(words(commands + report_commands,
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
version = u'@PACKAGE_VERSION@'
|
||||
release = u'@PACKAGE_VERSION@'
|
|
@ -1,29 +0,0 @@
|
|||
if ENABLE_DOC
|
||||
pdf-local: parallel.pdf
|
||||
endif
|
||||
|
||||
SRC = AvenueParadigm.pdf iVaNo_gain.pdf iVaNo_time_comp.pdf marco.bib \
|
||||
netbook_complete_comp.pdf netbook_complete_openclose.pdf \
|
||||
netbook_partial_comp.pdf netbook_partial_openclose.pdf parallel.tex \
|
||||
quest_complete_comp.pdf quest_complete_openclose.pdf quest_partial_comp.pdf \
|
||||
quest_partial_openclose.pdf RWMH_quest1_PriorsAndPosteriors1Comp.pdf \
|
||||
RWMH_quest1_PriorsAndPosteriors2Comp.pdf \
|
||||
RWMH_quest1_PriorsAndPosteriors3Comp.pdf \
|
||||
RWMH_quest1_PriorsAndPosteriors4Comp.pdf \
|
||||
RWMH_quest1_PriorsAndPosteriors5Comp.pdf \
|
||||
RWMH_quest1_PriorsAndPosteriors6Comp.pdf \
|
||||
RWMH_quest1_PriorsAndPosteriors7Comp.pdf waitbars1.pdf waitbars2.pdf \
|
||||
waitbarsP.pdf
|
||||
|
||||
EXTRA_DIST = $(SRC)
|
||||
|
||||
parallel.pdf: $(SRC)
|
||||
$(PDFLATEX) parallel
|
||||
$(BIBTEX) parallel
|
||||
$(PDFLATEX) parallel
|
||||
$(PDFLATEX) parallel
|
||||
$(PDFLATEX) parallel
|
||||
|
||||
clean-local:
|
||||
rm -f *.log *.aux *.toc *.blg *.bbl *.out
|
||||
rm -f parallel.pdf
|
File diff suppressed because it is too large
Load Diff
|
@ -1,11 +0,0 @@
|
|||
SUBDIRS = utils/cc sylv parser/cc tl doc integ kord src tests
|
||||
|
||||
EXTRA_DIST = dynare_simul
|
||||
|
||||
install-exec-local:
|
||||
$(MKDIR_P) $(DESTDIR)$(pkglibdir)/dynare++
|
||||
cp -r dynare_simul/* $(DESTDIR)$(pkglibdir)/dynare++
|
||||
|
||||
uninstall-local:
|
||||
rm -rf $(DESTDIR)$(pkglibdir)/dynare++
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
EXTRA_DIST = \
|
||||
dynare++-ramsey.tex \
|
||||
dynare++-tutorial.tex \
|
||||
sylvester.tex \
|
||||
tl.tex \
|
||||
changelog-old.html \
|
||||
changelog-sylv-old.html
|
||||
|
||||
if ENABLE_DOC
|
||||
pdf-local: dynare++-ramsey.pdf dynare++-tutorial.pdf sylvester.pdf tl.pdf
|
||||
endif
|
||||
|
||||
%.pdf: %.tex
|
||||
$(PDFLATEX) $<
|
||||
$(PDFLATEX) $<
|
||||
$(PDFLATEX) $<
|
||||
|
||||
CLEANFILES = *.pdf *.log *.aux *.out *.toc
|
||||
|
||||
|
|
@ -1,280 +0,0 @@
|
|||
<HTML>
|
||||
<TITLE>
|
||||
Dynare++ Change Log
|
||||
</TITLE>
|
||||
<!-- $Header$ -->
|
||||
<BODY>
|
||||
<TABLE CELLSPACING=2 ALIGN="CENTER" BORDER=1>
|
||||
<TR>
|
||||
<TD BGCOLOR="#d0d0d0" WIDTH="85"> <b>Revision</b> </TD>
|
||||
<TD BGCOLOR="#d0d0d0" WIDTH="85"> <b>Version</b></TD>
|
||||
<TD BGCOLOR="#d0d0d0" WIDTH="80"> <b>Date</b> </TD>
|
||||
<TD BGCOLOR="#d0d0d0" WIDTH="600"> <b>Description of changes</b></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD>
|
||||
<TD>1.3.7
|
||||
<TD>2008/01/15
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD> Corrected a serious bug in centralizing a
|
||||
decision rule. This bug implies that all results based on simulations
|
||||
of the decision rule were wrong. However results based on stochastic
|
||||
fix points were correct. Thanks to Wouter J. den Haan and Joris de Wind!
|
||||
|
||||
<TR><TD><TD><TD> <TD> Added options --centralize and --no-centralize.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Corrected an error of a wrong
|
||||
variance-covariance matrix in real-time simulations (thanks to Pawel
|
||||
Zabzcyk).
|
||||
|
||||
<TR><TD><TD><TD> <TD> Corrected a bug of integer overflow in refined
|
||||
faa Di Bruno formula if one of refinements is empty. This bug appeared
|
||||
when solving models without forward looking variables.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Corrected a bug in the Sylvester equation
|
||||
formerly working only for models with forward looking variables.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Corrected a bug in global check printout.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Added generating a dump file.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Fixed a bug of forgetting repeated assignments
|
||||
(for example in parameter settings and initval).
|
||||
|
||||
<TR><TD><TD><TD> <TD> Added a diff operator to the parser.
|
||||
|
||||
<TR>
|
||||
<TD>1539
|
||||
<TD>1.3.6
|
||||
<TD>2008/01/03
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD> Corrected a bug of segmentation faults for long
|
||||
names and path names.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Changed a way how random numbers are
|
||||
generated. Dynare++ uses a separate instance of Mersenne twister for
|
||||
each simulation, this corrects a flaw of additional randomness caused
|
||||
by operating system scheduler. This also corrects a strange behaviour
|
||||
of random generator on Windows, where each simulation was getting the
|
||||
same sequence of random numbers.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Added calculation of conditional distributions
|
||||
controlled by --condper and --condsim.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Dropped creating unfoled version of decision
|
||||
rule at the end. This might consume a lot of memory. However,
|
||||
simulations might be slower for some models.
|
||||
|
||||
<TR>
|
||||
<TD>1368
|
||||
<TD>1.3.5
|
||||
<TD>2007/07/11
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD> Corrected a bug of useless storing all derivative
|
||||
indices in a parser. This consumed a lot of memory for large models.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Added an option <tt>--ss-tol</tt> controlling a
|
||||
tolerance used for convergence of a non-linear solver.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Corrected buggy interaction of optimal policy
|
||||
and forward looking variables with more than one period.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Variance matrices can be positive
|
||||
semidefinite. This corrects a bug of throwing an error if estimating
|
||||
approximation errors on ellipse of the state space with a
|
||||
deterministic variable.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Implemented simulations with statistics
|
||||
calculated in real-time. Options <tt>--rtsim</tt> and <tt>--rtper</tt>.
|
||||
|
||||
<TR>
|
||||
<TD>1282
|
||||
<TD>1.3.4
|
||||
<TD>2007/05/15
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected a bug of wrong representation of NaN in generated M-files.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected a bug of occassionaly wrong evaluation of higher order derivatives of integer powers.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Implemented automatic handling of terms involving multiple leads.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected a bug in the numerical integration, i.e. checking of the precision of the solution.
|
||||
|
||||
<TR>
|
||||
<TD>1090
|
||||
<TD>1.3.3
|
||||
<TD>2006/11/20
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected a bug of non-registering an auxiliary variable in initval assignments.
|
||||
|
||||
<TR>
|
||||
<TD>988
|
||||
<TD>1.3.2
|
||||
<TD>2006/10/11
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected a few not-serious bugs: segfault on
|
||||
some exception, error in parsing large files, error in parsing
|
||||
matrices with comments, a bug in dynare_simul.m
|
||||
|
||||
<TR><TD><TD><TD> <TD>Added posibility to specify a list of shocks for
|
||||
which IRFs are calculated
|
||||
|
||||
<TR><TD><TD><TD> <TD>Added --order command line switch
|
||||
|
||||
<TR><TD><TD><TD> <TD>Added writing two MATLAB files for steady state
|
||||
calcs
|
||||
|
||||
<TR><TD><TD><TD> <TD>Implemented optimal policy using keyword
|
||||
planner_objective and planner_discount
|
||||
|
||||
<TR><TD><TD><TD> <TD>Implemented an R interface to Dynare++ algorithms
|
||||
(Tamas Papp)
|
||||
|
||||
<TR><TD><TD><TD> <TD>Highlevel code reengineered to allow for
|
||||
different model inputs
|
||||
|
||||
<TR>
|
||||
<TD>799
|
||||
<TD>1.3.1
|
||||
<TD>2006/06/13
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected few bugs: in error functions, in linear algebra module.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Updated dynare_simul.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Updated the tutorial.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected an error in summing up tensors where
|
||||
setting up the decision rule derivatives. Thanks to Michel
|
||||
Juillard. The previous version was making deterministic effects of
|
||||
future volatility smaller than they should be.
|
||||
|
||||
<TR>
|
||||
<TD>766
|
||||
<TD>1.3.0
|
||||
<TD>2006/05/22
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD>The non-linear solver replaced with a new one.
|
||||
|
||||
<TR><TD><TD><TD> <TD>The parser and derivator replaced with a new
|
||||
code. Now it is possible to put expressions in parameters and initval
|
||||
sections.
|
||||
|
||||
<TR>
|
||||
<TD>752
|
||||
<TD>1.2.2
|
||||
<TD>2006/05/22
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD>Added an option triggering/suppressing IRF calcs..
|
||||
|
||||
<TR><TD><TD><TD> <TD>Newton algortihm is now used for fix-point calculations.
|
||||
|
||||
<TR><TD><TD><TD> <TD> Vertical narrowing of tensors in Faa Di Bruno
|
||||
formula to avoid multiplication with zeros..
|
||||
|
||||
<TR>
|
||||
<TD>436
|
||||
<TD>1.2.1
|
||||
<TD>2005/08/17
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD>Faa Di Bruno for sparse matrices optimized. The
|
||||
implementation now accommodates vertical refinement of function stack
|
||||
in order to fit a corresponding slice to available memory. In
|
||||
addition, zero slices are identified. For some problems, this implies
|
||||
significant speedup.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Analytic derivator speedup.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected a bug in the threading code. The bug
|
||||
stayed concealed in Linux 2.4.* kernels, and exhibited in Linux 2.6.*,
|
||||
which has a different scheduling. This correction also allows using
|
||||
detached threads on Windows.
|
||||
|
||||
<TR>
|
||||
<TD>410
|
||||
<TD>1.2
|
||||
<TD>2005/07/29
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD> <TD>Added Dynare++ tutorial.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Changed and enriched contents of MAT-4 output
|
||||
file.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected a bug of wrong variable indexation
|
||||
resulting in an exception. The error occurred if a variable appeared
|
||||
at time t-1 or t+1 and not at t.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Added MATLAB interface, which allows simulation
|
||||
of a decision rule in MATLAB.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Got rid of Matrix Template Library.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Added checking of model residuals by the
|
||||
numerical integration. Three methods: checking along simulation path,
|
||||
checking along shocks, and on ellipse of states.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected a bug in calculation of higher moments
|
||||
of Normal dist.
|
||||
|
||||
<TR><TD><TD><TD> <TD>Corrected a bug of wrong drawing from Normal dist
|
||||
with non-zero covariances.
|
||||
|
||||
<TR><TD><TD><TD>
|
||||
<TD>Added numerical integration module. Product and Smolyak
|
||||
quadratures over Gauss-Hermite and Gauss-Legendre, and quasi Monte
|
||||
Carlo.
|
||||
|
||||
<TR>
|
||||
<TD>152
|
||||
<TD>1.1
|
||||
<TD>2005/04/22
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD>
|
||||
<TD>Added a calculation of approximation at a stochastic steady state
|
||||
(still experimental).
|
||||
|
||||
<TR><TD><TD><TD>
|
||||
<TD>Corrected a bug in Cholesky decomposition of variance-covariance
|
||||
matrix with off-diagonal elements.
|
||||
|
||||
<TR>
|
||||
<TD>89
|
||||
<TD>1.01
|
||||
<TD>2005/02/23
|
||||
<TD>
|
||||
|
||||
<TR><TD><TD><TD>
|
||||
<TD>Added version printout.
|
||||
|
||||
<TR><TD><TD><TD>
|
||||
<TD>Corrected the bug of multithreading support for P4 HT processors running on Win32.
|
||||
|
||||
<TR><TD><TD><TD>
|
||||
<TD>Enhanced Kronecker product code resulting in approx. 20% speedup.
|
||||
|
||||
<TR><TD><TD><TD>
|
||||
<TD>Implemented vertical stack container refinement, and another
|
||||
method for sparse folded Faa Di Bruno (both not used yet).
|
||||
|
||||
<TR>
|
||||
<TD>5
|
||||
<TD>1.0
|
||||
<TD>2005/02/23
|
||||
<TD>The first released version.
|
||||
|
||||
</TABLE>
|
||||
</BODY>
|
||||
</HTML>
|
|
@ -1,140 +0,0 @@
|
|||
<HTML>
|
||||
<!-- $Header: /var/lib/cvs/dynare_cpp/sylv/change_log.html,v 1.1.1.1 2004/06/04 13:00:05 kamenik Exp $ -->
|
||||
<!-- Tag $Name: $ -->
|
||||
<TITLE>
|
||||
Sylvester Solver Change Log
|
||||
</TITLE>
|
||||
<BODY>
|
||||
<TABLE CELLSPACING=2 ALIGN="CENTER" BORDER=1>
|
||||
<TR>
|
||||
<TD BGCOLOR="#d0d0d0" WIDTH="85"> Tag </TD>
|
||||
<TD BGCOLOR="#d0d0d0" WIDTH="80"> Date </TD>
|
||||
<TD BGCOLOR="#d0d0d0" WIDTH="600"> Description/Changes</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD>2003/09/10</TD>
|
||||
<TD>Initial version solving triangular system put to repository</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Implemented solution of general case.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Implemented a memory pool (Paris).</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Implemented MEX interface to the routine (Paris).</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Implemented QuasiTriangularZero (Paris) (not fully used yet).</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>rel-1</TD>
|
||||
<TD>2003/10-02</TD>
|
||||
<TD>Version sent to Michel.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Inheritance streamlined, QuasiTriangular inherits from GeneralMatrix.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Implemented block diagonalization algorithm.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Solution routines rewritten so that the output rewrites input,
|
||||
considerable memory improvement.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>MEX interface now links with LAPACK library from MATLAB.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Added a hack to MEX library loading in order to avoid MATLAB crash in Wins.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>rel-2</TD>
|
||||
<TD>2003/10/15</TD>
|
||||
<TD>Version sent to Michel.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>KronUtils now rewrite input by output using less memory.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Added iterative solution algorithm (doubling).</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Introduced abstraction for set of parameters (SylvParams).</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Algorithm enabled to solve problems with singular C.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Implemented a class chooser chossing between QuasiTriangularZero,
|
||||
and QuasiTriangular (padded with zero) depending on size of the
|
||||
problem. Full use of QuasiTriangularZero.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Reimplemented QuasiTriangular::solve, offdiagonal elements are
|
||||
eleiminated by gauss with partial pivoting, not by transformation of
|
||||
complex eigenvalues. More stable for ill conditioned eigenvalues.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Reimplemented calculation of eliminating vectors, much more
|
||||
numerically stable now.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>Implemented algorithm for ordering of eigenvalues (not used now,
|
||||
no numerical improvements).</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>rel-3</TD>
|
||||
<TD>2003/12/4</TD>
|
||||
<TD>Version sent to Michel.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
<TD>GeneralMatrix separated for use outside, in sylv module we use
|
||||
its subclass SylvMatrix. Implemented ConstGeneralMatrix (useful outside).
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>rel-4</TD>
|
||||
<TD>2004/6/4</TD>
|
||||
<TD>Version, which was moved to pythie.cepremap.cnrs.fr repository.</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</BODY>
|
||||
</HTML>
|
|
@ -1,157 +0,0 @@
|
|||
\documentclass[10pt]{article}
|
||||
\usepackage{array,natbib,times}
|
||||
\usepackage{amsmath, amsthm, amssymb}
|
||||
|
||||
%\usepackage[pdftex,colorlinks]{hyperref}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\title{Implementation of Ramsey Optimal Policy in Dynare++, Timeless Perspective}
|
||||
|
||||
\author{Ondra Kamen\'\i k}
|
||||
|
||||
\date{June 2006}
|
||||
\maketitle
|
||||
|
||||
\textbf{Abstract:} This document provides a derivation of Ramsey
|
||||
optimal policy from timeless perspective and describes its
|
||||
implementation in Dynare++.
|
||||
|
||||
\section{Derivation of the First Order Conditions}
|
||||
|
||||
Let us start with an economy populated by agents who take a number of
|
||||
variables exogenously, or given. These may include taxes or interest
|
||||
rates for example. These variables can be understood as decision (or control)
|
||||
variables of the timeless Ramsey policy (or social planner). The agent's
|
||||
information set at time $t$ includes mass-point distributions of these
|
||||
variables for all times after $t$. If $i_t$ denotes an interest rate
|
||||
for example, then the information set $I_t$ includes
|
||||
$i_{t|t},i_{t+1|t},\ldots,i_{t+k|t},\ldots$ as numbers. In addition
|
||||
the information set includes all realizations of past exogenous
|
||||
innovations $u_\tau$ for $\tau=t,t-1,\ldots$ and distibutions
|
||||
$u_\tau\sim N(0,\Sigma)$ for $\tau=t+1,\ldots$. These information sets will be denoted $I_t$.
|
||||
|
||||
An information set including only the information on past realizations
|
||||
of $u_\tau$ and future distributions of $u_\tau\sim N(0\sigma)$ will
|
||||
be denoted $J_t$. We will use the following notation for expectations
|
||||
through these sets:
|
||||
\begin{eqnarray*}
|
||||
E^I_t[X] &=& E(X|I_t)\\
|
||||
E^J_t[X] &=& E(X|J_t)
|
||||
\end{eqnarray*}
|
||||
|
||||
The agents optimize taking the decision variables of the social
|
||||
planner at $t$ and future as given. This means that all expectations
|
||||
they form are conditioned on the set $I_t$. Let $y_t$ denote a vector
|
||||
of all endogenous variables including the planer's decision
|
||||
variables. Let the number of endogenous variables be $n$. The economy
|
||||
can be described by $m$ equations including the first order conditions
|
||||
and transition equations:
|
||||
\begin{equation}\label{constr}
|
||||
E_t^I\left[f(y_{t-1},y_t,y_{t+1},u_t)\right] = 0.
|
||||
\end{equation}
|
||||
This lefts $n-m$
|
||||
the planner's control variables. The solution of this problem is a
|
||||
decision rule of the form:
|
||||
\begin{equation}\label{agent_dr}
|
||||
y_t=g(y_{t-1},u_t,c_{t|t},c_{t+1|t},\ldots,c_{t+k|t},\ldots),
|
||||
\end{equation}
|
||||
where $c$ is a vector of planner's control variables.
|
||||
|
||||
Each period the social planner chooses the vector $c_t$ to maximize
|
||||
his objective such that \eqref{agent_dr} holds for all times following
|
||||
$t$. This would lead to $n-m$ first order conditions with respect to
|
||||
$c_t$. These first order conditions would contain unknown derivatives
|
||||
of endogenous variables with respect to $c$, which would have to be
|
||||
retrieved from the implicit constraints \eqref{constr} since the
|
||||
explicit form \eqref{agent_dr} is not known.
|
||||
|
||||
The other way to proceed is to assume that the planner is so dumb that
|
||||
he is not sure what are his control variables. So he optimizes with
|
||||
respect to all $y_t$ given the constraints \eqref{constr}. If the
|
||||
planner's objective is $b(y_{t-1},y_t,y_{t+1},u_t)$ with a discount rate
|
||||
$\beta$, then the optimization problem looks as follows:
|
||||
\begin{align}
|
||||
\max_{\left\{y_\tau\right\}^\infty_t}&E_t^J
|
||||
\left[\sum_{\tau=t}^\infty\beta^{\tau-t}b(y_{\tau-1},y_\tau,y_{\tau+1},u_\tau)\right]\notag\\
|
||||
&\rm{s.t.}\label{planner_optim}\\
|
||||
&\hskip1cm E^I_\tau\left[f(y_{\tau-1},y_\tau,y_{\tau+1},u_\tau)\right]=0\quad\rm{for\ }
|
||||
\tau=\ldots,t-1,t,t+1,\ldots\notag
|
||||
\end{align}
|
||||
Note two things: First, each constraint \eqref{constr} in
|
||||
\eqref{planner_optim} is conditioned on $I_\tau$ not $I_t$. This is
|
||||
very important, since the behaviour of agents at period $\tau=t+k$ is
|
||||
governed by the constraint using expectations conditioned on $t+k$,
|
||||
not $t$. The social planner knows that at $t+k$ the agents will use
|
||||
all information available at $t+k$. Second, the constraints for the
|
||||
planner's decision made at $t$ include also constraints for agent's
|
||||
behaviour prior to $t$. This is because the agent's decision rules are
|
||||
given in the implicit form \eqref{constr} and not in the explicit form
|
||||
\eqref{agent_dr}.
|
||||
|
||||
Using Lagrange multipliers, this can be rewritten as
|
||||
\begin{align}
|
||||
\max_{y_t}E_t^J&\left[\sum_{\tau=t}^\infty\beta^{\tau-t}b(y_{\tau-1},y_\tau,y_{\tau+1},u_\tau)\right.\notag\\
|
||||
&\left.+\sum_{\tau=-\infty}^{\infty}\beta^{\tau-t}\lambda^T_\tau E_\tau^I\left[f(y_{\tau-1},y_\tau,y_{\tau+1},u_\tau)\right]\right],
|
||||
\label{planner_optim_l}
|
||||
\end{align}
|
||||
where $\lambda_t$ is a vector of Lagrange multipliers corresponding to
|
||||
constraints \eqref{constr}. Note that the multipliers are multiplied
|
||||
by powers of $\beta$ in order to make them stationary. Taking a
|
||||
derivative wrt $y_t$ and putting it to zero yields the first order
|
||||
conditions of the planner's problem:
|
||||
\begin{align}
|
||||
E^J_t\left[\vphantom{\frac{\int^(_)}{\int^(\_)}}\right.&\frac{\partial}{\partial y_t}b(y_{t-1},y_t,y_{t+1},u_t)+
|
||||
\beta L^{+1}\frac{\partial}{\partial y_{t-1}}b(y_{t-1},y_t,y_{t+1},u_t)\notag\\
|
||||
&+\beta^{-1}\lambda_{t-1}^TE^I_{t-1}\left[L^{-1}\frac{\partial}{\partial y_{t+1}}f(y_{t-1},y_t,y_{t+1},u_t)\right]\notag\\
|
||||
&+\lambda_t^TE^I_t\left[\frac{\partial}{\partial y_{t}}f(y_{t-1},y_t,y_{t+1},u_t)\right]\notag\\
|
||||
&+\beta\lambda_{t+1}^TE^I_{t+1}\left[L^{+1}\frac{\partial}{\partial y_{t-1}}f(y_{t-1},y_t,y_{t+1},u_t)\right]
|
||||
\left.\vphantom{\frac{\int^(_)}{\int^(\_)}}\right]
|
||||
= 0,\label{planner_optim_foc}
|
||||
\end{align}
|
||||
where $L^{+1}$ and $L^{-1}$ are one period lead and lag operators respectively.
|
||||
|
||||
Now we have to make a few assertions concerning expectations
|
||||
conditioned on the different information sets to simplify
|
||||
\eqref{planner_optim_foc}. Recall the formula for integration through
|
||||
information on which another expectation is conditioned, this is:
|
||||
$$E\left[E\left[u|v\right]\right] = E[u],$$
|
||||
where the outer expectation integrates through $v$. Since $J_t\subset
|
||||
I_t$, by easy application of the above formula we obtain
|
||||
\begin{eqnarray}
|
||||
E^J_t\left[E^I_t\left[X\right]\right] &=& E^J_t\left[X\right]\quad\rm{and}\notag\\
|
||||
E^J_t\left[E^I_{t-1}\left[X\right]\right] &=& E^J_t\left[X\right]\label{e_iden}\\
|
||||
E^J_t\left[E^I_{t+1}\left[X\right]\right] &=& E^J_{t+1}\left[X\right]\notag
|
||||
\end{eqnarray}
|
||||
Now, the last term of \eqref{planner_optim_foc} needs a special
|
||||
attention. It is equal to
|
||||
$E^J_t\left[\beta\lambda^T_{t+1}E^I_{t+1}[X]\right]$. If we assume
|
||||
that the problem \eqref{planner_optim} has a solution, then there is a
|
||||
deterministic function from $J_{t+1}$ to $\lambda_{t+1}$ and so
|
||||
$\lambda_{t+1}\in J_{t+1}\subset I_{t+1}$. And the last term is equal
|
||||
to $E^J_{t}\left[E^I_{t+1}[\beta\lambda^T_{t+1}X]\right]$, which is
|
||||
$E^J_{t+1}\left[\beta\lambda^T_{t+1}X\right]$. This term can be
|
||||
equivalently written as
|
||||
$E^J_{t}\left[\beta\lambda^T_{t+1}E^J_{t+1}[X]\right]$. The reason why
|
||||
we write the term in this way will be clear later. All in all, we have
|
||||
\begin{align}
|
||||
E^J_t\left[\vphantom{\frac{\int^(_)}{\int^(\_)}}\right.&\frac{\partial}{\partial y_t}b(y_{t-1},y_t,y_{t+1},u_t)+
|
||||
\beta L^{+1}\frac{\partial}{\partial y_{t-1}}b(y_{t-1},y_t,y_{t+1},u_t)\notag\\
|
||||
&+\beta^{-1}\lambda_{t-1}^TL^{-1}\frac{\partial}{\partial y_{t+1}}f(y_{t-1},y_t,y_{t+1},u_t)\notag\\
|
||||
&+\lambda_t^T\frac{\partial}{\partial y_{t}}f(y_{t-1},y_t,y_{t+1},u_t)\notag\\
|
||||
&+\beta\lambda_{t+1}^TE^J_{t+1}\left[L^{+1}\frac{\partial}{\partial y_{t-1}}f(y_{t-1},y_t,y_{t+1},u_t)\right]
|
||||
\left.\vphantom{\frac{\int^(_)}{\int^(\_)}}\right]
|
||||
= 0.\label{planner_optim_foc2}
|
||||
\end{align}
|
||||
Note that we have not proved that \eqref{planner_optim_foc} and
|
||||
\eqref{planner_optim_foc2} are equivalent. We proved only that if
|
||||
\eqref{planner_optim_foc} has a solution, then
|
||||
\eqref{planner_optim_foc2} is equivalent (and has the same solution).
|
||||
|
||||
%%- \section{Implementation}
|
||||
%%-
|
||||
%%- The user inputs $b(y_{t-1},y_t,y_{t+1},u_t)$, $\beta$, and agent's
|
||||
%%- first order conditions \eqref{constr}. The algorithm has to produce
|
||||
%%- \eqref{planner_optim_foc2}.
|
||||
%%-
|
||||
\end{document}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,176 +0,0 @@
|
|||
%
|
||||
% SYNOPSIS
|
||||
%
|
||||
% r = dynare_simul(name, shocks)
|
||||
% r = dynare_simul(name, prefix, shocks)
|
||||
% r = dynare_simul(name, shocks, start)
|
||||
% r = dynare_simul(name, prefix, shocks, start)
|
||||
%
|
||||
% name name of MAT-file produced by dynare++
|
||||
% prefix prefix of variables in the MAT-file
|
||||
% shocks matrix of shocks
|
||||
% start zero period value
|
||||
%
|
||||
% Note that this file requires the dynare_simul_ DLL to be in the path.
|
||||
% This DLL is distributed with Dynare, under the mex/matlab or mex/octave
|
||||
% subdirectory.
|
||||
%
|
||||
% SEMANTICS
|
||||
%
|
||||
% The command reads a decision rule from the MAT-file having the given
|
||||
% prefix. Then it starts simulating the decision rule with zero time value
|
||||
% equal to the given start. It uses the given shocks for the simulation. If
|
||||
% the start is not given, the state about which the decision rule is
|
||||
% centralized is taken (called fix point, or stochastic steady state, take
|
||||
% your pick).
|
||||
%
|
||||
% prefix Use the prefix with which you called dynare++, the default
|
||||
% prefix in dynare++ is 'dyn'.
|
||||
% shocks Number of rows must be a number of exogenous shocks,
|
||||
% number of columns gives the number of simulated
|
||||
% periods. NaNs and Infs in the matrix are substitued by
|
||||
% draws from the normal distribution using the covariance
|
||||
% matrix given in the model file.
|
||||
% start Vector of endogenous variables in the ordering given by
|
||||
% <prefix>_vars.
|
||||
%
|
||||
% Seed for random generator is derived from calling rand(1,1). Therefore,
|
||||
% seeding can be controlled with rand('state') and rand('state',some_seed).
|
||||
%
|
||||
% EXAMPLES
|
||||
%
|
||||
% All examples suppose that the prefix is 'dyn' and that your_model.mat
|
||||
% has been loaded into Matlab.
|
||||
%
|
||||
% 1. response to permanent negative shock to the third exo var EPS3 for
|
||||
% 100 periods
|
||||
%
|
||||
% shocks = zeros(4,100); % 4 exogenous variables in the model
|
||||
% shocks(dyn_i_EPS3,:) = -0.1; % the permanent shock to EPS3
|
||||
% r = dynare_simul('your_model.mat',shocks);
|
||||
%
|
||||
% 2. one stochastic simulation for 100 periods
|
||||
%
|
||||
% shocks = zeros(4,100)./0; % put NaNs everywhere
|
||||
% r = dynare_simul('your_model.mat',shocks);
|
||||
%
|
||||
% 3. one stochastic simulation starting at 75% undercapitalized economy
|
||||
%
|
||||
% shocks = zeros(4,100)./0; % put NaNs everywhere
|
||||
% ystart = dyn_ss; % get copy of DR fix point
|
||||
% ystart(dyn_i_K) = 0.75*dyn_ss(dyn_i_K); % scale down the capital
|
||||
% r = dynare_simul('your_model.mat',shocks,ystart);
|
||||
%
|
||||
%
|
||||
% SEE ALSO
|
||||
%
|
||||
% "DSGE Models with Dynare++. A Tutorial.", Ondra Kamenik, 2005
|
||||
|
||||
% Copyright © 2005-2011, Ondra Kamenik
|
||||
% Copyright © 2020, Dynare Team
|
||||
|
||||
|
||||
function r = dynare_simul(varargin)
|
||||
|
||||
if ~exist('dynare_simul_','file')
|
||||
error('Can''t find dynare_simul_ DLL in the path. The simplest way to add it is to run Dynare once in this session.')
|
||||
end
|
||||
|
||||
% get the file name and load data
|
||||
fname = varargin{1};
|
||||
load(fname);
|
||||
|
||||
% set prefix, shocks, ystart
|
||||
if ischar(varargin{2})
|
||||
prefix = varargin{2};
|
||||
if length(varargin) == 3
|
||||
shocks = varargin{3};
|
||||
ystart = NaN;
|
||||
elseif length(varargin) == 4
|
||||
shocks = varargin{3};
|
||||
ystart = varargin{4};
|
||||
else
|
||||
error('Wrong number of parameters.');
|
||||
end
|
||||
else
|
||||
prefix = 'dyn';
|
||||
if length(varargin) == 2
|
||||
shocks = varargin{2};
|
||||
ystart = NaN;
|
||||
elseif length(varargin) == 3
|
||||
shocks = varargin{2};
|
||||
ystart = varargin{3};
|
||||
else
|
||||
error('Wrong number of parameters.');
|
||||
end
|
||||
end
|
||||
|
||||
% load all needed variables but prefix_g_*
|
||||
if exist([prefix '_nstat'],'var')
|
||||
nstat = eval([prefix '_nstat']);
|
||||
else
|
||||
error(['Could not find variable ' prefix '_nstat in workspace']);
|
||||
end
|
||||
if exist([prefix '_npred'],'var')
|
||||
npred = eval([prefix '_npred']);
|
||||
else
|
||||
error(['Could not find variable ' prefix '_npred in workspace']);
|
||||
end
|
||||
if exist([prefix '_nboth'],'var')
|
||||
nboth = eval([prefix '_nboth']);
|
||||
else
|
||||
error(['Could not find variable ' prefix '_nboth in workspace']);
|
||||
end
|
||||
if exist([prefix '_nforw'],'var')
|
||||
nforw = eval([prefix '_nforw']);
|
||||
else
|
||||
error(['Could not find variable ' prefix '_nforw in workspace']);
|
||||
end
|
||||
if exist([prefix '_ss'],'var')
|
||||
ss = eval([prefix '_ss']);
|
||||
else
|
||||
error(['Could not find variable ' prefix '_ss in workspace']);
|
||||
end
|
||||
if exist([prefix '_vcov_exo'],'var')
|
||||
vcov_exo = eval([prefix '_vcov_exo']);
|
||||
else
|
||||
error(['Could not find variable ' prefix '_vcov_exo in workspace']);
|
||||
end
|
||||
nexog = size(vcov_exo,1);
|
||||
|
||||
if isnan(ystart)
|
||||
ystart = ss;
|
||||
end
|
||||
|
||||
% newer version of dynare++ doesn't return prefix_g_0, we make it here if
|
||||
% it does not exist in workspace
|
||||
g_zero = [prefix '_g_0'];
|
||||
if ~exist(g_zero,'var')
|
||||
dr.g_0=zeros(nstat+npred+nboth+nforw,1);
|
||||
else
|
||||
dr.g_0=eval(g_zero);
|
||||
end
|
||||
|
||||
% make derstr a string of comma seperated existing prefix_g_*
|
||||
order = 1;
|
||||
cont = 1;
|
||||
while cont == 1
|
||||
g_ord = [prefix '_g_' num2str(order)];
|
||||
if exist(g_ord,'var')
|
||||
dr.(['g_' num2str(order)])=eval(g_ord);
|
||||
order = order + 1;
|
||||
else
|
||||
cont = 0;
|
||||
end
|
||||
end
|
||||
|
||||
% set seed
|
||||
seed = ceil(10000*rand(1,1));
|
||||
|
||||
% call dynare_simul_
|
||||
[err,r]=dynare_simul_(order-1,nstat,npred,nboth,nforw,...
|
||||
nexog,ystart,shocks,vcov_exo,seed,ss,dr);
|
||||
|
||||
if err
|
||||
error('Simulation failed')
|
||||
end
|
|
@ -1 +0,0 @@
|
|||
SUBDIRS = cc src testing
|
|
@ -1,15 +0,0 @@
|
|||
noinst_LIBRARIES = libinteg.a
|
||||
|
||||
libinteg_a_SOURCES = \
|
||||
quadrature.cc \
|
||||
quadrature.hh \
|
||||
quasi_mcarlo.cc \
|
||||
quasi_mcarlo.hh \
|
||||
product.cc \
|
||||
product.hh \
|
||||
smolyak.cc \
|
||||
smolyak.hh \
|
||||
vector_function.cc \
|
||||
vector_function.hh \
|
||||
precalc_quadrature.hh
|
||||
libinteg_a_CPPFLAGS = -I../../sylv/cc -I../../utils/cc -I../../tl/cc -I$(top_srcdir)/mex/sources
|
File diff suppressed because it is too large
Load Diff
|
@ -1,143 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "product.hh"
|
||||
#include "symmetry.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
/* This constructs a product iterator corresponding to index (j0,0,…,0). */
|
||||
|
||||
prodpit::prodpit(const ProductQuadrature &q, int j0, int l)
|
||||
: prodq(q), level(l), npoints(q.uquad.numPoints(l)),
|
||||
jseq(q.dimen(), 0),
|
||||
end_flag(false),
|
||||
sig{q.dimen()},
|
||||
p{q.dimen()}
|
||||
{
|
||||
if (j0 < npoints)
|
||||
{
|
||||
jseq[0] = j0;
|
||||
setPointAndWeight();
|
||||
}
|
||||
else
|
||||
end_flag = true;
|
||||
}
|
||||
|
||||
bool
|
||||
prodpit::operator==(const prodpit &ppit) const
|
||||
{
|
||||
return &prodq == &ppit.prodq && end_flag == ppit.end_flag && jseq == ppit.jseq;
|
||||
}
|
||||
|
||||
prodpit &
|
||||
prodpit::operator++()
|
||||
{
|
||||
int i = prodq.dimen()-1;
|
||||
jseq[i]++;
|
||||
while (i >= 0 && jseq[i] == npoints)
|
||||
{
|
||||
jseq[i] = 0;
|
||||
i--;
|
||||
if (i >= 0)
|
||||
jseq[i]++;
|
||||
}
|
||||
sig.signalAfter(std::max(i, 0));
|
||||
|
||||
if (i == -1)
|
||||
end_flag = true;
|
||||
|
||||
if (!end_flag)
|
||||
setPointAndWeight();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* This calculates the weight and sets point coordinates from the indices. */
|
||||
|
||||
void
|
||||
prodpit::setPointAndWeight()
|
||||
{
|
||||
w = 1.0;
|
||||
for (int i = 0; i < prodq.dimen(); i++)
|
||||
{
|
||||
p[i] = (prodq.uquad).point(level, jseq[i]);
|
||||
w *= (prodq.uquad).weight(level, jseq[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Debug print. */
|
||||
|
||||
void
|
||||
prodpit::print() const
|
||||
{
|
||||
auto ff = std::cout.flags();
|
||||
std::cout << "j=[";
|
||||
for (int i = 0; i < prodq.dimen(); i++)
|
||||
std::cout << std::setw(2) << jseq[i];
|
||||
std::cout << std::showpos << std::fixed << std::setprecision(3)
|
||||
<< "] " << std::setw(4) << w << "*(";
|
||||
for (int i = 0; i < prodq.dimen()-1; i++)
|
||||
std::cout << std::setw(4) << p[i] << ' ';
|
||||
std::cout << std::setw(4) << p[prodq.dimen()-1] << ')' << std::endl;
|
||||
std::cout.flags(ff);
|
||||
}
|
||||
|
||||
ProductQuadrature::ProductQuadrature(int d, const OneDQuadrature &uq)
|
||||
: QuadratureImpl<prodpit>(d), uquad(uq)
|
||||
{
|
||||
// TODO: check d≥1
|
||||
}
|
||||
|
||||
/* This calls prodpit constructor to return an iterator which points
|
||||
approximatelly at ‘ti’-th portion out of ‘tn’ portions. First we find
|
||||
out how many points are in the level, and then construct an interator
|
||||
(j0,0,…,0) where j0=ti·npoints/tn. */
|
||||
|
||||
prodpit
|
||||
ProductQuadrature::begin(int ti, int tn, int l) const
|
||||
{
|
||||
// TODO: raise if l<dimen()
|
||||
// TODO: check l ≤ uquad.numLevels()
|
||||
int npoints = uquad.numPoints(l);
|
||||
return prodpit(*this, ti*npoints/tn, l);
|
||||
}
|
||||
|
||||
/* This just starts at the first level and goes to a higher level as long as a
|
||||
number of evaluations (which is nₖᵈ for k being the level) is less than the
|
||||
given number of evaluations. */
|
||||
|
||||
void
|
||||
ProductQuadrature::designLevelForEvals(int max_evals, int &lev, int &evals) const
|
||||
{
|
||||
int last_evals;
|
||||
evals = 1;
|
||||
lev = 1;
|
||||
do
|
||||
{
|
||||
lev++;
|
||||
last_evals = evals;
|
||||
evals = numEvals(lev);
|
||||
}
|
||||
while (lev < uquad.numLevels()-2 && evals < max_evals);
|
||||
lev--;
|
||||
evals = last_evals;
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Product quadrature.
|
||||
|
||||
/* This file defines a product multidimensional quadrature. If Qₖ$ denotes the
|
||||
one dimensional quadrature, then the product quadrature Q of k level and
|
||||
dimension d takes the form:
|
||||
|
||||
nₖ nₖ
|
||||
Qf = ∑ … ∑ w_i₁·…·w_{i_d} f(x_i₁,…,x_{i_d})
|
||||
i₁=1 i_d=1
|
||||
|
||||
which can be written in terms of the one dimensional quadrature Qₖ as
|
||||
|
||||
Qf=(Qₖ⊗…⊗Qₖ)f
|
||||
|
||||
Here we define the product quadrature iterator prodpit and plug it into
|
||||
QuadratureImpl to obtains ProductQuadrature. */
|
||||
|
||||
#ifndef PRODUCT_H
|
||||
#define PRODUCT_H
|
||||
|
||||
#include "int_sequence.hh"
|
||||
#include "vector_function.hh"
|
||||
#include "quadrature.hh"
|
||||
|
||||
/* This defines a product point iterator. We have to maintain the following: a
|
||||
pointer to product quadrature in order to know the dimension and the
|
||||
underlying one dimensional quadrature, then level, number of points in the
|
||||
level, integer sequence of indices, signal, the coordinates of the point and
|
||||
the weight.
|
||||
|
||||
The point indices, signal, and point coordinates are implmented as pointers
|
||||
in order to allow for empty constructor.
|
||||
|
||||
The constructor prodpit(const ProductQuadrature& q, int j0, int l)
|
||||
constructs an iterator pointing to (j0,0,…,0), which is used by begin()
|
||||
dictated by QuadratureImpl. */
|
||||
|
||||
class ProductQuadrature;
|
||||
|
||||
class prodpit
|
||||
{
|
||||
protected:
|
||||
const ProductQuadrature &prodq;
|
||||
int level{0};
|
||||
int npoints{0};
|
||||
IntSequence jseq;
|
||||
bool end_flag{true};
|
||||
ParameterSignal sig;
|
||||
Vector p;
|
||||
double w;
|
||||
public:
|
||||
prodpit() = default;
|
||||
prodpit(const ProductQuadrature &q, int j0, int l);
|
||||
prodpit(const prodpit &ppit) = default;
|
||||
~prodpit() = default;
|
||||
bool operator==(const prodpit &ppit) const;
|
||||
bool
|
||||
operator!=(const prodpit &ppit) const
|
||||
{
|
||||
return !operator==(ppit);
|
||||
}
|
||||
prodpit &operator=(const prodpit &spit) = delete;
|
||||
prodpit &operator++();
|
||||
const ParameterSignal &
|
||||
signal() const
|
||||
{
|
||||
return sig;
|
||||
}
|
||||
const Vector &
|
||||
point() const
|
||||
{
|
||||
return p;
|
||||
}
|
||||
double
|
||||
weight() const
|
||||
{
|
||||
return w;
|
||||
}
|
||||
void print() const;
|
||||
protected:
|
||||
void setPointAndWeight();
|
||||
};
|
||||
|
||||
/* The product quadrature is just QuadratureImpl with the product iterator
|
||||
plugged in. The object is constructed by just giving the underlying one
|
||||
dimensional quadrature, and the dimension. The only extra method is
|
||||
designLevelForEvals() which for the given maximum number of evaluations (and
|
||||
dimension and underlying quadrature from the object) returns a maximum level
|
||||
yeilding number of evaluations less than the given number. */
|
||||
|
||||
class ProductQuadrature : public QuadratureImpl<prodpit>
|
||||
{
|
||||
friend class prodpit;
|
||||
const OneDQuadrature &uquad;
|
||||
public:
|
||||
ProductQuadrature(int d, const OneDQuadrature &uq);
|
||||
~ProductQuadrature() override = default;
|
||||
int
|
||||
numEvals(int l) const override
|
||||
{
|
||||
int res = 1;
|
||||
for (int i = 0; i < dimen(); i++)
|
||||
res *= uquad.numPoints(l);
|
||||
return res;
|
||||
}
|
||||
void designLevelForEvals(int max_eval, int &lev, int &evals) const;
|
||||
protected:
|
||||
prodpit begin(int ti, int tn, int level) const override;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "quadrature.hh"
|
||||
#include "precalc_quadrature.hh"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
void
|
||||
OneDPrecalcQuadrature::calcOffsets()
|
||||
{
|
||||
offsets[0] = 0;
|
||||
for (int i = 1; i < num_levels; i++)
|
||||
offsets[i] = offsets[i-1] + num_points[i-1];
|
||||
}
|
||||
|
||||
GaussHermite::GaussHermite()
|
||||
: OneDPrecalcQuadrature(gh_num_levels, gh_num_points, gh_weights, gh_points)
|
||||
{
|
||||
}
|
||||
|
||||
GaussLegendre::GaussLegendre()
|
||||
: OneDPrecalcQuadrature(gl_num_levels, gl_num_points, gl_weights, gl_points)
|
||||
{
|
||||
}
|
|
@ -1,329 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Quadrature.
|
||||
|
||||
/* This file defines an interface for one dimensional (non-nested) quadrature
|
||||
OneDQuadrature, and a parent for all multi-dimensional quadratures. This
|
||||
parent class Quadrature presents a general concept of quadrature, this is
|
||||
|
||||
N
|
||||
∫ f(x)dx ≃ ∑ wᵢxᵢ
|
||||
ⁱ⁼¹
|
||||
|
||||
The class Quadrature just declares this concept. The concept is implemented
|
||||
by class QuadratureImpl which paralelizes the summation. All implementations
|
||||
therefore wishing to use the parallel implementation should inherit from
|
||||
QuadratureImpl and integration is done.
|
||||
|
||||
The integration concept relies on a point iterator, which goes through all
|
||||
xᵢ and wᵢ for i=1,…,N. All the iterators must be able to go through only a
|
||||
portion of the set i=1,…,N. This enables us to implement paralelism, for two
|
||||
threads for example, one iterator goes from the beginning to the
|
||||
(approximately) half, and the other goes from the half to the end.
|
||||
|
||||
Besides this concept of the general quadrature, this file defines also one
|
||||
dimensional quadrature, which is basically a scheme of points and weights
|
||||
for different levels. The class OneDQuadrature is a parent of all such
|
||||
objects, the classes GaussHermite and GaussLegendre are specific
|
||||
implementations for Gauss-Hermite and Gauss-Legendre quadratures resp. */
|
||||
|
||||
#ifndef QUADRATURE_H
|
||||
#define QUADRATURE_H
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "vector_function.hh"
|
||||
#include "int_sequence.hh"
|
||||
#include "sthread.hh"
|
||||
|
||||
/* This pure virtual class represents a concept of one-dimensional (non-nested)
|
||||
quadrature. So, one dimensional quadrature must return number of levels,
|
||||
number of points in a given level, and then a point and a weight in a given
|
||||
level and given order. */
|
||||
|
||||
class OneDQuadrature
|
||||
{
|
||||
public:
|
||||
virtual ~OneDQuadrature() = default;
|
||||
virtual int numLevels() const = 0;
|
||||
virtual int numPoints(int level) const = 0;
|
||||
virtual double point(int level, int i) const = 0;
|
||||
virtual double weight(int lelel, int i) const = 0;
|
||||
};
|
||||
|
||||
/* This is a general concept of multidimensional quadrature. at this general
|
||||
level, we maintain only a dimension, and declare virtual functions for
|
||||
integration. The function take two forms; first takes a constant
|
||||
VectorFunction as an argument, creates locally VectorFunctionSet and do
|
||||
calculation, second one takes as an argument VectorFunctionSet.
|
||||
|
||||
Part of the interface is a method returning a number of evaluations for a
|
||||
specific level. Note two things: this assumes that the number of evaluations
|
||||
is known apriori and thus it is not applicable for adaptive quadratures,
|
||||
second for Monte Carlo type of quadrature, the level is a number of
|
||||
evaluations. */
|
||||
|
||||
class Quadrature
|
||||
{
|
||||
protected:
|
||||
int dim;
|
||||
public:
|
||||
Quadrature(int d) : dim(d)
|
||||
{
|
||||
}
|
||||
virtual ~Quadrature() = default;
|
||||
int
|
||||
dimen() const
|
||||
{
|
||||
return dim;
|
||||
}
|
||||
virtual void integrate(const VectorFunction &func, int level,
|
||||
int tn, Vector &out) const = 0;
|
||||
virtual void integrate(VectorFunctionSet &fs, int level, Vector &out) const = 0;
|
||||
virtual int numEvals(int level) const = 0;
|
||||
};
|
||||
|
||||
/* This is just an integration worker, which works over a given QuadratureImpl.
|
||||
It also needs the function, level, a specification of the subgroup of
|
||||
points, and output vector.
|
||||
|
||||
See QuadratureImpl class declaration for details. */
|
||||
|
||||
template<typename _Tpit>
|
||||
class QuadratureImpl;
|
||||
|
||||
template<typename _Tpit>
|
||||
class IntegrationWorker : public sthread::detach_thread
|
||||
{
|
||||
const QuadratureImpl<_Tpit> &quad;
|
||||
VectorFunction &func;
|
||||
int level;
|
||||
int ti;
|
||||
int tn;
|
||||
Vector &outvec;
|
||||
public:
|
||||
IntegrationWorker(const QuadratureImpl<_Tpit> &q, VectorFunction &f, int l,
|
||||
int tii, int tnn, Vector &out)
|
||||
: quad(q), func(f), level(l), ti(tii), tn(tnn), outvec(out)
|
||||
{
|
||||
}
|
||||
|
||||
/* This integrates the given portion of the integral. We obtain first and
|
||||
last iterators for the portion (‘beg’ and ‘end’). Then we iterate through
|
||||
the portion. and finally we add the intermediate result to the result
|
||||
‘outvec’.
|
||||
|
||||
This method just everything up as it is coming. This might be imply large
|
||||
numerical errors, perhaps in future something smarter should be implemented. */
|
||||
|
||||
void
|
||||
operator()(std::mutex &mut) override
|
||||
{
|
||||
_Tpit beg = quad.begin(ti, tn, level);
|
||||
_Tpit end = quad.begin(ti+1, tn, level);
|
||||
Vector tmpall(outvec.length());
|
||||
tmpall.zeros();
|
||||
Vector tmp(outvec.length());
|
||||
|
||||
/* Note that since ‘beg’ came from begin(), it has empty signal and first
|
||||
evaluation gets no signal */
|
||||
for (_Tpit run = beg; run != end; ++run)
|
||||
{
|
||||
func.eval(run.point(), run.signal(), tmp);
|
||||
tmpall.add(run.weight(), tmp);
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lk{mut};
|
||||
outvec.add(1.0, tmpall);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* This is the class which implements the integration. The class is templated
|
||||
by the iterator type. We declare a method begin() returning an iterator to
|
||||
the beginnning of the ‘ti’-th portion out of total ‘tn’ portions for a given
|
||||
level.
|
||||
|
||||
In addition, we define a method which saves all the points to a given file.
|
||||
Only for debugging purposes. */
|
||||
|
||||
template<typename _Tpit>
|
||||
class QuadratureImpl : public Quadrature
|
||||
{
|
||||
friend class IntegrationWorker<_Tpit>;
|
||||
public:
|
||||
QuadratureImpl(int d) : Quadrature(d)
|
||||
{
|
||||
}
|
||||
|
||||
/* Just fill a thread group with workes and run it. */
|
||||
void
|
||||
integrate(VectorFunctionSet &fs, int level, Vector &out) const override
|
||||
{
|
||||
// TODO: out.length()==func.outdim()
|
||||
// TODO: dim == func.indim()
|
||||
out.zeros();
|
||||
sthread::detach_thread_group gr;
|
||||
for (int ti = 0; ti < fs.getNum(); ti++)
|
||||
gr.insert(std::make_unique<IntegrationWorker<_Tpit>>(*this, fs.getFunc(ti),
|
||||
level, ti, fs.getNum(), out));
|
||||
gr.run();
|
||||
}
|
||||
void
|
||||
integrate(const VectorFunction &func,
|
||||
int level, int tn, Vector &out) const override
|
||||
{
|
||||
VectorFunctionSet fs(func, tn);
|
||||
integrate(fs, level, out);
|
||||
}
|
||||
|
||||
/* Just for debugging. */
|
||||
void
|
||||
savePoints(const std::string &fname, int level) const
|
||||
{
|
||||
std::ofstream fd{fname, std::ios::out | std::ios::trunc};
|
||||
if (fd.fail())
|
||||
{
|
||||
// TODO: raise
|
||||
std::cerr << "Cannot open file " << fname << " for writing." << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
_Tpit beg = begin(0, 1, level);
|
||||
_Tpit end = begin(1, 1, level);
|
||||
fd << std::setprecision(12);
|
||||
for (_Tpit run = beg; run != end; ++run)
|
||||
{
|
||||
fd << std::setw(16) << run.weight();
|
||||
for (int i = 0; i < dimen(); i++)
|
||||
fd << '\t' << std::setw(16) << run.point()[i];
|
||||
fd << std::endl;
|
||||
}
|
||||
fd.close();
|
||||
}
|
||||
|
||||
_Tpit
|
||||
start(int level) const
|
||||
{
|
||||
return begin(0, 1, level);
|
||||
}
|
||||
_Tpit
|
||||
end(int level) const
|
||||
{
|
||||
return begin(1, 1, level);
|
||||
}
|
||||
protected:
|
||||
virtual _Tpit begin(int ti, int tn, int level) const = 0;
|
||||
};
|
||||
|
||||
/* This is only an interface to a precalculated data in file
|
||||
precalc_quadrature.hh which is basically C coded static data. It implements
|
||||
OneDQuadrature. The data file is supposed to define the following data:
|
||||
number of levels, array of number of points at each level, an array of
|
||||
weights and array of points. The both latter array store data level by
|
||||
level. An offset for a specific level is stored in ‘offsets’ integer
|
||||
sequence.
|
||||
|
||||
The implementing subclasses just fill the necessary data from the file, the
|
||||
rest is calculated here. */
|
||||
|
||||
class OneDPrecalcQuadrature : public OneDQuadrature
|
||||
{
|
||||
int num_levels;
|
||||
const int *num_points;
|
||||
const double *weights;
|
||||
const double *points;
|
||||
IntSequence offsets;
|
||||
public:
|
||||
OneDPrecalcQuadrature(int nlevels, const int *npoints,
|
||||
const double *wts, const double *pts)
|
||||
: num_levels(nlevels), num_points(npoints),
|
||||
weights(wts), points(pts), offsets(num_levels)
|
||||
{
|
||||
calcOffsets();
|
||||
}
|
||||
~OneDPrecalcQuadrature() override = default;
|
||||
int
|
||||
numLevels() const override
|
||||
{
|
||||
return num_levels;
|
||||
}
|
||||
int
|
||||
numPoints(int level) const override
|
||||
{
|
||||
return num_points[level-1];
|
||||
}
|
||||
double
|
||||
point(int level, int i) const override
|
||||
{
|
||||
return points[offsets[level-1]+i];
|
||||
}
|
||||
double
|
||||
weight(int level, int i) const override
|
||||
{
|
||||
return weights[offsets[level-1]+i];
|
||||
}
|
||||
protected:
|
||||
void calcOffsets();
|
||||
};
|
||||
|
||||
/* Just precalculated Gauss-Hermite quadrature. This quadrature integrates
|
||||
exactly integrals
|
||||
|
||||
+∞
|
||||
∫ xᵏe^{−x²}dx
|
||||
−∞
|
||||
|
||||
for level k.
|
||||
|
||||
Note that if pluging this one-dimensional quadrature to product or Smolyak
|
||||
rule in order to integrate a function f through normally distributed inputs,
|
||||
one has to wrap f to GaussConverterFunction and apply the product or Smolyak
|
||||
rule to the new function.
|
||||
|
||||
Check precalc_quadrature.hh for available levels. */
|
||||
|
||||
class GaussHermite : public OneDPrecalcQuadrature
|
||||
{
|
||||
public:
|
||||
GaussHermite();
|
||||
};
|
||||
|
||||
/* Just precalculated Gauss-Legendre quadrature. This quadrature integrates
|
||||
exactly integrals
|
||||
|
||||
₁
|
||||
∫ xᵏdx
|
||||
⁰
|
||||
|
||||
for level k.
|
||||
|
||||
Check precalc_quadrature.hh for available levels. */
|
||||
|
||||
class GaussLegendre : public OneDPrecalcQuadrature
|
||||
{
|
||||
public:
|
||||
GaussLegendre();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,214 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "quasi_mcarlo.hh"
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <array>
|
||||
|
||||
/* Here in the constructor, we have to calculate a maximum length of ‘coeff’
|
||||
array for a given ‘base’ and given maximum ‘maxn’. After allocation, we
|
||||
calculate the coefficients. */
|
||||
|
||||
RadicalInverse::RadicalInverse(int n, int b, int mxn)
|
||||
: num(n), base(b), maxn(mxn),
|
||||
coeff(static_cast<int>(floor(log(static_cast<double>(maxn))/log(static_cast<double>(b)))+2), 0)
|
||||
{
|
||||
int nr = num;
|
||||
j = -1;
|
||||
do
|
||||
{
|
||||
j++;
|
||||
coeff[j] = nr % base;
|
||||
nr = nr / base;
|
||||
}
|
||||
while (nr > 0);
|
||||
}
|
||||
|
||||
/* This evaluates the radical inverse. If there was no permutation, we have to
|
||||
calculate:
|
||||
|
||||
c₀ c₁ cⱼ
|
||||
── + ── + … + ────
|
||||
b b² bʲ⁺¹
|
||||
|
||||
which is evaluated as:
|
||||
|
||||
⎛ ⎛⎛cⱼ 1 cⱼ₋₁⎞ 1 cⱼ₋₂⎞ ⎞ 1 c₀
|
||||
⎢…⎢⎢──·─ + ────⎥·─ + ────⎥…⎥·─ + ──
|
||||
⎝ ⎝⎝ b b b ⎠ b b ⎠ ⎠ b b
|
||||
|
||||
|
||||
Now with permutation π, we have:
|
||||
|
||||
⎛ ⎛⎛π(cⱼ) 1 π(cⱼ₋₁)⎞ 1 π(cⱼ₋₂)⎞ ⎞ 1 π(c₀)
|
||||
⎢…⎢⎢─────·─ + ───────⎥·─ + ───────⎥…⎥·─ + ─────
|
||||
⎝ ⎝⎝ b b b ⎠ b b ⎠ ⎠ b b
|
||||
*/
|
||||
|
||||
double
|
||||
RadicalInverse::eval(const PermutationScheme &p) const
|
||||
{
|
||||
double res = 0;
|
||||
for (int i = j; i >= 0; i--)
|
||||
{
|
||||
int cper = p.permute(i, base, coeff[i]);
|
||||
res = (cper + res)/base;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/* We just add 1 to the lowest coefficient and check for overflow with respect
|
||||
to the base. */
|
||||
void
|
||||
RadicalInverse::increase()
|
||||
{
|
||||
// TODO: raise if num+1 > maxn
|
||||
num++;
|
||||
int i = 0;
|
||||
coeff[i]++;
|
||||
while (coeff[i] == base)
|
||||
{
|
||||
coeff[i] = 0;
|
||||
coeff[++i]++;
|
||||
}
|
||||
if (i > j)
|
||||
j = i;
|
||||
}
|
||||
|
||||
/* Debug print. */
|
||||
void
|
||||
RadicalInverse::print() const
|
||||
{
|
||||
std::cout << "n=" << num << " b=" << base << " c=";
|
||||
coeff.print();
|
||||
}
|
||||
|
||||
/* Here we have the first 170 primes. This means that we are not able to
|
||||
integrate dimensions greater than 170. */
|
||||
|
||||
std::array<int, 170> HaltonSequence::primes =
|
||||
{
|
||||
2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
|
||||
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
|
||||
73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
|
||||
127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
|
||||
179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
|
||||
233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
|
||||
283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
|
||||
353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
|
||||
419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
|
||||
467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
|
||||
547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
|
||||
607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
|
||||
661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
|
||||
739, 743, 751, 757, 761, 769, 773, 787, 797, 809,
|
||||
811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
|
||||
877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
|
||||
947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013
|
||||
};
|
||||
|
||||
/* This takes first ‘dim’ primes and constructs ‘dim’ radical inverses and
|
||||
calls eval(). */
|
||||
|
||||
HaltonSequence::HaltonSequence(int n, int mxn, int dim, const PermutationScheme &p)
|
||||
: num(n), maxn(mxn), per(p), pt(dim)
|
||||
{
|
||||
// TODO: raise if dim > num_primes
|
||||
// TODO: raise if n > mxn
|
||||
for (int i = 0; i < dim; i++)
|
||||
ri.emplace_back(num, primes[i], maxn);
|
||||
eval();
|
||||
}
|
||||
|
||||
/* This calls RadicalInverse::increase() for all radical inverses and calls
|
||||
eval(). */
|
||||
|
||||
void
|
||||
HaltonSequence::increase()
|
||||
{
|
||||
for (auto &i : ri)
|
||||
i.increase();
|
||||
num++;
|
||||
if (num <= maxn)
|
||||
eval();
|
||||
}
|
||||
|
||||
/* This sets point ‘pt’ to radical inverse evaluations in each dimension. */
|
||||
void
|
||||
HaltonSequence::eval()
|
||||
{
|
||||
for (unsigned int i = 0; i < ri.size(); i++)
|
||||
pt[i] = ri[i].eval(per);
|
||||
}
|
||||
|
||||
/* Debug print. */
|
||||
void
|
||||
HaltonSequence::print() const
|
||||
{
|
||||
auto ff = std::cout.flags();
|
||||
for (const auto &i : ri)
|
||||
i.print();
|
||||
std::cout << "point=[ "
|
||||
<< std::fixed << std::setprecision(6);
|
||||
for (unsigned int i = 0; i < ri.size(); i++)
|
||||
std::cout << std::setw(7) << pt[i] << ' ';
|
||||
std::cout << ']' << std::endl;
|
||||
std::cout.flags(ff);
|
||||
}
|
||||
|
||||
qmcpit::qmcpit(const QMCSpecification &s, int n)
|
||||
: spec(s), halton{n, s.level(), s.dimen(), s.getPerScheme()},
|
||||
sig{s.dimen()}
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
qmcpit::operator==(const qmcpit &qpit) const
|
||||
{
|
||||
return &spec == &qpit.spec && halton.getNum() == qpit.halton.getNum();
|
||||
}
|
||||
|
||||
qmcpit &
|
||||
qmcpit::operator++()
|
||||
{
|
||||
halton.increase();
|
||||
return *this;
|
||||
}
|
||||
|
||||
double
|
||||
qmcpit::weight() const
|
||||
{
|
||||
return 1.0/spec.level();
|
||||
}
|
||||
|
||||
int
|
||||
WarnockPerScheme::permute(int i, int base, int c) const
|
||||
{
|
||||
return (c+i) % base;
|
||||
}
|
||||
|
||||
int
|
||||
ReversePerScheme::permute(int i, int base, int c) const
|
||||
{
|
||||
return (base-c) % base;
|
||||
}
|
|
@ -1,256 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019-2022 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Quasi Monte Carlo quadrature.
|
||||
|
||||
/* This defines quasi Monte Carlo quadratures for cube and for a function
|
||||
multiplied by normal density. The quadrature for a cube is named
|
||||
QMCarloCubeQuadrature and integrates:
|
||||
|
||||
∫ f(x)dx
|
||||
[0,1]ⁿ
|
||||
|
||||
The quadrature for a function of normally distributed parameters is named
|
||||
QMCarloNormalQuadrature and integrates:
|
||||
|
||||
1
|
||||
──────── ∫ f(x)e^{−½xᵀx}dx
|
||||
√{(2π)ⁿ} [−∞,+∞]ⁿ
|
||||
|
||||
For a cube we define qmcpit as iterator of QMCarloCubeQuadrature, and for
|
||||
the normal density multiplied function we define qmcnpit as iterator of
|
||||
QMCarloNormalQuadrature.
|
||||
|
||||
The quasi Monte Carlo method generates low discrepancy points with equal
|
||||
weights. The one dimensional low discrepancy sequences are generated by
|
||||
RadicalInverse class, the sequences are combined for higher dimensions by
|
||||
HaltonSequence class. The Halton sequence can use a permutation scheme;
|
||||
PermutattionScheme is an abstract class for all permutaton schemes. We have
|
||||
three implementations: WarnockPerScheme, ReversePerScheme, and
|
||||
IdentityPerScheme. */
|
||||
|
||||
#ifndef QUASI_MCARLO_H
|
||||
#define QUASI_MCARLO_H
|
||||
|
||||
#include "int_sequence.hh"
|
||||
#include "quadrature.hh"
|
||||
|
||||
#include "Vector.hh"
|
||||
|
||||
#include <vector>
|
||||
|
||||
/* This abstract class declares permute() method which permutes coefficient ‘c’
|
||||
having index of ‘i’ fro the base ‘base’ and returns the permuted coefficient
|
||||
which must be in 0,…,base−1. */
|
||||
|
||||
class PermutationScheme
|
||||
{
|
||||
public:
|
||||
PermutationScheme() = default;
|
||||
virtual ~PermutationScheme() = default;
|
||||
virtual int permute(int i, int base, int c) const = 0;
|
||||
};
|
||||
|
||||
/* This class represents an integer number ‘num’ as c₀+c₁b+c₂b²+…+cⱼbʲ, where b
|
||||
is ‘base’ and c₀,…,cⱼ is stored in ‘coeff’. The size of IntSequence coeff
|
||||
does not grow with growing ‘num’, but is fixed from the very beginning and
|
||||
is set according to supplied maximum ‘maxn’.
|
||||
|
||||
The basic method is eval() which evaluates the RadicalInverse with a given
|
||||
permutation scheme and returns the point, and increase() which increases
|
||||
‘num’ and recalculates the coefficients. */
|
||||
|
||||
class RadicalInverse
|
||||
{
|
||||
int num;
|
||||
int base;
|
||||
int maxn;
|
||||
int j;
|
||||
IntSequence coeff;
|
||||
public:
|
||||
RadicalInverse(int n, int b, int mxn);
|
||||
RadicalInverse(const RadicalInverse &ri) = default;
|
||||
RadicalInverse &operator=(const RadicalInverse &radi) = default;
|
||||
double eval(const PermutationScheme &p) const;
|
||||
void increase();
|
||||
void print() const;
|
||||
};
|
||||
|
||||
/* This is a vector of RadicalInverses, each RadicalInverse has a different
|
||||
prime as its base. The static members ‘primes’ and ‘num_primes’ define a
|
||||
precalculated array of primes. The increase() method of the class increases
|
||||
indices in all RadicalInverse’s and sets point ‘pt’ to contain the points in
|
||||
each dimension. */
|
||||
|
||||
class HaltonSequence
|
||||
{
|
||||
private:
|
||||
static std::array<int, 170> primes;
|
||||
protected:
|
||||
int num;
|
||||
int maxn;
|
||||
std::vector<RadicalInverse> ri;
|
||||
const PermutationScheme &per;
|
||||
Vector pt;
|
||||
public:
|
||||
HaltonSequence(int n, int mxn, int dim, const PermutationScheme &p);
|
||||
HaltonSequence(const HaltonSequence &hs) = default;
|
||||
HaltonSequence &operator=(const HaltonSequence &hs) = delete;
|
||||
void increase();
|
||||
const Vector &
|
||||
point() const
|
||||
{
|
||||
return pt;
|
||||
}
|
||||
int
|
||||
getNum() const
|
||||
{
|
||||
return num;
|
||||
}
|
||||
void print() const;
|
||||
protected:
|
||||
void eval();
|
||||
};
|
||||
|
||||
/* This is a specification of quasi Monte Carlo quadrature. It consists of
|
||||
dimension ‘dim’, number of points (or level) ‘lev’, and the permutation
|
||||
scheme. This class is common to all quasi Monte Carlo classes. */
|
||||
|
||||
class QMCSpecification
|
||||
{
|
||||
protected:
|
||||
int dim;
|
||||
int lev;
|
||||
const PermutationScheme &per_scheme;
|
||||
public:
|
||||
QMCSpecification(int d, int l, const PermutationScheme &p)
|
||||
: dim(d), lev(l), per_scheme(p)
|
||||
{
|
||||
}
|
||||
virtual ~QMCSpecification() = default;
|
||||
int
|
||||
dimen() const
|
||||
{
|
||||
return dim;
|
||||
}
|
||||
int
|
||||
level() const
|
||||
{
|
||||
return lev;
|
||||
}
|
||||
const PermutationScheme &
|
||||
getPerScheme() const
|
||||
{
|
||||
return per_scheme;
|
||||
}
|
||||
};
|
||||
|
||||
/* This is an iterator for quasi Monte Carlo over a cube QMCarloCubeQuadrature.
|
||||
The iterator maintains HaltonSequence of the same dimension as given by the
|
||||
specification. An iterator can be constructed from a given number ‘n’, or by
|
||||
a copy constructor. */
|
||||
|
||||
class qmcpit
|
||||
{
|
||||
protected:
|
||||
const QMCSpecification &spec;
|
||||
HaltonSequence halton;
|
||||
ParameterSignal sig;
|
||||
public:
|
||||
qmcpit(const QMCSpecification &s, int n);
|
||||
qmcpit(const qmcpit &qpit) = default;
|
||||
virtual ~qmcpit() = default;
|
||||
bool operator==(const qmcpit &qpit) const;
|
||||
bool
|
||||
operator!=(const qmcpit &qpit) const
|
||||
{
|
||||
return !operator==(qpit);
|
||||
}
|
||||
qmcpit &operator=(const qmcpit &qpit) = delete;
|
||||
qmcpit &operator++();
|
||||
const ParameterSignal &
|
||||
signal() const
|
||||
{
|
||||
return sig;
|
||||
}
|
||||
const Vector &
|
||||
point() const
|
||||
{
|
||||
return halton.point();
|
||||
}
|
||||
double weight() const;
|
||||
void
|
||||
print() const
|
||||
{
|
||||
halton.print();
|
||||
}
|
||||
};
|
||||
|
||||
/* This is an easy declaration of quasi Monte Carlo quadrature for a cube.
|
||||
Everything important has been done in its iterator qmcpit, so we only
|
||||
inherit from general Quadrature and reimplement begin() and numEvals(). */
|
||||
|
||||
class QMCarloCubeQuadrature : public QuadratureImpl<qmcpit>, public QMCSpecification
|
||||
{
|
||||
public:
|
||||
QMCarloCubeQuadrature(int d, int l, const PermutationScheme &p)
|
||||
: QuadratureImpl<qmcpit>(d), QMCSpecification(d, l, p)
|
||||
{
|
||||
}
|
||||
~QMCarloCubeQuadrature() override = default;
|
||||
int
|
||||
numEvals(int l) const override
|
||||
{
|
||||
return l;
|
||||
}
|
||||
protected:
|
||||
qmcpit
|
||||
begin(int ti, int tn, int lev) const override
|
||||
{
|
||||
return qmcpit(*this, ti*level()/tn + 1);
|
||||
}
|
||||
};
|
||||
|
||||
/* Declares Warnock permutation scheme. */
|
||||
class WarnockPerScheme : public PermutationScheme
|
||||
{
|
||||
public:
|
||||
int permute(int i, int base, int c) const override;
|
||||
};
|
||||
|
||||
/* Declares reverse permutation scheme. */
|
||||
class ReversePerScheme : public PermutationScheme
|
||||
{
|
||||
public:
|
||||
int permute(int i, int base, int c) const override;
|
||||
};
|
||||
|
||||
/* Declares no permutation (identity) scheme. */
|
||||
class IdentityPerScheme : public PermutationScheme
|
||||
{
|
||||
public:
|
||||
int
|
||||
permute(int i, int base, int c) const override
|
||||
{
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,220 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "smolyak.hh"
|
||||
#include "symmetry.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
/* This constructs a beginning of ‘isum’ summand in ‘smolq’. We must be careful
|
||||
here, since ‘isum’ can be past-the-end, so no reference to vectors in
|
||||
‘smolq’ by ‘isum’ must be done in this case. */
|
||||
|
||||
smolpit::smolpit(const SmolyakQuadrature &q, unsigned int isum)
|
||||
: smolq(q), isummand(isum),
|
||||
jseq(q.dimen(), 0),
|
||||
sig{q.dimen()},
|
||||
p{q.dimen()}
|
||||
{
|
||||
if (isummand < q.numSummands())
|
||||
setPointAndWeight();
|
||||
}
|
||||
|
||||
bool
|
||||
smolpit::operator==(const smolpit &spit) const
|
||||
{
|
||||
return &smolq == &spit.smolq && isummand == spit.isummand && jseq == spit.jseq;
|
||||
}
|
||||
|
||||
/* We first try to increase index within the current summand. If we are at
|
||||
maximum, we go to a subsequent summand. Note that in this case all indices
|
||||
in ‘jseq’ will be zero, so no change is needed. */
|
||||
|
||||
smolpit &
|
||||
smolpit::operator++()
|
||||
{
|
||||
const IntSequence &levpts = smolq.levpoints[isummand];
|
||||
int i = smolq.dimen()-1;
|
||||
jseq[i]++;
|
||||
while (i >= 0 && jseq[i] == levpts[i])
|
||||
{
|
||||
jseq[i] = 0;
|
||||
i--;
|
||||
if (i >= 0)
|
||||
jseq[i]++;
|
||||
}
|
||||
sig.signalAfter(std::max(i, 0));
|
||||
|
||||
if (i < 0)
|
||||
isummand++;
|
||||
|
||||
if (isummand < smolq.numSummands())
|
||||
setPointAndWeight();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* Here we set the point coordinates according to ‘jseq’ and
|
||||
‘isummand’. Also the weight is set here. */
|
||||
|
||||
void
|
||||
smolpit::setPointAndWeight()
|
||||
{
|
||||
// todo: raise if isummand ≥ smolq.numSummands()
|
||||
int l = smolq.level;
|
||||
int d = smolq.dimen();
|
||||
int sumk = (smolq.levels[isummand]).sum();
|
||||
int m1exp = l + d - sumk - 1;
|
||||
w = (2*(m1exp/2) == m1exp) ? 1.0 : -1.0;
|
||||
w *= PascalTriangle::noverk(d-1, sumk-l);
|
||||
for (int i = 0; i < d; i++)
|
||||
{
|
||||
int ki = (smolq.levels[isummand])[i];
|
||||
p[i] = (smolq.uquad).point(ki, jseq[i]);
|
||||
w *= (smolq.uquad).weight(ki, jseq[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Debug print. */
|
||||
void
|
||||
smolpit::print() const
|
||||
{
|
||||
auto ff = std::cout.flags();
|
||||
std::cout << "isum=" << std::left << std::setw(3) << isummand << std::right << ": [";
|
||||
for (int i = 0; i < smolq.dimen(); i++)
|
||||
std::cout << std::setw(2) << (smolq.levels[isummand])[i] << ' ';
|
||||
std::cout << "] j=[";
|
||||
for (int i = 0; i < smolq.dimen(); i++)
|
||||
std::cout << std::setw(2) << jseq[i] << ' ';
|
||||
std::cout << std::showpos << std::fixed << std::setprecision(3)
|
||||
<< "] " << std::setw(4) << w << "*(";
|
||||
for (int i = 0; i < smolq.dimen()-1; i++)
|
||||
std::cout << std::setw(4) << p[i] << ' ';
|
||||
std::cout << std::setw(4) << p[smolq.dimen()-1] << ')' << std::endl;
|
||||
std::cout.flags(ff);
|
||||
}
|
||||
|
||||
/* Here is the constructor of SmolyakQuadrature. We have to setup ‘levels’,
|
||||
‘levpoints’ and ‘cumevals’. We have to go through all d-dimensional
|
||||
sequences k, such that l≤|k|≤l+d−1 and all kᵢ are positive integers. This is
|
||||
equivalent to going through all k such that l−d≤|k|≤l−1 and all kᵢ are
|
||||
non-negative integers. This is equivalent to going through d+1 dimensional
|
||||
sequences (k,x) such that |(k,x)|=l−1 and x=0,…,d−1. The resulting sequence
|
||||
of positive integers is obtained by adding 1 to all kᵢ. */
|
||||
|
||||
SmolyakQuadrature::SmolyakQuadrature(int d, int l, const OneDQuadrature &uq)
|
||||
: QuadratureImpl<smolpit>(d), level(l), uquad(uq)
|
||||
{
|
||||
// TODO: check l>1, l≥d
|
||||
// TODO: check l≥uquad.miLevel(), l≤uquad.maxLevel()
|
||||
int cum = 0;
|
||||
for (const auto &si : SymmetrySet(l-1, d+1))
|
||||
{
|
||||
if (si[d] <= d-1)
|
||||
{
|
||||
IntSequence lev(si, 0, d);
|
||||
lev.add(1);
|
||||
levels.push_back(lev);
|
||||
IntSequence levpts(d);
|
||||
for (int i = 0; i < d; i++)
|
||||
levpts[i] = uquad.numPoints(lev[i]);
|
||||
levpoints.push_back(levpts);
|
||||
cum += levpts.mult();
|
||||
cumevals.push_back(cum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Here we return a number of evalutions of the quadrature for the given level.
|
||||
If the given level is the current one, we simply return the maximum
|
||||
cumulative number of evaluations. Otherwise we call costly
|
||||
calcNumEvaluations() method. */
|
||||
|
||||
int
|
||||
SmolyakQuadrature::numEvals(int l) const
|
||||
{
|
||||
if (l != level)
|
||||
return calcNumEvaluations(l);
|
||||
else
|
||||
return cumevals[numSummands()-1];
|
||||
}
|
||||
|
||||
/* This divides all the evaluations to ‘tn’ approximately equal groups, and
|
||||
returns the beginning of the specified group ‘ti’. The granularity of
|
||||
divisions are summands as listed by ‘levels’. */
|
||||
|
||||
smolpit
|
||||
SmolyakQuadrature::begin(int ti, int tn, int l) const
|
||||
{
|
||||
// TODO: raise is level≠l
|
||||
if (ti == tn)
|
||||
return smolpit(*this, numSummands());
|
||||
|
||||
int totevals = cumevals[numSummands()-1];
|
||||
int evals = (totevals*ti)/tn;
|
||||
unsigned int isum = 0;
|
||||
while (isum+1 < numSummands() && cumevals[isum+1] < evals)
|
||||
isum++;
|
||||
return smolpit(*this, isum);
|
||||
}
|
||||
|
||||
/* This is the same in a structure as SmolyakQuadrature constructor. We have to
|
||||
go through all summands and calculate a number of evaluations in each
|
||||
summand. */
|
||||
|
||||
int
|
||||
SmolyakQuadrature::calcNumEvaluations(int lev) const
|
||||
{
|
||||
int cum = 0;
|
||||
for (const auto &si : SymmetrySet(lev-1, dim+1))
|
||||
{
|
||||
if (si[dim] <= dim-1)
|
||||
{
|
||||
IntSequence lev(si, 0, dim);
|
||||
lev.add(1);
|
||||
IntSequence levpts(dim);
|
||||
for (int i = 0; i < dim; i++)
|
||||
levpts[i] = uquad.numPoints(lev[i]);
|
||||
cum += levpts.mult();
|
||||
}
|
||||
}
|
||||
return cum;
|
||||
}
|
||||
|
||||
/* This returns a maximum level such that the number of evaluations is less
|
||||
than the given number. */
|
||||
|
||||
void
|
||||
SmolyakQuadrature::designLevelForEvals(int max_evals, int &lev, int &evals) const
|
||||
{
|
||||
int last_evals;
|
||||
evals = 1;
|
||||
lev = 1;
|
||||
do
|
||||
{
|
||||
lev++;
|
||||
last_evals = evals;
|
||||
evals = calcNumEvaluations(lev);
|
||||
}
|
||||
while (lev < uquad.numLevels() && evals <= max_evals);
|
||||
lev--;
|
||||
evals = last_evals;
|
||||
}
|
|
@ -1,149 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Smolyak quadrature.
|
||||
|
||||
/* This file defines Smolyak (sparse grid) multidimensional quadrature for
|
||||
non-nested underlying one dimensional quadrature. Let Q¹ₗ denote the one
|
||||
dimensional quadrature of l level. Let nₗ denote a number of points in the l
|
||||
level. Than the Smolyak quadrature can be defined as
|
||||
|
||||
⎛ d−1 ⎞
|
||||
Qᵈf = ∑ (−1)^{l+d−|k|−1} ⎢ ⎥ (Q¹_k₁⊗…⊗Q¹_{k_d})f
|
||||
l≤|k|≤l+d−1 ⎝|k|−l⎠
|
||||
|
||||
where d is the dimension, k is d-dimensional sequence of integers, and |k|
|
||||
denotes the sum of the sequence.
|
||||
|
||||
Here we define smolpit as Smolyak iterator and SmolyakQuadrature. */
|
||||
|
||||
#ifndef SMOLYAK_H
|
||||
#define SMOLYAK_H
|
||||
|
||||
#include "int_sequence.hh"
|
||||
#include "tl_static.hh"
|
||||
#include "vector_function.hh"
|
||||
#include "quadrature.hh"
|
||||
#include "pascal_triangle.hh"
|
||||
|
||||
/* Here we define the Smolyak point iterator. The Smolyak formula can be broken
|
||||
to a sum of product quadratures with various combinations of levels. The
|
||||
iterator follows this pattern. It maintains an index to a summand and then a
|
||||
point coordinates within the summand (product quadrature). The array of
|
||||
summands to which the ‘isummand’ points is maintained by the
|
||||
SmolyakQuadrature class to which the object knows the pointer ‘smolq’.
|
||||
|
||||
We provide a constructor which points to the beginning of the given summand.
|
||||
This constructor is used in SmolyakQuadrature::begin() method which
|
||||
approximately divideds all the iterators to subsets of equal size. */
|
||||
|
||||
class SmolyakQuadrature;
|
||||
|
||||
class smolpit
|
||||
{
|
||||
protected:
|
||||
const SmolyakQuadrature &smolq;
|
||||
unsigned int isummand{0};
|
||||
IntSequence jseq;
|
||||
ParameterSignal sig;
|
||||
Vector p;
|
||||
double w;
|
||||
public:
|
||||
smolpit(const SmolyakQuadrature &q, unsigned int isum);
|
||||
smolpit(const smolpit &spit) = default;
|
||||
~smolpit() = default;
|
||||
bool operator==(const smolpit &spit) const;
|
||||
bool
|
||||
operator!=(const smolpit &spit) const
|
||||
{
|
||||
return !operator==(spit);
|
||||
}
|
||||
smolpit &operator=(const smolpit &spit) = delete;
|
||||
smolpit &operator++();
|
||||
const ParameterSignal &
|
||||
signal() const
|
||||
{
|
||||
return sig;
|
||||
}
|
||||
const Vector &
|
||||
point() const
|
||||
{
|
||||
return p;
|
||||
}
|
||||
double
|
||||
weight() const
|
||||
{
|
||||
return w;
|
||||
}
|
||||
void print() const;
|
||||
protected:
|
||||
void setPointAndWeight();
|
||||
};
|
||||
|
||||
/* Here we define the class SmolyakQuadrature. It maintains an array of
|
||||
summands of the Smolyak quadrature formula:
|
||||
|
||||
⎛ d−1 ⎞
|
||||
∑ (−1)^{l+d−|k|−1} ⎢ ⎥ (Q¹_k₁⊗…⊗Q¹_{k_d})f
|
||||
l≤|k|≤l+d−1 ⎝|k|−l⎠
|
||||
|
||||
Each summand is fully specified by sequence k. The summands are here
|
||||
represented (besides k) also by sequence of number of points in each level
|
||||
selected by k, and also by a cummulative number of evaluations. The latter
|
||||
two are added only for conveniency.
|
||||
|
||||
The summands in the code are given by ‘levels’, which is a vector of
|
||||
k sequences, further by ‘levpoints’ which is a vector of sequences
|
||||
of nuber of points in each level, and by ‘cumevals’ which is the
|
||||
cumulative number of points, this is:
|
||||
|
||||
d
|
||||
∑ ∏ n_kᵢ
|
||||
ᵏ ⁱ⁼¹
|
||||
|
||||
where the sum is done through all k before the current.
|
||||
|
||||
The ‘levels’ and ‘levpoints’ vectors are used by smolpit. */
|
||||
|
||||
class SmolyakQuadrature : public QuadratureImpl<smolpit>
|
||||
{
|
||||
friend class smolpit;
|
||||
int level;
|
||||
const OneDQuadrature &uquad;
|
||||
std::vector<IntSequence> levels;
|
||||
std::vector<IntSequence> levpoints;
|
||||
std::vector<int> cumevals;
|
||||
public:
|
||||
SmolyakQuadrature(int d, int l, const OneDQuadrature &uq);
|
||||
~SmolyakQuadrature() override = default;
|
||||
int numEvals(int level) const override;
|
||||
void designLevelForEvals(int max_eval, int &lev, int &evals) const;
|
||||
protected:
|
||||
smolpit begin(int ti, int tn, int level) const override;
|
||||
unsigned int
|
||||
numSummands() const
|
||||
{
|
||||
return levels.size();
|
||||
}
|
||||
private:
|
||||
int calcNumEvaluations(int level) const;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,147 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vector_function.hh"
|
||||
|
||||
#include <dynlapack.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
/* Just an easy constructor of sequence of booleans defaulting to change
|
||||
everywhere. */
|
||||
|
||||
ParameterSignal::ParameterSignal(int n)
|
||||
: data(n, true)
|
||||
{
|
||||
}
|
||||
|
||||
/* This sets ‘false’ (no change) before a given parameter, and ‘true’ (change)
|
||||
after the given parameter (including). */
|
||||
|
||||
void
|
||||
ParameterSignal::signalAfter(int l)
|
||||
{
|
||||
for (size_t i = 0; i < std::min(static_cast<size_t>(l), data.size()); i++)
|
||||
data[i] = false;
|
||||
for (size_t i = l; i < data.size(); i++)
|
||||
data[i] = true;
|
||||
}
|
||||
|
||||
/* This constructs a function set hardcopying also the first. */
|
||||
VectorFunctionSet::VectorFunctionSet(const VectorFunction &f, int n)
|
||||
: funcs(n)
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
func_copies.push_back(f.clone());
|
||||
funcs[i] = func_copies.back().get();
|
||||
}
|
||||
}
|
||||
|
||||
/* This constructs a function set with shallow copy in the first and hard
|
||||
copies in others. */
|
||||
VectorFunctionSet::VectorFunctionSet(VectorFunction &f, int n)
|
||||
: funcs(n)
|
||||
{
|
||||
if (n > 0)
|
||||
funcs[0] = &f;
|
||||
for (int i = 1; i < n; i++)
|
||||
{
|
||||
func_copies.push_back(f.clone());
|
||||
funcs[i] = func_copies.back().get();
|
||||
}
|
||||
}
|
||||
|
||||
/* Here we construct the object from the given function f and given
|
||||
variance-covariance matrix Σ=vcov. The matrix A is calculated as lower
|
||||
triangular and yields Σ=AAᵀ. */
|
||||
|
||||
GaussConverterFunction::GaussConverterFunction(VectorFunction &f, const GeneralMatrix &vcov)
|
||||
: VectorFunction(f), func(&f), A(vcov.nrows(), vcov.nrows()),
|
||||
multiplier(calcMultiplier())
|
||||
{
|
||||
// TODO: raise if A.nrows() ≠ indim()
|
||||
calcCholeskyFactor(vcov);
|
||||
}
|
||||
|
||||
GaussConverterFunction::GaussConverterFunction(std::unique_ptr<VectorFunction> f, const GeneralMatrix &vcov)
|
||||
: VectorFunction(*f), func_storage{move(f)}, func{func_storage.get()}, A(vcov.nrows(), vcov.nrows()),
|
||||
multiplier(calcMultiplier())
|
||||
{
|
||||
// TODO: raise if A.nrows() ≠ indim()
|
||||
calcCholeskyFactor(vcov);
|
||||
}
|
||||
|
||||
GaussConverterFunction::GaussConverterFunction(const GaussConverterFunction &f)
|
||||
: VectorFunction(f), func_storage{f.func->clone()}, func{func_storage.get()}, A(f.A),
|
||||
multiplier(f.multiplier)
|
||||
{
|
||||
}
|
||||
|
||||
/* Here we evaluate the function
|
||||
|
||||
g(y) = 1/√(πⁿ) f(√2·Ay).
|
||||
|
||||
Since the matrix A is lower triangular, the change signal for the function f
|
||||
will look like (0,…,0,1,…,1) where the first 1 is in the same position as
|
||||
the first change in the given signal ‘sig’ of the input y=point. */
|
||||
|
||||
void
|
||||
GaussConverterFunction::eval(const Vector &point, const ParameterSignal &sig, Vector &out)
|
||||
{
|
||||
ParameterSignal s(sig);
|
||||
int i = 0;
|
||||
while (i < indim() && !sig[i])
|
||||
i++;
|
||||
s.signalAfter(i);
|
||||
|
||||
Vector x(indim());
|
||||
x.zeros();
|
||||
A.multaVec(x, point);
|
||||
x.mult(sqrt(2.0));
|
||||
|
||||
func->eval(x, s, out);
|
||||
|
||||
out.mult(multiplier);
|
||||
}
|
||||
|
||||
/* This returns 1/√(πⁿ). */
|
||||
|
||||
double
|
||||
GaussConverterFunction::calcMultiplier() const
|
||||
{
|
||||
return sqrt(pow(M_PI, -1*indim()));
|
||||
}
|
||||
|
||||
void
|
||||
GaussConverterFunction::calcCholeskyFactor(const GeneralMatrix &vcov)
|
||||
{
|
||||
A = vcov;
|
||||
|
||||
lapack_int rows = A.nrows(), lda = A.getLD();
|
||||
for (int i = 0; i < rows; i++)
|
||||
for (int j = i+1; j < rows; j++)
|
||||
A.get(i, j) = 0.0;
|
||||
|
||||
lapack_int info;
|
||||
dpotrf("L", &rows, A.base(), &lda, &info);
|
||||
// TODO: raise if info≠1
|
||||
}
|
|
@ -1,186 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Vector function.
|
||||
|
||||
/* This file defines interface for functions taking a vector as an input and
|
||||
returning a vector (with a different size) as an output. We are also
|
||||
introducing a parameter signalling; it is a boolean vector which tracks
|
||||
parameters which were changed from the previous call. The VectorFunction
|
||||
implementation can exploit this information and evaluate the function more
|
||||
efficiently. The information can be completely ignored.
|
||||
|
||||
From the signalling reason, and from other reasons, the function evaluation
|
||||
is not const. */
|
||||
|
||||
#ifndef VECTOR_FUNCTION_H
|
||||
#define VECTOR_FUNCTION_H
|
||||
|
||||
#include "Vector.hh"
|
||||
#include "GeneralMatrix.hh"
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
/* This is a simple class representing a vector of booleans. The items night be
|
||||
retrieved or changed, or can be set ‘true’ after some point. This is useful
|
||||
when we multiply the vector with lower triangular matrix.
|
||||
|
||||
‘true’ means that a parameter was changed. */
|
||||
|
||||
class ParameterSignal
|
||||
{
|
||||
protected:
|
||||
std::vector<bool> data;
|
||||
public:
|
||||
ParameterSignal(int n);
|
||||
ParameterSignal(const ParameterSignal &sig) = default;
|
||||
~ParameterSignal() = default;
|
||||
void signalAfter(int l);
|
||||
bool
|
||||
operator[](int i) const
|
||||
{
|
||||
return data[i];
|
||||
}
|
||||
std::vector<bool>::reference
|
||||
operator[](int i)
|
||||
{
|
||||
return data[i];
|
||||
}
|
||||
};
|
||||
|
||||
/* This is the abstract class for vector function. At this level of abstraction
|
||||
we only need to know size of input vector and a size of output vector.
|
||||
|
||||
The important thing here is a clone method, we will need to make hard copies
|
||||
of vector functions since the evaluations are not const. The hardcopies
|
||||
apply for parallelization. */
|
||||
|
||||
class VectorFunction
|
||||
{
|
||||
protected:
|
||||
int in_dim;
|
||||
int out_dim;
|
||||
public:
|
||||
VectorFunction(int idim, int odim)
|
||||
: in_dim(idim), out_dim(odim)
|
||||
{
|
||||
}
|
||||
VectorFunction(const VectorFunction &func) = default;
|
||||
virtual ~VectorFunction() = default;
|
||||
virtual std::unique_ptr<VectorFunction> clone() const = 0;
|
||||
virtual void eval(const Vector &point, const ParameterSignal &sig, Vector &out) = 0;
|
||||
int
|
||||
indim() const
|
||||
{
|
||||
return in_dim;
|
||||
}
|
||||
int
|
||||
outdim() const
|
||||
{
|
||||
return out_dim;
|
||||
}
|
||||
};
|
||||
|
||||
/* This makes ‘n’ copies of VectorFunction. The first constructor make exactly
|
||||
‘n’ new copies, the second constructor copies only the pointer to the first
|
||||
and others are hard (real) copies.
|
||||
|
||||
The class is useful for making a given number of copies at once, and this
|
||||
set can be reused many times if we need mupliple copis of the function (for
|
||||
example for paralelizing the code). */
|
||||
|
||||
class VectorFunctionSet
|
||||
{
|
||||
private:
|
||||
// Stores the hard copies made by the class
|
||||
std::vector<std::unique_ptr<VectorFunction>> func_copies;
|
||||
protected:
|
||||
std::vector<VectorFunction *> funcs;
|
||||
public:
|
||||
VectorFunctionSet(const VectorFunction &f, int n);
|
||||
VectorFunctionSet(VectorFunction &f, int n);
|
||||
~VectorFunctionSet() = default;
|
||||
VectorFunction &
|
||||
getFunc(int i)
|
||||
{
|
||||
return *(funcs[i]);
|
||||
}
|
||||
int
|
||||
getNum() const
|
||||
{
|
||||
return funcs.size();
|
||||
}
|
||||
};
|
||||
|
||||
/* This class wraps another VectorFunction to allow integration of a function
|
||||
through normally distributed inputs. Namely, if one wants to integrate
|
||||
|
||||
1
|
||||
─────────── ∫ f(x)e^{−½xᵀ|Σ|⁻¹x}dx
|
||||
√{(2π)ⁿ|Σ|}
|
||||
|
||||
then if we write Σ=AAᵀ and x=√2·Ay, we get integral
|
||||
|
||||
1 1
|
||||
─────────── ∫ f(√2·Ay)e^{−½yᵀy} √(2ⁿ)|A|dy = ───── ∫ f(√2·Ay)e^{−½yᵀy}dy
|
||||
√{(2π)ⁿ|Σ|} √(πⁿ)
|
||||
|
||||
which means that a given function f we have to wrap to yield a function
|
||||
|
||||
g(y) = 1/√(πⁿ) f(√2·Ay).
|
||||
|
||||
This is exactly what this class is doing. This transformation is useful
|
||||
since the Gauss-Hermite points and weights are defined for weighting
|
||||
function e^{−y²}, so this transformation allows using Gauss-Hermite
|
||||
quadratures seemlessly in a context of integration through normally
|
||||
distributed inputs.
|
||||
|
||||
The class maintains a pointer to the function f. When the object is
|
||||
constructed by the first constructor, the f is assumed to be owned by the
|
||||
caller. If the object of this class is copied, then f is copied and hence
|
||||
stored in a std::unique_ptr. The second constructor takes a smart pointer to
|
||||
the function and in that case the class takes ownership of f. */
|
||||
|
||||
class GaussConverterFunction : public VectorFunction
|
||||
{
|
||||
private:
|
||||
std::unique_ptr<VectorFunction> func_storage;
|
||||
protected:
|
||||
VectorFunction *func;
|
||||
GeneralMatrix A;
|
||||
double multiplier;
|
||||
public:
|
||||
GaussConverterFunction(VectorFunction &f, const GeneralMatrix &vcov);
|
||||
GaussConverterFunction(std::unique_ptr<VectorFunction> f, const GeneralMatrix &vcov);
|
||||
GaussConverterFunction(const GaussConverterFunction &f);
|
||||
~GaussConverterFunction() override = default;
|
||||
std::unique_ptr<VectorFunction>
|
||||
clone() const override
|
||||
{
|
||||
return std::make_unique<GaussConverterFunction>(*this);
|
||||
}
|
||||
void eval(const Vector &point, const ParameterSignal &sig, Vector &out) override;
|
||||
private:
|
||||
double calcMultiplier() const;
|
||||
void calcCholeskyFactor(const GeneralMatrix &vcov);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,5 +0,0 @@
|
|||
noinst_PROGRAMS = quadrature-points
|
||||
|
||||
quadrature_points_SOURCES = quadrature-points.cc
|
||||
quadrature_points_CPPFLAGS = -I../.. -I../../sylv/cc -I../../integ/cc -I../../tl/cc -I../../utils/cc
|
||||
quadrature_points_LDADD = ../cc/libinteg.a ../../tl/cc/libtl.a ../../parser/cc/libparser.a ../../sylv/cc/libsylv.a ../../utils/cc/libutils.a $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS)
|
|
@ -1,240 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2008-2011 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "parser/cc/matrix_parser.hh"
|
||||
#include "utils/cc/exception.hh"
|
||||
#include "sylv/cc/GeneralMatrix.hh"
|
||||
#include "sylv/cc/Vector.hh"
|
||||
#include "sylv/cc/SymSchurDecomp.hh"
|
||||
#include "sylv/cc/SylvException.hh"
|
||||
#include "integ/cc/quadrature.hh"
|
||||
#include "integ/cc/smolyak.hh"
|
||||
#include "integ/cc/product.hh"
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
struct QuadParams
|
||||
{
|
||||
std::string outname;
|
||||
std::string vcovname;
|
||||
int max_level{3};
|
||||
double discard_weight{0.0};
|
||||
QuadParams(int argc, char **argv);
|
||||
void check_consistency() const;
|
||||
private:
|
||||
enum class opt { max_level, discard_weight, vcov };
|
||||
};
|
||||
|
||||
QuadParams::QuadParams(int argc, char **argv)
|
||||
{
|
||||
if (argc == 1)
|
||||
{
|
||||
// Print the help and exit
|
||||
std::cerr << "Usage: " << argv[0] << " [--max-level INTEGER] [--discard-weight FLOAT] [--vcov FILENAME] OUTPUT_FILENAME" << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
outname = argv[argc-1];
|
||||
argc--;
|
||||
|
||||
struct option const opts[] = {
|
||||
{"max-level", required_argument, nullptr, static_cast<int>(opt::max_level)},
|
||||
{"discard-weight", required_argument, nullptr, static_cast<int>(opt::discard_weight)},
|
||||
{"vcov", required_argument, nullptr, static_cast<int>(opt::vcov)},
|
||||
{nullptr, 0, nullptr, 0}
|
||||
};
|
||||
|
||||
int ret;
|
||||
int index;
|
||||
while (-1 != (ret = getopt_long(argc, argv, "", opts, &index)))
|
||||
{
|
||||
if (ret == '?')
|
||||
{
|
||||
std::cerr << "Unknown option, ignored\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (static_cast<opt>(ret))
|
||||
{
|
||||
case opt::max_level:
|
||||
try
|
||||
{
|
||||
max_level = std::stoi(optarg);
|
||||
}
|
||||
catch (const std::invalid_argument &e)
|
||||
{
|
||||
std::cerr << "Couldn't parse integer " << optarg << ", ignored" << std::endl;
|
||||
}
|
||||
break;
|
||||
case opt::discard_weight:
|
||||
try
|
||||
{
|
||||
discard_weight = std::stod(optarg);
|
||||
}
|
||||
catch (const std::invalid_argument &e)
|
||||
{
|
||||
std::cerr << "Couldn't parse float " << optarg << ", ignored" << std::endl;
|
||||
}
|
||||
break;
|
||||
case opt::vcov:
|
||||
vcovname = optarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
check_consistency();
|
||||
}
|
||||
|
||||
void
|
||||
QuadParams::check_consistency() const
|
||||
{
|
||||
if (outname.empty())
|
||||
{
|
||||
std::cerr << "Error: output name not set" << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (vcovname.empty())
|
||||
{
|
||||
std::cerr << "Error: vcov file name not set" << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
QuadParams params(argc, argv);
|
||||
|
||||
// Open output file for writing
|
||||
std::ofstream fout{params.outname, std::ios::out | std::ios::trunc};
|
||||
if (fout.fail())
|
||||
{
|
||||
std::cerr << "Could not open " << params.outname << " for writing" << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
std::ifstream f{params.vcovname};
|
||||
std::ostringstream buffer;
|
||||
buffer << f.rdbuf();
|
||||
std::string contents{buffer.str()};
|
||||
|
||||
// Parse the vcov matrix
|
||||
ogp::MatrixParser mp;
|
||||
mp.parse(contents);
|
||||
if (mp.nrows() != mp.ncols())
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"VCOV matrix not square");
|
||||
// And put to the GeneralMatrix
|
||||
GeneralMatrix vcov(mp.nrows(), mp.ncols());
|
||||
vcov.zeros();
|
||||
for (ogp::MPIterator it = mp.begin(); it != mp.end(); ++it)
|
||||
vcov.get(it.row(), it.col()) = *it;
|
||||
|
||||
// Calculate the factor A of vcov, so that A·Aᵀ=VCOV
|
||||
GeneralMatrix A(vcov.nrows(), vcov.nrows());
|
||||
SymSchurDecomp ssd(vcov);
|
||||
ssd.getFactor(A);
|
||||
|
||||
// Construct Gauss-Hermite quadrature
|
||||
GaussHermite ghq;
|
||||
// Construct Smolyak quadrature
|
||||
int level = params.max_level;
|
||||
SmolyakQuadrature sq(vcov.nrows(), level, ghq);
|
||||
|
||||
std::cout << "Dimension: " << vcov.nrows() << std::endl
|
||||
<< "Maximum level: " << level << std::endl
|
||||
<< "Total number of nodes: " << sq.numEvals(level) << std::endl;
|
||||
|
||||
// Put the points to the vector
|
||||
std::vector<std::unique_ptr<Vector>> points;
|
||||
for (smolpit qit = sq.start(level); qit != sq.end(level); ++qit)
|
||||
points.push_back(std::make_unique<Vector>(const_cast<const Vector &>(qit.point())));
|
||||
// Sort and uniq
|
||||
std::sort(points.begin(), points.end(), [](auto &a, auto &b) { return a.get() < b.get(); });
|
||||
auto new_end = std::unique(points.begin(), points.end());
|
||||
points.erase(new_end, points.end());
|
||||
|
||||
std::cout << "Duplicit nodes removed: " << static_cast<unsigned long>(sq.numEvals(level)-points.size())
|
||||
<< std::endl;
|
||||
|
||||
// Calculate weights and mass
|
||||
double mass = 0.0;
|
||||
std::vector<double> weights;
|
||||
for (auto &point : points)
|
||||
{
|
||||
weights.push_back(std::exp(-point->dot(*point)));
|
||||
mass += weights.back();
|
||||
}
|
||||
|
||||
// Calculate discarded mass
|
||||
double discard_mass = 0.0;
|
||||
for (double weight : weights)
|
||||
if (weight/mass < params.discard_weight)
|
||||
discard_mass += weight;
|
||||
|
||||
std::cout << "Total mass discarded: " << std::fixed << discard_mass/mass << std::endl;
|
||||
|
||||
// Dump the results
|
||||
int npoints = 0;
|
||||
double upscale_weight = 1/(mass-discard_mass);
|
||||
Vector x(vcov.nrows());
|
||||
fout << std::setprecision(16);
|
||||
for (int i = 0; i < static_cast<int>(weights.size()); i++)
|
||||
if (weights[i]/mass >= params.discard_weight)
|
||||
{
|
||||
// Print the upscaled weight
|
||||
fout << std::setw(20) << upscale_weight*weights[i];
|
||||
// Multiply point with the factor A and √2
|
||||
A.multVec(0.0, x, std::sqrt(2.), *(points[i]));
|
||||
// Print the coordinates
|
||||
for (int j = 0; j < x.length(); j++)
|
||||
fout << ' ' << std::setw(20) << x[j];
|
||||
fout << std::endl;
|
||||
npoints++;
|
||||
}
|
||||
|
||||
std::cout << "Final number of points: " << npoints << std::endl;
|
||||
|
||||
fout.close();
|
||||
}
|
||||
catch (const SylvException &e)
|
||||
{
|
||||
e.printMessage();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
catch (const ogu::Exception &e)
|
||||
{
|
||||
e.print();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
check_PROGRAMS = tests
|
||||
|
||||
tests_SOURCES = tests.cc
|
||||
tests_CPPFLAGS = -I../cc -I../../tl/cc -I../../sylv/cc -I../../utils/cc -I$(top_srcdir)/mex/sources
|
||||
tests_LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS_MATIO)
|
||||
tests_LDADD = ../../sylv/cc/libsylv.a ../cc/libinteg.a ../../tl/cc/libtl.a ../../utils/cc/libutils.a $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS) $(LIBADD_MATIO)
|
||||
|
||||
check-local:
|
||||
./tests
|
|
@ -1,550 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GeneralMatrix.hh"
|
||||
#include <dynlapack.h>
|
||||
#include "SylvException.hh"
|
||||
|
||||
#include "rfs_tensor.hh"
|
||||
#include "normal_moments.hh"
|
||||
|
||||
#include "vector_function.hh"
|
||||
#include "quadrature.hh"
|
||||
#include "smolyak.hh"
|
||||
#include "product.hh"
|
||||
#include "quasi_mcarlo.hh"
|
||||
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <cstdlib>
|
||||
|
||||
/* Evaluates unfolded (Dx)ᵏ power, where x is a vector, D is a Cholesky factor
|
||||
(lower triangular) */
|
||||
class MomentFunction : public VectorFunction
|
||||
{
|
||||
GeneralMatrix D;
|
||||
int k;
|
||||
public:
|
||||
MomentFunction(const GeneralMatrix &inD, int kk)
|
||||
: VectorFunction(inD.nrows(), UFSTensor::calcMaxOffset(inD.nrows(), kk)),
|
||||
D(inD), k(kk)
|
||||
{
|
||||
}
|
||||
MomentFunction(const MomentFunction &func) = default;
|
||||
|
||||
std::unique_ptr<VectorFunction>
|
||||
clone() const override
|
||||
{
|
||||
return std::make_unique<MomentFunction>(*this);
|
||||
}
|
||||
void eval(const Vector &point, const ParameterSignal &sig, Vector &out) override;
|
||||
};
|
||||
|
||||
void
|
||||
MomentFunction::eval(const Vector &point, const ParameterSignal &sig, Vector &out)
|
||||
{
|
||||
if (point.length() != indim() || out.length() != outdim())
|
||||
{
|
||||
std::cerr << "Wrong length of vectors in MomentFunction::eval" << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
Vector y(point);
|
||||
y.zeros();
|
||||
D.multaVec(y, point);
|
||||
URSingleTensor ypow(y, k);
|
||||
out.zeros();
|
||||
out.add(1.0, ypow.getData());
|
||||
}
|
||||
|
||||
class TensorPower : public VectorFunction
|
||||
{
|
||||
int k;
|
||||
public:
|
||||
TensorPower(int nvar, int kk)
|
||||
: VectorFunction(nvar, UFSTensor::calcMaxOffset(nvar, kk)), k(kk)
|
||||
{
|
||||
}
|
||||
TensorPower(const TensorPower &func) = default;
|
||||
|
||||
std::unique_ptr<VectorFunction>
|
||||
clone() const override
|
||||
{
|
||||
return std::make_unique<TensorPower>(*this);
|
||||
}
|
||||
void eval(const Vector &point, const ParameterSignal &sig, Vector &out) override;
|
||||
};
|
||||
|
||||
void
|
||||
TensorPower::eval(const Vector &point, const ParameterSignal &sig, Vector &out)
|
||||
{
|
||||
if (point.length() != indim() || out.length() != outdim())
|
||||
{
|
||||
std::cerr << "Wrong length of vectors in TensorPower::eval" << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
URSingleTensor ypow(point, k);
|
||||
out.zeros();
|
||||
out.add(1.0, ypow.getData());
|
||||
}
|
||||
|
||||
/* Evaluates (1+1/d)ᵈ(x₁·…·x_d)^(1/d), its integral over [0,1]ᵈ
|
||||
is 1.0, and its variation grows exponentially */
|
||||
class Function1 : public VectorFunction
|
||||
{
|
||||
int dim;
|
||||
public:
|
||||
Function1(int d)
|
||||
: VectorFunction(d, 1), dim(d)
|
||||
{
|
||||
}
|
||||
Function1(const Function1 &f)
|
||||
: VectorFunction(f.indim(), f.outdim()), dim(f.dim)
|
||||
{
|
||||
}
|
||||
std::unique_ptr<VectorFunction>
|
||||
clone() const override
|
||||
{
|
||||
return std::make_unique<Function1>(*this);
|
||||
}
|
||||
void eval(const Vector &point, const ParameterSignal &sig, Vector &out) override;
|
||||
};
|
||||
|
||||
void
|
||||
Function1::eval(const Vector &point, const ParameterSignal &sig, Vector &out)
|
||||
{
|
||||
if (point.length() != dim || out.length() != 1)
|
||||
{
|
||||
std::cerr << "Wrong length of vectors in Function1::eval" << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
double r = 1;
|
||||
for (int i = 0; i < dim; i++)
|
||||
r *= point[i];
|
||||
r = pow(r, 1.0/dim);
|
||||
r *= pow(1.0 + 1.0/dim, static_cast<double>(dim));
|
||||
out[0] = r;
|
||||
}
|
||||
|
||||
// Evaluates Function1 but with transformation xᵢ=0.5(yᵢ+1)
|
||||
// This makes the new function integrate over [−1,1]ᵈ to 1.0
|
||||
class Function1Trans : public Function1
|
||||
{
|
||||
public:
|
||||
Function1Trans(int d)
|
||||
: Function1(d)
|
||||
{
|
||||
}
|
||||
Function1Trans(const Function1Trans &func) = default;
|
||||
|
||||
std::unique_ptr<VectorFunction>
|
||||
clone() const override
|
||||
{
|
||||
return std::make_unique<Function1Trans>(*this);
|
||||
}
|
||||
void eval(const Vector &point, const ParameterSignal &sig, Vector &out) override;
|
||||
};
|
||||
|
||||
void
|
||||
Function1Trans::eval(const Vector &point, const ParameterSignal &sig, Vector &out)
|
||||
{
|
||||
Vector p(point.length());
|
||||
for (int i = 0; i < p.length(); i++)
|
||||
p[i] = 0.5*(point[i]+1);
|
||||
Function1::eval(p, sig, out);
|
||||
out.mult(pow(0.5, indim()));
|
||||
}
|
||||
|
||||
/* WallTimer class. Constructor saves the wall time, destructor cancels the
|
||||
current time from the saved, and prints the message with time information */
|
||||
class WallTimer
|
||||
{
|
||||
std::string mes;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> start;
|
||||
bool new_line;
|
||||
public:
|
||||
WallTimer(std::string m, bool nl = true)
|
||||
: mes{m}, start{std::chrono::high_resolution_clock::now()}, new_line{nl}
|
||||
{
|
||||
}
|
||||
~WallTimer()
|
||||
{
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<double> duration = end - start;
|
||||
std::cout << mes << std::setw(8) << std::setprecision(4) << duration.count();
|
||||
if (new_line)
|
||||
std::cout << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
/****************************************************/
|
||||
/* declaration of TestRunnable class */
|
||||
/****************************************************/
|
||||
class TestRunnable
|
||||
{
|
||||
public:
|
||||
const std::string name;
|
||||
int dim; // dimension of the solved problem
|
||||
int nvar; // number of variables of the solved problem
|
||||
TestRunnable(std::string name_arg, int d, int nv)
|
||||
: name{move(name_arg)}, dim(d), nvar(nv)
|
||||
{
|
||||
}
|
||||
virtual ~TestRunnable() = default;
|
||||
bool test() const;
|
||||
virtual bool run() const = 0;
|
||||
protected:
|
||||
static bool smolyak_normal_moments(const GeneralMatrix &m, int imom, int level);
|
||||
static bool product_normal_moments(const GeneralMatrix &m, int imom, int level);
|
||||
static bool qmc_normal_moments(const GeneralMatrix &m, int imom, int level);
|
||||
static bool smolyak_product_cube(const VectorFunction &func, const Vector &res,
|
||||
double tol, int level);
|
||||
static bool qmc_cube(const VectorFunction &func, double res, double tol, int level);
|
||||
};
|
||||
|
||||
bool
|
||||
TestRunnable::test() const
|
||||
{
|
||||
std::cout << "Running test <" << name << ">" << std::endl;
|
||||
bool passed;
|
||||
{
|
||||
WallTimer tim("Wall clock time ", false);
|
||||
passed = run();
|
||||
}
|
||||
if (passed)
|
||||
{
|
||||
std::cout << "............................ passed" << std::endl << std::endl;
|
||||
return passed;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "............................ FAILED" << std::endl << std::endl;
|
||||
return passed;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************/
|
||||
/* definition of TestRunnable static methods */
|
||||
/****************************************************/
|
||||
bool
|
||||
TestRunnable::smolyak_normal_moments(const GeneralMatrix &m, int imom, int level)
|
||||
{
|
||||
// First make m·mᵀ and then Cholesky factor
|
||||
GeneralMatrix msq(m * transpose(m));
|
||||
|
||||
// Make vector function
|
||||
int dim = m.nrows();
|
||||
TensorPower tp(dim, imom);
|
||||
GaussConverterFunction func(tp, msq);
|
||||
|
||||
// Smolyak quadrature
|
||||
Vector smol_out(UFSTensor::calcMaxOffset(dim, imom));
|
||||
{
|
||||
WallTimer tim("\tSmolyak quadrature time: ");
|
||||
GaussHermite gs;
|
||||
SmolyakQuadrature quad(dim, level, gs);
|
||||
quad.integrate(func, level, sthread::detach_thread_group::max_parallel_threads, smol_out);
|
||||
std::cout << "\tNumber of Smolyak evaluations: " << quad.numEvals(level) << std::endl;
|
||||
}
|
||||
|
||||
// Check against theoretical moments
|
||||
UNormalMoments moments(imom, msq);
|
||||
smol_out.add(-1.0, moments.get(Symmetry{imom}).getData());
|
||||
std::cout << "\tError: " << std::setw(16) << std::setprecision(12) << smol_out.getMax() << std::endl;
|
||||
return smol_out.getMax() < 1.e-7;
|
||||
}
|
||||
|
||||
bool
|
||||
TestRunnable::product_normal_moments(const GeneralMatrix &m, int imom, int level)
|
||||
{
|
||||
// First make m·mᵀ and then Cholesky factor
|
||||
GeneralMatrix msq(m * transpose(m));
|
||||
|
||||
// Make vector function
|
||||
int dim = m.nrows();
|
||||
TensorPower tp(dim, imom);
|
||||
GaussConverterFunction func(tp, msq);
|
||||
|
||||
// Product quadrature
|
||||
Vector prod_out(UFSTensor::calcMaxOffset(dim, imom));
|
||||
{
|
||||
WallTimer tim("\tProduct quadrature time: ");
|
||||
GaussHermite gs;
|
||||
ProductQuadrature quad(dim, gs);
|
||||
quad.integrate(func, level, sthread::detach_thread_group::max_parallel_threads, prod_out);
|
||||
std::cout << "\tNumber of product evaluations: " << quad.numEvals(level) << std::endl;
|
||||
}
|
||||
|
||||
// Check against theoretical moments
|
||||
UNormalMoments moments(imom, msq);
|
||||
prod_out.add(-1.0, moments.get(Symmetry{imom}).getData());
|
||||
std::cout << "\tError: " << std::setw(16) << std::setprecision(12) << prod_out.getMax() << std::endl;
|
||||
return prod_out.getMax() < 1.e-7;
|
||||
}
|
||||
|
||||
bool
|
||||
TestRunnable::smolyak_product_cube(const VectorFunction &func, const Vector &res,
|
||||
double tol, int level)
|
||||
{
|
||||
if (res.length() != func.outdim())
|
||||
{
|
||||
std::cerr << "Incompatible dimensions of check value and function." << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
GaussLegendre glq;
|
||||
Vector out(func.outdim());
|
||||
double smol_error;
|
||||
double prod_error;
|
||||
{
|
||||
WallTimer tim("\tSmolyak quadrature time: ");
|
||||
SmolyakQuadrature quad(func.indim(), level, glq);
|
||||
quad.integrate(func, level, sthread::detach_thread_group::max_parallel_threads, out);
|
||||
out.add(-1.0, res);
|
||||
smol_error = out.getMax();
|
||||
std::cout << "\tNumber of Smolyak evaluations: " << quad.numEvals(level) << std::endl;
|
||||
std::cout << "\tError: " << std::setw(16) << std::setprecision(12) << smol_error << std::endl;
|
||||
}
|
||||
{
|
||||
WallTimer tim("\tProduct quadrature time: ");
|
||||
ProductQuadrature quad(func.indim(), glq);
|
||||
quad.integrate(func, level, sthread::detach_thread_group::max_parallel_threads, out);
|
||||
out.add(-1.0, res);
|
||||
prod_error = out.getMax();
|
||||
std::cout << "\tNumber of product evaluations: " << quad.numEvals(level) << std::endl;
|
||||
std::cout << "\tError: " << std::setw(16) << std::setprecision(12) << prod_error << std::endl;
|
||||
}
|
||||
|
||||
return smol_error < tol && prod_error < tol;
|
||||
}
|
||||
|
||||
bool
|
||||
TestRunnable::qmc_cube(const VectorFunction &func, double res, double tol, int level)
|
||||
{
|
||||
Vector r(1);
|
||||
double error1;
|
||||
{
|
||||
WallTimer tim("\tQuasi-Monte Carlo (Warnock scrambling) time: ");
|
||||
WarnockPerScheme wps;
|
||||
QMCarloCubeQuadrature qmc(func.indim(), level, wps);
|
||||
qmc.integrate(func, level, sthread::detach_thread_group::max_parallel_threads, r);
|
||||
error1 = std::max(res - r[0], r[0] - res);
|
||||
std::cout << "\tQuasi-Monte Carlo (Warnock scrambling) error: " << std::setw(16) << std::setprecision(12) << error1 << std::endl;
|
||||
}
|
||||
double error2;
|
||||
{
|
||||
WallTimer tim("\tQuasi-Monte Carlo (reverse scrambling) time: ");
|
||||
ReversePerScheme rps;
|
||||
QMCarloCubeQuadrature qmc(func.indim(), level, rps);
|
||||
qmc.integrate(func, level, sthread::detach_thread_group::max_parallel_threads, r);
|
||||
error2 = std::max(res - r[0], r[0] - res);
|
||||
std::cout << "\tQuasi-Monte Carlo (reverse scrambling) error: " << std::setw(16) << std::setprecision(12) << error2 << std::endl;
|
||||
}
|
||||
double error3;
|
||||
{
|
||||
WallTimer tim("\tQuasi-Monte Carlo (no scrambling) time: ");
|
||||
IdentityPerScheme ips;
|
||||
QMCarloCubeQuadrature qmc(func.indim(), level, ips);
|
||||
qmc.integrate(func, level, sthread::detach_thread_group::max_parallel_threads, r);
|
||||
error3 = std::max(res - r[0], r[0] - res);
|
||||
std::cout << "\tQuasi-Monte Carlo (no scrambling) error: " << std::setw(16) << std::setprecision(12) << error3 << std::endl;
|
||||
}
|
||||
|
||||
return error1 < tol && error2 < tol && error3 < tol;
|
||||
}
|
||||
|
||||
/****************************************************/
|
||||
/* definition of TestRunnable subclasses */
|
||||
/****************************************************/
|
||||
class SmolyakNormalMom1 : public TestRunnable
|
||||
{
|
||||
public:
|
||||
SmolyakNormalMom1()
|
||||
: TestRunnable("Smolyak normal moments (dim=2, level=4, order=4)", 4, 2)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
run() const override
|
||||
{
|
||||
GeneralMatrix m(2, 2);
|
||||
m.zeros();
|
||||
m.get(0, 0) = 1;
|
||||
m.get(1, 1) = 1;
|
||||
return smolyak_normal_moments(m, 4, 4);
|
||||
}
|
||||
};
|
||||
|
||||
class SmolyakNormalMom2 : public TestRunnable
|
||||
{
|
||||
public:
|
||||
SmolyakNormalMom2()
|
||||
: TestRunnable("Smolyak normal moments (dim=3, level=8, order=8)", 8, 3)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
run() const override
|
||||
{
|
||||
GeneralMatrix m(3, 3);
|
||||
m.zeros();
|
||||
m.get(0, 0) = 1;
|
||||
m.get(0, 2) = 0.5;
|
||||
m.get(1, 1) = 1;
|
||||
m.get(1, 0) = 0.5;
|
||||
m.get(2, 2) = 2;
|
||||
m.get(2, 1) = 4;
|
||||
return smolyak_normal_moments(m, 8, 8);
|
||||
}
|
||||
};
|
||||
|
||||
class ProductNormalMom1 : public TestRunnable
|
||||
{
|
||||
public:
|
||||
ProductNormalMom1()
|
||||
: TestRunnable("Product normal moments (dim=2, level=4, order=4)", 4, 2)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
run() const override
|
||||
{
|
||||
GeneralMatrix m(2, 2);
|
||||
m.zeros();
|
||||
m.get(0, 0) = 1;
|
||||
m.get(1, 1) = 1;
|
||||
return product_normal_moments(m, 4, 4);
|
||||
}
|
||||
};
|
||||
|
||||
class ProductNormalMom2 : public TestRunnable
|
||||
{
|
||||
public:
|
||||
ProductNormalMom2()
|
||||
: TestRunnable("Product normal moments (dim=3, level=8, order=8)", 8, 3)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
run() const override
|
||||
{
|
||||
GeneralMatrix m(3, 3);
|
||||
m.zeros();
|
||||
m.get(0, 0) = 1;
|
||||
m.get(0, 2) = 0.5;
|
||||
m.get(1, 1) = 1;
|
||||
m.get(1, 0) = 0.5;
|
||||
m.get(2, 2) = 2;
|
||||
m.get(2, 1) = 4;
|
||||
return product_normal_moments(m, 8, 8);
|
||||
}
|
||||
};
|
||||
|
||||
// Note that here we pass 1,1 to tls since smolyak has its own PascalTriangle
|
||||
class F1GaussLegendre : public TestRunnable
|
||||
{
|
||||
public:
|
||||
F1GaussLegendre()
|
||||
: TestRunnable("Function1 Gauss-Legendre (dim=6, level=13", 1, 1)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
run() const override
|
||||
{
|
||||
Function1Trans f1(6);
|
||||
Vector res(1);
|
||||
res[0] = 1.0;
|
||||
return smolyak_product_cube(f1, res, 1e-2, 13);
|
||||
}
|
||||
};
|
||||
|
||||
class F1QuasiMCarlo : public TestRunnable
|
||||
{
|
||||
public:
|
||||
F1QuasiMCarlo()
|
||||
: TestRunnable("Function1 Quasi-Monte Carlo (dim=6, level=1000000)", 1, 1)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
run() const override
|
||||
{
|
||||
Function1 f1(6);
|
||||
return qmc_cube(f1, 1.0, 1.e-4, 1000000);
|
||||
}
|
||||
};
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
std::vector<std::unique_ptr<TestRunnable>> all_tests;
|
||||
// Fill in vector of all tests
|
||||
all_tests.push_back(std::make_unique<SmolyakNormalMom1>());
|
||||
all_tests.push_back(std::make_unique<SmolyakNormalMom2>());
|
||||
all_tests.push_back(std::make_unique<ProductNormalMom1>());
|
||||
all_tests.push_back(std::make_unique<ProductNormalMom2>());
|
||||
all_tests.push_back(std::make_unique<F1GaussLegendre>());
|
||||
all_tests.push_back(std::make_unique<F1QuasiMCarlo>());
|
||||
|
||||
// Find maximum dimension and maximum nvar
|
||||
int dmax = 0;
|
||||
int nvmax = 0;
|
||||
for (const auto &test : all_tests)
|
||||
{
|
||||
dmax = std::max(dmax, test->dim);
|
||||
nvmax = std::max(nvmax, test->nvar);
|
||||
}
|
||||
TLStatic::init(dmax, nvmax); // initialize library
|
||||
|
||||
// Launch the tests
|
||||
int success = 0;
|
||||
for (const auto &test : all_tests)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (test->test())
|
||||
success++;
|
||||
}
|
||||
catch (const TLException &e)
|
||||
{
|
||||
std::cout << "Caught TL exception in <" << test->name << ">:" << std::endl;
|
||||
e.print();
|
||||
}
|
||||
catch (SylvException &e)
|
||||
{
|
||||
std::cout << "Caught Sylv exception in <" << test->name << ">:" << std::endl;
|
||||
e.printMessage();
|
||||
}
|
||||
}
|
||||
|
||||
int nfailed = all_tests.size() - success;
|
||||
std::cout << "There were " << nfailed << " tests that failed out of "
|
||||
<< all_tests.size() << " tests run." << std::endl;
|
||||
|
||||
if (nfailed)
|
||||
return EXIT_FAILURE;
|
||||
else
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
noinst_LIBRARIES = libkord.a
|
||||
|
||||
libkord_a_SOURCES = \
|
||||
approximation.cc \
|
||||
approximation.hh \
|
||||
decision_rule.cc \
|
||||
decision_rule.hh \
|
||||
dynamic_model.cc \
|
||||
dynamic_model.hh \
|
||||
faa_di_bruno.cc \
|
||||
faa_di_bruno.hh \
|
||||
first_order.cc \
|
||||
first_order.hh \
|
||||
global_check.cc \
|
||||
global_check.hh \
|
||||
kord_exception.hh \
|
||||
korder.cc \
|
||||
korder.hh \
|
||||
korder_stoch.cc \
|
||||
korder_stoch.hh \
|
||||
journal.cc \
|
||||
journal.hh \
|
||||
normal_conjugate.cc \
|
||||
normal_conjugate.hh \
|
||||
seed_generator.cc \
|
||||
seed_generator.hh
|
||||
|
||||
libkord_a_CPPFLAGS = -I../sylv/cc -I../tl/cc -I../integ/cc -I../utils/cc -I$(top_srcdir)/mex/sources $(CPPFLAGS_MATIO) -DDYNVERSION=\"$(PACKAGE_VERSION)\"
|
||||
|
||||
check_PROGRAMS = tests
|
||||
|
||||
tests_SOURCES = tests.cc
|
||||
tests_CPPFLAGS = -I../sylv/cc -I../tl/cc -I../integ/cc -I../utils/cc -I$(top_srcdir)/mex/sources
|
||||
tests_LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS_MATIO)
|
||||
tests_LDADD = libkord.a ../tl/cc/libtl.a ../sylv/cc/libsylv.a ../utils/cc/libutils.a $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS) $(LIBADD_MATIO)
|
||||
|
||||
check-local:
|
||||
./tests
|
||||
|
||||
CLEANFILES = out.txt
|
|
@ -1,586 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2004 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "kord_exception.hh"
|
||||
#include "decision_rule.hh"
|
||||
#include "dynamic_model.hh"
|
||||
#include "seed_generator.hh"
|
||||
|
||||
#include "SymSchurDecomp.hh"
|
||||
|
||||
#include <dynlapack.h>
|
||||
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
|
||||
// FoldDecisionRule conversion from UnfoldDecisionRule
|
||||
FoldDecisionRule::FoldDecisionRule(const UnfoldDecisionRule &udr)
|
||||
: DecisionRuleImpl<Storage::fold>(ctraits<Storage::fold>::Tpol(udr.nrows(), udr.nvars()),
|
||||
udr.ypart, udr.nu, udr.ysteady)
|
||||
{
|
||||
for (const auto &it : udr)
|
||||
insert(std::make_unique<ctraits<Storage::fold>::Ttensym>(*(it.second)));
|
||||
}
|
||||
|
||||
// UnfoldDecisionRule conversion from FoldDecisionRule
|
||||
UnfoldDecisionRule::UnfoldDecisionRule(const FoldDecisionRule &fdr)
|
||||
: DecisionRuleImpl<Storage::unfold>(ctraits<Storage::unfold>::Tpol(fdr.nrows(), fdr.nvars()),
|
||||
fdr.ypart, fdr.nu, fdr.ysteady)
|
||||
{
|
||||
for (const auto &it : fdr)
|
||||
insert(std::make_unique<ctraits<Storage::unfold>::Ttensym>(*(it.second)));
|
||||
}
|
||||
|
||||
/* This runs simulations with an output to journal file. Note that we
|
||||
report how many simulations had to be thrown out due to Nan or Inf. */
|
||||
|
||||
void
|
||||
SimResults::simulate(int num_sim, const DecisionRule &dr, const Vector &start,
|
||||
const TwoDMatrix &vcov, Journal &journal)
|
||||
{
|
||||
JournalRecordPair paa(journal);
|
||||
paa << "Performing " << num_sim << " stochastic simulations for "
|
||||
<< num_per << " periods burning " << num_burn << " initial periods" << endrec;
|
||||
simulate(num_sim, dr, start, vcov);
|
||||
int thrown = num_sim - data.size();
|
||||
if (thrown > 0)
|
||||
{
|
||||
JournalRecord rec(journal);
|
||||
rec << "I had to throw " << thrown << " simulations away due to Nan or Inf" << endrec;
|
||||
}
|
||||
}
|
||||
|
||||
/* This runs a given number of simulations by creating
|
||||
SimulationWorker for each simulation and inserting them to the
|
||||
thread group. */
|
||||
|
||||
void
|
||||
SimResults::simulate(int num_sim, const DecisionRule &dr, const Vector &start,
|
||||
const TwoDMatrix &vcov)
|
||||
{
|
||||
std::vector<RandomShockRealization> rsrs;
|
||||
rsrs.reserve(num_sim);
|
||||
|
||||
sthread::detach_thread_group gr;
|
||||
for (int i = 0; i < num_sim; i++)
|
||||
{
|
||||
RandomShockRealization sr(vcov, seed_generator::get_new_seed());
|
||||
rsrs.push_back(sr);
|
||||
gr.insert(std::make_unique<SimulationWorker>(*this, dr, DecisionRule::emethod::horner,
|
||||
num_per+num_burn, start, rsrs.back()));
|
||||
}
|
||||
gr.run();
|
||||
}
|
||||
|
||||
/* This adds the data with the realized shocks. It takes only periods
|
||||
which are not to be burnt. If the data is not finite, the both data
|
||||
and shocks are thrown away. */
|
||||
|
||||
bool
|
||||
SimResults::addDataSet(const TwoDMatrix &d, const ExplicitShockRealization &sr, const ConstVector &st)
|
||||
{
|
||||
KORD_RAISE_IF(d.nrows() != num_y,
|
||||
"Incompatible number of rows for SimResults::addDataSets");
|
||||
KORD_RAISE_IF(d.ncols() != num_per+num_burn,
|
||||
"Incompatible number of cols for SimResults::addDataSets");
|
||||
bool ret = false;
|
||||
if (d.isFinite())
|
||||
{
|
||||
data.emplace_back(d, num_burn, num_per);
|
||||
shocks.emplace_back(ConstTwoDMatrix(sr.getShocks(), num_burn, num_per));
|
||||
if (num_burn == 0)
|
||||
start.emplace_back(st);
|
||||
else
|
||||
start.emplace_back(d.getCol(num_burn-1));
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
SimResults::writeMat(const std::string &base, const std::string &lname) const
|
||||
{
|
||||
std::string matfile_name = base + ".mat";
|
||||
mat_t *matfd = Mat_Create(matfile_name.c_str(), nullptr);
|
||||
if (matfd)
|
||||
{
|
||||
writeMat(matfd, lname);
|
||||
Mat_Close(matfd);
|
||||
}
|
||||
}
|
||||
|
||||
/* This save the results as matrices with given prefix and with index
|
||||
appended. If there is only one matrix, the index is not appended. */
|
||||
|
||||
void
|
||||
SimResults::writeMat(mat_t *fd, const std::string &lname) const
|
||||
{
|
||||
for (int i = 0; i < getNumSets(); i++)
|
||||
{
|
||||
std::string tmp = lname + "_data";
|
||||
if (getNumSets() > 1)
|
||||
tmp += std::to_string(i+1);
|
||||
data[i].writeMat(fd, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsStats::simulate(int num_sim, const DecisionRule &dr,
|
||||
const Vector &start,
|
||||
const TwoDMatrix &vcov, Journal &journal)
|
||||
{
|
||||
SimResults::simulate(num_sim, dr, start, vcov, journal);
|
||||
{
|
||||
JournalRecordPair paa(journal);
|
||||
paa << "Calculating means from the simulations." << endrec;
|
||||
calcMean();
|
||||
}
|
||||
{
|
||||
JournalRecordPair paa(journal);
|
||||
paa << "Calculating covariances from the simulations." << endrec;
|
||||
calcVcov();
|
||||
}
|
||||
}
|
||||
|
||||
/* Here we do not save the data itself, we save only mean and vcov. */
|
||||
void
|
||||
SimResultsStats::writeMat(mat_t *fd, const std::string &lname) const
|
||||
{
|
||||
ConstTwoDMatrix(num_y, 1, mean).writeMat(fd, lname + "_mean");;
|
||||
vcov.writeMat(fd, lname + "_vcov");
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsStats::calcMean()
|
||||
{
|
||||
mean.zeros();
|
||||
if (data.size()*num_per > 0)
|
||||
{
|
||||
double mult = 1.0/data.size()/num_per;
|
||||
for (const auto &i : data)
|
||||
{
|
||||
for (int j = 0; j < num_per; j++)
|
||||
{
|
||||
ConstVector col{i.getCol(j)};
|
||||
mean.add(mult, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsStats::calcVcov()
|
||||
{
|
||||
if (data.size()*num_per > 1)
|
||||
{
|
||||
vcov.zeros();
|
||||
double mult = 1.0/(data.size()*num_per - 1);
|
||||
for (const auto &d : data)
|
||||
for (int j = 0; j < num_per; j++)
|
||||
for (int m = 0; m < num_y; m++)
|
||||
for (int n = m; n < num_y; n++)
|
||||
{
|
||||
double s = (d.get(m, j)-mean[m])*(d.get(n, j)-mean[n]);
|
||||
vcov.get(m, n) += mult*s;
|
||||
if (m != n)
|
||||
vcov.get(n, m) += mult*s;
|
||||
}
|
||||
}
|
||||
else
|
||||
vcov.infs();
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsDynamicStats::simulate(int num_sim, const DecisionRule &dr,
|
||||
const Vector &start,
|
||||
const TwoDMatrix &vcov, Journal &journal)
|
||||
{
|
||||
SimResults::simulate(num_sim, dr, start, vcov, journal);
|
||||
{
|
||||
JournalRecordPair paa(journal);
|
||||
paa << "Calculating means of the conditional simulations." << endrec;
|
||||
calcMean();
|
||||
}
|
||||
{
|
||||
JournalRecordPair paa(journal);
|
||||
paa << "Calculating variances of the conditional simulations." << endrec;
|
||||
calcVariance();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsDynamicStats::writeMat(mat_t *fd, const std::string &lname) const
|
||||
{
|
||||
mean.writeMat(fd, lname + "_cond_mean");
|
||||
variance.writeMat(fd, lname + "_cond_variance");
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsDynamicStats::calcMean()
|
||||
{
|
||||
mean.zeros();
|
||||
if (data.size() > 0)
|
||||
{
|
||||
double mult = 1.0/data.size();
|
||||
for (int j = 0; j < num_per; j++)
|
||||
{
|
||||
Vector meanj{mean.getCol(j)};
|
||||
for (const auto &i : data)
|
||||
{
|
||||
ConstVector col{i.getCol(j)};
|
||||
meanj.add(mult, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsDynamicStats::calcVariance()
|
||||
{
|
||||
if (data.size() > 1)
|
||||
{
|
||||
variance.zeros();
|
||||
double mult = 1.0/(data.size()-1);
|
||||
for (int j = 0; j < num_per; j++)
|
||||
{
|
||||
ConstVector meanj{mean.getCol(j)};
|
||||
Vector varj{variance.getCol(j)};
|
||||
for (const auto &i : data)
|
||||
{
|
||||
Vector col{i.getCol(j)};
|
||||
col.add(-1.0, meanj);
|
||||
for (int k = 0; k < col.length(); k++)
|
||||
col[k] = col[k]*col[k];
|
||||
varj.add(mult, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
variance.infs();
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsIRF::simulate(const DecisionRule &dr, Journal &journal)
|
||||
{
|
||||
JournalRecordPair paa(journal);
|
||||
paa << "Performing " << control.getNumSets() << " IRF simulations for "
|
||||
<< num_per << " periods; shock=" << ishock << ", impulse=" << imp << endrec;
|
||||
simulate(dr);
|
||||
int thrown = control.getNumSets() - data.size();
|
||||
if (thrown > 0)
|
||||
{
|
||||
JournalRecord rec(journal);
|
||||
rec << "I had to throw " << thrown
|
||||
<< " simulations away due to Nan or Inf" << endrec;
|
||||
}
|
||||
calcMeans();
|
||||
calcVariances();
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsIRF::simulate(const DecisionRule &dr)
|
||||
{
|
||||
sthread::detach_thread_group gr;
|
||||
for (int idata = 0; idata < control.getNumSets(); idata++)
|
||||
gr.insert(std::make_unique<SimulationIRFWorker>(*this, dr, DecisionRule::emethod::horner,
|
||||
num_per, idata, ishock, imp));
|
||||
gr.run();
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsIRF::calcMeans()
|
||||
{
|
||||
means.zeros();
|
||||
if (data.size() > 0)
|
||||
{
|
||||
for (const auto &i : data)
|
||||
means.add(1.0, i);
|
||||
means.mult(1.0/data.size());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsIRF::calcVariances()
|
||||
{
|
||||
if (data.size() > 1)
|
||||
{
|
||||
variances.zeros();
|
||||
for (const auto &i : data)
|
||||
{
|
||||
TwoDMatrix d(i);
|
||||
d.add(-1.0, means);
|
||||
for (int j = 0; j < d.nrows(); j++)
|
||||
for (int k = 0; k < d.ncols(); k++)
|
||||
variances.get(j, k) += d.get(j, k)*d.get(j, k);
|
||||
d.mult(1.0/(data.size()-1));
|
||||
}
|
||||
}
|
||||
else
|
||||
variances.infs();
|
||||
}
|
||||
|
||||
void
|
||||
SimResultsIRF::writeMat(mat_t *fd, const std::string &lname) const
|
||||
{
|
||||
means.writeMat(fd, lname + "_mean");
|
||||
variances.writeMat(fd, lname + "_var");
|
||||
}
|
||||
|
||||
void
|
||||
RTSimResultsStats::simulate(int num_sim, const DecisionRule &dr, const Vector &start,
|
||||
const TwoDMatrix &v, Journal &journal)
|
||||
{
|
||||
JournalRecordPair paa(journal);
|
||||
paa << "Performing " << num_sim << " real-time stochastic simulations for "
|
||||
<< num_per << " periods" << endrec;
|
||||
simulate(num_sim, dr, start, v);
|
||||
mean = nc.getMean();
|
||||
mean.add(1.0, dr.getSteady());
|
||||
nc.getVariance(vcov);
|
||||
if (thrown_periods > 0)
|
||||
{
|
||||
JournalRecord rec(journal);
|
||||
rec << "I had to throw " << thrown_periods << " periods away due to Nan or Inf" << endrec;
|
||||
JournalRecord rec1(journal);
|
||||
rec1 << "This affected " << incomplete_simulations << " out of "
|
||||
<< num_sim << " simulations" << endrec;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RTSimResultsStats::simulate(int num_sim, const DecisionRule &dr, const Vector &start,
|
||||
const TwoDMatrix &vcov)
|
||||
{
|
||||
std::vector<RandomShockRealization> rsrs;
|
||||
rsrs.reserve(num_sim);
|
||||
|
||||
sthread::detach_thread_group gr;
|
||||
for (int i = 0; i < num_sim; i++)
|
||||
{
|
||||
RandomShockRealization sr(vcov, seed_generator::get_new_seed());
|
||||
rsrs.push_back(sr);
|
||||
gr.insert(std::make_unique<RTSimulationWorker>(*this, dr, DecisionRule::emethod::horner,
|
||||
num_per, start, rsrs.back()));
|
||||
}
|
||||
gr.run();
|
||||
}
|
||||
|
||||
void
|
||||
RTSimResultsStats::writeMat(mat_t *fd, const std::string &lname)
|
||||
{
|
||||
ConstTwoDMatrix(nc.getDim(), 1, mean).writeMat(fd, lname + "_rt_mean");
|
||||
vcov.writeMat(fd, lname + "_rt_vcov");
|
||||
}
|
||||
|
||||
IRFResults::IRFResults(const DynamicModel &mod, const DecisionRule &dr,
|
||||
const SimResults &control, std::vector<int> ili,
|
||||
Journal &journal)
|
||||
: model(mod), irf_list_ind(std::move(ili))
|
||||
{
|
||||
int num_per = control.getNumPer();
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Calculating IRFs against control for " << static_cast<int>(irf_list_ind.size()) << " shocks and for "
|
||||
<< num_per << " periods" << endrec;
|
||||
const TwoDMatrix &vcov = mod.getVcov();
|
||||
for (int ishock : irf_list_ind)
|
||||
{
|
||||
double stderror = sqrt(vcov.get(ishock, ishock));
|
||||
irf_res.emplace_back(control, model.numeq(), num_per,
|
||||
ishock, stderror);
|
||||
irf_res.emplace_back(control, model.numeq(), num_per,
|
||||
ishock, -stderror);
|
||||
}
|
||||
|
||||
for (unsigned int ii = 0; ii < irf_list_ind.size(); ii++)
|
||||
{
|
||||
irf_res[2*ii].simulate(dr, journal);
|
||||
irf_res[2*ii+1].simulate(dr, journal);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IRFResults::writeMat(mat_t *fd, const std::string &prefix) const
|
||||
{
|
||||
for (unsigned int i = 0; i < irf_list_ind.size(); i++)
|
||||
{
|
||||
int ishock = irf_list_ind[i];
|
||||
auto shockname = model.getExogNames().getName(ishock);
|
||||
irf_res[2*i].writeMat(fd, prefix + "_irfp_" + shockname);
|
||||
irf_res[2*i+1].writeMat(fd, prefix + "_irfm_" + shockname);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SimulationWorker::operator()(std::mutex &mut)
|
||||
{
|
||||
ExplicitShockRealization esr(sr, np);
|
||||
TwoDMatrix m{dr.simulate(em, np, st, esr)};
|
||||
{
|
||||
std::unique_lock<std::mutex> lk{mut};
|
||||
res.addDataSet(m, esr, st);
|
||||
}
|
||||
}
|
||||
|
||||
/* Here we create a new instance of ExplicitShockRealization of the
|
||||
corresponding control, add the impulse, and simulate. */
|
||||
|
||||
void
|
||||
SimulationIRFWorker::operator()(std::mutex &mut)
|
||||
{
|
||||
ExplicitShockRealization esr(res.control.getShocks(idata));
|
||||
esr.addToShock(ishock, 0, imp);
|
||||
TwoDMatrix m{dr.simulate(em, np, res.control.getStart(idata), esr)};
|
||||
m.add(-1.0, res.control.getData(idata));
|
||||
{
|
||||
std::unique_lock<std::mutex> lk{mut};
|
||||
res.addDataSet(m, esr, res.control.getStart(idata));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RTSimulationWorker::operator()(std::mutex &mut)
|
||||
{
|
||||
NormalConj nc(res.nc.getDim());
|
||||
const PartitionY &ypart = dr.getYPart();
|
||||
int nu = dr.nexog();
|
||||
const Vector &ysteady = dr.getSteady();
|
||||
|
||||
// initialize vectors and subvectors for simulation
|
||||
Vector dyu(ypart.nys()+nu);
|
||||
ConstVector ystart_pred(ystart, ypart.nstat, ypart.nys());
|
||||
ConstVector ysteady_pred(ysteady, ypart.nstat, ypart.nys());
|
||||
Vector dy(dyu, 0, ypart.nys());
|
||||
Vector u(dyu, ypart.nys(), nu);
|
||||
Vector y(nc.getDim());
|
||||
ConstVector ypred(y, ypart.nstat, ypart.nys());
|
||||
|
||||
// simulate the first real-time period
|
||||
int ip = 0;
|
||||
dy = ystart_pred;
|
||||
dy.add(-1.0, ysteady_pred);
|
||||
sr.get(ip, u);
|
||||
dr.eval(em, y, dyu);
|
||||
if (ip >= res.num_burn)
|
||||
nc.update(y);
|
||||
|
||||
// simulate other real-time periods
|
||||
while (y.isFinite() && ip < res.num_burn + res.num_per)
|
||||
{
|
||||
ip++;
|
||||
dy = ypred;
|
||||
sr.get(ip, u);
|
||||
dr.eval(em, y, dyu);
|
||||
if (ip >= res.num_burn)
|
||||
nc.update(y);
|
||||
}
|
||||
{
|
||||
std::unique_lock<std::mutex> lk{mut};
|
||||
res.nc.update(nc);
|
||||
if (res.num_per-ip > 0)
|
||||
{
|
||||
res.incomplete_simulations++;
|
||||
res.thrown_periods += res.num_per-ip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This calculates factorization FFᵀ=V in the Cholesky way. It does
|
||||
not work for semidefinite matrices. */
|
||||
|
||||
void
|
||||
RandomShockRealization::choleskyFactor(const ConstTwoDMatrix &v)
|
||||
{
|
||||
factor = v;
|
||||
lapack_int rows = factor.nrows(), lda = factor.getLD();
|
||||
for (int i = 0; i < rows; i++)
|
||||
for (int j = i+1; j < rows; j++)
|
||||
factor.get(i, j) = 0.0;
|
||||
lapack_int info;
|
||||
|
||||
dpotrf("L", &rows, factor.base(), &lda, &info);
|
||||
KORD_RAISE_IF(info != 0,
|
||||
"Info!=0 in RandomShockRealization::choleskyFactor");
|
||||
}
|
||||
|
||||
/* This calculates FFᵀ=V factorization by symmetric Schur
|
||||
decomposition. It works for semidefinite matrices. */
|
||||
|
||||
void
|
||||
RandomShockRealization::schurFactor(const ConstTwoDMatrix &v)
|
||||
{
|
||||
SymSchurDecomp(v).getFactor(factor);
|
||||
}
|
||||
|
||||
void
|
||||
RandomShockRealization::get(int n, Vector &out)
|
||||
{
|
||||
KORD_RAISE_IF(out.length() != numShocks(),
|
||||
"Wrong length of out vector in RandomShockRealization::get");
|
||||
Vector d(out.length());
|
||||
for (int i = 0; i < d.length(); i++)
|
||||
d[i] = dis(mtwister);
|
||||
out.zeros();
|
||||
factor.multaVec(out, ConstVector(d));
|
||||
}
|
||||
|
||||
ExplicitShockRealization::ExplicitShockRealization(ShockRealization &sr,
|
||||
int num_per)
|
||||
: shocks(sr.numShocks(), num_per)
|
||||
{
|
||||
for (int j = 0; j < num_per; j++)
|
||||
{
|
||||
Vector jcol{shocks.getCol(j)};
|
||||
sr.get(j, jcol);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ExplicitShockRealization::get(int n, Vector &out)
|
||||
{
|
||||
KORD_RAISE_IF(out.length() != numShocks(),
|
||||
"Wrong length of out vector in ExplicitShockRealization::get");
|
||||
int i = n % shocks.ncols();
|
||||
ConstVector icol{shocks.getCol(i)};
|
||||
out = icol;
|
||||
}
|
||||
|
||||
void
|
||||
ExplicitShockRealization::addToShock(int ishock, int iper, double val)
|
||||
{
|
||||
KORD_RAISE_IF(ishock < 0 || ishock > numShocks(),
|
||||
"Wrong index of shock in ExplicitShockRealization::addToShock");
|
||||
int j = iper % shocks.ncols();
|
||||
shocks.get(ishock, j) += val;
|
||||
}
|
||||
|
||||
void
|
||||
GenShockRealization::get(int n, Vector &out)
|
||||
{
|
||||
KORD_RAISE_IF(out.length() != numShocks(),
|
||||
"Wrong length of out vector in GenShockRealization::get");
|
||||
ExplicitShockRealization::get(n, out);
|
||||
Vector r(numShocks());
|
||||
RandomShockRealization::get(n, r);
|
||||
for (int j = 0; j < numShocks(); j++)
|
||||
if (!std::isfinite(out[j]))
|
||||
out[j] = r[j];
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dynamic_model.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
void
|
||||
NameList::print() const
|
||||
{
|
||||
for (int i = 0; i < getNum(); i++)
|
||||
std::cout << getName(i) << '\n';
|
||||
}
|
||||
|
||||
void
|
||||
NameList::writeMat(mat_t *fd, const std::string &vname) const
|
||||
{
|
||||
int maxlen = 0;
|
||||
for (int i = 0; i < getNum(); i++)
|
||||
maxlen = std::max(maxlen, static_cast<int>(getName(i).size()));
|
||||
|
||||
if (maxlen == 0)
|
||||
return;
|
||||
|
||||
auto m = std::make_unique<char[]>(getNum()*maxlen);
|
||||
|
||||
for (int i = 0; i < getNum(); i++)
|
||||
for (int j = 0; j < maxlen; j++)
|
||||
if (j < static_cast<int>(getName(i).size()))
|
||||
m[j*getNum()+i] = getName(i)[j];
|
||||
else
|
||||
m[j*getNum()+i] = ' ';
|
||||
|
||||
size_t dims[2];
|
||||
dims[0] = getNum();
|
||||
dims[1] = maxlen;
|
||||
|
||||
matvar_t *v = Mat_VarCreate(vname.c_str(), MAT_C_CHAR, MAT_T_UINT8, 2, dims, m.get(), 0);
|
||||
|
||||
Mat_VarWrite(fd, v, MAT_COMPRESSION_NONE);
|
||||
|
||||
Mat_VarFree(v);
|
||||
}
|
||||
|
||||
void
|
||||
NameList::writeMatIndices(mat_t *fd, const std::string &prefix) const
|
||||
{
|
||||
TwoDMatrix aux(1, 1);
|
||||
for (int i = 0; i < getNum(); i++)
|
||||
{
|
||||
aux.get(0, 0) = i+1;
|
||||
aux.writeMat(fd, prefix + "_i_" + getName(i));
|
||||
}
|
||||
}
|
|
@ -1,384 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "SymSchurDecomp.hh"
|
||||
|
||||
#include "global_check.hh"
|
||||
#include "seed_generator.hh"
|
||||
|
||||
#include "smolyak.hh"
|
||||
#include "product.hh"
|
||||
#include "quasi_mcarlo.hh"
|
||||
|
||||
#include <utility>
|
||||
#include <cmath>
|
||||
|
||||
/* Here we just set a reference to the approximation, and create a new
|
||||
DynamicModel. */
|
||||
|
||||
ResidFunction::ResidFunction(const Approximation &app)
|
||||
: VectorFunction(app.getModel().nexog(), app.getModel().numeq()), approx(app),
|
||||
model(app.getModel().clone())
|
||||
{
|
||||
}
|
||||
|
||||
ResidFunction::ResidFunction(const ResidFunction &rf)
|
||||
: VectorFunction(rf), approx(rf.approx), model(rf.model->clone())
|
||||
{
|
||||
if (rf.yplus)
|
||||
yplus = std::make_unique<Vector>(*(rf.yplus));
|
||||
if (rf.ystar)
|
||||
ystar = std::make_unique<Vector>(*(rf.ystar));
|
||||
if (rf.u)
|
||||
u = std::make_unique<Vector>(*(rf.u));
|
||||
if (rf.hss)
|
||||
hss = std::make_unique<FTensorPolynomial>(*(rf.hss));
|
||||
}
|
||||
|
||||
/* This sets y* and u. We have to create ‘ystar’, ‘u’, ‘yplus’ and ‘hss’. */
|
||||
|
||||
void
|
||||
ResidFunction::setYU(const ConstVector &ys, const ConstVector &xx)
|
||||
{
|
||||
ystar = std::make_unique<Vector>(ys);
|
||||
u = std::make_unique<Vector>(xx);
|
||||
yplus = std::make_unique<Vector>(model->numeq());
|
||||
approx.getFoldDecisionRule().evaluate(DecisionRule::emethod::horner,
|
||||
*yplus, *ystar, *u);
|
||||
|
||||
// make a tensor polynomial of in-place subtensors from decision rule
|
||||
/* Note that the non-const polynomial will be used for a construction of
|
||||
‘hss’ and will be used in a const context. So this const cast is safe.
|
||||
|
||||
Note, that there is always a folded decision rule in Approximation. */
|
||||
const FoldDecisionRule &dr = approx.getFoldDecisionRule();
|
||||
FTensorPolynomial dr_ss(model->nstat()+model->npred(), model->nboth()+model->nforw(),
|
||||
const_cast<FoldDecisionRule &>(dr));
|
||||
|
||||
// make ‘ytmp_star’ be a difference of ‘yplus’ from steady
|
||||
Vector ytmp_star(ConstVector(*yplus, model->nstat(), model->npred()+model->nboth()));
|
||||
ConstVector ysteady_star(dr.getSteady(), model->nstat(),
|
||||
model->npred()+model->nboth());
|
||||
ytmp_star.add(-1.0, ysteady_star);
|
||||
|
||||
// make ‘hss’ and add steady to it
|
||||
/* Here is the const context of ‘dr_ss’. */
|
||||
hss = std::make_unique<FTensorPolynomial>(dr_ss, ytmp_star);
|
||||
ConstVector ysteady_ss(dr.getSteady(), model->nstat()+model->npred(),
|
||||
model->nboth()+model->nforw());
|
||||
if (hss->check(Symmetry{0}))
|
||||
hss->get(Symmetry{0}).getData().add(1.0, ysteady_ss);
|
||||
else
|
||||
{
|
||||
auto ten = std::make_unique<FFSTensor>(hss->nrows(), hss->nvars(), 0);
|
||||
ten->getData() = ysteady_ss;
|
||||
hss->insert(std::move(ten));
|
||||
}
|
||||
}
|
||||
|
||||
/* Here we evaluate the residual F(y*,u,u′). We have to evaluate ‘hss’ for
|
||||
u′=point and then we evaluate the system f. */
|
||||
|
||||
void
|
||||
ResidFunction::eval(const Vector &point, const ParameterSignal &sig, Vector &out)
|
||||
{
|
||||
KORD_RAISE_IF(point.length() != hss->nvars(),
|
||||
"Wrong dimension of input vector in ResidFunction::eval");
|
||||
KORD_RAISE_IF(out.length() != model->numeq(),
|
||||
"Wrong dimension of output vector in ResidFunction::eval");
|
||||
Vector yss(hss->nrows());
|
||||
hss->evalHorner(yss, point);
|
||||
model->evaluateSystem(out, *ystar, *yplus, yss, *u);
|
||||
}
|
||||
|
||||
/* This checks the 𝔼[F(y*,u,u′)] for a given y* and u by integrating with a
|
||||
given quadrature. Note that the input ‘ys’ is y* not whole y. */
|
||||
|
||||
void
|
||||
GlobalChecker::check(const Quadrature &quad, int level,
|
||||
const ConstVector &ys, const ConstVector &x, Vector &out)
|
||||
{
|
||||
for (int ifunc = 0; ifunc < vfs.getNum(); ifunc++)
|
||||
dynamic_cast<GResidFunction &>(vfs.getFunc(ifunc)).setYU(ys, x);
|
||||
quad.integrate(vfs, level, out);
|
||||
}
|
||||
|
||||
/* This method is a bulk version of GlobalChecker::check() vector code. It
|
||||
decides between Smolyak and product quadrature according to ‘max_evals’
|
||||
constraint.
|
||||
|
||||
Note that ‘y’ can be either full (all endogenous variables including static
|
||||
and forward looking), or just y* (state variables). The method is able to
|
||||
recognize it. */
|
||||
|
||||
void
|
||||
GlobalChecker::check(int max_evals, const ConstTwoDMatrix &y,
|
||||
const ConstTwoDMatrix &x, TwoDMatrix &out)
|
||||
{
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Checking approximation error for " << y.ncols()
|
||||
<< " states with at most " << max_evals << " evaluations" << endrec;
|
||||
|
||||
// Decide about which type of quadrature
|
||||
GaussHermite gh;
|
||||
|
||||
SmolyakQuadrature dummy_sq(model.nexog(), 1, gh);
|
||||
int smol_evals;
|
||||
int smol_level;
|
||||
dummy_sq.designLevelForEvals(max_evals, smol_level, smol_evals);
|
||||
|
||||
ProductQuadrature dummy_pq(model.nexog(), gh);
|
||||
int prod_evals;
|
||||
int prod_level;
|
||||
dummy_pq.designLevelForEvals(max_evals, prod_level, prod_evals);
|
||||
|
||||
bool take_smolyak = (smol_evals < prod_evals) && (smol_level >= prod_level-1);
|
||||
|
||||
std::unique_ptr<Quadrature> quad;
|
||||
int lev;
|
||||
|
||||
// Create the quadrature and report the decision
|
||||
if (take_smolyak)
|
||||
{
|
||||
quad = std::make_unique<SmolyakQuadrature>(model.nexog(), smol_level, gh);
|
||||
lev = smol_level;
|
||||
JournalRecord rec(journal);
|
||||
rec << "Selected Smolyak (level,evals)=(" << smol_level << ","
|
||||
<< smol_evals << ") over product (" << prod_level << ","
|
||||
<< prod_evals << ")" << endrec;
|
||||
}
|
||||
else
|
||||
{
|
||||
quad = std::make_unique<ProductQuadrature>(model.nexog(), gh);
|
||||
lev = prod_level;
|
||||
JournalRecord rec(journal);
|
||||
rec << "Selected product (level,evals)=(" << prod_level << ","
|
||||
<< prod_evals << ") over Smolyak (" << smol_level << ","
|
||||
<< smol_evals << ")" << endrec;
|
||||
}
|
||||
|
||||
// Check all columns of ‘y’ and ‘x’
|
||||
int first_row = (y.nrows() == model.numeq()) ? model.nstat() : 0;
|
||||
ConstTwoDMatrix ysmat(y, first_row, 0, model.npred()+model.nboth(), y.ncols());
|
||||
for (int j = 0; j < y.ncols(); j++)
|
||||
{
|
||||
ConstVector yj{ysmat.getCol(j)};
|
||||
ConstVector xj{x.getCol(j)};
|
||||
Vector outj{out.getCol(j)};
|
||||
check(*quad, lev, yj, xj, outj);
|
||||
}
|
||||
}
|
||||
|
||||
/* This method checks an error of the approximation by evaluating residual
|
||||
𝔼[F(y*,u,u′) | y*,u] for y* equal to the steady state, and changing u. We go
|
||||
through all elements of u and vary them from −mult·σ to mult·σ in ‘m’
|
||||
steps. */
|
||||
|
||||
void
|
||||
GlobalChecker::checkAlongShocksAndSave(mat_t *fd, const std::string &prefix,
|
||||
int m, double mult, int max_evals)
|
||||
{
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Calculating errors along shocks +/- "
|
||||
<< mult << " std errors, granularity " << m << endrec;
|
||||
|
||||
// Setup ‘y_mat’ of steady states for checking
|
||||
TwoDMatrix y_mat(model.numeq(), 2*m*model.nexog()+1);
|
||||
for (int j = 0; j < 2*m*model.nexog()+1; j++)
|
||||
{
|
||||
Vector yj{y_mat.getCol(j)};
|
||||
yj = model.getSteady();
|
||||
}
|
||||
|
||||
// Setup ‘exo_mat’ for checking
|
||||
TwoDMatrix exo_mat(model.nexog(), 2*m*model.nexog()+1);
|
||||
exo_mat.zeros();
|
||||
for (int ishock = 0; ishock < model.nexog(); ishock++)
|
||||
{
|
||||
double max_sigma = sqrt(model.getVcov().get(ishock, ishock));
|
||||
for (int j = 0; j < 2*m; j++)
|
||||
{
|
||||
int jmult = (j < m) ? j-m : j-m+1;
|
||||
exo_mat.get(ishock, 1+2*m*ishock+j) = mult*jmult*max_sigma/m;
|
||||
}
|
||||
}
|
||||
|
||||
TwoDMatrix errors(model.numeq(), 2*m*model.nexog()+1);
|
||||
check(max_evals, y_mat, exo_mat, errors);
|
||||
|
||||
// Report errors along shock and save them
|
||||
TwoDMatrix res(model.nexog(), 2*m+1);
|
||||
JournalRecord rec(journal);
|
||||
rec << "Shock value error" << endrec;
|
||||
ConstVector err0{errors.getCol(0)};
|
||||
for (int ishock = 0; ishock < model.nexog(); ishock++)
|
||||
{
|
||||
TwoDMatrix err_out(model.numeq(), 2*m+1);
|
||||
for (int j = 0; j < 2*m+1; j++)
|
||||
{
|
||||
int jj;
|
||||
Vector error{err_out.getCol(j)};
|
||||
if (j != m)
|
||||
{
|
||||
if (j < m)
|
||||
jj = 1 + 2*m*ishock+j;
|
||||
else
|
||||
jj = 1 + 2*m*ishock+j-1;
|
||||
ConstVector coljj{errors.getCol(jj)};
|
||||
error = coljj;
|
||||
}
|
||||
else
|
||||
{
|
||||
jj = 0;
|
||||
error = err0;
|
||||
}
|
||||
JournalRecord rec1(journal);
|
||||
std::string shockname{model.getExogNames().getName(ishock)};
|
||||
shockname.resize(8, ' ');
|
||||
rec1 << shockname << ' ' << exo_mat.get(ishock, jj)
|
||||
<< "\t" << error.getMax() << endrec;
|
||||
}
|
||||
err_out.writeMat(fd, prefix + "_shock_" + model.getExogNames().getName(ishock) + "_errors");
|
||||
}
|
||||
}
|
||||
|
||||
/* This method checks errors on ellipse of endogenous states (predetermined
|
||||
variables). The ellipse is shaped according to covariance matrix of
|
||||
endogenous variables based on the first order approximation and scaled by
|
||||
‘mult’. The points on the ellipse are chosen as polar images of the low
|
||||
discrepancy grid in a cube.
|
||||
|
||||
The method works as follows. First we calculate symmetric Schur factor of
|
||||
covariance matrix of the states. Second we generate low discrepancy points
|
||||
on the unit sphere. Third we transform the sphere with the
|
||||
variance-covariance matrix factor and multiplier ‘mult’ and initialize
|
||||
matrix of uₜ to zeros. Fourth we run the check() method and save the
|
||||
results. */
|
||||
|
||||
void
|
||||
GlobalChecker::checkOnEllipseAndSave(mat_t *fd, const std::string &prefix,
|
||||
int m, double mult, int max_evals)
|
||||
{
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Calculating errors at " << m
|
||||
<< " ellipse points scaled by " << mult << endrec;
|
||||
|
||||
// Make factor of covariance of variables
|
||||
/* Here we set ‘ycovfac’ to the symmetric Schur decomposition factor of a
|
||||
submatrix of covariances of all endogenous variables. The submatrix
|
||||
corresponds to state variables (predetermined plus both). */
|
||||
TwoDMatrix ycov{approx.calcYCov()};
|
||||
TwoDMatrix ycovpred(const_cast<const TwoDMatrix &>(ycov), model.nstat(), model.nstat(),
|
||||
model.npred()+model.nboth(), model.npred()+model.nboth());
|
||||
SymSchurDecomp ssd(ycovpred);
|
||||
ssd.correctDefinitness(1.e-05);
|
||||
TwoDMatrix ycovfac(ycovpred.nrows(), ycovpred.ncols());
|
||||
KORD_RAISE_IF(!ssd.isPositiveSemidefinite(),
|
||||
"Covariance matrix of the states not positive \
|
||||
semidefinite in GlobalChecker::checkOnEllipseAndSave");
|
||||
ssd.getFactor(ycovfac);
|
||||
|
||||
// Put low discrepancy sphere points to ‘ymat’
|
||||
/* Here we first calculate dimension ‘d’ of the sphere, which is a number of
|
||||
state variables minus one. We go through the ‘d’-dimensional cube [0,1]ᵈ
|
||||
by QMCarloCubeQuadrature and make a polar transformation to the sphere.
|
||||
The polar transformation fⁱ can be written recursively w.r.t. the
|
||||
dimension i as:
|
||||
|
||||
f⁰() = [1]
|
||||
|
||||
⎡cos(2πxᵢ)·fⁱ⁻¹(x₁,…,xᵢ₋₁)⎤
|
||||
fⁱ(x₁,…,xᵢ) = ⎣ sin(2πxᵢ) ⎦
|
||||
*/
|
||||
int d = model.npred()+model.nboth()-1;
|
||||
TwoDMatrix ymat(model.npred()+model.nboth(), (d == 0) ? 2 : m);
|
||||
if (d == 0)
|
||||
{
|
||||
ymat.get(0, 0) = 1;
|
||||
ymat.get(0, 1) = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int icol = 0;
|
||||
ReversePerScheme ps;
|
||||
QMCarloCubeQuadrature qmc(d, m, ps);
|
||||
qmcpit beg = qmc.start(m);
|
||||
qmcpit end = qmc.end(m);
|
||||
for (qmcpit run = beg; run != end; ++run, icol++)
|
||||
{
|
||||
Vector ycol{ymat.getCol(icol)};
|
||||
Vector x(run.point());
|
||||
x.mult(2*M_PI);
|
||||
ycol[0] = 1;
|
||||
for (int i = 0; i < d; i++)
|
||||
{
|
||||
Vector subsphere(ycol, 0, i+1);
|
||||
subsphere.mult(cos(x[i]));
|
||||
ycol[i+1] = sin(x[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transform sphere ‘ymat’ and prepare ‘umat’ for checking
|
||||
/* Here we multiply the sphere points in ‘ymat’ with the Cholesky factor to
|
||||
obtain the ellipse, scale the ellipse by the given ‘mult’, and initialize
|
||||
matrix of shocks ‘umat’ to zero. */
|
||||
TwoDMatrix umat(model.nexog(), ymat.ncols());
|
||||
umat.zeros();
|
||||
ymat.mult(mult);
|
||||
ymat.multLeft(ycovfac);
|
||||
ConstVector ys(model.getSteady(), model.nstat(),
|
||||
model.npred()+model.nboth());
|
||||
for (int icol = 0; icol < ymat.ncols(); icol++)
|
||||
{
|
||||
Vector ycol{ymat.getCol(icol)};
|
||||
ycol.add(1.0, ys);
|
||||
}
|
||||
|
||||
// Check on ellipse and save
|
||||
/* Here we check the points and save the results to MAT-4 file. */
|
||||
TwoDMatrix out(model.numeq(), ymat.ncols());
|
||||
check(max_evals, ymat, umat, out);
|
||||
|
||||
ymat.writeMat(fd, prefix + "_ellipse_points");
|
||||
out.writeMat(fd, prefix + "_ellipse_errors");
|
||||
}
|
||||
|
||||
/* Here we check the errors along a simulation. We simulate, then set ‘x’ to
|
||||
zeros, check and save results. */
|
||||
|
||||
void
|
||||
GlobalChecker::checkAlongSimulationAndSave(mat_t *fd, const std::string &prefix,
|
||||
int m, int max_evals)
|
||||
{
|
||||
JournalRecordPair pa(journal);
|
||||
pa << "Calculating errors at " << m
|
||||
<< " simulated points" << endrec;
|
||||
RandomShockRealization sr(model.getVcov(), seed_generator::get_new_seed());
|
||||
TwoDMatrix y{approx.getFoldDecisionRule().simulate(DecisionRule::emethod::horner,
|
||||
m, model.getSteady(), sr)};
|
||||
TwoDMatrix x(model.nexog(), m);
|
||||
x.zeros();
|
||||
TwoDMatrix out(model.numeq(), m);
|
||||
check(max_evals, y, x, out);
|
||||
|
||||
y.writeMat(fd, prefix + "_simul_points");
|
||||
out.writeMat(fd, prefix + "_simul_errors");
|
||||
}
|
|
@ -1,171 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Global check
|
||||
|
||||
/* The purpose of this file is to provide classes for checking error of
|
||||
approximation. If yₜ=g(y*ₜ₋₁,u) is an approximate solution, then we check
|
||||
for the error of residuals of the system equations. Let
|
||||
F(y*,u,u′)=f(g**(g*(y*,u′),u),g(y*,u),y*,u), then we calculate the integral:
|
||||
|
||||
𝔼ₜ[F(y*,u,u′)]
|
||||
|
||||
which we want to be zero for all y* and u.
|
||||
|
||||
There are a few possibilities how and where the integral is evaluated.
|
||||
Currently we offer the following ones:
|
||||
|
||||
— Along shocks. The y* is set to the steady state, and u is set to zero but
|
||||
one element is going from minus through plus shocks in few steps. The user
|
||||
gives the scaling factor, for instance the interval [−3σ,3σ] (where σ is
|
||||
one standard error of the shock), and a number of steps. This is repeated
|
||||
for each shock (element of the u vector).
|
||||
|
||||
— Along simulation. Some random simulation is run, and for each realization
|
||||
of y* and u along the path we evaluate the residual.
|
||||
|
||||
— On ellipse. Let V=AAᵀ be a covariance matrix of the predetermined
|
||||
variables y* based on linear approximation, then we calculate integral for
|
||||
points on the ellipse { Ax | ‖x‖₂=1 }. The points are selected by means of
|
||||
low discrepancy method and polar transformation. The shock u are zeros.
|
||||
|
||||
— Unconditional distribution.
|
||||
*/
|
||||
|
||||
#ifndef GLOBAL_CHECK_H
|
||||
#define GLOBAL_CHECK_H
|
||||
|
||||
#include <matio.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "vector_function.hh"
|
||||
#include "quadrature.hh"
|
||||
|
||||
#include "dynamic_model.hh"
|
||||
#include "journal.hh"
|
||||
#include "approximation.hh"
|
||||
|
||||
/* This is a class for implementing the VectorFunction interface evaluating the
|
||||
residual of equations, this is F(y*,u,u′)=f(g**(g*(y*,u),u′),y*,u) is
|
||||
written as a function of u′.
|
||||
|
||||
When the object is constructed, one has to specify (y*,u), this is done by
|
||||
the setYU() method. The object has basically two states. One is after
|
||||
construction and before the call to setYU(). The second is after the call to
|
||||
setYU(). We distinguish between the two states, an object in the second
|
||||
state contains ‘yplus’, ‘ystar’, ‘u’, and ‘hss’.
|
||||
|
||||
The vector ‘yplus’ is g*(y*,u). ‘ystar’ is y*, and polynomial ‘hss’ is
|
||||
partially evaluated g**(yplus, u).
|
||||
|
||||
The pointer to DynamicModel is important, since the DynamicModel evaluates
|
||||
the function f. When copying the object, we have to make also a copy of
|
||||
DynamicModel. */
|
||||
|
||||
class ResidFunction : public VectorFunction
|
||||
{
|
||||
protected:
|
||||
const Approximation ≈
|
||||
std::unique_ptr<DynamicModel> model;
|
||||
std::unique_ptr<Vector> yplus, ystar, u;
|
||||
std::unique_ptr<FTensorPolynomial> hss;
|
||||
public:
|
||||
ResidFunction(const Approximation &app);
|
||||
ResidFunction(const ResidFunction &rf);
|
||||
|
||||
std::unique_ptr<VectorFunction>
|
||||
clone() const override
|
||||
{
|
||||
return std::make_unique<ResidFunction>(*this);
|
||||
}
|
||||
void eval(const Vector &point, const ParameterSignal &sig, Vector &out) override;
|
||||
void setYU(const ConstVector &ys, const ConstVector &xx);
|
||||
};
|
||||
|
||||
/* This is a ResidFunction wrapped with GaussConverterFunction. */
|
||||
|
||||
class GResidFunction : public GaussConverterFunction
|
||||
{
|
||||
public:
|
||||
GResidFunction(const Approximation &app)
|
||||
: GaussConverterFunction(std::make_unique<ResidFunction>(app), app.getModel().getVcov())
|
||||
{
|
||||
}
|
||||
std::unique_ptr<VectorFunction>
|
||||
clone() const override
|
||||
{
|
||||
return std::make_unique<GResidFunction>(*this);
|
||||
}
|
||||
void
|
||||
setYU(const ConstVector &ys, const ConstVector &xx)
|
||||
{
|
||||
dynamic_cast<ResidFunction *>(func)->setYU(ys, xx);
|
||||
}
|
||||
};
|
||||
|
||||
/* This is a class encapsulating checking algorithms. Its core routine is
|
||||
check(), which calculates integral 𝔼[F(y*,u,u′) | y*,u] for given
|
||||
realizations of y* and u. The both are given in matrices. The methods
|
||||
checking along shocks, on ellipse and anlong a simulation path, just fill
|
||||
the matrices and call the core check().
|
||||
|
||||
The method checkUnconditionalAndSave() evaluates unconditional 𝔼[F(y,u,u′)].
|
||||
|
||||
The object also maintains a set of GResidFunction functions ‘vfs’ in order
|
||||
to save (possibly expensive) copying of DynamicModel’s. */
|
||||
|
||||
class GlobalChecker
|
||||
{
|
||||
const Approximation ≈
|
||||
const DynamicModel &model;
|
||||
Journal &journal;
|
||||
GResidFunction rf;
|
||||
VectorFunctionSet vfs;
|
||||
public:
|
||||
GlobalChecker(const Approximation &app, int n, Journal &jr)
|
||||
: approx(app), model(approx.getModel()), journal(jr),
|
||||
rf(approx), vfs(rf, n)
|
||||
{
|
||||
}
|
||||
void check(int max_evals, const ConstTwoDMatrix &y,
|
||||
const ConstTwoDMatrix &x, TwoDMatrix &out);
|
||||
void checkAlongShocksAndSave(mat_t *fd, const std::string &prefix,
|
||||
int m, double mult, int max_evals);
|
||||
void checkOnEllipseAndSave(mat_t *fd, const std::string &prefix,
|
||||
int m, double mult, int max_evals);
|
||||
void checkAlongSimulationAndSave(mat_t *fd, const std::string &prefix,
|
||||
int m, int max_evals);
|
||||
void checkUnconditionalAndSave(mat_t *fd, const std::string &prefix,
|
||||
int m, int max_evals);
|
||||
protected:
|
||||
void check(const Quadrature &quad, int level,
|
||||
const ConstVector &y, const ConstVector &x, Vector &out);
|
||||
};
|
||||
|
||||
/* Signalled resid function. Not implemented yet. todo: */
|
||||
|
||||
class ResidFunctionSig : public ResidFunction
|
||||
{
|
||||
public:
|
||||
ResidFunctionSig(const Approximation &app, const Vector &ys, const Vector &xx);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,123 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2007 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "normal_conjugate.hh"
|
||||
#include "kord_exception.hh"
|
||||
|
||||
// NormalConj diffuse prior constructor
|
||||
NormalConj::NormalConj(int d)
|
||||
: mu(d), kappa(0), nu(-1), lambda(d, d)
|
||||
{
|
||||
mu.zeros();
|
||||
lambda.zeros();
|
||||
}
|
||||
|
||||
// NormalConj data update constructor
|
||||
NormalConj::NormalConj(const ConstTwoDMatrix &ydata)
|
||||
: mu(ydata.nrows()), kappa(ydata.ncols()), nu(ydata.ncols()-1),
|
||||
lambda(ydata.nrows(), ydata.nrows())
|
||||
{
|
||||
mu.zeros();
|
||||
for (int i = 0; i < ydata.ncols(); i++)
|
||||
mu.add(1.0/ydata.ncols(), ydata.getCol(i));
|
||||
|
||||
lambda.zeros();
|
||||
for (int i = 0; i < ydata.ncols(); i++)
|
||||
{
|
||||
Vector diff{ydata.getCol(i)};
|
||||
diff.add(-1, mu);
|
||||
lambda.addOuter(diff);
|
||||
}
|
||||
}
|
||||
|
||||
// NormalConj::update() one observation code
|
||||
/* The method performs the following:
|
||||
|
||||
κ₀ 1
|
||||
μ₁ = ──── μ₀ + ──── y
|
||||
κ₀+1 κ₀+1
|
||||
|
||||
κ₁ = κ₀ + 1
|
||||
|
||||
ν₁ = ν₀ + 1
|
||||
|
||||
κ₀
|
||||
Λ₁ = Λ₀ + ──── (y − μ₀)(y − μ₀)ᵀ
|
||||
κ₀+1
|
||||
*/
|
||||
void
|
||||
NormalConj::update(const ConstVector &y)
|
||||
{
|
||||
KORD_RAISE_IF(y.length() != mu.length(),
|
||||
"Wrong length of a vector in NormalConj::update");
|
||||
|
||||
mu.mult(kappa/(1.0+kappa));
|
||||
mu.add(1.0/(1.0+kappa), y);
|
||||
|
||||
Vector diff(y);
|
||||
diff.add(-1, mu);
|
||||
lambda.addOuter(diff, kappa/(1.0+kappa));
|
||||
|
||||
kappa++;
|
||||
nu++;
|
||||
}
|
||||
|
||||
// NormalConj::update() multiple observations code
|
||||
/* The method evaluates the formula in the header file. */
|
||||
void
|
||||
NormalConj::update(const ConstTwoDMatrix &ydata)
|
||||
{
|
||||
NormalConj nc(ydata);
|
||||
update(nc);
|
||||
}
|
||||
|
||||
// NormalConj::update() with NormalConj code
|
||||
void
|
||||
NormalConj::update(const NormalConj &nc)
|
||||
{
|
||||
double wold = static_cast<double>(kappa)/(kappa+nc.kappa);
|
||||
double wnew = 1-wold;
|
||||
|
||||
mu.mult(wold);
|
||||
mu.add(wnew, nc.mu);
|
||||
|
||||
Vector diff(nc.mu);
|
||||
diff.add(-1, mu);
|
||||
lambda.add(1.0, nc.lambda);
|
||||
lambda.addOuter(diff);
|
||||
|
||||
kappa = kappa + nc.kappa;
|
||||
nu = nu + nc.kappa;
|
||||
}
|
||||
|
||||
/* This returns 1/(ν−d−1)·Λ, which is the mean of the variance in the posterior
|
||||
distribution. If the number of degrees of freedom is less than d, then NaNs
|
||||
are returned. */
|
||||
void
|
||||
NormalConj::getVariance(TwoDMatrix &v) const
|
||||
{
|
||||
if (nu > getDim()+1)
|
||||
{
|
||||
v = const_cast<const TwoDMatrix &>(lambda);
|
||||
v.mult(1.0/(nu-getDim()-1));
|
||||
}
|
||||
else
|
||||
v.nans();
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2007 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Conjugate family for normal distribution
|
||||
|
||||
/* The main purpose here is to implement a class representing conjugate
|
||||
distributions for mean and variance of the normal distribution. The class
|
||||
has two main methods: the first one is to update itself with respect to one
|
||||
observation, the second one is to update itself with respect to anothe
|
||||
object of the class. In the both methods, the previous state of the class
|
||||
corresponds to the prior distribution, and the final state corresponds to
|
||||
the posterior distribution.
|
||||
|
||||
The algebra can be found in Gelman, Carlin, Stern, Rubin (p.87). It goes as
|
||||
follows. Prior conjugate distribution takes the following form:
|
||||
|
||||
Σ ↝ InvWishart_ν₀(Λ₀⁻¹)
|
||||
μ|Σ ↝ 𝒩(μ₀,Σ/κ₀)
|
||||
|
||||
If the observations are y₁…yₙ, then the posterior distribution has the same
|
||||
form with the following parameters:
|
||||
|
||||
κ₀ n
|
||||
μₙ = ──── μ₀ + ──── ȳ
|
||||
κ₀+n κ₀+n
|
||||
|
||||
κₙ = κ₀ + n
|
||||
|
||||
νₙ = ν₀ + n
|
||||
|
||||
κ₀·n
|
||||
Λₙ = Λ₀ + S + ──── (ȳ − μ₀)(ȳ − μ₀)ᵀ
|
||||
κ₀+n
|
||||
|
||||
where
|
||||
|
||||
1 ₙ
|
||||
ȳ = ─ ∑ yᵢ
|
||||
n ⁱ⁼¹
|
||||
|
||||
ₙ
|
||||
S = ∑ (yᵢ − ȳ)(yᵢ − ȳ)ᵀ
|
||||
ⁱ⁼¹
|
||||
*/
|
||||
|
||||
#ifndef NORMAL_CONJUGATE_H
|
||||
#define NORMAL_CONJUGATE_H
|
||||
|
||||
#include "twod_matrix.hh"
|
||||
|
||||
/* The class is described by the four parameters: μ, κ, ν and Λ. */
|
||||
|
||||
class NormalConj
|
||||
{
|
||||
protected:
|
||||
Vector mu;
|
||||
int kappa;
|
||||
int nu;
|
||||
TwoDMatrix lambda;
|
||||
public:
|
||||
/* We provide the following constructors: The first constructs diffuse
|
||||
(Jeffrey’s) prior. It sets κ and Λ to zeros, ν to −1 and also the mean μ
|
||||
to zero (it should not be referenced). The second constructs the posterior
|
||||
using the diffuse prior and the observed data (columnwise). The third is a
|
||||
copy constructor. */
|
||||
NormalConj(int d);
|
||||
NormalConj(const ConstTwoDMatrix &ydata);
|
||||
NormalConj(const NormalConj &) = default;
|
||||
NormalConj(NormalConj &&) = default;
|
||||
|
||||
virtual ~NormalConj() = default;
|
||||
void update(const ConstVector &y);
|
||||
void update(const ConstTwoDMatrix &ydata);
|
||||
void update(const NormalConj &nc);
|
||||
int
|
||||
getDim() const
|
||||
{
|
||||
return mu.length();
|
||||
}
|
||||
const Vector &
|
||||
getMean() const
|
||||
{
|
||||
return mu;
|
||||
}
|
||||
void getVariance(TwoDMatrix &v) const;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "seed_generator.hh"
|
||||
|
||||
#include <limits>
|
||||
#include <mutex>
|
||||
|
||||
namespace seed_generator
|
||||
{
|
||||
std::mutex mut;
|
||||
|
||||
std::mt19937 rng;
|
||||
|
||||
std::uniform_int_distribution<std::mt19937::result_type> seed_generator(std::numeric_limits<std::mt19937::result_type>::min(),
|
||||
std::numeric_limits<std::mt19937::result_type>::max());
|
||||
|
||||
std::mt19937::result_type
|
||||
get_new_seed()
|
||||
{
|
||||
std::lock_guard<std::mutex> lk{mut};
|
||||
return seed_generator(rng);
|
||||
}
|
||||
|
||||
void
|
||||
set_meta_seed(std::mt19937::result_type s)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk{mut};
|
||||
rng.seed(s);
|
||||
}
|
||||
};
|
|
@ -1,487 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2004 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <chrono>
|
||||
#include <random>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "korder.hh"
|
||||
#include "SylvException.hh"
|
||||
|
||||
struct Rand
|
||||
{
|
||||
static std::mt19937 mtgen;
|
||||
static std::uniform_real_distribution<> dis;
|
||||
static void init(int n1, int n2, int n3, int n4, int n5);
|
||||
static double get(double m);
|
||||
static int get(int m);
|
||||
static bool discrete(double prob); // answers true with given probability
|
||||
};
|
||||
|
||||
std::mt19937 Rand::mtgen;
|
||||
std::uniform_real_distribution<> Rand::dis;
|
||||
|
||||
ConstTwoDMatrix
|
||||
make_matrix(int rows, int cols, const double *p)
|
||||
{
|
||||
return ConstTwoDMatrix{rows, cols, ConstVector{p, rows*cols}};
|
||||
}
|
||||
|
||||
void
|
||||
Rand::init(int n1, int n2, int n3, int n4, int n5)
|
||||
{
|
||||
decltype(mtgen)::result_type seed = n1;
|
||||
seed = 256*seed+n2;
|
||||
seed = 256*seed+n3;
|
||||
seed = 256*seed+n4;
|
||||
seed = 256*seed+n5;
|
||||
mtgen.seed(seed);
|
||||
}
|
||||
|
||||
double
|
||||
Rand::get(double m)
|
||||
{
|
||||
return 2*m*(dis(mtgen)-0.5);
|
||||
}
|
||||
|
||||
int
|
||||
Rand::get(int m)
|
||||
{
|
||||
return static_cast<int>(get(0.9999*m));
|
||||
}
|
||||
|
||||
bool
|
||||
Rand::discrete(double prob)
|
||||
{
|
||||
return dis(mtgen) < prob;
|
||||
}
|
||||
|
||||
struct SparseGenerator
|
||||
{
|
||||
static std::unique_ptr<FSSparseTensor> makeTensor(int dim, int nv, int r,
|
||||
double fill, double m);
|
||||
static void fillContainer(TensorContainer<FSSparseTensor> &c,
|
||||
int maxdim, int nv, int r, double m);
|
||||
};
|
||||
|
||||
std::unique_ptr<FSSparseTensor>
|
||||
SparseGenerator::makeTensor(int dim, int nv, int r,
|
||||
double fill, double m)
|
||||
{
|
||||
auto res = std::make_unique<FSSparseTensor>(dim, nv, r);
|
||||
FFSTensor dummy(0, nv, dim);
|
||||
for (Tensor::index fi = dummy.begin(); fi != dummy.end(); ++fi)
|
||||
for (int i = 0; i < r; i++)
|
||||
if (Rand::discrete(fill))
|
||||
{
|
||||
double x = Rand::get(m);
|
||||
res->insert(fi.getCoor(), i, x);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
SparseGenerator::fillContainer(TensorContainer<FSSparseTensor> &c,
|
||||
int maxdim, int nv, int r,
|
||||
double m)
|
||||
{
|
||||
Rand::init(maxdim, nv, r, static_cast<int>(5*m), 0);
|
||||
double fill = 0.5;
|
||||
for (int d = 1; d <= maxdim; d++)
|
||||
{
|
||||
c.insert(makeTensor(d, nv, r, fill, m));
|
||||
fill *= 0.3;
|
||||
}
|
||||
}
|
||||
|
||||
const double vdata[] =
|
||||
{ // 3x3
|
||||
0.1307870268, 0.1241940078, 0.1356703123,
|
||||
0.1241940078, 0.1986920419, 0.2010160581,
|
||||
0.1356703123, 0.2010160581, 0.2160336975
|
||||
};
|
||||
|
||||
const double gy_data[] =
|
||||
{ // 8x4
|
||||
0.3985178619, -0.5688233582, 0.9572900437, -0.6606847776, 0.1453004017,
|
||||
0.3025310675, -0.8627437750, -0.6903410191, 0.4751910580, -0.7270018589,
|
||||
-0.0939612498, -0.1463831989, 0.6742110220, 0.6046671043, 0.5215893126,
|
||||
-1.0412969986, -0.3524898417, -1.0986703430, 0.8006531522, 0.8879776376,
|
||||
-0.1037608317, -0.5587378073, -0.1010366945, 0.9462411248, -0.2439199881,
|
||||
1.3420621236, -0.7820285935, 0.3205293447, 0.3606124791, 0.2975422208,
|
||||
-0.5452861965, 1.6320340279
|
||||
};
|
||||
|
||||
const double gu_data[] =
|
||||
{ // just some numbers, no structure
|
||||
1.8415286914, -0.2638743845, 1.7690713274, 0.9668585956, 0.2303143646,
|
||||
-0.2229624279, -0.4381991822, 1.0082401405, -0.3186555860, -0.0624691529,
|
||||
-0.5189085756, 1.4269672156, 0.1163282969, 1.4020183445, -0.0952660426,
|
||||
0.2099097124, 0.6912400502, -0.5180935114, 0.5288316624, 0.2188053448,
|
||||
0.5715516767, 0.7813893410, -0.6385073106, 0.8335131513, 0.3605202168,
|
||||
-1.1167944865, -1.2263750934, 0.6113636081, 0.6964915482, -0.6451217688,
|
||||
0.4062810500, -2.0552251116, -1.6383406284, 0.0198915095, 0.0111014458,
|
||||
-1.2421792262, -1.0724161722, -0.4276904972, 0.1801494950, -2.0716473264
|
||||
};
|
||||
|
||||
const double vdata2[] =
|
||||
{ // 10×10 positive definite
|
||||
0.79666, -0.15536, 0.05667, -0.21026, 0.20262, 0.28505, 0.60341, -0.09703, 0.32363, 0.13299,
|
||||
-0.15536, 0.64380, -0.01131, 0.00980, 0.03755, 0.43791, 0.21784, -0.31755, -0.55911, -0.29655,
|
||||
0.05667, -0.01131, 0.56165, -0.34357, -0.40584, 0.20990, 0.28348, 0.20398, -0.19856, 0.35820,
|
||||
-0.21026, 0.00980, -0.34357, 0.56147, 0.10972, -0.34146, -0.49906, -0.19685, 0.21088, -0.31560,
|
||||
0.20262, 0.03755, -0.40584, 0.10972, 0.72278, 0.02155, 0.04089, -0.19696, 0.03446, -0.12919,
|
||||
0.28505, 0.43791, 0.20990, -0.34146, 0.02155, 0.75867, 0.77699, -0.31125, -0.55141, -0.02155,
|
||||
0.60341, 0.21784, 0.28348, -0.49906, 0.04089, 0.77699, 1.34553, -0.18613, -0.25811, -0.19016,
|
||||
-0.09703, -0.31755, 0.20398, -0.19685, -0.19696, -0.31125, -0.18613, 0.59470, 0.08386, 0.41750,
|
||||
0.32363, -0.55911, -0.19856, 0.21088, 0.03446, -0.55141, -0.25811, 0.08386, 0.98917, -0.12992,
|
||||
0.13299, -0.29655, 0.35820, -0.31560, -0.12919, -0.02155, -0.19016, 0.41750, -0.12992, 0.89608
|
||||
};
|
||||
|
||||
const double gy_data2[] =
|
||||
{ // 600 items make gy 30×20, whose gy(6:25,:) has spectrum within unit
|
||||
0.39414, -0.29766, 0.08948, -0.19204, -0.00750, 0.21159, 0.05494, 0.06225, 0.01771, 0.21913,
|
||||
-0.01373, 0.20086, -0.06086, -0.10955, 0.14424, -0.08390, 0.03948, -0.14713, 0.11674, 0.05091,
|
||||
0.24039, 0.28307, -0.11835, 0.13030, 0.11682, -0.27444, -0.19311, -0.16654, 0.12867, 0.25116,
|
||||
-0.19781, 0.45242, -0.15862, 0.24428, -0.11966, 0.11483, -0.32279, 0.29727, 0.20934, -0.18190,
|
||||
-0.15080, -0.09477, -0.30551, -0.02672, -0.26919, 0.11165, -0.06390, 0.03449, -0.26622, 0.22197,
|
||||
0.45141, -0.41683, 0.09760, 0.31094, -0.01652, 0.05809, -0.04514, -0.05645, 0.00554, 0.47980,
|
||||
0.11726, 0.42459, -0.13136, -0.30902, -0.14648, 0.11455, 0.02947, -0.03835, -0.04044, 0.03559,
|
||||
-0.26575, -0.01783, 0.31243, -0.14412, -0.13218, -0.05080, 0.18576, 0.13840, -0.05560, 0.35530,
|
||||
-0.25573, -0.11560, 0.15187, -0.18431, 0.08193, -0.32278, 0.17560, -0.05529, -0.10020, -0.23088,
|
||||
-0.20979, -0.49245, 0.09915, -0.16909, -0.03443, 0.19497, 0.18473, 0.25662, 0.29605, -0.20531,
|
||||
-0.39244, -0.43369, 0.05588, 0.24823, -0.14236, -0.08311, 0.16371, -0.19975, 0.30605, -0.17087,
|
||||
-0.01270, 0.00123, -0.22426, -0.13810, 0.05079, 0.06971, 0.01922, -0.09952, -0.23177, -0.41962,
|
||||
-0.41991, 0.41430, -0.04247, -0.13706, -0.12048, -0.28906, -0.22813, -0.25057, -0.18579, -0.20642,
|
||||
-0.47976, 0.25490, -0.05138, -0.30794, 0.31651, 0.02034, 0.12954, -0.20110, 0.13336, -0.40775,
|
||||
-0.30195, -0.13704, 0.12396, 0.28152, 0.02986, 0.27669, 0.24623, 0.08635, -0.11956, -0.02949,
|
||||
0.37401, 0.20838, 0.24801, -0.26872, 0.11195, 0.00315, -0.19069, 0.12839, -0.23036, -0.48228,
|
||||
0.08434, -0.39872, -0.28896, -0.28754, 0.24668, 0.23285, 0.25437, 0.10456, -0.14124, 0.20483,
|
||||
-0.19117, -0.33836, -0.24875, 0.08207, -0.03930, 0.20364, 0.15384, -0.15270, 0.24372, -0.11199,
|
||||
-0.46591, 0.30319, 0.05745, 0.09084, 0.06058, 0.31884, 0.05071, -0.28899, -0.30793, -0.03566,
|
||||
0.02286, 0.28178, 0.00736, -0.31378, -0.18144, -0.22346, -0.27239, 0.31043, -0.26228, 0.22181,
|
||||
-0.15096, -0.36953, -0.06032, 0.21496, 0.29545, -0.13112, 0.16420, -0.07573, -0.43111, -0.43057,
|
||||
0.26716, -0.31209, -0.05866, -0.29101, -0.27437, -0.18727, 0.28732, -0.19014, 0.08837, 0.30405,
|
||||
0.06103, -0.35612, 0.00173, 0.25134, -0.08987, -0.22766, -0.03254, -0.18662, -0.08491, 0.49401,
|
||||
-0.12145, -0.02961, -0.03668, -0.30043, -0.08555, 0.01701, -0.12544, 0.10969, -0.48202, 0.07245,
|
||||
0.20673, 0.11408, 0.04343, -0.01815, -0.31594, -0.23632, -0.06258, -0.27474, 0.12180, 0.16613,
|
||||
-0.37931, 0.30219, 0.15765, 0.25489, 0.17529, -0.17020, -0.30060, 0.22058, -0.02450, -0.42143,
|
||||
0.49642, 0.46899, -0.28552, -0.22549, -0.01333, 0.21567, 0.22251, 0.21639, -0.19194, -0.19140,
|
||||
-0.24106, 0.10952, -0.11019, 0.29763, -0.02039, -0.25748, 0.23169, 0.01357, 0.09802, -0.19022,
|
||||
0.37604, -0.40777, 0.18131, -0.10258, 0.29573, -0.31773, 0.09069, -0.02198, -0.26594, 0.48302,
|
||||
-0.10041, 0.20210, -0.05609, -0.01169, -0.17339, 0.17862, -0.22502, 0.29009, -0.45160, 0.19771,
|
||||
0.27634, 0.31695, -0.09993, 0.17167, 0.12394, 0.28088, -0.12502, -0.16967, -0.06296, -0.17036,
|
||||
0.27320, 0.01595, 0.16955, 0.30146, -0.15173, -0.29807, 0.08178, -0.06811, 0.21655, 0.26348,
|
||||
0.06316, 0.45661, -0.29756, -0.05742, -0.14715, -0.03037, -0.16656, -0.08768, 0.38078, 0.40679,
|
||||
-0.32779, -0.09106, 0.16107, -0.07301, 0.07700, -0.22694, -0.15692, -0.02548, 0.38749, -0.12203,
|
||||
-0.02980, -0.22067, 0.00680, -0.23058, -0.29112, 0.23032, -0.16026, 0.23392, -0.09990, 0.03628,
|
||||
-0.42592, -0.33474, -0.09499, -0.17442, -0.20110, 0.24618, -0.06418, -0.06715, 0.40754, 0.29377,
|
||||
0.29543, -0.16832, -0.08468, 0.06491, -0.01410, 0.19988, 0.24950, 0.14626, -0.27851, 0.06079,
|
||||
0.48134, -0.13475, 0.25398, 0.11738, 0.23369, -0.00661, -0.16811, -0.04557, -0.12030, -0.39527,
|
||||
-0.35760, 0.01840, -0.15941, 0.03290, 0.09988, -0.08307, 0.06644, -0.24637, 0.34112, -0.08026,
|
||||
0.00951, 0.27656, 0.16247, 0.28217, 0.17198, -0.16389, -0.03835, -0.02675, -0.08032, -0.21045,
|
||||
-0.38946, 0.23207, 0.10987, -0.31674, -0.28653, -0.27430, -0.29109, -0.00648, 0.38431, -0.38478,
|
||||
-0.41195, -0.19364, -0.20977, -0.05524, 0.05558, -0.20109, 0.11803, -0.19884, 0.43318, -0.39255,
|
||||
0.26612, -0.21771, 0.12471, 0.12856, -0.15104, -0.11676, 0.17582, -0.25330, 0.00298, -0.31712,
|
||||
0.21532, -0.20319, 0.14507, -0.04588, -0.22995, -0.06470, 0.18849, -0.13444, 0.37107, 0.07387,
|
||||
-0.14008, 0.09896, 0.13727, -0.28417, -0.09461, -0.18703, 0.04080, 0.02343, -0.49988, 0.17993,
|
||||
0.23189, -0.30581, -0.18334, -0.09667, -0.27699, -0.05998, 0.09118, -0.32453, 0.46251, 0.41500,
|
||||
-0.45314, -0.00544, 0.08529, 0.29099, -0.00937, -0.31650, 0.26163, 0.14506, 0.37498, -0.16454,
|
||||
0.35215, 0.31642, -0.09161, -0.31452, -0.04792, -0.04677, -0.19523, 0.27998, 0.05491, 0.44461,
|
||||
-0.01258, -0.27887, 0.18361, -0.04539, -0.02977, 0.30821, 0.29454, -0.17932, 0.16193, 0.23934,
|
||||
0.47923, 0.25373, 0.23258, 0.31484, -0.17958, -0.01136, 0.17681, 0.12869, 0.03235, 0.43762,
|
||||
0.13734, -0.09433, -0.03735, 0.17949, 0.14122, -0.17814, 0.06359, 0.16044, 0.12249, -0.22314,
|
||||
0.40775, 0.05147, 0.12389, 0.04290, -0.01642, 0.00082, -0.18056, 0.02875, 0.32690, 0.17712,
|
||||
0.34001, -0.21581, -0.01086, -0.18180, 0.17480, -0.17774, -0.07503, 0.28438, -0.19747, 0.29595,
|
||||
-0.28002, -0.02073, -0.16522, -0.18234, -0.20565, 0.29620, 0.07502, 0.01429, -0.31418, 0.43693,
|
||||
-0.12212, 0.11178, -0.28503, 0.04683, 0.00072, 0.05566, 0.18857, 0.26101, -0.38891, -0.21216,
|
||||
-0.21850, -0.15147, -0.30749, -0.23762, 0.14984, 0.03535, -0.02862, -0.00105, -0.39907, -0.06909,
|
||||
-0.36094, 0.21717, 0.15930, -0.18924, 0.13741, 0.01039, 0.13613, 0.00659, 0.07676, -0.13711,
|
||||
0.24285, -0.07564, -0.28349, -0.15658, 0.03135, -0.30909, -0.22534, 0.17363, -0.19376, 0.26038,
|
||||
0.05546, -0.22607, 0.32420, -0.02552, -0.05400, 0.13388, 0.04643, -0.31535, -0.06181, 0.30237,
|
||||
-0.04680, -0.29441, 0.12231, 0.03960, -0.01188, 0.01406, 0.25402, 0.03315, 0.25026, -0.10922
|
||||
};
|
||||
|
||||
const double gu_data2[] =
|
||||
{ // raw data 300 items
|
||||
0.26599, 0.41329, 0.31846, 0.92590, 0.43050, 0.17466, 0.02322, 0.72621, 0.37921, 0.70597,
|
||||
0.97098, 0.14023, 0.57619, 0.09938, 0.02281, 0.92341, 0.72654, 0.71000, 0.76687, 0.70182,
|
||||
0.88752, 0.49524, 0.42549, 0.42806, 0.57615, 0.76051, 0.15341, 0.47457, 0.60066, 0.40880,
|
||||
0.20668, 0.41949, 0.97620, 0.94318, 0.71491, 0.56402, 0.23553, 0.94387, 0.78567, 0.06362,
|
||||
0.85252, 0.86262, 0.25190, 0.03274, 0.93216, 0.37971, 0.08797, 0.14596, 0.73871, 0.06574,
|
||||
0.67447, 0.28575, 0.43911, 0.92133, 0.12327, 0.87762, 0.71060, 0.07141, 0.55443, 0.53310,
|
||||
0.91529, 0.25121, 0.07593, 0.94490, 0.28656, 0.82174, 0.68887, 0.67337, 0.99291, 0.03316,
|
||||
0.02849, 0.33891, 0.25594, 0.90071, 0.01248, 0.67871, 0.65953, 0.65369, 0.97574, 0.31578,
|
||||
0.23678, 0.39220, 0.06706, 0.80943, 0.57694, 0.08220, 0.18151, 0.19969, 0.37096, 0.37858,
|
||||
0.70153, 0.46816, 0.76511, 0.02520, 0.39387, 0.25527, 0.39050, 0.60141, 0.30322, 0.46195,
|
||||
0.12025, 0.33616, 0.04174, 0.00196, 0.68886, 0.74445, 0.15869, 0.18994, 0.95195, 0.62874,
|
||||
0.82874, 0.53369, 0.34383, 0.50752, 0.97023, 0.22695, 0.62407, 0.25840, 0.71279, 0.28785,
|
||||
0.31611, 0.20391, 0.19702, 0.40760, 0.85158, 0.68369, 0.63760, 0.09879, 0.11924, 0.32920,
|
||||
0.53052, 0.15900, 0.21229, 0.84080, 0.33933, 0.93651, 0.42705, 0.06199, 0.50092, 0.47192,
|
||||
0.57152, 0.01818, 0.31404, 0.50173, 0.87725, 0.50530, 0.10717, 0.04035, 0.32901, 0.33538,
|
||||
0.04780, 0.40984, 0.78216, 0.91288, 0.11314, 0.25248, 0.23823, 0.74001, 0.48089, 0.55531,
|
||||
0.82486, 0.01058, 0.05409, 0.44357, 0.52641, 0.68188, 0.94629, 0.61627, 0.33037, 0.11961,
|
||||
0.57988, 0.19653, 0.91902, 0.59838, 0.52974, 0.28364, 0.45767, 0.65836, 0.63045, 0.76140,
|
||||
0.27918, 0.27256, 0.46035, 0.77418, 0.92918, 0.14095, 0.89645, 0.25146, 0.21172, 0.47910,
|
||||
0.95451, 0.34377, 0.29927, 0.79220, 0.97654, 0.67591, 0.44385, 0.38434, 0.44860, 0.28170,
|
||||
0.90712, 0.20337, 0.00292, 0.55046, 0.62255, 0.45127, 0.80896, 0.43965, 0.59145, 0.23801,
|
||||
0.33601, 0.30119, 0.89935, 0.40850, 0.98226, 0.75430, 0.68318, 0.65407, 0.68067, 0.32942,
|
||||
0.11756, 0.27626, 0.83879, 0.72174, 0.75430, 0.13702, 0.03402, 0.58781, 0.07393, 0.23067,
|
||||
0.92537, 0.29445, 0.43437, 0.47685, 0.54548, 0.66082, 0.23805, 0.60208, 0.94337, 0.21363,
|
||||
0.72637, 0.57181, 0.77679, 0.63931, 0.72860, 0.38901, 0.94920, 0.04535, 0.12863, 0.40550,
|
||||
0.90095, 0.21418, 0.13953, 0.99639, 0.02526, 0.70018, 0.21828, 0.20294, 0.20191, 0.30954,
|
||||
0.39490, 0.68955, 0.11506, 0.15748, 0.40252, 0.91680, 0.61547, 0.78443, 0.19693, 0.67630,
|
||||
0.56552, 0.58556, 0.53554, 0.53507, 0.09831, 0.21229, 0.83135, 0.26375, 0.89287, 0.97069,
|
||||
0.70615, 0.42041, 0.43117, 0.21291, 0.26086, 0.26978, 0.77340, 0.43833, 0.46179, 0.54418,
|
||||
0.67878, 0.42776, 0.61454, 0.55915, 0.36363, 0.31999, 0.42442, 0.86649, 0.62513, 0.02047
|
||||
};
|
||||
|
||||
class TestRunnable
|
||||
{
|
||||
public:
|
||||
const std::string name;
|
||||
int dim; // dimension of the solved problem
|
||||
int nvar; // number of variable of the solved problem
|
||||
TestRunnable(std::string n, int d, int nv)
|
||||
: name{std::move(n)}, dim(d), nvar(nv)
|
||||
{
|
||||
}
|
||||
virtual ~TestRunnable() = default;
|
||||
bool test() const;
|
||||
virtual bool run() const = 0;
|
||||
protected:
|
||||
static double korder_unfold_fold(int maxdim, int unfold_dim,
|
||||
int nstat, int npred, int nboth, int forw,
|
||||
const TwoDMatrix &gy, const TwoDMatrix &gu,
|
||||
const TwoDMatrix &v);
|
||||
};
|
||||
|
||||
bool
|
||||
TestRunnable::test() const
|
||||
{
|
||||
std::cout << "Running test <" << name << ">" << std::endl;
|
||||
clock_t start = clock();
|
||||
auto start_real = std::chrono::steady_clock::now();
|
||||
bool passed = run();
|
||||
clock_t end = clock();
|
||||
auto end_real = std::chrono::steady_clock::now();
|
||||
std::chrono::duration<double> duration = end_real - start_real;
|
||||
std::cout << "CPU time " << std::setprecision(4) << std::setw(8)
|
||||
<< static_cast<double>(end-start)/CLOCKS_PER_SEC << " (CPU seconds)\n"
|
||||
<< "Real time " << std::setw(8) << duration.count() << " (seconds).....................";
|
||||
if (passed)
|
||||
std::cout << "passed\n\n";
|
||||
else
|
||||
std::cout << "FAILED\n\n";
|
||||
return passed;
|
||||
}
|
||||
|
||||
double
|
||||
TestRunnable::korder_unfold_fold(int maxdim, int unfold_dim,
|
||||
int nstat, int npred, int nboth, int nforw,
|
||||
const TwoDMatrix &gy, const TwoDMatrix &gu,
|
||||
const TwoDMatrix &v)
|
||||
{
|
||||
TensorContainer<FSSparseTensor> c(1);
|
||||
int ny = nstat+npred+nboth+nforw;
|
||||
int nu = v.nrows();
|
||||
int nz = nboth+nforw+ny+nboth+npred+nu;
|
||||
SparseGenerator::fillContainer(c, maxdim, nz, ny, 5.0);
|
||||
for (int d = 1; d <= maxdim; d++)
|
||||
std::cout << "\ttensor fill for dim=" << d << " is: "
|
||||
<< std::setprecision(2) << std::setw(6) << std::fixed
|
||||
<< c.get(Symmetry{d}).getFillFactor()*100.0 << " %\n"
|
||||
<< std::defaultfloat;
|
||||
Journal jr("out.txt");
|
||||
KOrder kord(nstat, npred, nboth, nforw, c, gy, gu, v, jr);
|
||||
// Perform unfolded steps until unfold_dim
|
||||
double maxerror = 0.0;
|
||||
for (int d = 2; d <= unfold_dim; d++)
|
||||
{
|
||||
clock_t pertime = clock();
|
||||
kord.performStep<Storage::unfold>(d);
|
||||
pertime = clock()-pertime;
|
||||
std::cout << "\ttime for unfolded step dim=" << d << ": " << std::setprecision(4)
|
||||
<< static_cast<double>(pertime)/CLOCKS_PER_SEC << std::endl;
|
||||
clock_t checktime = clock();
|
||||
double err = kord.check<Storage::unfold>(d);
|
||||
checktime = clock()-checktime;
|
||||
std::cout << "\ttime for step check dim=" << d << ": " << std::setprecision(4)
|
||||
<< static_cast<double>(checktime)/CLOCKS_PER_SEC << '\n'
|
||||
<< "\tmax error in step dim=" << d << ": " << std::setprecision(6) << err
|
||||
<< std::endl;
|
||||
maxerror = std::max(err, maxerror);
|
||||
}
|
||||
// Perform folded steps until maxdim
|
||||
if (unfold_dim < maxdim)
|
||||
{
|
||||
clock_t swtime = clock();
|
||||
kord.switchToFolded();
|
||||
swtime = clock()-swtime;
|
||||
std::cout << "\ttime for switching dim=" << unfold_dim << ": " << std::setprecision(4)
|
||||
<< static_cast<double>(swtime)/CLOCKS_PER_SEC << std::endl;
|
||||
|
||||
for (int d = unfold_dim+1; d <= maxdim; d++)
|
||||
{
|
||||
clock_t pertime = clock();
|
||||
kord.performStep<Storage::fold>(d);
|
||||
pertime = clock()-pertime;
|
||||
std::cout << "\ttime for folded step dim=" << d << ": " << std::setprecision(4)
|
||||
<< static_cast<double>(pertime)/CLOCKS_PER_SEC << std::endl;
|
||||
clock_t checktime = clock();
|
||||
double err = kord.check<Storage::fold>(d);
|
||||
checktime = clock()-checktime;
|
||||
std::cout << "\ttime for step check dim=" << d << ": " << std::setprecision(4)
|
||||
<< static_cast<double>(checktime)/CLOCKS_PER_SEC << '\n'
|
||||
<< "\tmax error in step dim=" << d << ": " << std::setprecision(6) << err
|
||||
<< std::endl;
|
||||
maxerror = std::max(err, maxerror);
|
||||
}
|
||||
}
|
||||
return maxerror;
|
||||
}
|
||||
|
||||
class UnfoldKOrderSmall : public TestRunnable
|
||||
{
|
||||
public:
|
||||
UnfoldKOrderSmall()
|
||||
: TestRunnable("unfold-3 fold-4 korder (stat=2,pred=3,both=1,forw=2,u=3,dim=4)",
|
||||
4, 18)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
run() const override
|
||||
{
|
||||
TwoDMatrix gy{make_matrix(8, 4, gy_data)};
|
||||
TwoDMatrix gu{make_matrix(8, 3, gu_data)};
|
||||
TwoDMatrix v{make_matrix(3, 3, vdata)};
|
||||
double err = korder_unfold_fold(4, 3, 2, 3, 1, 2,
|
||||
gy, gu, v);
|
||||
|
||||
return err < 5e-7;
|
||||
}
|
||||
};
|
||||
|
||||
// Same dimension as Smets & Wouters
|
||||
class UnfoldKOrderSW : public TestRunnable
|
||||
{
|
||||
public:
|
||||
UnfoldKOrderSW()
|
||||
: TestRunnable("unfold S&W korder (stat=5,pred=12,both=8,forw=5,u=10,dim=4)",
|
||||
4, 73)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
run() const override
|
||||
{
|
||||
TwoDMatrix gy{make_matrix(30, 20, gy_data2)};
|
||||
TwoDMatrix gu{make_matrix(30, 10, gu_data2)};
|
||||
TwoDMatrix v{make_matrix(10, 10, vdata2)};
|
||||
v.mult(0.001);
|
||||
gu.mult(.01);
|
||||
double err = korder_unfold_fold(4, 4, 5, 12, 8, 5,
|
||||
gy, gu, v);
|
||||
|
||||
return err < 0.5;
|
||||
}
|
||||
};
|
||||
|
||||
class UnfoldFoldKOrderSW : public TestRunnable
|
||||
{
|
||||
public:
|
||||
UnfoldFoldKOrderSW()
|
||||
: TestRunnable("unfold-2 fold-3 S&W korder (stat=5,pred=12,both=8,forw=5,u=10,dim=3)",
|
||||
4, 73)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
run() const override
|
||||
{
|
||||
TwoDMatrix gy{make_matrix(30, 20, gy_data2)};
|
||||
TwoDMatrix gu{make_matrix(30, 10, gu_data2)};
|
||||
TwoDMatrix v{make_matrix(10, 10, vdata2)};
|
||||
v.mult(0.001);
|
||||
gu.mult(.01);
|
||||
double err = korder_unfold_fold(4, 3, 5, 12, 8, 5,
|
||||
gy, gu, v);
|
||||
|
||||
return err < 0.5;
|
||||
}
|
||||
};
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
std::vector<std::unique_ptr<TestRunnable>> all_tests;
|
||||
// Fill in vector of all tests
|
||||
all_tests.push_back(std::make_unique<UnfoldKOrderSmall>());
|
||||
all_tests.push_back(std::make_unique<UnfoldKOrderSW>());
|
||||
all_tests.push_back(std::make_unique<UnfoldFoldKOrderSW>());
|
||||
|
||||
// Find maximum dimension and maximum nvar
|
||||
int dmax = 0;
|
||||
int nvmax = 0;
|
||||
for (const auto &test : all_tests)
|
||||
{
|
||||
if (dmax < test->dim)
|
||||
dmax = test->dim;
|
||||
if (nvmax < test->nvar)
|
||||
nvmax = test->nvar;
|
||||
}
|
||||
TLStatic::init(dmax, nvmax); // initialize library
|
||||
|
||||
// Launch the tests
|
||||
int success = 0;
|
||||
for (const auto &test : all_tests)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (test->test())
|
||||
success++;
|
||||
}
|
||||
catch (const TLException &e)
|
||||
{
|
||||
std::cout << "Caught TL exception in <" << test->name << ">:" << std::endl;
|
||||
e.print();
|
||||
}
|
||||
catch (SylvException &e)
|
||||
{
|
||||
std::cout << "Caught Sylv exception in <" << test->name << ">:" << std::endl;
|
||||
e.printMessage();
|
||||
}
|
||||
}
|
||||
|
||||
int nfailed = all_tests.size() - success;
|
||||
std::cout << "There were " << nfailed << " tests that failed out of "
|
||||
<< all_tests.size() << " tests run." << std::endl;
|
||||
|
||||
if (nfailed)
|
||||
return EXIT_FAILURE;
|
||||
else
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
noinst_LIBRARIES = libparser.a
|
||||
|
||||
GENERATED_FILES = assign_tab.cc formula_tab.cc matrix_tab.cc assign_tab.hh formula_tab.hh matrix_tab.hh assign_ll.cc formula_ll.cc matrix_ll.cc
|
||||
|
||||
libparser_a_SOURCES = \
|
||||
location.hh \
|
||||
atom_assignings.cc \
|
||||
atom_assignings.hh \
|
||||
atom_substitutions.cc \
|
||||
atom_substitutions.hh \
|
||||
dynamic_atoms.cc \
|
||||
dynamic_atoms.hh \
|
||||
fine_atoms.cc \
|
||||
fine_atoms.hh \
|
||||
formula_parser.cc \
|
||||
formula_parser.hh \
|
||||
matrix_parser.cc \
|
||||
matrix_parser.hh \
|
||||
parser_exception.cc \
|
||||
parser_exception.hh \
|
||||
static_atoms.cc \
|
||||
static_atoms.hh \
|
||||
static_fine_atoms.cc \
|
||||
static_fine_atoms.hh \
|
||||
tree.cc \
|
||||
tree.hh \
|
||||
$(GENERATED_FILES)
|
||||
|
||||
libparser_a_CPPFLAGS = -I../.. $(BOOST_CPPFLAGS)
|
||||
|
||||
BUILT_SOURCES = $(GENERATED_FILES)
|
||||
|
||||
EXTRA_DIST = assign.yy formula.yy matrix.yy assign.ll formula.ll matrix.ll
|
||||
|
||||
%_tab.cc %_tab.hh: %.yy
|
||||
$(YACC) -W -o$*_tab.cc $<
|
||||
|
||||
%_tab.$(OBJEXT): CXXFLAGS += -Wno-old-style-cast
|
||||
|
||||
%_ll.cc: %.ll
|
||||
$(LEX) -i -o$@ $<
|
||||
|
||||
%_ll.$(OBJEXT): CXXFLAGS += -Wno-old-style-cast
|
|
@ -1,74 +0,0 @@
|
|||
/* -*- C++ -*- */
|
||||
/*
|
||||
* Copyright © 2004-2011 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
%{
|
||||
#include "location.hh"
|
||||
#include "assign_tab.hh"
|
||||
|
||||
#define YY_USER_ACTION SET_LLOC(asgn_);
|
||||
%}
|
||||
|
||||
%option nounput
|
||||
%option noyy_top_state
|
||||
%option stack
|
||||
%option yylineno
|
||||
%option prefix="asgn_"
|
||||
%option never-interactive
|
||||
%x CMT
|
||||
|
||||
%%
|
||||
|
||||
/* comments */
|
||||
<*>"/*" {yy_push_state(CMT);}
|
||||
<CMT>[^*\n]*
|
||||
<CMT>"*"+[^*/\n]*
|
||||
<CMT>"*"+"/" {yy_pop_state();}
|
||||
<CMT>[\n]
|
||||
"//".*\n
|
||||
|
||||
/* spaces */
|
||||
[ \t\r\n] {return BLANK;}
|
||||
|
||||
/* names */
|
||||
[A-Za-z_][A-Za-z0-9_]* {
|
||||
asgn_lval.string = asgn_text;
|
||||
return NAME;
|
||||
}
|
||||
|
||||
; {return SEMICOLON;}
|
||||
= {return EQUAL_SIGN;}
|
||||
. {
|
||||
asgn_lval.character = asgn_text[0];
|
||||
return CHARACTER;
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
int
|
||||
asgn_wrap()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
asgn__destroy_buffer(void* p)
|
||||
{
|
||||
asgn__delete_buffer(static_cast<YY_BUFFER_STATE>(p));
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/*
|
||||
* Copyright © 2006-2011 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
%code requires
|
||||
{
|
||||
#include "location.hh"
|
||||
#define ASGN_LTYPE ogp::location_type
|
||||
}
|
||||
|
||||
%code
|
||||
{
|
||||
#include "atom_assignings.hh"
|
||||
#include <string>
|
||||
|
||||
void asgn_error(std::string);
|
||||
int asgn_lex();
|
||||
extern ogp::AtomAssignings* aparser;
|
||||
}
|
||||
|
||||
%union
|
||||
{
|
||||
int integer;
|
||||
char *string;
|
||||
char character;
|
||||
}
|
||||
|
||||
%token EQUAL_SIGN SEMICOLON CHARACTER BLANK
|
||||
%token <string> NAME;
|
||||
|
||||
%define api.prefix {asgn_}
|
||||
|
||||
%locations
|
||||
%defines
|
||||
%define parse.error verbose
|
||||
|
||||
%%
|
||||
|
||||
root : assignments | %empty;
|
||||
|
||||
assignments : assignments BLANK | assignments assignment | assignment | BLANK;
|
||||
|
||||
assignment : NAME EQUAL_SIGN material SEMICOLON {
|
||||
aparser->add_assignment(@1.off, $1, @1.ll, @3.off-@1.off, @3.ll + @4.ll);}
|
||||
| NAME space EQUAL_SIGN material SEMICOLON {
|
||||
aparser->add_assignment(@1.off, $1, @1.ll, @4.off-@1.off, @4.ll + @5.ll);}
|
||||
;
|
||||
|
||||
material : material CHARACTER | material NAME | material BLANK | NAME | CHARACTER | BLANK;
|
||||
|
||||
space : space BLANK | BLANK;
|
||||
|
||||
%%
|
||||
|
||||
void
|
||||
asgn_error(std::string mes)
|
||||
{
|
||||
aparser->error(std::move(mes));
|
||||
}
|
|
@ -1,254 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2006 Ondra Kamenik
|
||||
* Copyright © 2019-2022 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "atom_assignings.hh"
|
||||
#include "location.hh"
|
||||
#include "parser_exception.hh"
|
||||
|
||||
#include "utils/cc/exception.hh"
|
||||
|
||||
#include <limits>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
using namespace ogp;
|
||||
|
||||
AtomAssignings::AtomAssignings(const AtomAssignings &aa, ogp::StaticAtoms &a)
|
||||
: atoms(a), expr(aa.expr, atoms), left_names(aa.left_names),
|
||||
lname2expr(aa.lname2expr), order(aa.order)
|
||||
{
|
||||
}
|
||||
|
||||
/** A global symbol for passing info to the AtomAssignings from
|
||||
* asgn_parse(). */
|
||||
AtomAssignings *aparser;
|
||||
|
||||
/** The declaration of functions defined in asgn_ll.cc and asgn_tab.cc
|
||||
* generated from assign.lex assign.y */
|
||||
void *asgn__scan_string(const char *);
|
||||
void asgn__destroy_buffer(void *);
|
||||
void asgn_parse();
|
||||
extern location_type asgn_lloc;
|
||||
|
||||
void
|
||||
AtomAssignings::parse(const string &stream)
|
||||
{
|
||||
asgn_lloc.off = 0;
|
||||
asgn_lloc.ll = 0;
|
||||
void *p = asgn__scan_string(stream.c_str());
|
||||
aparser = this;
|
||||
asgn_parse();
|
||||
asgn__destroy_buffer(p);
|
||||
}
|
||||
|
||||
void
|
||||
AtomAssignings::error(string mes)
|
||||
{
|
||||
throw ParserException(std::move(mes), asgn_lloc.off);
|
||||
}
|
||||
|
||||
void
|
||||
AtomAssignings::add_assignment_to_double(string name, double val)
|
||||
{
|
||||
// if left hand side is a registered atom, insert it to tree
|
||||
int t;
|
||||
try
|
||||
{
|
||||
if (atoms.check(name))
|
||||
t = expr.add_nulary(name);
|
||||
else
|
||||
t = -1;
|
||||
}
|
||||
catch (const ParserException &e)
|
||||
{
|
||||
t = -1;
|
||||
}
|
||||
// register left hand side in order
|
||||
order.push_back(t);
|
||||
|
||||
// add the double to the tree
|
||||
std::ostringstream buf;
|
||||
buf << std::setprecision(std::numeric_limits<double>::max_digits10)
|
||||
<< val;
|
||||
try
|
||||
{
|
||||
expr.parse(buf.str());
|
||||
}
|
||||
catch (const ParserException &e)
|
||||
{
|
||||
// should never happen
|
||||
throw ParserException("Error parsing double "+buf.str()+": "+e.message(), 0);
|
||||
}
|
||||
|
||||
// register name of the left hand side and put to lname2expr
|
||||
left_names.insert(name);
|
||||
lname2expr.emplace(std::move(name), order.size()-1);
|
||||
}
|
||||
|
||||
void
|
||||
AtomAssignings::add_assignment(int asgn_off, const string &str, int name_len,
|
||||
int right_off, int right_len)
|
||||
{
|
||||
// the order of doing things here is important: since the
|
||||
// FormulaParser requires that all references from the i-th tree
|
||||
// refere to trees with index lass than i, so to capture also a
|
||||
// nulary term for the left hand side, it must be inserted to the
|
||||
// expression tree before the expression is parsed.
|
||||
|
||||
// find the name in the atoms
|
||||
string name = str.substr(0, name_len);
|
||||
|
||||
// if left hand side is a registered atom, insert it to tree
|
||||
int t;
|
||||
try
|
||||
{
|
||||
t = atoms.check(name);
|
||||
if (t == -1)
|
||||
t = expr.add_nulary(name);
|
||||
}
|
||||
catch (const ParserException &e)
|
||||
{
|
||||
atoms.register_name(name);
|
||||
t = expr.add_nulary(name);
|
||||
}
|
||||
// register left hand side in order
|
||||
order.push_back(t);
|
||||
|
||||
// parse expression on the right
|
||||
try
|
||||
{
|
||||
expr.parse(str.substr(right_off, right_len));
|
||||
}
|
||||
catch (const ParserException &e)
|
||||
{
|
||||
throw ParserException(e, asgn_off+right_off);
|
||||
}
|
||||
|
||||
// register name of the left hand side and put to lname2expr
|
||||
left_names.insert(name);
|
||||
if (lname2expr.find(name) != lname2expr.end())
|
||||
{
|
||||
// Prevent the occurrence of #415
|
||||
std::cerr << "Changing the value of " << name << " through a second assignment (e.g. in initval) is not supported. Aborting." << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
lname2expr[name] = order.size()-1;
|
||||
}
|
||||
|
||||
void
|
||||
AtomAssignings::apply_subst(const AtomSubstitutions::Toldnamemap &mm)
|
||||
{
|
||||
// go through all old variables and see what are their derived new
|
||||
// variables
|
||||
for (const auto &it : mm)
|
||||
{
|
||||
const string &oldname = it.first;
|
||||
const AtomSubstitutions::Tshiftnameset &sset = it.second;
|
||||
if (!sset.empty())
|
||||
{
|
||||
int told = atoms.index(oldname);
|
||||
if (told < 0 && !atoms.get_name_storage().query(oldname))
|
||||
atoms.register_name(oldname);
|
||||
if (told == -1)
|
||||
told = expr.add_nulary(oldname);
|
||||
// at least one substitution here, so make an expression
|
||||
expr.add_formula(told);
|
||||
// say that this expression is not assigned to any atom
|
||||
order.push_back(-1);
|
||||
// now go through all new names derived from the old name and
|
||||
// reference to the newly added formula
|
||||
for (const auto &itt : sset)
|
||||
{
|
||||
const string &newname = itt.first;
|
||||
left_names.insert(newname);
|
||||
lname2expr.emplace(newname, expr.nformulas()-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AtomAssignings::print() const
|
||||
{
|
||||
std::cout << "Atom Assignings\nExpressions:\n";
|
||||
expr.print();
|
||||
std::cout << "Left names:\n";
|
||||
for (auto it : lname2expr)
|
||||
std::cout << it.first << " ⇒ " << expr.formula(it.second) << " (t=" << order[it.second] << ")\n";
|
||||
}
|
||||
|
||||
void
|
||||
AtomAsgnEvaluator::setValues(EvalTree &et) const
|
||||
{
|
||||
// set values of constants
|
||||
aa.atoms.setValues(et);
|
||||
|
||||
// set values of variables to NaN or to user set values
|
||||
double nan = std::numeric_limits<double>::quiet_NaN();
|
||||
for (int i = 0; i < aa.atoms.nvar(); i++)
|
||||
{
|
||||
const string &ss = aa.atoms.name(i);
|
||||
int t = aa.atoms.index(ss);
|
||||
if (t >= 0)
|
||||
{
|
||||
auto it = user_values.find(t);
|
||||
if (it == user_values.end())
|
||||
et.set_nulary(t, nan);
|
||||
else
|
||||
et.set_nulary(t, it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AtomAsgnEvaluator::set_user_value(const string &name, double val)
|
||||
{
|
||||
int t = aa.atoms.index(name);
|
||||
if (t >= 0)
|
||||
{
|
||||
auto it = user_values.find(t);
|
||||
if (it == user_values.end())
|
||||
user_values.emplace(t, val);
|
||||
else
|
||||
it->second = val;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AtomAsgnEvaluator::load(int i, double res)
|
||||
{
|
||||
// set the value
|
||||
operator[](i) = res;
|
||||
// if i-th expression is atom, set its value to this EvalTree
|
||||
int t = aa.order[i];
|
||||
if (t >= 0)
|
||||
etree.set_nulary(t, res);
|
||||
}
|
||||
|
||||
double
|
||||
AtomAsgnEvaluator::get_value(const string &name) const
|
||||
{
|
||||
auto it = aa.lname2expr.find(name);
|
||||
if (it == aa.lname2expr.end())
|
||||
return std::numeric_limits<double>::quiet_NaN();
|
||||
else
|
||||
return operator[](it->second);
|
||||
}
|
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2006 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OGP_ATOM_ASSIGNINGS_H
|
||||
#define OGP_ATOM_ASSIGNINGS_H
|
||||
|
||||
#include "static_atoms.hh"
|
||||
#include "formula_parser.hh"
|
||||
#include "atom_substitutions.hh"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace ogp
|
||||
{
|
||||
class AtomAsgnEvaluator;
|
||||
|
||||
/** This class represents atom assignments used in parameters
|
||||
* settings and initval initialization. It maintains atoms of the
|
||||
* all expressions on the right hand side, the parsed formulas of
|
||||
* the right hand sides, and the information about the left hand
|
||||
* sides. See documentation to the order member below. */
|
||||
class AtomAssignings
|
||||
{
|
||||
friend class AtomAsgnEvaluator;
|
||||
protected:
|
||||
using Tvarintmap = std::map<string, int>;
|
||||
/** All atoms which should be sufficient for formulas at the
|
||||
* right hand sides. The atoms should be filled with names
|
||||
* (preregistered). This is a responsibility of the caller. */
|
||||
StaticAtoms &atoms;
|
||||
/** The formulas of right hand sides. */
|
||||
FormulaParser expr;
|
||||
/** Name storage of the names from left hand sides. */
|
||||
NameStorage left_names;
|
||||
/** Information on left hand sides. This maps a name to the
|
||||
* index of its assigned expression in expr. More than one
|
||||
* name may reference to the same expression. */
|
||||
Tvarintmap lname2expr;
|
||||
/** Information on left hand sides. If order[i] >= 0, then it
|
||||
* says that i-th expression in expr is assigned to atom with
|
||||
* order[i] tree index. */
|
||||
std::vector<int> order;
|
||||
public:
|
||||
/** Construct the object using the provided static atoms. */
|
||||
AtomAssignings(StaticAtoms &a) : atoms(a), expr(atoms)
|
||||
{
|
||||
}
|
||||
/** Make a copy with provided reference to (posibly different)
|
||||
* static atoms. */
|
||||
AtomAssignings(const AtomAssignings &aa, StaticAtoms &a);
|
||||
virtual ~AtomAssignings() = default;
|
||||
/** Parse the assignments from the given string. */
|
||||
void parse(const string &stream);
|
||||
/** Process a syntax error from bison. */
|
||||
void error(string mes);
|
||||
/** Add an assignment of the given name to the given
|
||||
* double. Can be called by a user, anytime. */
|
||||
void add_assignment_to_double(string name, double val);
|
||||
/** Add an assignment. Called from assign.y. */
|
||||
void add_assignment(int asgn_off, const string &str, int name_len,
|
||||
int right_off, int right_len);
|
||||
/** This applies old2new map (possibly from atom
|
||||
* substitutions) to this object. It registers new variables
|
||||
* in the atoms, and adds the expressions to expr, and left
|
||||
* names to lname2expr. The information about dynamical part
|
||||
* of substitutions is ignored, since we are now in the static
|
||||
* world. */
|
||||
void apply_subst(const AtomSubstitutions::Toldnamemap &mm);
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
};
|
||||
|
||||
/** This class basically evaluates the atom assignments
|
||||
* AtomAssignings, so it inherits from ogp::FormulaEvaluator. It
|
||||
* is also a storage for the results of the evaluation stored as a
|
||||
* vector, so the class inherits from std::vector<double> and
|
||||
* ogp::FormulaEvalLoader. As the expressions for atoms are
|
||||
* evaluated, the results are values for atoms which will be
|
||||
* used in subsequent evaluations. For this reason, the class
|
||||
* inherits also from AtomValues. */
|
||||
class AtomAsgnEvaluator : public FormulaEvalLoader,
|
||||
public AtomValues,
|
||||
protected FormulaEvaluator,
|
||||
public std::vector<double>
|
||||
{
|
||||
protected:
|
||||
using Tusrvalmap = std::map<int, double>;
|
||||
Tusrvalmap user_values;
|
||||
const AtomAssignings &aa;
|
||||
public:
|
||||
AtomAsgnEvaluator(const AtomAssignings &a)
|
||||
: FormulaEvaluator(a.expr),
|
||||
std::vector<double>(a.expr.nformulas()), aa(a)
|
||||
{
|
||||
}
|
||||
~AtomAsgnEvaluator() override = default;
|
||||
/** This sets all initial values to NaNs, all constants and
|
||||
* all values set by user by call set_value. This is called by
|
||||
* FormulaEvaluator::eval() method, which is called by eval()
|
||||
* method passing this argument as AtomValues. So the
|
||||
* ogp::EvalTree will be always this->etree. */
|
||||
void setValues(EvalTree &et) const override;
|
||||
/** User setting of the values. For example in initval,
|
||||
* parameters are known and should be set to their values. In
|
||||
* constrast endogenous variables are set initially to NaNs by
|
||||
* AtomValues::setValues. */
|
||||
void set_user_value(const string &name, double val);
|
||||
/** This sets the result of i-th expression in aa to res, and
|
||||
* also checks whether the i-th expression is an atom. If so,
|
||||
* it sets the value of the atom in ogp::EvalTree
|
||||
* this->etree. */
|
||||
void load(int i, double res) override;
|
||||
/** After the user values have been set, the assignments can
|
||||
* be evaluated. For this purpose we have eval() method. The
|
||||
* result is that this object as std::vector<double> will
|
||||
* contain the values. It is ordered given by formulas in
|
||||
* expr. */
|
||||
void
|
||||
eval()
|
||||
{
|
||||
FormulaEvaluator::eval(*this, *this);
|
||||
}
|
||||
/** This returns a value for a given name. If the name is not
|
||||
* found among atoms, or there is no assignment for the atom,
|
||||
* NaN is returned. */
|
||||
double get_value(const string &name) const;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,275 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2006 Ondra Kamenik
|
||||
* Copyright © 2019-2022 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "atom_substitutions.hh"
|
||||
#include "utils/cc/exception.hh"
|
||||
|
||||
using namespace ogp;
|
||||
|
||||
AtomSubstitutions::AtomSubstitutions(const AtomSubstitutions &as, const FineAtoms &oa,
|
||||
FineAtoms &na)
|
||||
: new2old(as.new2old), old2new(as.old2new), old_atoms(oa), new_atoms(na)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AtomSubstitutions::add_substitution(string newname, string oldname, int tshift)
|
||||
{
|
||||
// insert to new2old map
|
||||
new2old.emplace(newname, Tshiftname(oldname, tshift));
|
||||
// insert to old2new map
|
||||
auto it = old2new.find(oldname);
|
||||
if (it != old2new.end())
|
||||
it->second.emplace(std::move(newname), -tshift);
|
||||
else
|
||||
{
|
||||
Tshiftnameset snset;
|
||||
snset.emplace(std::move(newname), -tshift);
|
||||
old2new.emplace(std::move(oldname), snset);
|
||||
}
|
||||
|
||||
// put to info
|
||||
info.num_substs++;
|
||||
}
|
||||
|
||||
void
|
||||
AtomSubstitutions::substitutions_finished(VarOrdering::ord_type ot)
|
||||
{
|
||||
// create an external ordering of new_atoms from old_atoms
|
||||
const vector<string> &oa_ext = old_atoms.get_allvar();
|
||||
vector<string> na_ext;
|
||||
for (const auto &oname : oa_ext)
|
||||
{
|
||||
// add the old name itself
|
||||
na_ext.push_back(oname);
|
||||
// add all new names derived from the old name
|
||||
auto it = old2new.find(oname);
|
||||
if (it != old2new.end())
|
||||
for (const auto &itt : it->second)
|
||||
na_ext.push_back(itt.first);
|
||||
}
|
||||
|
||||
// call parsing finished for the new_atoms
|
||||
new_atoms.parsing_finished(ot, na_ext);
|
||||
}
|
||||
|
||||
string
|
||||
AtomSubstitutions::get_new4old(const string &oldname, int tshift) const
|
||||
{
|
||||
auto it = old2new.find(oldname);
|
||||
if (it != old2new.end())
|
||||
{
|
||||
const Tshiftnameset &sset = it->second;
|
||||
for (const auto &itt : sset)
|
||||
if (itt.second == -tshift)
|
||||
return itt.first;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void
|
||||
AtomSubstitutions::print() const
|
||||
{
|
||||
std::cout << "Atom Substitutions:\nOld ⇒ New:\n";
|
||||
for (const auto &it : old2new)
|
||||
for (const auto &itt : it.second)
|
||||
std::cout << " " << it.first << " ⇒ [" << itt.first << ", " << itt.second << "]\n";
|
||||
|
||||
std::cout << "Old ⇐ New:\n";
|
||||
for (const auto &it : new2old)
|
||||
std::cout << " [" << it.second.first << ", " << it.second.second << "] ⇐ " << it.first << '\n';
|
||||
}
|
||||
|
||||
void
|
||||
SAtoms::substituteAllLagsAndLeads(FormulaParser &fp, AtomSubstitutions &as)
|
||||
{
|
||||
string name;
|
||||
|
||||
int mlead, mlag;
|
||||
endovarspan(mlead, mlag);
|
||||
|
||||
// substitute all endo lagged more than 1
|
||||
while (!(name = findEndoWithLeadInInterval(mlag, -2)).empty())
|
||||
makeAuxVariables(name, -1, -2, mlag, fp, as);
|
||||
// substitute all endo leaded more than 1
|
||||
while (!(name = findEndoWithLeadInInterval(2, mlead)).empty())
|
||||
makeAuxVariables(name, 1, 2, mlead, fp, as);
|
||||
|
||||
exovarspan(mlead, mlag);
|
||||
|
||||
// substitute all lagged exo
|
||||
while (!(name = findExoWithLeadInInterval(mlag, -1)).empty())
|
||||
makeAuxVariables(name, -1, -1, mlag, fp, as);
|
||||
// substitute all leaded exo
|
||||
while (!(name = findExoWithLeadInInterval(1, mlead)).empty())
|
||||
makeAuxVariables(name, 1, 1, mlead, fp, as);
|
||||
|
||||
// notify that substitution have been finished
|
||||
as.substitutions_finished(order_type);
|
||||
}
|
||||
|
||||
void
|
||||
SAtoms::substituteAllLagsAndExo1Leads(FormulaParser &fp, AtomSubstitutions &as)
|
||||
{
|
||||
string name;
|
||||
|
||||
int mlead, mlag;
|
||||
endovarspan(mlead, mlag);
|
||||
|
||||
// substitute all endo lagged more than 1
|
||||
while (!(name = findEndoWithLeadInInterval(mlag, -2)).empty())
|
||||
makeAuxVariables(name, -1, -2, mlag, fp, as);
|
||||
|
||||
exovarspan(mlead, mlag);
|
||||
|
||||
// substitute all lagged exo
|
||||
while (!(name = findExoWithLeadInInterval(mlag, -1)).empty())
|
||||
makeAuxVariables(name, -1, -1, mlag, fp, as);
|
||||
// substitute all leaded exo by 1
|
||||
while (!(name = findExoWithLeadInInterval(1, 1)).empty())
|
||||
makeAuxVariables(name, 1, 1, 1, fp, as);
|
||||
|
||||
// notify that substitution have been finished
|
||||
as.substitutions_finished(order_type);
|
||||
}
|
||||
|
||||
string
|
||||
SAtoms::findNameWithLeadInInterval(const vector<string> &names,
|
||||
int ll1, int ll2) const
|
||||
{
|
||||
for (auto name : names)
|
||||
{
|
||||
auto it = vars.find(name);
|
||||
if (it != vars.end())
|
||||
{
|
||||
const DynamicAtoms::Tlagmap &lmap = it->second;
|
||||
for (auto itt : lmap)
|
||||
if (itt.first >= ll1 && itt.first <= ll2)
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
// nothing found
|
||||
return "";
|
||||
}
|
||||
|
||||
void
|
||||
SAtoms::attemptAuxName(const string &str, int ll, string &out) const
|
||||
{
|
||||
char c = (ll >= 0) ? ((ll == 0) ? 'e' : 'p') : 'm';
|
||||
string absll = std::to_string(std::abs(ll));
|
||||
int iter = 1;
|
||||
do
|
||||
{
|
||||
out = str + '_';
|
||||
for (int i = 0; i < iter; i++)
|
||||
out += c;
|
||||
if (ll != 0)
|
||||
out += absll;
|
||||
iter++;
|
||||
}
|
||||
while (varnames.query(out));
|
||||
}
|
||||
|
||||
void
|
||||
SAtoms::makeAuxVariables(const string &name, int step, int start, int limit_lead,
|
||||
FormulaParser &fp, AtomSubstitutions &as)
|
||||
{
|
||||
if (!(step == 1 || step == -1))
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Wrong value of step in SAtoms::makeAuxVariables");
|
||||
if (step*start > step*limit_lead)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Wrong value of start in SAtoms::makeAuxVariables");
|
||||
|
||||
// make sure that we do not go further than necessary, this is
|
||||
// that the limit lead is not behind maxlead or minlag
|
||||
int mlead, mlag;
|
||||
varspan(name, mlead, mlag);
|
||||
if (step == -1)
|
||||
limit_lead = std::max(limit_lead, mlag);
|
||||
else
|
||||
limit_lead = std::min(limit_lead, mlead);
|
||||
|
||||
// Comment to comments: name="a"; start=-3; step=-1;
|
||||
|
||||
// recover tree index of a previous atom, i.e. set tprev to a tree
|
||||
// index of atom "a(-2)"
|
||||
int tprev = index(name, start-step);
|
||||
if (tprev == -1)
|
||||
tprev = fp.add_nulary(name + '(' + std::to_string(start-step) + ')');
|
||||
|
||||
int ll = start;
|
||||
do
|
||||
{
|
||||
// either create atom "a_m2(0)" with tree index taux and add
|
||||
// equation "a_m2(0)=a(-2)"
|
||||
// or
|
||||
// check if "a_m2(0)" has not been already created (with
|
||||
// different step), in this case do not add equation "a_m2(0)
|
||||
// = a(-2)"
|
||||
string newname, newname_str;
|
||||
int taux;
|
||||
if ((newname = as.get_new4old(name, ll-step)).empty())
|
||||
{
|
||||
attemptAuxName(name, ll-step, newname_str);
|
||||
newname = newname_str;
|
||||
register_uniq_endo(newname);
|
||||
taux = fp.add_nulary(newname + "(0)");
|
||||
// add to substitutions
|
||||
as.add_substitution(newname, name, ll-step);
|
||||
|
||||
// add equation "a_m2(0) = a(-2)", this is taux = tprev
|
||||
fp.add_formula(fp.add_binary(code_t::MINUS, taux, tprev));
|
||||
}
|
||||
else
|
||||
{
|
||||
// example: exogenous EPS and occurrence at both EPS(-1)
|
||||
// EPS(+1)
|
||||
// first call makeAuxVariables("EPS",1,1,...) will make endo EPS_p0 = EPS
|
||||
// second call makeAuxVariables("EPS",-1,-1,...) will use this EPS_p0
|
||||
// to substitute for EPS(-1)
|
||||
taux = index(newname, 0);
|
||||
if (taux < 0)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Couldn't find tree index of previously substituted variable");
|
||||
}
|
||||
|
||||
// create atom "a_m2(-1)" or turn "a(-3)" if any to "a_m2(-1)"; tree index t
|
||||
int t = index(name, ll);
|
||||
if (t == -1)
|
||||
{
|
||||
// no "a(-3)", make t <-> a_m2(-1)
|
||||
t = fp.add_nulary(newname + '(' + std::to_string(step) + ')');
|
||||
}
|
||||
else
|
||||
{
|
||||
// turn a(-3) to a_m2(-1)
|
||||
unassign_variable(name, ll, t);
|
||||
assign_variable(newname, step, t);
|
||||
}
|
||||
|
||||
// next iteration starts with tprev <-> "a_m2(-1)" (this will be made equal to "a_m3(0)")
|
||||
tprev = t;
|
||||
|
||||
ll += step;
|
||||
}
|
||||
while (step*ll <= step*limit_lead);
|
||||
}
|
|
@ -1,200 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2006 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OGP_ATOM_SUBSTITUTIONS_H
|
||||
#define OGP_ATOM_SUBSTITUTIONS_H
|
||||
|
||||
#include "fine_atoms.hh"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ogp
|
||||
{
|
||||
|
||||
using std::string;
|
||||
using std::map;
|
||||
using std::pair;
|
||||
|
||||
/** This class tracts an information about the performed
|
||||
* substitutions. In fact, there is only one number to keep track
|
||||
* about, this is a number of substitutions. */
|
||||
struct SubstInfo
|
||||
{
|
||||
int num_substs{0};
|
||||
SubstInfo() = default;
|
||||
};
|
||||
|
||||
/** This class tracks all atom substitutions during the job and
|
||||
* then builds structures when all substitutions are finished. */
|
||||
class AtomSubstitutions
|
||||
{
|
||||
public:
|
||||
using Tshiftname = pair<string, int>;
|
||||
using Tshiftmap = map<string, Tshiftname>;
|
||||
using Tshiftnameset = set<Tshiftname>;
|
||||
using Toldnamemap = map<string, Tshiftnameset>;
|
||||
protected:
|
||||
/** This maps a new name to a shifted old name. This is, one
|
||||
* entry looks as "a_m3 ==> a(-3)", saying that a variable
|
||||
* "a_m3" corresponds to a variable "a" lagged by 3. */
|
||||
Tshiftmap new2old;
|
||||
/** This is inverse to new2old, which is not unique. For old
|
||||
* name, say "a", it says what new names are derived with what
|
||||
* shifts from the "a". For example, it can map "a" to a two
|
||||
* element set {["a_m3", +3], ["a_p2", -2]}. This says that
|
||||
* leading "a_m3" by 3 one gets old "a" and lagging "a_p2" by
|
||||
* 2 one gets also old "a". */
|
||||
Toldnamemap old2new;
|
||||
/** This is a reference to old atoms with multiple leads and
|
||||
* lags. They are supposed to be used with parsing finished
|
||||
* being had called, so that the external ordering is
|
||||
* available. */
|
||||
const FineAtoms &old_atoms;
|
||||
/** This is a reference to new atoms. All name pointers point
|
||||
* to storage of these atoms. */
|
||||
FineAtoms &new_atoms;
|
||||
/** Substitutions information. */
|
||||
SubstInfo info;
|
||||
public:
|
||||
/** Create the object with reference to the old and new
|
||||
* atoms. In the beginning, old atoms are supposed to be with
|
||||
* parsing_finished() called, and new atoms a simple copy of
|
||||
* old atoms. The new atoms will be an instance of SAtoms. All
|
||||
* substitution job is done by a substitution method of the
|
||||
* new atoms. */
|
||||
AtomSubstitutions(const FineAtoms &oa, FineAtoms &na)
|
||||
: old_atoms(oa), new_atoms(na)
|
||||
{
|
||||
}
|
||||
/** Construct a copy of the object using a different instances
|
||||
* of old atoms and new atoms, which are supposed to be
|
||||
* semantically same as the atoms from as. */
|
||||
AtomSubstitutions(const AtomSubstitutions &as, const FineAtoms &oa, FineAtoms &na);
|
||||
virtual ~AtomSubstitutions() = default;
|
||||
/** This is called during the substitution job from the
|
||||
* substitution method of the new atoms. This says that the
|
||||
* new name, say "a_m3" is a substitution of old name "a"
|
||||
* shifted by -3. */
|
||||
void add_substitution(string newname, string oldname, int tshift);
|
||||
/** This is called when all substitutions are finished. This
|
||||
* forms the new external ordering of the new atoms and calls
|
||||
* parsing_finished() for the new atoms with the given ordering type. */
|
||||
void substitutions_finished(VarOrdering::ord_type ot);
|
||||
/** Returns a new name for old name and given tshift. For "a"
|
||||
* and tshift=-3, it returns "a_m3". If there is no such
|
||||
* substitution, it returns an empty string. */
|
||||
string get_new4old(const string &oldname, int tshift) const;
|
||||
/** Return new2old. */
|
||||
const Tshiftmap &
|
||||
get_new2old() const
|
||||
{
|
||||
return new2old;
|
||||
}
|
||||
/** Return old2new. */
|
||||
const Toldnamemap &
|
||||
get_old2new() const
|
||||
{
|
||||
return old2new;
|
||||
}
|
||||
/** Return substitution info. */
|
||||
const SubstInfo &
|
||||
get_info() const
|
||||
{
|
||||
return info;
|
||||
}
|
||||
/** Return old atoms. */
|
||||
const FineAtoms &
|
||||
get_old_atoms() const
|
||||
{
|
||||
return old_atoms;
|
||||
}
|
||||
/** Return new atoms. */
|
||||
const FineAtoms &
|
||||
get_new_atoms() const
|
||||
{
|
||||
return new_atoms;
|
||||
}
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
};
|
||||
|
||||
class SAtoms : public FineAtoms
|
||||
{
|
||||
public:
|
||||
SAtoms()
|
||||
: FineAtoms()
|
||||
{
|
||||
}
|
||||
SAtoms(const SAtoms &sa) = default;
|
||||
/** This substitutes all lags and leads for all exogenous and
|
||||
* all lags and leads greater than 1 for all endogenous
|
||||
* variables. This is useful for perfect foresight problems
|
||||
* where we can do that. */
|
||||
void substituteAllLagsAndLeads(FormulaParser &fp, AtomSubstitutions &as);
|
||||
/** This substitutes all lags of all endo and exo and one step
|
||||
* leads of all exo variables. This is useful for stochastic
|
||||
* models where we cannot solve leads more than 1. */
|
||||
void substituteAllLagsAndExo1Leads(FormulaParser &fp, AtomSubstitutions &as);
|
||||
protected:
|
||||
/** This finds an endogenous variable name which occurs between
|
||||
* ll1 and ll2 included. */
|
||||
string
|
||||
findEndoWithLeadInInterval(int ll1, int ll2) const
|
||||
{
|
||||
return findNameWithLeadInInterval(get_endovars(), ll1, ll2);
|
||||
}
|
||||
/** This finds an exogenous variable name which occurs between
|
||||
* ll1 and ll2 included. */
|
||||
string
|
||||
findExoWithLeadInInterval(int ll1, int ll2) const
|
||||
{
|
||||
return findNameWithLeadInInterval(get_exovars(), ll1, ll2);
|
||||
}
|
||||
|
||||
/** This attempts to find a non registered name of the form
|
||||
* <str>_m<abs(ll)> or <str>_p<abs(ll)>. A letter 'p' is
|
||||
* chosen if ll is positive, 'm' if negative. If a name of
|
||||
* such form is already registered, one more character (either
|
||||
* 'p' or 'm') is added and the test is performed again. The
|
||||
* resulting name is returned in a string out. */
|
||||
void attemptAuxName(const string &str, int ll, string &out) const;
|
||||
|
||||
/** This makes auxiliary variables to eliminate all leads/lags
|
||||
* greater/less than or equal to start up to the limit_lead
|
||||
* for a variable with the given name. If the limit_lead is
|
||||
* greater/less than the maxlead/minlag of the variable, than
|
||||
* maxlead/minlag is used. This process is recorded in
|
||||
* AtomSubstitutions. The new auxiliary variables and their
|
||||
* atoms are created in this object. The auxiliary equations
|
||||
* are created in the given FormulaParser. The value of step
|
||||
* is allowed to be either -1 (lags) or +1 (leads). */
|
||||
void makeAuxVariables(const string &name, int step, int start, int limit_lead,
|
||||
FormulaParser &fp, AtomSubstitutions &as);
|
||||
private:
|
||||
/** This is a worker routine for findEndoWithLeadInInterval
|
||||
* and findExoWithLeadInInterval. */
|
||||
string findNameWithLeadInInterval(const vector<string> &names,
|
||||
int ll1, int ll2) const;
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,617 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019-2022 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "utils/cc/exception.hh"
|
||||
#include "dynamic_atoms.hh"
|
||||
|
||||
using namespace ogp;
|
||||
|
||||
void
|
||||
NameStorage::insert(string name)
|
||||
{
|
||||
if (!query(name))
|
||||
{
|
||||
name_store.push_back(name);
|
||||
name_set.insert(std::move(name));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NameStorage::print() const
|
||||
{
|
||||
for (auto i : name_store)
|
||||
std::cout << i << '\n';
|
||||
}
|
||||
|
||||
void
|
||||
Constants::import_constants(const Constants &c, OperationTree &otree, Tintintmap &tmap)
|
||||
{
|
||||
for (auto it : c.cmap)
|
||||
{
|
||||
int told = it.first;
|
||||
int tnew = otree.add_nulary();
|
||||
tmap.emplace(told, tnew);
|
||||
add_constant(tnew, it.second);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Constants::setValues(EvalTree &et) const
|
||||
{
|
||||
for (const auto &it : cmap)
|
||||
et.set_nulary(it.first, it.second);
|
||||
}
|
||||
|
||||
void
|
||||
Constants::add_constant(int t, double val)
|
||||
{
|
||||
cmap.emplace(t, val);
|
||||
cinvmap.emplace(val, t);
|
||||
}
|
||||
|
||||
bool
|
||||
Constants::is_constant(int t) const
|
||||
{
|
||||
if (t < OperationTree::num_constants)
|
||||
return true;
|
||||
auto it = cmap.find(t);
|
||||
return (it != cmap.end());
|
||||
}
|
||||
|
||||
double
|
||||
Constants::get_constant_value(int t) const
|
||||
{
|
||||
auto it = cmap.find(t);
|
||||
if (it != cmap.end())
|
||||
return it->second;
|
||||
else
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Tree index is not constant in Constants::get_constant_value");
|
||||
}
|
||||
|
||||
int
|
||||
Constants::check(const string &str) const
|
||||
{
|
||||
double d = std::stod(str);
|
||||
auto it = cinvmap.find(d);
|
||||
if (it != cinvmap.end())
|
||||
return it->second;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
Constants::print() const
|
||||
{
|
||||
for (const auto &it : cmap)
|
||||
std::cout << "$" << it.first << ": " << it.second << "\n";
|
||||
}
|
||||
|
||||
int
|
||||
DynamicAtoms::check(const string &name) const
|
||||
{
|
||||
if (is_string_constant(name))
|
||||
return Constants::check(name);
|
||||
|
||||
return check_variable(name);
|
||||
}
|
||||
|
||||
int
|
||||
DynamicAtoms::check_variable(const string &name) const
|
||||
{
|
||||
string str;
|
||||
int ll;
|
||||
parse_variable(name, str, ll);
|
||||
auto it = vars.find(str);
|
||||
|
||||
if (it != vars.end())
|
||||
{
|
||||
const Tlagmap &lmap = it->second;
|
||||
auto itt = lmap.find(ll);
|
||||
if (itt != lmap.end())
|
||||
return itt->second;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
DynamicAtoms::assign(const string &name, int t)
|
||||
{
|
||||
if (is_string_constant(name))
|
||||
assign_constant(name, t);
|
||||
else
|
||||
assign_variable(name, t);
|
||||
}
|
||||
|
||||
void
|
||||
DynamicAtoms::assign_constant(const string &name, int t)
|
||||
{
|
||||
double val = std::stod(name);
|
||||
add_constant(t, val);
|
||||
}
|
||||
|
||||
// parse the name and then call assing_variable(varname, ll, t)
|
||||
|
||||
void
|
||||
DynamicAtoms::assign_variable(const string &name, int t)
|
||||
{
|
||||
int ll;
|
||||
string str;
|
||||
parse_variable(name, str, ll);
|
||||
// here str is just name without lead/lag
|
||||
varnames.insert(str);
|
||||
|
||||
assign_variable(str, ll, t);
|
||||
}
|
||||
|
||||
void
|
||||
DynamicAtoms::assign_variable(const string &varname, int ll, int t)
|
||||
{
|
||||
if (indices.end() != indices.find(t))
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Attempt to assign already allocated tree index");
|
||||
|
||||
auto it = vars.find(varname);
|
||||
if (it != vars.end())
|
||||
{
|
||||
Tlagmap &lmap = it->second;
|
||||
if (lmap.end() != lmap.find(ll))
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Attempt to assign already allocated variable");
|
||||
lmap.emplace(ll, t);
|
||||
}
|
||||
else
|
||||
{
|
||||
Tlagmap lmap;
|
||||
lmap.emplace(ll, t);
|
||||
vars.emplace(varname, lmap);
|
||||
}
|
||||
indices.emplace(t, varname);
|
||||
|
||||
nv++;
|
||||
minlag = std::min(ll, minlag);
|
||||
maxlead = std::max(ll, maxlead);
|
||||
}
|
||||
|
||||
void
|
||||
DynamicAtoms::unassign_variable(const string &varname, int ll, int t)
|
||||
{
|
||||
auto it = vars.find(varname);
|
||||
if (it != vars.end())
|
||||
{
|
||||
Tlagmap &lmap = it->second;
|
||||
auto itt = lmap.find(ll);
|
||||
if (itt != lmap.end())
|
||||
{
|
||||
if (itt->second == t)
|
||||
{
|
||||
// erase it from the lagmap; if it becomes empty,
|
||||
// erase the lagmap from varmap
|
||||
lmap.erase(itt);
|
||||
if (lmap.size() == 0)
|
||||
vars.erase(it);
|
||||
// erase it from the indices
|
||||
auto ittt = indices.find(t);
|
||||
if (ittt != indices.end())
|
||||
indices.erase(ittt);
|
||||
|
||||
nv--;
|
||||
if (ll == minlag || ll == maxlead)
|
||||
update_minmaxll();
|
||||
}
|
||||
else
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Tree index inconsistent in DynamicAtoms::unassign_variable");
|
||||
}
|
||||
else
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Lead/lag of the variable not found in DynamicAtoms::unassign_variable");
|
||||
}
|
||||
else
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Variable not found in DynamicAtoms::unassign_variable");
|
||||
}
|
||||
|
||||
void
|
||||
DynamicAtoms::update_minmaxll()
|
||||
{
|
||||
minlag = std::numeric_limits<int>::max();
|
||||
maxlead = std::numeric_limits<int>::min();
|
||||
for (const auto &it : vars)
|
||||
{
|
||||
const Tlagmap &lmap = it.second;
|
||||
for (auto itt : lmap)
|
||||
{
|
||||
int ll = itt.first;
|
||||
minlag = std::min(ll, minlag);
|
||||
maxlead = std::max(ll, maxlead);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vector<int>
|
||||
DynamicAtoms::variables() const
|
||||
{
|
||||
vector<int> res;
|
||||
for (const auto &var : vars)
|
||||
{
|
||||
const Tlagmap &lmap = var.second;
|
||||
for (auto itt : lmap)
|
||||
res.push_back(itt.second);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
DynamicAtoms::varspan(int t, int &mlead, int &mlag) const
|
||||
{
|
||||
auto it = indices.find(t);
|
||||
if (indices.end() == it)
|
||||
{
|
||||
mlead = std::numeric_limits<int>::min();
|
||||
mlag = std::numeric_limits<int>::max();
|
||||
return;
|
||||
}
|
||||
varspan(it->second, mlead, mlag);
|
||||
}
|
||||
|
||||
void
|
||||
DynamicAtoms::varspan(const string &name, int &mlead, int &mlag) const
|
||||
{
|
||||
auto it = vars.find(name);
|
||||
if (vars.end() == it)
|
||||
{
|
||||
mlead = std::numeric_limits<int>::min();
|
||||
mlag = std::numeric_limits<int>::max();
|
||||
return;
|
||||
}
|
||||
const Tlagmap &lmap = it->second;
|
||||
auto beg = lmap.begin();
|
||||
auto end = lmap.rbegin();
|
||||
mlag = beg->first;
|
||||
mlead = end->first;
|
||||
}
|
||||
|
||||
void
|
||||
DynamicAtoms::varspan(const vector<string> &names, int &mlead, int &mlag) const
|
||||
{
|
||||
mlead = std::numeric_limits<int>::min();
|
||||
mlag = std::numeric_limits<int>::max();
|
||||
for (const auto &name : names)
|
||||
{
|
||||
int lag, lead;
|
||||
varspan(name, lead, lag);
|
||||
mlead = std::max(lead, mlead);
|
||||
mlag = std::min(lag, mlag);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
DynamicAtoms::is_named_atom(int t) const
|
||||
{
|
||||
return indices.end() != indices.find(t);
|
||||
}
|
||||
|
||||
int
|
||||
DynamicAtoms::index(const string &name, int ll) const
|
||||
{
|
||||
auto it = vars.find(name);
|
||||
if (vars.end() != it)
|
||||
{
|
||||
const Tlagmap &lmap = it->second;
|
||||
auto itt = lmap.find(ll);
|
||||
if (lmap.end() != itt)
|
||||
return itt->second;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool
|
||||
DynamicAtoms::is_referenced(const string &name) const
|
||||
{
|
||||
return vars.find(name) != vars.end();
|
||||
}
|
||||
|
||||
const DynamicAtoms::Tlagmap &
|
||||
DynamicAtoms::lagmap(const string &name) const
|
||||
{
|
||||
auto it = vars.find(name);
|
||||
if (vars.end() == it)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Couldn't find the name "
|
||||
+ name + " in DynamicAtoms::lagmap");
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const string &
|
||||
DynamicAtoms::name(int t) const
|
||||
{
|
||||
auto it = indices.find(t);
|
||||
if (indices.end() == it)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Couldn't find tree index in DynamicAtoms::name");
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int
|
||||
DynamicAtoms::lead(int t) const
|
||||
{
|
||||
const string &nam = name(t);
|
||||
const Tlagmap &lmap = lagmap(nam);
|
||||
auto it = lmap.begin();
|
||||
while (it != lmap.end() && it->second != t)
|
||||
++it;
|
||||
if (lmap.end() == it)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Couldn't find the three index in DynamicAtoms::lead");
|
||||
return it->first;
|
||||
}
|
||||
|
||||
void
|
||||
DynamicAtoms::print() const
|
||||
{
|
||||
std::cout << "names:\n";
|
||||
varnames.print();
|
||||
std::cout << "constants:\n";
|
||||
Constants::print();
|
||||
std::cout << "variables:\n";
|
||||
for (const auto &var : vars)
|
||||
{
|
||||
const Tlagmap &lmap = var.second;
|
||||
for (auto itt : lmap)
|
||||
std::cout << "$" << itt.second << ": " << var.first << "(" << itt.first << ")\n";
|
||||
}
|
||||
std::cout << "indices:\n";
|
||||
for (auto indice : indices)
|
||||
std::cout << "t=" << indice.first << " ⇒ " << indice.second << "\n";
|
||||
}
|
||||
|
||||
/** Note that the str has been parsed by the lexicographic
|
||||
* analyzer. It can be either a variable or a double. So it is easy to
|
||||
* recognize it by the first character. */
|
||||
bool
|
||||
DynamicAtoms::is_string_constant(const string &str)
|
||||
{
|
||||
return str[0] == '.' || str[0] == '-' || (str[0] >= '0' && str[0] <= '9');
|
||||
}
|
||||
|
||||
VarOrdering::VarOrdering(const VarOrdering &vo, const vector<string> &vnames,
|
||||
const DynamicAtoms &a)
|
||||
: n_stat(vo.n_stat), n_pred(vo.n_pred), n_both(vo.n_both), n_forw(vo.n_forw),
|
||||
der_atoms(vo.der_atoms), positions(vo.positions),
|
||||
outer2y(vo.outer2y), y2outer(vo.y2outer), varnames(vnames), atoms(a)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
VarOrdering::check(int t) const
|
||||
{
|
||||
return positions.find(t) != positions.end();
|
||||
}
|
||||
|
||||
int
|
||||
VarOrdering::get_pos_of(int t) const
|
||||
{
|
||||
auto it = positions.find(t);
|
||||
if (it != positions.end())
|
||||
return it->second;
|
||||
else
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Couldn't find the tree index in VarOrdering::get_pos_of");
|
||||
}
|
||||
|
||||
void
|
||||
VarOrdering::do_general(ord_type ordering)
|
||||
{
|
||||
// auxiliary vectors for setting der_atoms and map
|
||||
vector<int> pred_minus;
|
||||
vector<int> both_minus;
|
||||
vector<int> stat;
|
||||
vector<int> pred_pad;
|
||||
vector<int> both_pad;
|
||||
vector<int> forw_pad;
|
||||
vector<int> both_plus;
|
||||
vector<int> forw_plus;
|
||||
|
||||
// auxiliary vectors for setting y2outer and outer2y
|
||||
vector<int> y2o_stat;
|
||||
vector<int> y2o_pred;
|
||||
vector<int> y2o_both;
|
||||
vector<int> y2o_forw;
|
||||
|
||||
for (unsigned int i = 0; i < varnames.size(); i++)
|
||||
{
|
||||
const string &ss = varnames[i];
|
||||
int lead;
|
||||
int lag;
|
||||
atoms.varspan(ss, lead, lag);
|
||||
if (lag == 0 && lead == 0)
|
||||
{
|
||||
stat.push_back(atoms.index(ss, 0));
|
||||
y2o_stat.push_back(i);
|
||||
}
|
||||
else if (lag == -1 && lead < 1)
|
||||
{
|
||||
pred_minus.push_back(atoms.index(ss, -1));
|
||||
pred_pad.push_back(atoms.index(ss, 0));
|
||||
y2o_pred.push_back(i);
|
||||
}
|
||||
else if (lag > -1 && lead == 1)
|
||||
{
|
||||
forw_pad.push_back(atoms.index(ss, 0));
|
||||
forw_plus.push_back(atoms.index(ss, 1));
|
||||
y2o_forw.push_back(i);
|
||||
}
|
||||
else if (lag == -1 && lead == 1)
|
||||
{
|
||||
both_minus.push_back(atoms.index(ss, -1));
|
||||
both_pad.push_back(atoms.index(ss, 0));
|
||||
both_plus.push_back(atoms.index(ss, 1));
|
||||
y2o_both.push_back(i);
|
||||
}
|
||||
else
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"A wrong lag/lead of a variable in VarOrdering::do_pbspbfbf");
|
||||
}
|
||||
|
||||
// here we fill ords according to ordering
|
||||
vector<int> *ords[8];
|
||||
if (ordering == pbspbfbf)
|
||||
{
|
||||
ords[0] = &pred_minus;
|
||||
ords[1] = &both_minus;
|
||||
ords[2] = &stat;
|
||||
ords[3] = &pred_pad;
|
||||
ords[4] = &both_pad;
|
||||
ords[5] = &forw_pad;
|
||||
ords[6] = &both_plus;
|
||||
ords[7] = &forw_plus;
|
||||
}
|
||||
else if (ordering == bfspbfpb)
|
||||
{
|
||||
ords[0] = &both_plus;
|
||||
ords[1] = &forw_plus;
|
||||
ords[2] = &stat;
|
||||
ords[3] = &pred_pad;
|
||||
ords[4] = &both_pad;
|
||||
ords[5] = &forw_pad;
|
||||
ords[6] = &pred_minus;
|
||||
ords[7] = &both_minus;
|
||||
}
|
||||
else // BEWARE: when implementing a new ordering, check also the code below setting y2outer
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Ordering not implemented in VarOrdering::do_general");
|
||||
|
||||
// make der_atoms and positions
|
||||
int off = 0;
|
||||
for (auto &ord : ords)
|
||||
for (unsigned int j = 0; j < ord->size(); j++, off++)
|
||||
if ((*ord)[j] != -1)
|
||||
{
|
||||
der_atoms.push_back((*ord)[j]);
|
||||
positions.emplace((*ord)[j], off);
|
||||
}
|
||||
|
||||
// set integer constants
|
||||
n_stat = stat.size();
|
||||
n_pred = pred_pad.size();
|
||||
n_both = both_pad.size();
|
||||
n_forw = forw_pad.size();
|
||||
|
||||
// make y2outer mapping
|
||||
y2outer.insert(y2outer.end(), y2o_stat.begin(), y2o_stat.end());
|
||||
y2outer.insert(y2outer.end(), y2o_pred.begin(), y2o_pred.end());
|
||||
y2outer.insert(y2outer.end(), y2o_both.begin(), y2o_both.end());
|
||||
y2outer.insert(y2outer.end(), y2o_forw.begin(), y2o_forw.end());
|
||||
// make outer2y mapping
|
||||
outer2y.resize(y2outer.size(), -1);
|
||||
for (unsigned int i = 0; i < y2outer.size(); i++)
|
||||
outer2y[y2outer[i]] = i;
|
||||
}
|
||||
|
||||
void
|
||||
VarOrdering::do_increasing_time()
|
||||
{
|
||||
// get maxlead and minlag of the variables
|
||||
int mlag, mlead;
|
||||
atoms.varspan(varnames, mlead, mlag);
|
||||
// setup the matrix of tree indices, if there is no occurrence,
|
||||
// the index is set to -1
|
||||
vector<int> ll_init(varnames.size(), -1);
|
||||
vector<vector<int>> tree_ind(mlead-mlag+1, ll_init);
|
||||
for (unsigned int iv = 0; iv < varnames.size(); iv++)
|
||||
{
|
||||
try
|
||||
{
|
||||
const DynamicAtoms::Tlagmap &lmap = atoms.lagmap(varnames[iv]);
|
||||
for (auto it : lmap)
|
||||
{
|
||||
int ll = it.first;
|
||||
int t = it.second;
|
||||
tree_ind[ll-mlag][iv] = t;
|
||||
}
|
||||
}
|
||||
catch (const ogu::Exception &e)
|
||||
{
|
||||
// ignore the error of not found variable in the tree
|
||||
}
|
||||
}
|
||||
|
||||
// setup der_atoms and positions
|
||||
for (int ll = mlag; ll <= mlead; ll++)
|
||||
for (unsigned int iv = 0; iv < varnames.size(); iv++)
|
||||
{
|
||||
int t = tree_ind[ll-mlag][iv];
|
||||
if (t != -1)
|
||||
{
|
||||
der_atoms.push_back(t);
|
||||
int pos = (ll-mlag)*varnames.size() + iv;
|
||||
positions.emplace(t, pos);
|
||||
}
|
||||
}
|
||||
|
||||
// set outer2y and y2outer to identities
|
||||
for (unsigned int iv = 0; iv < varnames.size(); iv++)
|
||||
{
|
||||
outer2y.push_back(iv);
|
||||
y2outer.push_back(iv);
|
||||
}
|
||||
|
||||
// set n_stat, n_pred, n_both, and n_forw
|
||||
for (auto varname : varnames)
|
||||
{
|
||||
int mmlag, mmlead;
|
||||
atoms.varspan(varname, mmlead, mmlag);
|
||||
if (mmlead == 0 && mmlag == 0)
|
||||
n_stat++;
|
||||
else if (mmlead <= 0 && mmlag < 0)
|
||||
n_pred++;
|
||||
else if (mmlead > 0 && mmlag >= 0)
|
||||
n_forw++;
|
||||
else if (mmlead > 0 && mmlag < 0)
|
||||
n_both++;
|
||||
else if (mmlead < mmlag)
|
||||
// variable does not occur in the tree, cound as static
|
||||
n_stat++;
|
||||
else
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"A wrong lag/lead of a variable in VarOrdering::do_increasing_time");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VarOrdering::print() const
|
||||
{
|
||||
std::cout << "nstat=" << n_stat << ", npred=" << n_pred << ", nboth=" << n_both
|
||||
<< ", nforw=" << n_forw << "\n"
|
||||
<< "der_atoms:\n";
|
||||
for (int der_atom : der_atoms)
|
||||
std::cout << " " << der_atom;
|
||||
std::cout << "\nmap:\n";
|
||||
for (auto position : positions)
|
||||
std::cout << " [" << position.first << "→" << position.second << "]";
|
||||
std::cout << "\ny2outer:\n";
|
||||
for (int i : y2outer)
|
||||
std::cout << " " << i;
|
||||
std::cout << "\nouter2y:\n";
|
||||
for (int i : outer2y)
|
||||
std::cout << " " << i;
|
||||
std::cout << "\n";
|
||||
}
|
|
@ -1,470 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OGP_DYNAMIC_ATOMS_H
|
||||
#define OGP_DYNAMIC_ATOMS_H
|
||||
|
||||
#include "formula_parser.hh"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
|
||||
namespace ogp
|
||||
{
|
||||
using std::vector;
|
||||
using std::map;
|
||||
using std::set;
|
||||
using std::string;
|
||||
|
||||
/** Class storing names. We will keep names of variables in
|
||||
* various places, and all these pointers will point to one
|
||||
* storage, which will be responsible for allocation and
|
||||
* deallocation. The main function of the class is to allocate
|
||||
* space for names, and return a pointer of the stored name if
|
||||
* required. */
|
||||
class NameStorage
|
||||
{
|
||||
protected:
|
||||
/** Vector of names allocated, this is the storage. */
|
||||
vector<string> name_store;
|
||||
/** Map useful to quickly decide if the name is already
|
||||
* allocated or not. */
|
||||
set<string> name_set;
|
||||
public:
|
||||
/** Query for the name. If the name has been stored, it
|
||||
* true, otherwise false. */
|
||||
bool
|
||||
query(const string &name) const
|
||||
{
|
||||
return name_set.find(name) != name_set.end();
|
||||
}
|
||||
/** Insert the name if it has not been inserted yet. */
|
||||
void insert(string name);
|
||||
int
|
||||
num() const
|
||||
{
|
||||
return static_cast<int>(name_store.size());
|
||||
}
|
||||
const string &
|
||||
get_name(int i) const
|
||||
{
|
||||
return name_store[i];
|
||||
}
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
};
|
||||
|
||||
class Constants : public AtomValues
|
||||
{
|
||||
public:
|
||||
/** Type for a map mapping tree indices to double values. */
|
||||
using Tconstantmap = map<int, double>;
|
||||
using Tintintmap = map<int, int>;
|
||||
protected:
|
||||
/** Map mapping a tree index of a constant to its double value. */
|
||||
Tconstantmap cmap;
|
||||
public:
|
||||
Constants() = default;
|
||||
/** Copy constructor. */
|
||||
Constants(const Constants &c)
|
||||
: cmap(c.cmap), cinvmap(c.cinvmap)
|
||||
{
|
||||
}
|
||||
/** Copy constructor registering the constants in the given
|
||||
* tree. The mapping from old tree indices to new ones is
|
||||
* traced in tmap. */
|
||||
Constants(const Constants &c, OperationTree &otree, Tintintmap &tmap)
|
||||
{
|
||||
import_constants(c, otree, tmap);
|
||||
}
|
||||
/** Import constants registering their tree indices in the
|
||||
* given tree. The mapping form old tree indices to new ones
|
||||
* is traced in tmap. */
|
||||
void import_constants(const Constants &c, OperationTree &otree, Tintintmap &tmap);
|
||||
/** Implements AtomValues interface. This sets the values to
|
||||
* the evaluation tree EvalTree. */
|
||||
void setValues(EvalTree &et) const override;
|
||||
/** This adds a constant with the given tree index. The
|
||||
* constant must be checked previously and asserted that it
|
||||
* does not exist. */
|
||||
void add_constant(int t, double val);
|
||||
/** Returns true if the tree index is either an hardwired
|
||||
* constant (initial number OperationTree:num_constants in
|
||||
* OperationTree) or the tree index is a registered constant
|
||||
* by add_constant method. */
|
||||
bool is_constant(int t) const;
|
||||
double get_constant_value(int t) const;
|
||||
/** Return -1 if the given string representation of a constant
|
||||
* is not among the constants (double represenations). If it
|
||||
* is, its tree index is returned. */
|
||||
int check(const string &str) const;
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
const Tconstantmap &
|
||||
get_constantmap() const
|
||||
{
|
||||
return cmap;
|
||||
}
|
||||
private:
|
||||
/** Inverse map to Tconstantmap. */
|
||||
using Tconstantinvmap = map<double, int>;
|
||||
/** This is an inverse map to cmap. This is only used for fast
|
||||
* queries for the existing double constants in check
|
||||
* method and add_constant. */
|
||||
Tconstantinvmap cinvmap;
|
||||
};
|
||||
|
||||
/** This class is a parent to Atoms classes which distinguish between
|
||||
* constants (numerical literals), and variables with lags and
|
||||
* leads. This abstraction does not distinguish between a parameter
|
||||
* and a variable without lag or lead. In this sense, everything is a
|
||||
* variable.*/
|
||||
class DynamicAtoms : public Atoms, public Constants
|
||||
{
|
||||
public:
|
||||
/** Definition of a type mapping lags to the indices of the variables. */
|
||||
using Tlagmap = map<int, int>;
|
||||
protected:
|
||||
/** Definition of a type mapping names of the atoms to Tlagmap. */
|
||||
using Tvarmap = map<string, Tlagmap>;
|
||||
/** Definition of a type mapping indices of variables to the variable names. */
|
||||
using Tindexmap = map<int, string>;
|
||||
/** This is just a storage for variable names, since all other
|
||||
* instances of a variable name just point to the memory
|
||||
* allocated by this object. */
|
||||
NameStorage varnames;
|
||||
/** This is the map for variables. Each variable name is
|
||||
* mapped to the Tlagmap, which maps lags/leads to the nulary
|
||||
* term indices in the tree. */
|
||||
Tvarmap vars;
|
||||
/** This is almost inverse map to the vars. It maps variable
|
||||
* indices to the names. A returned name can be in turn used
|
||||
* as a key in vars. */
|
||||
Tindexmap indices;
|
||||
|
||||
/** Number of variables. */
|
||||
int nv{0};
|
||||
/** Minimum lag, if there is at least one lag, than this is a negative number. */
|
||||
int minlag{std::numeric_limits<int>::max()};
|
||||
/** Maximum lead, if there is at least one lead, than this is a positive number. */
|
||||
int maxlead{std::numeric_limits<int>::min()};
|
||||
public:
|
||||
/** Construct empty DynamicAtoms. */
|
||||
DynamicAtoms() = default;
|
||||
/** Check the nulary term identified by its string
|
||||
* representation. The nulary term can be either a constant or
|
||||
* a variable. If constant, -1 is returned so that it could be
|
||||
* assigned regardless if the same constant has already
|
||||
* appeared or not. If variable, then -1 is returned only if
|
||||
* the variable has not been assigned an index, otherwise the
|
||||
* assigned index is returned. */
|
||||
int check(const string &name) const override;
|
||||
/** Assign the nulary term identified by its string
|
||||
* representation. This method should be called when check()
|
||||
* returns -1. */
|
||||
void assign(const string &name, int t) override;
|
||||
/** Return a number of all variables. */
|
||||
int
|
||||
nvar() const override
|
||||
{
|
||||
return nv;
|
||||
}
|
||||
/** Return the vector of variable indices. */
|
||||
vector<int> variables() const override;
|
||||
/** Return max lead and min lag for a variable given by the
|
||||
* index. If a variable cannot be found, the method retursn
|
||||
* the smallest integer as maxlead and the largest integer as
|
||||
* minlag. */
|
||||
void varspan(int t, int &mlead, int &mlag) const;
|
||||
/** Return max lead and min lag for a variable given by the
|
||||
* name (without lead, lag). The same is valid if the variable
|
||||
* name cannot be found. */
|
||||
void varspan(const string &name, int &mlead, int &mlag) const;
|
||||
/** Return max lead and min lag for a vector of variables given by the names. */
|
||||
void varspan(const vector<string> &names, int &mlead, int &mlag) const;
|
||||
/** Return true for all tree indices corresponding to a
|
||||
* variable in the sense of this class. (This is parameters,
|
||||
* exo and endo). Since the semantics of 'variable' will be
|
||||
* changed in subclasses, we use name 'named atom'. These are
|
||||
* all atoms but constants. */
|
||||
bool is_named_atom(int t) const;
|
||||
/** Return index of the variable described by the variable
|
||||
* name and lag/lead. If it doesn't exist, return -1. */
|
||||
int index(const string &name, int ll) const;
|
||||
/** Return true if a variable is referenced, i.e. it has lag
|
||||
* map. */
|
||||
bool is_referenced(const string &name) const;
|
||||
/** Return the lag map for the variable name. */
|
||||
const Tlagmap &lagmap(const string &name) const;
|
||||
/** Return the variable name for the tree index. It throws an
|
||||
* exception if the tree index t is not a named atom. */
|
||||
const string &name(int t) const;
|
||||
/** Return the lead/lag for the tree index. It throws an
|
||||
* exception if the tree index t is not a named atom. */
|
||||
int lead(int t) const;
|
||||
/** Return maximum lead. */
|
||||
int
|
||||
get_maxlead() const
|
||||
{
|
||||
return maxlead;
|
||||
}
|
||||
/** Return minimum lag. */
|
||||
int
|
||||
get_minlag() const
|
||||
{
|
||||
return minlag;
|
||||
}
|
||||
/** Return the name storage to allow querying to other
|
||||
* classes. */
|
||||
const NameStorage &
|
||||
get_name_storage() const
|
||||
{
|
||||
return varnames;
|
||||
}
|
||||
/** Assign the variable with a given lead. The varname must be
|
||||
* from the varnames storage. The method checks if the
|
||||
* variable iwht the given lead/lag is not assigned. If so, an
|
||||
* exception is thrown. */
|
||||
void assign_variable(const string &varname, int ll, int t);
|
||||
/** Unassign the variable with a given lead and given tree
|
||||
* index. The tree index is only provided as a check. An
|
||||
* exception is thrown if the name, ll, and the tree index t
|
||||
* are not consistent. The method also updates nv, indices,
|
||||
* maxlead and minlag. The varname must be from the varnames
|
||||
* storage. */
|
||||
void unassign_variable(const string &varname, int ll, int t);
|
||||
/** Debug print. */
|
||||
void print() const override;
|
||||
protected:
|
||||
/** Do the check for the variable. A subclass may need to
|
||||
* reimplement this so that it could raise an error if the
|
||||
* variable is not among a given list. */
|
||||
virtual int check_variable(const string &name) const;
|
||||
/** Assign the constant. */
|
||||
void assign_constant(const string &name, int t);
|
||||
/** Assign the variable. */
|
||||
void assign_variable(const string &name, int t);
|
||||
/** The method just updates minlag or/and maxlead. Note that
|
||||
* when assigning variables, the update is done when inserting
|
||||
* to the maps, however, if removing a variable, we need to
|
||||
* call this method. */
|
||||
void update_minmaxll();
|
||||
/** The method parses the string to recover a variable name
|
||||
* and lag/lead ll. The variable name doesn't contain a lead/lag. */
|
||||
virtual void parse_variable(const string &in, string &out, int &ll) const = 0;
|
||||
public:
|
||||
/** Return true if the str represents a double.*/
|
||||
static bool is_string_constant(const string &str);
|
||||
};
|
||||
|
||||
/** This class is a parent of all orderings of the dynamic atoms
|
||||
* of variables which can appear before t, at t, or after t. It
|
||||
* encapsulates the ordering, and the information about the number
|
||||
* of static (appearing only at time t) predetermined (appearing
|
||||
* before t and possibly at t), both (appearing before t and after
|
||||
* t and possibly at t) and forward looking (appearing after t and
|
||||
* possibly at t).
|
||||
*
|
||||
* The constructor takes a list of variable names. The class also
|
||||
* provides mapping from the ordering of the variables in the list
|
||||
* (outer) to the new ordering (at time t) and back.
|
||||
*
|
||||
* The user of the subclass must call do_ordering() after
|
||||
* initialization.
|
||||
*
|
||||
* The class contains a few preimplemented methods for
|
||||
* ordering. The class is used in this way: Make a subclass, and
|
||||
* implement pure virtual do_ordering() by just plugging a
|
||||
* preimplemented method, or plugging your own implementation. The
|
||||
* method do_ordering() is called by the user after the constructor.
|
||||
*/
|
||||
class VarOrdering
|
||||
{
|
||||
protected:
|
||||
/** Number of static variables. */
|
||||
int n_stat;
|
||||
/** Number of predetermined variables. */
|
||||
int n_pred;
|
||||
/** Number of both variables. */
|
||||
int n_both;
|
||||
/** Number of forward looking variables. */
|
||||
int n_forw;
|
||||
/** This is a set of tree indices corresponding to the
|
||||
* variables at all times as they occur in the formulas. In
|
||||
* fact, since this is used only for derivatives, the ordering
|
||||
* of this vector is only important for ordering of the
|
||||
* derivatives, in other contexts the ordering is not
|
||||
* important, so it is rather a set of indices.*/
|
||||
vector<int> der_atoms;
|
||||
/** This maps tree index of the variable to the position in
|
||||
* the row of the ordering. One should be careful with making
|
||||
* space in the positions for variables not appearing at time
|
||||
* t. For instance in the pred(t-1), both(t-1), stat(t),
|
||||
* pred(t), both(t), forw(t), both(t+1), forw(t+1) ordering,
|
||||
* the variables x(t-1), y(t-1), x(t+1), z(t-1), z(t), and
|
||||
* z(t+1) having tree indices 6,5,4,3,2,1 will be ordered as
|
||||
* follows: y(t-1), x(t-1), z(t-1), [y(t)], [x(t)], z(t),
|
||||
* x(t+1), where a bracketed expresion means non-existent by
|
||||
* occupying a space. The map thus will look as follows:
|
||||
* {5→0, 6→1, 3→2, 2→5, 3→6}. Note that nothing is mapped
|
||||
* to positions 3 and 4. */
|
||||
map<int, int> positions;
|
||||
/** This maps an ordering of the list of variables in
|
||||
* constructor to the new ordering (at time t). The length is
|
||||
* the number of variables. */
|
||||
vector<int> outer2y;
|
||||
/** This maps a new ordering to the ordering of the list of
|
||||
* variables in constructor (at time t). The length is the
|
||||
* number of variables. */
|
||||
vector<int> y2outer;
|
||||
/** This is just a reference for variable names to keep it
|
||||
* from constructor to do_ordering() implementations. */
|
||||
const vector<string> &varnames;
|
||||
/** This is just a reference to atoms to keep it from
|
||||
* constructor to do_ordering() implementations. */
|
||||
const DynamicAtoms &atoms;
|
||||
public:
|
||||
/** This is an enum type for an ordering type implemented by
|
||||
* do_general. */
|
||||
enum ord_type { pbspbfbf, bfspbfpb };
|
||||
/** Construct the ordering of the variables given by the names
|
||||
* with their dynamic occurrences defined by the atoms. It
|
||||
* calls the virtual method do_ordering which can be
|
||||
* reimplemented. */
|
||||
VarOrdering(const vector<string> &vnames, const DynamicAtoms &a)
|
||||
: n_stat(0), n_pred(0), n_both(0), n_forw(0), varnames(vnames), atoms(a)
|
||||
{
|
||||
}
|
||||
VarOrdering(const VarOrdering &vo, const vector<string> &vnames,
|
||||
const DynamicAtoms &a);
|
||||
VarOrdering(const VarOrdering &vo) = delete;
|
||||
virtual std::unique_ptr<VarOrdering> clone(const vector<string> &vnames,
|
||||
const DynamicAtoms &a) const = 0;
|
||||
/** Destructor does nothing here. */
|
||||
virtual ~VarOrdering() = default;
|
||||
/** This is the method setting the ordering and the map. A
|
||||
* subclass must reimplement it, possibly using a
|
||||
* preimplemented ordering. This method must be called by the
|
||||
* user after the class has been created. */
|
||||
virtual void do_ordering() = 0;
|
||||
/** Return number of static. */
|
||||
int
|
||||
nstat() const
|
||||
{
|
||||
return n_stat;
|
||||
}
|
||||
/** Return number of predetermined. */
|
||||
int
|
||||
npred() const
|
||||
{
|
||||
return n_pred;
|
||||
}
|
||||
/** Return number of both. */
|
||||
int
|
||||
nboth() const
|
||||
{
|
||||
return n_both;
|
||||
}
|
||||
/** Return number of forward looking. */
|
||||
int
|
||||
nforw() const
|
||||
{
|
||||
return n_forw;
|
||||
}
|
||||
/** Return the set of tree indices for derivatives. */
|
||||
const vector<int> &
|
||||
get_der_atoms() const
|
||||
{
|
||||
return der_atoms;
|
||||
}
|
||||
/** Return the y2outer. */
|
||||
const vector<int> &
|
||||
get_y2outer() const
|
||||
{
|
||||
return y2outer;
|
||||
}
|
||||
/** Return the outer2y. */
|
||||
const vector<int> &
|
||||
get_outer2y() const
|
||||
{
|
||||
return outer2y;
|
||||
}
|
||||
/** Query the atom given by the tree index. True is returned
|
||||
* if the atom is one of the variables in the object. */
|
||||
bool check(int t) const;
|
||||
/** Return the position of the atom (nulary term) given by a
|
||||
* tree index. It is a lookup to the map. If the atom cannot
|
||||
* be found, the exception is raised. */
|
||||
int get_pos_of(int t) const;
|
||||
/** This returns a length of ordered row of atoms. In all
|
||||
* cases so far, it does not depend on the ordering and it is
|
||||
* as follows. */
|
||||
int
|
||||
length() const
|
||||
{
|
||||
return n_stat+2*n_pred+3*n_both+2*n_forw;
|
||||
}
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
protected:
|
||||
/** This is a general ordering method which orders the
|
||||
* variables by the given ordering ord_type. See documentation
|
||||
* for respective do_ methods. */
|
||||
void do_general(ord_type ordering);
|
||||
/** This is a preimplemented ordering for do_ordering()
|
||||
* method. It assumes that the variables appear only at time
|
||||
* t-1, t, t+1. It orders the atoms as pred(t-1), both(t-1),
|
||||
* stat(t), pred(t), both(t), forw(t), both(t+1),
|
||||
* forw(t+1). It builds the der_atoms, the map of positions,
|
||||
* as well as y2outer and outer2y. */
|
||||
void
|
||||
do_pbspbfbf()
|
||||
{
|
||||
do_general(pbspbfbf);
|
||||
}
|
||||
/** This is a preimplemented ordering for do_ordering()
|
||||
* method. It assumes that the variables appear only at time
|
||||
* t-1, t, t+1. It orders the atoms as both(t+1), forw(t+1),
|
||||
* stat(t), pred(t), both(t), forw(t), pred(t-1),
|
||||
* both(t-1). It builds the der_atoms, the map of positions,
|
||||
* as well as y2outer and outer2y. */
|
||||
void
|
||||
do_bfspbfpb()
|
||||
{
|
||||
do_general(bfspbfpb);
|
||||
}
|
||||
/** This is a preimplemented ordering for do_ordering()
|
||||
* method. It makes no assumptions about occurences of
|
||||
* variables at different times. It orders the atoms with
|
||||
* increasing time keeping the given ordering within one
|
||||
* time. This implies that y2outer and outer2y will be
|
||||
* identities. The der_atoms will be just a sequence of atoms
|
||||
* from the least to the most time preserving the order of atoms
|
||||
* within one time. */
|
||||
void do_increasing_time();
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,536 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019-2022 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "utils/cc/exception.hh"
|
||||
|
||||
#include "parser_exception.hh"
|
||||
#include "fine_atoms.hh"
|
||||
|
||||
using namespace ogp;
|
||||
|
||||
AllvarOuterOrdering::AllvarOuterOrdering(const vector<string> &allvar_outer,
|
||||
const FineAtoms &a)
|
||||
: atoms(a), allvar(),
|
||||
endo2all(a.get_endovars().size(), -1),
|
||||
exo2all(a.get_exovars().size(), -1)
|
||||
{
|
||||
// fill in the allvar from allvar_outer
|
||||
for (const auto &s : allvar_outer)
|
||||
{
|
||||
if (atoms.varnames.query(s))
|
||||
allvar.push_back(s);
|
||||
else
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Variable " + s + " is not a declared symbol in AllvarOuterOrdering constructor");
|
||||
}
|
||||
|
||||
// fill in endo2all and exo2all
|
||||
for (unsigned int i = 0; i < allvar.size(); i++)
|
||||
{
|
||||
auto it = atoms.endo_outer_map.find(allvar[i]);
|
||||
if (it != atoms.endo_outer_map.end())
|
||||
endo2all[it->second] = i;
|
||||
else
|
||||
{
|
||||
it = atoms.exo_outer_map.find(allvar[i]);
|
||||
if (it != atoms.exo_outer_map.end())
|
||||
exo2all[it->second] = i;
|
||||
else
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Name " + allvar[i] + " is neither endogenous nor exogenous variable in AllvarOuterOrdering constructor");
|
||||
}
|
||||
}
|
||||
|
||||
// check whether everything has been filled
|
||||
unsigned int iendo = 0;
|
||||
while (iendo < endo2all.size() && endo2all[iendo] != -1)
|
||||
iendo++;
|
||||
unsigned int iexo = 0;
|
||||
while (iexo < exo2all.size() && exo2all[iexo] != -1)
|
||||
iexo++;
|
||||
if (iendo < endo2all.size())
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Endogenous variable " + atoms.get_endovars()[iendo]
|
||||
+" not found in outer all ordering in AllvarOuterOrdering constructor");
|
||||
if (iexo < exo2all.size())
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Exogenous variable " + atoms.get_exovars()[iexo]
|
||||
+" not found in outer all ordering in AllvarOuterOrdering constructor");
|
||||
}
|
||||
|
||||
AllvarOuterOrdering::AllvarOuterOrdering(const AllvarOuterOrdering &avo,
|
||||
const FineAtoms &a)
|
||||
: atoms(a), allvar(avo.allvar),
|
||||
endo2all(avo.endo2all),
|
||||
exo2all(avo.exo2all)
|
||||
{
|
||||
}
|
||||
|
||||
FineAtoms::FineAtoms(const FineAtoms &fa)
|
||||
: DynamicAtoms(fa), params(), endovars(), exovars(),
|
||||
der_atoms(fa.der_atoms),
|
||||
endo_atoms_map(fa.endo_atoms_map),
|
||||
exo_atoms_map(fa.exo_atoms_map)
|
||||
{
|
||||
// fill in params
|
||||
for (const auto ¶m : fa.params)
|
||||
{
|
||||
if (!varnames.query(param))
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Parameter " + param + " does not exist in FineAtoms copy cosntructor");
|
||||
params.push_back(param);
|
||||
param_outer_map.emplace(param, params.size()-1);
|
||||
}
|
||||
// fill in endovars
|
||||
for (const auto &endovar : fa.endovars)
|
||||
{
|
||||
if (!varnames.query(endovar))
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Endo variable " + endovar + " does not exist in FineAtoms copy constructor");
|
||||
endovars.push_back(endovar);
|
||||
endo_outer_map.emplace(endovar, endovars.size()-1);
|
||||
}
|
||||
// fill in exovars
|
||||
for (const auto &exovar : fa.exovars)
|
||||
{
|
||||
if (!varnames.query(exovar))
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Exo variable " + exovar + " does not exist in FineAtoms copy cosntructor");
|
||||
exovars.push_back(exovar);
|
||||
exo_outer_map.emplace(exovar, exovars.size()-1);
|
||||
}
|
||||
|
||||
if (fa.endo_order)
|
||||
endo_order = fa.endo_order->clone(endovars, *this);
|
||||
|
||||
if (fa.exo_order)
|
||||
exo_order = fa.exo_order->clone(exovars, *this);
|
||||
|
||||
if (fa.allvar_order)
|
||||
allvar_order = std::make_unique<AllvarOuterOrdering>(*(fa.allvar_order), *this);
|
||||
}
|
||||
|
||||
int
|
||||
FineAtoms::check_variable(const string &name) const
|
||||
{
|
||||
string str;
|
||||
int ll;
|
||||
parse_variable(name, str, ll);
|
||||
if (varnames.query(str))
|
||||
return DynamicAtoms::check_variable(name);
|
||||
else
|
||||
{
|
||||
throw ParserException("Variable <"+str+"> not declared.", 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
FineAtoms::num_exo_periods() const
|
||||
{
|
||||
int mlead, mlag;
|
||||
exovarspan(mlead, mlag);
|
||||
return mlead-mlag+1;
|
||||
}
|
||||
|
||||
void
|
||||
FineAtoms::parsing_finished(VarOrdering::ord_type ot)
|
||||
{
|
||||
make_internal_orderings(ot);
|
||||
|
||||
// by default, concatenate outer endo and outer exo and make it as
|
||||
// allvar outer:
|
||||
vector<string> allvar_tmp;
|
||||
allvar_tmp.insert(allvar_tmp.end(), endovars.begin(), endovars.end());
|
||||
allvar_tmp.insert(allvar_tmp.end(), exovars.begin(), exovars.end());
|
||||
|
||||
allvar_order = std::make_unique<AllvarOuterOrdering>(allvar_tmp, *this);
|
||||
}
|
||||
|
||||
void
|
||||
FineAtoms::parsing_finished(VarOrdering::ord_type ot,
|
||||
const vector<string> &allvar)
|
||||
{
|
||||
make_internal_orderings(ot);
|
||||
allvar_order = std::make_unique<AllvarOuterOrdering>(allvar, *this);
|
||||
}
|
||||
|
||||
const vector<string> &
|
||||
FineAtoms::get_allvar() const
|
||||
{
|
||||
if (!allvar_order)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"FineAtoms::get_allvars called before parsing_finished");
|
||||
|
||||
return allvar_order->get_allvar();
|
||||
}
|
||||
|
||||
const vector<int> &
|
||||
FineAtoms::outer_endo2all() const
|
||||
{
|
||||
if (!allvar_order)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"FineAtoms::outer_endo2all called before parsing_finished");
|
||||
|
||||
return allvar_order->get_endo2all();
|
||||
}
|
||||
|
||||
const vector<int> &
|
||||
FineAtoms::outer_exo2all() const
|
||||
{
|
||||
if (!allvar_order)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"FineAtoms::outer_exo2all called before parsing_finished");
|
||||
|
||||
return allvar_order->get_exo2all();
|
||||
}
|
||||
|
||||
vector<int>
|
||||
FineAtoms::variables() const
|
||||
{
|
||||
if (endo_order)
|
||||
return der_atoms;
|
||||
else
|
||||
{
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"FineAtoms::variables called before parsing_finished");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
FineAtoms::nstat() const
|
||||
{
|
||||
if (endo_order)
|
||||
return endo_order->nstat();
|
||||
else
|
||||
{
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"FineAtoms::nstat called before parsing_finished");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
FineAtoms::npred() const
|
||||
{
|
||||
if (endo_order)
|
||||
return endo_order->npred();
|
||||
else
|
||||
{
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"FineAtoms::npred called before parsing_finished");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
FineAtoms::nboth() const
|
||||
{
|
||||
if (endo_order)
|
||||
return endo_order->nboth();
|
||||
else
|
||||
{
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"FineAtoms::nboth called before parsing_finished");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
FineAtoms::nforw() const
|
||||
{
|
||||
if (endo_order)
|
||||
return endo_order->nforw();
|
||||
else
|
||||
{
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"FineAtoms::nforw called before parsing_finished");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
FineAtoms::get_pos_of_endo(int t) const
|
||||
{
|
||||
if (endo_order)
|
||||
return endo_order->get_pos_of(t);
|
||||
else
|
||||
{
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"FineAtoms::get_pos_of_endo called before parsing_finished");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
FineAtoms::get_pos_of_exo(int t) const
|
||||
{
|
||||
if (exo_order)
|
||||
return exo_order->get_pos_of(t);
|
||||
else
|
||||
{
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"FineAtoms::get_pos_of_exo called before parsing_finished");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
FineAtoms::get_pos_of_all(int t) const
|
||||
{
|
||||
if (endo_order && exo_order)
|
||||
{
|
||||
if (endo_order->check(t))
|
||||
return endo_order->get_pos_of(t);
|
||||
else if (exo_order->check(t))
|
||||
return endo_order->length() + exo_order->get_pos_of(t);
|
||||
else
|
||||
{
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Atom is not endo nor exo in FineAtoms::get_pos_of_all");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"FineAtoms::get_pos_of_exo called before parsing_finished");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
const vector<int> &
|
||||
FineAtoms::y2outer_endo() const
|
||||
{
|
||||
if (!endo_order)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"FineAtoms::y2outer_endo called before parsing_finished");
|
||||
return endo_order->get_y2outer();
|
||||
}
|
||||
|
||||
const vector<int> &
|
||||
FineAtoms::outer2y_endo() const
|
||||
{
|
||||
if (!endo_order)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"FineAtoms::outer2y_endo called before parsing_finished");
|
||||
return endo_order->get_outer2y();
|
||||
}
|
||||
|
||||
const vector<int> &
|
||||
FineAtoms::y2outer_exo() const
|
||||
{
|
||||
if (!exo_order)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"FineAtoms::y2outer_endo called before parsing_finished");
|
||||
return exo_order->get_y2outer();
|
||||
}
|
||||
|
||||
const vector<int> &
|
||||
FineAtoms::outer2y_exo() const
|
||||
{
|
||||
if (!exo_order)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"FineAtoms::outer2y_exo called before parsing_finished");
|
||||
return exo_order->get_outer2y();
|
||||
}
|
||||
|
||||
const vector<int> &
|
||||
FineAtoms::get_endo_atoms_map() const
|
||||
{
|
||||
if (!endo_order)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"FineAtoms::get_endo_atoms_map called before parsing_finished");
|
||||
return endo_atoms_map;
|
||||
}
|
||||
|
||||
const vector<int> &
|
||||
FineAtoms::get_exo_atoms_map() const
|
||||
{
|
||||
if (!exo_order)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"FineAtoms::get_exo_atoms_map called before parsing_finished");
|
||||
return exo_atoms_map;
|
||||
}
|
||||
|
||||
int
|
||||
FineAtoms::name2outer_param(const string &name) const
|
||||
{
|
||||
auto it = param_outer_map.find(name);
|
||||
if (it == param_outer_map.end())
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Name is not a parameter in FineAtoms::name2outer_param");
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int
|
||||
FineAtoms::name2outer_endo(const string &name) const
|
||||
{
|
||||
auto it = endo_outer_map.find(name);
|
||||
if (it == endo_outer_map.end())
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Name is not an endogenous variable in FineAtoms::name2outer_endo");
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int
|
||||
FineAtoms::name2outer_exo(const string &name) const
|
||||
{
|
||||
auto it = exo_outer_map.find(name);
|
||||
if (it == exo_outer_map.end())
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Name is not an exogenous variable in FineAtoms::name2outer_exo");
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int
|
||||
FineAtoms::name2outer_allvar(const string &name) const
|
||||
{
|
||||
if (!allvar_order)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"FineAtoms::name2outer_allvar called beore parsing_finished");
|
||||
|
||||
auto it = endo_outer_map.find(name);
|
||||
if (it != endo_outer_map.end())
|
||||
return allvar_order->get_endo2all()[it->second];
|
||||
else
|
||||
{
|
||||
it = exo_outer_map.find(name);
|
||||
if (it != exo_outer_map.end())
|
||||
return allvar_order->get_exo2all()[it->second];
|
||||
}
|
||||
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Name " + name + " is neither endo nor exo variable in FineAtoms::name2outer_allvar");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
FineAtoms::register_uniq_endo(string name)
|
||||
{
|
||||
if (varnames.query(name))
|
||||
throw ogp::ParserException("Endogenous variable <"+name+"> is not unique.", 0);
|
||||
varnames.insert(name);
|
||||
endovars.push_back(name);
|
||||
endo_outer_map.emplace(std::move(name), endovars.size()-1);
|
||||
}
|
||||
|
||||
void
|
||||
FineAtoms::register_uniq_exo(string name)
|
||||
{
|
||||
if (varnames.query(name))
|
||||
throw ogp::ParserException("Exogenous variable <"+name+"> is not unique.", 0);
|
||||
varnames.insert(name);
|
||||
exovars.push_back(name);
|
||||
exo_outer_map.emplace(std::move(name), exovars.size()-1);
|
||||
}
|
||||
|
||||
void
|
||||
FineAtoms::register_uniq_param(string name)
|
||||
{
|
||||
if (varnames.query(name))
|
||||
throw ogp::ParserException("Parameter <"+name+"> is not unique.", 0);
|
||||
varnames.insert(name);
|
||||
params.push_back(name);
|
||||
param_outer_map.emplace(std::move(name), params.size()-1);
|
||||
}
|
||||
|
||||
void
|
||||
FineAtoms::make_internal_orderings(VarOrdering::ord_type ot)
|
||||
{
|
||||
bool endo_ordering_done = false;
|
||||
bool exo_ordering_done = false;
|
||||
|
||||
order_type = ot;
|
||||
|
||||
int mlead, mlag;
|
||||
endovarspan(mlead, mlag);
|
||||
if (mlag >= -1 && mlead <= 1)
|
||||
{
|
||||
// make endo ordering
|
||||
if (ot == VarOrdering::pbspbfbf)
|
||||
endo_order = std::make_unique<EndoVarOrdering1>(endovars, *this);
|
||||
else
|
||||
endo_order = std::make_unique<EndoVarOrdering2>(endovars, *this);
|
||||
endo_order->do_ordering();
|
||||
endo_ordering_done = true;
|
||||
}
|
||||
|
||||
exovarspan(mlead, mlag);
|
||||
if (mlag == 0 && mlead == 0)
|
||||
{
|
||||
// make exo ordering
|
||||
exo_order = std::make_unique<ExoVarOrdering>(exovars, *this);
|
||||
exo_order->do_ordering();
|
||||
exo_ordering_done = true;
|
||||
}
|
||||
|
||||
if (endo_ordering_done && exo_ordering_done)
|
||||
{
|
||||
// concatenate der atoms from endo_order and exo_order
|
||||
der_atoms.clear();
|
||||
der_atoms.insert(der_atoms.end(),
|
||||
endo_order->get_der_atoms().begin(),
|
||||
endo_order->get_der_atoms().end());
|
||||
der_atoms.insert(der_atoms.end(),
|
||||
exo_order->get_der_atoms().begin(),
|
||||
exo_order->get_der_atoms().end());
|
||||
|
||||
// create endo_atoms_map; der_atoms is a concatenation, so it is easy
|
||||
int endo_atoms = endo_order->get_der_atoms().size();
|
||||
endo_atoms_map.clear();
|
||||
for (int i = 0; i < endo_atoms; i++)
|
||||
endo_atoms_map.push_back(i);
|
||||
// create exo_atoms_map
|
||||
int exo_atoms = exo_order->get_der_atoms().size();
|
||||
exo_atoms_map.clear();
|
||||
for (int i = 0; i < exo_atoms; i++)
|
||||
exo_atoms_map.push_back(endo_atoms + i);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FineAtoms::print() const
|
||||
{
|
||||
DynamicAtoms::print();
|
||||
if (endo_order)
|
||||
{
|
||||
std::cout << "Endo ordering:\n";
|
||||
endo_order->print();
|
||||
}
|
||||
else
|
||||
std::cout << "Endo ordering not created.\n";
|
||||
|
||||
if (exo_order)
|
||||
{
|
||||
std::cout << "Exo ordering:\n";
|
||||
exo_order->print();
|
||||
}
|
||||
else
|
||||
std::cout << "Exo ordering not created.\n";
|
||||
|
||||
std::cout << "endo atoms map:\n";
|
||||
for (unsigned int i = 0; i < endo_atoms_map.size(); i++)
|
||||
std::cout << i << " → " << endo_atoms_map[i] << "\n";
|
||||
std::cout << "exo atoms map:\n";
|
||||
for (unsigned int i = 0; i < exo_atoms_map.size(); i++)
|
||||
std::cout << i << " → " << exo_atoms_map[i] << "\n";
|
||||
}
|
|
@ -1,431 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OGP_FINE_ATOMS_H
|
||||
#define OGP_FINE_ATOMS_H
|
||||
|
||||
#include "dynamic_atoms.hh"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
namespace ogp
|
||||
{
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
||||
/** This is just ordering used for endogenous variables. It
|
||||
* assumes that we have only time t-1, t, and t+1, orders them as
|
||||
* pred(t-1), both(t-1), stat(t), pred(t), both(t), forw(t),
|
||||
* both(t+1), forw(t+1). */
|
||||
class EndoVarOrdering1 : public VarOrdering
|
||||
{
|
||||
public:
|
||||
EndoVarOrdering1(const vector<string> &vnames, const DynamicAtoms &a)
|
||||
: VarOrdering(vnames, a)
|
||||
{
|
||||
}
|
||||
EndoVarOrdering1(const EndoVarOrdering1 &vo, const vector<string> &vnames,
|
||||
const DynamicAtoms &a)
|
||||
: VarOrdering(vo, vnames, a)
|
||||
{
|
||||
}
|
||||
std::unique_ptr<VarOrdering>
|
||||
clone(const vector<string> &vnames, const DynamicAtoms &a) const override
|
||||
{
|
||||
return std::make_unique<EndoVarOrdering1>(*this, vnames, a);
|
||||
}
|
||||
void
|
||||
do_ordering() override
|
||||
{
|
||||
do_pbspbfbf();
|
||||
}
|
||||
};
|
||||
|
||||
/** This is just another ordering used for endogenous
|
||||
* variables. It assumes that we have only time t-1, t, and t+1,
|
||||
* orders them as both(t+1), forw(t+1), pred(t-1), both(t-1),
|
||||
* stat(t), pred(t), both(t), forw(t). */
|
||||
class EndoVarOrdering2 : public VarOrdering
|
||||
{
|
||||
public:
|
||||
EndoVarOrdering2(const vector<string> &vnames, const DynamicAtoms &a)
|
||||
: VarOrdering(vnames, a)
|
||||
{
|
||||
}
|
||||
EndoVarOrdering2(const EndoVarOrdering2 &vo, const vector<string> &vnames,
|
||||
const DynamicAtoms &a)
|
||||
: VarOrdering(vo, vnames, a)
|
||||
{
|
||||
}
|
||||
std::unique_ptr<VarOrdering>
|
||||
clone(const vector<string> &vnames, const DynamicAtoms &a) const override
|
||||
{
|
||||
return std::make_unique<EndoVarOrdering2>(*this, vnames, a);
|
||||
}
|
||||
void
|
||||
do_ordering() override
|
||||
{
|
||||
do_bfspbfpb();
|
||||
}
|
||||
};
|
||||
|
||||
/** This is just ordering used for exogenous variables. It makes
|
||||
* no assumptions about their timing. It orders them from the
|
||||
* least time to the latest time. */
|
||||
class ExoVarOrdering : public VarOrdering
|
||||
{
|
||||
public:
|
||||
ExoVarOrdering(const vector<string> &vnames, const DynamicAtoms &a)
|
||||
: VarOrdering(vnames, a)
|
||||
{
|
||||
}
|
||||
ExoVarOrdering(const ExoVarOrdering &vo, const vector<string> &vnames,
|
||||
const DynamicAtoms &a)
|
||||
: VarOrdering(vo, vnames, a)
|
||||
{
|
||||
}
|
||||
std::unique_ptr<VarOrdering>
|
||||
clone(const vector<string> &vnames, const DynamicAtoms &a) const override
|
||||
{
|
||||
return std::make_unique<ExoVarOrdering>(*this, vnames, a);
|
||||
}
|
||||
void
|
||||
do_ordering() override
|
||||
{
|
||||
do_increasing_time();
|
||||
}
|
||||
};
|
||||
|
||||
class FineAtoms;
|
||||
|
||||
/** This class provides an outer ordering of all variables (endo
|
||||
* and exo). It maps the ordering to the particular outer
|
||||
* orderings of endo and exo. It works tightly with the FineAtoms
|
||||
* class. */
|
||||
class AllvarOuterOrdering
|
||||
{
|
||||
protected:
|
||||
/** Type for a map mapping a variable name to an integer. */
|
||||
using Tvarintmap = map<string, int>;
|
||||
/** Reference to atoms. */
|
||||
const FineAtoms &atoms;
|
||||
/** The vector of all endo and exo variables in outer
|
||||
* ordering. The pointers point to storage in atoms. */
|
||||
vector<string> allvar;
|
||||
/** The mapping from outer endogenous to outer all. For
|
||||
* example endo2all[0] is the order of the first outer
|
||||
* endogenous variable in the allvar ordering. */
|
||||
vector<int> endo2all;
|
||||
/** The mapping from outer exogenous to outer all. For example
|
||||
* exo2all[0] is the order of the first outer exogenous
|
||||
* variables in the allvar ordering. */
|
||||
vector<int> exo2all;
|
||||
public:
|
||||
/** Construct the allvar outer ordering from the provided
|
||||
* sequence of endo and exo names. The names can have an
|
||||
* arbitrary storage, the storage is transformed to the atoms
|
||||
* storage. An exception is thrown if either the list is not
|
||||
* exhaustive, or some string is not a variable. */
|
||||
AllvarOuterOrdering(const vector<string> &allvar_outer, const FineAtoms &a);
|
||||
/** Copy constructor using the storage of provided atoms. */
|
||||
AllvarOuterOrdering(const AllvarOuterOrdering &allvar_outer, const FineAtoms &a);
|
||||
/** Return endo2all mapping. */
|
||||
const vector<int> &
|
||||
get_endo2all() const
|
||||
{
|
||||
return endo2all;
|
||||
}
|
||||
/** Return exo2all mapping. */
|
||||
const vector<int> &
|
||||
get_exo2all() const
|
||||
{
|
||||
return exo2all;
|
||||
}
|
||||
/** Return the allvar ordering. */
|
||||
const vector<string> &
|
||||
get_allvar() const
|
||||
{
|
||||
return allvar;
|
||||
}
|
||||
};
|
||||
|
||||
/** This class refines the DynamicAtoms by distinguishing among
|
||||
* parameters (no lag and leads) and endogenous and exogenous
|
||||
* variables (with lags and leads). For parameters, endogenous and
|
||||
* exogenous, it defines outer orderings and internal
|
||||
* orderings. The internal orderings are created by
|
||||
* parsing_finished() method when it is sure that no new variables
|
||||
* would be registered. The outer orderings are given by the order
|
||||
* of calls of registering methods.
|
||||
*
|
||||
* In addition, the class also defines outer ordering of
|
||||
* endogenous and exogenous variables. This is input as a
|
||||
* parameter to parsing_finished(). By default, this whole outer
|
||||
* ordering is just a concatenation of outer ordering of
|
||||
* endogenous and exogenous variables.
|
||||
*
|
||||
* The internal ordering of all endo and exo variables is just a
|
||||
* concatenation of endo and exo variables in their internal
|
||||
* orderings. This is the ordering with respect to which all
|
||||
* derivatives are taken. */
|
||||
class FineAtoms : public DynamicAtoms
|
||||
{
|
||||
friend class AllvarOuterOrdering;
|
||||
protected:
|
||||
using Tvarintmap = map<string, int>;
|
||||
private:
|
||||
/** The vector of parameters names. The order gives the order
|
||||
* the data is communicated with outside world. */
|
||||
vector<string> params;
|
||||
/** A map mapping a name of a parameter to an index in the outer
|
||||
* ordering. */
|
||||
Tvarintmap param_outer_map;
|
||||
/** The vector of endogenous variables. This defines the order
|
||||
* like parameters. */
|
||||
vector<string> endovars;
|
||||
/** A map mapping a name of an endogenous variable to an index
|
||||
* in the outer ordering. */
|
||||
Tvarintmap endo_outer_map;
|
||||
/** The vector of exogenous variables. Also defines the order
|
||||
* like parameters and endovars. */
|
||||
vector<string> exovars;
|
||||
/** A map mapping a name of an exogenous variable to an index
|
||||
* in the outer ordering. */
|
||||
Tvarintmap exo_outer_map;
|
||||
|
||||
protected:
|
||||
/** This is the internal ordering of all atoms corresponding
|
||||
* to endogenous variables. It is constructed by
|
||||
* parsing_finished() method, which should be called after all
|
||||
* parsing jobs have been finished. */
|
||||
std::unique_ptr<VarOrdering> endo_order;
|
||||
/** This is the internal ordering of all atoms corresponding
|
||||
* to exogenous variables. It has the same handling as
|
||||
* endo_order. */
|
||||
std::unique_ptr<VarOrdering> exo_order;
|
||||
/** This is the all variables outer ordering. It is
|
||||
* constructed by parsing finished. */
|
||||
std::unique_ptr<AllvarOuterOrdering> allvar_order;
|
||||
/** This vector defines a set of atoms as tree indices used
|
||||
* for differentiation. The order of the atoms in this vector
|
||||
* defines ordering of the derivative tensors. The ordering is
|
||||
* a concatenation of atoms from endo_order and then
|
||||
* exo_order. This vector is setup by parsing_finished() and
|
||||
* is returned by variables(). */
|
||||
vector<int> der_atoms;
|
||||
/** This is a mapping from endogenous atoms to all atoms in
|
||||
* der_atoms member. The mapping maps index in endogenous atom
|
||||
* ordering to index (not value) in der_atoms. It is useful if
|
||||
* one wants to evaluate derivatives wrt only endogenous
|
||||
* variables. It is set by parsing_finished(). By definition,
|
||||
* it is monotone. */
|
||||
vector<int> endo_atoms_map;
|
||||
/** This is a mapping from exogenous atoms to all atoms in
|
||||
* der_atoms member. It is the same as endo_atoms_map for
|
||||
* atoms of exogenous variables. */
|
||||
vector<int> exo_atoms_map;
|
||||
public:
|
||||
FineAtoms() = default;
|
||||
FineAtoms(const FineAtoms &fa);
|
||||
/** Deletes endo_order and exo_order. */
|
||||
~FineAtoms() override = default;
|
||||
/** Overrides DynamicAtoms::check_variable so that the error
|
||||
* would be raised if the variable name is not declared. A
|
||||
* variable is declared by inserting it to
|
||||
* DynamicAtoms::varnames. This is a responsibility of a
|
||||
* subclass. */
|
||||
int check_variable(const string &name) const override;
|
||||
/** This calculates min lag and max lead of endogenous variables. */
|
||||
void
|
||||
endovarspan(int &mlead, int &mlag) const
|
||||
{
|
||||
varspan(endovars, mlead, mlag);
|
||||
}
|
||||
/** This calculates mim lag and max lead of exogenous variables. */
|
||||
void
|
||||
exovarspan(int &mlead, int &mlag) const
|
||||
{
|
||||
varspan(exovars, mlead, mlag);
|
||||
}
|
||||
/** This calculates the number of periods in which at least
|
||||
* one exogenous variable occurs. */
|
||||
int num_exo_periods() const;
|
||||
/** Return an (external) ordering of parameters. */
|
||||
const vector<string> &
|
||||
get_params() const
|
||||
{
|
||||
return params;
|
||||
}
|
||||
/** Return an external ordering of endogenous variables. */
|
||||
const vector<string> &
|
||||
get_endovars() const
|
||||
{
|
||||
return endovars;
|
||||
}
|
||||
/** Return an external ordering of exogenous variables. */
|
||||
const vector<string> &
|
||||
get_exovars() const
|
||||
{
|
||||
return exovars;
|
||||
}
|
||||
/** This constructs internal orderings and makes the indices
|
||||
* returned by variables method available. Further it
|
||||
* constructs outer ordering of all variables by a simple
|
||||
* concatenation of outer endogenous and outer exogenous. In
|
||||
* addition, it makes nstat, npred, nboth, nforw available. */
|
||||
void parsing_finished(VarOrdering::ord_type ot);
|
||||
/** This does the same thing as
|
||||
* parsing_finished(VarOrdering::ord_type) plus it allows for
|
||||
* inputing a different outer ordering of all variables. The
|
||||
* ordering is input as a list of strings, their storage can
|
||||
* be arbitrary. */
|
||||
void parsing_finished(VarOrdering::ord_type ot, const vector<string> &avo);
|
||||
/** Return the external ordering of all variables (endo and
|
||||
* exo). This is either the second argument to
|
||||
* parsing_finished or the default external ordering. This
|
||||
* must be called only after parsing_finished. */
|
||||
const vector<string> &get_allvar() const;
|
||||
/** Return the map from outer ordering of endo variables to
|
||||
* the allvar ordering. This must be called only after
|
||||
* parsing_finished. */
|
||||
const vector<int> &outer_endo2all() const;
|
||||
/** Return the map from outer ordering of exo variables to
|
||||
* the allvar ordering. This must be called only after
|
||||
* parsing_finished. */
|
||||
const vector<int> &outer_exo2all() const;
|
||||
/** Return the atoms with respect to which we are going to
|
||||
* differentiate. This must be called after
|
||||
* parsing_finished. */
|
||||
vector<int> variables() const override;
|
||||
/** Return the number of static. */
|
||||
int nstat() const;
|
||||
/** Return the number of predetermined. */
|
||||
int npred() const;
|
||||
/** Return the number of both. */
|
||||
int nboth() const;
|
||||
/** Return the number of forward looking. */
|
||||
int nforw() const;
|
||||
/** Return the index of an endogenous atom given by tree index in
|
||||
* the endo ordering. This must be also called only after
|
||||
* parsing_finished(). */
|
||||
int get_pos_of_endo(int t) const;
|
||||
/** Return the index of an exogenous atom given by tree index in
|
||||
* the exo ordering. This must be also called only after
|
||||
* parsing_finished(). */
|
||||
int get_pos_of_exo(int t) const;
|
||||
/** Return the index of either endogenous or exogenous atom
|
||||
* given by tree index in the concatenated ordering of
|
||||
* endogenous and exogenous atoms. This must be also called
|
||||
* only after parsing_finished(). */
|
||||
int get_pos_of_all(int t) const;
|
||||
/** Return the mapping from endogenous at time t to outer
|
||||
* ordering of endogenous. */
|
||||
const vector<int> &y2outer_endo() const;
|
||||
/** Return the mapping from the outer ordering of endogenous to endogenous
|
||||
* at time t. */
|
||||
const vector<int> &outer2y_endo() const;
|
||||
/** Return the mapping from exogenous at time t to outer
|
||||
* ordering of exogenous. */
|
||||
const vector<int> &y2outer_exo() const;
|
||||
/** Return the mapping from the outer ordering of exogenous to exogenous
|
||||
* at time t. */
|
||||
const vector<int> &outer2y_exo() const;
|
||||
/** Return the endo_atoms_map. */
|
||||
const vector<int> &get_endo_atoms_map() const;
|
||||
/** Return the exo_atoms_map. */
|
||||
const vector<int> &get_exo_atoms_map() const;
|
||||
/** Return an index in the outer ordering of a given
|
||||
* parameter. An exception is thrown if the name is not a
|
||||
* parameter. */
|
||||
int name2outer_param(const string &name) const;
|
||||
/** Return an index in the outer ordering of a given
|
||||
* endogenous variable. An exception is thrown if the name is not a
|
||||
* and endogenous variable. */
|
||||
int name2outer_endo(const string &name) const;
|
||||
/** Return an index in the outer ordering of a given
|
||||
* exogenous variable. An exception is thrown if the name is not a
|
||||
* and exogenous variable. */
|
||||
int name2outer_exo(const string &name) const;
|
||||
/** Return an index in the outer ordering of all variables
|
||||
* (endo and exo) for a given name. An exception is thrown if
|
||||
* the name is not a variable. This must be called only after
|
||||
* parsing_finished(). */
|
||||
int name2outer_allvar(const string &name) const;
|
||||
/** Return the number of endogenous variables at time t-1, these are state
|
||||
* variables. */
|
||||
int
|
||||
nys() const
|
||||
{
|
||||
return npred()+nboth();
|
||||
}
|
||||
/** Return the number of endogenous variables at time t+1. */
|
||||
int
|
||||
nyss() const
|
||||
{
|
||||
return nboth()+nforw();
|
||||
}
|
||||
/** Return the number of endogenous variables. */
|
||||
int
|
||||
ny() const
|
||||
{
|
||||
return endovars.size();
|
||||
}
|
||||
/** Return the number of exogenous variables. */
|
||||
int
|
||||
nexo() const
|
||||
{
|
||||
return static_cast<int>(exovars.size());
|
||||
}
|
||||
/** Return the number of parameters. */
|
||||
int
|
||||
np() const
|
||||
{
|
||||
return static_cast<int>(params.size());
|
||||
}
|
||||
/** Register unique endogenous variable name. The order of
|
||||
* calls defines the endo outer ordering. The method is
|
||||
* virtual, since a superclass may want to do some additional
|
||||
* action. */
|
||||
virtual void register_uniq_endo(string name);
|
||||
/** Register unique exogenous variable name. The order of
|
||||
* calls defines the exo outer ordering. The method is
|
||||
* virtual, since a superclass may want to do somem additional
|
||||
* action. */
|
||||
virtual void register_uniq_exo(string name);
|
||||
/** Register unique parameter name. The order of calls defines
|
||||
* the param outer ordering. The method is
|
||||
* virtual, since a superclass may want to do somem additional
|
||||
* action. */
|
||||
virtual void register_uniq_param(string name);
|
||||
/** Debug print. */
|
||||
void print() const override;
|
||||
private:
|
||||
/** This performs the common part of parsing_finished(), which
|
||||
* is a construction of internal orderings. */
|
||||
void make_internal_orderings(VarOrdering::ord_type ot);
|
||||
protected:
|
||||
/** This remembers the ordering type of the last call make_internal_ordering. */
|
||||
VarOrdering::ord_type order_type;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,92 +0,0 @@
|
|||
/* -*- C++ -*- */
|
||||
/*
|
||||
* Copyright © 2004-2011 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
%{
|
||||
#include "location.hh"
|
||||
#include "formula_tab.hh"
|
||||
|
||||
#define YY_USER_ACTION SET_LLOC(fmla_);
|
||||
%}
|
||||
|
||||
%option nounput
|
||||
%option noyy_top_state
|
||||
%option stack
|
||||
%option yylineno
|
||||
%option prefix="fmla_"
|
||||
%option never-interactive
|
||||
%x CMT
|
||||
|
||||
%%
|
||||
|
||||
/* comments */
|
||||
<*>"/*" {yy_push_state(CMT);}
|
||||
<CMT>[^*\n]*
|
||||
<CMT>"*"+[^*/\n]*
|
||||
<CMT>"*"+"/" {yy_pop_state();}
|
||||
<CMT>[\n]
|
||||
"//".*\n
|
||||
|
||||
/* initial spaces or tabs are ignored */
|
||||
|
||||
[ \t\r\n]
|
||||
[+] {return YPLUS;}
|
||||
[-] {return YMINUS;}
|
||||
[*] {return YTIMES;}
|
||||
[/] {return YDIVIDE;}
|
||||
[\^] {return YPOWER;}
|
||||
exp {return YEXP;}
|
||||
log {return YLOG;}
|
||||
sin {return YSIN;}
|
||||
cos {return YCOS;}
|
||||
tan {return YTAN;}
|
||||
sqrt {return YSQRT;}
|
||||
erf {return YERF;}
|
||||
erfc {return YERFC;}
|
||||
diff {return YDIFF;}
|
||||
|
||||
/* names: parameters, variables (lagged/leaded) */
|
||||
[A-Za-z_][A-Za-z0-9_]*([\(\{][+-]?[0-9]+[\)\}])? {
|
||||
fmla_lval.string=fmla_text;
|
||||
return NAME;
|
||||
}
|
||||
|
||||
/* floating point numbers */
|
||||
(([0-9]*\.?[0-9]+)|([0-9]+\.))([edED][-+]?[0-9]+)? {
|
||||
fmla_lval.string=fmla_text;
|
||||
return DNUMBER;
|
||||
}
|
||||
|
||||
= {return EQUAL_SIGN;}
|
||||
|
||||
. {return fmla_text[0];}
|
||||
|
||||
%%
|
||||
|
||||
int
|
||||
fmla_wrap()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
fmla__destroy_buffer(void* p)
|
||||
{
|
||||
fmla__delete_buffer(static_cast<YY_BUFFER_STATE>(p));
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/*
|
||||
* Copyright © 2006-2011 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
%code requires
|
||||
{
|
||||
#include "location.hh"
|
||||
#define FMLA_LTYPE ogp::location_type
|
||||
}
|
||||
|
||||
%code
|
||||
{
|
||||
#include "formula_parser.hh"
|
||||
#include <string>
|
||||
|
||||
void fmla_error(std::string);
|
||||
int fmla_lex();
|
||||
extern ogp::FormulaParser* fparser;
|
||||
}
|
||||
|
||||
%union
|
||||
{
|
||||
char* string;
|
||||
double dvalue;
|
||||
int integer;
|
||||
}
|
||||
|
||||
%token EQUAL_SIGN
|
||||
%left YPLUS YMINUS
|
||||
%left YTIMES YDIVIDE
|
||||
%precedence YUMINUS YUPLUS
|
||||
%right YPOWER
|
||||
%token YEXP YLOG YSIN YCOS YTAN YSQRT YERF YERFC YDIFF
|
||||
%token <string> DNUMBER NAME
|
||||
%type <integer> expression
|
||||
|
||||
%define api.prefix {fmla_}
|
||||
|
||||
%locations
|
||||
%defines
|
||||
%define parse.error verbose
|
||||
|
||||
%%
|
||||
root : equation_list
|
||||
| expression
|
||||
{fparser->add_formula($1);}
|
||||
;
|
||||
|
||||
equation_list : equation_list equation | equation ;
|
||||
|
||||
equation : expression EQUAL_SIGN expression ';'
|
||||
{fparser->add_formula(fparser->add_binary(ogp::code_t::MINUS,$1,$3));}
|
||||
| expression ';'
|
||||
{fparser->add_formula($1);}
|
||||
;
|
||||
|
||||
expression : '(' expression ')' { $$ = $2;}
|
||||
| expression YPLUS expression {$$=fparser->add_binary(ogp::code_t::PLUS,$1,$3);}
|
||||
| expression YMINUS expression {$$=fparser->add_binary(ogp::code_t::MINUS,$1,$3);}
|
||||
| expression YTIMES expression {$$=fparser->add_binary(ogp::code_t::TIMES,$1,$3);}
|
||||
| expression YDIVIDE expression {$$=fparser->add_binary(ogp::code_t::DIVIDE,$1,$3);}
|
||||
| expression YPOWER expression {$$=fparser->add_binary(ogp::code_t::POWER,$1,$3);}
|
||||
| YMINUS expression %prec YUMINUS {$$=fparser->add_unary(ogp::code_t::UMINUS,$2);}
|
||||
| YPLUS expression %prec YUPLUS {$$ = $2;}
|
||||
| YSIN '(' expression ')' {$$=fparser->add_unary(ogp::code_t::SIN,$3);}
|
||||
| YCOS '(' expression ')' {$$=fparser->add_unary(ogp::code_t::COS,$3);}
|
||||
| YTAN '(' expression ')' {$$=fparser->add_unary(ogp::code_t::TAN,$3);}
|
||||
| YEXP '(' expression ')' {$$=fparser->add_unary(ogp::code_t::EXP,$3);}
|
||||
| YLOG '(' expression ')' {$$=fparser->add_unary(ogp::code_t::LOG,$3);}
|
||||
| YSQRT '(' expression ')' {$$=fparser->add_unary(ogp::code_t::SQRT,$3);}
|
||||
| YERF '(' expression ')' {$$=fparser->add_unary(ogp::code_t::ERF,$3);}
|
||||
| YERFC '(' expression ')' {$$=fparser->add_unary(ogp::code_t::ERFC,$3);}
|
||||
| YDIFF '(' expression ',' NAME ')' {$$=fparser->add_derivative($3, fparser->add_nulary($5));}
|
||||
| NAME {$$=fparser->add_nulary($1);}
|
||||
| DNUMBER {$$=fparser->add_nulary($1);}
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
void
|
||||
fmla_error(std::string s)
|
||||
{
|
||||
fparser->error(std::move(s));
|
||||
}
|
|
@ -1,536 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2005 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "utils/cc/pascal_triangle.hh"
|
||||
#include "utils/cc/exception.hh"
|
||||
|
||||
#include "parser_exception.hh"
|
||||
#include "location.hh"
|
||||
#include "formula_parser.hh"
|
||||
#include "formula_tab.hh"
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace ogp;
|
||||
|
||||
extern location_type fmla_lloc;
|
||||
|
||||
FormulaParser::FormulaParser(const FormulaParser &fp, Atoms &a)
|
||||
: otree(fp.otree), atoms(a), formulas(fp.formulas), ders()
|
||||
{
|
||||
// create derivatives
|
||||
for (const auto &der : fp.ders)
|
||||
ders.push_back(std::make_unique<FormulaDerivatives>(*der));
|
||||
}
|
||||
|
||||
void
|
||||
FormulaParser::differentiate(int max_order)
|
||||
{
|
||||
ders.clear();
|
||||
vector<int> vars;
|
||||
vars = atoms.variables();
|
||||
for (int formula : formulas)
|
||||
ders.push_back(std::make_unique<FormulaDerivatives>(otree, vars, formula, max_order));
|
||||
}
|
||||
|
||||
const FormulaDerivatives &
|
||||
FormulaParser::derivatives(int i) const
|
||||
{
|
||||
if (i < static_cast<int>(ders.size()))
|
||||
return *(ders[i]);
|
||||
else
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Wrong formula index in FormulaParser::derivatives");
|
||||
return *(ders[0]); // just because of compiler
|
||||
}
|
||||
|
||||
void
|
||||
FormulaParser::add_formula(int t)
|
||||
{
|
||||
formulas.push_back(t);
|
||||
}
|
||||
|
||||
int
|
||||
FormulaParser::add_binary(code_t code, int t1, int t2)
|
||||
{
|
||||
return otree.add_binary(code, t1, t2);
|
||||
}
|
||||
|
||||
int
|
||||
FormulaParser::add_unary(code_t code, int t)
|
||||
{
|
||||
return otree.add_unary(code, t);
|
||||
}
|
||||
|
||||
int
|
||||
FormulaParser::add_nulary(const string &str)
|
||||
{
|
||||
int t = -1;
|
||||
try
|
||||
{
|
||||
t = atoms.check(str);
|
||||
}
|
||||
catch (const ParserException &e)
|
||||
{
|
||||
throw ParserException(e, fmla_lloc.off);
|
||||
}
|
||||
if (t == -1)
|
||||
{
|
||||
t = otree.add_nulary();
|
||||
atoms.assign(str, t);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
void
|
||||
FormulaParser::add_subst_formulas(const map<int, int> &subst, const FormulaParser &fp)
|
||||
{
|
||||
for (int i = 0; i < fp.nformulas(); i++)
|
||||
{
|
||||
int f = add_substitution(fp.formula(i), subst, fp);
|
||||
add_formula(f);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FormulaParser::substitute_formulas(const map<int, int> &smap)
|
||||
{
|
||||
for (int i = 0; i < nformulas(); i++)
|
||||
{
|
||||
// make substitution and replace the formula for it
|
||||
int f = add_substitution(formulas[i], smap);
|
||||
formulas[i] = f;
|
||||
// update the derivatives if any
|
||||
if (i < static_cast<int>(ders.size()) && ders[i])
|
||||
{
|
||||
int order = ders[i]->get_order();
|
||||
ders[i] = std::make_unique<FormulaDerivatives>(otree, atoms.variables(), formulas[i], order);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Global symbols for passing info to parser. */
|
||||
FormulaParser *fparser;
|
||||
|
||||
/** The declarations of functions defined in formula_ll.cc and
|
||||
* formula_tab.cc generated from formula.lex and formula.y */
|
||||
void *fmla__scan_string(const char *);
|
||||
void fmla__destroy_buffer(void *);
|
||||
int fmla_parse();
|
||||
extern location_type fmla_lloc;
|
||||
|
||||
/** This makes own copy of provided data, sets the buffer for the
|
||||
* parser with fmla_scan_buffer, and launches fmla_parse(). Note that
|
||||
* the pointer returned from fmla_scan_buffer must be freed at the
|
||||
* end. */
|
||||
void
|
||||
FormulaParser::parse(const string &stream)
|
||||
{
|
||||
fmla_lloc.off = 0;
|
||||
fmla_lloc.ll = 0;
|
||||
void *p = fmla__scan_string(stream.c_str());
|
||||
fparser = this;
|
||||
fmla_parse();
|
||||
fmla__destroy_buffer(p);
|
||||
}
|
||||
|
||||
void
|
||||
FormulaParser::error(string mes) const
|
||||
{
|
||||
throw ParserException(std::move(mes), fmla_lloc.off);
|
||||
}
|
||||
|
||||
int
|
||||
FormulaParser::last_formula() const
|
||||
{
|
||||
int res = -1;
|
||||
for (int formula : formulas)
|
||||
res = std::max(res, formula);
|
||||
return std::max(res, otree.get_last_nulary());
|
||||
}
|
||||
|
||||
int
|
||||
FormulaParser::pop_last_formula()
|
||||
{
|
||||
if (formulas.size() == 0)
|
||||
return -1;
|
||||
int t = formulas.back();
|
||||
if (formulas.size() == ders.size())
|
||||
ders.pop_back();
|
||||
formulas.pop_back();
|
||||
return t;
|
||||
}
|
||||
|
||||
void
|
||||
FormulaParser::print() const
|
||||
{
|
||||
atoms.print();
|
||||
for (int formula : formulas)
|
||||
{
|
||||
std::cout << "formula " << formula << ":\n";
|
||||
otree.print_operation(formula);
|
||||
}
|
||||
for (unsigned int i = 0; i < ders.size(); i++)
|
||||
{
|
||||
std::cout << "derivatives for the formula " << formulas[i] << ":\n";
|
||||
ders[i]->print(otree);
|
||||
}
|
||||
}
|
||||
|
||||
/** This constructor makes a vector of indices for formulas
|
||||
* corresponding to derivatives of the given formula. The formula is
|
||||
* supposed to belong to the provided tree, the created derivatives
|
||||
* are added to the tree.
|
||||
*
|
||||
* The algorithm is as follows. todo: update description of the
|
||||
* algorithm
|
||||
*/
|
||||
FormulaDerivatives::FormulaDerivatives(OperationTree &otree,
|
||||
const vector<int> &vars, int f, int max_order)
|
||||
: nvar(vars.size()), order(max_order)
|
||||
{
|
||||
FoldMultiIndex fmi_zero(nvar);
|
||||
tder.push_back(f);
|
||||
indices.push_back(fmi_zero);
|
||||
unsigned int last_order_beg = 0;
|
||||
unsigned int last_order_end = tder.size();
|
||||
|
||||
for (int k = 1; k <= order; k++)
|
||||
{
|
||||
// interval <last_order_beg,last_order_end) is guaranteed
|
||||
// here to contain at least one item
|
||||
for (unsigned int run = last_order_beg; run < last_order_end; run++)
|
||||
{
|
||||
// shift one order from the run
|
||||
FoldMultiIndex fmi(indices[run], 1);
|
||||
// set starting variable from the run, note that if k=1,
|
||||
// the shift order ctor of fmi will set it to zero
|
||||
int ivar_start = fmi[k-1];
|
||||
for (int ivar = ivar_start; ivar < nvar; ivar++, fmi.increment())
|
||||
{
|
||||
int der = otree.add_derivative(tder[run], vars[ivar]);
|
||||
if (der != OperationTree::zero)
|
||||
{
|
||||
tder.push_back(der);
|
||||
indices.push_back(fmi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set new last_order_beg and last_order_end
|
||||
last_order_beg = last_order_end;
|
||||
last_order_end = tder.size();
|
||||
// if there was no new derivative, break out from the loop
|
||||
if (last_order_beg >= last_order_end)
|
||||
break;
|
||||
}
|
||||
|
||||
// build ind2der map
|
||||
for (unsigned int i = 0; i < indices.size(); i++)
|
||||
ind2der.emplace(indices[i], i);
|
||||
|
||||
}
|
||||
|
||||
FormulaDerivatives::FormulaDerivatives(const FormulaDerivatives &fd) = default;
|
||||
|
||||
int
|
||||
FormulaDerivatives::derivative(const FoldMultiIndex &mi) const
|
||||
{
|
||||
if (mi.order() > order)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Wrong order of multi-index in FormulaDerivatives::derivative");
|
||||
if (mi.nv() != nvar)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Wrong multi-index variables in FormulaDerivatives::derivative");
|
||||
|
||||
auto it = ind2der.find(mi);
|
||||
if (it == ind2der.end())
|
||||
return OperationTree::zero;
|
||||
else
|
||||
return tder[it->second];
|
||||
}
|
||||
|
||||
void
|
||||
FormulaDerivatives::print(const OperationTree &otree) const
|
||||
{
|
||||
for (const auto &it : ind2der)
|
||||
{
|
||||
std::cout << "derivative ";
|
||||
it.first.print();
|
||||
std::cout << " is formula " << tder[it.second] << '\n';
|
||||
otree.print_operation(tder[it.second]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FormulaCustomEvaluator::eval(const AtomValues &av, FormulaEvalLoader &loader)
|
||||
{
|
||||
etree.reset_all();
|
||||
av.setValues(etree);
|
||||
for (unsigned int i = 0; i < terms.size(); i++)
|
||||
{
|
||||
double res = etree.eval(terms[i]);
|
||||
loader.load(static_cast<int>(i), res);
|
||||
}
|
||||
}
|
||||
|
||||
FoldMultiIndex::FoldMultiIndex(int nv)
|
||||
: nvar(nv), ord(0), data(std::make_unique<int[]>(ord))
|
||||
{
|
||||
}
|
||||
|
||||
FoldMultiIndex::FoldMultiIndex(int nv, int ordd, int ii)
|
||||
: nvar(nv), ord(ordd), data(std::make_unique<int[]>(ord))
|
||||
{
|
||||
for (int i = 0; i < ord; i++)
|
||||
data[i] = ii;
|
||||
}
|
||||
|
||||
/** Note that a monotone sequence mapped by monotone mapping yields a
|
||||
* monotone sequence. */
|
||||
FoldMultiIndex::FoldMultiIndex(int nv, const FoldMultiIndex &mi, const vector<int> &mp)
|
||||
: nvar(nv), ord(mi.ord), data(std::make_unique<int[]>(ord))
|
||||
{
|
||||
for (int i = 0; i < ord; i++)
|
||||
{
|
||||
if (i < ord-1 && mp[i+1] < mp[i])
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Mapping not monotone in FoldMultiIndex constructor");
|
||||
if (mp[mi[i]] >= nv || mp[mi[i]] < 0)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Mapping out of bounds in FoldMultiIndex constructor");
|
||||
data[i] = mp[mi[i]];
|
||||
}
|
||||
}
|
||||
|
||||
FoldMultiIndex::FoldMultiIndex(const FoldMultiIndex &fmi, int new_orders)
|
||||
: nvar(fmi.nvar),
|
||||
ord(fmi.ord+new_orders),
|
||||
data(std::make_unique<int[]>(ord))
|
||||
{
|
||||
std::copy_n(fmi.data.get(), fmi.ord, data.get());
|
||||
int new_item = (fmi.ord > 0) ? fmi.data[fmi.ord-1] : 0;
|
||||
for (int i = fmi.ord; i < ord; i++)
|
||||
data[i] = new_item;
|
||||
}
|
||||
|
||||
FoldMultiIndex::FoldMultiIndex(const FoldMultiIndex &fmi)
|
||||
: nvar(fmi.nvar),
|
||||
ord(fmi.ord),
|
||||
data(std::make_unique<int[]>(ord))
|
||||
{
|
||||
std::copy_n(fmi.data.get(), ord, data.get());
|
||||
}
|
||||
|
||||
const FoldMultiIndex &
|
||||
FoldMultiIndex::operator=(const FoldMultiIndex &fmi)
|
||||
{
|
||||
if (ord != fmi.ord)
|
||||
data = std::make_unique<int[]>(fmi.ord);
|
||||
|
||||
ord = fmi.ord;
|
||||
nvar = fmi.nvar;
|
||||
std::copy_n(fmi.data.get(), ord, data.get());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
FoldMultiIndex::operator<(const FoldMultiIndex &fmi) const
|
||||
{
|
||||
if (nvar != fmi.nvar)
|
||||
ogu::Exception(__FILE__, __LINE__,
|
||||
"Different nvar in FoldMultiIndex::operator<");
|
||||
|
||||
if (ord < fmi.ord)
|
||||
return true;
|
||||
if (ord > fmi.ord)
|
||||
return false;
|
||||
|
||||
int i = 0;
|
||||
while (i < ord && data[i] == fmi.data[i])
|
||||
i++;
|
||||
if (i == ord)
|
||||
return false;
|
||||
else
|
||||
return data[i] < fmi.data[i];
|
||||
}
|
||||
|
||||
bool
|
||||
FoldMultiIndex::operator==(const FoldMultiIndex &fmi) const
|
||||
{
|
||||
bool res = true;
|
||||
res = res && (nvar == fmi.nvar) && (ord == fmi.ord);
|
||||
if (res)
|
||||
for (int i = 0; i < ord; i++)
|
||||
if (data[i] != fmi.data[i])
|
||||
return false;
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
FoldMultiIndex::increment()
|
||||
{
|
||||
if (ord == 0)
|
||||
return;
|
||||
|
||||
int k = ord-1;
|
||||
data[k]++;
|
||||
while (k > 0 && data[k] == nvar)
|
||||
{
|
||||
data[k] = 0;
|
||||
data[--k]++;
|
||||
}
|
||||
for (int kk = 1; kk < ord; kk++)
|
||||
if (data[kk-1] > data[kk])
|
||||
data[kk] = data[kk-1];
|
||||
}
|
||||
|
||||
// For description of an algorithm for calculation of folded offset,
|
||||
// see Tensor Library Documentation, Ondra Kamenik, 2005, description
|
||||
// of FTensor::getOffsetRecurse().
|
||||
int
|
||||
FoldMultiIndex::offset() const
|
||||
{
|
||||
// make copy for the recursions
|
||||
auto tmp = std::make_unique<int[]>(ord);
|
||||
std::copy_n(data.get(), ord, tmp.get());
|
||||
// call the recursive algorithm
|
||||
int res = offset_recurse(tmp.get(), ord, nvar);
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
FoldMultiIndex::print() const
|
||||
{
|
||||
std::cout << "[";
|
||||
for (int i = 0; i < ord; i++)
|
||||
std::cout << data[i] << ' ';
|
||||
std::cout << "]";
|
||||
}
|
||||
|
||||
int
|
||||
FoldMultiIndex::offset_recurse(int *data, int len, int nv)
|
||||
{
|
||||
if (len == 0)
|
||||
return 0;
|
||||
// calculate length of initial constant indices
|
||||
int prefix = 1;
|
||||
while (prefix < len && data[0] == data[prefix])
|
||||
prefix++;
|
||||
|
||||
int m = data[0];
|
||||
int s1 = PascalTriangle::noverk(nv+len-1, len) - PascalTriangle::noverk(nv-m+len-1, len);
|
||||
|
||||
// cancel m from the rest of the sequence
|
||||
for (int i = prefix; i < len; i++)
|
||||
data[i] -= m;
|
||||
|
||||
// calculate offset of the remaining sequence
|
||||
int s2 = offset_recurse(data+prefix, len-prefix, nv-m);
|
||||
// return the sum
|
||||
return s1+s2;
|
||||
}
|
||||
|
||||
bool
|
||||
ltfmi::operator()(const FoldMultiIndex &i1, const FoldMultiIndex &i2) const
|
||||
{
|
||||
return i1 < i2;
|
||||
}
|
||||
|
||||
FormulaDerEvaluator::FormulaDerEvaluator(const FormulaParser &fp)
|
||||
: etree(fp.otree, -1)
|
||||
{
|
||||
for (const auto &der : fp.ders)
|
||||
ders.push_back(der.get());
|
||||
|
||||
der_atoms = fp.atoms.variables();
|
||||
}
|
||||
|
||||
void
|
||||
FormulaDerEvaluator::eval(const AtomValues &av, FormulaDerEvalLoader &loader, int order)
|
||||
{
|
||||
if (ders.size() == 0)
|
||||
return;
|
||||
int maxorder = ders[0]->order;
|
||||
|
||||
if (order > maxorder)
|
||||
throw ogu::Exception(__FILE__, __LINE__,
|
||||
"Wrong order in FormulaDerEvaluator::eval");
|
||||
|
||||
etree.reset_all();
|
||||
av.setValues(etree);
|
||||
|
||||
auto vars = std::make_unique<int[]>(order);
|
||||
|
||||
for (unsigned int i = 0; i < ders.size(); i++)
|
||||
{
|
||||
for (const auto &it : ders[i]->ind2der)
|
||||
{
|
||||
const FoldMultiIndex &mi = it.first;
|
||||
if (mi.order() == order)
|
||||
{
|
||||
// set vars from multiindex mi and variables
|
||||
for (int k = 0; k < order; k++)
|
||||
vars[k] = der_atoms[mi[k]];
|
||||
// evaluate
|
||||
double res = etree.eval(ders[i]->tder[it.second]);
|
||||
// load
|
||||
loader.load(i, order, vars.get(), res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FormulaDerEvaluator::eval(const vector<int> &mp, const AtomValues &av,
|
||||
FormulaDerEvalLoader &loader, int order)
|
||||
{
|
||||
etree.reset_all();
|
||||
av.setValues(etree);
|
||||
|
||||
int nvar_glob = der_atoms.size();
|
||||
int nvar = mp.size();
|
||||
auto vars = std::make_unique<int[]>(order);
|
||||
|
||||
for (unsigned int i = 0; i < ders.size(); i++)
|
||||
{
|
||||
FoldMultiIndex mi(nvar, order);
|
||||
do
|
||||
{
|
||||
// find index of the derivative in the tensor
|
||||
FoldMultiIndex mi_glob(nvar_glob, mi, mp);
|
||||
int der = ders[i]->derivative(mi_glob);
|
||||
if (der != OperationTree::zero)
|
||||
{
|
||||
// set vars from the global multiindex
|
||||
for (int k = 0; k < order; k++)
|
||||
vars[k] = der_atoms[mi_glob[k]];
|
||||
// evaluate derivative
|
||||
double res = etree.eval(der);
|
||||
// load
|
||||
loader.load(i, order, vars.get(), res);
|
||||
}
|
||||
mi.increment();
|
||||
}
|
||||
while (!mi.past_the_end());
|
||||
}
|
||||
}
|
|
@ -1,497 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2005-2011 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OGP_FORMULA_PARSER_H
|
||||
#define OGP_FORMULA_PARSER_H
|
||||
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "tree.hh"
|
||||
|
||||
namespace ogp
|
||||
{
|
||||
using std::vector;
|
||||
|
||||
/** Pure virtual class defining a minimal interface for
|
||||
* representation of nulary terms within FormulaParser. */
|
||||
class Atoms
|
||||
{
|
||||
public:
|
||||
Atoms() = default;
|
||||
virtual ~Atoms() = default;
|
||||
/** This returns previously assigned internal index to the
|
||||
* given atom, or returns -1 if the atom has not been assigned
|
||||
* yet. The method can raise an exception, if the Atoms
|
||||
* implementation is strict and the name is not among
|
||||
* prescribed possible values. */
|
||||
virtual int check(const std::string &name) const = 0;
|
||||
/** This method assigns an internal index to the nulary term
|
||||
* described by the name. The internal index is allocated by
|
||||
* OperationTree class. */
|
||||
virtual void assign(const std::string &name, int t) = 0;
|
||||
/** Returns a number of variables which will be used for
|
||||
* differentiations. */
|
||||
virtual int nvar() const = 0;
|
||||
/** Returns a vector of variable's internal indices which will
|
||||
* be used for differentiations. */
|
||||
virtual vector<int> variables() const = 0;
|
||||
/** Debug print. */
|
||||
virtual void print() const = 0;
|
||||
};
|
||||
|
||||
/** Pure virtual class defining interface for all classes able to
|
||||
* set nulary terms to evaluation tree EvalTree. The
|
||||
* implementations of this class will have to be connected with
|
||||
* Atoms to have knowledge about the atoms and their indices in
|
||||
* the tree, and will call EvalTree::set_nulary. */
|
||||
class AtomValues
|
||||
{
|
||||
public:
|
||||
virtual ~AtomValues() = default;
|
||||
virtual void setValues(EvalTree &et) const = 0;
|
||||
};
|
||||
|
||||
class FormulaDerEvaluator;
|
||||
class FoldMultiIndex;
|
||||
/** For ordering FoldMultiIndex in the std::map. */
|
||||
struct ltfmi
|
||||
{
|
||||
bool operator()(const FoldMultiIndex &i1, const FoldMultiIndex &i2) const;
|
||||
};
|
||||
|
||||
/** This class stores derivatives (tree indices) of one formula
|
||||
* for all orders upto a given one. It stores the derivatives as a
|
||||
* sequence (vector) of these tree indices and sequence of the
|
||||
* multidimensional indices of variables wrt which the derivatives
|
||||
* were taken. In order to speed up querying for a derivative
|
||||
* given the variables, we have a map mapping the multidimensional
|
||||
* index to the order of the derivative in the sequence.
|
||||
*
|
||||
* The only reason we do not have only this map is that the
|
||||
* iterators of the map do not survive the insertions to the map,
|
||||
* and implementation of the constructor has to be very difficult.
|
||||
*/
|
||||
class FormulaDerivatives
|
||||
{
|
||||
friend class FormulaDerEvaluator;
|
||||
protected:
|
||||
/** Vector of derivatives. This is a list of derivatives (tree
|
||||
* indices), the ordering is given by the algorithm used to
|
||||
* create it. Currently, it starts with zero-th derivative,
|
||||
* the formula itself and carries with first order, second,
|
||||
* etc. */
|
||||
vector<int> tder;
|
||||
/** Vector of multiindices corresponding to the vector of
|
||||
* derivatives. */
|
||||
vector<FoldMultiIndex> indices;
|
||||
/** For retrieving derivatives via a multiindex, we have a map
|
||||
* mapping a multiindex to a derivative in the tder
|
||||
* ordering. This means that indices[ind2der[index]] == index. */
|
||||
using Tfmiintmap = map<FoldMultiIndex, int, ltfmi>;
|
||||
Tfmiintmap ind2der;
|
||||
/** The number of variables. */
|
||||
int nvar;
|
||||
/** The maximum order of derivatives. */
|
||||
int order;
|
||||
public:
|
||||
/** The constructor allocates and fills the sequence of the
|
||||
* indices of derivatives for a formula.
|
||||
* @param otree the OperationTree for which all work is done
|
||||
* and to which the derivatives are added.
|
||||
* @param vars the vector of nulary terms in the tree; the
|
||||
* derivatives are taken with respect to these variables in
|
||||
* the ordering given by the vector.
|
||||
* @param f the index of the formula being differentiated. The
|
||||
* zero derivative is set to f.
|
||||
* @param max_order the maximum order of differentiation.
|
||||
*/
|
||||
FormulaDerivatives(OperationTree &otree, const vector<int> &vars, int f, int max_order);
|
||||
/** Copy constructor. */
|
||||
FormulaDerivatives(const FormulaDerivatives &fd);
|
||||
virtual ~FormulaDerivatives() = default;
|
||||
/** Random access to the derivatives via multiindex. */
|
||||
int derivative(const FoldMultiIndex &mi) const;
|
||||
/** Return the order. */
|
||||
int
|
||||
get_order() const
|
||||
{
|
||||
return order;
|
||||
}
|
||||
/** Debug print. */
|
||||
void print(const OperationTree &otree) const;
|
||||
};
|
||||
|
||||
class FormulaEvaluator;
|
||||
|
||||
/** This class is able to parse a number of formulas and
|
||||
* differentiate them. The life cycle of the object is as follows:
|
||||
* After it is created, a few calls to parse will add formulas
|
||||
* (zero derivatives) to the object. Then a method differentiate()
|
||||
* can be called and a vector of pointers to derivatives for each
|
||||
* formula is created. After this, no one should call other
|
||||
* parse() or differentiate(). A const reference of the object can
|
||||
* be used in constructors of FormulaEvaluator and
|
||||
* FormulaDerEvaluator in order to evaluate formulas (zero
|
||||
* derivatives) and higher derivatives resp. */
|
||||
class FormulaParser
|
||||
{
|
||||
friend class FormulaCustomEvaluator;
|
||||
friend class FormulaDerEvaluator;
|
||||
protected:
|
||||
/** The OperationTree of all formulas, including derivatives. */
|
||||
OperationTree otree;
|
||||
/** Reference to Atoms. The Atoms are filled with nulary terms
|
||||
* during execution of parse(). */
|
||||
Atoms &atoms;
|
||||
/** Vector of formulas (zero derivatives) in the order as they
|
||||
* have been parsed. */
|
||||
vector<int> formulas;
|
||||
/** The vector to derivatives, each vector corresponds to a
|
||||
* formula in the vector formulas. */
|
||||
vector<std::unique_ptr<FormulaDerivatives>> ders;
|
||||
public:
|
||||
/** Construct an empty formula parser. */
|
||||
FormulaParser(Atoms &a)
|
||||
: atoms(a)
|
||||
{
|
||||
}
|
||||
FormulaParser(const FormulaParser &fp) = delete;
|
||||
/** Copy constructor using a different instance of Atoms. */
|
||||
FormulaParser(const FormulaParser &fp, Atoms &a);
|
||||
virtual ~FormulaParser() = default;
|
||||
|
||||
/** Requires an addition of the formula; called from the
|
||||
* parser. */
|
||||
void add_formula(int t);
|
||||
/** Requires an addition of the binary operation; called from
|
||||
* the parser. */
|
||||
int add_binary(code_t code, int t1, int t2);
|
||||
/** Requires an addition of the unary operation; called from
|
||||
* the parser. */
|
||||
int add_unary(code_t code, int t);
|
||||
/** Requires an addition of the nulary operation given by the
|
||||
* string. The Atoms are consulted for uniquness and are given
|
||||
* an internal index generated by the OperationTree. This is
|
||||
* the channel through which the Atoms are filled. */
|
||||
int add_nulary(const std::string &str);
|
||||
|
||||
/** Adds a derivative to the tree. This just calls
|
||||
* OperationTree::add_derivative. */
|
||||
int
|
||||
add_derivative(int t, int v)
|
||||
{
|
||||
return otree.add_derivative(t, v);
|
||||
}
|
||||
/** Adds a substitution. This just calls
|
||||
* OperationTree::add_substitution. */
|
||||
int
|
||||
add_substitution(int t, const map<int, int> &subst)
|
||||
{
|
||||
return otree.add_substitution(t, subst);
|
||||
}
|
||||
/** Add the substitution given by the map where left sides of
|
||||
* substitutions come from another parser. The right sides are
|
||||
* from this object. The given t is from the given parser fp. */
|
||||
int
|
||||
add_substitution(int t, const map<int, int> &subst,
|
||||
const FormulaParser &fp)
|
||||
{
|
||||
return otree.add_substitution(t, subst, fp.otree);
|
||||
}
|
||||
/** This adds formulas from the given parser with (possibly)
|
||||
* different atoms applying substitutions from the given map
|
||||
* mapping atoms from fp to atoms of the object. */
|
||||
void add_subst_formulas(const map<int, int> &subst, const FormulaParser &fp);
|
||||
/** Substitute formulas. For each i from 1 through all
|
||||
* formulas, it adds a substitution of the i-th formula and
|
||||
* make it to be i-th formula.*/
|
||||
void substitute_formulas(const std::map<int, int> &subst);
|
||||
/** This method turns the given term to nulary operation. It
|
||||
* should be used with caution, since this method does not
|
||||
* anything do with atoms, but usually some action is also
|
||||
* needed (at leat to assign the tree index t to some
|
||||
* atom). */
|
||||
void
|
||||
nularify(int t)
|
||||
{
|
||||
otree.nularify(t);
|
||||
}
|
||||
/** Returns a set of nulary terms of the given term. Just
|
||||
* calls OperationTree::nulary_of_term. */
|
||||
const unordered_set<int> &
|
||||
nulary_of_term(int t) const
|
||||
{
|
||||
return otree.nulary_of_term(t);
|
||||
}
|
||||
|
||||
/** Parse a given string containing one or more formulas. The
|
||||
* formulas are parsed and added to the OperationTree and to
|
||||
* the formulas vector. */
|
||||
void parse(const std::string &stream);
|
||||
/** Processes a syntax error from bison. */
|
||||
void error(std::string mes) const;
|
||||
/** Differentiate all the formulas up to the given order. The
|
||||
* variables with respect to which the derivatives are taken
|
||||
* are obtained by Atoms::variables(). If the derivates exist,
|
||||
* they are destroyed and created again (with possibly
|
||||
* different order). */
|
||||
void differentiate(int max_order);
|
||||
/** Return i-th formula derivatives. */
|
||||
const FormulaDerivatives &derivatives(int i) const;
|
||||
|
||||
/** This returns a maximum index of zero derivative formulas
|
||||
* including all nulary terms. This is a mimumum length of the
|
||||
* tree for which it is safe to evaluate zero derivatives of
|
||||
* the formulas. */
|
||||
int last_formula() const;
|
||||
/** This returns a tree index of the i-th formula in the
|
||||
* vector. */
|
||||
int
|
||||
formula(int i) const
|
||||
{
|
||||
return formulas[i];
|
||||
}
|
||||
|
||||
/** This returns a tree index of the last formula and pops its
|
||||
* item from the formulas vector. The number of formulas is
|
||||
* then less by one. Returns -1 if there is no formula. If
|
||||
* there are derivatives of the last formula, they are
|
||||
* destroyed and the vector ders is popped from the back. */
|
||||
int pop_last_formula();
|
||||
|
||||
/** This returns a number of formulas. */
|
||||
int
|
||||
nformulas() const
|
||||
{
|
||||
return static_cast<int>(formulas.size());
|
||||
}
|
||||
|
||||
/** This returns a reference to atoms. */
|
||||
const Atoms &
|
||||
getAtoms() const
|
||||
{
|
||||
return atoms;
|
||||
}
|
||||
Atoms &
|
||||
getAtoms()
|
||||
{
|
||||
return atoms;
|
||||
}
|
||||
/** This returns the tree. */
|
||||
const OperationTree &
|
||||
getTree() const
|
||||
{
|
||||
return otree;
|
||||
}
|
||||
OperationTree &
|
||||
getTree()
|
||||
{
|
||||
return otree;
|
||||
}
|
||||
|
||||
/** Debug print. */
|
||||
void print() const;
|
||||
};
|
||||
|
||||
/** This is a pure virtual class defining an interface for all
|
||||
* classes which will load the results of formula (zero
|
||||
* derivative) evaluations. A primitive implementation of this
|
||||
* class can be a vector of doubles. */
|
||||
class FormulaEvalLoader
|
||||
{
|
||||
public:
|
||||
virtual ~FormulaEvalLoader() = default;
|
||||
/** Set the value res for the given formula. The formula is
|
||||
* identified by an index corresponding to the ordering in
|
||||
* which the formulas have been parsed (starting from
|
||||
* zero). */
|
||||
virtual void load(int i, double res) = 0;
|
||||
};
|
||||
|
||||
/** This class evaluates a selected subset of terms of the
|
||||
* tree. In the protected constructor, one can constraint the
|
||||
* initialization of the evaluation tree to a given number of
|
||||
* terms in the beginning. Using this constructor, one has to make
|
||||
* sure, that the terms in the beginning do not refer to terms
|
||||
* behind the initial part. */
|
||||
class FormulaCustomEvaluator
|
||||
{
|
||||
protected:
|
||||
/** The evaluation tree. */
|
||||
EvalTree etree;
|
||||
/** The custom tree indices to be evaluated. */
|
||||
vector<int> terms;
|
||||
public:
|
||||
/** Construct from FormulaParser and given list of terms. */
|
||||
FormulaCustomEvaluator(const FormulaParser &fp, vector<int> ts)
|
||||
: etree(fp.otree), terms(std::move(ts))
|
||||
{
|
||||
}
|
||||
/** Construct from OperationTree and given list of terms. */
|
||||
FormulaCustomEvaluator(const OperationTree &ot, vector<int> ts)
|
||||
: etree(ot), terms(std::move(ts))
|
||||
{
|
||||
}
|
||||
/** Evaluate the terms using the given AtomValues and load the
|
||||
* results using the given loader. The loader is called for
|
||||
* each term in the order of the terms. */
|
||||
void eval(const AtomValues &av, FormulaEvalLoader &loader);
|
||||
protected:
|
||||
FormulaCustomEvaluator(const FormulaParser &fp)
|
||||
: etree(fp.otree, fp.last_formula()), terms(fp.formulas)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/** This class evaluates zero derivatives of the FormulaParser. */
|
||||
class FormulaEvaluator : public FormulaCustomEvaluator
|
||||
{
|
||||
public:
|
||||
/** Construct from FormulaParser. */
|
||||
FormulaEvaluator(const FormulaParser &fp)
|
||||
: FormulaCustomEvaluator(fp)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/** This is a pure virtual class defining an interface for all
|
||||
* classes which will load the results of formula derivative
|
||||
* evaluations. */
|
||||
class FormulaDerEvalLoader
|
||||
{
|
||||
public:
|
||||
virtual ~FormulaDerEvalLoader() = default;
|
||||
/** This loads the result of the derivative of the given
|
||||
* order. The semantics of i is the same as in
|
||||
* FormulaEvalLoader::load. The indices of variables with
|
||||
* respect to which the derivative was taken are stored in
|
||||
* memory pointed by vars. These are the tree indices of the
|
||||
* variables. */
|
||||
virtual void load(int i, int order, const int *vars, double res) = 0;
|
||||
};
|
||||
|
||||
/** This class is a utility class representing the tensor
|
||||
* multindex. It can basically increment itself, and calculate
|
||||
* its offset in the folded tensor. */
|
||||
class FoldMultiIndex
|
||||
{
|
||||
/** Number of variables. */
|
||||
int nvar;
|
||||
/** Dimension. */
|
||||
int ord;
|
||||
/** The multiindex. */
|
||||
std::unique_ptr<int[]> data;
|
||||
public:
|
||||
/** Initializes to the zero derivative. Order is 0, data is
|
||||
* empty. */
|
||||
FoldMultiIndex(int nv);
|
||||
/** Initializes the multiindex to zeros or given i. */
|
||||
FoldMultiIndex(int nv, int order, int i = 0);
|
||||
/** Makes a new multiindex of the same order applying a given
|
||||
* mapping to the indices. The mapping is supposed to be monotone. */
|
||||
FoldMultiIndex(int nv, const FoldMultiIndex &mi, const vector<int> &mp);
|
||||
/** Shifting constructor. This adds a given number of orders
|
||||
* to the end, copying the last item to the newly added items,
|
||||
* keeping the index ordered. If the index was empty (zero-th
|
||||
* dimension), then zeros are added. */
|
||||
FoldMultiIndex(const FoldMultiIndex &fmi, int new_orders);
|
||||
/** Copy constructor. */
|
||||
FoldMultiIndex(const FoldMultiIndex &fmi);
|
||||
/** Desctructor. */
|
||||
virtual ~FoldMultiIndex() = default;
|
||||
/** Assignment operator. */
|
||||
const FoldMultiIndex &operator=(const FoldMultiIndex &fmi);
|
||||
/** Operator < implementing lexicographic ordering within one
|
||||
* order, increasing order across orders. */
|
||||
bool operator<(const FoldMultiIndex &fmi) const;
|
||||
bool operator==(const FoldMultiIndex &fmi) const;
|
||||
/** Increment the multiindex. */
|
||||
void increment();
|
||||
/** Return offset of the multiindex in the folded tensor. */
|
||||
int offset() const;
|
||||
const int &
|
||||
operator[](int i) const
|
||||
{
|
||||
return data[i];
|
||||
}
|
||||
/** Return order of the multiindex, i.e. dimension of the
|
||||
* tensor. */
|
||||
int
|
||||
order() const
|
||||
{
|
||||
return ord;
|
||||
}
|
||||
/** Return the number of variables. */
|
||||
int
|
||||
nv() const
|
||||
{
|
||||
return nvar;
|
||||
}
|
||||
/** Return the data. */
|
||||
const int *
|
||||
ind() const
|
||||
{
|
||||
return data.get();
|
||||
}
|
||||
/** Return true if the end of the tensor is reached. The
|
||||
* result of a subsequent increment should be considered
|
||||
* unpredictable. */
|
||||
bool
|
||||
past_the_end() const
|
||||
{
|
||||
return (ord == 0) || (data[0] == nvar);
|
||||
}
|
||||
/** Prints the multiindex in the brackets. */
|
||||
void print() const;
|
||||
private:
|
||||
static int offset_recurse(int *data, int len, int nv);
|
||||
};
|
||||
|
||||
/** This class evaluates derivatives of the FormulaParser. */
|
||||
class FormulaDerEvaluator
|
||||
{
|
||||
/** Its own instance of EvalTree. */
|
||||
EvalTree etree;
|
||||
/** The indices of derivatives for each formula. This is a
|
||||
* const copy FormulaParser::ders. We do not allocate nor
|
||||
* deallocate anything here. */
|
||||
vector<const FormulaDerivatives *> ders;
|
||||
/** A copy of tree indices corresponding to atoms to with
|
||||
* respect the derivatives were taken. */
|
||||
vector<int> der_atoms;
|
||||
public:
|
||||
/** Construct the object from FormulaParser. */
|
||||
FormulaDerEvaluator(const FormulaParser &fp);
|
||||
/** Evaluate the derivatives from the FormulaParser wrt to all
|
||||
* atoms in variables vector at the given AtomValues. The
|
||||
* given loader is used for output. */
|
||||
void eval(const AtomValues &av, FormulaDerEvalLoader &loader, int order);
|
||||
/** Evaluate the derivatives from the FormulaParser wrt to a
|
||||
* selection of atoms of the atoms in der_atoms vector at the
|
||||
* given AtomValues. The selection is given by a monotone
|
||||
* mapping to the indices (not values) of the der_atoms. */
|
||||
void eval(const vector<int> &mp, const AtomValues &av, FormulaDerEvalLoader &loader,
|
||||
int order);
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,42 +0,0 @@
|
|||
// Copyright © 2006, Ondra Kamenik
|
||||
|
||||
// $Id: location.h 762 2006-05-22 13:00:07Z kamenik $
|
||||
|
||||
// Purpose: This file defines macros for lex and bison so that the
|
||||
// very primitive location tracking would be enabled. The location of
|
||||
// a token is given by offset of its first character. The offset is
|
||||
// relative to the number which is (and must be) initialized before
|
||||
// parsing. This file is to be included to the top of bison and lex
|
||||
// sources.
|
||||
|
||||
// How to use: in preamble of bison and flex, you must include this
|
||||
// file and declare extern YYLTYPE prefix##lloc. In addition, in flex,
|
||||
// you must define int prefix##ll =0; and use macro SET_LLOC(prefix)
|
||||
// in EVERY action consuming material (this can be done with #define
|
||||
// YY_USER_ACTION) and in bison you must use option %locations.
|
||||
|
||||
#ifndef OG_LOCATION_H
|
||||
#define OG_LOCATION_H
|
||||
|
||||
namespace ogp
|
||||
{
|
||||
struct location_type
|
||||
{
|
||||
int off{0}; // offset of the token
|
||||
int ll{0}; // length ot the token
|
||||
location_type() = default;
|
||||
};
|
||||
};
|
||||
|
||||
// set current off to the first off and add all lengths
|
||||
#define YYLLOC_DEFAULT(Current, Rhs, N) \
|
||||
{ \
|
||||
(Current).off = (Rhs)[1].off; \
|
||||
(Current).ll = 0; \
|
||||
for (int i = 1; i <= N; i++) \
|
||||
(Current).ll += (Rhs)[i].ll; \
|
||||
}
|
||||
|
||||
#define SET_LLOC(prefix) (prefix ## lloc.off += prefix ## lloc.ll, prefix ## lloc.ll = prefix ## leng)
|
||||
|
||||
#endif
|
|
@ -1,82 +0,0 @@
|
|||
/* -*- C++ -*- */
|
||||
/*
|
||||
* Copyright © 2006-2011 Ondra Kamenik
|
||||
* Copyright © 2019-2022 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
%{
|
||||
#include <string>
|
||||
|
||||
#include "location.hh"
|
||||
#include "matrix_tab.hh"
|
||||
|
||||
extern void matrix_error(std::string);
|
||||
|
||||
#define YY_USER_ACTION SET_LLOC(matrix_);
|
||||
%}
|
||||
|
||||
%option nounput
|
||||
%option noyy_top_state
|
||||
%option stack
|
||||
%option yylineno
|
||||
%option prefix="matrix_"
|
||||
%option never-interactive
|
||||
%x CMT
|
||||
|
||||
%%
|
||||
|
||||
/* comments */
|
||||
<*>"/*" {yy_push_state(CMT);}
|
||||
<CMT>[^*\n]*
|
||||
<CMT>"*"+[^*/\n]*
|
||||
<CMT>"*"+"/" {yy_pop_state();}
|
||||
<CMT>[\n]
|
||||
"//".*\n
|
||||
|
||||
/* ignore spaces and commas */
|
||||
[ \t,]
|
||||
/* new row */
|
||||
\r\n {return NEW_ROW;}
|
||||
\n {return NEW_ROW;}
|
||||
;[ \t]*\n {return NEW_ROW;}
|
||||
;[ \t]*\r\n {return NEW_ROW;}
|
||||
; {return NEW_ROW;}
|
||||
|
||||
[+-]?(([0-9]*\.?[0-9]+)|([0-9]+\.))([edED][-+]?[0-9]+)? {
|
||||
matrix_lval.val = strtod(matrix_text, NULL);
|
||||
return DNUMBER;
|
||||
}
|
||||
|
||||
. {
|
||||
using namespace std::string_literals;
|
||||
matrix_error("Unrecognized character "s + matrix_text);
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
int
|
||||
matrix_wrap()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
matrix__destroy_buffer(void* p)
|
||||
{
|
||||
matrix__delete_buffer(static_cast<YY_BUFFER_STATE>(p));
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
/*
|
||||
* Copyright © 2006-2011 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
%code requires
|
||||
{
|
||||
#include "location.hh"
|
||||
#define MATRIX_LTYPE ogp::location_type
|
||||
}
|
||||
|
||||
%code
|
||||
{
|
||||
#include "matrix_parser.hh"
|
||||
|
||||
void matrix_error(std::string);
|
||||
int matrix_lex();
|
||||
extern ogp::MatrixParser* mparser;
|
||||
}
|
||||
|
||||
%union
|
||||
{
|
||||
double val;
|
||||
int integer;
|
||||
}
|
||||
|
||||
%token NEW_ROW
|
||||
%token <val> DNUMBER
|
||||
|
||||
%define api.prefix {matrix_};
|
||||
|
||||
%locations
|
||||
%defines
|
||||
%define parse.error verbose
|
||||
|
||||
%%
|
||||
|
||||
matrix : first_row other_rows
|
||||
| first_row other_rows empty_rows
|
||||
| first_row empty_rows other_rows empty_rows
|
||||
| first_row empty_rows other_rows
|
||||
| empty_rows first_row other_rows
|
||||
| empty_rows first_row other_rows empty_rows
|
||||
| empty_rows first_row empty_rows other_rows empty_rows
|
||||
| empty_rows first_row empty_rows
|
||||
| first_row empty_rows
|
||||
| empty_rows first_row
|
||||
| first_row
|
||||
| empty_rows
|
||||
;
|
||||
|
||||
empty_rows : empty_rows NEW_ROW | NEW_ROW;
|
||||
|
||||
lod : DNUMBER {mparser->add_item($1);}
|
||||
| lod DNUMBER {mparser->add_item($2);}
|
||||
;
|
||||
|
||||
first_row : lod;
|
||||
|
||||
other_rows : other_rows one_row | other_rows empty_rows one_row |one_row ;
|
||||
|
||||
one_row : NEW_ROW {mparser->start_row();} lod;
|
||||
|
||||
|
||||
%%
|
||||
|
||||
void
|
||||
matrix_error(std::string s)
|
||||
{
|
||||
mparser->error(std::move(s));
|
||||
}
|
||||
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2006 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "parser_exception.hh"
|
||||
#include "matrix_parser.hh"
|
||||
#include "location.hh"
|
||||
#include "matrix_tab.hh"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace ogp;
|
||||
|
||||
/** A global symbol for passing info to the MatrixParser from
|
||||
* matrix_parse(). */
|
||||
MatrixParser *mparser;
|
||||
|
||||
/** The declaration of functions defined in matrix_ll.cc and
|
||||
* matrix_tab.cc generated from matrix.lex and matrix.y. */
|
||||
void *matrix__scan_string(const char *);
|
||||
void matrix__destroy_buffer(void *);
|
||||
int matrix_parse();
|
||||
extern ogp::location_type matrix_lloc;
|
||||
|
||||
void
|
||||
MatrixParser::parse(const string &stream)
|
||||
{
|
||||
// reinitialize the object
|
||||
data.clear();
|
||||
row_lengths.clear();
|
||||
nc = 0;
|
||||
// allocate temporary buffer and parse
|
||||
matrix_lloc.off = 0;
|
||||
matrix_lloc.ll = 0;
|
||||
void *p = matrix__scan_string(stream.c_str());
|
||||
mparser = this;
|
||||
matrix_parse();
|
||||
matrix__destroy_buffer(p);
|
||||
}
|
||||
|
||||
void
|
||||
MatrixParser::add_item(double v)
|
||||
{
|
||||
data.push_back(v);
|
||||
if (row_lengths.size() == 0)
|
||||
row_lengths.push_back(0);
|
||||
(row_lengths.back())++;
|
||||
nc = std::max(nc, row_lengths.back());
|
||||
}
|
||||
|
||||
void
|
||||
MatrixParser::start_row()
|
||||
{
|
||||
row_lengths.push_back(0);
|
||||
}
|
||||
|
||||
void
|
||||
MatrixParser::error(string mes) const
|
||||
{
|
||||
throw ParserException(std::move(mes), matrix_lloc.off);
|
||||
}
|
||||
|
||||
int
|
||||
MatrixParser::find_first_non_empty_row(int start) const
|
||||
{
|
||||
int r = start;
|
||||
while (r < static_cast<int>(row_lengths.size()) && row_lengths[r] == 0)
|
||||
r++;
|
||||
return r;
|
||||
}
|
||||
|
||||
MPIterator
|
||||
MatrixParser::begin() const
|
||||
{
|
||||
MPIterator it(*this);
|
||||
return it;
|
||||
}
|
||||
|
||||
MPIterator
|
||||
MatrixParser::end() const
|
||||
{
|
||||
MPIterator it(*this, "end");
|
||||
return it;
|
||||
}
|
||||
|
||||
MPIterator::MPIterator(const MatrixParser &mp)
|
||||
: p(&mp), i(0), r(mp.find_first_non_empty_row())
|
||||
{
|
||||
}
|
||||
|
||||
MPIterator::MPIterator(const MatrixParser &mp, const char *dummy)
|
||||
: p(&mp), i(mp.data.size()), r(mp.row_lengths.size())
|
||||
{
|
||||
}
|
||||
|
||||
MPIterator &
|
||||
MPIterator::operator++()
|
||||
{
|
||||
i++;
|
||||
c++;
|
||||
if (p->row_lengths[r] <= c)
|
||||
{
|
||||
c = 0;
|
||||
r = p->find_first_non_empty_row(r+1);
|
||||
}
|
||||
return *this;
|
||||
}
|
|
@ -1,150 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2006 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OGP_MATRIX_PARSER
|
||||
#define OGP_MATRIX_PARSER
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace ogp
|
||||
{
|
||||
using std::vector;
|
||||
|
||||
/** This class reads the given string and parses it as a
|
||||
* matrix. The matrix is read row by row. The row delimiter is
|
||||
* either a newline character or semicolon (first newline
|
||||
* character after the semicolon is ignored), the column delimiter
|
||||
* is either blank character or comma. A different number of items
|
||||
* in the row is not reconciliated, we do not construct a matrix
|
||||
* here. The class provides only an iterator to go through all
|
||||
* read items, the iterator provides information on row number and
|
||||
* column number of the item. */
|
||||
class MPIterator;
|
||||
class MatrixParser
|
||||
{
|
||||
friend class MPIterator;
|
||||
protected:
|
||||
/** Raw data as they were read. */
|
||||
vector<double> data;
|
||||
/** Number of items in each row. */
|
||||
vector<int> row_lengths;
|
||||
/** Maximum number of row lengths. */
|
||||
int nc{0};
|
||||
public:
|
||||
MatrixParser() = default;
|
||||
MatrixParser(const MatrixParser &mp) = default;
|
||||
virtual ~MatrixParser() = default;
|
||||
/** Return a number of read rows. */
|
||||
int
|
||||
nrows() const
|
||||
{
|
||||
return static_cast<int>(row_lengths.size());
|
||||
}
|
||||
/** Return a maximum number of items in the rows. */
|
||||
int
|
||||
ncols() const
|
||||
{
|
||||
return nc;
|
||||
}
|
||||
/** Parses a given data. This initializes the object data. */
|
||||
void parse(const std::string &stream);
|
||||
/** Adds newly read item. This should be called from bison
|
||||
* parser. */
|
||||
void add_item(double v);
|
||||
/** Starts a new row. This should be called from bison
|
||||
* parser. */
|
||||
void start_row();
|
||||
/** Process a parse error from the parser. */
|
||||
void error(std::string mes) const;
|
||||
/** Return begin iterator. */
|
||||
MPIterator begin() const;
|
||||
/** Return end iterator. */
|
||||
MPIterator end() const;
|
||||
protected:
|
||||
/** Returns an index of the first non-empty row starting at
|
||||
* start. If the start row is non-empty, returns the start. If
|
||||
* there is no other non-empty row, returns
|
||||
* row_lengths.size(). */
|
||||
int find_first_non_empty_row(int start = 0) const;
|
||||
};
|
||||
|
||||
/** This is an iterator intended to iterate through a matrix parsed
|
||||
* by MatrixParser. The iterator provides only read-only access. */
|
||||
class MPIterator
|
||||
{
|
||||
friend class MatrixParser;
|
||||
protected:
|
||||
/** Reference to the matrix parser. */
|
||||
const MatrixParser *p{nullptr};
|
||||
/** The index of the pointed item in the matrix parser. */
|
||||
unsigned int i{0};
|
||||
/** The column number of the pointed item starting from zero. */
|
||||
int c{0};
|
||||
/** The row number of the pointed item starting from zero. */
|
||||
int r{0};
|
||||
|
||||
public:
|
||||
MPIterator() = default;
|
||||
/** Constructs an iterator pointing to the beginning of the
|
||||
* parsed matrix. */
|
||||
MPIterator(const MatrixParser &mp);
|
||||
/** Constructs an iterator pointing to the past-the-end of the
|
||||
* parsed matrix. */
|
||||
MPIterator(const MatrixParser &mp, const char *dummy);
|
||||
/** Return read-only reference to the pointed item. */
|
||||
const double &
|
||||
operator*() const
|
||||
{
|
||||
return p->data[i];
|
||||
}
|
||||
/** Return a row index of the pointed item. */
|
||||
int
|
||||
row() const
|
||||
{
|
||||
return r;
|
||||
}
|
||||
/** Return a column index of the pointed item. */
|
||||
int
|
||||
col() const
|
||||
{
|
||||
return c;
|
||||
}
|
||||
/** Assignment operator. */
|
||||
MPIterator &operator=(const MPIterator &it) = default;
|
||||
/** Return true if the iterators are the same, this is if they
|
||||
* have the same underlying object and the same item index. */
|
||||
bool
|
||||
operator==(const MPIterator &it) const
|
||||
{
|
||||
return it.p == p && it.i == i;
|
||||
}
|
||||
/** Negative of the operator==. */
|
||||
bool
|
||||
operator!=(const MPIterator &it) const
|
||||
{
|
||||
return !(it == *this);
|
||||
}
|
||||
/** Increment operator. */
|
||||
MPIterator &operator++();
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2006 Ondra Kamenik
|
||||
* Copyright © 2019 Dynare Team
|
||||
*
|
||||
* This file is part of Dynare.
|
||||
*
|
||||
* Dynare is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dynare is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "parser_exception.hh"
|
||||
|
||||
using namespace ogp;
|
||||
|
||||
ParserException::ParserException(string m, int offset)
|
||||
: mes(std::move(m)), off(offset),
|
||||
aux_i1(-1), aux_i2(-1), aux_i3(-1)
|
||||
{
|
||||
}
|
||||
|
||||
ParserException::ParserException(string m, const char *dum, int i1)
|
||||
: mes(std::move(m)), off(0),
|
||||
aux_i1(i1), aux_i2(-1), aux_i3(-1)
|
||||
{
|
||||
}
|
||||
|
||||
ParserException::ParserException(string m, const char *dum, int i1, int i2)
|
||||
: mes(std::move(m)), off(0),
|
||||
aux_i1(i1), aux_i2(i2), aux_i3(-1)
|
||||
{
|
||||
}
|
||||
|
||||
ParserException::ParserException(string m, const char *dum, int i1, int i2, int i3)
|
||||
: mes(std::move(m)), off(0),
|
||||
aux_i1(i1), aux_i2(i2), aux_i3(i3)
|
||||
{
|
||||
}
|
||||
|
||||
ParserException::ParserException(const ParserException &m, int plus_offset)
|
||||
: aux_i1(-1), aux_i2(-1), aux_i3(-1)
|
||||
{
|
||||
copy(m);
|
||||
off += plus_offset;
|
||||
}
|
||||
|
||||
ParserException::ParserException(const ParserException &m, const char *dum, int i)
|
||||
: aux_i1(-1), aux_i2(-1), aux_i3(-1)
|
||||
{
|
||||
copy(m);
|
||||
aux_i3 = m.aux_i2;
|
||||
aux_i2 = m.aux_i1;
|
||||
aux_i1 = i;
|
||||
}
|
||||
|
||||
ParserException::ParserException(const ParserException &m, const char *dum, int i1, int i2)
|
||||
: aux_i1(-1), aux_i2(-1), aux_i3(-1)
|
||||
{
|
||||
copy(m);
|
||||
aux_i3 = m.aux_i1;
|
||||
aux_i2 = i2;
|
||||
aux_i1 = i1;
|
||||
}
|
||||
|
||||
ParserException::ParserException(const ParserException &m, const char *dum, int i1, int i2, int i3)
|
||||
: aux_i1(-1), aux_i2(-1), aux_i3(-1)
|
||||
{
|
||||
copy(m);
|
||||
aux_i3 = i3;
|
||||
aux_i2 = i2;
|
||||
aux_i1 = i1;
|
||||
}
|
||||
|
||||
void
|
||||
ParserException::copy(const ParserException &e)
|
||||
{
|
||||
mes = e.mes;
|
||||
off = e.off;
|
||||
aux_i1 = e.aux_i1;
|
||||
aux_i2 = e.aux_i2;
|
||||
aux_i3 = e.aux_i3;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue