1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) 2012 - Scilab Enterprises - Adeline CARNIS
4 // This file must be used under the terms of the CeCILL.
5 // This source file is licensed as described in the file COPYING, which
6 // you should have received as part of this distribution. The terms
7 // are also available at
8 // http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10 function [d, v] = eigs(varargin)
14 if(rhs == 0 | rhs > 6)
15 error(msprintf(gettext("%s : Wrong number of input arguments : %d to %d expected.\n"), "eigs", 1, 6));
19 if((typeof(varargin(1)) <> "constant") & typeof(varargin(1)) <> "function" & (typeof(varargin(1)) <> "sparse") | varargin(1) == [])
20 error(msprintf(gettext("%s: Wrong type for input argument #%d: A full or sparse square matrix or a function expected"), "eigs", 1));
24 if(rhs >= 1 & typeof(varargin(1)) <> "function")
25 if(isreal(varargin(1)))
26 resid = rand(size(varargin(1), "r"), 1);
28 resid = rand(size(varargin(1), "r"), 1).* %i;
32 if(rhs > 1 & typeof(varargin(1)) == "function")
33 if(size(varargin(2)) <> 1)
34 error(msprintf(gettext("%s: Wrong type for input argument #%d: A positive integer expected if the first input argument is a function."), "eigs",2));
38 resid = rand(varargin(2),1);
49 if(~issparse(varargin(1)))
53 if(~issparse(varargin(1)) & ~issparse(varargin(2)))
59 if(typeof(varargin(1)) <> "function")
62 nev = min(size(varargin(1), 'r'), 6)
65 if(issparse(varargin(1)))
66 d = speigs(varargin(1), [], nev, 'LM', maxiter, tol, ncv, cholB, resid, info);
68 d = %_eigs(varargin(1), [], nev, 'LM', maxiter, tol, ncv, cholB, resid, info);
71 if(issparse(varargin(1)))
72 [d, v] = speigs(varargin(1), [], nev, 'LM', maxiter, tol, ncv, cholB, resid, info);
74 [d, v] = %_eigs(varargin(1), [], nev, 'LM', maxiter, tol, ncv, cholB, resid, info);
79 nev = min(size(varargin(1), 'r'), 6)
82 if(issparse(varargin(1)) | issparse(varargin(2)))
83 d = speigs(varargin(1), varargin(2), nev, 'LM', maxiter, tol, ncv, cholB, resid, info);
85 d = %_eigs(varargin(1), varargin(2), nev, 'LM', maxiter, tol, ncv, cholB, resid, info);
88 if(issparse(varargin(1)) | issparse(varargin(2)))
89 [d, v] = speigs(varargin(1), varargin(2), nev, 'LM', maxiter, tol, ncv, cholB, resid, info);
91 [d, v] = %_eigs(varargin(1), varargin(2), nev, 'LM', maxiter, tol, ncv, cholB, resid, info);
98 if(issparse(varargin(1)) | issparse(varargin(2)))
99 d = speigs(varargin(1), varargin(2), varargin(3), 'LM', maxiter, tol, ncv, cholB, resid, info);
101 d = %_eigs(varargin(1), varargin(2), varargin(3), 'LM', maxiter, tol, ncv, cholB, resid, info);
104 if(issparse(varargin(1)) | issparse(varargin(2)))
105 [d, v] = speigs(varargin(1), varargin(2), varargin(3), 'LM', maxiter, tol, ncv, cholB, resid, info);
107 [d, v] = %_eigs(varargin(1), varargin(2), varargin(3), 'LM', maxiter, tol, ncv, cholB, resid, info);
114 if(issparse(varargin(1)) | issparse(varargin(2)))
115 d = speigs(varargin(1), varargin(2), varargin(3), varargin(4), maxiter, tol, ncv, cholB, resid, info);
117 d = %_eigs(varargin(1), varargin(2), varargin(3), varargin(4), maxiter, tol, ncv, cholB, resid, info);
120 if(issparse(varargin(1)) | issparse(varargin(2)))
121 [d, v] = speigs(varargin(1), varargin(2), varargin(3), varargin(4), maxiter, tol, ncv, cholB, resid, info);
123 [d, v] = %_eigs(varargin(1), varargin(2), varargin(3), varargin(4), maxiter, tol, ncv, cholB, resid, info);
132 error(msprintf(gettext("%s: Wrong type for input argument #%d: A structure expected"), "eigs", 5));
134 if(and(~isfield(opts, ["tol", "maxiter", "ncv", "resid", "cholB"])))
135 error(msprintf(gettext("%s: Wrong type for input argument: If A is a matrix, use opts with tol, maxiter, ncv, resid, cholB"), "eigs"));
137 if(isfield(opts, "tol"))
140 if(isfield(opts, "maxiter"))
141 maxiter = opts.maxiter;
143 if(isfield(opts, "ncv"))
146 if(isfield(opts, "resid"))
148 if(issparse(varargin(1)) | issparse(varargin(2)))
154 if(issparse(varargin(1)) | issparse(varargin(2)))
161 if(isfield(opts,"cholB"))
164 if(issparse(varargin(1)) | issparse(varargin(2)))
165 d = speigs(varargin(1), varargin(2), varargin(3), varargin(4), maxiter, tol, ncv, cholB, resid, info);
167 d = %_eigs(varargin(1), varargin(2), varargin(3), varargin(4), maxiter, tol, ncv, cholB, resid, info);
172 error(msprintf(gettext("%s: Wrong type for input argument #%d: A structure expected"), "eigs",5));
174 if(and(~isfield(opts, ["tol", "maxiter", "ncv", "resid", "cholB"])))
175 error(msprintf(gettext("%s: Wrong type for input argument: If A is a matrix, use opts with tol, maxiter, ncv, resid, cholB"), "eigs"));
177 if(isfield(opts, "tol"))
180 if(isfield(opts, "maxiter"))
181 maxiter = opts.maxiter;
183 if(isfield(opts, "ncv"))
186 if(isfield(opts, "resid"))
188 if(issparse(varargin(1)) | issparse(varargin(2)))
194 if(issparse(varargin(1)) | issparse(varargin(2)))
201 if(isfield(opts, "cholB"))
204 if(issparse(varargin(1)))
205 [d, v] = speigs(varargin(1), varargin(2), varargin(3), varargin(4), maxiter, tol, ncv, cholB, resid, info);
207 [d, v] = %_eigs(varargin(1), varargin(2), varargin(3), varargin(4), maxiter, tol, ncv, cholB, resid, info);
214 nev = min(varargin(2), 6)
217 d = feigs(varargin(1), varargin(2), [], nev, 'LM', maxiter, tol, ncv, cholB, resid, info, a_real, a_sym);
219 [d, v] = feigs(varargin(1), varargin(2), [], nev, 'LM', maxiter, tol, ncv, cholB, resid, info, a_real, a_sym);
222 nev = min(varargin(2), 6);
225 d = feigs(varargin(1), varargin(2), varargin(3), nev, 'LM', maxiter, tol, ncv, cholB, resid, info, a_real, a_sym);
227 [d, v] = feigs(varargin(1), varargin(2), varargin(3), nev, 'LM', maxiter, tol, ncv, cholB, resid, info, a_real, a_sym);
233 d = feigs(varargin(1), varargin(2), varargin(3), varargin(4), 'LM', maxiter, tol, ncv, cholB, resid, info, a_real, a_sym);
235 [d, v] = feigs(varargin(1), varargin(2), varargin(3), varargin(4), 'LM', maxiter, tol, ncv, cholB, resid, info, a_real, a_sym);
241 d = feigs(varargin(1), varargin(2), varargin(3), varargin(4), varargin(5), maxiter, tol, ncv, cholB, resid, info, a_real, a_sym);
243 [d, v] = feigs(varargin(1), varargin(2), varargin(3), varargin(4), varargin(5), maxiter, tol, ncv, cholB, resid, info, a_real, a_sym);
250 if(~isstruct(opts)) then
251 error(msprintf(gettext("%s: Wrong type for input argument #%d: A structure expected"), "eigs",5));
253 if(and(~isfield(opts, ["tol", "maxiter", "ncv", "resid", "cholB", "issym", "isreal"])))
254 error(msprintf(gettext("%s: Wrong type for input argument: Use opts with tol, maxiter, ncv, resid, cholB, issym, isreal"), "eigs"));
256 if(isfield(opts,"tol"))
259 if(isfield(opts,"maxiter"))
260 maxiter = opts.maxiter;
262 if(isfield(opts, "ncv"))
265 if(isfield(opts,"resid"))
272 if(isfield(opts,"cholB"))
275 if(isfield(opts,"issym"))
278 if(isfield(opts,"isreal"))
279 a_real = opts.isreal;
280 if(~a_real & ~isfield(opts,"resid"))
281 resid = rand(varargin(2),1).*%i;
285 d = feigs(varargin(1), varargin(2), varargin(3), varargin(4), varargin(5), maxiter, tol, ncv, cholB, resid, info, a_real, a_sym);
288 if (~isstruct(opts)) then
289 error(msprintf(gettext("%s: Wrong type for input argument #%d: A structure expected"), "eigs",5));
291 if (and(~isfield(opts, ["tol", "maxiter", "ncv", "resid", "cholB" ])))
292 error(msprintf(gettext("%s: Wrong type for input argument: Use opts with tol, maxiter, ncv, resid, cholB, issym, isreal"), "eigs"));
294 if (isfield(opts,"tol"))
297 if (isfield(opts,"maxiter"))
298 maxiter = opts.maxiter;
300 if (isfield(opts, "ncv"))
303 if(isfield(opts,"resid"))
310 if (isfield(opts,"cholB"))
313 if (isfield(opts,"isreal"))
314 a_real = opts.isreal;
315 if(~a_real & ~isfield(opts,"resid"))
316 resid = rand(varargin(2),1).*%i;
319 if (isfield(opts,"issym"))
322 [d, v] = feigs(varargin(1), varargin(2), varargin(3), varargin(4), varargin(5), maxiter, tol, ncv, cholB, resid, info, a_real, a_sym);
329 function [res_d, res_v] = speigs(A, %_B, nev, which, maxiter, tol, ncv, cholB, resid, info)
336 //**************************
338 //**************************
341 //check if A is a square matrix
342 if(mA * nA < 2 | mA <> nA)
343 error(msprintf(gettext("%s: Wrong type for input argument #%d: A square matrix expected.\n"), "eigs", 1));
346 //check if A is complex
349 //check if A is symetric
352 //*************************
353 //Second variable B :
354 //*************************
355 if((typeof(%_B) <> "constant") & (typeof(%_B) <> "sparse"))
356 error(msprintf(gettext("%s: Wrong type for input argument #%d: An empty matrix or full or sparse square matrix expected.\n"), "eigs", 2));
358 [mB, nB] = size(%_B);
360 //Check if B is a square matrix
361 if(mB * nB <> 0 & (mB <> mA | nB <> nA))
362 error(msprintf(gettext("%s: Wrong dimension for input argument #%d: B must have the same size as A.\n"), "eigs", 2));
365 //check if B is complex
369 //*************************
371 //*************************
372 //verification du type de nev
373 //check if nev is complex?
374 if(typeof(nev) <> "constant") | (~isreal(nev)) | (size(nev,"*") <> 1)
375 error(msprintf(gettext("%s: Wrong type for input argument #%d: A scalar expected.\n"), "eigs", 3));
378 if(nev <> floor(nev) | (nev<=0))
379 error(msprintf(gettext("%s: Wrong type for input argument #%d: k must be a positive integer.\n"), "eigs", 3));
382 if(Asym & Areal & Breal)
384 error(msprintf(gettext("%s: Wrong value for input argument #%d: For real symmetric problems, k must be an integer in the range 1 to N - 1.\n"), "eigs", 3));
388 error(msprintf(gettext("%s: Wrong value for input argument #%d: For real non symmetric or complex problems, k must be an integer in the range 1 to N - 2.\n"), "eigs", 3));
392 //*************************
394 //*************************
398 if(typeof(which) <> "constant" | which == [] | isnan(which))
399 error(msprintf(gettext("%s: Wrong type for input argument #%d: A scalar expected.\n"), "eigs", 4));
405 [mWHICH, nWHICH] = size(which);
406 if(mWHICH * nWHICH <> 1)
407 error(msprintf(gettext("%s: Wrong type for input argument #%d: A string expected.\n"), "eigs", 4));
409 if(strcmp(which,'LM') ~= 0 & strcmp(which,'SM') ~= 0 & strcmp(which,'LR') ~= 0 & strcmp(which,'SR') ~= 0 & strcmp(which,'LI') ~= 0 & strcmp(which,'SI') ~= 0 & strcmp(which,'LA') ~= 0 & strcmp(which,'SA') ~= 0 & strcmp(which,'BE') ~= 0)
410 if(Areal & Breal & Asym)
411 error(msprintf(gettext("%s: Wrong value for input argument #%d: Unrecognized sigma value.\n Sigma must be one of ''%s'', ''%s'', ''%s'', ''%s'' or ''%s''.\n"), "eigs", 4, "LM", "SM", "LA", "SA", "BE"));
413 error(msprintf(gettext("%s: Wrong value for input argument #%d: Unrecognized sigma value.\n Sigma must be one of ''%s'', ''%s'', ''%s'', ''%s'', ''%s'' or ''%s''.\n"), "eigs", 4, "LM", "SM", "LR", "SR", "LI", "SI"));
416 if((~Areal | ~Breal | ~Asym) & (strcmp(which,'LA') == 0 | strcmp(which,'SA') == 0 | strcmp(which,'BE') == 0))
417 error(msprintf(gettext("%s: Invalid sigma value for complex or non symmetric problem.\n"), "eigs"));
419 if(Areal & Breal & Asym & (strcmp(which,'LR') == 0 | strcmp(which,'SR') == 0 | strcmp(which,'LI') == 0 | strcmp(which,'SI') == 0))
420 error(msprintf(gettext("%s: Invalid sigma value for real symmetric problem.\n"), "eigs"));
425 error(msprintf(gettext("%s: Wrong type for input argument #%d: a real scalar or a string expected.\n"), "eigs", 4));
429 sigma = complex(sigma);
432 //*************************
434 //*************************
435 if(typeof(maxiter) <> "constant" | ~isreal(maxiter) | size(maxiter, "*") <> 1)
436 error(msprintf(gettext("%s: Wrong type for input argument #%d: %s must be a scalar.\n"), "eigs", 5, "opts.maxiter"));
439 if((maxiter <> floor(maxiter)) | (maxiter <= 0) )
440 error(msprintf(gettext("%s: Wrong type for input argument #%d: %s must be an integer positive value.\n"), "eigs", 5, "opts.maxiter"));
443 //*************************
445 //*************************
446 if(typeof(tol) <> "constant" | ~isreal(tol) | isnan(tol))
447 error(msprintf(gettext("%s: Wrong type for input argument #%d: %s must be a real scalar.\n"), "eigs", 6, "opts.tol"));
450 if(size(tol, "*") <> 1)
451 error(msprintf(gettext("%s: Wrong dimension for input argument #%d: %s must be 1 by 1 size.\n"), "eigs", 6, "opts.tol"));
454 //*************************
456 //*************************
457 if(typeof(ncv) <> "constant" | ~isreal(ncv))
458 error(msprintf(gettext("%s: Wrong type for input argument #%d: %s must be an integer scalar.\n"), "eigs", 7, "opts.ncv"));
461 if(size(ncv, "*") > 1 | ncv <> floor(ncv) | (ncv <> [] & ncv <= 0))
462 error(msprintf(gettext("%s: Wrong type for input argument #%d: %s must be an integer scalar.\n"), "eigs", 7, "opts.ncv"));
466 if(~Asym & Areal & Breal)
467 ncv = min(max(2*nev+1, 20), nA);
469 ncv = min(max(2*nev, 20), nA);
472 if(ncv <= nev | ncv > nA)
473 if(Asym & Areal & Breal)
474 error(msprintf(gettext("%s: Wrong value for input argument #%d: For real symmetric problems, NCV must be k < NCV <= N.\n"), "eigs", 7));
475 elseif(~Asym & Areal & Breal)
476 error(msprintf(gettext("%s: Wrong value for input argument #%d: For real non symmetric problems, NCV must be k + 2 < NCV < N.\n"), "eigs", 7));
478 error(msprintf(gettext("%s: Wrong value for input argument #%d: For complex problems, NCV must be k + 1 < NCV <= N.\n"), "eigs", 7));
483 //*************************
485 //*************************
488 if and(opts.cholB <> [%f %t]) then
489 error(msprintf(gettext("%s: Wrong value for input argument #%d: %s must be %s or %s.\n"), "eigs", 8, "opts.cholB","%f", "%t"));
492 //check if chol is complex?
493 if(~isreal(cholB) | size(cholB, "*") <> 1)
494 error(msprintf(gettext("%s: Wrong type for input argument #%d: %s must be an integer scalar or a boolean.\n"), "eigs", 8, "opts.cholB"));
497 if(and(cholB <> [0 1]))
498 error(msprintf(gettext("%s: Wrong value for input argument #%d: %s must be %s or %s.\n"), "eigs", 8, "opts.cholB","%f", "%t"));
501 error(msprintf(gettext("%s: Wrong type for input argument #%d: %s must be an integer scalar or a boolean.\n"), "eigs", 8, "opts.cholB"));
504 //*************************
506 //*************************
507 if(typeof(resid) <> "constant")
508 error(msprintf(gettext("%s: Wrong type for input argument #%d: A real or complex matrix expected.\n"), "eigs", 9));
511 if(size(resid, "*") ~= nA)
512 error(msprintf(gettext("%s: Wrong dimension for input argument #%d: Start vector %s must be N by 1.\n"), "eigs", 9, "opts.resid"));
518 error(msprintf(gettext("%s: Wrong type for input argument #%d: Start vector %s must be real for real problems.\n"), "eigs", 9, "opts.resid"));
522 error(msprintf(gettext("%s: Wrong type for input argument #%d: Start vector %s must be complex for complex problems.\n"), "eigs", 9, "opts.resid"));
526 iparam = zeros(11,1);
534 if(~strcmp(which,'SM') | sigma <> 0)
539 //bmat initialization
540 if(matB == 0 | iparam(7) == 1)
547 if(or(triu(%_B) <> %_B))
548 error(msprintf(gettext("%s: Wrong type for input argument #%d: B must be symmetric or hermitian, definite, semi positive.\n"), "eigs", 2));
550 if(issparse(%_B)) //sparse cholesky decomposition is reversed...
559 if(~cholB & matB & iparam(7) == 1)
560 if(issparse(%_B) & ~Breal)
561 error(msprintf(gettext("%s: Impossible to use the Cholesky factorisation with complex sparse matrices.\n"), "eigs"));
564 [R, P] = spchol(%_B);
575 if(matB & issparse(%_B) & iparam(7) ==1)
576 Rfact = umf_lufact(R);
577 Rprimefact = umf_lufact(R');
584 _select = zeros(ncv,1);
587 AMSB = A - sigma * speye(nA, nA);
590 AMSB = A - (sigma * Rprime * R);
592 AMSB = A - sigma * %_B;
595 Lup = umf_lufact(AMSB);
600 lworkl = ncv * ncv + 8 * ncv;
602 workl = zeros(lworkl, 1);
603 workd = zeros(3 * nA, 1);
607 lworkl = 3 * ncv * (ncv + 2);
609 workl = zeros(lworkl, 1);
610 workd = zeros(3 * nA, 1);
611 dr = zeros(nev+1, 1);
612 di = zeros(nev+1, 1);
613 z = zeros(nA, nev + 1);
614 workev = zeros(3 * ncv, 1);
617 lworkl = 3 * ncv * ncv + 5 * ncv;
618 v = zeros(nA, ncv) + 0 * %i;
619 workl = zeros(lworkl, 1) + 0 * %i;
620 workd = zeros(3 * nA, 1) + 0 * %i;
621 rwork = zeros(ncv, 1);
622 d = zeros(nev + 1, 1) + 0 * %i;
623 z = zeros(nA, nev) + 0 * %i;
624 workev = zeros(2 * ncv, 1) + 0 * %i;
630 [ido, resid, v, iparam, ipntr, workd, workl, info] = dsaupd(ido, bmat, nA, which, nev, tol, resid, ncv, v, iparam, ipntr, workd, workl, info);
632 error(msprintf(gettext("%s: Error with %s: info = %d.\n"), "eigs", "DSAUPD", info));
635 [ido, resid, v, iparam, ipntr, workd, workl, info] = dnaupd(ido, bmat, nA, which, nev, tol, resid, ncv, v, iparam, ipntr, workd, workl, info);
637 error(msprintf(gettext("%s: Error with %s: info = %d.\n"), "eigs", "DNAUPD", info));
641 [ido, resid, v, iparam, ipntr, workd, workl, rwork, info] = znaupd(ido, bmat, nA, which, nev, tol, resid, ncv, v, iparam, ipntr, workd, workl, rwork, info);
643 error(msprintf(gettext("%s: Error with %s: info = %d.\n"), "eigs", "ZNAUPD", info));
647 if(ido == -1 | ido == 1 | ido == 2)
650 workd(ipntr(2):ipntr(2)+nA-1) = workd(ipntr(1):ipntr(1)+nA-1);
653 workd(ipntr(2):ipntr(2)+nA-1) = A * workd(ipntr(1):ipntr(1)+nA-1);
656 y = umf_lusolve(Rprimefact, workd(ipntr(1):ipntr(1)+nA-1));
663 workd(ipntr(2):ipntr(2)+nA-1) = umf_lusolve(Rfact, y);
665 workd(ipntr(2):ipntr(2)+nA-1) = Rprime \ (A * (R \ workd(ipntr(1):ipntr(1)+nA-1)));
669 elseif(iparam(7) == 3)
672 workd(ipntr(2):ipntr(2)+nA-1) = workd(ipntr(1):ipntr(1)+nA-1);
674 workd(ipntr(2):ipntr(2)+nA-1) = umf_lusolve(Lup, workd(ipntr(1):ipntr(1)+nA-1));
679 workd(ipntr(2):ipntr(2)+nA-1) = Rprime * (R * workd(ipntr(1):ipntr(1)+nA-1));
681 workd(ipntr(2):ipntr(2)+nA-1) = %_B * workd(ipntr(1):ipntr(1)+nA-1);
685 workd(ipntr(2):ipntr(2)+nA-1) = Rprime * (R * workd(ipntr(1):ipntr(1)+nA-1));
687 workd(ipntr(2):ipntr(2)+nA-1) = %_B * workd(ipntr(1):ipntr(1)+nA-1);
689 workd(ipntr(2):ipntr(2)+nA-1) = umf_lusolve(Lup, workd(ipntr(2):ipntr(2)+nA-1));
691 workd(ipntr(2):ipntr(2)+nA-1) = umf_lusolve(Lup, workd(ipntr(3):ipntr(3)+nA-1));
697 error(msprintf(gettext("%s: Error with %s: unknown mode returned.\n"), "eigs", "DSAUPD"));
699 error(msprintf(gettext("%s: Error with %s: unknown mode returned.\n"), "eigs", "DNAUPD"));
702 error(msprintf(gettext("%s: Error with %s: unknown mode returned.\n"), "eigs", "ZNAUPD"));
713 [d, z, resid, v, iparam, iptnr, workd, workl, info_eupd] = dseupd(rvec, howmny, _select, d, z, sigma, bmat, nA, which, nev, tol, resid, ncv, v, iparam, ipntr, workd, workl, info_eupd);
715 error(msprintf(gettext("%s: Error with %s: info = %d.\n"), "eigs", "DSEUPD", info_eupd));
724 sigmar = real(sigma);
725 sigmai = imag(sigma);
726 [dr, di, z, resid, v, iparam, ipntr, workd, workl, info_eupd] = dneupd(rvec, howmny, _select, dr, di, z, sigmar, sigmai, workev, bmat, nA, which, nev, tol, resid, ncv, v, iparam, ipntr, workd, workl, info_eupd);
728 error(msprintf(gettext("%s: Error with %s: info = %d.\n"), "eigs", "DNEUPD", info_eupd));
730 res_d = complex(dr,di);
737 if(modulo(nev + 1, 2) == 1)
740 res_v(:,[c1, c2]) = [res_v(:,c1) + res_v(:,c2) * %i res_v(:,c1) - res_v(:,c2) * %i];
746 [d, z, resid, iparam, ipntr, workd, workl, rwork, info_eupd] = zneupd(rvec, howmny, _select, d, z, sigma, workev, bmat, nA, which, nev, tol, resid, ncv, v, iparam, ipntr, workd, workl, rwork, info_eupd);
748 error(msprintf(gettext("%s: Error with %s: info = %d.\n"), "eigs", "ZNEUPD", info_eupd));
758 if rvec & iparam(7)==1 & matB<>0
760 res_v = umf_lusolve(Rprimefact, res_v);
762 res_v = res_v(perm, :);
771 function [res_d, res_v] = feigs(A_fun, nA, %_B, nev, which, maxiter, tol, ncv, cholB, resid, info, a_real, a_sym)
778 //**************************
779 //Second variable nA :
780 //**************************
781 if(size(nA,'*') <> 1 | ~isreal(nA) | typeof(nA) <> "constant")
782 error(msprintf(gettext("%s: Wrong type for input argument #%d: n must be a positive integer.\n"), "eigs", 2));
785 if(floor(nA) <> nA | nA <= 0)
786 error(msprintf(gettext("%s: Wrong type for input argument #%d: n must be a positive integer.\n"), "eigs", 2));
789 //*************************
791 //*************************
792 if((typeof(%_B) <> "constant") & (typeof(%_B) <> "sparse"))
793 error(msprintf(gettext("%s: Wrong type for input argument #%d: An empty matrix or full or sparse square matrix expected.\n"), "eigs", 3));
795 [mB, nB] = size(%_B);
797 //Check if B is a square matrix
798 if(mB * nB == 1 | mB <> nB)
799 error(msprintf(gettext("%s: Wrong dimension for input argument #%d: B must have the same size as A.\n"), "eigs", 3));
802 //check if B is complex
806 //*************************
808 //*************************
809 //verification du type de nev
810 //check if nev is complex?
811 if(typeof(nev) <> "constant") | (~isreal(nev)) | (size(nev,"*") <> 1)
812 error(msprintf(gettext("%s: Wrong type for input argument #%d: A scalar expected.\n"), "eigs", 3));
815 if(nev <> floor(nev) | (nev<=0))
816 error(msprintf(gettext("%s: Wrong type for input argument #%d: k must be a positive integer.\n"), "eigs", 4));
819 if(a_sym & a_real & Breal)
821 error(msprintf(gettext("%s: Wrong value for input argument #%d: For real symmetric problems, k must be in the range 1 to N - 1.\n"), "eigs", 4));
825 error(msprintf(gettext("%s: Wrong value for input argument #%d: For real non symmetric or complex problems, k must be in the range 1 to N - 2.\n"), "eigs", 4));
829 //*************************
831 //*************************
835 if(typeof(which) <> "constant" | which == [] | isnan(which))
836 error(msprintf(gettext("%s: Wrong type for input argument #%d: a scalar expected.\n"), "eigs", 5));
841 [mWHICH, nWHICH] = size(which);
842 if(mWHICH * nWHICH <> 1)
843 error(msprintf(gettext("%s: Wrong type for input argument #%d: a string expected.\n"), "eigs", 5));
845 if(strcmp(which,'LM') ~= 0 & strcmp(which,'SM') ~= 0 & strcmp(which,'LR') ~= 0 & strcmp(which,'SR') ~= 0 & strcmp(which,'LI') ~= 0 & strcmp(which,'SI') ~= 0 & strcmp(which,'LA') ~= 0 & strcmp(which,'SA') ~= 0 & strcmp(which,'BE') ~= 0)
846 if(a_real & Breal & a_sym)
847 error(msprintf(gettext("%s: Wrong value for input argument #%d: Unrecognized sigma value.\n Sigma must be one of %s, %s, %s, %s or %s.\n"), "eigs", 5, "LM", "SM", "LA", "SA", "BE"));
849 error(msprintf(gettext("%s: Wrong value for input argument #%d: Unrecognized sigma value.\n Sigma must be one of %s, %s, %s, %s, %s or %s.\n"), "eigs", 5, "LM", "SM", "LR", "SR", "LI", "SI"));
852 if((~a_real | ~Breal | ~a_sym) & (strcmp(which,'LA') == 0 | strcmp(which,'SA') == 0 | strcmp(which,'BE') == 0))
853 error(msprintf(gettext("%s: Invalid sigma value for complex or non symmetric problem.\n"), "eigs"));
855 if(a_real & Breal & a_sym & (strcmp(which,'LR') == 0 | strcmp(which,'SR') == 0 | strcmp(which,'LI') == 0 | strcmp(which,'SI') == 0))
856 error(msprintf(gettext("%s: Invalid sigma value for real symmetric problem.\n"), "eigs"));
860 error(msprintf(gettext("%s: Wrong type for input argument #%d: a real scalar or a string expected.\n"), "eigs", 5));
864 sigma = complex(sigma);
867 //*************************
869 //*************************
870 if(typeof(maxiter) <> "constant" | ~isreal(maxiter) | size(maxiter,'*') <> 1)
871 error(msprintf(gettext("%s: Wrong type for input argument #%d: %s must be a scalar.\n"), "eigs", 6, "opts.maxiter"));
874 if((maxiter <> floor(maxiter)) | (maxiter <= 0) )
875 error(msprintf(gettext("%s: Wrong type for input argument #%d: %s must be an integer positive value.\n"), "eigs", 6, "opts.maxiter"));
878 //*************************
880 //*************************
881 if(typeof(tol) <> "constant" | ~isreal(tol) | isnan(tol))
882 error(msprintf(gettext("%s: Wrong type for input argument #%d: %s must be a real scalar.\n"), "eigs", 7, "opts.tol"));
885 if(size(tol,'*') <> 1)
886 error(msprintf(gettext("%s: Wrong dimension for input argument #%d: %s must be 1 by 1 size.\n"), "eigs", 7, "opts.tol"));
889 //*************************
891 //*************************
892 if(typeof(ncv) <> "constant" | ~isreal(ncv))
893 error(msprintf(gettext("%s: Wrong type for input argument #%d: %s must be an integer scalar.\n"), "eigs", 8, "opts.ncv"));
896 if(size(ncv,'*') > 1 | ncv <> floor(ncv) | (ncv <> [] & ncv <= 0))
897 error(msprintf(gettext("%s: Wrong dimension for input argument #%d: %s must be an integer scalar.\n"), "eigs", 8, "opts.ncv"));
901 if(~a_sym & a_real & Breal)
902 ncv = min(max(2*nev+1, 20), nA);
904 ncv = min(max(2*nev, 20), nA);
907 if(ncv <= nev | ncv > nA)
908 if(a_sym & a_real & Breal)
909 error(msprintf(gettext("%s: Wrong value for input argument #%d: For real symmetric problems, NCV must be k < NCV <= N.\n"), "eigs", 8));
910 elseif(~a_sym & a_real & Breal)
911 error(msprintf(gettext("%s: Wrong value for input argument #%d: For real non symmetric problems, NCV must be k + 2 < NCV < N.\n"), "eigs", 8));
914 error(msprintf(gettext("%s: Wrong value for input argument #%d: For complex problems, NCV must be k + 1 < NCV <= N.\n"), "eigs", 8));
919 //*************************
921 //*************************
924 if and(cholB <> [%f %t]) then
925 error(msprintf(gettext("%s: Wrong value for input argument #%d: %s must be %s or %s.\n"), "eigs", 8, "opts.cholB","%f", "%t"));
928 //check if chol is complex?
929 if(~isreal(cholB) | size(cholB, "*") <> 1)
930 error(msprintf(gettext("%s: Wrong type for input argument #%d: %s must be an integer scalar or a boolean.\n"), "eigs", 8, "opts.cholB"));
933 if(and(cholB <> [0 1]))
934 error(msprintf(gettext("%s: Wrong value for input argument #%d: %s must be %s or %s.\n"), "eigs", 8, "opts.cholB","%f", "%t"));
937 error(msprintf(gettext("%s: Wrong type for input argument #%d: %s must be an integer scalar or a boolean.\n"), "eigs", 8, "opts.cholB"));
940 //*************************
942 //*************************
943 if(typeof(resid) <> "constant")
944 error(msprintf(gettext("%s: Wrong type for input argument #%d: A real or complex matrix expected.\n"), "eigs", 10));
947 if(size(resid,'*') ~= nA)
948 error(msprintf(gettext("%s: Wrong dimension for input argument #%d: Start vector opts.resid must be N by 1.\n"), "eigs", 10));
954 error(msprintf(gettext("%s: Wrong type for input argument #%d: Start vector opts.resid must be real for real problems.\n"), "eigs", 10));
958 error(msprintf(gettext("%s: Wrong type for input argument #%d: Start vector opts.resid must be complex for complex problems.\n"), "eigs", 10));
962 iparam = zeros(11,1);
970 if(~strcmp(which,'SM') | sigma <> 0)
975 //bmat initialization
976 if(matB == 0 | iparam(7) == 1)
983 if(~and(triu(%_B) == %_B))
984 error(msprintf(gettext("%s: Wrong type for input argument #%d: B must be symmetric or hermitian, definite, semi positive.\n"), "eigs", 2));
990 if(~cholB & matB <> 0 & iparam(7) == 1)
992 error(msprintf(gettext("%s: Impossible to use the Cholesky factorisation with complex sparse matrices.\n"), "eigs"));
1007 _select = zeros(ncv,1);
1011 lworkl = ncv * ncv + 8 * ncv;
1013 workl = zeros(lworkl, 1);
1014 workd = zeros(3 * nA, 1);
1018 lworkl = 3 * ncv * (ncv + 2);
1020 workl = zeros(lworkl, 1);
1021 workd = zeros(3 * nA, 1);
1022 dr = zeros(nev+1, 1);
1023 di = zeros(nev+1, 1);
1024 z = zeros(nA, nev + 1);
1025 workev = zeros(3 * ncv, 1);
1028 lworkl = 3 * ncv * ncv + 5 * ncv;
1029 v = zeros(nA, ncv) + 0 * %i;
1030 workl = zeros(lworkl, 1) + 0 * %i;
1031 workd = zeros(3 * nA, 1) + 0 * %i;
1032 rwork = zeros(ncv, 1);
1033 d = zeros(nev + 1, 1) + 0 * %i;
1034 z = zeros(nA, nev) + 0 * %i;
1035 workev = zeros(2 * ncv, 1) + 0 * %i;
1040 [ido, resid, v, iparam, ipntr, workd, workl, info] = dsaupd(ido, bmat, nA, which, nev, tol, resid, ncv, v, iparam, ipntr, workd, workl, info_aupd);
1042 error(msprintf(gettext("%s: Error with %s: info = %d.\n"), "eigs", "DSAUPD", info_aupd));
1045 [ido, resid, v, iparam, ipntr, workd, workl, info] = dnaupd(ido, bmat, nA, which, nev, tol, resid, ncv, v, iparam, ipntr, workd, workl, info_aupd);
1047 error(msprintf(gettext("%s: Error with %s: info = %d.\n"), "eigs", "DNAUPD", info_aupd));
1051 [ido, resid, v, iparam, ipntr, workd, workl, rwork, info] = znaupd(ido, bmat, nA, which, nev, tol, resid, ncv, v, iparam, ipntr, workd, workl, rwork, info_aupd);
1053 error(msprintf(gettext("%s: Error with %s: info = %d.\n"), "eigs", "ZNAUPD", info_aupd));
1057 if(ido == -1 | ido == 1 | ido == 2)
1060 ierr = execstr('A_fun(workd(ipntr(1):ipntr(1)+nA-1))', 'errcatch');
1064 workd(ipntr(2):ipntr(2)+nA-1) = A_fun(workd(ipntr(1):ipntr(1)+nA-1));
1066 ierr = execstr('A_fun(inv(R) * workd(ipntr(1):ipntr(1)+nA-1))', 'errcatch');
1070 workd(ipntr(2):ipntr(2)+nA-1) = inv(Rprime) * A_fun(inv(R) * workd(ipntr(1):ipntr(1)+nA-1));
1072 elseif(iparam(7) == 3)
1075 workd(ipntr(2):ipntr(2)+nA-1) = workd(ipntr(1):ipntr(1)+nA-1);
1077 ierr = execstr('A_fun(workd(ipntr(1):ipntr(1)+nA-1))', 'errcatch');
1081 workd(ipntr(2):ipntr(2)+nA-1) = A_fun(workd(ipntr(1):ipntr(1)+nA-1));
1086 workd(ipntr(2):ipntr(2)+nA-1) = Rprime * R * workd(ipntr(1):ipntr(1)+nA-1);
1088 workd(ipntr(2):ipntr(2)+nA-1) = %_B * workd(ipntr(1):ipntr(1)+nA-1);
1092 workd(ipntr(2):ipntr(2)+nA-1) = Rprime * R * workd(ipntr(1):ipntr(1)+nA-1);
1094 workd(ipntr(2):ipntr(2)+nA-1) = %_B * workd(ipntr(1):ipntr(1)+nA-1);
1096 ierr = execstr('A_fun(workd(ipntr(2):ipntr(2)+nA-1))', 'errcatch');
1100 workd(ipntr(2):ipntr(2)+nA-1) = A_fun(workd(ipntr(2):ipntr(2)+nA-1));
1102 ierr = execstr('A_fun(workd(ipntr(3):ipntr(3)+nA-1))', 'errcatch');
1106 workd(ipntr(2):ipntr(2)+nA-1) = A_fun(workd(ipntr(3):ipntr(3)+nA-1));
1112 error(msprintf(gettext("%s: Error with %s: unknown mode returned.\n"), "eigs", "DSAUPD"));
1114 error(msprintf(gettext("%s: Error with %s: unknown mode returned.\n"), "eigs", "DNAUPD"));
1117 error(msprintf(gettext("%s: Error with %s: unknown mode returned.\n"), "eigs", "ZNAUPD"));
1125 error(msprintf(gettext("%s: Wrong value for input argument #%d: n does not match rows number of matrix A.\n"), "eigs", 2));
1127 error(msprintf(gettext("%s: Wrong type or value for input arguments.\n"), "eigs"));
1132 [d, z, resid, v, iparam, iptnr, workd, workl, info_eupd] = dseupd(rvec, howmny, _select, d, z, sigma, bmat, nA, which, nev, tol, resid, ncv, v, iparam, ipntr, workd, workl, info);
1134 error(msprintf(gettext("%s: Error with %s: info = %d.\n"), "eigs", "DSEUPD", info));
1139 res_d = diag(res_d);
1144 sigmar = real(sigma);
1145 sigmai = imag(sigma);
1146 [dr, di, z, resid, v, iparam, ipntr, workd, workl, info_eupd] = dneupd(rvec, howmny, _select, dr, di, z, sigmar, sigmai, workev, bmat, nA, which, nev, tol, resid, ncv, v, iparam, ipntr, workd, workl, info);
1148 error(msprintf(gettext("%s: Error with %s: info = %d.\n"), "eigs", "DNEUPD", info));
1150 res_d = complex(dr,di);
1157 if(modulo(nev,2) == 1)
1160 res_v(:,[c1, c2]) = [res_v(:,c1) + res_v(:,c2) * %i res_v(:,c1) - res_v(:,c2) * %i];
1166 [d, z, resid, iparam, ipntr, workd, workl, rwork, info_eupd] = zneupd(rvec, howmny, _select, d, z, sigma, workev, bmat, nA, which, nev, tol, resid, ncv, v, iparam, ipntr, workd, workl, rwork, info);
1168 error(msprintf(gettext("%s: Error with %s: info = %d.\n"), "eigs", "ZNEUPD", info));