# Inputting a big structured matrix in Mathematica

Hi this is my first post and this is a problem that has bothered me a lot.

Suppose we have the $2012\times2012$ square matrix:

$\begin{bmatrix}-3&1&1&1&1&1&\ldots&1&1&1&1\\1&2&1&1&1&1&\ldots&1&1&1&1\\1&1&-3&1&1&1&\ldots&1&1&1&1\\1&1&1&2&1&1&\ldots&1&1&1&1\\1&1&1&1&-3&1&\ldots&1&1&1&1\\1&1&1&1&1&2&\ldots&1&1&1&1\\\vdots&\vdots&\vdots&\vdots&\vdots&\vdots&\ldots&\vdots&\vdots&\vdots&\vdots\\1&1&1&1&1&1&\ldots&-3&1&1&1\\1&1&1&1&1&1&\ldots&1&2&1&1\\1&1&1&1&1&1&\ldots&1&1&-3&1\\1&1&1&1&1&1&\ldots&1&1&1&2\end{bmatrix}$

How can I write it using Mathematica? Of course I need to define something like a function which will assign elements to the positions of the matrix.

-
You shouldn't be in such a hurry to Accept (green check-mark) an answer, as it may discourage other, potentially better answers. –  Mr.Wizard Sep 24 '12 at 19:19

Try something like

matrix = SparseArray[{{i_, i_} /; OddQ[i] -> -3, {i_, i_} /; EvenQ[i] ->
2}, {2012,2012}, 1] // Normal;


If you are interested in the formal solution for it determinant,

Clear[matrix];
matrix[n_] :=  SparseArray[{{i_, i_} /; OddQ[i] -> -3, {i_, i_} /; EvenQ[i] ->
2}, {n, n}, 1];


you can start guessing a recursion from

Table[matrix[n] // Det, {n, 2, 32, 2}]


Thanks to Mr Wizard's advice you can in fact do

   f = Table[matrix[n] // Det, {n, 2, 32, 2}] // FindSequenceFunction;
f[n]


(* (-1)^n 4^(n-1) (3 n+4) *)

And for the Odd matrices (following R.M's request)

   Table[matrix[n] // Det, {n, 1, 31, 2}] //FindSequenceFunction // #[n] &


(* 3 (-1)^n 4^(n-1) n *)

   f/@ Range[16]
f[2012/2] // N


(* 3.552922584185648*10^608 *)

-
Ok thanks, but I need to find the determinant, how can this be done? –  Papadopoulos Geοrgios Sep 24 '12 at 19:10
you type Det[matrix] though i) it might take a while and ii) its probably a big number –  chris Sep 24 '12 at 19:10
for instance for a 200x200 matrix of this type the determinant is 122127291363683260941189119017928357791687427527492255482904576 –  chris Sep 24 '12 at 19:13
Thanks again, if I replace the {2012,2012} with {n,n} will I get the general formula of the determinant? –  Papadopoulos Geοrgios Sep 24 '12 at 19:13
Less guessing if you use FindSequenceFunction ;-) –  Mr.Wizard Sep 24 '12 at 19:21
SparseArray[Band[{1, 1}, {12, 12}] -> {-3, 2}, Automatic, 1] // MatrixForm


Replace {12, 12} with {2012, 2012} for the full array.

-
+1. And to implement your FindSequenceFunction hint, take a look at a[n_] := SparseArray[Band[{1, 1}, {n, n}] -> {-3, 2}, Automatic, 1]; Partition[Table[ 2^(2 - n - Mod[n, 2]) Det[a[n]] , {n, 2, 50, 1}] , 2] // MatrixForm. –  whuber Sep 24 '12 at 19:58
@Mr.Wizard beyond readability, any advantage of using Band? –  chris Sep 24 '12 at 20:27
@chris It is also about 1400 times faster for this specific problem on my system. –  Mr.Wizard Sep 24 '12 at 20:32
@Mr.Wizard ah! I see your point about a better answer then ;-) Well I already had given you my vote so... –  chris Sep 24 '12 at 20:33
@chris My comment was not to slight your answer. Your answer is more complete than mine and you were engaging the OP to discover and address his real needs, both of which merit the Accept IMHO. Rather, I frequently encourage users to wait a day before choosing an answer as there are people in different time zones who will not even have a chance to see the question before it is "concluded" (if you will). –  Mr.Wizard Sep 24 '12 at 20:59

Just for completeness sake, here is an even more efficient way to construct the SparseArray

n = 123013;
AbsoluteTiming[
pos = Transpose[{#, #}] &[Range[n]];
vals = ConstantArray[-3, {n}];
vals[[2 ;; -Mod[n, 2] - 1 ;; 2]] = -2;
SparseArray[pos -> vals, {n, n}, 1]
]
(*{0.009, Null}*)
AbsoluteTiming[
SparseArray[Band[{1, 1}, {n, n}] -> {-3, 2}, Automatic, 1]
]
(*{0.482, Null}*)


Using one rule is generally a very efficient way to generate a SparseArray

-
You can make this twice as fast by using pos = {#, #}\[Transpose] &@Range@n; vals = ConstantArray[-3, n]; :-) (+1 btw) –  Mr.Wizard Sep 25 '12 at 5:59
@Mr.Wizard, you are right, why not go all the way. Fixed. –  user21 Sep 25 '12 at 6:05
OK, I also did, that, but that seemed small compared to the Transpose. –  user21 Sep 25 '12 at 6:11
Interestingly I get about a 50% speed improvement of the entire operation by using ConstantArray in place of Table, over the intermediate version. Maybe Table is faster in v8? –  Mr.Wizard Sep 25 '12 at 6:17
Hm, yes this may be due to version or OS. It's sure good to have both. But an improvement of Table is also conceivable. Something like this can be very hard to track down to a (or several) courses. –  user21 Sep 25 '12 at 6:25

Yet another way (with timings similar to ruebenko's):

 values = ArrayPad[{-3, 2}, {0, n - 2}, "Periodic"];
diag = Transpose[Range[{n, n}]];
SparseArray[diag -> values, {n, n}, 1]]

-
a quick note: ArrayPad does not return a packed array, so, it is less efficient in space. –  user21 Sep 25 '12 at 10:13
@ruebenko, right; that explains kernel crashes and out of memory messages with other variants using ArrayPad:) –  kguler Sep 25 '12 at 10:22
if you see crashes, please report them to the support such that they can be fixed. –  user21 Sep 25 '12 at 11:43
that said, the fact that some function does/can not return a packed array does not mean that it is more susceptible to crashes. Out of memory, and it's subsequent kernel shut down yes. –  user21 Sep 25 '12 at 11:50