On Wed, 6 Apr 2016, Artur T. wrote:
Dear all,
I've got a function which involves matrix inversion and is frequently
called in loop. From time to time matrix inversion, however, fails. Thus
I tried to use the catch command similar to this tiny example:
<hansl>
function matrix matI(matrix mat)
return inv(mat)
end function
mat = zeros(2,2)
scalar err = 0
catch mI = matI(mat)
err = $error
if err==0
printf "WORKS \n"
else
printf "FAILS \n"
endif
</hansl>
In this example-script everything works fine. However, in my larger
script involving many different things before function "matI" is called,
gretl stops giving me the error message:
<gretl-output>
Unmatched "endif"
</gretl-output>
Executing the script above with current gretl one sees, inter alia:
<output>
? catch mI = matI(mat)
In regard to function matI:
Warning: "catch" should not be used on calls to user-defined functions
</output>
This should be taken seriously. For "catch" to work reliably it must
be applied directly to a built-in command or function. On return from
a user-defined function it's too late to ensure integrity of gretl's
state in case of error, so (although you may be OK in simple cases)
problems such as you mention are to be expected.
You should move the "catch" into the function where inv() is called.
Here's one possible approach:
<hansl>
function matrix try_invert (matrix m, scalar *err)
catch matrix ret = inv(m)
err = $error
if err
ret = {}
endif
return ret
end function
mat = zeros(2,2)
scalar err = 0
mI = try_invert(mat, &err)
if !err
printf "WORKS\n"
else
printf "FAILS\n"
endif
</hansl>
And here's another:
<hansl>
function scalar try_invert (matrix m, matrix *minv)
catch minv = inv(m)
return $error
end function
mat = zeros(2,2)
matrix minv
err = try_invert(mat, &minv)
if !err
printf "WORKS\n"
else
printf "FAILS\n"
endif
</hansl>
Allin