I'm trying to implement a function which, given a matrix with one free parameter, would return the value of the parameter at which the lowest eigenvalue of the matrix is equal to a certain number.
Importantly, I'm planning to run this algorithm for extremely large sparse matrices, so I would like to use Arnoldi method.
Here's my attempt:
FitMat[matrix_, lowest_, param_, starting_, howmany_] :=
Module[{mat, fu},
mat[x_] := matrix /. {param -> x};
fu[x_] := Min[Eigenvalues[mat[x], howmany
, Method -> {"Arnoldi", "Criteria" -> "RealPart"}
]];
Return[
x /. FindRoot[fu[x] == lowest, {x, starting}
]
];
];
FitMat[( {
{1, 2, 1},
{3, 4, 1},
{x, 4, 9}
} ), -3, x, 50, 1]
This, however, results in the following error:
Eigenvalues::arm: Method -> Arnoldi can only be used for matrices of machine- or arbitrary-precision real numbers.
Please note that replacing mat[x_]
and/or fu[x_]
with mat[x_?NumericQ]
and/or fu[x_?NumericQ]
totally ruins the code, even if the Method
specification is not used.
Could anyone please fix my solution or come up with a better one?
(Of course, the problem I'm trying to solve is highly non-linear; however, I typically do have a pretty good estimate for the value of starting
. So, for small matrices the same code without specifying the Method
works well.)
fu[x_?NumericQ]
totally ruins the code? Without it I'm getting messages about a singular Jacobian whenever I try to insert the initial condition inside the function to avoid that issue. $\endgroup$ – b3m2a1 Oct 22 '19 at 4:59Method
, the code works as it should. $\endgroup$ – mavzolej Oct 22 '19 at 7:01_NumericQ
to definitions does not seem to resolve the issue. $\endgroup$ – mavzolej Oct 22 '19 at 7:06