def _eval_trace(self): from sympy.matrices.expressions.trace import Trace from sympy import Sum return Trace(self).rewrite(Sum).doit()
def _eval_trace(self): from sympy.matrices.expressions.trace import Trace return conjugate(Trace(self.arg))
def _eval_trace(self): from sympy.matrices.expressions.trace import Trace return Trace._eval_rewrite_as_Sum(Trace(self)).doit()
def _eval_trace(self): if self.rowblocksizes == self.colblocksizes: return Add( *[Trace(self.blocks[i, i]) for i in range(self.blockshape[0])]) raise NotImplementedError( "Can't perform trace of irregular blockshape")
def identify_hadamard_products(expr: tUnion[ArrayContraction, ArrayDiagonal]): editor: _EditArrayContraction = _EditArrayContraction(expr) map_contr_to_args: tDict[FrozenSet, List[_ArgE]] = defaultdict(list) map_ind_to_inds: tDict[Optional[int], int] = defaultdict(int) for arg_with_ind in editor.args_with_ind: for ind in arg_with_ind.indices: map_ind_to_inds[ind] += 1 if None in arg_with_ind.indices: continue map_contr_to_args[frozenset(arg_with_ind.indices)].append(arg_with_ind) k: FrozenSet[int] v: List[_ArgE] for k, v in map_contr_to_args.items(): make_trace: bool = False if len(k) == 1 and next(iter(k)) >= 0 and sum( [next(iter(k)) in i for i in map_contr_to_args]) == 1: # This is a trace: the arguments are fully contracted with only one # index, and the index isn't used anywhere else: make_trace = True first_element = S.One elif len(k) != 2: # Hadamard product only defined for matrices: continue if len(v) == 1: # Hadamard product with a single argument makes no sense: continue for ind in k: if map_ind_to_inds[ind] <= 2: # There is no other contraction, skip: continue def check_transpose(x): x = [i if i >= 0 else -1 - i for i in x] return x == sorted(x) # Check if expression is a trace: if all([map_ind_to_inds[j] == len(v) and j >= 0 for j in k]) and all([j >= 0 for j in k]): # This is a trace make_trace = True first_element = v[0].element if not check_transpose(v[0].indices): first_element = first_element.T hadamard_factors = v[1:] else: hadamard_factors = v # This is a Hadamard product: hp = hadamard_product(*[ i.element if check_transpose(i.indices) else Transpose(i.element) for i in hadamard_factors ]) hp_indices = v[0].indices if not check_transpose(hadamard_factors[0].indices): hp_indices = list(reversed(hp_indices)) if make_trace: hp = Trace(first_element * hp.T)._normalize() hp_indices = [] editor.insert_after(v[0], _ArgE(hp, hp_indices)) for i in v: editor.args_with_ind.remove(i) return editor.to_array_contraction()
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)) expr = KroneckerProduct(A, B) cg = convert_matrix_to_array(expr) assert cg == Reshape(PermuteDims(ArrayTensorProduct(A, B), [0, 2, 1, 3]), (k**2, k**2)) expr = KroneckerProduct(A, B, C, D) cg = convert_matrix_to_array(expr) assert cg == Reshape( PermuteDims(ArrayTensorProduct(A, B, C, D), [0, 2, 4, 6, 1, 3, 5, 7]), (k**4, k**4))
def _a2m_trace(arg): if isinstance(arg, _CodegenArrayAbstract): return _array_contraction(arg, (0, 1)) else: from sympy.matrices.expressions.trace import Trace return Trace(arg)
def density(self, expr): n, ZGSE = self.dimension, self.normalization_constant h_pspace = RandomMatrixPSpace('P', model=self) H = RandomMatrixSymbol('H', n, n, pspace=h_pspace) return Lambda(H, exp(-S(n) * Trace(H**2)) / ZGSE)(expr)
def normalization_constant(self): n = self.dimension _H = MatrixSymbol('_H', n, n) return Integral(exp(-S(n) * Trace(_H**2)))
def test_mixed_deriv_mixed_expressions(): expr = 3 * Trace(A) assert expr.diff(A) == 3 * Identity(k) expr = k deriv = expr.diff(A) assert isinstance(deriv, ZeroMatrix) assert deriv == ZeroMatrix(k, k) expr = Trace(A)**2 assert expr.diff(A) == (2 * Trace(A)) * Identity(k) expr = Trace(A) * A I = Identity(k) assert expr.diff(A) == ArrayAdd( ArrayTensorProduct(I, A), PermuteDims(ArrayTensorProduct(Trace(A) * I, I), Permutation(3)(1, 2))) expr = Trace(Trace(A) * A) assert expr.diff(A) == (2 * Trace(A)) * Identity(k) expr = Trace(Trace(Trace(A) * A) * A) assert expr.diff(A) == (3 * Trace(A)**2) * Identity(k)
def test_matrix_derivatives_of_traces(): expr = Trace(A) * A I = Identity(k) assert expr.diff(A) == ArrayAdd( ArrayTensorProduct(I, A), PermuteDims(ArrayTensorProduct(Trace(A) * I, I), Permutation(3)(1, 2))) 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)