def test_variable(self): x = Variable(2) y = Variable(2) assert y.name() != x.name() x = Variable(2, name='x') y = Variable() self.assertEqual(x.name(), 'x') self.assertEqual(x.size, (2,1)) self.assertEqual(y.size, (1,1)) self.assertEqual(x.curvature, u.Curvature.AFFINE) self.assertEqual(x.canonicalize()[0].size, (2,1)) self.assertEqual(x.canonicalize()[1], []) # Scalar variable coeff = self.a.coefficients(self.intf) self.assertEqual(coeff[self.a], 1) # Vector variable. coeffs = x.coefficients(self.intf) self.assertItemsEqual(coeffs.keys(), [x]) vec = coeffs[x] self.assertEqual(vec.size, (2,2)) self.assertEqual(list(vec), [1,0,0,1]) # Matrix variable. coeffs = self.A.coefficients(self.intf) self.assertItemsEqual(coeffs.keys(), [self.A]) mat = coeffs[self.A] self.assertEqual(mat.size, (2,2)) self.assertEqual(list(mat), [1,0,0,1])
def test_variable(self): x = Variable(2) y = Variable(2) assert y.name() != x.name() x = Variable(2, name='x') y = Variable() self.assertEqual(x.name(), 'x') self.assertEqual(x.size, (2, 1)) self.assertEqual(y.size, (1, 1)) self.assertEqual(x.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(x.canonical_form[0].size, (2, 1)) self.assertEqual(x.canonical_form[1], []) # Scalar variable coeff = self.a.coefficients() self.assertEqual(coeff[self.a.id], [1]) # Vector variable. coeffs = x.coefficients() self.assertItemsEqual(coeffs.keys(), [x.id]) vec = coeffs[x.id][0] self.assertEqual(vec.shape, (2, 2)) self.assertEqual(vec[0, 0], 1) # Matrix variable. coeffs = self.A.coefficients() self.assertItemsEqual(coeffs.keys(), [self.A.id]) self.assertEqual(len(coeffs[self.A.id]), 2) mat = coeffs[self.A.id][1] self.assertEqual(mat.shape, (2, 4)) self.assertEqual(mat[0, 2], 1)
def test_variable(self): x = Variable(2) y = Variable(2) assert y.name() != x.name() x = Variable(2, name='x') y = Variable() self.assertEqual(x.name(), 'x') self.assertEqual(x.size, (2,1)) self.assertEqual(y.size, (1,1)) self.assertEqual(x.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(x.canonical_form[0].size, (2,1)) self.assertEqual(x.canonical_form[1], []) # Scalar variable coeff = self.a.coefficients() self.assertEqual(coeff[self.a], [1]) # Vector variable. coeffs = x.coefficients() self.assertItemsEqual(coeffs.keys(), [x]) vec = coeffs[x][0] self.assertEqual(vec.size, (2,2)) self.assertEqual(vec[0,0], 1) # Matrix variable. coeffs = self.A.coefficients() self.assertItemsEqual(coeffs.keys(), [self.A]) self.assertEqual(len(coeffs[self.A]), 2) mat = coeffs[self.A][1] self.assertEqual(mat.size, (2,4)) self.assertEqual(mat[0,2], 1)
class TestVstack(unittest.TestCase): """ Unit tests for the expressions.affine module. """ def setUp(self): self.x = Variable(2, name='x') self.y = Variable(2, name='y') self.A = Variable(3, 2, name='A') self.B = Variable(5, 2, name='B') self.C = Constant([[1, 2], [1, 2]]) self.intf = intf.DEFAULT_INTERFACE # Test the variables method. def test_variables(self): exp, constr = vstack(self.x, self.y, self.x + self.y).canonical_form self.assertEquals(constr, []) self.assertItemsEqual(exp.variables(), [self.x, self.y]) exp = vstack(self.A, self.B, self.C).canonical_form[0] self.assertItemsEqual(exp.variables(), [self.A, self.B]) # Test coefficients method. def test_coefficients(self): exp = vstack(self.x).canonical_form[0] coeffs = exp.coefficients() self.assertEqual(coeffs.keys(), self.x.coefficients().keys()) exp = vstack(self.x, self.y).canonical_form[0] coeffs = exp.coefficients() self.assertItemsEqual(coeffs.keys(), self.x.coefficients().keys() + \ self.y.coefficients().keys()) for k, blocks in coeffs.items(): self.assertEqual(len(blocks), 1) for block in blocks: self.assertEqual(intf.size(block), (4, 2)) exp = vstack(self.A, self.B, self.C).canonical_form[0] coeffs = exp.coefficients() blocks = coeffs[self.A] self.assertEqual(len(blocks), 2) for block in blocks: self.assertEqual(intf.size(block), (10, 6))
class TestVstack(unittest.TestCase): """ Unit tests for the expressions.affine module. """ def setUp(self): self.x = Variable(2, name='x') self.y = Variable(2, name='y') self.A = Variable(3,2, name='A') self.B = Variable(5,2, name='B') self.C = Constant([[1, 2], [1, 2]]) self.intf = intf.DEFAULT_INTERFACE # Test the variables method. def test_variables(self): exp,constr = vstack(self.x, self.y, self.x+self.y).canonical_form self.assertEquals(constr, []) self.assertItemsEqual(exp.variables(), [self.x, self.y]) exp = vstack(self.A, self.B, self.C).canonical_form[0] self.assertItemsEqual(exp.variables(), [self.A, self.B]) # Test coefficients method. def test_coefficients(self): exp = vstack(self.x).canonical_form[0] coeffs = exp.coefficients() self.assertEqual(coeffs.keys(), self.x.coefficients().keys()) exp = vstack(self.x, self.y).canonical_form[0] coeffs = exp.coefficients() self.assertItemsEqual(coeffs.keys(), self.x.coefficients().keys() + \ self.y.coefficients().keys()) for k,blocks in coeffs.items(): self.assertEqual(len(blocks), 1) for block in blocks: self.assertEqual(intf.size(block), (4,2)) exp = vstack(self.A, self.B, self.C).canonical_form[0] coeffs = exp.coefficients() blocks = coeffs[self.A.id] self.assertEqual(len(blocks), 2) for block in blocks: self.assertEqual(intf.size(block), (10,6))
class TestAffVstack(unittest.TestCase): """ Unit tests for the expressions.affine module. """ def setUp(self): self.x = Variable(2, name='x') self.y = Variable(2, name='y') self.A = Variable(3,2, name='A') self.B = Variable(5,2, name='B') self.C = Constant([[1, 2], [1, 2]]) self.intf = intf.DEFAULT_INTERFACE # Test the variables method. def test_variables(self): exp = AffVstack(self.x, self.y, self.x+self.y) self.assertItemsEqual(exp.variables(), [self.x, self.y, self.x, self.y]) exp = AffVstack(self.A, self.B, self.C) self.assertItemsEqual(exp.variables(), [self.A, self.B]) # Test coefficients method. def test_coefficients(self): exp = AffVstack(self.x) coeffs = exp.coefficients(self.intf) self.assertEqual(coeffs.keys(), self.x.coefficients(self.intf).keys()) exp = AffVstack(self.x, self.y) coeffs = exp.coefficients(self.intf) self.assertItemsEqual(coeffs.keys(), self.x.coefficients(self.intf).keys() + \ self.y.coefficients(self.intf).keys()) for k,v in coeffs.items(): self.assertEqual(intf.size(v), (4,2)) exp = AffVstack(self.A, self.B, self.C) coeffs = exp.coefficients(self.intf) v = coeffs[self.A] self.assertEqual(intf.size(v), (10,3))
class TestExpressions(unittest.TestCase): """ Unit tests for the expression/expression module. """ def setUp(self): self.a = Variable(name='a') self.x = Variable(2, name='x') self.y = Variable(3, name='y') self.z = Variable(2, name='z') self.A = Variable(2,2,name='A') self.B = Variable(2,2,name='B') self.C = Variable(3,2,name='C') self.intf = intf.DEFAULT_INTERFACE # Test the Variable class. def test_variable(self): x = Variable(2) y = Variable(2) assert y.name() != x.name() x = Variable(2, name='x') y = Variable() self.assertEqual(x.name(), 'x') self.assertEqual(x.size, (2,1)) self.assertEqual(y.size, (1,1)) self.assertEqual(x.curvature, u.Curvature.AFFINE) self.assertEqual(x.canonicalize()[0].size, (2,1)) self.assertEqual(x.canonicalize()[1], []) # Scalar variable coeff = self.a.coefficients(self.intf) self.assertEqual(coeff[self.a], 1) # Vector variable. coeffs = x.coefficients(self.intf) self.assertItemsEqual(coeffs.keys(), [x]) vec = coeffs[x] self.assertEqual(vec.size, (2,2)) self.assertEqual(list(vec), [1,0,0,1]) # Matrix variable. coeffs = self.A.coefficients(self.intf) self.assertItemsEqual(coeffs.keys(), [self.A]) mat = coeffs[self.A] self.assertEqual(mat.size, (2,2)) self.assertEqual(list(mat), [1,0,0,1]) # Test the TransposeVariable class. def test_transpose_variable(self): var = self.a.T self.assertEquals(var.name(), "a") self.assertEquals(var.size, (1,1)) self.a.save_value(2) self.assertEquals(var.value, 2) var = self.x.T self.assertEquals(var.name(), "x.T") self.assertEquals(var.size, (1,2)) self.x.save_value( matrix([1,2]) ) self.assertEquals(var.value[0,0], 1) self.assertEquals(var.value[0,1], 2) var = self.C.T self.assertEquals(var.name(), "C.T") self.assertEquals(var.size, (2,3)) coeffs = var.coefficients(self.intf) self.assertItemsEqual(coeffs.keys(), [var]) mat = coeffs[var] self.assertEqual(mat.size, (2,2)) self.assertEqual(list(mat), [1,0,0,1]) index = var[1,0] self.assertEquals(index.name(), "C[0,1]") self.assertEquals(index.size, (1,1)) var = self.x.T.T self.assertEquals(var.name(), "x") self.assertEquals(var.size, (2,1)) # Test the Constant class. def test_constants(self): c = Constant(2) self.assertEqual(c.name(), str(2)) c = Constant(2, name="c") self.assertEqual(c.name(), "c") self.assertEqual(c.value, 2) self.assertEqual(c.size, (1,1)) self.assertEqual(c.curvature, u.Curvature.CONSTANT) self.assertEqual(c.sign, u.Sign.POSITIVE) self.assertEqual(Constant(-2).sign, u.Sign.NEGATIVE) self.assertEqual(Constant(0).sign, u.Sign.ZERO) self.assertEqual(c.canonicalize()[0].size, (1,1)) self.assertEqual(c.canonicalize()[1], []) coeffs = c.coefficients(self.intf) self.assertEqual(coeffs.keys(), [s.CONSTANT]) self.assertEqual(coeffs[s.CONSTANT], 2) # Test the sign. c = Constant([[2],[2]]) self.assertEqual(c.size, (1,2)) self.assertEqual(c.sign.neg_mat.value.shape, (1,2)) # Test the Parameter class. def test_parameters(self): p = Parameter(name='p') self.assertEqual(p.name(), "p") self.assertEqual(p.size, (1,1)) # Test the AddExpresion class. def test_add_expression(self): # Vectors c = Constant([2,2]) exp = self.x + c self.assertEqual(exp.curvature, u.Curvature.AFFINE) self.assertEqual(exp.sign, u.Sign.UNKNOWN) self.assertEqual(exp.canonicalize()[0].size, (2,1)) self.assertEqual(exp.canonicalize()[1], []) self.assertEqual(exp.name(), self.x.name() + " + " + c.name()) self.assertEqual(exp.size, (2,1)) z = Variable(2, name='z') exp = exp + z + self.x with self.assertRaises(Exception) as cm: (self.x + self.y) self.assertEqual(str(cm.exception), "Incompatible dimensions.") # Matrices exp = self.A + self.B self.assertEqual(exp.curvature, u.Curvature.AFFINE) self.assertEqual(exp.size, (2,2)) with self.assertRaises(Exception) as cm: (self.A + self.C) self.assertEqual(str(cm.exception), "Incompatible dimensions.") # Test the SubExpresion class. def test_sub_expression(self): # Vectors c = Constant([2,2]) exp = self.x - c self.assertEqual(exp.curvature, u.Curvature.AFFINE) self.assertEqual(exp.sign, u.Sign.UNKNOWN) self.assertEqual(exp.canonicalize()[0].size, (2,1)) self.assertEqual(exp.canonicalize()[1], []) self.assertEqual(exp.name(), self.x.name() + " - " + Constant([2,2]).name()) self.assertEqual(exp.size, (2,1)) z = Variable(2, name='z') exp = exp - z - self.x with self.assertRaises(Exception) as cm: (self.x - self.y) self.assertEqual(str(cm.exception), "Incompatible dimensions.") # Matrices exp = self.A - self.B self.assertEqual(exp.curvature, u.Curvature.AFFINE) self.assertEqual(exp.size, (2,2)) with self.assertRaises(Exception) as cm: (self.A - self.C) self.assertEqual(str(cm.exception), "Incompatible dimensions.") # Test the MulExpresion class. def test_mul_expression(self): # Vectors c = Constant([[2],[2]]) exp = c*self.x self.assertEqual(exp.curvature, u.Curvature.AFFINE) self.assertEqual((c[0]*self.x).sign, u.Sign.UNKNOWN) self.assertEqual(exp.canonicalize()[0].size, (1,1)) self.assertEqual(exp.canonicalize()[1], []) self.assertEqual(exp.name(), c.name() + " * " + self.x.name()) self.assertEqual(exp.size, (1,1)) with self.assertRaises(Exception) as cm: ([2,2,3]*self.x) const_name = Constant([2,2,3]).name() self.assertEqual(str(cm.exception), "Incompatible dimensions.") # Matrices with self.assertRaises(Exception) as cm: Constant([[2, 1],[2, 2]]) * self.C self.assertEqual(str(cm.exception), "Incompatible dimensions.") with self.assertRaises(Exception) as cm: (self.A * self.B) self.assertEqual(str(cm.exception), "Cannot multiply two non-constants.") # Constant expressions T = Constant([[1,2,3],[3,5,5]]) exp = (T + T) * self.B self.assertEqual(exp.curvature, u.Curvature.AFFINE) self.assertEqual(exp.size, (3,2)) # Expression that would break sign multiplication without promotion. c = Constant([[2],[2],[-2]]) exp = [[1],[2]] + c*self.C self.assertEqual(exp.sign.pos_mat.value.shape, (1,2)) # Test the NegExpression class. def test_neg_expression(self): # Vectors exp = -self.x self.assertEqual(exp.curvature, u.Curvature.AFFINE) self.assertEqual(exp.sign, u.Sign.UNKNOWN) self.assertEqual(exp.canonicalize()[0].size, (2,1)) self.assertEqual(exp.canonicalize()[1], []) self.assertEqual(exp.name(), "-%s" % self.x.name()) self.assertEqual(exp.size, self.x.size) # Matrices exp = -self.C self.assertEqual(exp.curvature, u.Curvature.AFFINE) self.assertEqual(exp.size, (3,2)) # Test promotion of scalar constants. def test_scalar_const_promotion(self): # Vectors exp = self.x + 2 self.assertEqual(exp.curvature, u.Curvature.AFFINE) self.assertEqual(exp.sign, u.Sign.UNKNOWN) self.assertEqual(exp.canonicalize()[0].size, (2,1)) self.assertEqual(exp.canonicalize()[1], []) self.assertEqual(exp.name(), self.x.name() + " + " + Constant(2).name()) self.assertEqual(exp.size, (2,1)) self.assertEqual((4 - self.x).size, (2,1)) self.assertEqual((4 * self.x).size, (2,1)) self.assertEqual((4 <= self.x).size, (2,1)) self.assertEqual((4 == self.x).size, (2,1)) self.assertEqual((self.x >= 4).size, (2,1)) # Matrices exp = (self.A + 2) + 4 self.assertEqual(exp.curvature, u.Curvature.AFFINE) self.assertEqual((3 * self.A).size, (2,2)) self.assertEqual(exp.size, (2,2)) # Test indexing expression. def test_index_expression(self): # Tuple of integers as key. exp = self.x[1,0] self.assertEqual(exp.name(), "x[1,0]") self.assertEqual(exp.curvature, u.Curvature.AFFINE) self.assertEquals(exp.size, (1,1)) coeff = exp.coefficients(self.intf) self.assertEqual(coeff[exp], 1) self.assertEqual(exp.value, None) with self.assertRaises(Exception) as cm: (self.x[2,0]) self.assertEqual(str(cm.exception), "Invalid indices 2,0 for 'x'.") # Slicing exp = self.C[0:2,1] self.assertEquals(exp.name(), "C[0:2,1]") self.assertEquals(exp.size, (2,1)) exp = self.C[0:,0:2] self.assertEquals(exp.name(), "C[0:,0:2]") self.assertEquals(exp.size, (3,2)) exp = self.C[0::2,0::2] self.assertEquals(exp.name(), "C[0::2,0::2]") self.assertEquals(exp.size, (2,1)) exp = self.C[:3,:1:2] self.assertEquals(exp.name(), "C[0:3,0]") self.assertEquals(exp.size, (3,1)) c = Constant([[1,-2],[0,4]]) exp = c[1,1] print exp self.assertEqual(exp.curvature, u.Curvature.CONSTANT) self.assertEqual(exp.sign, u.Sign.POSITIVE) self.assertEqual(c[0,1].sign, u.Sign.ZERO) self.assertEqual(c[1,0].sign, u.Sign.NEGATIVE) self.assertEquals(exp.size, (1,1)) self.assertEqual(exp.value, 4) c = Constant([[1,-2,3],[0,4,5],[7,8,9]]) exp = c[0:3,0:4:2] self.assertEqual(exp.curvature, u.Curvature.CONSTANT) self.assertEquals(exp.size, (3,2)) self.assertEqual(exp[0,1].value, 7) # Arithmetic expression indexing exp = (self.x + self.z)[1,0] self.assertEqual(exp.name(), "x[1,0] + z[1,0]") self.assertEqual(exp.curvature, u.Curvature.AFFINE) self.assertEqual(exp.sign, u.Sign.UNKNOWN) self.assertEquals(exp.size, (1,1)) exp = (self.x + self.a)[1,0] self.assertEqual(exp.name(), "x[1,0] + a") self.assertEqual(exp.curvature, u.Curvature.AFFINE) self.assertEquals(exp.size, (1,1)) exp = (self.x - self.z)[1,0] self.assertEqual(exp.name(), "x[1,0] - z[1,0]") self.assertEqual(exp.curvature, u.Curvature.AFFINE) self.assertEquals(exp.size, (1,1)) exp = (self.x - self.a)[1,0] self.assertEqual(exp.name(), "x[1,0] - a") self.assertEqual(exp.curvature, u.Curvature.AFFINE) self.assertEquals(exp.size, (1,1)) exp = (-self.x)[1,0] self.assertEqual(exp.name(), "-x[1,0]") self.assertEqual(exp.curvature, u.Curvature.AFFINE) self.assertEquals(exp.size, (1,1)) c = Constant([[1,2],[3,4]]) exp = (c*self.x)[1,0] self.assertEqual(exp.name(), "[[2], [4]] * x[0:,0]") self.assertEqual(exp.curvature, u.Curvature.AFFINE) self.assertEquals(exp.size, (1,1)) c = Constant([[1,2],[3,4]]) exp = (c*self.a)[1,0] self.assertEqual(exp.name(), "2 * a") self.assertEqual(exp.curvature, u.Curvature.AFFINE) self.assertEquals(exp.size, (1,1))
class TestExpressions(unittest.TestCase): """ Unit tests for the expression/expression module. """ def setUp(self): self.a = Variable(name='a') self.x = Variable(2, name='x') self.y = Variable(3, name='y') self.z = Variable(2, name='z') self.A = Variable(2, 2, name='A') self.B = Variable(2, 2, name='B') self.C = Variable(3, 2, name='C') self.intf = intf.DEFAULT_INTERFACE # Test the Variable class. def test_variable(self): x = Variable(2) y = Variable(2) assert y.name() != x.name() x = Variable(2, name='x') y = Variable() self.assertEqual(x.name(), 'x') self.assertEqual(x.size, (2, 1)) self.assertEqual(y.size, (1, 1)) self.assertEqual(x.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(x.canonical_form[0].size, (2, 1)) self.assertEqual(x.canonical_form[1], []) # Scalar variable coeff = self.a.coefficients() self.assertEqual(coeff[self.a.id], [1]) # Vector variable. coeffs = x.coefficients() self.assertItemsEqual(coeffs.keys(), [x.id]) vec = coeffs[x.id][0] self.assertEqual(vec.shape, (2, 2)) self.assertEqual(vec[0, 0], 1) # Matrix variable. coeffs = self.A.coefficients() self.assertItemsEqual(coeffs.keys(), [self.A.id]) self.assertEqual(len(coeffs[self.A.id]), 2) mat = coeffs[self.A.id][1] self.assertEqual(mat.shape, (2, 4)) self.assertEqual(mat[0, 2], 1) # Test tranposing variables. def test_transpose_variable(self): var = self.a.T self.assertEquals(var.name(), "a") self.assertEquals(var.size, (1, 1)) self.a.save_value(2) self.assertEquals(var.value, 2) var = self.x.T self.assertEquals(var.name(), "x.T") self.assertEquals(var.size, (1, 2)) self.x.save_value(matrix([1, 2])) self.assertEquals(var.value[0, 0], 1) self.assertEquals(var.value[0, 1], 2) var = self.C.T self.assertEquals(var.name(), "C.T") self.assertEquals(var.size, (2, 3)) # coeffs = var.canonical_form[0].coefficients() # mat = coeffs.values()[0][0] # self.assertEqual(mat.size, (2,6)) # self.assertEqual(mat[1,3], 1) index = var[1, 0] self.assertEquals(index.name(), "C.T[1,0]") self.assertEquals(index.size, (1, 1)) var = self.x.T.T self.assertEquals(var.name(), "x.T.T") self.assertEquals(var.size, (2, 1)) # Test the Constant class. def test_constants(self): c = Constant(2) self.assertEqual(c.name(), str(2)) c = Constant(2) self.assertEqual(c.value, 2) self.assertEqual(c.size, (1, 1)) self.assertEqual(c.curvature, u.Curvature.CONSTANT_KEY) self.assertEqual(c.sign, u.Sign.POSITIVE_KEY) self.assertEqual(Constant(-2).sign, u.Sign.NEGATIVE_KEY) self.assertEqual(Constant(0).sign, u.Sign.ZERO_KEY) self.assertEqual(c.canonical_form[0].size, (1, 1)) self.assertEqual(c.canonical_form[1], []) coeffs = c.coefficients() self.assertEqual(coeffs.keys(), [s.CONSTANT]) self.assertEqual(coeffs[s.CONSTANT], [2]) # Test the sign. c = Constant([[2], [2]]) self.assertEqual(c.size, (1, 2)) self.assertEqual(c._dcp_attr.sign.neg_mat.shape, (1, 2)) # Test sign of a complex expression. c = Constant([1, 2]) A = Constant([[1, 1], [1, 1]]) exp = c.T * A * c self.assertEqual(exp.sign, u.Sign.POSITIVE_KEY) self.assertEqual((c.T * c).sign, u.Sign.POSITIVE_KEY) exp = c.T.T self.assertEqual(exp._dcp_attr.sign.pos_mat.shape, (2, 1)) exp = c.T * self.A self.assertEqual(exp._dcp_attr.sign.pos_mat.shape, (1, 2)) # Test the Parameter class. def test_parameters(self): p = Parameter(name='p') self.assertEqual(p.name(), "p") self.assertEqual(p.size, (1, 1)) p = Parameter(4, 3, sign="positive") with self.assertRaises(Exception) as cm: p.value = 1 self.assertEqual(str(cm.exception), "Invalid dimensions (1,1) for Parameter value.") val = -np.ones((4, 3)) val[0, 0] = 2 p = Parameter(4, 3, sign="positive") with self.assertRaises(Exception) as cm: p.value = val self.assertEqual(str(cm.exception), "Invalid sign for Parameter value.") p = Parameter(4, 3, sign="negative") with self.assertRaises(Exception) as cm: p.value = val self.assertEqual(str(cm.exception), "Invalid sign for Parameter value.") # No error for unknown sign. p = Parameter(4, 3) p.value = val # Test the AddExpresion class. def test_add_expression(self): # Vectors c = Constant([2, 2]) exp = self.x + c self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY) self.assertEqual(exp.canonical_form[0].size, (2, 1)) self.assertEqual(exp.canonical_form[1], []) # self.assertEqual(exp.name(), self.x.name() + " + " + c.name()) self.assertEqual(exp.size, (2, 1)) z = Variable(2, name='z') exp = exp + z + self.x with self.assertRaises(Exception) as cm: (self.x + self.y) self.assertEqual(str(cm.exception), "Incompatible dimensions (2, 1) (3, 1)") # Matrices exp = self.A + self.B self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(exp.size, (2, 2)) with self.assertRaises(Exception) as cm: (self.A + self.C) self.assertEqual(str(cm.exception), "Incompatible dimensions (2, 2) (3, 2)") # Test the SubExpresion class. def test_sub_expression(self): # Vectors c = Constant([2, 2]) exp = self.x - c self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY) self.assertEqual(exp.canonical_form[0].size, (2, 1)) self.assertEqual(exp.canonical_form[1], []) # self.assertEqual(exp.name(), self.x.name() + " - " + Constant([2,2]).name()) self.assertEqual(exp.size, (2, 1)) z = Variable(2, name='z') exp = exp - z - self.x with self.assertRaises(Exception) as cm: (self.x - self.y) self.assertEqual(str(cm.exception), "Incompatible dimensions (2, 1) (3, 1)") # Matrices exp = self.A - self.B self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(exp.size, (2, 2)) with self.assertRaises(Exception) as cm: (self.A - self.C) self.assertEqual(str(cm.exception), "Incompatible dimensions (2, 2) (3, 2)") # Test the MulExpresion class. def test_mul_expression(self): # Vectors c = Constant([[2], [2]]) exp = c * self.x self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual((c[0] * self.x).sign, u.Sign.UNKNOWN_KEY) self.assertEqual(exp.canonical_form[0].size, (1, 1)) self.assertEqual(exp.canonical_form[1], []) # self.assertEqual(exp.name(), c.name() + " * " + self.x.name()) self.assertEqual(exp.size, (1, 1)) with self.assertRaises(Exception) as cm: ([2, 2, 3] * self.x) print cm.exception self.assertEqual(str(cm.exception), "Incompatible dimensions (3, 1) (2, 1)") # Matrices with self.assertRaises(Exception) as cm: Constant([[2, 1], [2, 2]]) * self.C self.assertEqual(str(cm.exception), "Incompatible dimensions (2, 2) (3, 2)") with self.assertRaises(Exception) as cm: (self.A * self.B) self.assertEqual(str(cm.exception), "Cannot multiply two non-constants.") # Constant expressions T = Constant([[1, 2, 3], [3, 5, 5]]) exp = (T + T) * self.B self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(exp.size, (3, 2)) # Expression that would break sign multiplication without promotion. c = Constant([[2], [2], [-2]]) exp = [[1], [2]] + c * self.C self.assertEqual(exp._dcp_attr.sign.pos_mat.shape, (1, 2)) # Test the DivExpresion class. def test_div_expression(self): # Vectors exp = self.x / 2 self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY) self.assertEqual(exp.canonical_form[0].size, (2, 1)) self.assertEqual(exp.canonical_form[1], []) # self.assertEqual(exp.name(), c.name() + " * " + self.x.name()) self.assertEqual(exp.size, (2, 1)) with self.assertRaises(Exception) as cm: (self.x / [2, 2, 3]) print cm.exception self.assertEqual(str(cm.exception), "Can only divide by a scalar constant.") # Constant expressions. c = Constant(2) exp = c / (3 - 5) self.assertEqual(exp.curvature, u.Curvature.CONSTANT_KEY) self.assertEqual(exp.size, (1, 1)) self.assertEqual(exp.sign, u.Sign.NEGATIVE_KEY) # Parameters. p = Parameter(sign="positive") exp = 2 / p p.value = 2 self.assertEquals(exp.value, 1) # Test the NegExpression class. def test_neg_expression(self): # Vectors exp = -self.x self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) assert exp.is_affine() self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY) assert not exp.is_positive() self.assertEqual(exp.canonical_form[0].size, (2, 1)) self.assertEqual(exp.canonical_form[1], []) # self.assertEqual(exp.name(), "-%s" % self.x.name()) self.assertEqual(exp.size, self.x.size) # Matrices exp = -self.C self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(exp.size, (3, 2)) # Test promotion of scalar constants. def test_scalar_const_promotion(self): # Vectors exp = self.x + 2 self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) assert exp.is_affine() self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY) assert not exp.is_negative() self.assertEqual(exp.canonical_form[0].size, (2, 1)) self.assertEqual(exp.canonical_form[1], []) # self.assertEqual(exp.name(), self.x.name() + " + " + Constant(2).name()) self.assertEqual(exp.size, (2, 1)) self.assertEqual((4 - self.x).size, (2, 1)) self.assertEqual((4 * self.x).size, (2, 1)) self.assertEqual((4 <= self.x).size, (2, 1)) self.assertEqual((4 == self.x).size, (2, 1)) self.assertEqual((self.x >= 4).size, (2, 1)) # Matrices exp = (self.A + 2) + 4 self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual((3 * self.A).size, (2, 2)) self.assertEqual(exp.size, (2, 2)) # Test indexing expression. def test_index_expression(self): # Tuple of integers as key. exp = self.x[1, 0] # self.assertEqual(exp.name(), "x[1,0]") self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) assert exp.is_affine() self.assertEquals(exp.size, (1, 1)) # coeff = exp.canonical_form[0].coefficients()[self.x][0] # self.assertEqual(coeff[0,1], 1) self.assertEqual(exp.value, None) exp = self.x[1, 0].T # self.assertEqual(exp.name(), "x[1,0]") self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEquals(exp.size, (1, 1)) with self.assertRaises(Exception) as cm: (self.x[2, 0]) self.assertEqual(str(cm.exception), "Index/slice out of bounds.") # Slicing exp = self.C[0:2, 1] # self.assertEquals(exp.name(), "C[0:2,1]") self.assertEquals(exp.size, (2, 1)) exp = self.C[0:, 0:2] # self.assertEquals(exp.name(), "C[0:,0:2]") self.assertEquals(exp.size, (3, 2)) exp = self.C[0::2, 0::2] # self.assertEquals(exp.name(), "C[0::2,0::2]") self.assertEquals(exp.size, (2, 1)) exp = self.C[:3, :1:2] # self.assertEquals(exp.name(), "C[0:3,0]") self.assertEquals(exp.size, (3, 1)) exp = self.C[0:, 0] # self.assertEquals(exp.name(), "C[0:,0]") self.assertEquals(exp.size, (3, 1)) c = Constant([[1, -2], [0, 4]]) exp = c[1, 1] self.assertEqual(exp.curvature, u.Curvature.CONSTANT_KEY) self.assertEqual(exp.sign, u.Sign.POSITIVE_KEY) assert exp.is_positive() self.assertEqual(c[0, 1].sign, u.Sign.ZERO_KEY) assert c[0, 1].is_zero() self.assertEqual(c[1, 0].sign, u.Sign.NEGATIVE_KEY) assert c[1, 0].is_negative() self.assertEquals(exp.size, (1, 1)) self.assertEqual(exp.value, 4) c = Constant([[1, -2, 3], [0, 4, 5], [7, 8, 9]]) exp = c[0:3, 0:4:2] self.assertEqual(exp.curvature, u.Curvature.CONSTANT_KEY) assert exp.is_constant() self.assertEquals(exp.size, (3, 2)) self.assertEqual(exp[0, 1].value, 7) # Slice of transpose exp = self.C.T[0:2, 1] self.assertEquals(exp.size, (2, 1)) # Arithmetic expression indexing exp = (self.x + self.z)[1, 0] # self.assertEqual(exp.name(), "x[1,0] + z[1,0]") self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY) self.assertEquals(exp.size, (1, 1)) exp = (self.x + self.a)[1, 0] # self.assertEqual(exp.name(), "x[1,0] + a") self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEquals(exp.size, (1, 1)) exp = (self.x - self.z)[1, 0] # self.assertEqual(exp.name(), "x[1,0] - z[1,0]") self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEquals(exp.size, (1, 1)) exp = (self.x - self.a)[1, 0] # self.assertEqual(exp.name(), "x[1,0] - a") self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEquals(exp.size, (1, 1)) exp = (-self.x)[1, 0] # self.assertEqual(exp.name(), "-x[1,0]") self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEquals(exp.size, (1, 1)) c = Constant([[1, 2], [3, 4]]) exp = (c * self.x)[1, 0] # self.assertEqual(exp.name(), "[[2], [4]] * x[0:,0]") self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEquals(exp.size, (1, 1)) c = Constant([[1, 2], [3, 4]]) exp = (c * self.a)[1, 0] # self.assertEqual(exp.name(), "2 * a") self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEquals(exp.size, (1, 1))
class TestExpressions(unittest.TestCase): """ Unit tests for the expression/expression module. """ def setUp(self): self.a = Variable(name='a') self.x = Variable(2, name='x') self.y = Variable(3, name='y') self.z = Variable(2, name='z') self.A = Variable(2,2,name='A') self.B = Variable(2,2,name='B') self.C = Variable(3,2,name='C') self.intf = intf.DEFAULT_INTERFACE # Test the Variable class. def test_variable(self): x = Variable(2) y = Variable(2) assert y.name() != x.name() x = Variable(2, name='x') y = Variable() self.assertEqual(x.name(), 'x') self.assertEqual(x.size, (2,1)) self.assertEqual(y.size, (1,1)) self.assertEqual(x.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(x.canonical_form[0].size, (2,1)) self.assertEqual(x.canonical_form[1], []) # Scalar variable coeff = self.a.coefficients() self.assertEqual(coeff[self.a], [1]) # Vector variable. coeffs = x.coefficients() self.assertItemsEqual(coeffs.keys(), [x]) vec = coeffs[x][0] self.assertEqual(vec.size, (2,2)) self.assertEqual(vec[0,0], 1) # Matrix variable. coeffs = self.A.coefficients() self.assertItemsEqual(coeffs.keys(), [self.A]) self.assertEqual(len(coeffs[self.A]), 2) mat = coeffs[self.A][1] self.assertEqual(mat.size, (2,4)) self.assertEqual(mat[0,2], 1) # Test tranposing variables. def test_transpose_variable(self): var = self.a.T self.assertEquals(var.name(), "a") self.assertEquals(var.size, (1,1)) self.a.save_value(2) self.assertEquals(var.value, 2) var = self.x.T self.assertEquals(var.name(), "x.T") self.assertEquals(var.size, (1,2)) self.x.save_value( matrix([1,2]) ) self.assertEquals(var.value[0,0], 1) self.assertEquals(var.value[0,1], 2) var = self.C.T self.assertEquals(var.name(), "C.T") self.assertEquals(var.size, (2,3)) # coeffs = var.canonical_form[0].coefficients() # mat = coeffs.values()[0][0] # self.assertEqual(mat.size, (2,6)) # self.assertEqual(mat[1,3], 1) index = var[1,0] self.assertEquals(index.name(), "C.T[1,0]") self.assertEquals(index.size, (1,1)) var = self.x.T.T self.assertEquals(var.name(), "x.T.T") self.assertEquals(var.size, (2,1)) # Test the Constant class. def test_constants(self): c = Constant(2) self.assertEqual(c.name(), str(2)) c = Constant(2) self.assertEqual(c.value, 2) self.assertEqual(c.size, (1,1)) self.assertEqual(c.curvature, u.Curvature.CONSTANT_KEY) self.assertEqual(c.sign, u.Sign.POSITIVE_KEY) self.assertEqual(Constant(-2).sign, u.Sign.NEGATIVE_KEY) self.assertEqual(Constant(0).sign, u.Sign.ZERO_KEY) self.assertEqual(c.canonical_form[0].size, (1,1)) self.assertEqual(c.canonical_form[1], []) coeffs = c.coefficients() self.assertEqual(coeffs.keys(), [s.CONSTANT]) self.assertEqual(coeffs[s.CONSTANT], [2]) # Test the sign. c = Constant([[2],[2]]) self.assertEqual(c.size, (1,2)) self.assertEqual(c._dcp_attr.sign.neg_mat.shape, (1,2)) # Test sign of a complex expression. c = Constant([1, 2]) A = Constant([[1,1],[1,1]]) exp = c.T*A*c self.assertEqual(exp.sign, u.Sign.POSITIVE_KEY) self.assertEqual((c.T*c).sign, u.Sign.POSITIVE_KEY) exp = c.T.T self.assertEqual(exp._dcp_attr.sign.pos_mat.shape, (2,1)) exp = c.T*self.A self.assertEqual(exp._dcp_attr.sign.pos_mat.shape, (1,2)) # Test the Parameter class. def test_parameters(self): p = Parameter(name='p') self.assertEqual(p.name(), "p") self.assertEqual(p.size, (1,1)) p = Parameter(4, 3, sign="positive") with self.assertRaises(Exception) as cm: p.value = 1 self.assertEqual(str(cm.exception), "Invalid dimensions (1,1) for Parameter value.") val = -np.ones((4,3)) val[0,0] = 2 p = Parameter(4, 3, sign="positive") with self.assertRaises(Exception) as cm: p.value = val self.assertEqual(str(cm.exception), "Invalid sign for Parameter value.") p = Parameter(4, 3, sign="negative") with self.assertRaises(Exception) as cm: p.value = val self.assertEqual(str(cm.exception), "Invalid sign for Parameter value.") # No error for unknown sign. p = Parameter(4, 3) p.value = val # Test the AddExpresion class. def test_add_expression(self): # Vectors c = Constant([2,2]) exp = self.x + c self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY) self.assertEqual(exp.canonical_form[0].size, (2,1)) self.assertEqual(exp.canonical_form[1], []) # self.assertEqual(exp.name(), self.x.name() + " + " + c.name()) self.assertEqual(exp.size, (2,1)) z = Variable(2, name='z') exp = exp + z + self.x with self.assertRaises(Exception) as cm: (self.x + self.y) self.assertEqual(str(cm.exception), "Incompatible dimensions.") # Matrices exp = self.A + self.B self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(exp.size, (2,2)) with self.assertRaises(Exception) as cm: (self.A + self.C) self.assertEqual(str(cm.exception), "Incompatible dimensions.") # Test the SubExpresion class. def test_sub_expression(self): # Vectors c = Constant([2,2]) exp = self.x - c self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY) self.assertEqual(exp.canonical_form[0].size, (2,1)) self.assertEqual(exp.canonical_form[1], []) # self.assertEqual(exp.name(), self.x.name() + " - " + Constant([2,2]).name()) self.assertEqual(exp.size, (2,1)) z = Variable(2, name='z') exp = exp - z - self.x with self.assertRaises(Exception) as cm: (self.x - self.y) self.assertEqual(str(cm.exception), "Incompatible dimensions.") # Matrices exp = self.A - self.B self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(exp.size, (2,2)) with self.assertRaises(Exception) as cm: (self.A - self.C) self.assertEqual(str(cm.exception), "Incompatible dimensions.") # Test the MulExpresion class. def test_mul_expression(self): # Vectors c = Constant([[2],[2]]) exp = c*self.x self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual((c[0]*self.x).sign, u.Sign.UNKNOWN_KEY) self.assertEqual(exp.canonical_form[0].size, (1,1)) self.assertEqual(exp.canonical_form[1], []) # self.assertEqual(exp.name(), c.name() + " * " + self.x.name()) self.assertEqual(exp.size, (1,1)) with self.assertRaises(Exception) as cm: ([2,2,3]*self.x) print cm.exception self.assertEqual(str(cm.exception), "Incompatible dimensions.") # Matrices with self.assertRaises(Exception) as cm: Constant([[2, 1],[2, 2]]) * self.C self.assertEqual(str(cm.exception), "Incompatible dimensions.") with self.assertRaises(Exception) as cm: (self.A * self.B) self.assertEqual(str(cm.exception), "Cannot multiply two non-constants.") # Constant expressions T = Constant([[1,2,3],[3,5,5]]) exp = (T + T) * self.B self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(exp.size, (3,2)) # Expression that would break sign multiplication without promotion. c = Constant([[2],[2],[-2]]) exp = [[1],[2]] + c*self.C self.assertEqual(exp._dcp_attr.sign.pos_mat.shape, (1,2)) # Test the NegExpression class. def test_neg_expression(self): # Vectors exp = -self.x self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) assert exp.is_affine() self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY) assert not exp.is_positive() self.assertEqual(exp.canonical_form[0].size, (2,1)) self.assertEqual(exp.canonical_form[1], []) # self.assertEqual(exp.name(), "-%s" % self.x.name()) self.assertEqual(exp.size, self.x.size) # Matrices exp = -self.C self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(exp.size, (3,2)) # Test promotion of scalar constants. def test_scalar_const_promotion(self): # Vectors exp = self.x + 2 self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) assert exp.is_affine() self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY) assert not exp.is_negative() self.assertEqual(exp.canonical_form[0].size, (2,1)) self.assertEqual(exp.canonical_form[1], []) # self.assertEqual(exp.name(), self.x.name() + " + " + Constant(2).name()) self.assertEqual(exp.size, (2,1)) self.assertEqual((4 - self.x).size, (2,1)) self.assertEqual((4 * self.x).size, (2,1)) self.assertEqual((4 <= self.x).size, (2,1)) self.assertEqual((4 == self.x).size, (2,1)) self.assertEqual((self.x >= 4).size, (2,1)) # Matrices exp = (self.A + 2) + 4 self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual((3 * self.A).size, (2,2)) self.assertEqual(exp.size, (2,2)) # Test indexing expression. def test_index_expression(self): # Tuple of integers as key. exp = self.x[1,0] # self.assertEqual(exp.name(), "x[1,0]") self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) assert exp.is_affine() self.assertEquals(exp.size, (1,1)) # coeff = exp.canonical_form[0].coefficients()[self.x][0] # self.assertEqual(coeff[0,1], 1) self.assertEqual(exp.value, None) exp = self.x[1,0].T # self.assertEqual(exp.name(), "x[1,0]") self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEquals(exp.size, (1,1)) with self.assertRaises(Exception) as cm: (self.x[2,0]) self.assertEqual(str(cm.exception), "Index/slice out of bounds.") # Slicing exp = self.C[0:2,1] # self.assertEquals(exp.name(), "C[0:2,1]") self.assertEquals(exp.size, (2,1)) exp = self.C[0:,0:2] # self.assertEquals(exp.name(), "C[0:,0:2]") self.assertEquals(exp.size, (3,2)) exp = self.C[0::2,0::2] # self.assertEquals(exp.name(), "C[0::2,0::2]") self.assertEquals(exp.size, (2,1)) exp = self.C[:3,:1:2] # self.assertEquals(exp.name(), "C[0:3,0]") self.assertEquals(exp.size, (3,1)) exp = self.C[0:,0] # self.assertEquals(exp.name(), "C[0:,0]") self.assertEquals(exp.size, (3,1)) c = Constant([[1,-2],[0,4]]) exp = c[1,1] self.assertEqual(exp.curvature, u.Curvature.CONSTANT_KEY) self.assertEqual(exp.sign, u.Sign.POSITIVE_KEY) assert exp.is_positive() self.assertEqual(c[0,1].sign, u.Sign.ZERO_KEY) assert c[0, 1].is_zero() self.assertEqual(c[1,0].sign, u.Sign.NEGATIVE_KEY) assert c[1,0].is_negative() self.assertEquals(exp.size, (1,1)) self.assertEqual(exp.value, 4) c = Constant([[1,-2,3],[0,4,5],[7,8,9]]) exp = c[0:3,0:4:2] self.assertEqual(exp.curvature, u.Curvature.CONSTANT_KEY) assert exp.is_constant() self.assertEquals(exp.size, (3,2)) self.assertEqual(exp[0,1].value, 7) # Slice of transpose exp = self.C.T[0:2,1] self.assertEquals(exp.size, (2,1)) # Arithmetic expression indexing exp = (self.x + self.z)[1,0] # self.assertEqual(exp.name(), "x[1,0] + z[1,0]") self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY) self.assertEquals(exp.size, (1,1)) exp = (self.x + self.a)[1,0] # self.assertEqual(exp.name(), "x[1,0] + a") self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEquals(exp.size, (1,1)) exp = (self.x - self.z)[1,0] # self.assertEqual(exp.name(), "x[1,0] - z[1,0]") self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEquals(exp.size, (1,1)) exp = (self.x - self.a)[1,0] # self.assertEqual(exp.name(), "x[1,0] - a") self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEquals(exp.size, (1,1)) exp = (-self.x)[1,0] # self.assertEqual(exp.name(), "-x[1,0]") self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEquals(exp.size, (1,1)) c = Constant([[1,2],[3,4]]) exp = (c*self.x)[1,0] # self.assertEqual(exp.name(), "[[2], [4]] * x[0:,0]") self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEquals(exp.size, (1,1)) c = Constant([[1,2],[3,4]]) exp = (c*self.a)[1,0] # self.assertEqual(exp.name(), "2 * a") self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEquals(exp.size, (1,1))
class test_coefficients(unittest.TestCase): """ Unit tests for the expressions.affine module. """ def setUp(self): self.a = Variable() self.x = Variable(2, name='x') self.y = Variable(2, name='y') self.A = Variable(2,2) self.c = Constant(3) self.C = Constant([[1, 2], [1, 2]]) def test_leaf_coeffs(self): """Test the coefficients for Variables and Constants. """ # Scalars coeffs = self.a.coefficients() self.assertItemsEqual(coeffs.keys(), [self.a]) blocks = coeffs[self.a] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0], 1) # Vectors coeffs = self.x.coefficients() self.assertItemsEqual(coeffs.keys(), [self.x]) blocks = coeffs[self.x] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0].size, (2,2)) # Matrices coeffs = self.A.coefficients() self.assertItemsEqual(coeffs.keys(), [self.A]) blocks = coeffs[self.A] self.assertEqual(len(blocks), 2) self.assertEqual(blocks[0].size, (2,4)) # Constants coeffs = self.c.coefficients() self.assertItemsEqual(coeffs.keys(), [s.CONSTANT]) blocks = coeffs[s.CONSTANT] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0], 3) coeffs = self.C.coefficients() self.assertItemsEqual(coeffs.keys(), [s.CONSTANT]) blocks = coeffs[s.CONSTANT] self.assertEqual(len(blocks), 2) self.assertEqual(blocks[0].size, (2,1)) self.assertEqual(blocks[0][0,0], 1) def test_add(self): """Test adding coefficients. """ coeffs = cu.add(self.x.coefficients(), self.y.coefficients()) self.assertItemsEqual(coeffs.keys(), [self.x, self.y]) blocks = coeffs[self.x] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0].size, (2,2)) coeffs = cu.add(coeffs, coeffs) self.assertItemsEqual(coeffs.keys(), [self.x, self.y]) blocks = coeffs[self.x] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0].size, (2,2)) self.assertEqual(blocks[0][0,0], 2) coeffs = cu.add(coeffs, self.C.coefficients()) self.assertItemsEqual(coeffs.keys(), [self.x, self.y, s.CONSTANT]) blocks = coeffs[s.CONSTANT] self.assertEqual(len(blocks), 2) self.assertEqual(blocks[0].size, (2,1)) self.assertEqual(blocks[0][0,0], 1) def test_neg(self): """Test negating coefficients. """ coeffs = cu.neg(self.a.coefficients()) self.assertItemsEqual(coeffs.keys(), [self.a]) blocks = coeffs[self.a] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0], -1) coeffs = cu.neg(self.A.coefficients()) self.assertItemsEqual(coeffs.keys(), [self.A]) blocks = coeffs[self.A] self.assertEqual(len(blocks), 2) self.assertEqual(blocks[0].size, (2,4)) self.assertEqual(blocks[0][0,0], -1) def test_sub(self): """Test subtracting coefficients. """ coeffs = cu.sub(self.x.coefficients(), self.y.coefficients()) self.assertItemsEqual(coeffs.keys(), [self.x, self.y]) blocks = coeffs[self.y] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0].size, (2,2)) self.assertEqual(blocks[0][0,0], -1) coeffs = cu.sub(coeffs, self.x.coefficients()) self.assertItemsEqual(coeffs.keys(), [self.x, self.y]) blocks = coeffs[self.x] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0].size, (2,2)) self.assertEqual(blocks[0][0,0], 0) def test_mul(self): """Test multiplying coefficients. """ coeffs = cu.add(self.x.coefficients(), self.y.coefficients()) coeffs = cu.mul(self.C.coefficients(), coeffs) self.assertItemsEqual(coeffs.keys(), [self.x, self.y]) blocks = coeffs[self.y] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0].size, (2,2)) self.assertEqual(blocks[0][1,0], 2) # Scalar by Matrix multiplication. coeffs = cu.add(self.x.coefficients(), self.y.coefficients()) coeffs = cu.mul(self.c.coefficients(), coeffs) self.assertItemsEqual(coeffs.keys(), [self.x, self.y]) blocks = coeffs[self.y] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0].size, (2,2)) self.assertEqual(blocks[0][0,0], 3) # Matrix by Scalar multiplication. coeffs = self.a.coefficients() coeffs = cu.mul(self.C.coefficients(), coeffs) self.assertItemsEqual(coeffs.keys(), [self.a]) blocks = coeffs[self.a] self.assertEqual(len(blocks), 2) self.assertEqual(blocks[0].size, (2,1)) self.assertEqual(blocks[0][1,0], 2) self.assertEqual(blocks[1].size, (2,1)) self.assertEqual(blocks[1][1,0], 2) def test_index(self): """Test indexing/slicing into coefficients. """ # Index. sum_coeffs = cu.add(self.x.coefficients(), self.y.coefficients()) key = ku.validate_key((1, 0), self.x.shape) coeffs = cu.index(sum_coeffs, key) self.assertItemsEqual(coeffs.keys(), [self.x, self.y]) blocks = coeffs[self.y] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0].size, (1,2)) self.assertEqual(blocks[0][0,0], 0) # Slice. sum_coeffs = cu.add(self.A.coefficients(), self.C.coefficients()) key = ku.validate_key((slice(None, None, None), 1), self.A.shape) coeffs = cu.index(sum_coeffs, key) self.assertItemsEqual(coeffs.keys(), [self.A, s.CONSTANT]) # Variable. blocks = coeffs[self.A] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0].size, (2,4)) # Constant. blocks = coeffs[s.CONSTANT] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0].size, (2,1))
class test_coefficients(unittest.TestCase): """ Unit tests for the expressions.affine module. """ def setUp(self): self.a = Variable() self.x = Variable(2, name='x') self.y = Variable(2, name='y') self.A = Variable(2, 2) self.c = Constant(3) self.C = Constant([[1, 2], [1, 2]]) def test_leaf_coeffs(self): """Test the coefficients for Variables and Constants. """ # Scalars coeffs = self.a.coefficients() self.assertItemsEqual(coeffs.keys(), [self.a]) blocks = coeffs[self.a] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0], 1) # Vectors coeffs = self.x.coefficients() self.assertItemsEqual(coeffs.keys(), [self.x]) blocks = coeffs[self.x] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0].shape, (2, 2)) # Matrices coeffs = self.A.coefficients() self.assertItemsEqual(coeffs.keys(), [self.A]) blocks = coeffs[self.A] self.assertEqual(len(blocks), 2) self.assertEqual(blocks[0].shape, (2, 4)) # Constants coeffs = self.c.coefficients() self.assertItemsEqual(coeffs.keys(), [s.CONSTANT]) blocks = coeffs[s.CONSTANT] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0], 3) coeffs = self.C.coefficients() self.assertItemsEqual(coeffs.keys(), [s.CONSTANT]) blocks = coeffs[s.CONSTANT] self.assertEqual(len(blocks), 2) print blocks[0] self.assertEqual(blocks[0].shape, (2, 1)) self.assertEqual(blocks[0][0, 0], 1) def test_add(self): """Test adding coefficients. """ coeffs = cu.add(self.x.coefficients(), self.y.coefficients()) self.assertItemsEqual(coeffs.keys(), [self.x, self.y]) blocks = coeffs[self.x] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0].shape, (2, 2)) coeffs = cu.add(coeffs, coeffs) self.assertItemsEqual(coeffs.keys(), [self.x, self.y]) blocks = coeffs[self.x] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0].shape, (2, 2)) self.assertEqual(blocks[0][0, 0], 2) coeffs = cu.add(coeffs, self.C.coefficients()) self.assertItemsEqual(coeffs.keys(), [self.x, self.y, s.CONSTANT]) blocks = coeffs[s.CONSTANT] self.assertEqual(len(blocks), 2) self.assertEqual(blocks[0].shape, (2, 1)) self.assertEqual(blocks[0][0, 0], 1) def test_neg(self): """Test negating coefficients. """ coeffs = cu.neg(self.a.coefficients()) self.assertItemsEqual(coeffs.keys(), [self.a]) blocks = coeffs[self.a] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0], -1) coeffs = cu.neg(self.A.coefficients()) self.assertItemsEqual(coeffs.keys(), [self.A]) blocks = coeffs[self.A] self.assertEqual(len(blocks), 2) self.assertEqual(blocks[0].shape, (2, 4)) self.assertEqual(blocks[0][0, 0], -1) def test_sub(self): """Test subtracting coefficients. """ coeffs = cu.sub(self.x.coefficients(), self.y.coefficients()) self.assertItemsEqual(coeffs.keys(), [self.x, self.y]) blocks = coeffs[self.y] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0].shape, (2, 2)) self.assertEqual(blocks[0][0, 0], -1) coeffs = cu.sub(coeffs, self.x.coefficients()) self.assertItemsEqual(coeffs.keys(), [self.x, self.y]) blocks = coeffs[self.x] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0].shape, (2, 2)) self.assertEqual(blocks[0][0, 0], 0) def test_mul(self): """Test multiplying coefficients. """ coeffs = cu.add(self.x.coefficients(), self.y.coefficients()) coeffs = cu.mul(self.C.coefficients(), coeffs) self.assertItemsEqual(coeffs.keys(), [self.x, self.y]) blocks = coeffs[self.y] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0].shape, (2, 2)) self.assertEqual(blocks[0][1, 0], 2) # Scalar by Matrix multiplication. coeffs = cu.add(self.x.coefficients(), self.y.coefficients()) coeffs = cu.mul(self.c.coefficients(), coeffs) self.assertItemsEqual(coeffs.keys(), [self.x, self.y]) blocks = coeffs[self.y] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0].shape, (2, 2)) self.assertEqual(blocks[0][0, 0], 3) # Matrix by Scalar multiplication. coeffs = self.a.coefficients() coeffs = cu.mul(self.C.coefficients(), coeffs) self.assertItemsEqual(coeffs.keys(), [self.a]) blocks = coeffs[self.a] self.assertEqual(len(blocks), 2) self.assertEqual(blocks[0].shape, (2, 1)) self.assertEqual(blocks[0][1, 0], 2) self.assertEqual(blocks[1].shape, (2, 1)) self.assertEqual(blocks[1][1, 0], 2) def test_index(self): """Test indexing/slicing into coefficients. """ # Index. sum_coeffs = cu.add(self.x.coefficients(), self.y.coefficients()) key = ku.validate_key((1, 0), self.x.shape) coeffs = cu.index(sum_coeffs, key) self.assertItemsEqual(coeffs.keys(), [self.x, self.y]) blocks = coeffs[self.y] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0].shape, (1, 2)) self.assertEqual(blocks[0][0, 0], 0) # Slice. sum_coeffs = cu.add(self.A.coefficients(), self.C.coefficients()) key = ku.validate_key((slice(None, None, None), 1), self.A.shape) coeffs = cu.index(sum_coeffs, key) self.assertItemsEqual(coeffs.keys(), [self.A, s.CONSTANT]) # Variable. blocks = coeffs[self.A] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0].shape, (2, 4)) # Constant. blocks = coeffs[s.CONSTANT] self.assertEqual(len(blocks), 1) self.assertEqual(blocks[0].shape, (2, 1))
class TestAffObjective(unittest.TestCase): """ Unit tests for the expressions.affine module. """ def setUp(self): self.x = Variable(2, name="x") self.y = Variable(2, name="y") self.A = Constant([[1, 2], [1, 2]]) self.xAff = AffObjective([self.x], [deque([self.x])], u.Shape(2, 1)) self.yAff = AffObjective([self.y], [deque([self.y])], u.Shape(2, 1)) self.constAff = AffObjective([self.A], [deque([self.A])], u.Shape(2, 2)) self.intf = intf.DEFAULT_INTERFACE # Test adding AffObjectives. def test_add(self): add = self.xAff + self.yAff self.assertItemsEqual(add._terms, [deque([self.x]), deque([self.y])]) self.assertItemsEqual(add.variables(), [self.x, self.y]) add = self.xAff + self.xAff self.assertItemsEqual(add._terms, [deque([self.x]), deque([self.x])]) self.assertItemsEqual(add.variables(), [self.x, self.x]) with self.assertRaises(Exception) as cm: self.xAff + self.constAff self.assertEqual(str(cm.exception), "Incompatible dimensions.") # Test multiplying AffObjectives. def test_mul(self): mul = self.constAff * self.xAff self.assertItemsEqual(mul._terms, [deque([self.x, self.A])]) self.assertItemsEqual(mul.variables(), [self.x]) mul = self.constAff * (self.yAff + self.xAff) self.assertItemsEqual(mul._terms, [deque([self.x, self.A]), deque([self.y, self.A])]) self.assertItemsEqual(mul.variables(), [self.x, self.y]) with self.assertRaises(Exception) as cm: self.xAff * self.yAff self.assertEqual(str(cm.exception), "Incompatible dimensions.") # Test negating AffObjectives. def test_neg(self): neg = -self.xAff self.assertEqual(neg._terms[0][1].name(), "-1") self.assertItemsEqual(neg.variables(), [self.x]) # Test subtracting AffObjectives. def test_sub(self): sub = self.xAff - self.yAff self.assertItemsEqual(sub._terms, (self.xAff + -self.yAff)._terms) self.assertItemsEqual(sub.variables(), [self.x, self.y]) with self.assertRaises(Exception) as cm: self.xAff - self.constAff self.assertEqual(str(cm.exception), "Incompatible dimensions.") # Test coefficients method. def test_coefficients(self): # Leaf coeffs = self.xAff.coefficients(self.intf) self.assertEqual(coeffs.keys(), self.x.coefficients(self.intf).keys()) # Sum with different keys exp = self.xAff + self.yAff coeffs = exp.coefficients(self.intf) keys = self.x.coefficients(self.intf).keys() + self.y.coefficients(self.intf).keys() self.assertItemsEqual(coeffs.keys(), keys) # Sum with same keys exp = self.xAff + self.xAff coeffs = exp.coefficients(self.intf) xCoeffs = self.x.coefficients(self.intf) self.assertItemsEqual(coeffs.keys(), xCoeffs) self.assertEqual(list(coeffs[self.x]), [2, 0, 0, 2]) # Product exp = self.constAff * self.yAff coeffs = exp.coefficients(self.intf) yCoeffs = self.y.coefficients(self.intf) self.assertItemsEqual(coeffs.keys(), yCoeffs) self.assertEqual(list(coeffs[self.y]), [1, 2, 1, 2]) # Distributed product exp = self.constAff * (self.xAff + self.yAff) coeffs = exp.coefficients(self.intf) xCoeffs = self.x.coefficients(self.intf) yCoeffs = self.y.coefficients(self.intf) self.assertItemsEqual(coeffs.keys(), xCoeffs.keys() + yCoeffs.keys()) self.assertEqual(list(coeffs[self.x]), [1, 2, 1, 2])