Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Imagine one has an array of integer value sets that looks like this:

testValues = {{9, 8, 8, 10, 1}, {10, 0, 0, 1, 0}, {8, 0, 0, 5, 7}, {1, 5, 7, 2, 7}, {6, 9, 3, 9, 10}, {7, 10, 7, 5, 3}, {3, 10, 6, 1, 9}, {5, 8, 7, 9, 2}, {2, 3, 2, 7, 0}, {3, 7, 10, 2, 7}};

And a set of lists that looks like this:

listA = {1,2,3,4,5,6,7,8,9,10};
listB = {1,2,3,4,5};
listR = {{67,56,55,33,24,32,54,667,99,103498},{5}};
listQ = {{653,29,49,69,19},{20987}}

Here, Length[listA] == Length[listR[[1]]], Length[listB] == Length[listQ[[1]]], and the number of entries in testValues is Length[listA]*Length[listB].

I want to very quickly output an array with entries:

{{listR[[a, 1]], listQ[[b, 1]]},...}

For all {a,b} pairs where testValues[[a,b]] >= threshold for some integer threshold value. The entries in the array do not need to be in any particular order.

The naive way of proceeding could look like:

outputList ={};

For[a = 1, a <= Length[listA], a++,
  For[b = 1, b <= Length[listB], b++,

    If[testValues[[a, b]] >= threshold,
      outputList = Append[outputList, {listR[[a, 1]], listQ[[b, 1]]}];
      ];

    ];
  ];

However, this is quite slow. Is there a much faster method using Select perhaps?

The relevant list sizes are in reality something like Length[listA] $\approx 10^2$, Length[listB] $\approx 10^4$, and testValues has Length[listA]*Length[listB] entries.


Update:

I was able to use Position to do the following:

goodIndices = Position[int, x_ /; x >= 3];
outputList[[i]] = {listR[[#[[1]], 1]], listQ[[#[[2]], 1]]} & /@ goodIndices;

This is about 4x faster than the naive approach I posted earlier. Are further speedups possible?

share|improve this question
    
I don't see the definition of listA, listB and listR, listQ. –  Vahagn Poghosyan Sep 21 '13 at 8:44
    
In any case, you could play with DeleteCases function with levelspec 2 –  Vahagn Poghosyan Sep 21 '13 at 8:56
    
@VahagnPoghosyan I've added explicit examples for all of the lists. –  RM1618 Sep 21 '13 at 8:56
add comment

1 Answer

up vote 1 down vote accepted

Here is a straightforward functional transformation of your For loop which should be faster:

pairs = Select[Tuples[{listA, listB}], Extract[testValues, #] >= threshold &];
outputList = Table[{listR[[First[p], 1]], listQ[[Last[p], 1]]}, {p, pairs}];
share|improve this answer
    
Hmm, this doesn't seem to perform similarly? I'm getting position specification errors for different examples? –  RM1618 Sep 21 '13 at 11:10
    
For your example the code produces the exact same output as your for loop. –  sakra Sep 21 '13 at 12:02
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.