def test_NumPyPrinter(): from sympy.core.function import Lambda from sympy.matrices.expressions.adjoint import Adjoint from sympy.matrices.expressions.diagonal import (DiagMatrix, DiagonalMatrix, DiagonalOf) from sympy.matrices.expressions.funcmatrix import FunctionMatrix from sympy.matrices.expressions.hadamard import HadamardProduct from sympy.matrices.expressions.kronecker import KroneckerProduct from sympy.matrices.expressions.special import (OneMatrix, ZeroMatrix) from sympy.abc import a, b p = NumPyPrinter() assert p.doprint(sign(x)) == 'numpy.sign(x)' A = MatrixSymbol("A", 2, 2) B = MatrixSymbol("B", 2, 2) C = MatrixSymbol("C", 1, 5) D = MatrixSymbol("D", 3, 4) assert p.doprint(A**(-1)) == "numpy.linalg.inv(A)" assert p.doprint(A**5) == "numpy.linalg.matrix_power(A, 5)" assert p.doprint(Identity(3)) == "numpy.eye(3)" u = MatrixSymbol('x', 2, 1) v = MatrixSymbol('y', 2, 1) assert p.doprint(MatrixSolve(A, u)) == 'numpy.linalg.solve(A, x)' assert p.doprint(MatrixSolve(A, u) + v) == 'numpy.linalg.solve(A, x) + y' assert p.doprint(ZeroMatrix(2, 3)) == "numpy.zeros((2, 3))" assert p.doprint(OneMatrix(2, 3)) == "numpy.ones((2, 3))" assert p.doprint(FunctionMatrix(4, 5, Lambda((a, b), a + b))) == \ "numpy.fromfunction(lambda a, b: a + b, (4, 5))" assert p.doprint(HadamardProduct(A, B)) == "numpy.multiply(A, B)" assert p.doprint(KroneckerProduct(A, B)) == "numpy.kron(A, B)" assert p.doprint(Adjoint(A)) == "numpy.conjugate(numpy.transpose(A))" assert p.doprint(DiagonalOf(A)) == "numpy.reshape(numpy.diag(A), (-1, 1))" assert p.doprint(DiagMatrix(C)) == "numpy.diagflat(C)" assert p.doprint(DiagonalMatrix(D)) == "numpy.multiply(D, numpy.eye(3, 4))" # Workaround for numpy negative integer power errors assert p.doprint(x**-1) == 'x**(-1.0)' assert p.doprint(x**-2) == 'x**(-2.0)' expr = Pow(2, -1, evaluate=False) assert p.doprint(expr) == "2**(-1.0)" assert p.doprint(S.Exp1) == 'numpy.e' assert p.doprint(S.Pi) == 'numpy.pi' assert p.doprint(S.EulerGamma) == 'numpy.euler_gamma' assert p.doprint(S.NaN) == 'numpy.nan' assert p.doprint(S.Infinity) == 'numpy.PINF' assert p.doprint(S.NegativeInfinity) == 'numpy.NINF'
def test_field_assumptions(): X = MatrixSymbol('X', 4, 4) Y = MatrixSymbol('Y', 4, 4) assert ask(Q.real_elements(X), Q.real_elements(X)) assert not ask(Q.integer_elements(X), Q.real_elements(X)) assert ask(Q.complex_elements(X), Q.real_elements(X)) assert ask(Q.real_elements(X + Y), Q.real_elements(X)) is None assert ask(Q.real_elements(X + Y), Q.real_elements(X) & Q.real_elements(Y)) from sympy.matrices.expressions.hadamard import HadamardProduct assert ask(Q.real_elements(HadamardProduct(X, Y)), Q.real_elements(X) & Q.real_elements(Y)) assert ask(Q.complex_elements(X + Y), Q.real_elements(X) & Q.complex_elements(Y)) assert ask(Q.real_elements(X.T), Q.real_elements(X)) assert ask(Q.real_elements(X.I), Q.real_elements(X) & Q.invertible(X)) assert ask(Q.real_elements(Trace(X)), Q.real_elements(X)) assert ask(Q.integer_elements(Determinant(X)), Q.integer_elements(X)) assert not ask(Q.integer_elements(X.I), Q.integer_elements(X))
def test_matrix_derivative_by_scalar(): assert A.diff(i) == ZeroMatrix(k, k) assert (A*(X + B)*c).diff(i) == ZeroMatrix(k, 1) assert x.diff(i) == ZeroMatrix(k, 1) assert (x.T*y).diff(i) == ZeroMatrix(1, 1) assert (x*x.T).diff(i) == ZeroMatrix(k, k) assert (x + y).diff(i) == ZeroMatrix(k, 1) assert hadamard_power(x, 2).diff(i) == ZeroMatrix(k, 1) assert hadamard_power(x, i).diff(i).dummy_eq( HadamardProduct(x.applyfunc(log), HadamardPower(x, i))) assert hadamard_product(x, y).diff(i) == ZeroMatrix(k, 1) assert hadamard_product(i*OneMatrix(k, 1), x, y).diff(i) == hadamard_product(x, y) assert (i*x).diff(i) == x assert (sin(i)*A*B*x).diff(i) == cos(i)*A*B*x assert x.applyfunc(sin).diff(i) == ZeroMatrix(k, 1) assert Trace(i**2*X).diff(i) == 2*i*Trace(X) mu = symbols("mu") expr = (2*mu*x) assert expr.diff(x) == 2*mu*Identity(k)
def test_derivatives_elementwise_applyfunc(): expr = x.applyfunc(tan) assert expr.diff(x).dummy_eq( DiagMatrix(x.applyfunc(lambda x: tan(x)**2 + 1))) assert expr[i, 0].diff(x[m, 0]).doit() == (tan(x[i, 0])**2 + 1) * KDelta(i, m) _check_derivative_with_explicit_matrix(expr, x, expr.diff(x)) expr = (i**2 * x).applyfunc(sin) assert expr.diff(i).dummy_eq( HadamardProduct((2 * i) * x, (i**2 * x).applyfunc(cos))) assert expr[i, 0].diff(i).doit() == 2 * i * x[i, 0] * cos(i**2 * x[i, 0]) _check_derivative_with_explicit_matrix(expr, i, expr.diff(i)) expr = (log(i) * A * B).applyfunc(sin) assert expr.diff(i).dummy_eq( HadamardProduct(A * B / i, (log(i) * A * B).applyfunc(cos))) _check_derivative_with_explicit_matrix(expr, i, expr.diff(i)) expr = A * x.applyfunc(exp) # TODO: restore this result (currently returning the transpose): # assert expr.diff(x).dummy_eq(DiagMatrix(x.applyfunc(exp))*A.T) _check_derivative_with_explicit_matrix(expr, x, expr.diff(x)) expr = x.T * A * x + k * y.applyfunc(sin).T * x assert expr.diff(x).dummy_eq(A.T * x + A * x + k * y.applyfunc(sin)) _check_derivative_with_explicit_matrix(expr, x, expr.diff(x)) expr = x.applyfunc(sin).T * y # TODO: restore (currently returning the traspose): # assert expr.diff(x).dummy_eq(DiagMatrix(x.applyfunc(cos))*y) _check_derivative_with_explicit_matrix(expr, x, expr.diff(x)) expr = (a.T * X * b).applyfunc(sin) assert expr.diff(X).dummy_eq(a * (a.T * X * b).applyfunc(cos) * b.T) _check_derivative_with_explicit_matrix(expr, X, expr.diff(X)) expr = a.T * X.applyfunc(sin) * b assert expr.diff(X).dummy_eq( DiagMatrix(a) * X.applyfunc(cos) * DiagMatrix(b)) _check_derivative_with_explicit_matrix(expr, X, expr.diff(X)) expr = a.T * (A * X * B).applyfunc(sin) * b assert expr.diff(X).dummy_eq( A.T * DiagMatrix(a) * (A * X * B).applyfunc(cos) * DiagMatrix(b) * B.T) _check_derivative_with_explicit_matrix(expr, X, expr.diff(X)) expr = a.T * (A * X * b).applyfunc(sin) * b.T # TODO: not implemented #assert expr.diff(X) == ... #_check_derivative_with_explicit_matrix(expr, X, expr.diff(X)) expr = a.T * A * X.applyfunc(sin) * B * b assert expr.diff(X).dummy_eq( HadamardProduct(A.T * a * b.T * B.T, X.applyfunc(cos))) expr = a.T * (A * X.applyfunc(sin) * B).applyfunc(log) * b # TODO: wrong # assert expr.diff(X) == A.T*DiagMatrix(a)*(A*X.applyfunc(sin)*B).applyfunc(Lambda(k, 1/k))*DiagMatrix(b)*B.T expr = a.T * (X.applyfunc(sin)).applyfunc(log) * b
def test_convert_array_to_hadamard_products(): expr = HadamardProduct(M, N) cg = convert_matrix_to_array(expr) ret = convert_array_to_matrix(cg) assert ret == expr expr = HadamardProduct(M, N)*P cg = convert_matrix_to_array(expr) ret = convert_array_to_matrix(cg) assert ret == expr expr = Q*HadamardProduct(M, N)*P cg = convert_matrix_to_array(expr) ret = convert_array_to_matrix(cg) assert ret == expr expr = Q*HadamardProduct(M, N.T)*P cg = convert_matrix_to_array(expr) ret = convert_array_to_matrix(cg) assert ret == expr expr = HadamardProduct(M, N)*HadamardProduct(Q, P) cg = convert_matrix_to_array(expr) ret = convert_array_to_matrix(cg) assert expr == ret expr = P.T*HadamardProduct(M, N)*HadamardProduct(Q, P) cg = convert_matrix_to_array(expr) ret = convert_array_to_matrix(cg) assert expr == ret # ArrayDiagonal should be converted cg = _array_diagonal(_array_tensor_product(M, N, Q), (1, 3), (0, 2, 4)) ret = convert_array_to_matrix(cg) expected = PermuteDims(_array_diagonal(_array_tensor_product(HadamardProduct(M.T, N.T), Q), (1, 2)), [1, 0, 2]) assert expected == ret # Special case that should return the same expression: cg = _array_diagonal(_array_tensor_product(HadamardProduct(M, N), Q), (0, 2)) ret = convert_array_to_matrix(cg) assert ret == cg # Hadamard products with traces: expr = Trace(HadamardProduct(M, N)) cg = convert_matrix_to_array(expr) ret = convert_array_to_matrix(cg) assert ret == Trace(HadamardProduct(M.T, N.T)) expr = Trace(A*HadamardProduct(M, N)) cg = convert_matrix_to_array(expr) ret = convert_array_to_matrix(cg) assert ret == Trace(HadamardProduct(M, N)*A) expr = Trace(HadamardProduct(A, M)*N) cg = convert_matrix_to_array(expr) ret = convert_array_to_matrix(cg) assert ret == Trace(HadamardProduct(M.T, N)*A) # These should not be converted into Hadamard products: cg = _array_diagonal(_array_tensor_product(M, N), (0, 1, 2, 3)) ret = convert_array_to_matrix(cg) assert ret == cg cg = _array_diagonal(_array_tensor_product(A), (0, 1)) ret = convert_array_to_matrix(cg) assert ret == cg cg = _array_diagonal(_array_tensor_product(M, N, P), (0, 2, 4), (1, 3, 5)) assert convert_array_to_matrix(cg) == HadamardProduct(M, N, P) cg = _array_diagonal(_array_tensor_product(M, N, P), (0, 3, 4), (1, 2, 5)) assert convert_array_to_matrix(cg) == HadamardProduct(M, P, N.T) cg = _array_diagonal(_array_tensor_product(I, I1, x), (1, 4), (3, 5)) assert convert_array_to_matrix(cg) == DiagMatrix(x)
def convert_matrix_to_array(expr: Basic) -> Basic: if isinstance(expr, MatMul): args_nonmat = [] args = [] for arg in expr.args: if isinstance(arg, MatrixExpr): args.append(arg) else: args_nonmat.append(convert_matrix_to_array(arg)) contractions = [(2*i+1, 2*i+2) for i in range(len(args)-1)] scalar = _array_tensor_product(*args_nonmat) if args_nonmat else S.One if scalar == 1: tprod = _array_tensor_product( *[convert_matrix_to_array(arg) for arg in args]) else: tprod = _array_tensor_product( scalar, *[convert_matrix_to_array(arg) for arg in args]) return _array_contraction( tprod, *contractions ) elif isinstance(expr, MatAdd): return _array_add( *[convert_matrix_to_array(arg) for arg in expr.args] ) elif isinstance(expr, Transpose): return _permute_dims( convert_matrix_to_array(expr.args[0]), [1, 0] ) elif isinstance(expr, Trace): inner_expr: MatrixExpr = convert_matrix_to_array(expr.arg) # type: ignore return _array_contraction(inner_expr, (0, len(inner_expr.shape) - 1)) elif isinstance(expr, Mul): return _array_tensor_product(*[convert_matrix_to_array(i) for i in expr.args]) elif isinstance(expr, Pow): base = convert_matrix_to_array(expr.base) if (expr.exp > 0) == True: return _array_tensor_product(*[base for i in range(expr.exp)]) else: return expr elif isinstance(expr, MatPow): base = convert_matrix_to_array(expr.base) if expr.exp.is_Integer != True: b = symbols("b", cls=Dummy) return ArrayElementwiseApplyFunc(Lambda(b, b**expr.exp), convert_matrix_to_array(base)) elif (expr.exp > 0) == True: return convert_matrix_to_array(MatMul.fromiter(base for i in range(expr.exp))) else: return expr elif isinstance(expr, HadamardProduct): tp = _array_tensor_product(*[convert_matrix_to_array(arg) for arg in expr.args]) diag = [[2*i for i in range(len(expr.args))], [2*i+1 for i in range(len(expr.args))]] return _array_diagonal(tp, *diag) elif isinstance(expr, HadamardPower): base, exp = expr.args if isinstance(exp, Integer) and exp > 0: return convert_matrix_to_array(HadamardProduct.fromiter(base for i in range(exp))) else: d = Dummy("d") return ArrayElementwiseApplyFunc(Lambda(d, d**exp), base) elif isinstance(expr, KroneckerProduct): kp_args = [convert_matrix_to_array(arg) for arg in expr.args] permutation = [2*i for i in range(len(kp_args))] + [2*i + 1 for i in range(len(kp_args))] return Reshape(_permute_dims(_array_tensor_product(*kp_args), permutation), expr.shape) else: return expr
def test_arrayexpr_convert_matrix_to_array(): expr = M * N result = ArrayContraction(ArrayTensorProduct(M, N), (1, 2)) assert convert_matrix_to_array(expr) == result expr = M * N * M result = _array_contraction(ArrayTensorProduct(M, N, M), (1, 2), (3, 4)) assert convert_matrix_to_array(expr) == result expr = Transpose(M) assert convert_matrix_to_array(expr) == PermuteDims(M, [1, 0]) expr = M * Transpose(N) assert convert_matrix_to_array(expr) == _array_contraction( _array_tensor_product(M, PermuteDims(N, [1, 0])), (1, 2)) expr = 3 * M * N res = convert_matrix_to_array(expr) rexpr = convert_array_to_matrix(res) assert expr == rexpr expr = 3 * M + N * M.T * M + 4 * k * N res = convert_matrix_to_array(expr) rexpr = convert_array_to_matrix(res) assert expr == rexpr expr = Inverse(M) * N rexpr = convert_array_to_matrix(convert_matrix_to_array(expr)) assert expr == rexpr expr = M**2 rexpr = convert_array_to_matrix(convert_matrix_to_array(expr)) assert expr == rexpr expr = M * (2 * N + 3 * M) res = convert_matrix_to_array(expr) rexpr = convert_array_to_matrix(res) assert expr == rexpr expr = Trace(M) result = ArrayContraction(M, (0, 1)) assert convert_matrix_to_array(expr) == result expr = 3 * Trace(M) result = ArrayContraction(ArrayTensorProduct(3, M), (0, 1)) assert convert_matrix_to_array(expr) == result expr = 3 * Trace(Trace(M) * M) result = ArrayContraction(ArrayTensorProduct(3, M, M), (0, 1), (2, 3)) assert convert_matrix_to_array(expr) == result expr = 3 * Trace(M)**2 result = ArrayContraction(ArrayTensorProduct(3, M, M), (0, 1), (2, 3)) assert convert_matrix_to_array(expr) == result expr = HadamardProduct(M, N) result = ArrayDiagonal(ArrayTensorProduct(M, N), (0, 2), (1, 3)) assert convert_matrix_to_array(expr) == result expr = HadamardProduct(M * N, N * M) result = ArrayDiagonal( ArrayContraction(ArrayTensorProduct(M, N, N, M), (1, 2), (5, 6)), (0, 2), (1, 3)) assert convert_matrix_to_array(expr) == result expr = HadamardPower(M, 2) result = ArrayDiagonal(ArrayTensorProduct(M, M), (0, 2), (1, 3)) assert convert_matrix_to_array(expr) == result expr = HadamardPower(M * N, 2) result = ArrayDiagonal( ArrayContraction(ArrayTensorProduct(M, N, M, N), (1, 2), (5, 6)), (0, 2), (1, 3)) assert convert_matrix_to_array(expr) == result expr = HadamardPower(M, n) d0 = Dummy("d0") result = ArrayElementwiseApplyFunc(Lambda(d0, d0**n), M) assert convert_matrix_to_array(expr).dummy_eq(result) expr = M**2 assert isinstance(expr, MatPow) assert convert_matrix_to_array(expr) == ArrayContraction( ArrayTensorProduct(M, M), (1, 2)) expr = a.T * b cg = convert_matrix_to_array(expr) assert cg == ArrayContraction(ArrayTensorProduct(a, b), (0, 2))