# How to combine SparseArray and If

Because I am dealing with huge matrixes, my computer can not handle it, because of the memory. But, in my matrix, a very small percentage of the elements are non-zero. So I should use SparseArray as far as I am aware. The problem is that, I do not really know how to transform my old way of defining my matrix to the new "SparseArray way". I gonna give a very simple toy model of my old way:

n = 3;

H = ConstantArray[0, {n*n, n*n}];

Do[
i = ix + (iy - 1)*n;
j = jx + (jy - 1)*n;
x = ix;
y = iy;
If[i == n && j == i - 1, H[[i, j]] = t*Exp[I*x],
If[i == n && j == i + n, H[[i, j]] = t,
If[i == n && j == i - (n - 1), H[[i, j]] = t*Exp[-I*x],
If[i == n && j == i + n*(n - 1), H[[i, j]] = t, 0]]]],
{iy, 1, n,1}, {ix, 1, n, 1}, {jy, 1, n, 1}, {jx, 1, n, 1}];


So my matrixes are like this but with many-many If.

Could somebody give me an idea of how to do it?

Thanks a lot

It may not be highly time-efficient (read this) but you can make Part assignments to a SparseArray object just as you would a conventional array, therefore you merely need to replace your ConstantArray with:

SparseArray[{}, {n*n, n*n}]


You can also specify a different background for the array with the third argument:

SparseArray[{}, {n*n, n*n}, 5]


Please take a look at this question, as explicit loops are rarely optimal in Mathematica:
Alternatives to procedural loops and iterating over lists in Mathematica

By the way you should avoid starting user symbols with capital letters (unless you know exactly what you're doing) to avoid conflicts with built-ins, so use h instead of H.

After looking at your code in depth I believe you would be served by something like this:

n = 3;

SparseArray[
{i_, j_} :>
With[{x = Mod[i, n, 1]},
Which[
i != n,             0,
j == i - 1,         t*Exp[I*x],
j == i + n,         t,
j == i - (n - 1),   t*Exp[-I*x],
j == i + n*(n - 1), t,
True,               0
]
],
{n*n, n*n}
]


I observe that all but one row of the resultant array is entirely zero. Of course it will be far more efficient to identify this pattern and program accordingly, but I assume that this code is merely an illustration of the kind of operation you wish to perform and not representative of the operation itself.

• It might be more profitable for OP if he recasts the rules implemented as nested If[]s as actual rules within SparseArray[]... – J. M. is away May 16 '13 at 10:59
• Maybe I could do something similar to this: – Mencia May 16 '13 at 11:29
• mat = SparseArray[{i_, j_} /; i == j :> 1, {8, 8}]; – Mencia May 16 '13 at 11:29
• But what is the way to put more than one condition as I did, i==j:>1, but many of them ? – Mencia May 16 '13 at 11:30
• @Mencia you just need to put them in a list: SparseArray[{{i_, j_} /; i == j -> -2, {i_, j_} /; Abs[i - j] == 1 -> 1, {i_, j_} /; i != j && j == 5 :> i + j}, {10, 10}] // MatrixForm – Mr.Wizard May 16 '13 at 11:49