5
$\begingroup$

I have generated a matrix of zeros.

tab=Table[0,{i,10},{j,10}]

tab is defined such that given tab[[1]] (the first row of tab), I am doing For[i=2,i<=10,i++,tab=ReplacePart[tab,i->2*tab[[i-1]]]] so that given the first row, all the other rows follow.

Now I have generated another table, tab1 which is a 3x10 matrix of

{{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, 
 {3, 3, 3, 3, 3, 3, 3, 3, 3, 3}}

The problem is to replace the first row of tab with the first row of tab1 {1,....,1} and to calculate tab. Then doing the same with replacing the first row of tab with the second row of tab1 and then the third row of tab1. In each realization of the matrix of tab, I want to calculate the sum of each column and store the result. So in the end, I will have a 3x10 matrix of the sums of columns from each realization. [I am presenting this as a relatively simple problem as in the real problem I am trying to solve, there are about 50000 realizations of the first row of the matrix of dimensions 50x100].

I have tried

For[j = 1, j <= 3, j++, ps[j] = tab1[[j]]];
For[tab[[1]] = ps[j]; i = 2, i <= 10, i++, 
 tab = ReplacePart[tab, i -> 2*tab[[i - 1]]]]; 

but its not working. I would appreciate any help. Thank you.

$\endgroup$
1
  • $\begingroup$ As I read your question, at each step, any row of your 3 x 10 matrix consists entirely of equal numbers. That is, at each step in the process, each row has the form {k, k, k, k, k, k, k, k, k, k}. Is that correct? $\endgroup$
    – m_goldberg
    Dec 14, 2015 at 15:21

3 Answers 3

3
$\begingroup$

As I understand your question, the computation can be done for one column and then rows of length 10 can be generated from that column. If that is correct, then this may be what you looking for.

Module[{t = {1, 2, 3}, sums},
  sums = Table[Total @ Thread[Times[t[[i]], {1, 2, 4}]], {i, Length @ t}];
  ConstantArray[#, 10]& /@ sums]
{{7, 7, 7, 7, 7, 7, 7, 7, 7, 7}, 
 {14, 14, 14, 14, 14, 14, 14, 14, 14, 14}, 
 {21, 21, 21, 21, 21, 21, 21, 21, 21, 21}}
$\endgroup$
2
  • $\begingroup$ Hello, thanks for your response. Yes, for each stage/iteration, I get a row of identically equal numbers. I will try your suggestion. $\endgroup$ Dec 14, 2015 at 16:29
  • $\begingroup$ @SupratimDasGupta. There was a typo in my code as originally posted. I have corrected it, so please use the corrected version if you are experimenting with my code. $\endgroup$
    – m_goldberg
    Dec 14, 2015 at 16:35
3
$\begingroup$

The final result can be obtained with

Total /@ (NestList[2 # &, #, 9] & /@ tab1)

or

Plus @@@ (NestList[2 # &, #, 9] & /@ tab1)

or

Plus @@ NestList[2 # &, tab1, 9]

where 9 is the number of rows of tab minus 1. With the given value for tab1, one gets

(* {{1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023}, 
    {2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046}, 
    {3069, 3069, 3069, 3069, 3069, 3069, 3069, 3069, 3069, 3069}} *)

Update

Per OP's comment

the real problem that I am trying to solve [...] is (tab, i -> 2*tab[[i - 1]]] + 4 * rnorm[[i]]) where rnorm is a matrix of random normal variables

This can be achieved for instance with

First@*Total /@ (NestList[{2 #[[1]] + 4 rnorm[[#[[2]]]], #[[2]] + 1} &, 
          {#, 2}, 9] & /@ tab1)

or

First@*Plus @@@ (NestList[{2 #[[1]] + 4 rnorm[[#[[2]]]], #[[2]] + 1} &, 
          {#, 2}, 9] & /@ tab1)

or

rnorm2 = ConstantArray[#, 3] & /@ rnorm;
First@*Plus @@ NestList[{2 #[[1]] + 4 rnorm2[[#[[2]]]], #[[2]] + 1} &, 
          {tab1, 2}, 9]

where the parameter 3 used for rnorm2 is the number of rows of tab1.

$\endgroup$
4
  • $\begingroup$ Hello, I got your point about adding the columns repeatedly using NestList (for each realization of the first row of the matrix); but in the real problem that I am trying to solve it is (tab, i -> 2*tab[[i - 1]]]+4*rnorm[[i]]) where rnorm is a matrix of random normal variables. So to pull in each row of rnorm (given tab1) for each calculation and then repeating the process, do I do Total /@ (NestList[2+4*rnorm # &, #, 9] & /@@ tab1rnorm)? I am not sure of the syntax. If you can help, I would greatly appreciate. $\endgroup$ Dec 14, 2015 at 22:57
  • $\begingroup$ @SupratimDasGupta Ok, I have updated my answer according to your new question. $\endgroup$
    – user31159
    Dec 15, 2015 at 6:41
  • $\begingroup$ Hello, thank you very much for your help. I would try your suggestion. $\endgroup$ Dec 15, 2015 at 17:09
  • $\begingroup$ For getting the matrix tab to be repeated 3 times (based on the values of tab1), (given tab1[[1]],each row of tab is 1.011 tabl+0.12 rnorms* tabl); I have tried (NestList[{(1.011) #[[1]] + 0.12 rnorms[[#[[2]]]] #[[1]], #[[2]] + 1} &, {#, 1}, 9] & /@ tabl) which is giving me the wrong result (I have tried to compute each matrix manually by replacing the first row of tab). The above command of NestList is not taking each row of rnorms and multiplying it with the given row of tab1[[1]] and then computing the whole matrix each time. I would appreciate any help. $\endgroup$ Dec 16, 2015 at 0:07
2
$\begingroup$

Whenever a computation depends upon a previous computation it is a good idea to think Fold or FoldList.

For the simple case of multiplying the previous row by two NestList works fine (and Goldberg's approach is even better) but for more complicated functions I think there is a benefit to considering FoldList.

tab1 = {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
        {2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
        {3, 3, 3, 3, 3, 3, 3, 3, 3, 3}};

The matrix generated by using tab1[[1]] as the input is

FoldList[2*#1 &, tab1[[1]], Range[9]]

which produces

Mathematica graphics

and then one computes the total

Total@FoldList[2*#1 &, tab1[[1]], Range[9]]
(* {1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023} *)

To apply this to all of the rows in tab1 wrap the above step in Map using a Function to define the index into tab1.

Map[
 Function[tab1Index,
  Total@FoldList[2*#1 &, tab1[[tab1Index]], 
    Range[Length[tab1[[1]]] - 1]]
  ], Range[Length[tab1]]
 ]

resulting in

{{1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023},
 {2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046, 2046},
 {3069, 3069, 3069, 3069, 3069, 3069, 3069, 3069, 3069, 3069}}

This should be fast for 50000 realizations on a 50x100 matrix.

$\endgroup$
1
  • $\begingroup$ Hello, Thank you for your help. $\endgroup$ Dec 15, 2015 at 17:10

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.