2

I'm currently trying to find a way to eliminate from a square matrix of generic dimension the duplicate (up to sign) rows and columns, obtaining a smaller dimensional matrix. I searched around here but I couldn't find an answer, neither I managed to combine methods for list manipulation in order to arrive at my result.

I'll make an example in order to clarify. Suppose I have a matrix of this form: $$ \left(\begin{array}{cccccc} x_1 & w_2 & -x_1 & -w_1 & -w_2 & w_1\\ z_2 & x_2 & -z_2 & z_1 & -x_2 & -z_1 \\ -x_1 & -w_2 & x_1 & w_1 & w_2 & -w_1\\ -y_2 & y_1 & y_2 & x_3 & -y_1 & -x_3\\ z_2 & x_2 & -z_2 & z_1 & -x_2 & -z_1\\ y_2 & -y_1 & -y_2 & -x_3 & y_1 & x_3\\ \end{array} \right) $$

I want to eliminate rows and columns 3,5,6, (copies of 1,2,4) ending up with the matrix

$$ \left(\begin{array}{ccc} x_1 & w_2 & -w_1\\ z_2 & x_2 & z_1\\ -y_2 & y_1 & x_3\\ \end{array} \right) $$

I would like to implement this operation so that it can act on matrices of arbitrary dimension.

Thank you very much!

Stefano

Stefano
  • 23
  • 3
  • 1
    Can you post the matrix in Mathematica syntax as well please? People won't want to re-type it. DeleteDuplicates with a custom comparison function might work. – Szabolcs May 16 '14 at 16:10
  • @Szabolcs: the matrices I am using are generated by a custom antisymmetrized tensor product, it's quite long to write down. Anyway, the elements can be whatever, the matrix I used is just an example. The problem with DeleteDuplicates is that, even if I can tell him to eliminate both equal and opposite elements, it eliminates the elements, while I'd like to eliminate rows and columns. For example my matrix might contain a lot of zeroes and not all of them should be eliminated. – Stefano May 19 '14 at 11:44
  • To those who voted to close: it is not too difficult to copy the array into Mathematica; right click and select Show Math As > MathML Code, copy and paste into Mathematica, and let it interpret the input. Evaluate the cell and let it read TraditionalForm data. Done. – Mr.Wizard May 22 '14 at 01:47

2 Answers2

4
dd = DeleteDuplicates[#, SameQ[Abs[#1], Abs[#2]] &] &

Transpose@dd@Transpose@dd@
    {{x1, w2, -x1, -w1, -w2, w1}, 
     {z2, x2, -z2, z1, -x2, -z1}, 
     {-x1, -w2, x1, w1, w2, -w1}, 
     {-y2, y1, y2,  x3, -y1, -x3}, 
     {z2, x2, -z2, z1, -x2, -z1}, 
     {y2, -y1, -y2, -x3, y1, x3}}

Mathematica graphics

Sjoerd C. de Vries
  • 65,815
  • 14
  • 188
  • 323
2

Using the core of myOrdering from here:

fn =
  Module[{first, abs = Abs[#]},
    first[a_] := First /@ GatherBy[Ordering@a, a[[#]] &] // Sort;
    #[[first @ abs, first[abs\[Transpose]]]]
  ] &;

fn @ a // MatrixForm

$\left( \begin{array}{ccc} x_1 & w_2 & -w_1 \\ z_2 & x_2 & z_1 \\ -y_2 & y_1 & x_3 \end{array} \right)$

For an explanation of why this is superior to DeleteDuplicates see: How to represent a list as a cycle

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • Thank you! It really works wonder.

    I have only one question more, I noticed that this method only works if the entries of the matrix are monomials. It might happen that my matrix contains polynomials, such as $\frac{1}{2}(x_1+z_2)$, for example. Is it possible to do something about it?

    – Stefano May 22 '14 at 11:43
  • @Stefano Glad I could help, and thanks for the Accept. So you want -(1/2) (x1 + z2) and (1/2) (x1 + z2) to be equivalent, correct? Please try using abs = # /. -x_ :> x instead. (Depending on your expressions you might need more than this; let me know.) – Mr.Wizard May 23 '14 at 08:04
  • I tried the substitution and it works perfectly! It only seems to have problems when both letters and numerical factors appear together, but this is not an issue, as I can easily eliminate the numerical factors. Thank you again for your help! – Stefano May 23 '14 at 15:52