26 #if defined (HAVE_CONFIG_H)
50 #if defined (HAVE_ARPACK)
56 eigs_callback (octave::interpreter& interp)
57 : m_interpreter (interp)
68 octave::interpreter& m_interpreter;
74 bool m_warned_imaginary =
false;
78 static int call_depth = 0;
81 eigs_callback::eigs_func (
const ColumnVector&
x,
int& eigs_error)
87 if (m_eigs_fcn.is_defined ())
93 tmp = m_interpreter.feval (m_eigs_fcn, args, 1);
95 catch (octave::execution_exception& ee)
100 if (tmp.
length () && tmp(0).is_defined ())
102 if (! m_warned_imaginary && tmp(0).iscomplex ())
104 warning (
"eigs: ignoring imaginary part returned from user-supplied function");
105 m_warned_imaginary =
true;
108 retval = tmp(0).xvector_value (
"eigs: evaluation of user-supplied function failed");
128 if (m_eigs_fcn.is_defined ())
134 tmp = m_interpreter.feval (m_eigs_fcn, args, 1);
136 catch (octave::execution_exception& ee)
141 if (tmp.
length () && tmp(0).is_defined ())
143 retval = tmp(0).xcomplex_vector_value (
"eigs: evaluation of user-supplied function failed");
157 DEFMETHOD (__eigs__, interp, args, nargout,
182 #if defined (HAVE_ARPACK)
184 int nargin = args.
length ();
191 std::string fcn_name;
195 double sigmar, sigmai;
196 bool have_sigma =
false;
197 std::string typ =
"LM";
204 bool have_a_fcn =
false;
205 bool a_is_complex =
false;
206 bool b_is_complex =
false;
207 bool symmetric =
false;
208 bool sym_tested =
false;
210 bool a_is_sparse =
false;
211 bool b_is_sparse =
false;
214 double tol = std::numeric_limits<double>::epsilon ();
222 eigs_callback callback (interp);
228 error (
"eigs: invalid recursive call");
230 if (args(0).is_function_handle () || args(0).is_inline_function ()
231 || args(0).is_string ())
235 if (callback.m_eigs_fcn.is_undefined ())
236 error (
"eigs: unknown function");
239 error (
"eigs: incorrect number of arguments");
241 n = args(1).nint_value ();
247 if (args(0).iscomplex ())
249 if (args(0).issparse ())
251 ascm = (args(0).sparse_complex_matrix_value ());
255 acm = (args(0).complex_matrix_value ());
260 if (args(0).issparse ())
262 asmm = (args(0).sparse_matrix_value ());
267 amm = (args(0).matrix_value ());
274 if (nargin > 1 + arg_offset
275 && ! (args(1 + arg_offset).is_real_scalar ()))
277 if (args(1+arg_offset).iscomplex ())
279 b_arg = 1+arg_offset;
280 if (args(b_arg).issparse ())
282 bscm = (args(b_arg).sparse_complex_matrix_value ());
286 bcm = (args(b_arg).complex_matrix_value ());
293 b_arg = 1+arg_offset;
294 if (args(b_arg).issparse ())
296 bsmm = (args(b_arg).sparse_matrix_value ());
300 bmm = (args(b_arg).matrix_value ());
306 if (nargin > (1+arg_offset))
307 k = args(1+arg_offset).nint_value ();
309 if (nargin > (2+arg_offset))
311 if (args(2+arg_offset).is_string ())
313 typ = args(2+arg_offset).string_value ();
316 transform (typ.begin (), typ.end (), typ.begin (), toupper);
322 sigma = args(2+arg_offset).xcomplex_value (
"eigs: SIGMA must be a scalar or a string");
328 sigmar = sigma.real ();
329 sigmai = sigma.imag ();
331 if (nargin > (3+arg_offset))
333 if (! args(3+arg_offset).isstruct ())
334 error (
"eigs: OPTS argument must be a structure");
337 +arg_offset).xscalar_map_value (
"eigs: OPTS argument must be a scalar structure");
345 if (tmp.
numel () != 1)
346 error (
"eigs: OPTS.issym must be a scalar value");
348 symmetric = tmp.
xbool_value (
"eigs: OPTS.issym must be a logical value");
358 if (tmp.
numel () != 1)
359 error (
"eigs: OPTS.isreal must be a scalar value");
361 a_is_complex = ! tmp.
xbool_value (
"eigs: OPTS.isreal must be a logical value");
380 if (a_is_complex || b_is_complex)
393 if (tmp.
numel () != 1)
394 error (
"eigs: OPTS.cholB must be a scalar value");
396 cholB = tmp.
xbool_value (
"eigs: OPTS.cholB must be a logical value");
404 if (nargin > (4+arg_offset))
405 error (
"eigs: incorrect number of arguments");
408 if (! sym_tested && ! have_a_fcn)
428 if (a_is_complex || b_is_complex)
431 bscm = args(b_arg).sparse_complex_matrix_value ();
433 bcm = args(b_arg).complex_matrix_value ();
438 bsmm = args(b_arg).sparse_matrix_value ();
440 bmm = args(b_arg).matrix_value ();
446 if (! have_sigma && typ ==
"SM")
450 if (a_is_complex || b_is_complex)
456 return callback.eigs_complex_func (
x, eigs_error);
466 (eigs_complex_fcn,
n, typ, sigma, k, p, info, eig_vec,
468 (nargout > 1), cholB, disp, maxit);
471 (eigs_complex_fcn,
n, typ, sigma, k, p, info, eig_vec,
473 (nargout > 1), cholB, disp, maxit);
479 (ascm, sigma, k, p, info, eig_vec, eig_val, bscm, permB,
484 (acm, sigma, k, p, info, eig_vec, eig_val, bcm, permB,
492 (ascm, typ, k, p, info, eig_vec, eig_val, bscm, permB,
497 (acm, typ, k, p, info, eig_vec, eig_val, bcm, permB,
505 retval(0) =
real (eig_val);
517 else if (sigmai != 0.0)
523 return callback.eigs_complex_func (
x, eigs_error);
534 (eigs_complex_fcn,
n, typ, sigma, k, p, info, eig_vec,
536 (nargout > 1), cholB, disp, maxit);
539 (eigs_complex_fcn,
n, typ, sigma, k, p, info, eig_vec,
541 (nargout > 1), cholB, disp, maxit);
560 retval(0) =
real (eig_val);
576 return callback.eigs_func (
x, eigs_error);
588 (eigs_fcn,
n, typ, sigmar, k, p, info, eig_vec,
590 (nargout > 1), cholB, disp, maxit);
593 (eigs_fcn,
n, typ, sigmar, k, p, info, eig_vec,
595 (nargout > 1), cholB, disp, maxit);
601 (asmm, sigmar, k, p, info, eig_vec, eig_val, bsmm,
606 (amm, sigmar, k, p, info, eig_vec, eig_val, bmm,
614 (asmm, typ, k, p, info, eig_vec, eig_val, bsmm,
619 (amm, typ, k, p, info, eig_vec, eig_val, bmm, permB,
638 (eigs_fcn,
n, typ, sigmar, k, p, info, eig_vec,
640 (nargout > 1), cholB, disp, maxit);
643 (eigs_fcn,
n, typ, sigmar, k, p, info, eig_vec,
645 (nargout > 1), cholB, disp, maxit);
651 (asmm, sigmar, k, p, info, eig_vec, eig_val, bsmm,
656 (amm, sigmar, k, p, info, eig_vec, eig_val, bmm,
664 (asmm, typ, k, p, info, eig_vec, eig_val, bsmm,
669 (amm, typ, k, p, info, eig_vec, eig_val, bmm, permB,
683 "eigs: None of the %" OCTAVE_IDX_TYPE_FORMAT
684 " requested eigenvalues converged", k);
687 "eigs: Only %" OCTAVE_IDX_TYPE_FORMAT
688 " of the %" OCTAVE_IDX_TYPE_FORMAT
689 " requested eigenvalues converged",
692 if (! fcn_name.empty ())
703 octave_unused_parameter (interp);
704 octave_unused_parameter (args);
705 octave_unused_parameter (nargout);
717 OCTAVE_END_NAMESPACE(
octave)
octave_value getfield(const std::string &key) const
octave_idx_type length() const
bool xbool_value(const char *fmt,...) const
octave_idx_type numel() const
int nint_value(bool frc_str_conv=false) const
Array< double > vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
Array< Complex > complex_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
double double_value(bool frc_str_conv=false) const
void clear_function(const std::string &name)
ColumnVector real(const ComplexColumnVector &a)
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
octave_idx_type EigsRealNonSymmetricMatrixShift(const M &m, double sigmar, octave_idx_type k_arg, octave_idx_type p_arg, octave_idx_type &info, ComplexMatrix &eig_vec, ComplexColumnVector &eig_val, const M &_b, ColumnVector &permB, ColumnVector &resid, std::ostream &os, double tol, bool rvec, bool cholB, int disp, int maxit)
octave_idx_type EigsRealSymmetricMatrixShift(const M &m, double sigma, octave_idx_type k_arg, octave_idx_type p_arg, octave_idx_type &info, Matrix &eig_vec, ColumnVector &eig_val, const M &_b, ColumnVector &permB, ColumnVector &resid, std::ostream &os, double tol, bool rvec, bool cholB, int disp, int maxit)
octave_idx_type EigsRealNonSymmetricMatrix(const M &m, const std::string typ, octave_idx_type k_arg, octave_idx_type p_arg, octave_idx_type &info, ComplexMatrix &eig_vec, ComplexColumnVector &eig_val, const M &_b, ColumnVector &permB, ColumnVector &resid, std::ostream &os, double tol, bool rvec, bool cholB, int disp, int maxit)
octave_idx_type EigsComplexNonSymmetricMatrix(const M &m, const std::string typ, octave_idx_type k_arg, octave_idx_type p_arg, octave_idx_type &info, ComplexMatrix &eig_vec, ComplexColumnVector &eig_val, const M &_b, ColumnVector &permB, ComplexColumnVector &cresid, std::ostream &os, double tol, bool rvec, bool cholB, int disp, int maxit)
octave_idx_type EigsRealSymmetricFunc(EigsFunc fcn, octave_idx_type n_arg, const std::string &_typ, double sigma, octave_idx_type k_arg, octave_idx_type p_arg, octave_idx_type &info, Matrix &eig_vec, ColumnVector &eig_val, const M &_b, ColumnVector &permB, ColumnVector &resid, std::ostream &os, double tol, bool rvec, bool cholB, int disp, int maxit)
octave_idx_type EigsRealNonSymmetricFunc(EigsFunc fcn, octave_idx_type n_arg, const std::string &_typ, double sigmar, octave_idx_type k_arg, octave_idx_type p_arg, octave_idx_type &info, ComplexMatrix &eig_vec, ComplexColumnVector &eig_val, const M &_b, ColumnVector &permB, ColumnVector &resid, std::ostream &os, double tol, bool rvec, bool cholB, int disp, int maxit)
octave_idx_type EigsComplexNonSymmetricMatrixShift(const M &m, Complex sigma, octave_idx_type k_arg, octave_idx_type p_arg, octave_idx_type &info, ComplexMatrix &eig_vec, ComplexColumnVector &eig_val, const M &_b, ColumnVector &permB, ComplexColumnVector &cresid, std::ostream &os, double tol, bool rvec, bool cholB, int disp, int maxit)
octave_idx_type EigsRealSymmetricMatrix(const M &m, const std::string typ, octave_idx_type k_arg, octave_idx_type p_arg, octave_idx_type &info, Matrix &eig_vec, ColumnVector &eig_val, const M &_b, ColumnVector &permB, ColumnVector &resid, std::ostream &os, double tol, bool rvec, bool cholB, int disp, int maxit)
octave_idx_type EigsComplexNonSymmetricFunc(EigsComplexFunc fcn, octave_idx_type n_arg, const std::string &_typ, Complex sigma, octave_idx_type k_arg, octave_idx_type p_arg, octave_idx_type &info, ComplexMatrix &eig_vec, ComplexColumnVector &eig_val, const M &_b, ColumnVector &permB, ComplexColumnVector &cresid, std::ostream &os, double tol, bool rvec, bool cholB, int disp, int maxit)
std::function< ColumnVector(const ColumnVector &x, int &eigs_error)> EigsFunc
std::function< ComplexColumnVector(const ComplexColumnVector &x, int &eigs_error)> EigsComplexFunc
void warning(const char *fmt,...)
void warning_with_id(const char *id, const char *fmt,...)
void() error(const char *fmt,...)
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
void err_user_supplied_eval(const char *name)
ColumnVector transform(const Matrix &m, double x, double y, double z)
octave_value get_function_handle(interpreter &interp, const octave_value &arg, const std::string ¶meter_name)
F77_RET_T const F77_DBLE * x
std::complex< double > Complex
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.