def test_inverse(): pytest.raises(ShapeError, lambda: Inverse(A)) pytest.raises(ShapeError, lambda: Inverse(A * B)) pytest.raises(TypeError, lambda: Inverse(1)) assert Inverse(C).shape == (n, n) assert Inverse(A * E).shape == (n, n) assert Inverse(E * A).shape == (m, m) assert Inverse(C).inverse() == C assert isinstance(Inverse(Inverse(C)), Inverse) assert C.inverse().inverse() == C assert C.inverse() * C == Identity(C.rows) assert Identity(n).inverse() == Identity(n) assert (3 * Identity(n)).inverse() == Identity(n) / 3 # Simplifies Muls if possible (i.e. submatrices are square) assert (C * D).inverse() == D.inverse() * C.inverse() # But still works when not possible assert isinstance((A * E).inverse(), Inverse) assert Inverse(eye(3)).doit() == eye(3) assert Inverse(eye(3)).doit(deep=False) == eye(3) assert det(Inverse(C)) == 1 / det(C)
def test_adjoint(): Sq = MatrixSymbol('Sq', n, n) assert Adjoint(A).shape == (m, n) assert Adjoint(A * B).shape == (l, n) assert adjoint(Adjoint(A)) == A assert isinstance(Adjoint(Adjoint(A)), Adjoint) assert conjugate(Adjoint(A)) == Transpose(A) == Adjoint(A).conjugate() assert transpose(Adjoint(A)) == Adjoint( Transpose(A)) == Transpose(A).adjoint() assert Adjoint(eye(3)).doit() == Adjoint(eye(3)).doit(deep=False) == eye(3) assert Adjoint(Integer(5)).doit() == Integer(5) assert Adjoint(Matrix([[1, 2], [3, 4]])).doit() == Matrix([[1, 3], [2, 4]]) assert adjoint(trace(Sq)) == conjugate(trace(Sq)) assert trace(adjoint(Sq)) == conjugate(trace(Sq)) assert Adjoint(Sq)[0, 1] == conjugate(Sq[1, 0]) assert Adjoint(A * B).doit() == Adjoint(B) * Adjoint(A) assert Adjoint(C + D).doit() == Adjoint(C) + Adjoint(D)
def test_subs(): A = ImmutableMatrix([[1, 2], [3, 4]]) B = ImmutableMatrix([[1, 2], [x, 4]]) C = ImmutableMatrix([[-x, x*y], [-(x + y), y**2]]) assert B.subs({x: 3}) == A assert (x*B).subs({x: 3}) == 3*A assert (x*eye(2) + B).subs({x: 3}) == 3*eye(2) + A assert C.subs({x: -1, y: -2}) == A assert C.subs({x: y - 1, y: x - 1}, simultaneous=True) == \ ImmutableMatrix([[1 - y, (x - 1)*(y - 1)], [2 - x - y, (x - 1)**2]])
def test_subs(): A = ImmutableMatrix([[1, 2], [3, 4]]) B = ImmutableMatrix([[1, 2], [x, 4]]) C = ImmutableMatrix([[-x, x * y], [-(x + y), y**2]]) assert B.subs({x: 3}) == A assert (x * B).subs({x: 3}) == 3 * A assert (x * eye(2) + B).subs({x: 3}) == 3 * eye(2) + A assert C.subs({x: -1, y: -2}) == A assert C.subs({x: y - 1, y: x - 1}, simultaneous=True) == \ ImmutableMatrix([[1 - y, (x - 1)*(y - 1)], [2 - x - y, (x - 1)**2]])
def rotation_matrix(self, other): """ Returns the direction cosine matrix(DCM), also known as the 'rotation matrix' of this coordinate system with respect to another system. If v_a is a vector defined in system 'A' (in matrix format) and v_b is the same vector defined in system 'B', then v_a = A.rotation_matrix(B) * v_b. A Diofant Matrix is returned. Parameters ========== other : CoordSysCartesian The system which the DCM is generated to. Examples ======== >>> from diofant.vector import CoordSysCartesian >>> from diofant import symbols >>> q1 = symbols('q1') >>> N = CoordSysCartesian('N') >>> A = N.orient_new_axis('A', q1, N.i) >>> N.rotation_matrix(A) Matrix([ [1, 0, 0], [0, cos(q1), -sin(q1)], [0, sin(q1), cos(q1)]]) """ from diofant.vector.functions import _path if not isinstance(other, CoordSysCartesian): raise TypeError(str(other) + " is not a CoordSysCartesian") # Handle special cases if other == self: return eye(3) elif other == self._parent: return self._parent_rotation_matrix elif other._parent == self: return other._parent_rotation_matrix.T # Else, use tree to calculate position rootindex, path = _path(self, other) result = eye(3) i = -1 for i in range(rootindex): result *= path[i]._parent_rotation_matrix i += 2 while i < len(path): result *= path[i]._parent_rotation_matrix.T i += 1 return result
def test_block_index(): I = Identity(3) Z = ZeroMatrix(3, 3) B = BlockMatrix([[I, I], [I, I]]) e3 = ImmutableMatrix(eye(3)) BB = BlockMatrix([[e3, e3], [e3, e3]]) assert B[0, 0] == B[3, 0] == B[0, 3] == B[3, 3] == 1 assert B[4, 3] == B[5, 1] == 0 BB = BlockMatrix([[e3, e3], [e3, e3]]) assert B.as_explicit() == BB.as_explicit() BI = BlockMatrix([[I, Z], [Z, I]]) assert BI.as_explicit().equals(eye(6))
def test_Trace(): assert isinstance(Trace(A), Trace) assert not isinstance(Trace(A), MatrixExpr) pytest.raises(ShapeError, lambda: Trace(C)) assert trace(eye(3)) == 3 assert trace(Matrix(3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 9])) == 15 assert adjoint(Trace(A)) == trace(Adjoint(A)) assert conjugate(Trace(A)) == trace(Adjoint(A)) assert transpose(Trace(A)) == Trace(A) assert isinstance(A / Trace(A), MatrixExpr) # Some easy simplifications assert trace(Identity(5)) == 5 assert trace(ZeroMatrix(5, 5)) == 0 assert trace(2 * A * B) == 2 * Trace(A * B) assert trace(A.T) == trace(A) i, j = symbols('i j') F = FunctionMatrix(3, 3, Lambda((i, j), i + j)) assert trace(F) == (0 + 0) + (1 + 1) + (2 + 2) pytest.raises(TypeError, lambda: Trace(1)) assert Trace(A).arg is A assert str(trace(A)) == str(Trace(A).doit())
def compute_basis(self): order = self.order nsd = self.nsd N = [] pol, coeffs, basis = bernstein_space(order, nsd) points = create_point_set(order, nsd) equations = [] for p in points: ex = pol.subs(x, p[0]) if nsd > 1: ex = ex.subs(y, p[1]) if nsd > 2: ex = ex.subs(z, p[2]) equations.append(ex) A = create_matrix(equations, coeffs) Ainv = A.inv() b = eye(len(equations)) xx = Ainv * b for i in range(0, len(equations)): Ni = pol for j in range(0, len(coeffs)): Ni = Ni.subs(coeffs[j], xx[j, i]) N.append(Ni) self.N = N
def test_immutable_evaluation(): X = ImmutableMatrix(eye(3)) A = ImmutableMatrix(3, 3, range(9)) assert isinstance(X + A, ImmutableMatrix) assert isinstance(X * A, ImmutableMatrix) assert isinstance(X * 2, ImmutableMatrix) assert isinstance(2 * X, ImmutableMatrix) assert isinstance(A**2, ImmutableMatrix)
def test_det(): assert isinstance(Determinant(A), Determinant) assert not isinstance(Determinant(A), MatrixExpr) pytest.raises(ShapeError, lambda: Determinant(C)) assert det(eye(3)) == 1 assert det(Matrix(3, 3, [1, 3, 2, 4, 1, 3, 2, 5, 2])) == 17 assert isinstance(A / det(A), MatrixExpr) pytest.raises(TypeError, lambda: Determinant(1)) assert Determinant(A).arg is A
def test_sparse_solve(): A = SparseMatrix(((25, 15, -5), (15, 18, 0), (-5, 0, 11))) assert A.cholesky() == Matrix([[5, 0, 0], [3, 3, 0], [-1, 1, 3]]) assert A.cholesky() * A.cholesky().T == Matrix([[25, 15, -5], [15, 18, 0], [-5, 0, 11]]) A = SparseMatrix(((25, 15, -5), (15, 18, 0), (-5, 0, 11))) L, D = A.LDLdecomposition() assert 15 * L == Matrix([[15, 0, 0], [9, 15, 0], [-3, 5, 15]]) assert D == Matrix([[25, 0, 0], [0, 9, 0], [0, 0, 9]]) assert L * D * L.T == A A = SparseMatrix(((3, 0, 2), (0, 0, 1), (1, 2, 0))) assert A.inv() * A == SparseMatrix(eye(3)) A = SparseMatrix([[2, -1, 0], [-1, 2, -1], [0, 0, 2]]) ans = SparseMatrix([[Rational(2, 3), Rational(1, 3), Rational(1, 6)], [Rational(1, 3), Rational(2, 3), Rational(1, 3)], [0, 0, Rational(1, 2)]]) assert A.inv(method='CH') == ans assert A.inv(method='LDL') == ans assert A * ans == SparseMatrix(eye(3)) s = A.solve(A[:, 0], 'LDL') assert A * s == A[:, 0] s = A.solve(A[:, 0], 'CH') assert A * s == A[:, 0] A = A.col_join(A) s = A.solve_least_squares(A[:, 0], 'CH') assert A * s == A[:, 0] s = A.solve_least_squares(A[:, 0], 'LDL') assert A * s == A[:, 0] pytest.raises(ValueError, lambda: SparseMatrix([[1, 0, 1], [0, 0, 1]]).solve([1, 1])) pytest.raises( ValueError, lambda: SparseMatrix([[1, 0], [0, 0], [2, 1]]).solve([1, 1, 1]))
def test_containers(): assert octave_code([1, 2, 3, [4, 5, [6, 7]], 8, [9, 10], 11]) == \ '{1, 2, 3, {4, 5, {6, 7}}, 8, {9, 10}, 11}' assert octave_code((1, 2, (3, 4))) == '{1, 2, {3, 4}}' assert octave_code([1]) == '{1}' assert octave_code((1, )) == '{1}' assert octave_code(Tuple(*[1, 2, 3])) == '{1, 2, 3}' assert octave_code((1, x * y, (3, x**2))) == '{1, x.*y, {3, x.^2}}' # scalar, matrix, empty matrix and empty list assert octave_code( (1, eye(3), Matrix(0, 0, []), [])) == '{1, [1 0 0;\n0 1 0;\n0 0 1], [], {}}'
def test_inverse_laplace_transform(): ILT = inverse_laplace_transform a, b = symbols('a b', positive=True, finite=True) def simp_hyp(expr): return factor_terms(expand_mul(expr)).rewrite(sin) # just test inverses of all of the above assert ILT(1 / s, s, t) == Heaviside(t) assert ILT(1 / s**2, s, t) == t * Heaviside(t) assert ILT(1 / s**5, s, t) == t**4 * Heaviside(t) / 24 assert ILT(exp(-a * s) / s, s, t) == Heaviside(t - a) assert ILT(exp(-a * s) / (s + b), s, t) == exp(b * (a - t)) * Heaviside(-a + t) assert ILT(a / (s**2 + a**2), s, t) == sin(a * t) * Heaviside(t) assert ILT(s / (s**2 + a**2), s, t) == cos(a * t) * Heaviside(t) # TODO is there a way around simp_hyp? assert simp_hyp(ILT(a / (s**2 - a**2), s, t)) == sinh(a * t) * Heaviside(t) assert simp_hyp(ILT(s / (s**2 - a**2), s, t)) == cosh(a * t) * Heaviside(t) assert ILT(a / ((s + b)**2 + a**2), s, t) == exp(-b * t) * sin(a * t) * Heaviside(t) assert ILT((s + b) / ((s + b)**2 + a**2), s, t) == exp(-b * t) * cos(a * t) * Heaviside(t) # TODO sinh/cosh shifted come out a mess. also delayed trig is a mess # TODO should this simplify further? assert ILT(exp(-a*s)/s**b, s, t) == \ (t - a)**(b - 1)*Heaviside(t - a)/gamma(b) assert ILT(exp(-a*s)/sqrt(1 + s**2), s, t) == \ Heaviside(t - a)*besselj(0, a - t) # note: besselj(0, x) is even # XXX ILT turns these branch factor into trig functions ... assert simplify(ILT(a**b*(s + sqrt(s**2 - a**2))**(-b)/sqrt(s**2 - a**2), s, t).rewrite(exp)) == \ Heaviside(t)*besseli(b, a*t) assert ILT(a**b*(s + sqrt(s**2 + a**2))**(-b)/sqrt(s**2 + a**2), s, t).rewrite(exp) == \ Heaviside(t)*besselj(b, a*t) assert ILT(1 / (s * sqrt(s + 1)), s, t) == Heaviside(t) * erf(sqrt(t)) # TODO can we make erf(t) work? assert ILT(1 / (s**2 * (s**2 + 1)), s, t) == (t - sin(t)) * Heaviside(t) assert ILT((s * eye(2) - Matrix([[1, 0], [0, 2]])).inv(), s, t) ==\ Matrix([[exp(t)*Heaviside(t), 0], [0, exp(2*t)*Heaviside(t)]])
def test_valued_tensor_get_matrix(): (A, _, AB, _, _, _, E, px, py, pz, _, _, _, _, _, _, _, _, _, _, _, _, _, _, i0, i1, *_) = _get_valued_base_test_variables() matab = AB(i0, i1).get_matrix() assert matab == Matrix([ [1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, -1], ]) # when alternating contravariant/covariant with [1, -1, -1, -1] metric # it becomes the identity matrix: assert AB(i0, -i1).get_matrix() == eye(4) # covariant and contravariant forms: assert A(i0).get_matrix() == Matrix([E, px, py, pz]) assert A(-i0).get_matrix() == Matrix([E, -px, -py, -pz])
def test_valued_tensor_get_matrix(): (A, B, AB, BA, C, Lorentz, E, px, py, pz, LorentzD, mu0, mu1, mu2, ndm, n0, n1, n2, NA, NB, NC, minkowski, ba_matrix, ndm_matrix, i0, i1, i2, i3, i4) = _get_valued_base_test_variables() matab = AB(i0, i1).get_matrix() assert matab == Matrix([ [1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, -1], ]) # when alternating contravariant/covariant with [1, -1, -1, -1] metric # it becomes the identity matrix: assert AB(i0, -i1).get_matrix() == eye(4) # covariant and contravariant forms: assert A(i0).get_matrix() == Matrix([E, px, py, pz]) assert A(-i0).get_matrix() == Matrix([E, -px, -py, -pz])
def transform(name, X, Y, g_correct=None, recursive=False): """ Transforms from cartesian coordinates X to any curvilinear coordinates Y. It printing useful information, like Jacobian, metric tensor, determinant of metric, Laplace operator in the new coordinates, ... g_correct ... if not None, it will be taken as the metric --- this is useful if diofant's trigsimp() is not powerful enough to simplify the metric so that it is usable for later calculation. Leave it as None, only if the metric that transform() prints is not simplified, you can help it by specifying the correct one. recursive ... apply recursive trigonometric simplification (use only when needed, as it is an expensive operation) """ print("_" * 80) print("Transformation:", name) for x, y in zip(X, Y): pprint(Eq(y, x)) J = X.jacobian(Y) print("Jacobian:") pprint(J) g = J.T * eye(J.shape[0]) * J g = g.applyfunc(expand) print("metric tensor g_{ij}:") pprint(g) if g_correct is not None: g = g_correct print("metric tensor g_{ij} specified by hand:") pprint(g) print("inverse metric tensor g^{ij}:") g_inv = g.inv(method="ADJ") g_inv = g_inv.applyfunc(simplify) pprint(g_inv) print("det g_{ij}:") g_det = g.det() pprint(g_det) f = Function("f")(*list(Y)) print("Laplace:") pprint(laplace(f, g_inv, g_det, Y))
def test_valued_metric_inverse(): (A, B, AB, BA, C, Lorentz, E, px, py, pz, LorentzD, mu0, mu1, mu2, ndm, n0, n1, n2, NA, NB, NC, minkowski, ba_matrix, ndm_matrix, i0, i1, i2, i3, i4) = _get_valued_base_test_variables() # let's assign some fancy matrix, just to verify it: # (this has no physical sense, it's just testing diofant); # it is symmetrical: md = [[2, 2, 2, 1], [2, 3, 1, 0], [2, 1, 2, 3], [1, 0, 3, 2]] with pytest.raises(ValueError): Lorentz.data = [[[1, 2], [1, 2]], [[3, 4], [3, 4]]] with pytest.raises(ValueError): Lorentz.data = [[1, 2]] with pytest.raises(ValueError): Lorentz.data = [[1]] with pytest.raises(ValueError): Lorentz.data = [1] with pytest.raises(ValueError): Lorentz.data = [[1], [2]] Lorentz.data = md m = Matrix(md) metric = Lorentz.metric minv = m.inv() meye = eye(4) # the Kronecker Delta: KD = Lorentz.get_kronecker_delta() for i in range(4): for j in range(4): assert metric(i0, i1).data[i, j] == m[i, j] assert metric(-i0, -i1).data[i, j] == minv[i, j] assert metric(i0, -i1).data[i, j] == meye[i, j] assert metric(-i0, i1).data[i, j] == meye[i, j] assert metric(i0, i1)[i, j] == m[i, j] assert metric(-i0, -i1)[i, j] == minv[i, j] assert metric(i0, -i1)[i, j] == meye[i, j] assert metric(-i0, i1)[i, j] == meye[i, j] assert KD(i0, -i1)[i, j] == meye[i, j]
def test_valued_metric_inverse(): (_, _, _, _, _, Lorentz, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, i0, i1, *_) = _get_valued_base_test_variables() # let's assign some fancy matrix, just to verify it: # (this has no physical sense, it's just testing diofant); # it is symmetrical: md = [[2, 2, 2, 1], [2, 3, 1, 0], [2, 1, 2, 3], [1, 0, 3, 2]] with pytest.raises(ValueError): Lorentz.data = [[[1, 2], [1, 2]], [[3, 4], [3, 4]]] with pytest.raises(ValueError): Lorentz.data = [[1, 2]] with pytest.raises(ValueError): Lorentz.data = [[1]] with pytest.raises(ValueError): Lorentz.data = [1] with pytest.raises(ValueError): Lorentz.data = [[1], [2]] Lorentz.data = md m = Matrix(md) metric = Lorentz.metric minv = m.inv() meye = eye(4) # the Kronecker Delta: KD = Lorentz.get_kronecker_delta() for i in range(4): for j in range(4): assert metric(i0, i1).data[i, j] == m[i, j] assert metric(-i0, -i1).data[i, j] == minv[i, j] assert metric(i0, -i1).data[i, j] == meye[i, j] assert metric(-i0, i1).data[i, j] == meye[i, j] assert metric(i0, i1)[i, j] == m[i, j] assert metric(-i0, -i1)[i, j] == minv[i, j] assert metric(i0, -i1)[i, j] == meye[i, j] assert metric(-i0, i1)[i, j] == meye[i, j] assert KD(i0, -i1)[i, j] == meye[i, j]
def test_matrix_symbol_MM(): X = MatrixSymbol('X', 3, 3) Y = eye(3) + X assert Y[1, 1] == 1 + X[1, 1]
def test_sparse_zeros_sparse_eye(): assert SparseMatrix.eye(3) == eye(3, cls=SparseMatrix) assert len(SparseMatrix.eye(3)._smat) == 3 assert SparseMatrix.zeros(3) == zeros(3, cls=SparseMatrix) assert len(SparseMatrix.zeros(3)._smat) == 0
def test_sparse_matrix(): def sparse_eye(n): return SparseMatrix.eye(n) def sparse_zeros(n): return SparseMatrix.zeros(n) # creation args pytest.raises(TypeError, lambda: SparseMatrix(1, 2)) pytest.raises(ValueError, lambda: SparseMatrix(2, 2, (1, 3, 4, 5, 6))) a = SparseMatrix(((1, 0), (0, 1))) assert SparseMatrix(a) == a a = MutableSparseMatrix([]) b = MutableDenseMatrix([1, 2]) assert a.row_join(b) == b assert a.col_join(b) == b assert type(a.row_join(b)) == type(a) assert type(a.col_join(b)) == type(a) # test element assignment a = SparseMatrix(((1, 0), (0, 1))) a[3] = 4 assert a[1, 1] == 4 a[3] = 1 a[0, 0] = 2 assert a == SparseMatrix(((2, 0), (0, 1))) a[1, 0] = 5 assert a == SparseMatrix(((2, 0), (5, 1))) a[1, 1] = 0 assert a == SparseMatrix(((2, 0), (5, 0))) assert a._smat == {(0, 0): 2, (1, 0): 5} # test_multiplication a = SparseMatrix(( (1, 2), (3, 1), (0, 6), )) b = SparseMatrix(( (1, 2), (3, 0), )) c = a * b assert c[0, 0] == 7 assert c[0, 1] == 2 assert c[1, 0] == 6 assert c[1, 1] == 6 assert c[2, 0] == 18 assert c[2, 1] == 0 c = b * x assert isinstance(c, SparseMatrix) assert c[0, 0] == x assert c[0, 1] == 2 * x assert c[1, 0] == 3 * x assert c[1, 1] == 0 c = 5 * b assert isinstance(c, SparseMatrix) assert c[0, 0] == 5 assert c[0, 1] == 2 * 5 assert c[1, 0] == 3 * 5 assert c[1, 1] == 0 # test_power A = SparseMatrix([[2, 3], [4, 5]]) assert (A**5)[:] == [6140, 8097, 10796, 14237] A = SparseMatrix([[2, 1, 3], [4, 2, 4], [6, 12, 1]]) assert (A**3)[:] == [290, 262, 251, 448, 440, 368, 702, 954, 433] # test_creation a = SparseMatrix([[x, 0], [0, 0]]) m = a assert m.cols == m.rows assert m.cols == 2 assert m[:] == [x, 0, 0, 0] b = SparseMatrix(2, 2, [x, 0, 0, 0]) m = b assert m.cols == m.rows assert m.cols == 2 assert m[:] == [x, 0, 0, 0] assert a == b S = sparse_eye(3) del S[1, :] assert S == SparseMatrix([[1, 0, 0], [0, 0, 1]]) S = sparse_eye(3) del S[:, 1] assert S == SparseMatrix([[1, 0], [0, 0], [0, 1]]) S = SparseMatrix.eye(3) S[2, 1] = 2 S.col_swap(1, 0) assert S == SparseMatrix([[0, 1, 0], [1, 0, 0], [2, 0, 1]]) S.row_swap(0, 1) assert S == SparseMatrix([[1, 0, 0], [0, 1, 0], [2, 0, 1]]) S.col_swap(0, 1) assert S == SparseMatrix([[0, 1, 0], [1, 0, 0], [0, 2, 1]]) S.row_swap(0, 2) assert S == SparseMatrix([[0, 2, 1], [1, 0, 0], [0, 1, 0]]) S.col_swap(0, 2) assert S == SparseMatrix([[1, 2, 0], [0, 0, 1], [0, 1, 0]]) a = SparseMatrix(1, 2, [1, 2]) b = a.copy() c = a.copy() assert a[0] == 1 del a[0, :] assert a == SparseMatrix(0, 2, []) del b[:, 1] assert b == SparseMatrix(1, 1, [1]) # test_determinant assert SparseMatrix(1, 1, [0]).det() == 0 assert SparseMatrix([[1]]).det() == 1 assert SparseMatrix(((-3, 2), (8, -5))).det() == -1 assert SparseMatrix(((x, 1), (y, 2 * y))).det() == 2 * x * y - y assert SparseMatrix(((1, 1, 1), (1, 2, 3), (1, 3, 6))).det() == 1 assert SparseMatrix(((3, -2, 0, 5), (-2, 1, -2, 2), (0, -2, 5, 0), (5, 0, 3, 4))).det() == -289 assert SparseMatrix(((1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12), (13, 14, 15, 16))).det() == 0 assert SparseMatrix(((3, 2, 0, 0, 0), (0, 3, 2, 0, 0), (0, 0, 3, 2, 0), (0, 0, 0, 3, 2), (2, 0, 0, 0, 3))).det() == 275 assert SparseMatrix(((1, 0, 1, 2, 12), (2, 0, 1, 1, 4), (2, 1, 1, -1, 3), (3, 2, -1, 1, 8), (1, 1, 1, 0, 6))).det() == -55 assert SparseMatrix(((-5, 2, 3, 4, 5), (1, -4, 3, 4, 5), (1, 2, -3, 4, 5), (1, 2, 3, -2, 5), (1, 2, 3, 4, -1))).det() == 11664 assert SparseMatrix(((2, 7, -1, 3, 2), (0, 0, 1, 0, 1), (-2, 0, 7, 0, 2), (-3, -2, 4, 5, 3), (1, 0, 0, 0, 1))).det() == 123 # test_slicing m0 = sparse_eye(4) assert m0[:3, :3] == sparse_eye(3) assert m0[2:4, 0:2] == sparse_zeros(2) m1 = SparseMatrix(3, 3, lambda i, j: i + j) assert m1[0, :] == SparseMatrix(1, 3, (0, 1, 2)) assert m1[1:3, 1] == SparseMatrix(2, 1, (2, 3)) m2 = SparseMatrix([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]) assert m2[:, -1] == SparseMatrix(4, 1, [3, 7, 11, 15]) assert m2[-2:, :] == SparseMatrix([[8, 9, 10, 11], [12, 13, 14, 15]]) assert SparseMatrix([[1, 2], [3, 4]])[[1], [1]] == Matrix([[4]]) # test_submatrix_assignment m = sparse_zeros(4) m[2:4, 2:4] = sparse_eye(2) assert m == SparseMatrix([(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)]) assert len(m._smat) == 2 m[:2, :2] = sparse_eye(2) assert m == sparse_eye(4) m[:, 0] = SparseMatrix(4, 1, (1, 2, 3, 4)) assert m == SparseMatrix([(1, 0, 0, 0), (2, 1, 0, 0), (3, 0, 1, 0), (4, 0, 0, 1)]) m[:, :] = sparse_zeros(4) assert m == sparse_zeros(4) m[:, :] = ((1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12), (13, 14, 15, 16)) assert m == SparseMatrix( ((1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12), (13, 14, 15, 16))) m[:2, 0] = [0, 0] assert m == SparseMatrix( ((0, 2, 3, 4), (0, 6, 7, 8), (9, 10, 11, 12), (13, 14, 15, 16))) # test_reshape m0 = sparse_eye(3) assert m0.reshape(1, 9) == SparseMatrix(1, 9, (1, 0, 0, 0, 1, 0, 0, 0, 1)) m1 = SparseMatrix(3, 4, lambda i, j: i + j) assert m1.reshape(4, 3) == \ SparseMatrix([(0, 1, 2), (3, 1, 2), (3, 4, 2), (3, 4, 5)]) assert m1.reshape(2, 6) == \ SparseMatrix([(0, 1, 2, 3, 1, 2), (3, 4, 2, 3, 4, 5)]) # test_applyfunc m0 = sparse_eye(3) assert m0.applyfunc(lambda x: 2 * x) == sparse_eye(3) * 2 assert m0.applyfunc(lambda x: 0) == sparse_zeros(3) # test_LUdecomp testmat = SparseMatrix([[0, 2, 5, 3], [3, 3, 7, 4], [8, 4, 0, 2], [-2, 6, 3, 4]]) L, U, p = testmat.LUdecomposition() assert L.is_lower assert U.is_upper assert (L * U).permuteBkwd(p) - testmat == sparse_zeros(4) testmat = SparseMatrix([[6, -2, 7, 4], [0, 3, 6, 7], [1, -2, 7, 4], [-9, 2, 6, 3]]) L, U, p = testmat.LUdecomposition() assert L.is_lower assert U.is_upper assert (L * U).permuteBkwd(p) - testmat == sparse_zeros(4) M = Matrix(((1, x, 1), (2, y, 0), (y, 0, z))) L, U, p = M.LUdecomposition() assert L.is_lower assert U.is_upper assert (L * U).permuteBkwd(p) - M == sparse_zeros(3) # test_LUsolve A = SparseMatrix([[2, 3, 5], [3, 6, 2], [8, 3, 6]]) B = SparseMatrix(3, 1, [3, 7, 5]) b = A * B soln = A.LUsolve(b) assert soln == B A = SparseMatrix([[0, -1, 2], [5, 10, 7], [8, 3, 4]]) B = SparseMatrix(3, 1, [-1, 2, 5]) b = A * B soln = A.LUsolve(b) assert soln == B # test_inverse A = sparse_eye(4) assert A.inv() == sparse_eye(4) assert A.inv(method='CH') == sparse_eye(4) assert A.inv(method='LDL') == sparse_eye(4) A = SparseMatrix([[2, 3, 5], [3, 6, 2], [7, 2, 6]]) Ainv = SparseMatrix(Matrix(A).inv()) assert A * Ainv == sparse_eye(3) assert A.inv(method='CH') == Ainv assert A.inv(method='LDL') == Ainv A = SparseMatrix([[2, 3, 5], [3, 6, 2], [5, 2, 6]]) Ainv = SparseMatrix(Matrix(A).inv()) assert A * Ainv == sparse_eye(3) assert A.inv(method='CH') == Ainv assert A.inv(method='LDL') == Ainv # test_cross v1 = Matrix(1, 3, [1, 2, 3]) v2 = Matrix(1, 3, [3, 4, 5]) assert v1.cross(v2) == Matrix(1, 3, [-2, 4, -2]) assert v1.norm(2)**2 == 14 # conjugate a = SparseMatrix(((1, 2 + I), (3, 4))) assert a.C == SparseMatrix([[1, 2 - I], [3, 4]]) # mul assert a * Matrix(2, 2, [1, 0, 0, 1]) == a assert a + Matrix(2, 2, [1, 1, 1, 1]) == SparseMatrix([[2, 3 + I], [4, 5]]) assert a * 0 == Matrix([[0, 0], [0, 0]]) # col join assert a.col_join(sparse_eye(2)) == SparseMatrix([[1, 2 + I], [3, 4], [1, 0], [0, 1]]) A = SparseMatrix(ones(3)) B = eye(3) assert A.col_join(B) == Matrix([[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 0, 0], [0, 1, 0], [0, 0, 1]]) # row join A = SparseMatrix(((1, 0, 1), (0, 1, 0), (1, 1, 0))) B = Matrix(((1, 0, 0), (0, 1, 0), (0, 0, 1))) assert A.row_join(B) == Matrix([[1, 0, 1, 1, 0, 0], [0, 1, 0, 0, 1, 0], [1, 1, 0, 0, 0, 1]]) # symmetric assert not a.is_symmetric(simplify=False) assert sparse_eye(3).is_symmetric(simplify=False) # test_cofactor assert sparse_eye(3) == sparse_eye(3).cofactorMatrix() test = SparseMatrix([[1, 3, 2], [2, 6, 3], [2, 3, 6]]) assert test.cofactorMatrix() == \ SparseMatrix([[27, -6, -6], [-12, 2, 3], [-3, 1, 0]]) test = SparseMatrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) assert test.cofactorMatrix() == \ SparseMatrix([[-3, 6, -3], [6, -12, 6], [-3, 6, -3]]) # test_jacobian L = SparseMatrix(1, 2, [x**2 * y, 2 * y**2 + x * y]) syms = [x, y] assert L.jacobian(syms) == Matrix([[2 * x * y, x**2], [y, 4 * y + x]]) L = SparseMatrix(1, 2, [x, x**2 * y**3]) assert L.jacobian(syms) == SparseMatrix([[1, 0], [2 * x * y**3, x**2 * 3 * y**2]]) # test_QR A = Matrix([[1, 2], [2, 3]]) Q, S = A.QRdecomposition() R = Rational assert Q == Matrix([[5**R(-1, 2), (R(2) / 5) * (R(1) / 5)**R(-1, 2)], [2 * 5**R(-1, 2), (-R(1) / 5) * (R(1) / 5)**R(-1, 2)]]) assert S == Matrix([[5**R(1, 2), 8 * 5**R(-1, 2)], [0, (R(1) / 5)**R(1, 2)]]) assert Q * S == A assert Q.T * Q == sparse_eye(2) R = Rational # test nullspace # first test reduced row-ech form M = SparseMatrix([[5, 7, 2, 1], [1, 6, 2, -1]]) out, tmp = M.rref() assert out == Matrix([[1, 0, -R(2) / 23, R(13) / 23], [0, 1, R(8) / 23, R(-6) / 23]]) M = SparseMatrix([[1, 3, 0, 2, 6, 3, 1], [-2, -6, 0, -2, -8, 3, 1], [3, 9, 0, 0, 6, 6, 2], [-1, -3, 0, 1, 0, 9, 3]]) out, tmp = M.rref() assert out == Matrix([[1, 3, 0, 0, 2, 0, 0], [0, 0, 0, 1, 2, 0, 0], [0, 0, 0, 0, 0, 1, R(1) / 3], [0, 0, 0, 0, 0, 0, 0]]) # now check the vectors basis = M.nullspace() assert basis[0] == Matrix([-3, 1, 0, 0, 0, 0, 0]) assert basis[1] == Matrix([0, 0, 1, 0, 0, 0, 0]) assert basis[2] == Matrix([-2, 0, 0, -2, 1, 0, 0]) assert basis[3] == Matrix([0, 0, 0, 0, 0, R(-1) / 3, 1]) # test eigen sparse_eye3 = sparse_eye(3) assert sparse_eye3.charpoly(x) == PurePoly(((x - 1)**3)) assert sparse_eye3.charpoly(y) == PurePoly(((y - 1)**3)) # test values M = Matrix([(0, 1, -1), (1, 1, 0), (-1, 0, 1)]) vals = M.eigenvals() assert sorted(vals) == [-1, 1, 2] R = Rational M = Matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) assert M.eigenvects() == [ (1, 3, [Matrix([1, 0, 0]), Matrix([0, 1, 0]), Matrix([0, 0, 1])]) ] M = Matrix([[5, 0, 2], [3, 2, 0], [0, 0, 1]]) assert M.eigenvects() == [(1, 1, [Matrix([R(-1) / 2, R(3) / 2, 1])]), (2, 1, [Matrix([0, 1, 0])]), (5, 1, [Matrix([1, 1, 0])])] assert M.zeros(3, 5) == SparseMatrix(3, 5, {}) A = SparseMatrix( 10, 10, { (0, 0): 18, (0, 9): 12, (1, 4): 18, (2, 7): 16, (3, 9): 12, (4, 2): 19, (5, 7): 16, (6, 2): 12, (9, 7): 18 }) assert A.row_list() == [(0, 0, 18), (0, 9, 12), (1, 4, 18), (2, 7, 16), (3, 9, 12), (4, 2, 19), (5, 7, 16), (6, 2, 12), (9, 7, 18)] assert A.col_list() == [(0, 0, 18), (4, 2, 19), (6, 2, 12), (1, 4, 18), (2, 7, 16), (5, 7, 16), (9, 7, 18), (0, 9, 12), (3, 9, 12)] assert SparseMatrix.eye(2).nnz() == 2 M = SparseMatrix.eye(3) * 2 M[1, 0] = -1 M.col_op(1, lambda v, i: v + 2 * M[i, 0]) assert M == Matrix([[2, 4, 0], [-1, 0, 0], [0, 0, 2]]) M = SparseMatrix.zeros(3) M.fill(1) assert M == ones(3) assert SparseMatrix(ones(0, 3)).tolist() == []
def test_matadd_of_matrices(): assert MatAdd(eye(2), 4 * eye(2), eye(2)).doit() == ImmutableMatrix(6 * eye(2))
import pytest from diofant import (Equality, ImmutableMatrix, ImmutableSparseMatrix, Matrix, SparseMatrix, Unequality, eye, false, sympify, true, zeros) from diofant.abc import x, y __all__ = () IM = ImmutableMatrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) ieye = ImmutableMatrix(eye(3)) def test_immutable_creation(): assert IM.shape == (3, 3) assert IM[1, 2] == 6 assert IM[2, 2] == 9 def test_immutability(): with pytest.raises(TypeError): IM[2, 2] = 5 ISM = SparseMatrix(IM).as_immutable() with pytest.raises(TypeError): ISM[2, 2] = 5 def test_slicing(): assert IM[1, :] == ImmutableMatrix([[4, 5, 6]]) assert IM[:2, :2] == ImmutableMatrix([[1, 2], [4, 5]])
def test_matadd_sympify(): assert isinstance(MatAdd(eye(1), eye(1)).args[0], Basic)
def test_equality(): a, b, c = Identity(3), eye(3), ImmutableMatrix(eye(3)) for x in [a, b, c]: for y in [a, b, c]: assert x.equals(y)
"""Interaction tests for different kind of Matrices.""" import pytest from diofant import (Identity, ImmutableMatrix, MatAdd, Matrix, MatrixExpr, MatrixSymbol, eye) from diofant.abc import a from diofant.matrices.matrices import classof __all__ = () SM = MatrixSymbol('X', 3, 3) MM = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) IM = ImmutableMatrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) meye = eye(3) imeye = ImmutableMatrix(eye(3)) ideye = Identity(3) def test_IM_MM(): assert isinstance(MM + IM, Matrix) assert isinstance(IM + MM, ImmutableMatrix) assert isinstance(2*IM + MM, ImmutableMatrix) assert MM.equals(IM) assert MM.equals(2) is False def test_ME_MM(): assert isinstance(Identity(3) + MM, MatrixExpr) assert isinstance(SM + MM, MatAdd)
def test_matadd(): pytest.raises(ShapeError, lambda: X + eye(1)) MatAdd(X, eye(1), check=False) # not raises
def __new__(cls, name, location=None, rotation_matrix=None, parent=None, vector_names=None, variable_names=None): """ The orientation/location parameters are necessary if this system is being defined at a certain orientation or location wrt another. Parameters ========== name : str The name of the new CoordSysCartesian instance. location : Vector The position vector of the new system's origin wrt the parent instance. rotation_matrix : Diofant ImmutableMatrix The rotation matrix of the new coordinate system with respect to the parent. In other words, the output of new_system.rotation_matrix(parent). parent : CoordSysCartesian The coordinate system wrt which the orientation/location (or both) is being defined. vector_names, variable_names : iterable(optional) Iterables of 3 strings each, with custom names for base vectors and base scalars of the new system respectively. Used for simple str printing. """ name = str(name) Vector = diofant.vector.Vector BaseVector = diofant.vector.BaseVector Point = diofant.vector.Point if not isinstance(name, str): raise TypeError("name should be a string") # If orientation information has been provided, store # the rotation matrix accordingly if rotation_matrix is None: parent_orient = Matrix(eye(3)) else: if not isinstance(rotation_matrix, Matrix): raise TypeError("rotation_matrix should be an Immutable" + "Matrix instance") parent_orient = rotation_matrix # If location information is not given, adjust the default # location as Vector.zero if parent is not None: if not isinstance(parent, CoordSysCartesian): raise TypeError("parent should be a " + "CoordSysCartesian/None") if location is None: location = Vector.zero else: if not isinstance(location, Vector): raise TypeError("location should be a Vector") # Check that location does not contain base # scalars for x in location.free_symbols: if isinstance(x, BaseScalar): raise ValueError("location should not contain" + " BaseScalars") origin = parent.origin.locate_new(name + '.origin', location) else: location = Vector.zero origin = Point(name + '.origin') # All systems that are defined as 'roots' are unequal, unless # they have the same name. # Systems defined at same orientation/position wrt the same # 'parent' are equal, irrespective of the name. # This is true even if the same orientation is provided via # different methods like Axis/Body/Space/Quaternion. # However, coincident systems may be seen as unequal if # positioned/oriented wrt different parents, even though # they may actually be 'coincident' wrt the root system. if parent is not None: obj = super(CoordSysCartesian, cls).__new__(cls, Symbol(name), location, parent_orient, parent) else: obj = super(CoordSysCartesian, cls).__new__(cls, Symbol(name), location, parent_orient) obj._name = name # Initialize the base vectors if vector_names is None: vector_names = (name + '.i', name + '.j', name + '.k') latex_vects = [(r'\mathbf{\hat{i}_{%s}}' % name), (r'\mathbf{\hat{j}_{%s}}' % name), (r'\mathbf{\hat{k}_{%s}}' % name)] pretty_vects = (name + '_i', name + '_j', name + '_k') else: _check_strings('vector_names', vector_names) vector_names = list(vector_names) latex_vects = [(r'\mathbf{\hat{%s}_{%s}}' % (x, name)) for x in vector_names] pretty_vects = [(name + '_' + x) for x in vector_names] obj._i = BaseVector(vector_names[0], 0, obj, pretty_vects[0], latex_vects[0]) obj._j = BaseVector(vector_names[1], 1, obj, pretty_vects[1], latex_vects[1]) obj._k = BaseVector(vector_names[2], 2, obj, pretty_vects[2], latex_vects[2]) # Initialize the base scalars if variable_names is None: variable_names = (name + '.x', name + '.y', name + '.z') latex_scalars = [(r"\mathbf{{x}_{%s}}" % name), (r"\mathbf{{y}_{%s}}" % name), (r"\mathbf{{z}_{%s}}" % name)] pretty_scalars = (name + '_x', name + '_y', name + '_z') else: _check_strings('variable_names', vector_names) variable_names = list(variable_names) latex_scalars = [(r"\mathbf{{%s}_{%s}}" % (x, name)) for x in variable_names] pretty_scalars = [(name + '_' + x) for x in variable_names] obj._x = BaseScalar(variable_names[0], 0, obj, pretty_scalars[0], latex_scalars[0]) obj._y = BaseScalar(variable_names[1], 1, obj, pretty_scalars[1], latex_scalars[1]) obj._z = BaseScalar(variable_names[2], 2, obj, pretty_scalars[2], latex_scalars[2]) # Assign a Del operator instance from diofant.vector.deloperator import Del obj._delop = Del(obj) # Assign params obj._parent = parent if obj._parent is not None: obj._root = obj._parent._root else: obj._root = obj obj._parent_rotation_matrix = parent_orient obj._origin = origin # Return the instance return obj
def orient_new(self, name, orienters, location=None, vector_names=None, variable_names=None): """ Creates a new CoordSysCartesian oriented in the user-specified way with respect to this system. Please refer to the documentation of the orienter classes for more information about the orientation procedure. Parameters ========== name : str The name of the new CoordSysCartesian instance. orienters : iterable/Orienter An Orienter or an iterable of Orienters for orienting the new coordinate system. If an Orienter is provided, it is applied to get the new system. If an iterable is provided, the orienters will be applied in the order in which they appear in the iterable. location : Vector(optional) The location of the new coordinate system's origin wrt this system's origin. If not specified, the origins are taken to be coincident. vector_names, variable_names : iterable(optional) Iterables of 3 strings each, with custom names for base vectors and base scalars of the new system respectively. Used for simple str printing. Examples ======== >>> from diofant.vector import CoordSysCartesian >>> from diofant import symbols >>> q0, q1, q2, q3 = symbols('q0 q1 q2 q3') >>> N = CoordSysCartesian('N') Using an AxisOrienter >>> from diofant.vector import AxisOrienter >>> axis_orienter = AxisOrienter(q1, N.i + 2 * N.j) >>> A = N.orient_new('A', (axis_orienter, )) Using a BodyOrienter >>> from diofant.vector import BodyOrienter >>> body_orienter = BodyOrienter(q1, q2, q3, '123') >>> B = N.orient_new('B', (body_orienter, )) Using a SpaceOrienter >>> from diofant.vector import SpaceOrienter >>> space_orienter = SpaceOrienter(q1, q2, q3, '312') >>> C = N.orient_new('C', (space_orienter, )) Using a QuaternionOrienter >>> from diofant.vector import QuaternionOrienter >>> q_orienter = QuaternionOrienter(q0, q1, q2, q3) >>> D = N.orient_new('D', (q_orienter, )) """ if isinstance(orienters, Orienter): if isinstance(orienters, AxisOrienter): final_matrix = orienters.rotation_matrix(self) else: final_matrix = orienters.rotation_matrix() else: final_matrix = Matrix(eye(3)) for orienter in orienters: if isinstance(orienter, AxisOrienter): final_matrix *= orienter.rotation_matrix(self) else: final_matrix *= orienter.rotation_matrix() return CoordSysCartesian(name, rotation_matrix=final_matrix, vector_names=vector_names, variable_names=variable_names, location=location, parent=self)
def test_matmul_sympify(): assert isinstance(MatMul(eye(1), eye(1)).args[0], Basic)