Coverage for gpkit\tests\t_examples.py : 0%
![Show keyboard shortcuts](keybd_closed.png)
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""Unit testing of tests in docs/source/examples"""
2import unittest
3import os
4import pickle
5import numpy as np
7from gpkit import settings, Model, Variable
8from gpkit.tests.helpers import generate_example_tests
9from gpkit.small_scripts import mag
10from gpkit.small_classes import Quantity
11from gpkit.constraints.loose import Loose
12from gpkit.exceptions import (UnknownInfeasible,
13 PrimalInfeasible, DualInfeasible, UnboundedGP)
16def assert_logtol(first, second, logtol=1e-6):
17 "Asserts that the logs of two arrays have a given abstol"
18 np.testing.assert_allclose(np.log(mag(first)), np.log(mag(second)),
19 atol=logtol, rtol=0)
22# pylint: disable=too-many-public-methods
23class TestExamples(unittest.TestCase):
24 """
25 To test a new example, add a function called `test_$EXAMPLENAME`, where
26 $EXAMPLENAME is the name of your example in docs/source/examples without
27 the file extension.
29 This function should accept two arguments (e.g. 'self' and 'example').
30 The imported example script will be passed to the second: anything that
31 was a global variable (e.g, "sol") in the original script is available
32 as an attribute (e.g., "example.sol")
34 If you don't want to perform any checks on the example besides making
35 sure it runs, just put "pass" as the function's body, e.g.:
37 def test_dummy_example(self, example):
38 pass
40 But it's good practice to ensure the example's solution as well, e.g.:
42 def test_dummy_example(self, example):
43 self.assertAlmostEqual(example.sol["cost"], 3.121)
44 """
46 # TODO: allow enabling plotting examples, make plots in correct folder...
47 # def test_plot_sweep1d(self, _):
48 # import matplotlib.pyplot as plt
49 # plt.close("all")
51 def test_issue_1513(self, example):
52 pass
54 def test_autosweep(self, example):
55 from gpkit import ureg
56 bst1, tol1 = example.bst1, example.tol1
57 bst2, tol2 = example.bst2, example.tol2
59 l_ = np.linspace(1, 10, 100)
60 for bst in [bst1, example.bst1_loaded]:
61 sol1 = bst.sample_at(l_)
62 assert_logtol(sol1("l"), l_)
63 assert_logtol(sol1("A"), l_**2 + 1, tol1)
64 assert_logtol(sol1["cost"], (l_**2 + 1)**2, tol1)
65 self.assertEqual(Quantity(1.0, sol1("A").units),
66 Quantity(1.0, ureg.m)**2)
68 ndig = -int(np.log10(tol2))
69 self.assertAlmostEqual(bst2.cost_at("cost", 3), 1.0, ndig)
70 # before corner
71 A_bc = np.linspace(1, 3, 50)
72 sol_bc = bst2.sample_at(A_bc)
73 assert_logtol(sol_bc("A"), (A_bc/3)**0.5, tol2)
74 assert_logtol(sol_bc["cost"], A_bc/3, tol2)
75 # after corner
76 A_ac = np.linspace(3, 10, 50)
77 sol_ac = bst2.sample_at(A_ac)
78 assert_logtol(sol_ac("A"), (A_ac/3)**2, tol2)
79 assert_logtol(sol_ac["cost"], (A_ac/3)**4, tol2)
81 def test_treemap(self, example):
82 pass
84 def test_checking_result_changes(self, example):
85 sol = example.sol
86 self.assertAlmostEqual(sol["cost"], 0.48, 2)
88 def test_evaluated_fixed_variables(self, example):
89 sol = example.sol
90 t_night = example.t_night
91 self.assertTrue((sol["variables"][t_night] == [16, 12, 8]).all())
93 def test_evaluated_free_variables(self, example):
94 x2 = example.x2
95 sol = example.sol
96 self.assertTrue(abs(sol(x2) - 4) <= 1e-4)
98 def test_external_constraint(self, example):
99 pass
101 def test_migp(self, example):
102 if settings["default_solver"] == "mosek_conif":
103 assert_logtol(example.sol(example.x), [1]*3 + [2]*6 + [3]*2)
104 else:
105 assert_logtol(example.sol(example.x),
106 np.sqrt(example.sol(example.num)))
108 def test_external_function(self, example):
109 external_code = example.external_code
110 self.assertEqual(external_code(0), 0)
112 def test_external_sp(self, example):
113 m = example.m
114 sol = m.localsolve(verbosity=0)
115 self.assertAlmostEqual(sol["cost"], 0.707, places=3)
117 def test_freeing_fixed_variables(self, example):
118 x = example.x
119 y = Variable("y", 3)
120 m = Model(x, [x >= 1 + y, y >= 1])
121 sol = m.solve(verbosity=0)
122 self.assertTrue(abs(sol["cost"] - 4) <= 1e-4)
123 self.assertTrue(y in sol["constants"])
125 del m.substitutions["y"]
126 sol = m.solve(verbosity=0)
127 self.assertTrue(abs(sol["cost"] - 2) <= 1e-4)
128 self.assertTrue(y in sol["freevariables"])
130 def test_gettingstarted(self, example):
131 pass
134 def test_loose_constraintsets(self, example):
135 m = example.m
136 sol = m.solve(verbosity=0)
137 self.assertAlmostEqual(sol["cost"], 2, 3)
139 def test_sub_multi_values(self, example):
140 x = example.x
141 y = example.y
142 z = example.z
143 p = example.p
144 self.assertTrue(all(p.sub({x: 1, "y": 2}) == 2*z))
145 self.assertTrue(all(
146 p.sub({x: 1, y: 2, "z": [1, 2]}) == z.sub({z: [2, 4]})
147 ))
149 def test_substitutions(self, example):
150 x = example.x
151 p = example.p
152 self.assertTrue(p.sub({x: 3}) == 9)
153 self.assertTrue(p.sub({x.key: 3}) == 9)
154 self.assertTrue(p.sub({"x": 3}) == 9)
156 def test_tight_constraintsets(self, example):
157 m = example.m
158 sol = m.solve(verbosity=0)
159 self.assertAlmostEqual(sol["cost"], 2, places=2)
161 def test_vectorization(self, example):
162 x = example.x
163 y = example.y
164 z = example.z
165 self.assertEqual(y.shape, (5, 3))
166 self.assertEqual(x.shape, (2, 5, 3))
167 self.assertEqual(z.shape, (7, 3))
169 def test_model_var_access(self, example):
170 model = example.PS
171 _ = model["E"]
172 with self.assertRaises(ValueError):
173 _ = model["m"] # multiple variables called m
175 def test_performance_modeling(self, example):
176 m = Model(example.M.cost, Loose(example.M), example.M.substitutions)
178 sol = m.solve(verbosity=0)
179 sol.table()
180 sol.save("solution.pkl")
181 sol.table()
182 sol_loaded = pickle.load(open("solution.pkl", "rb"))
183 sol_loaded.table()
185 sweepsol = m.sweep({example.AC.fuse.W: (50, 100, 150)}, verbosity=0)
186 sweepsol.table()
187 sweepsol.save("sweepsolution.pkl")
188 sweepsol.table()
189 sol_loaded = pickle.load(open("sweepsolution.pkl", "rb"))
190 sol_loaded.table()
192 def test_sp_to_gp_sweep(self, example):
193 sol = example.sol
194 cost = sol["cost"]
195 self.assertAlmostEqual(cost[0], 4628.21, places=2)
196 self.assertAlmostEqual(cost[1], 6226.60, places=2)
197 self.assertAlmostEqual(cost[2], 7362.77, places=2)
199 def test_boundschecking(self, example): # pragma: no cover
200 if "mosek_cli" in settings["default_solver"]:
201 with self.assertRaises(UnknownInfeasible):
202 example.gp.solve(verbosity=0)
203 else:
204 example.gp.solve(verbosity=0) # mosek_conif and cvxopt solve it
206 def test_vectorize(self, example):
207 pass
209 def test_primal_infeasible_ex1(self, example):
210 primal_or_unknown = PrimalInfeasible
211 if "cvxopt" in settings["default_solver"]: # pragma: no cover
212 primal_or_unknown = UnknownInfeasible
213 with self.assertRaises(primal_or_unknown):
214 example.m.solve(verbosity=0)
216 def test_primal_infeasible_ex2(self, example):
217 primal_or_unknown = PrimalInfeasible
218 if "cvxopt" in settings["default_solver"]: # pragma: no cover
219 primal_or_unknown = UnknownInfeasible
220 with self.assertRaises(primal_or_unknown):
221 example.m.solve(verbosity=0)
223 def test_docstringparsing(self, example):
224 pass
226 def test_debug(self, example):
227 dual_or_primal = DualInfeasible
228 if "mosek_conif" == settings["default_solver"]: # pragma: no cover
229 dual_or_primal = PrimalInfeasible
230 with self.assertRaises(UnboundedGP):
231 example.m.gp()
232 with self.assertRaises(dual_or_primal):
233 gp = example.m.gp(checkbounds=False)
234 gp.solve(verbosity=0)
236 primal_or_unknown = PrimalInfeasible
237 if "cvxopt" == settings["default_solver"]: # pragma: no cover
238 primal_or_unknown = UnknownInfeasible
239 with self.assertRaises(primal_or_unknown):
240 example.m2.solve(verbosity=0)
242 with self.assertRaises(UnboundedGP):
243 example.m3.gp()
244 with self.assertRaises(DualInfeasible):
245 gp3 = example.m3.gp(checkbounds=False)
246 gp3.solve(verbosity=0)
248 def test_simple_sp(self, example):
249 pass
251 def test_simple_box(self, example):
252 pass
254 def test_x_greaterthan_1(self, example):
255 pass
257 def test_beam(self, example):
258 self.assertFalse(np.isnan(example.sol("w")).any())
260 def test_water_tank(self, example):
261 pass
263 def test_sin_approx_example(self, example):
264 pass
266 def test_simpleflight(self, example):
267 self.assertTrue(example.sol.almost_equal(example.sol_loaded))
268 for sol in [example.sol, example.sol_loaded]:
269 freevarcheck = {
270 "A": 8.46,
271 "C_D": 0.0206,
272 "C_f": 0.0036,
273 "C_L": 0.499,
274 "Re": 3.68e+06,
275 "S": 16.4,
276 "W": 7.34e+03,
277 "V": 38.2,
278 "W_w": 2.40e+03
279 }
280 # sensitivity values from p. 34 of W. Hoburg's thesis
281 senscheck = {
282 r"(\frac{S}{S_{wet}})": 0.4300,
283 "e": -0.4785,
284 "V_{min}": -0.3691,
285 "k": 0.4300,
286 r"\mu": 0.0860,
287 "(CDA0)": 0.0915,
288 "C_{L,max}": -0.1845,
289 r"\tau": -0.2903,
290 "N_{ult}": 0.2903,
291 "W_0": 1.0107,
292 r"\rho": -0.2275
293 }
294 for key in freevarcheck:
295 sol_rat = mag(sol["variables"][key])/freevarcheck[key]
296 self.assertTrue(abs(1-sol_rat) < 1e-2)
297 for key in senscheck:
298 sol_rat = sol["sensitivities"]["variables"][key]/senscheck[key]
299 self.assertTrue(abs(1-sol_rat) < 1e-2)
301 def test_relaxation(self, example):
302 pass
304 def test_unbounded(self, example):
305 pass
308FILE_DIR = os.path.dirname(os.path.realpath(__file__))
309EXAMPLE_DIR = os.path.abspath(FILE_DIR + '../../../docs/source/examples')
310SOLVERS = settings["installed_solvers"]
311if os.path.isdir(EXAMPLE_DIR):
312 TESTS = generate_example_tests(EXAMPLE_DIR, [TestExamples], SOLVERS)
313else: # pragma: no cover
314 TESTS = []
316if __name__ == "__main__": # pragma: no cover
317 # pylint:disable=wrong-import-position
318 from gpkit.tests.helpers import run_tests
319 run_tests(TESTS)