Mathematica中复杂矩阵的最大函数

时间:2013-08-05 13:56:54

标签: wolfram-mathematica

我想逐个元素地比较矩阵并找到矩阵的最大值,就像我有三个3x3矩阵一样

tdata = {{{1, 5, 1}, {7, 4, 2}, {2, 4, 3}}, {{2, 0, 8}, {9, 8, 2}, {2,
 3, 0}}, {{2, 2, 9}, {10, 9, 5}, {9, 3, 3}}}

然后使用

MapThread[Max, tdata, 2] // MatrixForm

我可以得到正确的结果。

{{2, 5, 9}, {10, 9, 5}, {9, 4, 3}}

但是,当矩阵是复杂矩阵时,Max函数不起作用。例如,

tdata = {{{0.323031 + 5.23687 I, 8.92856 + 1.31365 I},
{9.94387 + 3.04104 I, 8.72483 + 2.5648 I}},
{{5.96575 + 9.2521 I,  8.58461 + 2.56753 I},
{0.902715 + 3.75791 I, 4.06809 + 8.61552 I}},
{{9.36592 + 1.17263 I, 9.74628 + 2.22183 I},
{4.61866 + 4.61158 I, 9.0791 + 2.50036 I}}}

我试图为复杂矩阵实现一个新的Max函数,但它不起作用。这是一个演示,

complexMax[lis_] := Module[{abs = Abs[lis]}, Take[lis, Position[abs, Max[abs]][[1]]]]

然后

MapThread[complexMax, tdata, 2]

结果就像

{{complexMax[0.323031 + 5.23687 I, 5.96575 + 9.2521 I, 9.36592 + 1.17263 I], 
 complexMax[8.92856 + 1.31365 I, 8.58461 + 2.56753 I, 9.74628 + 2.22183 I]}, 
{complexMax[9.94387 + 3.04104 I, 0.902715 + 3.75791 I, 4.61866 + 4.61158 I], 
 complexMax[8.72483 + 2.5648 I, 4.06809 + 8.61552 I, 9.0791 + 2.50036 I]}}

有任何想法如何解决问题?

3 个答案:

答案 0 :(得分:2)

我认为这就是你想要的:

MapThread[Last@SortBy[{##}, Abs] &, tdata, 2] // MatrixForm

(* {{5.96575 + 9.2521 I,9.74628 + 2.22183 I},{9.94387 + 3.04104 I,   4.06809 + 8.61552 I}} *)

FWIW按规范排序复杂的数字,(实部首先)

MapThread[Last@Sort[{##}] &, tdata, 2] // MatrixForm

(* {{9.36592 + 1.17263 I,9.74628 + 2.22183 I},{9.94387 + 3.04104 I,   9.0791 + 2.50036 I}} *)

请注意,如果您执行此操作,您的方法也会起作用:

 MapThread[complexMax[{##}] &, tdata, 2]

诀窍是Mapthread传递给你的函数的参数是一个序列,而不是一个列表。

答案 1 :(得分:2)

当前代码的问题在于使用MapThread会导致complexMax被调用而不是单个参数是一个列表(即complexMax[{elem1, elem2, elem3...}]),但是有多个参数(即complexMax[elem1, elem2, elem3])。

您可以通过将参数声明为单个表达式(lis_ w / single下划线)但作为表达式序列来解决此问题:lis__带有双下划线。

进行此更正会导致另一个问题,但Abs需要列表作为输入,Take也是如此。因此,您需要将lis括在括号中的几个地方。

最后,看起来你最后还需要一个[[1]]

complexMax[lis__] := Module[{abs = Abs[{lis}]},
  Take[{lis}, Position[abs, Max[abs]][[1]]][[1]]] 

MapThread[complexMax, tdata, 2]

结果

{{5.96575 + 9.2521 I, 9.74628 + 2.22183 I}, {9.94387 + 3.04104 I, 
  4.06809 + 8.61552 I}}

答案 2 :(得分:1)

现在有一个专门用于 Mathematica 的StackExchange网站:https://mathematica.stackexchange.com/ - 请在那里询问您未来的问题。


正如latkin已经解释的那样,如果要使用MapThread中所示的最大函数,则需要接受多个参数。您可以使用第二种模式编写函数来处理两种形式,例如: cMax[ns__] := cMax[{ns}]

Position更快Ordering

cMax[ns__] := cMax[{ns}]

cMax[lis_List] := lis ~Extract~ Ordering[Abs[lis], -1]

现在:

MapThread[cMax, tdata, 2]
{{5.96575 + 9.2521 I, 9.74628 + 2.22183 I},
 {9.94387 + 3.04104 I, 4.06809 + 8.61552 I}}

但是,使用打包数据时,使用MapThread会更快 ,从而导致解包,而是使用Transpose将数字保留在列表中:

Map[cMax, Transpose[tdata, {3, 1, 2}], {2}]
{{5.96575 + 9.2521 I, 9.74628 + 2.22183 I},
 {9.94387 + 3.04104 I, 4.06809 + 8.61552 I}}

时序:

cd = RandomComplex[9 + 9 I, {15000, 7, 7}];

MapThread[Last@SortBy[{##}, Abs] &, cd, 2] // Timing // First

MapThread[cMax, cd, 2]                     // Timing // First

Map[cMax, Transpose[cd, {3, 1, 2}], {2}]   // Timing // First
  

0.562

     

0.483

     

0.0156