Coverage for gpkit/tests/t_vars.py: 100%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

195 statements  

1"""Test VarKey, Variable, VectorVariable, and ArrayVariable classes""" 

2import sys 

3import unittest 

4import numpy as np 

5from gpkit import (Monomial, NomialArray, Variable, VarKey, 

6 VectorVariable, ArrayVariable, Vectorize) 

7import gpkit 

8from gpkit.nomials import Variable as PlainVariable 

9 

10 

11class TestVarKey(unittest.TestCase): 

12 """TestCase for the VarKey class""" 

13 

14 def test_init(self): 

15 """Test VarKey initialization""" 

16 # test no-name init 

17 _ = ArrayVariable(1) 

18 # test protected field 

19 with self.assertRaises(ValueError): 

20 _ = ArrayVariable(1, idx=5) 

21 # test type 

22 x = VarKey('x') 

23 self.assertEqual(type(x), VarKey) 

24 # test no args 

25 x = VarKey() 

26 self.assertEqual(type(x), VarKey) 

27 y = VarKey(**x.descr) 

28 self.assertEqual(x, y) 

29 # test special 'name' keyword overwriting behavior 

30 x = VarKey('x', flavour='vanilla') 

31 self.assertEqual(x.name, 'x') 

32 x = VarKey(name='x') 

33 self.assertEqual(x.name, 'x') 

34 # pylint: disable=redundant-keyword-arg 

35 self.assertRaises(TypeError, lambda: VarKey('x', name='y')) 

36 self.assertIsInstance(x.latex(), str) 

37 self.assertIsInstance(x.latex_unitstr(), str) 

38 # test index latex printing 

39 y = VectorVariable(2, "y") 

40 self.assertEqual(y[0].key.latex(), "{\\vec{y}}_{0}") 

41 

42 def test_ast(self): # pylint: disable=too-many-statements 

43 if sys.platform[:3] == "win": # pragma: no cover 

44 return 

45 

46 t = Variable("t") 

47 u = Variable("u") 

48 v = Variable("v") 

49 w = Variable("w") 

50 x = VectorVariable(3, "x") 

51 y = VectorVariable(3, "y") 

52 z = VectorVariable(3, "z") 

53 a = VectorVariable((3, 2), "a") 

54 

55 # print(w >= x) # TODO: this always prints the vector on the left 

56 self.assertEqual(str(3*(x + y)*z), "3·(x[:] + y[:])·z[:]") 

57 nni = 3 

58 ii = np.tile(np.arange(1, nni+1), a.shape[1:]+(1,)).T 

59 self.assertEqual(str(w*NomialArray(ii)/nni)[:4], "w·[[") 

60 self.assertEqual(str(w*NomialArray(ii)/nni)[-4:], "]]/3") 

61 self.assertEqual(str(NomialArray(ii)*w/nni)[:2], "[[") 

62 self.assertEqual(str(NomialArray(ii)*w/nni)[-6:], "]]·w/3") 

63 self.assertEqual(str(w*ii/nni)[:4], "w·[[") 

64 self.assertEqual(str(w*ii/nni)[-4:], "]]/3") 

65 self.assertEqual(str(w*(ii/nni))[:4], "w·[[") 

66 self.assertEqual(str(w*(ii/nni))[-2:], "]]") 

67 self.assertEqual(str(w >= (x[0]*t + x[1]*u)/v), 

68 "w ≥ (x[0]·t + x[1]·u)/v") 

69 self.assertEqual(str(x), "x[:]") 

70 self.assertEqual(str(x*2), "x[:]·2") 

71 self.assertEqual(str(2*x), "2·x[:]") 

72 self.assertEqual(str(x + 2), "x[:] + 2") 

73 self.assertEqual(str(2 + x), "2 + x[:]") 

74 self.assertEqual(str(x/2), "x[:]/2") 

75 self.assertEqual(str(2/x), "2/x[:]") 

76 self.assertEqual(str(x**3), "x[:]³") 

77 self.assertEqual(str(-x), "-x[:]") 

78 self.assertEqual(str(x/y/z), "x[:]/y[:]/z[:]") 

79 self.assertEqual(str(x/(y/z)), "x[:]/(y[:]/z[:])") 

80 self.assertEqual(str(x <= y), "x[:] ≤ y[:]") 

81 self.assertEqual(str(x >= y + z), "x[:] ≥ y[:] + z[:]") 

82 self.assertEqual(str(x[:2]), "x[:2]") 

83 self.assertEqual(str(x[:]), "x[:]") 

84 self.assertEqual(str(x[1:]), "x[1:]") 

85 self.assertEqual(str(y * [1, 2, 3]), "y[:]·[1, 2, 3]") 

86 self.assertEqual(str(x[:2] == (y*[1, 2, 3])[:2]), 

87 "x[:2] = (y[:]·[1, 2, 3])[:2]") 

88 self.assertEqual(str(y + [1, 2, 3]), "y[:] + [1, 2, 3]") 

89 self.assertEqual(str(x == y + [1, 2, 3]), "x[:] = y[:] + [1, 2, 3]") 

90 self.assertEqual(str(x >= y + [1, 2, 3]), "x[:] ≥ y[:] + [1, 2, 3]") 

91 self.assertEqual(str(a[:, 0]), "a[:,0]") 

92 self.assertEqual(str(a[2, :]), "a[2,:]") 

93 g = 1 + 3*a[2, 0]**2 

94 gstrbefore = str(g) 

95 g.ast = None 

96 gstrafter = str(g) 

97 self.assertEqual(gstrbefore, gstrafter) 

98 

99 cstr = str(2*a >= a + np.ones((3, 2))/2) 

100 self.assertEqual(cstr, """2·a[:] ≥ a[:] + [[0.5 0.5] 

101 [0.5 0.5] 

102 [0.5 0.5]]""") 

103 

104 def test_eq_neq(self): 

105 """Test boolean equality operators""" 

106 # no args 

107 vk1 = VarKey() 

108 vk2 = VarKey() 

109 self.assertTrue(vk1 != vk2) 

110 self.assertFalse(vk1 == vk2) 

111 self.assertEqual(vk1, vk1) 

112 V = VarKey('V') 

113 vel = VarKey('V') 

114 self.assertTrue(V == vel) 

115 self.assertFalse(V != vel) 

116 self.assertEqual(vel, vel) 

117 x1 = Variable("x", 3, "m") 

118 x2 = Variable("x", 2, "ft") 

119 x3 = Variable("x", 2, "m") 

120 self.assertNotEqual(x2.key, x3.key) 

121 self.assertEqual(x1.key, x3.key) 

122 

123 def test_repr(self): 

124 """Test __repr__ method""" 

125 for k in ('x', '$x$', 'var_name', 'var name', r"\theta", r'$\pi_{10}$'): 

126 var = VarKey(k) 

127 self.assertEqual(repr(var), k) 

128 

129 def test_dict_key(self): 

130 """make sure variables are well-behaved dict keys""" 

131 v = VarKey() 

132 x = VarKey('$x$') 

133 d = {v: 1273, x: 'foo'} 

134 self.assertEqual(d[v], 1273) 

135 self.assertEqual(d[x], 'foo') 

136 d = {VarKey(): None, VarKey(): 12} 

137 self.assertEqual(len(d), 2) 

138 

139 def test_units_attr(self): 

140 """Make sure VarKey objects have a units attribute""" 

141 x = VarKey('x') 

142 for vk in (VarKey(), x, VarKey(**x.descr), VarKey(units='m')): 

143 self.assertTrue("units" in vk.descr) 

144 

145class TestVariable(unittest.TestCase): 

146 """TestCase for the Variable class""" 

147 

148 def test_init(self): 

149 """Test Variable initialization""" 

150 v = Variable('v') 

151 self.assertTrue(isinstance(v, PlainVariable)) 

152 self.assertTrue(isinstance(v, Monomial)) 

153 # test that operations on Variable cast to Monomial 

154 self.assertTrue(isinstance(3*v, Monomial)) 

155 self.assertFalse(isinstance(3*v, PlainVariable)) 

156 

157 def test_value(self): 

158 """Detailed tests for value kwarg of __init__""" 

159 a = Variable('a') 

160 b = Variable('b', value=4) 

161 c = a**2 + b 

162 self.assertEqual(b.value, 4) 

163 self.assertTrue(isinstance(b.value, float)) 

164 p1 = c.value 

165 p2 = a**2 + 4 

166 self.assertEqual(p1, p2) 

167 self.assertEqual(a.value, a) 

168 

169 def test_hash(self): 

170 x1 = Variable("x", "-", "first x") 

171 x2 = Variable("x", "-", "second x") 

172 self.assertEqual(hash(x1), hash(x2)) 

173 p1 = Variable("p", "psi", "first pressure") 

174 p2 = Variable("p", "psi", "second pressure") 

175 self.assertEqual(hash(p1), hash(p2)) 

176 xu = Variable("x", "m", "x with units") 

177 self.assertNotEqual(hash(x1), hash(xu)) 

178 

179 def test_unit_parsing(self): 

180 x = Variable("x", "s^0.5/m^0.5") 

181 y = Variable("y", "(m/s)^-0.5") 

182 self.assertEqual(x.units, y.units) 

183 

184 def test_to(self): 

185 x = Variable("x", "ft") 

186 self.assertEqual(x.to("inch").c.magnitude, 12) 

187 

188 def test_eq_ne(self): 

189 # test for #1138 

190 W = Variable("W", 5, "lbf", "weight of 1 bag of sugar") 

191 self.assertTrue(W != W.key) 

192 self.assertTrue(W.key != W) 

193 self.assertFalse(W == W.key) 

194 self.assertFalse(W.key == W) 

195 

196 

197class TestVectorVariable(unittest.TestCase): 

198 """TestCase for the VectorVariable class. 

199 Note: more relevant tests in t_posy_array.""" 

200 

201 def test_init(self): 

202 """Test VectorVariable initialization""" 

203 # test 1 

204 n = 3 

205 v = VectorVariable(n, 'v', label='dummy variable') 

206 self.assertTrue(isinstance(v, NomialArray)) 

207 v_mult = 3*v 

208 for i in range(n): 

209 self.assertTrue(isinstance(v[i], PlainVariable)) 

210 self.assertTrue(isinstance(v[i], Monomial)) 

211 # test that operations on Variable cast to Monomial 

212 self.assertTrue(isinstance(v_mult[i], Monomial)) 

213 self.assertFalse(isinstance(v_mult[i], PlainVariable)) 

214 

215 # test 2 

216 x = VectorVariable(3, 'x', label='dummy variable') 

217 x_0 = Variable('x', idx=(0,), shape=(3,), label='dummy variable') 

218 x_1 = Variable('x', idx=(1,), shape=(3,), label='dummy variable') 

219 x_2 = Variable('x', idx=(2,), shape=(3,), label='dummy variable') 

220 x2 = NomialArray([x_0, x_1, x_2]) 

221 self.assertEqual(x, x2) 

222 

223 # test inspired by issue 137 

224 N = 20 

225 x_arr = np.arange(0, 5, 5/N) + 1e-6 

226 x = VectorVariable(N, 'x', x_arr, 'm', "Beam Location") 

227 

228 with self.assertRaises(ValueError): 

229 _ = VectorVariable(2, "x", [1, 2, 3]) 

230 

231 with Vectorize(2): 

232 x = VectorVariable(3, "x", np.array([13, 15, 17])) 

233 self.assertEqual(x[0, 0].value, 13) 

234 self.assertEqual(x[1, 0].value, 15) 

235 self.assertEqual(x[2, 0].value, 17) 

236 self.assertEqual(x[0, 0].value, x[0, 1].value) 

237 self.assertEqual(x[1, 0].value, x[1, 1].value) 

238 self.assertEqual(x[2, 0].value, x[2, 1].value) 

239 

240 

241class TestArrayVariable(unittest.TestCase): 

242 """TestCase for the ArrayVariable class""" 

243 

244 def test_is_vector_variable(self): 

245 """ 

246 Make sure ArrayVariable is a shortcut to VectorVariable 

247 (we want to know if this changes). 

248 """ 

249 self.assertTrue(ArrayVariable is VectorVariable) 

250 

251 def test_str(self): 

252 """Make sure string looks something like a numpy array""" 

253 x = ArrayVariable((2, 4), 'x') 

254 self.assertEqual(str(x), "x[:]") 

255 

256 

257class TestVectorize(unittest.TestCase): 

258 """TestCase for gpkit.vectorize""" 

259 

260 def test_shapes(self): 

261 with gpkit.Vectorize(3): 

262 with gpkit.Vectorize(5): 

263 y = gpkit.Variable("y") 

264 x = gpkit.VectorVariable(2, "x") 

265 z = gpkit.VectorVariable(7, "z") 

266 

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

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

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

270 

271 

272TESTS = [TestVarKey, TestVariable, TestVectorVariable, TestArrayVariable, 

273 TestVectorize] 

274 

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

276 # pylint: disable=wrong-import-position 

277 from gpkit.tests.helpers import run_tests 

278 run_tests(TESTS)