b.gatessucks's answer shows you what to do and is worthy of the accept. However, it does not explain why your previous approach wasn't going to work.
First, a point on efficiency. In your For
loop, you were redefining iM
and staDis
each iteration of the loop, even though the values didn't change. This is unnecessary. Similarly, you didn't really need both iMP
and iMPV
. You could have saved a little memory by going straight to MatrixPower[im,i][[4]]
, or even incorporating the next line with the Norm
function, much as b.gatessucks did with his answer. In the problem posed in your question, the speedup and memory saving will be trivial, but it is worth bearing these sort of tips in mind as you move on to bigger problems with larger matrices etc.
The reason you weren't getting the desired result out of your loop is that Do
, For
and other Fortran-style looping constructs in Mathematica do not actually return any values. You have to set up side effects inside the loop, defining other variables as you did in the code in your question. List-based operations, like the Table
command b.gatessucks used, directly return a result so you can define a variable name to take that result, as he did in his answer. It is much more direct, and in my view a more transparent style of code.
I'd also note that if you just want to plot the result in a ListPlot
or similar, you don't actually need the sequential index as part of the result. In other words, a vector would do, rather than the two-column matrix you seemed to be building up and b.gatessucks used in his answer.
There are many different ways to build up lists from intermediate calculations. For example, the following give the exact same results as the Table
version, but use functional programming (Slot
#
notation).
You can Map
the required function to a vector created with Range
result2 =
Norm[MatrixPower[iM, #][[4]] - staDis, 1]/2 & /@ Range[2, 50];
ListLogPlot[result2]
Or you can use Array
. Here I've used the little-known third argument to specify a 49-element array where the index starts at 2, not the default of 1.
Array[Norm[MatrixPower[iM, #][[4]] - staDis, 1]/2 &, {49}, {2}]
Which approach you use out of Table
, Array
and a functional construct like Map
depends on the nature of your problem and particularly what you are iterating over. I'd also suggest you have a good look at NestList
and FoldList
in the documentation. Those functions simplify many operations that programmers familiar with other languages tend to try to use loops for.