Coverage for gpkit/tests/t_vars.py: 100%
195 statements
« prev ^ index » next coverage.py v6.4.2, created at 2022-07-28 12:37 -0400
« prev ^ index » next coverage.py v6.4.2, created at 2022-07-28 12:37 -0400
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
11class TestVarKey(unittest.TestCase):
12 """TestCase for the VarKey class"""
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}")
42 def test_ast(self): # pylint: disable=too-many-statements
43 if sys.platform[:3] == "win": # pragma: no cover
44 return
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")
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)
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]]""")
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)
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)
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)
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)
145class TestVariable(unittest.TestCase):
146 """TestCase for the Variable class"""
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))
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)
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))
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)
184 def test_to(self):
185 x = Variable("x", "ft")
186 self.assertEqual(x.to("inch").c.magnitude, 12)
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)
197class TestVectorVariable(unittest.TestCase):
198 """TestCase for the VectorVariable class.
199 Note: more relevant tests in t_posy_array."""
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))
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)
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")
228 with self.assertRaises(ValueError):
229 _ = VectorVariable(2, "x", [1, 2, 3])
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)
241class TestArrayVariable(unittest.TestCase):
242 """TestCase for the ArrayVariable class"""
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)
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[:]")
257class TestVectorize(unittest.TestCase):
258 """TestCase for gpkit.vectorize"""
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")
267 self.assertEqual(y.shape, (5, 3))
268 self.assertEqual(x.shape, (2, 5, 3))
269 self.assertEqual(z.shape, (7, 3))
272TESTS = [TestVarKey, TestVariable, TestVectorVariable, TestArrayVariable,
273 TestVectorize]
275if __name__ == "__main__": # pragma: no cover
276 # pylint: disable=wrong-import-position
277 from gpkit.tests.helpers import run_tests
278 run_tests(TESTS)