2
$\begingroup$

I have to create a 900x900 matrix and then diagonalize it. It is something similar to the below matrix. The value of a,b,c,d....up to 900 values (which are the first column and row) are the number. The pattern of calculation the rest elements of the matrix is showing here (here I take an example of multiplying 3x3 matrix. the first element is a*a and so on). On top of my head, I can use Excel to calculate but it is gonna take me a long long time. Do you guys have any suggestions about the method of doing it more effectively? I would really appreciate it.

{{state, a, b, c}, 
 {a, a*a, a*b, a*c}, 
 {b, b*a, b*b, b*c}, 
 {c, c*a, c*b, c*c}}
$\endgroup$
  • $\begingroup$ One possibility: Outer[Times, {state, a, b, c}, {state, a, b, c}] /. {state^2 -> state, state -> 1} Only works if you don't yet have numbers, but it can be adapted. Can we get more information about the entries? Are they symbolic? NUmeric? Etc. $\endgroup$ – march Jul 22 '16 at 20:59
  • 2
    $\begingroup$ It looks as if your matrix will have at most rank 2. It should be possible to generate a symbolic diagonalisation for it without ever building the full matrix. It might help if you explain what you plan to do with the diagonalised form. $\endgroup$ – mikado Jul 22 '16 at 21:04
3
$\begingroup$

With Times:

avec = Array[a, 4];
m = Outer[Times, avec, avec] /. {a[1] -> 1};
m[[1, 1]] = s;
MatrixForm[m]
Eigenvalues[m]

enter image description here

Here a[2] is your a, a[3] is your b, etc. Change the 4 to 900 if you wish. There are two nonzero eigenvalues.

$\endgroup$
  • $\begingroup$ Thank you, do you have any way that I can import the value of a[n] (n from 1 to 900) from Excel. As far as I understand, for you method, I have to assign each value for a[1], a[2]...up to 900 step be step, haven't I? $\endgroup$ – Quang Phan Jul 22 '16 at 21:10
  • $\begingroup$ Import from an excel file using Import. $\endgroup$ – bill s Jul 22 '16 at 21:13
  • $\begingroup$ yeah I know how to import it into mathematica but how to assign these 900 numbers to a[1], a[2], a[3]....a[n] at the same time instead of edit it one by one? $\endgroup$ – Quang Phan Jul 22 '16 at 21:18
  • $\begingroup$ say your imported data is a length 900 list called dat. Then you can assign: Table[a[i] = dat[[i]], {i, 900}] $\endgroup$ – bill s Jul 22 '16 at 21:44
  • 1
    $\begingroup$ @QuangPhan Try test = Flatten[Import["Documents/test.xlsx"]]. There is an extra List for some reason. $\endgroup$ – JungHwan Min Jul 23 '16 at 0:07
6
$\begingroup$
yourlist = {a, b, c};
mat = ReplacePart[Outer[Times, #, #]&@Prepend[yourlist, 1], {1, 1} -> state]

enter image description here

Change yourlist to the list of your interest.

Or, taking @mikado 's idea of symbolically diagonalizing:

matfunc[1, 1] = state;
matfunc[1, a_Integer] := yourlist[[a - 1]];
matfunc[a_Integer, 1] := yourlist[[a - 1]];
matfunc[a_Integer, b_Integer] := yourlist[[a - 1]] yourlist[[b - 1]];
$\endgroup$
1
$\begingroup$

The matrix desired is at most rank two and can be easily expressed as the product of a matrix and its transpose. I will number the elements for convenience and assume that state > 1 (otherwise we have imaginary elements, which would require further thought).

n = 3;
v1 = Prepend[Array[a, n], 1];
v2 = Prepend[Array[0 &, n], Sqrt[state - 1]];
M1 = Transpose[{v1, v2}];

The desired matrix is given by

M = M1.Transpose[M1]

(* {{state, a[1],      a[2],       a[3]},
    {a[1],  a[1]^2,    a[1] a[2],  a[1] a[3]},
    {a[2],  a[1] a[2], a[2]^2,     a[2] a[3]},
    {a[3],  a[1] a[3], a[2] a[3],  a[3]^2}} *)

This can then be diagonalised. Symbolically this is messy so for the demonstration I will assume some arbitrary values:

testcase = {state -> 13., a[i_] -> i^2 - 7.};

The matrix M1 can be factorised using

{U, S, V} = SingularValueDecomposition[M1 /. testcase, 2];

giving M1 == U.S.Transpose[V] (for real V). Note that U and V are orthonormal and S is diagonal, so that M == M1.Transpose[M1] == U.(S.S).Transpose[U] is the diagonalisation.

This can be verified by evaluating

U.(S.S).Transpose[U] - M /. testcase // Chop
(* {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}} *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.