有没有有效的简单方法来比较Mathematica相同长度的两个列表?

Osi*_* Xu 11 arrays wolfram-mathematica list mathematica-8

鉴于两个列表A={a1,a2,a3,...an}B={b1,b2,b3,...bn},我会说A>=B,当且仅当所有ai>=bi.

有两个列表的内置逻辑比较A==B,但没有A>B.我们需要像这样比较每个元素吗?

And@@Table[A[[i]]>=B[[i]],{i,n}]

有什么更好的技巧吗?

编辑: 非常感谢大家.

这是另一个问题:

如何在N个列表中找到最大列表(如果存在)?

使用Mathematica在N个列表中查找具有相同长度的最大列表的任何有效简便方法?

Dav*_*idC 18

方法1:我更喜欢这种方法.

NonNegative[Min[a - b]]
Run Code Online (Sandbox Code Playgroud)

方法2:这只是为了好玩.正如列昂尼德指出的那样,对于我使用的数据,它有一些不公平的优势.如果进行成对比较,并在适当的时候返回False和Break,那么循环可能更有效(尽管我通常避免在mma中循环):

result = True;
n = 1; While[n < 1001, If[a[[n]] < b[[n]], result = False; Break[]]; n++]; result
Run Code Online (Sandbox Code Playgroud)

对10 ^ 6个数字列表进行一些时序比较:

a = Table[RandomInteger[100], {10^6}];
b = Table[RandomInteger[100], {10^6}];

(* OP's method *)
And @@ Table[a[[i]] >= b[[i]], {i, 10^6}] // Timing

(* acl's uncompiled method *)
And @@ Thread[a >= b] // Timing

(* Leonid's method *)
lessEqual[a, b] // Timing

(* David's method #1 *)
NonNegative[Min[a - b]] // Timing
Run Code Online (Sandbox Code Playgroud)

时间2


编辑:我删除了方法#2的时间,因为它们可能会产生误导.方法#1更适合作为一般方法.

  • 尼斯.快速而简单.+1 (2认同)
  • 这当然不会影响你所欣赏的美丽而快速的第一种方法. (2认同)

acl*_*acl 8

例如,

And @@ Thread[A >= B]
Run Code Online (Sandbox Code Playgroud)

应该做的工作.

编辑:另一方面,这

cmp = Compile[
  {
   {a, _Integer, 1},
   {b, _Integer, 1}
   },
  Module[
   {flag = True},
   Do[
    If[Not[a[[p]] >= b[[p]]], flag = False; Break[]],
    {p, 1, Length@a}];
   flag],
  CompilationTarget \[Rule] "C"
  ]
Run Code Online (Sandbox Code Playgroud)

比你快20倍.不过,也是丑陋的20倍.

编辑2:由于David没有可用的C编译器,所以这里是所有时序结果,有两个不同之处.首先,他的第二种方法已被修复以比较所有元素.其次,我比较a自己,这是最糟糕的情况(否则,我上面的第二种方法只需要比较第一种方法来违反条件).

(*OP's method*)
And @@ Table[a[[i]] >= b[[i]], {i, 10^6}] // Timing

(*acl's uncompiled method*)
And @@ Thread[a >= b] // Timing

(*Leonid's method*)
lessEqual[a, b] // Timing

(*David's method #1*)
NonNegative[Min[a - b]] // Timing

(*David's method #2*)
Timing[result = True;
 n = 1; While[n < Length[a], 
  If[a[[n]] < b[[n]], result = False; Break[]];
  n++]; result]

(*acl's compiled method*)
cmp[a, a] // Timing
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

所以编译的方法要快得多(请注意,David的第二种方法和编译方法在这里是相同的算法,唯一的区别是开销).

所有这些都是电池供电所以可能会有一些随机的波动,但我认为它们具有代表性.

编辑3:如果,正如ruebenko在评论中建议的那样,我将替换PartCompile`GetElement,像这样

cmp2 = Compile[{{a, _Integer, 1}, {b, _Integer, 1}}, 
  Module[{flag = True}, 
   Do[If[Not[Compile`GetElement[a, p] >= Compile`GetElement[b, p]], 
     flag = False; Break[]], {p, 1, Length@a}];
   flag], CompilationTarget -> "C"]
Run Code Online (Sandbox Code Playgroud)

然后cmp2是两倍快cmp.