00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026
00027 #include "ov.h"
00028 #include "defun-dld.h"
00029 #include "error.h"
00030 #include "gripes.h"
00031 #include "quit.h"
00032 #include "variables.h"
00033 #include "ov-re-sparse.h"
00034 #include "ov-cx-sparse.h"
00035 #include "oct-map.h"
00036 #include "pager.h"
00037 #include "unwind-prot.h"
00038
00039 #include "eigs-base.cc"
00040
00041
00042 static octave_function *eigs_fcn = 0;
00043
00044
00045 static bool warned_imaginary = false;
00046
00047
00048 static int call_depth = 0;
00049
00050 ColumnVector
00051 eigs_func (const ColumnVector &x, int &eigs_error)
00052 {
00053 ColumnVector retval;
00054 octave_value_list args;
00055 args(0) = x;
00056
00057 if (eigs_fcn)
00058 {
00059 octave_value_list tmp = eigs_fcn->do_multi_index_op (1, args);
00060
00061 if (error_state)
00062 {
00063 eigs_error = 1;
00064 gripe_user_supplied_eval ("eigs");
00065 return retval;
00066 }
00067
00068 if (tmp.length () && tmp(0).is_defined ())
00069 {
00070 if (! warned_imaginary && tmp(0).is_complex_type ())
00071 {
00072 warning ("eigs: ignoring imaginary part returned from user-supplied function");
00073 warned_imaginary = true;
00074 }
00075
00076 retval = ColumnVector (tmp(0).vector_value ());
00077
00078 if (error_state)
00079 {
00080 eigs_error = 1;
00081 gripe_user_supplied_eval ("eigs");
00082 }
00083 }
00084 else
00085 {
00086 eigs_error = 1;
00087 gripe_user_supplied_eval ("eigs");
00088 }
00089 }
00090
00091 return retval;
00092 }
00093
00094 ComplexColumnVector
00095 eigs_complex_func (const ComplexColumnVector &x, int &eigs_error)
00096 {
00097 ComplexColumnVector retval;
00098 octave_value_list args;
00099 args(0) = x;
00100
00101 if (eigs_fcn)
00102 {
00103 octave_value_list tmp = eigs_fcn->do_multi_index_op (1, args);
00104
00105 if (error_state)
00106 {
00107 eigs_error = 1;
00108 gripe_user_supplied_eval ("eigs");
00109 return retval;
00110 }
00111
00112 if (tmp.length () && tmp(0).is_defined ())
00113 {
00114 retval = ComplexColumnVector (tmp(0).complex_vector_value ());
00115
00116 if (error_state)
00117 {
00118 eigs_error = 1;
00119 gripe_user_supplied_eval ("eigs");
00120 }
00121 }
00122 else
00123 {
00124 eigs_error = 1;
00125 gripe_user_supplied_eval ("eigs");
00126 }
00127 }
00128
00129 return retval;
00130 }
00131
00132 DEFUN_DLD (eigs, args, nargout,
00133 "-*- texinfo -*-\n\
00134 @deftypefn {Loadable Function} {@var{d} =} eigs (@var{A})\n\
00135 @deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{k})\n\
00136 @deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{k}, @var{sigma})\n\
00137 @deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{k}, @var{sigma}, @var{opts})\n\
00138 @deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{B})\n\
00139 @deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{B}, @var{k})\n\
00140 @deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{B}, @var{k}, @var{sigma})\n\
00141 @deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{B}, @var{k}, @var{sigma}, @var{opts})\n\
00142 @deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n})\n\
00143 @deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{B})\n\
00144 @deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{k})\n\
00145 @deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{B}, @var{k})\n\
00146 @deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{k}, @var{sigma})\n\
00147 @deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{B}, @var{k}, @var{sigma})\n\
00148 @deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{k}, @var{sigma}, @var{opts})\n\
00149 @deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{B}, @var{k}, @var{sigma}, @var{opts})\n\
00150 @deftypefnx {Loadable Function} {[@var{V}, @var{d}] =} eigs (@var{A}, @dots{})\n\
00151 @deftypefnx {Loadable Function} {[@var{V}, @var{d}] =} eigs (@var{af}, @var{n}, @dots{})\n\
00152 @deftypefnx {Loadable Function} {[@var{V}, @var{d}, @var{flag}] =} eigs (@var{A}, @dots{})\n\
00153 @deftypefnx {Loadable Function} {[@var{V}, @var{d}, @var{flag}] =} eigs (@var{af}, @var{n}, @dots{})\n\
00154 Calculate a limited number of eigenvalues and eigenvectors of @var{A},\n\
00155 based on a selection criteria. The number of eigenvalues and eigenvectors to\n\
00156 calculate is given by @var{k} and defaults to 6.\n\
00157 \n\
00158 By default, @code{eigs} solve the equation\n\
00159 @tex\n\
00160 $A \\nu = \\lambda \\nu$,\n\
00161 @end tex\n\
00162 @ifinfo\n\
00163 @code{A * v = lambda * v},\n\
00164 @end ifinfo\n\
00165 where\n\
00166 @tex\n\
00167 $\\lambda$ is a scalar representing one of the eigenvalues, and $\\nu$\n\
00168 @end tex\n\
00169 @ifinfo\n\
00170 @code{lambda} is a scalar representing one of the eigenvalues, and @code{v}\n\
00171 @end ifinfo\n\
00172 is the corresponding eigenvector. If given the positive definite matrix\n\
00173 @var{B} then @code{eigs} solves the general eigenvalue equation\n\
00174 @tex\n\
00175 $A \\nu = \\lambda B \\nu$.\n\
00176 @end tex\n\
00177 @ifinfo\n\
00178 @code{A * v = lambda * B * v}.\n\
00179 @end ifinfo\n\
00180 \n\
00181 The argument @var{sigma} determines which eigenvalues are returned.\n\
00182 @var{sigma} can be either a scalar or a string. When @var{sigma} is a\n\
00183 scalar, the @var{k} eigenvalues closest to @var{sigma} are returned. If\n\
00184 @var{sigma} is a string, it must have one of the following values.\n\
00185 \n\
00186 @table @asis\n\
00187 @item 'lm'\n\
00188 Largest Magnitude (default).\n\
00189 \n\
00190 @item 'sm'\n\
00191 Smallest Magnitude.\n\
00192 \n\
00193 @item 'la'\n\
00194 Largest Algebraic (valid only for real symmetric problems).\n\
00195 \n\
00196 @item 'sa'\n\
00197 Smallest Algebraic (valid only for real symmetric problems).\n\
00198 \n\
00199 @item 'be'\n\
00200 Both Ends, with one more from the high-end if @var{k} is odd (valid only for\n\
00201 real symmetric problems).\n\
00202 \n\
00203 @item 'lr'\n\
00204 Largest Real part (valid only for complex or unsymmetric problems).\n\
00205 \n\
00206 @item 'sr'\n\
00207 Smallest Real part (valid only for complex or unsymmetric problems).\n\
00208 \n\
00209 @item 'li'\n\
00210 Largest Imaginary part (valid only for complex or unsymmetric problems).\n\
00211 \n\
00212 @item 'si'\n\
00213 Smallest Imaginary part (valid only for complex or unsymmetric problems).\n\
00214 @end table\n\
00215 \n\
00216 If @var{opts} is given, it is a structure defining possible options that\n\
00217 @code{eigs} should use. The fields of the @var{opts} structure are:\n\
00218 \n\
00219 @table @code\n\
00220 @item issym\n\
00221 If @var{af} is given, then flags whether the function @var{af} defines a\n\
00222 symmetric problem. It is ignored if @var{A} is given. The default is false.\n\
00223 \n\
00224 @item isreal\n\
00225 If @var{af} is given, then flags whether the function @var{af} defines a\n\
00226 real problem. It is ignored if @var{A} is given. The default is true.\n\
00227 \n\
00228 @item tol\n\
00229 Defines the required convergence tolerance, calculated as\n\
00230 @code{tol * norm (A)}. The default is @code{eps}.\n\
00231 \n\
00232 @item maxit\n\
00233 The maximum number of iterations. The default is 300.\n\
00234 \n\
00235 @item p\n\
00236 The number of Lanzcos basis vectors to use. More vectors will result in\n\
00237 faster convergence, but a greater use of memory. The optimal value of\n\
00238 @code{p} is problem dependent and should be in the range @var{k} to @var{n}.\n\
00239 The default value is @code{2 * @var{k}}.\n\
00240 \n\
00241 @item v0\n\
00242 The starting vector for the algorithm. An initial vector close to the\n\
00243 final vector will speed up convergence. The default is for @sc{arpack}\n\
00244 to randomly generate a starting vector. If specified, @code{v0} must be\n\
00245 an @var{n}-by-1 vector where @code{@var{n} = rows (@var{A})}\n\
00246 \n\
00247 @item disp\n\
00248 The level of diagnostic printout (0|1|2). If @code{disp} is 0 then\n\
00249 diagnostics are disabled. The default value is 0.\n\
00250 \n\
00251 @item cholB\n\
00252 Flag if @code{chol (@var{B})} is passed rather than @var{B}. The default is\n\
00253 false.\n\
00254 \n\
00255 @item permB\n\
00256 The permutation vector of the Cholesky@tie{}factorization of @var{B} if\n\
00257 @code{cholB} is true. That is @code{chol (@var{B}(permB, permB))}. The\n\
00258 default is @code{1:@var{n}}.\n\
00259 \n\
00260 @end table\n\
00261 It is also possible to represent @var{A} by a function denoted @var{af}.\n\
00262 @var{af} must be followed by a scalar argument @var{n} defining the length\n\
00263 of the vector argument accepted by @var{af}. @var{af} can be\n\
00264 a function handle, an inline function, or a string. When @var{af} is a\n\
00265 string it holds the name of the function to use.\n\
00266 \n\
00267 @var{af} is a function of the form @code{y = af (x)}\n\
00268 where the required return value of @var{af} is determined by\n\
00269 the value of @var{sigma}. The four possible forms are\n\
00270 \n\
00271 @table @code\n\
00272 @item A * x\n\
00273 if @var{sigma} is not given or is a string other than 'sm'.\n\
00274 \n\
00275 @item A \\ x\n\
00276 if @var{sigma} is 0 or 'sm'.\n\
00277 \n\
00278 @item (A - sigma * I) \\ x\n\
00279 for the standard eigenvalue problem, where @code{I} is the identity matrix of\n\
00280 the same size as @var{A}.\n\
00281 \n\
00282 @item (A - sigma * B) \\ x\n\
00283 for the general eigenvalue problem.\n\
00284 @end table\n\
00285 \n\
00286 The return arguments of @code{eigs} depend on the number of return arguments\n\
00287 requested. With a single return argument, a vector @var{d} of length @var{k}\n\
00288 is returned containing the @var{k} eigenvalues that have been found. With\n\
00289 two return arguments, @var{V} is a @var{n}-by-@var{k} matrix whose columns\n\
00290 are the @var{k} eigenvectors corresponding to the returned eigenvalues. The\n\
00291 eigenvalues themselves are returned in @var{d} in the form of a\n\
00292 @var{n}-by-@var{k} matrix, where the elements on the diagonal are the\n\
00293 eigenvalues.\n\
00294 \n\
00295 Given a third return argument @var{flag}, @code{eigs} returns the status\n\
00296 of the convergence. If @var{flag} is 0 then all eigenvalues have converged.\n\
00297 Any other value indicates a failure to converge.\n\
00298 \n\
00299 This function is based on the @sc{arpack} package, written by R. Lehoucq,\n\
00300 K. Maschhoff, D. Sorensen, and C. Yang. For more information see\n\
00301 @url{http://www.caam.rice.edu/software/ARPACK/}.\n\
00302 \n\
00303 @seealso{eig, svds}\n\
00304 @end deftypefn")
00305 {
00306 octave_value_list retval;
00307 #ifdef HAVE_ARPACK
00308 int nargin = args.length ();
00309 std::string fcn_name;
00310 octave_idx_type n = 0;
00311 octave_idx_type k = 6;
00312 Complex sigma = 0.;
00313 double sigmar, sigmai;
00314 bool have_sigma = false;
00315 std::string typ = "LM";
00316 Matrix amm, bmm, bmt;
00317 ComplexMatrix acm, bcm, bct;
00318 SparseMatrix asmm, bsmm, bsmt;
00319 SparseComplexMatrix ascm, bscm, bsct;
00320 int b_arg = 0;
00321 bool have_b = false;
00322 bool have_a_fun = false;
00323 bool a_is_complex = false;
00324 bool b_is_complex = false;
00325 bool symmetric = false;
00326 bool sym_tested = false;
00327 bool cholB = false;
00328 bool a_is_sparse = false;
00329 ColumnVector permB;
00330 int arg_offset = 0;
00331 double tol = DBL_EPSILON;
00332 int maxit = 300;
00333 int disp = 0;
00334 octave_idx_type p = -1;
00335 ColumnVector resid;
00336 ComplexColumnVector cresid;
00337 octave_idx_type info = 1;
00338
00339 warned_imaginary = false;
00340
00341 unwind_protect frame;
00342
00343 frame.protect_var (call_depth);
00344 call_depth++;
00345
00346 if (call_depth > 1)
00347 {
00348 error ("eigs: invalid recursive call");
00349 if (fcn_name.length())
00350 clear_function (fcn_name);
00351 return retval;
00352 }
00353
00354 if (nargin == 0)
00355 print_usage ();
00356 else if (args(0).is_function_handle () || args(0).is_inline_function ()
00357 || args(0).is_string ())
00358 {
00359 if (args(0).is_string ())
00360 {
00361 std::string name = args(0).string_value ();
00362 std::string fname = "function y = ";
00363 fcn_name = unique_symbol_name ("__eigs_fcn_");
00364 fname.append (fcn_name);
00365 fname.append ("(x) y = ");
00366 eigs_fcn = extract_function (args(0), "eigs", fcn_name, fname,
00367 "; endfunction");
00368 }
00369 else
00370 eigs_fcn = args(0).function_value ();
00371
00372 if (!eigs_fcn)
00373 {
00374 error ("eigs: unknown function");
00375 return retval;
00376 }
00377
00378 if (nargin < 2)
00379 {
00380 error ("eigs: incorrect number of arguments");
00381 return retval;
00382 }
00383 else
00384 {
00385 n = args(1).nint_value ();
00386 arg_offset = 1;
00387 have_a_fun = true;
00388 }
00389 }
00390 else
00391 {
00392 if (args(0).is_complex_type ())
00393 {
00394 if (args(0).is_sparse_type ())
00395 {
00396 ascm = (args(0).sparse_complex_matrix_value());
00397 a_is_sparse = true;
00398 }
00399 else
00400 acm = (args(0).complex_matrix_value());
00401 a_is_complex = true;
00402 symmetric = false;
00403 sym_tested = true;
00404 }
00405 else
00406 {
00407 if (args(0).is_sparse_type ())
00408 {
00409 asmm = (args(0).sparse_matrix_value());
00410 a_is_sparse = true;
00411 }
00412 else
00413 {
00414 amm = (args(0).matrix_value());
00415 }
00416 }
00417
00418 }
00419
00420
00421
00422 if (!error_state && nargin > 1 + arg_offset &&
00423 !(args(1 + arg_offset).is_real_scalar ()))
00424 {
00425 if (args(1+arg_offset).is_complex_type ())
00426 {
00427 b_arg = 1+arg_offset;
00428 have_b = true;
00429 b_is_complex = true;
00430 arg_offset++;
00431 }
00432 else
00433 {
00434 b_arg = 1+arg_offset;
00435 have_b = true;
00436 arg_offset++;
00437 }
00438 }
00439
00440 if (!error_state && nargin > (1+arg_offset))
00441 k = args(1+arg_offset).nint_value ();
00442
00443 if (!error_state && nargin > (2+arg_offset))
00444 {
00445 if (args(2+arg_offset).is_string ())
00446 {
00447 typ = args(2+arg_offset).string_value ();
00448
00449
00450 transform (typ.begin (), typ.end (), typ.begin (), toupper);
00451
00452 sigma = 0.;
00453 }
00454 else
00455 {
00456 sigma = args(2+arg_offset).complex_value ();
00457
00458 if (! error_state)
00459 have_sigma = true;
00460 else
00461 {
00462 error ("eigs: SIGMA must be a scalar or a string");
00463 return retval;
00464 }
00465 }
00466 }
00467
00468 sigmar = std::real (sigma);
00469 sigmai = std::imag (sigma);
00470
00471 if (!error_state && nargin > (3+arg_offset))
00472 {
00473 if (args(3+arg_offset).is_map ())
00474 {
00475 octave_scalar_map map = args(3+arg_offset).scalar_map_value ();
00476
00477 if (! error_state)
00478 {
00479 octave_value tmp;
00480
00481
00482 tmp = map.getfield ("issym");
00483 if (tmp.is_defined () && !sym_tested)
00484 {
00485 symmetric = tmp.double_value () != 0.;
00486 sym_tested = true;
00487 }
00488
00489
00490 tmp = map.getfield ("isreal");
00491 if (tmp.is_defined () && have_a_fun)
00492 a_is_complex = ! (tmp.double_value () != 0.);
00493
00494 tmp = map.getfield ("tol");
00495 if (tmp.is_defined ())
00496 tol = tmp.double_value ();
00497
00498 tmp = map.getfield ("maxit");
00499 if (tmp.is_defined ())
00500 maxit = tmp.nint_value ();
00501
00502 tmp = map.getfield ("p");
00503 if (tmp.is_defined ())
00504 p = tmp.nint_value ();
00505
00506 tmp = map.getfield ("v0");
00507 if (tmp.is_defined ())
00508 {
00509 if (a_is_complex || b_is_complex)
00510 cresid = ComplexColumnVector (tmp.complex_vector_value ());
00511 else
00512 resid = ColumnVector (tmp.vector_value ());
00513 }
00514
00515 tmp = map.getfield ("disp");
00516 if (tmp.is_defined ())
00517 disp = tmp.nint_value ();
00518
00519 tmp = map.getfield ("cholB");
00520 if (tmp.is_defined ())
00521 cholB = tmp.double_value () != 0.;
00522
00523 tmp = map.getfield ("permB");
00524 if (tmp.is_defined ())
00525 permB = ColumnVector (tmp.vector_value ()) - 1.0;
00526 }
00527 else
00528 {
00529 error ("eigs: OPTS argument must be a scalar structure");
00530 return retval;
00531 }
00532 }
00533 else
00534 {
00535 error ("eigs: OPTS argument must be a structure");
00536 return retval;
00537 }
00538 }
00539
00540 if (nargin > (4+arg_offset))
00541 {
00542 error ("eigs: incorrect number of arguments");
00543 return retval;
00544 }
00545
00546
00547 if (!sym_tested && !have_a_fun)
00548 {
00549 if (a_is_sparse)
00550 symmetric = asmm.is_symmetric();
00551 else
00552 symmetric = amm.is_symmetric();
00553 }
00554
00555 if (have_b)
00556 {
00557 if (a_is_complex || b_is_complex)
00558 {
00559 if (a_is_sparse)
00560 bscm = args(b_arg).sparse_complex_matrix_value ();
00561 else
00562 bcm = args(b_arg).complex_matrix_value ();
00563 }
00564 else
00565 {
00566 if (a_is_sparse)
00567 bsmm = args(b_arg).sparse_matrix_value ();
00568 else
00569 bmm = args(b_arg).matrix_value ();
00570 }
00571 }
00572
00573
00574
00575 if (!error_state && !have_sigma && typ == "SM")
00576 have_sigma = true;
00577
00578 if (!error_state)
00579 {
00580 octave_idx_type nconv;
00581 if (a_is_complex || b_is_complex)
00582 {
00583 ComplexMatrix eig_vec;
00584 ComplexColumnVector eig_val;
00585
00586
00587 if (have_a_fun)
00588 nconv = EigsComplexNonSymmetricFunc
00589 (eigs_complex_func, n, typ, sigma, k, p, info, eig_vec, eig_val,
00590 cresid, octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
00591 else if (have_sigma)
00592 {
00593 if (a_is_sparse)
00594 nconv = EigsComplexNonSymmetricMatrixShift
00595 (ascm, sigma, k, p, info, eig_vec, eig_val, bscm, permB,
00596 cresid, octave_stdout, tol, (nargout > 1), cholB, disp,
00597 maxit);
00598 else
00599 nconv = EigsComplexNonSymmetricMatrixShift
00600 (acm, sigma, k, p, info, eig_vec, eig_val, bcm, permB, cresid,
00601 octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
00602 }
00603 else
00604 {
00605 if (a_is_sparse)
00606 nconv = EigsComplexNonSymmetricMatrix
00607 (ascm, typ, k, p, info, eig_vec, eig_val, bscm, permB, cresid,
00608 octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
00609 else
00610 nconv = EigsComplexNonSymmetricMatrix
00611 (acm, typ, k, p, info, eig_vec, eig_val, bcm, permB, cresid,
00612 octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
00613 }
00614
00615 if (nargout < 2)
00616 retval (0) = eig_val;
00617 else
00618 {
00619 retval(2) = double (info);
00620 retval(1) = ComplexDiagMatrix (eig_val);
00621 retval(0) = eig_vec;
00622 }
00623 }
00624 else if (sigmai != 0.)
00625 {
00626
00627 ComplexMatrix eig_vec;
00628 ComplexColumnVector eig_val;
00629
00630 if (have_a_fun)
00631 nconv = EigsComplexNonSymmetricFunc
00632 (eigs_complex_func, n, typ, sigma, k, p, info, eig_vec, eig_val,
00633 cresid, octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
00634 else
00635 {
00636 if (a_is_sparse)
00637 nconv = EigsComplexNonSymmetricMatrixShift
00638 (SparseComplexMatrix (asmm), sigma, k, p, info, eig_vec,
00639 eig_val, SparseComplexMatrix (bsmm), permB, cresid,
00640 octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
00641 else
00642 nconv = EigsComplexNonSymmetricMatrixShift
00643 (ComplexMatrix (amm), sigma, k, p, info, eig_vec,
00644 eig_val, ComplexMatrix (bmm), permB, cresid,
00645 octave_stdout, tol, (nargout > 1), cholB, disp, maxit);
00646 }
00647
00648 if (nargout < 2)
00649 retval (0) = eig_val;
00650 else
00651 {
00652 retval(2) = double (info);
00653 retval(1) = ComplexDiagMatrix (eig_val);
00654 retval(0) = eig_vec;
00655 }
00656 }
00657 else
00658 {
00659 if (symmetric)
00660 {
00661 Matrix eig_vec;
00662 ColumnVector eig_val;
00663
00664 if (have_a_fun)
00665 nconv = EigsRealSymmetricFunc
00666 (eigs_func, n, typ, sigmar, k, p, info, eig_vec, eig_val,
00667 resid, octave_stdout, tol, (nargout > 1), cholB, disp,
00668 maxit);
00669 else if (have_sigma)
00670 {
00671 if (a_is_sparse)
00672 nconv = EigsRealSymmetricMatrixShift
00673 (asmm, sigmar, k, p, info, eig_vec, eig_val, bsmm, permB,
00674 resid, octave_stdout, tol, (nargout > 1), cholB, disp,
00675 maxit);
00676 else
00677 nconv = EigsRealSymmetricMatrixShift
00678 (amm, sigmar, k, p, info, eig_vec, eig_val, bmm, permB,
00679 resid, octave_stdout, tol, (nargout > 1), cholB, disp,
00680 maxit);
00681 }
00682 else
00683 {
00684 if (a_is_sparse)
00685 nconv = EigsRealSymmetricMatrix
00686 (asmm, typ, k, p, info, eig_vec, eig_val, bsmm, permB,
00687 resid, octave_stdout, tol, (nargout > 1), cholB, disp,
00688 maxit);
00689 else
00690 nconv = EigsRealSymmetricMatrix
00691 (amm, typ, k, p, info, eig_vec, eig_val, bmm, permB,
00692 resid, octave_stdout, tol, (nargout > 1), cholB, disp,
00693 maxit);
00694 }
00695
00696 if (nargout < 2)
00697 retval (0) = eig_val;
00698 else
00699 {
00700 retval(2) = double (info);
00701 retval(1) = DiagMatrix (eig_val);
00702 retval(0) = eig_vec;
00703 }
00704 }
00705 else
00706 {
00707 ComplexMatrix eig_vec;
00708 ComplexColumnVector eig_val;
00709
00710 if (have_a_fun)
00711 nconv = EigsRealNonSymmetricFunc
00712 (eigs_func, n, typ, sigmar, k, p, info, eig_vec, eig_val,
00713 resid, octave_stdout, tol, (nargout > 1), cholB, disp,
00714 maxit);
00715 else if (have_sigma)
00716 {
00717 if (a_is_sparse)
00718 nconv = EigsRealNonSymmetricMatrixShift
00719 (asmm, sigmar, k, p, info, eig_vec, eig_val, bsmm, permB,
00720 resid, octave_stdout, tol, (nargout > 1), cholB, disp,
00721 maxit);
00722 else
00723 nconv = EigsRealNonSymmetricMatrixShift
00724 (amm, sigmar, k, p, info, eig_vec, eig_val, bmm, permB,
00725 resid, octave_stdout, tol, (nargout > 1), cholB, disp,
00726 maxit);
00727 }
00728 else
00729 {
00730 if (a_is_sparse)
00731 nconv = EigsRealNonSymmetricMatrix
00732 (asmm, typ, k, p, info, eig_vec, eig_val, bsmm, permB,
00733 resid, octave_stdout, tol, (nargout > 1), cholB, disp,
00734 maxit);
00735 else
00736 nconv = EigsRealNonSymmetricMatrix
00737 (amm, typ, k, p, info, eig_vec, eig_val, bmm, permB,
00738 resid, octave_stdout, tol, (nargout > 1), cholB, disp,
00739 maxit);
00740 }
00741
00742 if (nargout < 2)
00743 retval (0) = eig_val;
00744 else
00745 {
00746 retval(2) = double (info);
00747 retval(1) = ComplexDiagMatrix (eig_val);
00748 retval(0) = eig_vec;
00749 }
00750 }
00751 }
00752
00753 if (nconv <= 0)
00754 warning ("eigs: None of the %d requested eigenvalues converged", k);
00755 else if (nconv < k)
00756 warning ("eigs: Only %d of the %d requested eigenvalues converged",
00757 nconv, k);
00758 }
00759
00760 if (! fcn_name.empty ())
00761 clear_function (fcn_name);
00762 #else
00763 error ("eigs: not available in this version of Octave");
00764 #endif
00765
00766 return retval;
00767 }
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532