# Restart iteration in a for loop when an error is thrown

I have to run a `for` loop based on random numbers generation and inversion of a matrix. When the matrix is singular, my code stops, throwing a `SingularException()` error. If this occurs at a certain iteration of the loop, how can I force the code to restart again the iteration with new numbers generation until a regular matrix is found to continue the loop until the end?

To keep it simple, suppose the following code:

``````res=zeros(500)
for i=1:length(res)
X=rand(100,100)
X2=transpose(X)*X
res[i]=tr(inv(X2))
end
``````

If at iteration `i` the matrix `X2` is singular, how can I run again iteration `i` until the iteration can be completed and then proceed with the loop?

I think you would have to use a `while` loop instead, with a condition on incrementing `i`.

1 Like

Ok, Iâ€™ll try your solution

Another possible option is to put the body of the loop into a function and wrap it in a `try ... catch` block. If an exception is found you call the function again.

So something like:

``````function my_inner_loop()
try
X=rand(100,100)
X2=transpose(X)*X
return tr(inv(X2))
catch
my_inner_loop()
end
end
``````

Do I have to call manually the function if an exception is found? Because I want to let the loop running alone in background even when my PC is off.

I think you could do something like this:

``````    i = 0

function my_inner_loop(;maxtries=100)
while i < maxtries
try
X=rand(100,100)
X2=transpose(X)*X
r = tr(inv(X2))
return r
catch
i += 1
my_inner_loop()
end
end
return nothing # or 0 or whatever makes sense
end
``````

Ok, thanks! Iâ€™ll try this solution too How do I call the function?

I would suggest that you do a QR decomposition of X = QR, so that X'X = R'R, use that to detect invertibility and just return `Inf` for singular matrices, then work with `Rinv = inv(R)` etc.

Alternatively, if you are willing to use an SVD,

``````sum(x -> abs2(1/x), svd(X).S)
``````

is equivalent to `tr(inv(X'*X))` because of similarity invariance.

1 Like

After posting the above I realized that there are some scoping issues with the variables. The following code might be closer to what you want for the non-math part:

``````function my_outerspace_loop(maxtries=100)

i = 1
result = nothing
function my_inner_loop(max)
# global i
while i < maxtries
@show i
try
X=rand(100,100)
X[1,1] < 0.1 || throw()
X2=transpose(X)*X
result = tr(inv(X2))
break
catch
println("Trying again...")
i += 1
return my_inner_loop(max)
end
end
return (result, i) # or 0 or whatever makes sense
end

my_inner_loop(maxtries)
end

``````

Thank you for your suggestion But I really want to know how to restart an iteration. Thatâ€™s my central problem.

Thanks. But how can I call this function? `my_inner_loop(1)` or `my_inner_loop()` with any number inside `()`?

In this case you would call `my_outerspace_loop(n)` where n is the maximum number of times you want to allow your algorithm to try to find an appropriate solution. You do not call `my_inner_loop` directly.

Is that what you meant by â€śhow to callâ€ť?

1 Like

Yes, thatâ€™s what I mean! Thank you! Iâ€™ll apply your method!

I accidentally left in some testing stuff. Donâ€™t forget to comment out `X[1,1] < 0.1 || throw()` or youâ€™ll never get anywhere in life.

1 Like

Ok, perfect!