Пример #1
0
def test_matrix_derivative_with_inverse():

    # Cookbook example 61:
    expr = a.T * Inverse(X) * b
    assert expr.diff(X) == -Inverse(X).T * a * b.T * Inverse(X).T

    # Cookbook example 63:
    expr = Trace(A * Inverse(X) * B)
    assert expr.diff(X) == -(X**(-1) * B * A * X**(-1)).T

    # Cookbook example 64:
    expr = Trace(Inverse(X + A))
    assert expr.diff(X) == -(Inverse(X + A) * Inverse(X + A)).T
Пример #2
0
def affine_shape_parametrization_from_vertices_mapping(dim, vertices_mapping):
    # Check if the "identity" string is provided, and return this trivial case
    if isinstance(vertices_mapping, str):
        assert vertices_mapping.lower() == "identity"
        return tuple(["x[" + str(i) + "]" for i in range(dim)])
    # Get a sympy symbol for mu
    mu = strings_to_sympy_symbolic_parameters(
        itertools.chain(*vertices_mapping.values()), MatrixSymbol)
    # Convert vertices from string to symbols
    vertices_mapping_symbolic = dict()
    for (reference_vertex, deformed_vertex) in vertices_mapping.items():
        assert isinstance(reference_vertex,
                          Matrix) == isinstance(deformed_vertex, Matrix)
        if isinstance(reference_vertex, Matrix):
            reference_vertex_symbolic = reference_vertex
            deformed_vertex_symbolic = deformed_vertex
        else:
            reference_vertex_symbolic = python_string_to_sympy(
                reference_vertex, None, None)
            deformed_vertex_symbolic = python_string_to_sympy(
                deformed_vertex, None, mu)
        assert reference_vertex_symbolic not in vertices_mapping_symbolic
        vertices_mapping_symbolic[
            reference_vertex_symbolic] = deformed_vertex_symbolic
    # Find A and b such that x_o = A x + b for all (x, x_o) in vertices_mapping
    lhs = zeros(dim + dim**2, dim + dim**2)
    rhs = zeros(dim + dim**2, 1)
    for (offset,
         (reference_vertex,
          deformed_vertex)) in enumerate(vertices_mapping_symbolic.items()):
        for i in range(dim):
            rhs[offset * dim + i] = deformed_vertex[i]
            lhs[offset * dim + i, i] = 1
            for j in range(dim):
                lhs[offset * dim + i, (i + 1) * dim + j] = reference_vertex[j]
    solution = Inverse(lhs) * rhs
    b = zeros(dim, 1)
    for i in range(dim):
        b[i] = solution[i]
    A = zeros(dim, dim)
    for i in range(dim):
        for j in range(dim):
            A[i, j] = solution[dim + i * dim + j]
    # Convert into an expression
    x = sympy_symbolic_coordinates(dim, MatrixListSymbol)
    x_o = A * x + b
    return tuple([str(x_o[i]).replace(", 0]", "]") for i in range(dim)])
Пример #3
0
def test_matrix_derivative_with_inverse():

    # Cookbook example 61:
    expr = a.T * Inverse(X) * b
    assert expr.diff(X) == -Inverse(X).T * a * b.T * Inverse(X).T

    # Cookbook example 62:
    expr = Determinant(Inverse(X))
    # Not implemented yet:
    # assert expr.diff(X) == -Determinant(X.inv())*(X.inv()).T

    # Cookbook example 63:
    expr = Trace(A * Inverse(X) * B)
    assert expr.diff(X) == -(X**(-1) * B * A * X**(-1)).T

    # Cookbook example 64:
    expr = Trace(Inverse(X + A))
    assert expr.diff(X) == -(Inverse(X + A)).T**2
Пример #4
0
def test_parsing_of_matrix_expressions():

    expr = M * N
    assert parse_matrix_expression(expr) == CodegenArrayContraction(
        CodegenArrayTensorProduct(M, N), (1, 2))

    expr = Transpose(M)
    assert parse_matrix_expression(expr) == CodegenArrayPermuteDims(M, [1, 0])

    expr = M * Transpose(N)
    assert parse_matrix_expression(expr) == CodegenArrayContraction(
        CodegenArrayTensorProduct(M, CodegenArrayPermuteDims(N, [1, 0])),
        (1, 2))

    expr = 3 * M * N
    res = parse_matrix_expression(expr)
    rexpr = recognize_matrix_expression(res)
    assert expr == rexpr

    expr = 3 * M + N * M.T * M + 4 * k * N
    res = parse_matrix_expression(expr)
    rexpr = recognize_matrix_expression(res)
    assert expr == rexpr

    expr = Inverse(M) * N
    rexpr = recognize_matrix_expression(parse_matrix_expression(expr))
    assert expr == rexpr

    expr = M**2
    rexpr = recognize_matrix_expression(parse_matrix_expression(expr))
    assert expr == rexpr

    expr = M * (2 * N + 3 * M)
    res = parse_matrix_expression(expr)
    rexpr = recognize_matrix_expression(res)
    assert expr.expand() == rexpr.doit()

    expr = Trace(M)
    result = CodegenArrayContraction(M, (0, 1))
    assert parse_matrix_expression(expr) == result
Пример #5
0
def test_matrix_derivatives_of_traces():

    expr = Trace(A) * A
    assert expr.diff(A) == Derivative(Trace(A) * A, A)
    assert expr[i, j].diff(
        A[m, n]).doit() == (KDelta(i, m) * KDelta(j, n) * Trace(A) +
                            KDelta(m, n) * A[i, j])

    ## First order:

    # Cookbook example 99:
    expr = Trace(X)
    assert expr.diff(X) == Identity(k)
    assert expr.rewrite(Sum).diff(X[m, n]).doit() == KDelta(m, n)

    # Cookbook example 100:
    expr = Trace(X * A)
    assert expr.diff(X) == A.T
    assert expr.rewrite(Sum).diff(X[m, n]).doit() == A[n, m]

    # Cookbook example 101:
    expr = Trace(A * X * B)
    assert expr.diff(X) == A.T * B.T
    assert expr.rewrite(Sum).diff(X[m, n]).doit().dummy_eq((A.T * B.T)[m, n])

    # Cookbook example 102:
    expr = Trace(A * X.T * B)
    assert expr.diff(X) == B * A

    # Cookbook example 103:
    expr = Trace(X.T * A)
    assert expr.diff(X) == A

    # Cookbook example 104:
    expr = Trace(A * X.T)
    assert expr.diff(X) == A

    # Cookbook example 105:
    # TODO: TensorProduct is not supported
    #expr = Trace(TensorProduct(A, X))
    #assert expr.diff(X) == Trace(A)*Identity(k)

    ## Second order:

    # Cookbook example 106:
    expr = Trace(X**2)
    assert expr.diff(X) == 2 * X.T

    # Cookbook example 107:
    expr = Trace(X**2 * B)
    assert expr.diff(X) == (X * B + B * X).T
    expr = Trace(MatMul(X, X, B))
    assert expr.diff(X) == (X * B + B * X).T

    # Cookbook example 108:
    expr = Trace(X.T * B * X)
    assert expr.diff(X) == B * X + B.T * X

    # Cookbook example 109:
    expr = Trace(B * X * X.T)
    assert expr.diff(X) == B * X + B.T * X

    # Cookbook example 110:
    expr = Trace(X * X.T * B)
    assert expr.diff(X) == B * X + B.T * X

    # Cookbook example 111:
    expr = Trace(X * B * X.T)
    assert expr.diff(X) == X * B.T + X * B

    # Cookbook example 112:
    expr = Trace(B * X.T * X)
    assert expr.diff(X) == X * B.T + X * B

    # Cookbook example 113:
    expr = Trace(X.T * X * B)
    assert expr.diff(X) == X * B.T + X * B

    # Cookbook example 114:
    expr = Trace(A * X * B * X)
    assert expr.diff(X) == A.T * X.T * B.T + B.T * X.T * A.T

    # Cookbook example 115:
    expr = Trace(X.T * X)
    assert expr.diff(X) == 2 * X
    expr = Trace(X * X.T)
    assert expr.diff(X) == 2 * X

    # Cookbook example 116:
    expr = Trace(B.T * X.T * C * X * B)
    assert expr.diff(X) == C.T * X * B * B.T + C * X * B * B.T

    # Cookbook example 117:
    expr = Trace(X.T * B * X * C)
    assert expr.diff(X) == B * X * C + B.T * X * C.T

    # Cookbook example 118:
    expr = Trace(A * X * B * X.T * C)
    assert expr.diff(X) == A.T * C.T * X * B.T + C * A * X * B

    # Cookbook example 119:
    expr = Trace((A * X * B + C) * (A * X * B + C).T)
    assert expr.diff(X) == 2 * A.T * (A * X * B + C) * B.T

    # Cookbook example 120:
    # TODO: no support for TensorProduct.
    # expr = Trace(TensorProduct(X, X))
    # expr = Trace(X)*Trace(X)
    # expr.diff(X) == 2*Trace(X)*Identity(k)

    # Higher Order

    # Cookbook example 121:
    expr = Trace(X**k)
    #assert expr.diff(X) == k*(X**(k-1)).T

    # Cookbook example 122:
    expr = Trace(A * X**k)
    #assert expr.diff(X) == # Needs indices

    # Cookbook example 123:
    expr = Trace(B.T * X.T * C * X * X.T * C * X * B)
    assert expr.diff(
        X
    ) == C * X * X.T * C * X * B * B.T + C.T * X * B * B.T * X.T * C.T * X + C * X * B * B.T * X.T * C * X + C.T * X * X.T * C.T * X * B * B.T

    # Other

    # Cookbook example 124:
    expr = Trace(A * X**(-1) * B)
    assert expr.diff(X) == -Inverse(X).T * A.T * B.T * Inverse(X).T

    # Cookbook example 125:
    expr = Trace(Inverse(X.T * C * X) * A)
    # Warning: result in the cookbook is equivalent if B and C are symmetric:
    assert expr.diff(X) == -X.inv().T * A.T * X.inv() * C.inv().T * X.inv(
    ).T - X.inv().T * A * X.inv() * C.inv() * X.inv().T

    # Cookbook example 126:
    expr = Trace((X.T * C * X).inv() * (X.T * B * X))
    assert expr.diff(X) == -2 * C * X * (X.T * C * X).inv() * X.T * B * X * (
        X.T * C * X).inv() + 2 * B * X * (X.T * C * X).inv()

    # Cookbook example 127:
    expr = Trace((A + X.T * C * X).inv() * (X.T * B * X))
    # Warning: result in the cookbook is equivalent if B and C are symmetric:
    assert expr.diff(X) == B * X * Inverse(A + X.T * C * X) - C * X * Inverse(
        A + X.T * C *
        X) * X.T * B * X * Inverse(A + X.T * C * X) - C.T * X * Inverse(
            A.T + (C * X).T * X) * X.T * B.T * X * Inverse(
                A.T + (C * X).T * X) + B.T * X * Inverse(A.T + (C * X).T * X)
Пример #6
0
def test_parsing_of_matrix_expressions():

    expr = M*N
    assert parse_matrix_expression(expr) == CodegenArrayContraction(CodegenArrayTensorProduct(M, N), (1, 2))

    expr = Transpose(M)
    assert parse_matrix_expression(expr) == CodegenArrayPermuteDims(M, [1, 0])

    expr = M*Transpose(N)
    assert parse_matrix_expression(expr) == CodegenArrayContraction(CodegenArrayTensorProduct(M, CodegenArrayPermuteDims(N, [1, 0])), (1, 2))

    expr = 3*M*N
    res = parse_matrix_expression(expr)
    rexpr = recognize_matrix_expression(res)
    assert expr == rexpr

    expr = 3*M + N*M.T*M + 4*k*N
    res = parse_matrix_expression(expr)
    rexpr = recognize_matrix_expression(res)
    assert expr == rexpr

    expr = Inverse(M)*N
    rexpr = recognize_matrix_expression(parse_matrix_expression(expr))
    assert expr == rexpr

    expr = M**2
    rexpr = recognize_matrix_expression(parse_matrix_expression(expr))
    assert expr == rexpr

    expr = M*(2*N + 3*M)
    res = parse_matrix_expression(expr)
    rexpr = recognize_matrix_expression(res)
    assert expr == rexpr

    expr = Trace(M)
    result = CodegenArrayContraction(M, (0, 1))
    assert parse_matrix_expression(expr) == result

    expr = 3*Trace(M)
    result = CodegenArrayContraction(CodegenArrayTensorProduct(3, M), (0, 1))
    assert parse_matrix_expression(expr) == result

    expr = 3*Trace(Trace(M) * M)
    result = CodegenArrayContraction(CodegenArrayTensorProduct(3, M, M), (0, 1), (2, 3))
    assert parse_matrix_expression(expr) == result

    expr = 3*Trace(M)**2
    result = CodegenArrayContraction(CodegenArrayTensorProduct(3, M, M), (0, 1), (2, 3))
    assert parse_matrix_expression(expr) == result

    expr = HadamardProduct(M, N)
    result = CodegenArrayDiagonal(CodegenArrayTensorProduct(M, N), (0, 2), (1, 3))
    assert parse_matrix_expression(expr) == result

    expr = HadamardPower(M, 2)
    result = CodegenArrayDiagonal(CodegenArrayTensorProduct(M, M), (0, 2), (1, 3))
    assert parse_matrix_expression(expr) == result

    expr = M**2
    assert isinstance(expr, MatPow)
    assert parse_matrix_expression(expr) == CodegenArrayContraction(CodegenArrayTensorProduct(M, M), (1, 2))
Пример #7
0
MATRIX_DIFF_RULES = {
    # e =expression, s = a list of symbols respsect to which
    # we want to differentiate
    Symbol: lambda e, s: d(e) if (e in s) else 0,
    MatrixSymbol: lambda e, s: d(e) if (e in s) else ZeroMatrix(*e.shape),
    SymmetricMatrixSymbol: lambda e, s: d(e) if (e in s) else ZeroMatrix(*e.shape),
    Add: lambda e, s: Add(*[_matDiff_apply(arg, s) for arg in e.args]),
    Mul: lambda e, s: _matDiff_apply(e.args[0], s) if len(e.args)==1 else Mul(_matDiff_apply(e.args[0],s),Mul(*e.args[1:])) + Mul(e.args[0], _matDiff_apply(Mul(*e.args[1:]),s)),
    MatAdd: lambda e, s: MatAdd(*[_matDiff_apply(arg, s) for arg in e.args]),
    MatMul: lambda e, s: _matDiff_apply(e.args[0], s) if len(e.args)==1 else MatMul(_matDiff_apply(e.args[0],s),MatMul(*e.args[1:])) + MatMul(e.args[0], _matDiff_apply(MatMul(*e.args[1:]),s)),
    Kron: lambda e, s: _matDiff_apply(e.args[0],s) if len(e.args)==1 else Kron(_matDiff_apply(e.args[0],s),Kron(*e.args[1:]))
                  + Kron(e.args[0],_matDiff_apply(Kron(*e.args[1:]),s)),
    Determinant: lambda e, s: MatMul(Determinant(e.args[0]), Trace(e.args[0].I*_matDiff_apply(e.args[0], s))), 
    # inverse always has 1 arg, so we index
    Inverse: lambda e, s: -Inverse(e.args[0]) * _matDiff_apply(e.args[0], s) * Inverse(e.args[0]),
    # trace always has 1 arg
    Trace: lambda e, s: Trace(_matDiff_apply(e.args[0], s)),
    # transpose also always has 1 arg, index
    Transpose: lambda e, s: Transpose(_matDiff_apply(e.args[0], s))
    }


def _matDiff_apply(expr, syms):
    if expr.__class__ in list(MATRIX_DIFF_RULES.keys()):
        return MATRIX_DIFF_RULES[expr.__class__](expr, syms)
    elif expr.is_constant():
        return 0
    else:
        raise TypeError("Don't know how to differentiate class %s", expr.__class__) 
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 = ArrayContraction(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) == ArrayContraction(
        ArrayTensorProduct(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 = HadamardPower(M, 2)
    result = ArrayDiagonal(ArrayTensorProduct(M, M), (0, 2), (1, 3))
    assert convert_matrix_to_array(expr) == 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))
Пример #9
0
	def _eval_inverse(self):
		inv = Inverse(self)
		inv.is_Symmetric = True
		return inv
Пример #10
0
def test_xxinv():
    assert xxinv(MatMul(D, Inverse(D), D, evaluate=False)) == \
                 MatMul(Identity(n), D, evaluate=False)