使用Mathematica自动揭示矩阵结构

4

我花费大量时间查看较大的矩阵(10x10、20x20等),它们通常具有某些结构,但随着它们变得越来越大,很难快速确定它们的结构。理想情况下,我希望Mathematica自动生成一些表示矩阵的方式,以突出其结构。例如,

(A = {{1, 2 + 3 I}, {2 - 3 I, 4}}) // StructureForm

将会给予

{{a, b}, {Conjugate[b], c}}

或者甚至

{{a, b + c I}, {b - c I, d}}

是可以接受的。一个有些天真的实现

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]]
  ]

仅适用于实数矩阵,例如。

StructureForm @ {{1, 2}, {2, 3}} == {{a, b}, {b, c}}

显然,我需要定义我认为可能存在的关系(等式、否定、共轭、负共轭等),但我不确定如何建立这些关系,至少不能太复杂。一旦我有了这些关系,下一个问题是如何确定哪个是最简单的?有什么想法吗?
其中一个可能性是针对每对元素生成一个三元组,关联它们的位置,例如对于上面的A,生成{{1,2}, 共轭, {2,1}},然后可以使用图算法。
编辑:顺便提一下,我的灵感来自Stewart的矩阵算法系列 (1, 2)。

2
通常来说可能会有些困难。对于结构检查,例如是否具有假定为实数的符号变量的Hermitian性质,可以使用类似SameQ [mat,ComplexExpand [Conjugate [Transpose [mat]]]]的实用程序。如果您使用明确的Re和Im,则内置的HermitianMatrixQ也可能有所帮助。同样SymmetricMatrixQ也是如此。 - Daniel Lichtblau
@Daniel,我知道这不容易,但我想问一下。HermitianMatrixQSymmetricMatrixQ都很好,可以用来显示只有这些类型对称性的矩阵。不幸的是,通常情况下,我处理的矩阵除了具有厄米对称性外,还具有更复杂的对称性,我希望有一个工具可以显示这样的结构。绝对不是一个简单的请求。 - rcollyer
@Daniel,此外,MatrixPlotArrayPlot有时很有用,但它们无法显示符号矩阵的结构,而且很难使用它们来确定厄米性。理想情况下,我希望执行一个测试来更清楚地显示结构,而当前的工具需要多次测试。 - rcollyer
我想知道,如果矩阵的两个部分具有某种数值相似性,并不意味着它们一定是相同的结构的一部分,对吗?可以看一下 RotationMatrix[a] // structureForm ==> {{"a", "b"}, {-"b", "a"}},而 RotationMatrix[[Pi]/4] // structureForm ==> {{"a", -"a"}, {"a", "a"}} 以及 RotationMatrix[[Pi]/8] // structureForm ==> {{"a", "b"}, {-"b", "a"}}。 - Sjoerd C. de Vries
@rcollyer 这不是我的意思。当前的方法往往将数值相等等同于结构相等。然而,数值相等可能只是偶然发生,并不意味着任何结构关系。在上面的例子中,我认为_structure_应该是{a,b}而不是{a,a}(b可能等于a,但不一定相等)。 - Sjoerd C. de Vries
显示剩余4条评论
2个回答

4
我们可以从定义我们想要识别的关系开始:
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[]

这些关系的表达形式对于定义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
  ]

简而言之,此函数检查矩阵中每个可能的值对,当一对匹配到一个已定义的关系时,推断出替换规则。请注意,关系定义是以替换规则对的形式value -> name表示的。矩阵值被分配字母名称,从左到右,从上到下进行。在假定同样顺序的优先级的情况下,冗余的推断关系将被忽略。
请注意,如果找到26个不同的值,该函数将耗尽名称-分配策略的备选方案将是必需的。另外,名称被表示为字符串而不是符号。这方便地避免了单个字母符号名称的任何不必要的绑定。如果喜欢符号,则可以轻松应用Symbol函数来处理每个名称。
以下是该函数的一些示例用法:
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

enter image description here


1
+1,聪明。我喜欢使用TuplesSelect来避免重复计算一些对。顺便说一句,使用DeleteDuplicates也可以避免相等的关系,但这只是个细节问题。我喜欢使用Relationship的原因是一组函数可以传递到structureForm中,这些函数需要2个参数,并成为Relationship的条件。此外,显示条件也可以与之一起传递。我再试几天,但看起来很不错。 - rcollyer
@rcollyer 相等关系的定义只有在等式的语义与 PatternMatchQ 不同时才是必要的。试着删除这个定义,然后评估,例如 structureForm[{{1.0, 1}, {1.0, 1}}]。在任何特定的应用程序中,这可能是一个问题或不是问题。如果矩阵可以包含符号表达式,我想相等关系的定义会更加详细,可能涉及到 Reduce - WReach

3
您尝试过查看特征值吗?特征值揭示了矩阵的结构和对称性的大量信息,并且在数据集的统计分析中是标准的。例如,
1. Hermitian/对称特征值具有实特征值。 2. 正半定矩阵具有非负特征值,反之亦然。 3. 旋转矩阵具有复特征值。 4. 循环矩阵的特征值仅是第一行DFT的 DFT。循环矩阵的美妙之处在于每个循环矩阵都有相同的特征向量集。在某些情况下,这些结果(循环)可以扩展到Toeplitz矩阵。
如果您正在处理随机矩阵(实验观测可以建模为随机矩阵),您还可以阅读random matrix theory,它将特征值的分布与矩阵的基本对称性和元素的统计分布相关联。具体地说,
  1. 对称/共轭高斯矩阵的特征值分布是一个[半圆]
  2. Wishart矩阵的特征值分布(如果A是一个随机高斯矩阵,W=AA'是一个Wishart矩阵)由Marcenko-Pastur分布给出。

此外,特征值之间的差异(间距)也传达了关于矩阵的信息。

我不确定您要寻找的结构是否类似于矩阵内的连接图或类似的东西...我推测随机矩阵理论(比那些链接更一般和广泛)在这方面有一些结果。

也许这并不是您正在寻找的内容,但据我所知,没有一个停止解决矩阵结构的解决方案。您将不得不使用多个工具来确定它,如果我要做的话,特征值会是我的首选。


@RM,如果矩阵是纯数值的话,你说的特征值/向量是正确的选择。然而,如果矩阵是符号的话,由于公式的复杂性,特征值就不那么有用了。有时候,仅仅能够看一下数值的排列方式也是有帮助的。我知道这不能是唯一的工具,但拥有它会很好。 - rcollyer
1
@rcollyer:你说的特征值在数值计算中非常有用,这一点是正确的。然而,我不同意特征值在符号矩阵中没有用处。是的,方程会变得更加混乱,随着矩阵大小的增长,它可能会变得更加困难。但对于像你的例子中那样较小的尺寸,它们仍然值得一试。矩阵的特征值是其特征多项式|A-λI|的根。Mathematica有一个内置函数CharacteristicPolynomial,可以为您提供矩阵的表达式。现在,您可以获得一个关于您的变量的漂亮的多项式(续...) - user616736
1
你可以始终使用“判别式”、“Δ”来设置变量的边界,以使其成为特定结构... 如果“Δ>0”,则多项式有实根->特征值是实数->Hermitian/对称。如果“Δ=0”,则存在多重根->矩阵不是满秩,“Δ<0”->复杂特征值。如果你有一个符号矩阵,并且想要探究一下如果改变一些变量会发生什么,这些特征值尤其有用。还有一些更多的代数结果可以用来缩小根的符号范围,这将告诉你关于正定性的信息。 - user616736
@yoda,显然我很无知,我没有注意到名字的更改。 - rcollyer
@rcollyer :) 最近连续看了这6部电影,然后气鼓鼓地转变了想法...不过我想我会坚持下去的。 - user616736
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接