1

I have a huge table of data which I need to insert all of them in my main function using a For loop. For example, I have

subsnum = {{x -> 1., y -> 1.}, {x -> 2., y -> 2.}, {x -> 3., 
y -> 3.}};
FullScalarMasses = {{x^2, y^3}, {x + y, y}};

and I want to calculate the Eigenvalues of "FullScalarMasses" for all elements of "subsnum". The code I use is the following

For[i = 0, i <= 3, i++, 
es1 = Eigenvalues[FullScalarMasses //. subsnum[[i]]]]

however I get this error and can't continue:

ReplaceRepeated::reps: {List} is neither a list of replacement rules nor a valid dispatch table, and so cannot be used for replacing. >>

How can I solve the problem? In practice my code is a lot more complicated than this. I have a big data table with more than a million values, and I need to calculate several things for each element of the table. An the only way I can think of is using "ReplaceRepeated" in a For loop. Is there any other way I can do this?

P.S.: I have to calculate many things in the loop at the same time for the same element, so "Table" is not an option.

  • 1
    The For loop starts at i = 0. So subsnum[[i]] evaluates to subsnum[[0]], which returns the head of the expression, List. Then you have the ReplaceRepeated error. You can start at i = 1 to avoid this issue. –  Sep 06 '16 at 23:24
  • Slightly on a tangent, For is highly inefficient on Mathematica. I recommend Do, which is a native Mathematica function, with the same functionality as, but with significantly faster evaluation than, For . That is: Do[es1 = Eigenvalues[FullScalarMasses //. subsnum[[i]], {i, 3}] – JungHwan Min Sep 06 '16 at 23:34
  • @Xavier Thanks a lot for your answer. I was dealing with this for a long time and I never noticed this was the problem. I was sure it's something to do with Replace! – tenure track job seeker Sep 07 '16 at 02:36
  • 1
    "I have to calculate many things in the loop at the same time for the same element" <- If it is for the same element, then why is Table not an option? Calculating many things is not a problem. Calculating things which depend on perviously calculated elements (not the same element!) would preclude the use of Table. – Szabolcs Sep 07 '16 at 05:36

2 Answers2

4

You don't need the loop at all. This returns all eigenvalues of all three of the matrices defined by subsnum and fullScalarMasses:

subsnum = {{x -> 1., y -> 1.}, {x -> 2., y -> 2.}, {x -> 3., y -> 3.}};
fullScalarMasses[x_, y_] := {{x^2, y^3}, {x + y, y}}; 
Eigenvalues[fullScalarMasses[x, y]] /. subsnum

{{-0.414214, 2.41421}, {-2.74456, 8.74456}, {-7.0767, 19.0767}}
bill s
  • 68,936
  • 4
  • 101
  • 191
  • Thanks, but as I said the real code is a lot longer and I really need to have a For loop. For this specific example it's possible to do this, as I always do, but for my problem I cannot. – tenure track job seeker Sep 07 '16 at 02:37
  • 2
    You can make the function as complicated as you want and the iteration does not change. In other words, by rewriting your problem as a function you will be able to iterate it easily. – bill s Sep 07 '16 at 02:51
3

First rule of learning Mathematica: Never, ever use For! It is never needed, it is error prone and it encourages bad practices. If you really want a procedural loop, use Do, and forget that For even exists. For complex procedural cases, use While.

First, consciously or unconsciously you have copied the standard for pattern using 0-based indexing from C-like languages. Mathematica uses 1-based indexing. This is less likely to happen with Do, with which you'll never see any 0-based examples, and which encourages dropping the starting index anyway.

Rewrite your code like this:

Do[
  es1 = Eigenvalues[FullScalarMasses //. subsnum[[i]]]],
  {i, 1, Length[subsnum]}
]

Then realize that this is simpler:

Do[
  es1 = Eigenvalues[FullScalarMasses //. subsnum[[i]]]],
  {i, Length[subsnum]}
]

This is even simpler

Do[
  es1 = Eigenvalues[FullScalarMasses //. rule]],
  {rule, subsnum}
]

The transition to a non-procedural Table is immediate:

Table[
  Eigenvalues[FullScalarMasses //. rule]],
  {rule, subsnum}
]

The jump to a Map form or similar is also very straightforward.

Other advantages of Do compared to For:

  • It automatically localizes the iterator while For uses global variables (i is set permanently)

  • All those commas in For are too easy to get wrong; For has both worse readability and "writeability" than Do

  • Do is faster for very tight loops due to not explicitly setting the iterator

Note 1: I am not advocating against procedural programming here. I am advocating specifically against For, which encourages bad practices in writing Mathematica code and is error prone.

Note 2: There are a few examples where For indeed produces the most elegant code. However, these are rare, and I maintain that the disadvantages far outweigh any occasional advantages. See here and links within: Are there any cases when For[] loops are reasonable?

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263