1
$\begingroup$

In my program, I'm computing a vector inside a Do loop. The example below is an overly-simplified version, but the structure is the same (the original code can't be reduced to a Table). Using Reap/Sow, I get the following result:

In[1]:= v1 = Reap[Do[Sow[{{i, i}, {i^2, i^2}} // Transpose];, {i, 3}]][[2, 1]]

Out[1]= {{{1, 1}, {1, 1}}, {{2, 4}, {2, 4}}, {{3, 9}, {3, 9}}}

The final list I'm looking for is the transpose of this matrix:

In[2]:= v1 = Transpose@v1

Out[2]= {{{1, 1}, {2, 4}, {3, 9}}, {{1, 1}, {2, 4}, {3, 9}}}

The real vectors I'm working with are very large and Transposing the matrix after computing it takes a lot of time and memory (the dimensions of the vectors are around {201, 2, 500 000}). It often takes more time than computing the vector in the first place.

Is there a way to use Reap/Sow to arrange the vectors on columns instead of rows, in order to get the desired result without having to transpose at the end?

$\endgroup$
1
  • 1
    $\begingroup$ Read in the help under "Sow" about tagging. With this you can then write: v1 = Reap[Do[Sow[{i, i^2}, 1]; Sow[{i, i^2}, 2];, {i, 3}]] $\endgroup$ Oct 21, 2020 at 15:28

1 Answer 1

2
$\begingroup$

You can Sow and Reap different tags like this:

v1 = Reap[
   Do[
    MapIndexed[
      Sow[#1, First @ #2] &,
      {{i, i}, {i^2, i^3}} // Transpose
    ];,
    {i, 3}
  ],
  Range[2]
][[2, All, 1]]

{{{1, 1}, {2, 4}, {3, 9}}, {{1, 1}, {2, 8}, {3, 27}}}

Of course, you do need to know the number of tags to collect (2, in this case).

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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