1
$\begingroup$

why does the following not work (Table isn't plugging in values for k):

m = 3;    
n = 5;
SparseArray[Table[{i_, j_} /; j == i + k n -> 1, {k, 0, m - 1}], {n, m (n + 1)}]

instead one seemingly has to jump through hoops and do:

SparseArray[Table[{i_, j_} /; j == i + k n -> 1 /. {k -> t}, {t, 0, m - 1}], {n, m (n + 1)}]
$\endgroup$
  • $\begingroup$ If speed on large creation is important, methods posted so far can be handily beat, look at using ArrayPad on an appropriate base... $\endgroup$ – ciao Apr 30 '15 at 19:20
1
$\begingroup$

Condition (/;) has attribute HoldAll, so j == i + k n is not evaluated and the value of k never gets there. Rule is not held, so t in {k -> t} is evaluated before replacing k in the Condition.


But it turns out you don't actually need the Table here, you can do something like:

 SparseArray[{i_, j_} /; (i == Mod[j, n, 1] && j <= m n) -> 1, {n, m (n + 1)}]

This is slower than the original for large matrices through. We can replace the pattern with Band to get even faster than the original:

SparseArray[Table[Band[{1, (k - 1) n + 1}] -> 1, {k, m}], {n, m (n + 1)}]
$\endgroup$
  • $\begingroup$ looks nice, but for large m and n the mod solution seems to be considerably slower (by a factor of 50) $\endgroup$ – Peter Apr 30 '15 at 16:47
  • $\begingroup$ @Peter You're right, I guess the Mod breaks some of the optimizations so it has to loop over all of the possible {i,j} pairs? $\endgroup$ – 2012rcampion Apr 30 '15 at 17:24
1
$\begingroup$

Not sure how large of m and n you deem "large", but certainly it should be obvious that creating a Table for the purposes of populating a SparseArray is, to be charitable, counterproductive (I'd use something much more colorful were an engineer working for me to do such things).

Take advantage of the sparse-aware Mathematica functions:

ArrayPad[ArrayPad[SparseArray@IdentityMatrix[{n, n}], {{0, 0}, {0, n (m - 1)}}, "Periodic"], {{0, 0}, {0, m}}]

Produces same results as yours and the current (only) answer, vastly faster (~60X faster than yours on 500x500 and well over order of magnitude faster than only answer so far). Side benefit - its sparse result needs only about 1/3 the storage compared to your method and existing answer.

N.B. The double padding is a bit faster than re-sparsifying to end dimensions...

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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