Using Mathematica to Automatically Reveal Matrix Structure
I spend a lot of time looking at larger matric开发者_如何学编程es (10x10, 20x20, etc) which usually have some structure, but it is difficult to quickly determine the structure of them as they get larger. Ideally, I'd like to have Mathematica automatically generate some representation of a matrix that will highlight its structure. For instance,
(A = {{1, 2 + 3 I}, {2 - 3 I, 4}}) // StructureForm
would give
{{a, b}, {Conjugate[b], c}}
or even
{{a, b + c I}, {b - c I, d}}
is acceptable. A somewhat naive implementation
StructureForm[M_?MatrixQ] :=
MatrixForm @ Module[
{pos, chars},
pos = Reap[
Map[Sow[Position[M, #1], #1] &, M, {2}], _,
Union[Flatten[#2, 1]] &
][[2]]; (* establishes equality relationship *)
chars = CharacterRange["a", "z"][[;; Length @ pos ]];
SparseArray[Flatten[Thread /@ Thread[pos -> chars] ], Dimensions[M]]
]
works only for real numeric matrices, e.g.
StructureForm @ {{1, 2}, {2, 3}} == {{a, b}, {b, c}}
Obviously, I need to define what relationships I think may exist (equality, negation, conjugate, negative conjugate, etc.), but I'm not sure how to establish that these relationships exist, at least in a clean manner. And, once I have the relationships, the next question is how to determine which is the simplest, in some sense? Any thoughts?
One possibility that comes to mind is for each pair of elements generate a triple relating their positions, like {{1,2}, Conjugate, {2,1}}
for A
, above, then it becomes amenable to graph algorithms.
Edit: Incidentally, my inspiration is from the Matrix Algorithms series (1, 2) by Stewart.
We can start by defining the relationships that we want to recognize:
ClearAll@relationship
relationship[a_ -> sA_, b_ -> sB_] /; b == a := b -> sA
relationship[a_ -> sA_, b_ -> sB_] /; b == -a := b -> -sA
relationship[a_ -> sA_, b_ -> sB_] /; b == Conjugate[a] := b -> SuperStar[sA]
relationship[a_ -> sA_, b_ -> sB_] /; b == -Conjugate[a] := b -> -SuperStar[sA]
relationship[_, _] := Sequence[]
The form in which these relationships are expressed is convenient for the definition of structureForm
:
ClearAll@structureForm
structureForm[matrix_?MatrixQ] :=
Module[{values, rules, pairs, inferences}
, values = matrix // Flatten // DeleteDuplicates
; rules = Thread[Rule[values, CharacterRange["a", "z"][[;; Length@values]]]]
; pairs = rules[[#]]& /@ Select[Tuples[Range[Length@values], 2], #[[1]] < #[[2]]&]
; inferences = relationship @@@ pairs
; matrix /. inferences ~Join~ rules
]
In a nutshell, this function checks each possible pair of values in the matrix inferring a substitution rule whenever a pair matches a defined relationship. Note how the relationship definitions are expressed in terms of pairs of substitution rules in the form value -> name. Matrix values are assigned letter names, proceeding from left-to-right, top-to-bottom. Redundant inferred relationships are ignored assuming a precedence in that same order.
Beware that the function will run out of names after it finds 26 distinct values -- an alternate name-assignment strategy will be needed if that is an issue. Also, the names are being represented as strings instead of symbols. This conveniently dodges any unwanted bindings of the single-letter symbols names. If symbols are preferred, it would be trivial to apply the Symbol
function to each name.
Here are some sample uses of the function:
In[31]:= structureForm @ {{1, 2 + 3 I}, {2 - 3 I, 4}}
Out[31]= {{"a", "b"}, {SuperStar["b"], "d"}}
In[32]:= $m = a + b I /. a | b :> RandomInteger[{-2, 2}, {10, 10}];
$m // MatrixForm
$m // structureForm // MatrixForm
Have you tried looking at the eigenvalues? The eigenvalues reveal a great deal of information on the structure and symmetry of matrices and are standard in statistical analysis of datasets. For e.g.,
- Hermitian/symmetric eigenvalues have real eigenvalues.
- Positive semi-definite matrices have non-negative eigenvalues and vice versa.
- Rotation matrices have complex eigenvalues.
- Circulant matrices have eigenvalues that are simply the DFT of the first row. The beauty of circulant matrices is that every circulant matrix has the same set of eigenvectors. In some cases, these results (circulant) can be extended to Toeplitz matrices.
If you're dealing with matrices that are random (an experimental observation can be modeled as a random matrix), you could also read up on random matrix theory, which relates the distributions of eigenvalues to the underlying symmetries in the matrix and the statistical distributions of elements. Specifically,
- The eigenvalue distribution of symmetric/hermitian Gaussian matrices is a [semicircle]
- Eigenvalue distributions of Wishart matrices (if
A
is a random Gaussian matrix,W=AA'
is a Wishart matrix) are given by the Marcenko-Pastur distribution
Also, the differences (spacings) between the eigenvalues also convey information about the matrix.
I'm not sure if the structure that you're looking for is like a connected graph within the matrix or something similar... I presume random matrix theory (which is more general and vast than those links will ever tell you) has some results in this regard.
Perhaps this is not really what you were looking for, but afaik, there is no one stop solution to getting the structure of a matrix. You'll have to use multiple tools to nail it down, and if I were to do it, eigenvalues would be my first pick.
精彩评论