0
$\begingroup$

This may be an easy question, but I can't find it anywhere.

I have a code which solves linear equations in a do loop (possibly compiled) using LinearSolve. To save the results I use Reap and Sow. It may happen that the solutions start to diverge, in which case LinearSolve will generate a warning message. If this happens, I want to stop the do loop, and still have the results up to that point saved by reap, ideally only to the step just before the message was generated, but that's not so important.

This is a minimal example of my code:

mat1 = {{-1, 3}, {4, 2}};
mat2 = {{-1, 3}, {nr, 2}};
vec={1.,1.};

nr=1;
results = Reap[ Do[
           Sow[LinearSolve[mat1,vec],sol1];
           Sow[LinearSolve[mat2,vec],sol2];
           nr=nr*10.;,
               {20}],
           {sol1,sol2}]

For me this generates a message at the 11th step, so what I'm looking for is a code to stop the do loop when this message is generated, and have the reap pick up two lists of results both of length 10.

The only thing I've found which comes close is Check, but this doesn't stop the do loop.

Edit: The uncompiled version can be done with Check and Break, as suggested by Malte Lenz, but for the compiled version this doesn't work.

The compiled version would be something like this:

comp = Compile[{}, Block[{nr = 1., sol1, sol2, currestep = 1.},
Do[
Check[
 sol1 = LinearSolve[mat1, vec];
 sol2 = LinearSolve[mat2, vec];
 Sow[{sol1, sol2}];
 nr = nr*10;
 currstep += 1;,
 errorstep = currstep; Print["error at step ", errorstep]; 
 Break[]],
{30}]
 ], CompilationOptions -> {"InlineExternalDefinitions" -> True}]

nr = 1;
currstep = 1;
results = Reap[
  comp[]
 ,{sol1, sol2}]

(It doesn't seem to save like this, but I think that's beside the point.)

Now the Break complains with:

Break::nofwd: No enclosing For, While, or Do found for Break[]. >>
$\endgroup$

1 Answer 1

1
$\begingroup$

You could use Break to stop the Do iteration:

ClearAll[nr];
mat1 = {{-1, 3}, {4, 2}};
mat2 = {{-1, 3}, {nr, 2}};
vec = {1., 1.};

nr = 1;

results = Reap[Do[
  Check[
    Sow[LinearSolve[mat1, vec], sol1];
    Sow[LinearSolve[mat2, vec], sol2];,
    Break[]
  ];
  nr = nr*10.;
, {20}], {sol1, sol2}]
$\endgroup$
1
  • $\begingroup$ Thanks, this works for the uncompiled version, but when compiled it complains that there's no Do to break from. I edited my question with an example of compiled code. $\endgroup$
    – Jansen
    Apr 21, 2015 at 9:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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