88from dolo .compiler .model_v2 import ModelV2 , yaml_compose
99from dolo .numeric .decision_rule import DecisionRule
1010from dolo .numeric .garray import GArray , QP , SliceQP
11- from dolo .numeric .grids import UniformCartesianGrid , ProductGrid , UnstructuredGrid , EmptyGrid
11+ from dolo .numeric .grids import (
12+ UniformCartesianGrid ,
13+ ProductGrid ,
14+ UnstructuredGrid ,
15+ EmptyGrid ,
16+ )
1217from dolo .numeric .tau import Tau , trembling_hand
1318from dolo .numeric .discretized_model import DiscretizedModel
1419from dolo .algos .time_iteration import residuals_simple , time_iteration
@@ -25,6 +30,7 @@ def _load_v2(path: str) -> ModelV2:
2530# 1. GArray and QP Unit Tests
2631# ---------------------------------------------------------------------------
2732
33+
2834def test_garray_cartesian ():
2935 grid = UniformCartesianGrid (min = [0.1 , 1.0 ], max = [0.5 , 5.0 ], n = [10 , 20 ])
3036 ga = GArray .zeros (grid , n_vars = 3 )
@@ -79,7 +85,9 @@ def test_qualified_point_and_batch():
7985 assert "QualifiedPoint" in repr (qp )
8086
8187 # Construct QualifiedBatch
82- batch = QualifiedBatch (loc = 1 , exo = np .array ([0.02 ]), endo = np .array ([[1.0 , 2.0 ], [1.5 , 2.5 ]]))
88+ batch = QualifiedBatch (
89+ loc = 1 , exo = np .array ([0.02 ]), endo = np .array ([[1.0 , 2.0 ], [1.5 , 2.5 ]])
90+ )
8391 assert batch .val .shape == (2 , 3 )
8492 assert np .allclose (batch .val [0 ], [0.02 , 1.0 , 2.0 ])
8593 assert np .allclose (batch .val [1 ], [0.02 , 1.5 , 2.5 ])
@@ -106,7 +114,10 @@ def test_trembling_hand_1d():
106114# 2. Universal Euler Residuals & Parity
107115# ---------------------------------------------------------------------------
108116
109- def euler_residuals (dmodel : DiscretizedModel , controls : GArray , dr : DecisionRule ) -> GArray :
117+
118+ def euler_residuals (
119+ dmodel : DiscretizedModel , controls : GArray , dr : DecisionRule
120+ ) -> GArray :
110121 """Universal Euler residuals using Tau, GArray, and direct dr(SliceQP) calls."""
111122 res = GArray .zeros_like (controls )
112123 for i , m_val , s_endo in dmodel .regimes ():
@@ -119,10 +130,13 @@ def euler_residuals(dmodel: DiscretizedModel, controls: GArray, dr: DecisionRule
119130 return res
120131
121132
122- @pytest .mark .parametrize ("model_path" , [
123- "examples/models/rbc_mc.yaml" ,
124- "examples/models/rbc_iid.yaml" ,
125- ])
133+ @pytest .mark .parametrize (
134+ "model_path" ,
135+ [
136+ "examples/models/rbc_mc.yaml" ,
137+ "examples/models/rbc_iid.yaml" ,
138+ ],
139+ )
126140def test_tau_euler_parity (model_path : str ):
127141 model = _load_v2 (model_path )
128142 dmodel = DiscretizedModel (model )
@@ -156,6 +170,7 @@ def test_tau_euler_parity(model_path: str):
156170# 3. DecisionRule with QP and SliceQP
157171# ---------------------------------------------------------------------------
158172
173+
159174def test_decision_rule_qp_dispatch ():
160175 model = _load_v2 ("examples/models/rbc_mc.yaml" )
161176 dmodel = DiscretizedModel (model )
@@ -185,10 +200,14 @@ def test_decision_rule_qp_dispatch():
185200# 4. Transition Matrix & Ergodic Distribution
186201# ---------------------------------------------------------------------------
187202
188- @pytest .mark .parametrize ("model_path" , [
189- "examples/models/rbc_mc.yaml" ,
190- "examples/models/rbc_iid.yaml" ,
191- ])
203+
204+ @pytest .mark .parametrize (
205+ "model_path" ,
206+ [
207+ "examples/models/rbc_mc.yaml" ,
208+ "examples/models/rbc_iid.yaml" ,
209+ ],
210+ )
192211def test_transition_matrix_and_ergodic (model_path : str ):
193212 model = _load_v2 (model_path )
194213 dmodel = DiscretizedModel (model )
@@ -205,18 +224,24 @@ def test_transition_matrix_and_ergodic(model_path: str):
205224 # Ergodic distribution
206225 mu = dmodel .ergodic_distribution (controls )
207226 assert isinstance (mu , GArray )
208- assert np .isclose (mu .data .sum (), 1.0 ), f"Ergodic distribution does not sum to 1: { mu .data .sum ()} "
227+ assert np .isclose (
228+ mu .data .sum (), 1.0
229+ ), f"Ergodic distribution does not sum to 1: { mu .data .sum ()} "
209230 assert np .all (mu .data >= 0.0 ), "Negative stationary probabilities!"
210231
211232
212233# ---------------------------------------------------------------------------
213234# 5. Full Time Iteration Solver Parity
214235# ---------------------------------------------------------------------------
215236
216- @pytest .mark .parametrize ("model_path" , [
217- "examples/models/rbc_mc.yaml" ,
218- "examples/models/rbc_iid.yaml" ,
219- ])
237+
238+ @pytest .mark .parametrize (
239+ "model_path" ,
240+ [
241+ "examples/models/rbc_mc.yaml" ,
242+ "examples/models/rbc_iid.yaml" ,
243+ ],
244+ )
220245def test_full_solver_parity (model_path : str ):
221246 model = _load_v2 (model_path )
222247 dmodel = DiscretizedModel (model )
@@ -243,22 +268,30 @@ def test_full_solver_parity(model_path: str):
243268 it += 1
244269 dr .set_values (controls )
245270
246- fn = lambda flat_x : euler_residuals (
247- dmodel , controls .unravel (flat_x ), dr
248- ).ravel ().reshape ((- 1 , n_x ))
271+ fn = (
272+ lambda flat_x : euler_residuals (dmodel , controls .unravel (flat_x ), dr )
273+ .ravel ()
274+ .reshape ((- 1 , n_x ))
275+ )
249276
250277 dfn = SerialDifferentiableFunction (fn )
251- flat_controls , _ = newton (dfn , controls .ravel ().reshape ((- 1 , n_x )), verbose = False , maxit = 10 )
278+ flat_controls , _ = newton (
279+ dfn , controls .ravel ().reshape ((- 1 , n_x )), verbose = False , maxit = 10
280+ )
252281 new_controls = controls .unravel (flat_controls )
253282
254283 err = (new_controls - controls ).norm ()
255284 controls = new_controls
256285
257286 # Parity check on final decision rule coefficients
258287 if isinstance (sol_legacy .dr .coefficients , list ):
259- dr_diff = max (float (np .max (np .abs (c1 - c2 ))) for c1 , c2 in zip (sol_legacy .dr .coefficients , dr .coefficients ))
288+ dr_diff = max (
289+ float (np .max (np .abs (c1 - c2 )))
290+ for c1 , c2 in zip (sol_legacy .dr .coefficients , dr .coefficients )
291+ )
260292 else :
261293 dr_diff = float (np .max (np .abs (sol_legacy .dr .coefficients - dr .coefficients )))
262294
263- assert dr_diff < 1e-5 , f"Decision rule parity failed on { model_path } ! diff={ dr_diff } "
264-
295+ assert (
296+ dr_diff < 1e-5
297+ ), f"Decision rule parity failed on { model_path } ! diff={ dr_diff } "
0 commit comments