Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I need to break my for loop in case of an thrown message and append s to the result list. Breaking the loop works, but my result is empty. I can not use Table[] because it does not support Break[].

EDIT: s has the form of list, so I get a Table structure for result

EDIT 2: AppendTo[] yields empty result too.

result = {};
For[i = 0, i < 6, i++, 
 s = {Quiet[
    Check[If[i == 3, Message[FindRoot::jsing, x, 1], i], "Nan", 
     FindRoot::jsing]]};
 If[s == "Nan", Break[], AppendTo[result, s]];
 ]
result

yields:

{}

Any help appreciated.

share|improve this question

4 Answers 4

up vote 5 down vote accepted

How about:

result = {};
For[i = 0, i < 6, i++, 
 s = Check[If[i == 3, Message[FindRoot::jsing, x, 1], i], "Nan", 
   FindRoot::jsing];
 Print[s];
 If[s == "Nan", Break[], result = {result, s}];]
Flatten[result]

or

result = {};
For[i = 0, i < 6, i++, 
 s = Check[If[i == 3, Message[FindRoot::jsing, x, 1], i], "Nan", 
   FindRoot::jsing];
 Print[s];
 If[s == "Nan", Break[], AppendTo[result, {s, dim}]];]
result
share|improve this answer
    
this works for one dimensional form of s but not for lists (edited problem, sorry) –  Martin Scherer Apr 19 '12 at 17:30
    
second one has table structure, thank you. –  Martin Scherer Apr 19 '12 at 17:42

In an effort to "say no to loops", here is an alternative that substitutes For and Break with Fold and a Throw/Catch construct. There might be another alternative using FoldList and fewer uses of Flatten, but it's late at night here and I wasn't able to get that quite working. This works:

Catch@Fold[
  With[{chk = 
      Check[If[#2 == 3, Message[FindRoot::jsing, x, 1], #2], "Nan", 
       FindRoot::jsing]},
    If[chk == "Nan", Throw[Flatten@{#1, #2}], 
     Flatten@{#1, chk}]] &, {}, Range[6] ]

FindRoot::jsing: Encountered a singular Jacobian at the point x = 1. Try perturbing the initial point(s). >>

{1, 2, 3}

I think approaches such as this are preferable to For loops, since the latter tends to result in iterator variables (in this case, i) that remain globally defined, which is probably not what you want.

share|improve this answer

You may not be able to use Table with Break[] but you can use Do:

Break[]
    exits the nearest enclosing Do, For or While.

I also prefer Sow and Reap for speed and flexibility.

Reap[
  Do[
    s = Check[If[i == 3, Message[FindRoot::jsing, x, 1], i], "Nan", FindRoot::jsing];
    If[s == "Nan", Break[], Sow@s],
    {i, 0, 5}
  ]
][[2, 1]]
{0, 1, 2}
share|improve this answer

The reason Append[] isn't working in your loop is that it returns a new list with your new element added to the end.

If you want to change the list in place, you should use AppendTo[] instead.

share|improve this answer
    
thx, now I know why Append in loops is evil! –  Martin Scherer Apr 19 '12 at 17:34
3  
@MartinScherer Oh no, the main reason for that (Append being evil in loops) is not it. It is that the full list is copied to append a single element. –  Leonid Shifrin Apr 19 '12 at 17:35
    
calling copy constructors all the time :) –  Martin Scherer Apr 19 '12 at 17:40
    
@LeonidShifrin, which suggests an interesting follow-up question. Is AppendTo's implementation equally eager to copy things repeatedly? I can imagine an implementation where the Append version is forced to copy with every operation, but where AppendTo is implemented much like C++'s std::vector and only has to copy some of the time instead of on every step. I just ran some Timings and it looks like their behavior is almost identical. –  sblom Apr 19 '12 at 17:48
2  
@sblom I noticed that I did not really answer your question. The answer is yes, AppendTo is just as bad in this regard as Append. Moreover, you can see that AppendTo has been actually implemented with Set and Append, by using On[Set], and then say a = Range[5]; AppendTo[a, 6]. –  Leonid Shifrin Apr 19 '12 at 19:31

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.