00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
#ifndef parpack_INC
00038
#define parpack_INC
00039
00040
#include "arpack_proto.h"
00041
#include "Mat.h"
00042
00043
namespace PLearn {
00044
using namespace std;
00045
00046
00087
template<
class MatT>
00088 int eigenSparseSymmMat(MatT& A,
Vec e_values,
Mat e_vectors,
long int& n_evalues,
00089
int max_n_iter=300,
bool compute_vectors=
true,
bool largest_evalues=
true,
00090
bool according_to_magnitude=
true,
bool both_ends=
false)
00091 {
00092
#ifdef NOARPACK
00093
PLERROR(
"eigenSparseSymmMat: ARPACK not available on this system!");
00094
return 0;
00095
#else
00096
long int ido=0;
00097
char bmat[1];
00098 bmat[0] =
'I';
00099
char which[2];
00100
long int n=A.length();
00101
if (e_vectors.
length()!=n_evalues || e_vectors.
width()!=n)
00102
PLERROR(
"eigenSparseSymmMat: expected e_vectors.width(%d)=A.length(%d), e_vectors.length(%d)=e_values.length(%d)",
00103 e_vectors.
width(),n,e_vectors.
length(),n_evalues);
00104
if (both_ends)
00105 strncpy(which,
"BE",2);
00106
else
00107 {
00108 which[0]= largest_evalues?
'L' :
'S';
00109 which[1]= according_to_magnitude?
'M' :
'A';
00110 }
00111
real tol=0;
00112
long int ncv=
MIN(3+
int(n_evalues*1.5),n-1);
00113 e_vectors.
resize(ncv,n);
00114
long int iparam[11];
00115 iparam[0]=1;
00116 iparam[2]=max_n_iter;
00117 iparam[6]=1;
00118
long int ipntr[11];
00119
Vec workd(3*n);
00120
long int lworkl = (ncv * ncv) + (ncv * 8);
00121
Vec workl(lworkl);
00122
Vec resid(n);
00123
long int info=0;
00124
for (;;) {
00125
#ifdef USEDOUBLE
00126
dsaupd_(&ido, bmat, &n, which, &n_evalues, &tol, resid.
data(), &ncv, e_vectors.
data(), &n,
00127 iparam, ipntr, workd.
data(), workl.
data(), &lworkl, &info, 1, 2);
00128
#endif
00129
#ifdef USEFLOAT
00130
ssaupd_(&ido, bmat, &n, which, &n_evalues, &tol, resid.
data(), &ncv, e_vectors.
data(), &n,
00131 iparam, ipntr, workd.
data(), workl.
data(), &lworkl, &info, 1, 2);
00132
#endif
00133
if (ido == -1 || ido == 1) {
00134
Vec x=workd.
subVec(ipntr[0]-1,n);
00135
Vec z=workd.
subVec(ipntr[1]-1,n);
00136
product(A,
x, z);
00137 }
else break;
00138 }
00139
if (info != 0 && info != 1)
00140 {
00141
PLWARNING(
"eigenSparseSymmMat: saupd returning error %ld",info);
00142
return info;
00143 }
00144
if (info > 0)
00145 {
00146 n_evalues = iparam[4];
00147 e_values.
resize(n_evalues);
00148 }
00149 e_vectors.
resize(n_evalues,n);
00150
if (n_evalues>0)
00151 {
00152
long int rvec = compute_vectors;
00153
TVec<long int> select(ncv);
00154
long int ierr;
00155
real sigma =0;
00156
#ifdef USEDOUBLE
00157
dseupd_(&rvec,
"All",
select.data(), e_values.
data(), e_vectors.
data(), &n, &sigma,
00158 bmat, &n, which, &n_evalues, &tol, resid.
data(), &ncv, e_vectors.
data(), &n,
00159 iparam, ipntr, workd.
data(), workl.
data(), &lworkl, &ierr, 3, 1, 2);
00160
#endif
00161
#ifdef USEFLOAT
00162
sseupd_(&rvec,
"All",
select.data(), e_values.
data(), e_vectors.
data(), &n, &sigma,
00163 bmat, &n, which, &n_evalues, &tol, resid.
data(), &ncv, e_vectors.
data(), &n,
00164 iparam, ipntr, workd.
data(), workl.
data(), &lworkl, &ierr, 3, 1, 2);
00165
#endif
00166
if (ierr != 0)
00167 {
00168
PLWARNING(
"eigenSparseSymmMat: seupd returning error %ld",ierr);
00169
return ierr;
00170 }
00171 }
00172
#endif
00173
return info;
00174 }
00175
00176
00184
template<
class MatT>
00185 int eigenSparseNonSymmMat(MatT& A,
Vec e_values,
Mat e_vectors,
long int& n_evalues,
00186
int max_n_iter=300,
bool compute_vectors=
true,
bool largest_evalues=
true,
00187
bool according_to_magnitude=
true,
bool both_ends=
false)
00188 {
00189
#ifdef NOARPACK
00190
PLERROR(
"eigenSparseNonSymmMat: ARPACK not available on this system!");
00191
return 0;
00192
#else
00193
long int ido=0;
00194
char bmat[1];
00195 bmat[0] =
'I';
00196
char which[2];
00197
long int n=A.length();
00198
if (e_vectors.
length()!=n_evalues || e_vectors.
width()!=n)
00199
PLERROR(
"eigenSparseNonSymmMat: expected e_vectors.width(%d)=A.length(%d), e_vectors.length(%d)=e_values.length(%d)",
00200 e_vectors.
width(),n,e_vectors.
length(),n_evalues);
00201
if (both_ends)
00202 strncpy(which,
"BE",2);
00203
else
00204 {
00205 which[0]= largest_evalues?
'L' :
'S';
00206 which[1]= according_to_magnitude?
'M' :
'R';
00207 }
00208
real tol=0;
00209
long int ncv=
MIN(3+
int(n_evalues*1.5),n-1);
00210 e_vectors.
resize(ncv,n);
00211
long int iparam[11];
00212 iparam[0]=1;
00213 iparam[2]=max_n_iter;
00214 iparam[6]=1;
00215
long int ipntr[11];
00216
Vec workd(3*n);
00217
long int lworkl = 3*(ncv * ncv) + (ncv * 6);
00218
Vec workl(lworkl);
00219
Vec resid(n);
00220
long int info=0;
00221
for (;;) {
00222
#ifdef USEDOUBLE
00223
dnaupd_(&ido, bmat, &n, which, &n_evalues, &tol, resid.
data(), &ncv, e_vectors.
data(), &n,
00224 iparam, ipntr, workd.
data(), workl.
data(), &lworkl, &info, 1, 2);
00225
#endif
00226
#ifdef USEFLOAT
00227
snaupd_(&ido, bmat, &n, which, &n_evalues, &tol, resid.
data(), &ncv, e_vectors.
data(), &n,
00228 iparam, ipntr, workd.
data(), workl.
data(), &lworkl, &info, 1, 2);
00229
#endif
00230
if (ido == -1 || ido == 1) {
00231
Vec x=workd.
subVec(ipntr[0]-1,n);
00232
Vec z=workd.
subVec(ipntr[1]-1,n);
00233
product(A,
x, z);
00234 }
else break;
00235 }
00236
if (info != 0 && info != 1)
00237 {
00238
PLWARNING(
"eigenSparseNonSymmMat: naupd returning error %ld",info);
00239
return info;
00240 }
00241
Vec e_valuesIm(n_evalues+1);
00242
Vec workev(3*ncv);
00243
if (info > 0)
00244 {
00245 n_evalues = iparam[4];
00246 e_values.
resize(n_evalues+1);
00247 }
00248 e_vectors.
resize(n_evalues+1,n);
00249
if (n_evalues>0)
00250 {
00251
long int rvec = compute_vectors;
00252
TVec<long int> select(ncv);
00253
long int ierr;
00254
real sigmai =0;
00255
real sigmar =0;
00256
#ifdef USEDOUBLE
00257
dneupd_(&rvec,
"A",
select.data(), e_values.
data(), e_valuesIm.
data(), e_vectors.
data(), &n,
00258 &sigmar, &sigmai, workev.
data(), bmat, &n, which, &n_evalues, &tol,
00259 resid.
data(), &ncv, e_vectors.
data(), &n, iparam, ipntr, workd.
data(),
00260 workl.
data(), &lworkl, &ierr, 3, 1, 2);
00261
#endif
00262
#ifdef USEFLOAT
00263
sneupd_(&rvec,
"A",
select.data(), e_values.
data(), e_valuesIm.
data(), e_vectors.
data(), &n,
00264 &sigmar, &sigmai, workev.
data(), bmat, &n, which, &n_evalues, &tol,
00265 resid.
data(), &ncv, e_vectors.
data(), &n, iparam, ipntr, workd.
data(),
00266 workl.
data(), &lworkl, &ierr, 3, 1, 2);
00267
#endif
00268
if (ierr != 0)
00269 {
00270
PLWARNING(
"eigenSparseNonSymmMat: neupd returning error %ld",ierr);
00271
return ierr;
00272 }
00273 }
00274
#endif
00275
return info;
00276 }
00277
00278
00279 }
00280
00281
00282
#endif