# Manipulating matrix expressions

I have some generic matrices where I know the dimensions of the matrices, but not the actual values. I'm wanting Mathematica to use matrix identities to find a more amenable form for a proof. I define the matrices here generically because I don't know how else to tell Mathematica it's a matrix, even though I don't want to do manipulation by elements.

(X = Array[Sort[x[##]] &, {3, 1}]) // MatrixForm


$$\left( \begin{array}{c} x(1,1) \\ x(1,2) \\ x(1,3) \\ \end{array} \right)$$

(\mu = Array[Sort[mu[##]] &, {3, 1}]) // MatrixForm


$$\left( \begin{array}{c} \mu (1,1) \\ \mu (1,2) \\ \mu (1,3) \\ \end{array} \right)$$

(\CapitalSigma = Array[Sort[\Sigma[##]] &, {3, 3}]) // MatrixForm


$$\left( \begin{array}{ccc} \sigma (1,1) & \sigma (1,2) & \sigma (1,3) \\ \sigma (1,2) & \sigma (2,2) & \sigma (2,3) \\ \sigma (1,3) & \sigma (2,3) & \sigma (3,3) \\ \end{array} \right)$$

I apologize for potentially mixing Greek letters with Latin (because I can't put those symbols in StackExchange code apparently, but I can in Mathematica). Note that $$\Sigma$$ is symmetric.

I have the following expression that I want Mathematica to simplify:

$$\mu_0^T \Sigma x - x^T \Sigma \mu_0$$ I expect that the two terms can be combined because I saw someone else do it, but I don't know exactly how they did it.

Thread::tdlen: Objects of unequal length in {{mu[1,1],mu[1,2],mu[1,3]}} {{sig[1,1],sig[1,2],sig[1,3]},{sig[1,2],sig[2,2],sig[2,3]},{sig[1,3],sig[2,3],sig[3,3]}} x cannot be combined.
Thread::tdlen: Objects of unequal length in Transpose[x] {sig[1,1],sig[1,2],sig[1,3]} {mu[1,1]} cannot be combined.
Thread::tdlen: Objects of unequal length in Transpose[x] {sig[1,2],sig[2,2],sig[2,3]} {mu[1,2]} cannot be combined.
General::stop: Further output of Thread::tdlen will be suppressed during this calculation.


So I have several problems here. The output of this statement won't display properly (I used TeXForm to convert but it's not working here). Second, what it does display shows the elements of the matrices instead of just the matrix symbols. When I do x.mu I don't want to see the elements of the result, but want a simplification based on the whole of the matrices. And, of course, I want to get rid of the errors.

Ideas?

• If $A^T=A$ then $x^T A y = (x^T A y)^T = y^T A^T x = y^T A x$. Oct 3, 2022 at 20:00
• @user293787 Very helpful comment, thank you! Oct 4, 2022 at 16:45

First note that MMA does not distinguish between Row/Column vectors. The rule for dot product is: last index of first object is contracted with first vector of second object.

Then a more MMA like definitions of your objects is:

xs = Array[Subscript[x, ##] &, 3];
us = Array[Subscript[u, ##] &, 3];
ss = Array[Subscript[s, Min[##], Max[##]] &, {3, 3}];


And finally:

us . ss . xs - xs . ss . us // Simplify

(* 0 *)


Discussion and references (code examples in the next sections):

In order to simplify complicated expressions made from vectors and matrices, the best method I know of, by hand or by computer, is using Einstein notation (which for your purpose might be the same as using sums with indices without the sum symbol). A matrix/vector based solution using TensorReduce is given below.

Tensor packages that simplify such tensor/matrix expressions typically use Einstein notation. A list of tensor packages can be found on this wikipedia page (I looked into one or two, use at your own risk).

The native tensor calculus functions in Mathematica do not use Einstein notation. I personally find them quite heavy to use but you can find information in the documentation (you can check the tech notes on the TensorContract page) and I show how to use TensorReduce to obtain the desired result below.

In the following I will show an example of how to achieve the simplification manually, how to achieve the same simplification automatically with TensorReduce then how to use one of the most popular tensor packages xAct to obtain the same result. The xAct package needs to be downloaded from the xAct website. That said, I also find xAct heavy so you might want to try another package in the list above.

### Mathematica assisted "manual" approach using Einstein notation

(automatic methods given in the next sections)

$$m^T S x$$ with sums: $$\Sigma_{i,j} m_i S_{i,j} x_j$$

in Einstein notation: $$m_i S^{i,j} x_j$$

$$x^T S m$$ with sums: $$\Sigma_{i,j} x_i S_{i,j} m_j$$

in Einstein notation: $$x_i S^{i,j} m_j$$

In code:

a=m[i]*S[i,j]*x[j]-x[i]*S[i,j]*m[j]


out: (* -m[j] S[i, j] x[i] + m[i] S[i, j] x[j] *)

(Notice that terms were swapped after evaluating the command)

Renaming the indices in the second term m[i] S[i, j] x[j] (note again that it is the second term after Mathematica sorted the terms) :

a=ReplaceAt[a, {i -> j, j -> i}, Cases[Position[a, i | j], {2, __}]]


out: -m[j] S[i, j] x[i] + m[j] S[j, i] x[i]

Imposing that S is symmetric:

SetAttributes[S,Orderless]


evaluating the expression when S is symmetric:

a


out: 0

### Using Tensor Reduce

\$Assumptions = {S ∈ Matrices[{d, d}, Symmetric[{1, 2}]],
x ∈ Vectors[d], m ∈ Vectors[d]};


Simplifying the expression:

x . S . m - m . S . x // TensorReduce


out: 0

or:

TensorContract[TensorProduct[x, S, m], {{1, 2}, {3, 4}}] -
TensorContract[
TensorProduct[m, S, x], {{1, 2}, {3, 4}}] // TensorReduce


out: 0

[ EDIT:

ResourceFunction["EinsteinSummation"][{{i}, {i, j}, {j}}, {x, S, m}] -
ResourceFunction["EinsteinSummation"][{{i}, {i, j}, {j}}, {m, S,
x}] // TensorReduce


out: 0

]

### Using xAct

After installing xAct, you can use the xTensor package by evaluating the command below:

<< xActxTensor


Setting up the definitions (this is the part that I feel is a bit heavy):

DefConstantSymbol[d]; (* dimension *)
DefManifold[M, d, {i, j}]; (* This is R^d for our purpose where R is the real number line *)
DefTensor[S[i, j], M, Symmetric[{i, j}]];
DefTensor[x[i], M];
DefTensor[m[i], M];


Simplifying the expression (note the -i and i notation which represents respectively down and up indices in Einstein notation):

x[-i] S[i, j] m[-j] - m[-i] S[i, j] x[-j] // ToCanonical


out: 0