Is there any efficient easy way to compare two lists with the same length with Mathematica?

前端 未结 5 982
感情败类
感情败类 2021-02-13 23:41

Given two lists A={a1,a2,a3,...an} and B={b1,b2,b3,...bn}, I would say A>=B if and only if all ai>=bi.

There is

5条回答
  •  天命终不由人
    2021-02-14 00:27

    For instance,

    And @@ Thread[A >= B]
    

    should do the job.

    EDIT: On the other hand, this

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

    is 20 times faster. 20 times uglier, too, though.

    EDIT 2: Since David does not have a C compiler available, here are all the timing results, with two differences. Firstly, his second method has been fixed to compare all elements. Secondly, I compare a to itself, which is the worst case (otherwise, my second method above will only have to compare elements up to the first to violate the condition).

    (*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
    

    enter image description here

    So the compiled method is much faster (note that David's second method and the compiled method here are the same algorithm, and the only difference is overhead).

    All these are on battery power so there may be some random fluctuations, but I think they are representative.

    EDIT 3: If, as ruebenko suggested in a comment, I replace Part with Compile`GetElement, like this

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

    then cmp2 is a twice as fast as cmp.

提交回复
热议问题