Hide keyboard shortcuts

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 

6 

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) 

14 

15 

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) 

20 

21 

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. 

28 

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") 

33 

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.: 

36 

37 def test_dummy_example(self, example): 

38 pass 

39 

40 But it's good practice to ensure the example's solution as well, e.g.: 

41 

42 def test_dummy_example(self, example): 

43 self.assertAlmostEqual(example.sol["cost"], 3.121) 

44 """ 

45 

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") 

50 

51 def test_issue_1513(self, example): 

52 pass 

53 

54 def test_issue_1522(self, example): 

55 pass 

56 

57 def test_autosweep(self, example): 

58 from gpkit import ureg 

59 bst1, tol1 = example.bst1, example.tol1 

60 bst2, tol2 = example.bst2, example.tol2 

61 

62 l_ = np.linspace(1, 10, 100) 

63 for bst in [bst1, example.bst1_loaded]: 

64 sol1 = bst.sample_at(l_) 

65 assert_logtol(sol1("l"), l_) 

66 assert_logtol(sol1("A"), l_**2 + 1, tol1) 

67 assert_logtol(sol1["cost"], (l_**2 + 1)**2, tol1) 

68 self.assertEqual(Quantity(1.0, sol1("A").units), 

69 Quantity(1.0, ureg.m)**2) 

70 

71 ndig = -int(np.log10(tol2)) 

72 self.assertAlmostEqual(bst2.cost_at("cost", 3), 1.0, ndig) 

73 # before corner 

74 A_bc = np.linspace(1, 3, 50) 

75 sol_bc = bst2.sample_at(A_bc) 

76 assert_logtol(sol_bc("A"), (A_bc/3)**0.5, tol2) 

77 assert_logtol(sol_bc["cost"], A_bc/3, tol2) 

78 # after corner 

79 A_ac = np.linspace(3, 10, 50) 

80 sol_ac = bst2.sample_at(A_ac) 

81 assert_logtol(sol_ac("A"), (A_ac/3)**2, tol2) 

82 assert_logtol(sol_ac["cost"], (A_ac/3)**4, tol2) 

83 

84 def test_treemap(self, example): 

85 pass 

86 

87 def test_checking_result_changes(self, example): 

88 sol = example.sol 

89 self.assertAlmostEqual(sol["cost"], 0.48, 2) 

90 

91 def test_evaluated_fixed_variables(self, example): 

92 sol = example.sol 

93 t_night = example.t_night 

94 self.assertTrue((sol["variables"][t_night] == [16, 12, 8]).all()) 

95 

96 def test_evaluated_free_variables(self, example): 

97 x2 = example.x2 

98 sol = example.sol 

99 self.assertTrue(abs(sol(x2) - 4) <= 1e-4) 

100 

101 def test_external_constraint(self, example): 

102 pass 

103 

104 def test_migp(self, example): 

105 if settings["default_solver"] == "mosek_conif": 

106 assert_logtol(example.sol(example.x), [1]*3 + [2]*6 + [3]*2) 

107 else: 

108 assert_logtol(example.sol(example.x), 

109 np.sqrt(example.sol(example.num))) 

110 

111 def test_external_function(self, example): 

112 external_code = example.external_code 

113 self.assertEqual(external_code(0), 0) 

114 

115 def test_external_sp(self, example): 

116 m = example.m 

117 sol = m.localsolve(verbosity=0) 

118 self.assertAlmostEqual(sol["cost"], 0.707, places=3) 

119 

120 def test_freeing_fixed_variables(self, example): 

121 x = example.x 

122 y = Variable("y", 3) 

123 m = Model(x, [x >= 1 + y, y >= 1]) 

124 sol = m.solve(verbosity=0) 

125 self.assertTrue(abs(sol["cost"] - 4) <= 1e-4) 

126 self.assertTrue(y in sol["constants"]) 

127 

128 del m.substitutions["y"] 

129 sol = m.solve(verbosity=0) 

130 self.assertTrue(abs(sol["cost"] - 2) <= 1e-4) 

131 self.assertTrue(y in sol["freevariables"]) 

132 

133 def test_gettingstarted(self, example): 

134 pass 

135 

136 

137 def test_loose_constraintsets(self, example): 

138 m = example.m 

139 sol = m.solve(verbosity=0) 

140 self.assertAlmostEqual(sol["cost"], 2, 3) 

141 

142 def test_sub_multi_values(self, example): 

143 x = example.x 

144 y = example.y 

145 z = example.z 

146 p = example.p 

147 self.assertTrue(all(p.sub({x: 1, "y": 2}) == 2*z)) 

148 self.assertTrue(all( 

149 p.sub({x: 1, y: 2, "z": [1, 2]}) == z.sub({z: [2, 4]}) 

150 )) 

151 

152 def test_substitutions(self, example): 

153 x = example.x 

154 p = example.p 

155 self.assertTrue(p.sub({x: 3}) == 9) 

156 self.assertTrue(p.sub({x.key: 3}) == 9) 

157 self.assertTrue(p.sub({"x": 3}) == 9) 

158 

159 def test_tight_constraintsets(self, example): 

160 m = example.m 

161 sol = m.solve(verbosity=0) 

162 self.assertAlmostEqual(sol["cost"], 2, places=2) 

163 

164 def test_vectorization(self, example): 

165 x = example.x 

166 y = example.y 

167 z = example.z 

168 self.assertEqual(y.shape, (5, 3)) 

169 self.assertEqual(x.shape, (2, 5, 3)) 

170 self.assertEqual(z.shape, (7, 3)) 

171 

172 def test_model_var_access(self, example): 

173 model = example.PS 

174 _ = model["E"] 

175 with self.assertRaises(ValueError): 

176 _ = model["m"] # multiple variables called m 

177 

178 def test_performance_modeling(self, example): 

179 m = Model(example.M.cost, Loose(example.M), example.M.substitutions) 

180 

181 sol = m.solve(verbosity=0) 

182 sol.table() 

183 sol.save("solution.pkl") 

184 sol.table() 

185 sol_loaded = pickle.load(open("solution.pkl", "rb")) 

186 sol_loaded.table() 

187 

188 sweepsol = m.sweep({example.AC.fuse.W: (50, 100, 150)}, verbosity=0) 

189 sweepsol.table() 

190 sweepsol.save("sweepsolution.pkl") 

191 sweepsol.table() 

192 sol_loaded = pickle.load(open("sweepsolution.pkl", "rb")) 

193 sol_loaded.table() 

194 

195 def test_sp_to_gp_sweep(self, example): 

196 sol = example.sol 

197 cost = sol["cost"] 

198 self.assertAlmostEqual(cost[0], 4628.21, places=2) 

199 self.assertAlmostEqual(cost[1], 6226.60, places=2) 

200 self.assertAlmostEqual(cost[2], 7362.77, places=2) 

201 

202 def test_boundschecking(self, example): # pragma: no cover 

203 if "mosek_cli" in settings["default_solver"]: 

204 with self.assertRaises(UnknownInfeasible): 

205 example.gp.solve(verbosity=0) 

206 else: 

207 example.gp.solve(verbosity=0) # mosek_conif and cvxopt solve it 

208 

209 def test_vectorize(self, example): 

210 pass 

211 

212 def test_primal_infeasible_ex1(self, example): 

213 primal_or_unknown = PrimalInfeasible 

214 if "cvxopt" in settings["default_solver"]: # pragma: no cover 

215 primal_or_unknown = UnknownInfeasible 

216 with self.assertRaises(primal_or_unknown): 

217 example.m.solve(verbosity=0) 

218 

219 def test_primal_infeasible_ex2(self, example): 

220 primal_or_unknown = PrimalInfeasible 

221 if "cvxopt" in settings["default_solver"]: # pragma: no cover 

222 primal_or_unknown = UnknownInfeasible 

223 with self.assertRaises(primal_or_unknown): 

224 example.m.solve(verbosity=0) 

225 

226 def test_docstringparsing(self, example): 

227 pass 

228 

229 def test_debug(self, example): 

230 dual_or_primal = DualInfeasible 

231 if "mosek_conif" == settings["default_solver"]: # pragma: no cover 

232 dual_or_primal = PrimalInfeasible 

233 with self.assertRaises(UnboundedGP): 

234 example.m.gp() 

235 with self.assertRaises(dual_or_primal): 

236 gp = example.m.gp(checkbounds=False) 

237 gp.solve(verbosity=0) 

238 

239 primal_or_unknown = PrimalInfeasible 

240 if "cvxopt" == settings["default_solver"]: # pragma: no cover 

241 primal_or_unknown = UnknownInfeasible 

242 with self.assertRaises(primal_or_unknown): 

243 example.m2.solve(verbosity=0) 

244 

245 with self.assertRaises(UnboundedGP): 

246 example.m3.gp() 

247 with self.assertRaises(DualInfeasible): 

248 gp3 = example.m3.gp(checkbounds=False) 

249 gp3.solve(verbosity=0) 

250 

251 def test_simple_sp(self, example): 

252 pass 

253 

254 def test_simple_box(self, example): 

255 pass 

256 

257 def test_x_greaterthan_1(self, example): 

258 pass 

259 

260 def test_beam(self, example): 

261 self.assertFalse(np.isnan(example.sol("w")).any()) 

262 

263 def test_water_tank(self, example): 

264 pass 

265 

266 def test_sin_approx_example(self, example): 

267 pass 

268 

269 def test_simpleflight(self, example): 

270 self.assertTrue(example.sol.almost_equal(example.sol_loaded)) 

271 for sol in [example.sol, example.sol_loaded]: 

272 freevarcheck = { 

273 "A": 8.46, 

274 "C_D": 0.0206, 

275 "C_f": 0.0036, 

276 "C_L": 0.499, 

277 "Re": 3.68e+06, 

278 "S": 16.4, 

279 "W": 7.34e+03, 

280 "V": 38.2, 

281 "W_w": 2.40e+03 

282 } 

283 # sensitivity values from p. 34 of W. Hoburg's thesis 

284 senscheck = { 

285 r"(\frac{S}{S_{wet}})": 0.4300, 

286 "e": -0.4785, 

287 "V_{min}": -0.3691, 

288 "k": 0.4300, 

289 r"\mu": 0.0860, 

290 "(CDA0)": 0.0915, 

291 "C_{L,max}": -0.1845, 

292 r"\tau": -0.2903, 

293 "N_{ult}": 0.2903, 

294 "W_0": 1.0107, 

295 r"\rho": -0.2275 

296 } 

297 for key in freevarcheck: 

298 sol_rat = mag(sol["variables"][key])/freevarcheck[key] 

299 self.assertTrue(abs(1-sol_rat) < 1e-2) 

300 for key in senscheck: 

301 sol_rat = sol["sensitivities"]["variables"][key]/senscheck[key] 

302 self.assertTrue(abs(1-sol_rat) < 1e-2) 

303 

304 def test_relaxation(self, example): 

305 pass 

306 

307 def test_unbounded(self, example): 

308 pass 

309 

310 

311FILE_DIR = os.path.dirname(os.path.realpath(__file__)) 

312EXAMPLE_DIR = os.path.abspath(FILE_DIR + '../../../docs/source/examples') 

313SOLVERS = settings["installed_solvers"] 

314if os.path.isdir(EXAMPLE_DIR): 

315 TESTS = generate_example_tests(EXAMPLE_DIR, [TestExamples], SOLVERS) 

316else: # pragma: no cover 

317 TESTS = [] 

318 

319if __name__ == "__main__": # pragma: no cover 

320 # pylint:disable=wrong-import-position 

321 from gpkit.tests.helpers import run_tests 

322 run_tests(TESTS)