22 using namespace tensor;
23 using namespace linalg;
25 ARPACK::ARPACK(
size_t _n,
enum EigType _t,
size_t _nev)
28 static const char *whichs[6] = {
"LM",
"SM",
"LR",
"SR",
"LI",
"SI"};
30 static const char *whichs[6] = {
"LM",
"SM",
"LA",
"SA", NULL, NULL};
31 if (_t == LargestImaginary) {
32 std::cerr <<
"Cannot use LargestImaginary eigenvalue selector with real problems."
36 if (_t == SmallestImaginary) {
37 std::cerr <<
"Cannot use SmallestImaginary eigenvalue selector with real problems."
42 if (_t < 0 || _t > 6) {
43 std::cerr <<
"Invalid argument EigType passed to Arpack constructor"
50 which = whichs[which_eig];
65 if ((nev == 0) || (nev > (n-1))) {
66 std::cerr <<
"Error in ARPACK::ARPACK(): \n "
67 <<
"You request NEV=" << nev <<
" eigenvalues, while only between 1 and "
68 << (n-1) <<
" eigenvalues can be computed.";
81 ncv = std::min<integer>(std::max<integer>(2 * nev, 20), n);
82 V =
new ELT_T[n * ncv];
86 maxit = std::max<integer>(300,(int)(ceil(2.0*n/std::max<integer>(ncv,1))));
90 for (
size_t i = 1; i < 12; i++)
105 lworkl = symmetric? ncv*(ncv + 8) : ncv*(3*ncv + 5);
107 workd =
new ELT_T[n * 3];
108 workl =
new ELT_T[lworkl];
109 workv =
new ELT_T[lworkv];
110 rwork =
new double[ncv];
111 for (
size_t i = 0; i < 15; i++)
115 status = Initialized;
121 delete[] workd; workd = 0;
122 delete[] workl; workl = 0;
123 delete[] workv; workv = 0;
124 delete[] rwork; rwork = 0;
128 delete[] resid; resid = 0;
131 ARPACK::Status ARPACK::update() {
133 if (status < Initialized) {
134 error =
"ARPACK: Cannot call update() with an uninitialized ARPACK object.";
138 if (status > Running) {
139 error =
"ARPACK: Cannot call update() after the algorithm is finished.";
145 caupp(ido, bmat, n, which, nev, tol, resid, ncv, V, n, iparam, ipntr, workd,
146 workl, lworkl, rwork, info);
148 saupp(ido, bmat, n, which, nev, tol, resid, ncv, V, n, iparam, ipntr, workd,
149 workl, lworkl, info);
155 error =
"Maximum number of iterations reached";
156 status = TooManyIterations;
157 }
else if (info > 0) {
158 error =
"Algorithm failed to converge";
159 status = NoConvergence;
160 }
else if (info < 0) {
162 case -9: error =
"Starting vector is zero";
break;
163 default: error =
"Internal error -- some parameter is wrong";
break;
165 std::cerr << error <<
' ' << info <<
'\n';
170 }
else if (ido != 1 && ido != -1) {
171 error =
"Internal error -- ARPACK asks for B matrix";
183 return get_data(vectors? vectors->
begin() : NULL);
200 ELT_T *d = output.begin();
203 ELT_T sigma = number_zero<ELT_T>();
206 ceupp(rvec, hwmny, d, z, ldz, sigma, workv, bmat, n, which, nev, tol,
207 resid, ncv, V, n, iparam, ipntr, workd, workl, lworkl, rwork, info);
209 seupp(rvec, hwmny, d, z, ldz, sigma, bmat, n, which, nev, tol,
210 resid, ncv, V, n, iparam, ipntr, workd, workl, lworkl, info);
213 static const char *
const messages[17] = {
215 "N must be positive.",
216 "NEV must be positive.",
217 "NCV must satisfy NEV < NCV <= N.",
218 "WHICH be one of 'LM', 'SM', 'LA', 'SA' or 'BE'.",
219 "BMAT must be one of 'I' or 'G'.",
220 "Length of private work workl array is not sufficient.",
221 "Error return from trid. eigenvalue calculation.",
222 "Starting vector is zero.",
223 "IPARAM[7] must be 1,2,3,4,5.",
224 "IPARAM[7] = 1 and BMAT = 'G' are incompatible.",
225 "NEV and WHICH = 'BE' are incompatible.",
226 "DSAUPP did not find any eigenvalues to sufficient accuracy.",
227 "HOWMNY must be one of 'A' or 'S' if rvec = true.",
228 "HOWMNY = 'S' not yet implemented."};
229 std::cerr <<
"Routine ARPACK::get_data() failed" << std::endl
230 << messages[(info < -16 || info > 0) ? 0 : (-info)] << std::endl
231 <<
"N=" << n << std::endl
232 <<
"NEV=" << n << std::endl
233 <<
"WHICH=" << which << std::endl
234 <<
"BMAT=" << bmat << std::endl
235 <<
"LWORKL=" << workl << std::endl;
236 for (
int i = 0; i < 12; i++)
237 std::cerr <<
"IPARAM[" << i <<
"]=" << iparam[i] << std::endl;
238 for (
int i = 8; i < 11; i++)
239 std::cerr <<
"IPNTR[" << i <<
"]=" << ipntr[i] << std::endl;
242 return output(range(0,nev-1));
245 void ARPACK::set_start_vector(
const ELT_T *v) {
246 if (status >= Running) {
247 std::cerr <<
"ARPACK:: Cannot change start vector while running\n";
251 memcpy(resid, v, n *
sizeof(ELT_T));
254 void ARPACK::set_random_start_vector() {
258 void ARPACK::set_tolerance(
double _tol) {
259 if (status >= Running) {
260 std::cerr <<
"ARPACK:: Cannot change tolerance while running\n";
266 void ARPACK::set_maxiter(
size_t new_maxiter) {
267 if (status >= Running) {
268 std::cerr <<
"ARPACK:: Cannot change number of iterations while running\n";
275 ELT_T *ARPACK::get_x_vector() {
276 if (status != Running) {
277 std::cerr <<
"ARPACK:: get_x_vector() invoked outside main loop";
281 return &workd[ipntr[1-1]-1];
284 ELT_T *ARPACK::get_y_vector() {
285 if (status != Running) {
286 std::cerr <<
"ARPACK:: get_y_vector() invoked outside main loop";
290 return &workd[ipntr[2-1]-1];
295 return Vector<ELT_T>(n, get_x_vector());
300 return Vector<ELT_T>(n, get_y_vector());
305 memcpy(get_y_vector(), y.
begin(),
sizeof(Tensor<ELT_T>::elt_t)*n);
314 aux = -tensor::real(values);
329 aux = tensor::real(values);
332 return sort_indices(aux);
An N-dimensional array of numbers.
Real Tensor with elements of type "double".
iterator begin()
Iterator at the beginning.
Complex Tensor with elements of type "cdouble".
Vector of 'index' type, where 'index' fits the indices of a tensor.
EigType
Type of eigenvalues that eigs and Arpack compute.