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 #ifndef ANASAZI_LOCA_SORT_HPP
00031 #define ANASAZI_LOCA_SORT_HPP
00032
00038 #include "AnasaziSortManager.hpp"
00039 #include "Teuchos_LAPACK.hpp"
00040
00041 namespace Anasazi {
00042
00043 template<class ScalarType, class MV, class OP>
00044 class LOCASort : public SortManager<ScalarType,MV,OP> {
00045
00046 public:
00047
00049
00061 LOCASort(const string which = "LM",
00062 ScalarType cayleyPole = Teuchos::ScalarTraits<ScalarType>::zero(),
00063 ScalarType cayleyZero = Teuchos::ScalarTraits<ScalarType>::zero()
00064 )
00065 { _which = which; _sigma = cayleyPole; _mu = cayleyZero; };
00066
00068 virtual ~LOCASort() {};
00069
00070
00072
00083 ReturnType sort(Eigensolver<ScalarType,MV,OP>* solver, int n, ScalarType *evals, std::vector<int> *perm = 0) const;
00084
00086
00099 ReturnType sort(Eigensolver<ScalarType,MV,OP>* solver, int n, ScalarType *r_evals, ScalarType *i_evals, std::vector<int> *perm = 0) const;
00100
00101 protected:
00102
00103 string _which;
00104 ScalarType _sigma, _mu;
00105
00106 private:
00107
00108
00109 ScalarType realLambda(const ScalarType er, const ScalarType ei) const;
00110
00111 };
00112
00113 template<class ScalarType, class MV, class OP>
00114 ReturnType LOCASort<ScalarType,MV,OP>::sort(Eigensolver<ScalarType,MV,OP>* solver, int n, ScalarType *evals, std::vector<int> *perm) const
00115 {
00116 int i, j, tempord;
00117 ScalarType temp, temp2;
00118 Teuchos::LAPACK<int,ScalarType> lapack;
00119
00120
00121
00122 if (perm) {
00123 for (i=0; i < n; i++) {
00124 (*perm)[i] = i;
00125 }
00126 }
00127
00128
00129
00130
00131
00132 if (!_which.compare("SM")) {
00133 for (j=1; j < n; ++j) {
00134 temp = evals[j];
00135 if (perm)
00136 tempord = (*perm)[j];
00137 temp2 = evals[j]*evals[j];
00138 for (i=j-1; i>=0 && (evals[i]*evals[i])>temp2; --i) {
00139 evals[i+1]=evals[i];
00140 if (perm)
00141 (*perm)[i+1]=(*perm)[i];
00142 }
00143 evals[i+1] = temp;
00144 if (perm)
00145 (*perm)[i+1] = tempord;
00146 }
00147 return Ok;
00148 }
00149
00150
00151
00152 if (!_which.compare("SR")) {
00153 for (j=1; j < n; ++j) {
00154 temp = evals[j];
00155 if (perm)
00156 tempord = (*perm)[j];
00157 for (i=j-1; i>=0 && evals[i]>temp; --i) {
00158 evals[i+1]=evals[i];
00159 if (perm)
00160 (*perm)[i+1]=(*perm)[i];
00161 }
00162 evals[i+1] = temp;
00163 if (perm)
00164 (*perm)[i+1] = tempord;
00165 }
00166 return Ok;
00167 }
00168
00169
00170
00171
00172
00173 if (!_which.compare("SI")) {
00174 return Undefined;
00175 }
00176
00177
00178
00179 if (!_which.compare("LM")) {
00180 for (j=1; j < n; ++j) {
00181 temp = evals[j];
00182 if (perm)
00183 tempord = (*perm)[j];
00184 temp2 = evals[j]*evals[j];
00185 for (i=j-1; i>=0 && (evals[i]*evals[i])<temp2; --i) {
00186 evals[i+1]=evals[i];
00187 if (perm)
00188 (*perm)[i+1]=(*perm)[i];
00189 }
00190 evals[i+1] = temp;
00191 if (perm)
00192 (*perm)[i+1] = tempord;
00193 }
00194 return Ok;
00195 }
00196
00197
00198
00199 if (!_which.compare("LR")) {
00200 for (j=1; j < n; ++j) {
00201 temp = evals[j];
00202 if (perm)
00203 tempord = (*perm)[j];
00204 for (i=j-1; i>=0 && evals[i]<temp; --i) {
00205 evals[i+1]=evals[i];
00206 if (perm)
00207 (*perm)[i+1]=(*perm)[i];
00208 }
00209 evals[i+1] = temp;
00210 if (perm)
00211 (*perm)[i+1] = tempord;
00212 }
00213 return Ok;
00214 }
00215
00216
00217
00218
00219
00220 if (!_which.compare("LI")) {
00221 return Undefined;
00222 }
00223
00224
00225
00226 if (!_which.compare("CA")) {
00227
00228
00229
00230
00231
00232 ScalarType templambda;
00233 for (j=1; j < n; ++j) {
00234 temp = evals[j];
00235 tempord = (*perm)[j];
00236 templambda=realLambda(evals[j],0);
00237 for (i=j-1; i>=0 && realLambda(evals[i],0)<templambda; --i) {
00238 evals[i+1]=evals[i];
00239 (*perm)[i+1]=(*perm)[i];
00240 }
00241 evals[i+1] = temp; (*perm)[i+1] = tempord;
00242 }
00243 return Ok;
00244 }
00245
00246
00247 return Undefined;
00248 }
00249
00250
00251 template<class ScalarType, class MV, class OP>
00252 ReturnType LOCASort<ScalarType,MV,OP>::sort(Eigensolver<ScalarType,MV,OP>* solver, int n, ScalarType *r_evals, ScalarType *i_evals, std::vector<int> *perm) const {
00253 int i, j, tempord;
00254 ScalarType temp, tempr, tempi;
00255 Teuchos::LAPACK<int,ScalarType> lapack;
00256
00257
00258
00259 if (perm) {
00260 for (i=0; i < n; i++) {
00261 (*perm)[i] = i;
00262 }
00263 }
00264
00265
00266
00267
00268
00269 if (!_which.compare("SM")) {
00270 for (j=1; j < n; ++j) {
00271 tempr = r_evals[j]; tempi = i_evals[j];
00272 if (perm)
00273 tempord = (*perm)[j];
00274 temp=lapack.LAPY2(r_evals[j],i_evals[j]);
00275 for (i=j-1; i>=0 && lapack.LAPY2(r_evals[i],i_evals[i])>temp; --i) {
00276 r_evals[i+1]=r_evals[i]; i_evals[i+1]=i_evals[i];
00277 if (perm)
00278 (*perm)[i+1]=(*perm)[i];
00279 }
00280 r_evals[i+1] = tempr; i_evals[i+1] = tempi;
00281 if (perm)
00282 (*perm)[i+1] = tempord;
00283 }
00284 return Ok;
00285 }
00286
00287
00288
00289 if (!_which.compare("SR")) {
00290 for (j=1; j < n; ++j) {
00291 tempr = r_evals[j]; tempi = i_evals[j];
00292 if (perm)
00293 tempord = (*perm)[j];
00294 for (i=j-1; i>=0 && r_evals[i]>tempr; --i) {
00295 r_evals[i+1]=r_evals[i]; i_evals[i+1]=i_evals[i];
00296 if (perm)
00297 (*perm)[i+1]=(*perm)[i];
00298 }
00299 r_evals[i+1] = tempr; i_evals[i+1] = tempi;
00300 if (perm)
00301 (*perm)[i+1] = tempord;
00302 }
00303 return Ok;
00304 }
00305
00306
00307
00308 if (!_which.compare("SI")) {
00309 for (j=1; j < n; ++j) {
00310 tempr = r_evals[j]; tempi = i_evals[j];
00311 if (perm)
00312 tempord = (*perm)[j];
00313 for (i=j-1; i>=0 && i_evals[i]>tempi; --i) {
00314 r_evals[i+1]=r_evals[i]; i_evals[i+1]=i_evals[i];
00315 if (perm)
00316 (*perm)[i+1]=(*perm)[i];
00317 }
00318 r_evals[i+1] = tempr; i_evals[i+1] = tempi;
00319 if (perm)
00320 (*perm)[i+1] = tempord;
00321 }
00322 return Ok;
00323 }
00324
00325
00326
00327 if (!_which.compare("LM")) {
00328 for (j=1; j < n; ++j) {
00329 tempr = r_evals[j]; tempi = i_evals[j];
00330 if (perm)
00331 tempord = (*perm)[j];
00332 temp=lapack.LAPY2(r_evals[j],i_evals[j]);
00333 for (i=j-1; i>=0 && lapack.LAPY2(r_evals[i],i_evals[i])<temp; --i) {
00334 r_evals[i+1]=r_evals[i]; i_evals[i+1]=i_evals[i];
00335 if (perm)
00336 (*perm)[i+1]=(*perm)[i];
00337 }
00338 r_evals[i+1] = tempr; i_evals[i+1] = tempi;
00339 if (perm)
00340 (*perm)[i+1] = tempord;
00341 }
00342 return Ok;
00343 }
00344
00345
00346
00347 if (!_which.compare("LR")) {
00348 for (j=1; j < n; ++j) {
00349 tempr = r_evals[j]; tempi = i_evals[j];
00350 if (perm)
00351 tempord = (*perm)[j];
00352 for (i=j-1; i>=0 && r_evals[i]<tempr; --i) {
00353 r_evals[i+1]=r_evals[i]; i_evals[i+1]=i_evals[i];
00354 if (perm)
00355 (*perm)[i+1]=(*perm)[i];
00356 }
00357 r_evals[i+1] = tempr; i_evals[i+1] = tempi;
00358 if (perm)
00359 (*perm)[i+1] = tempord;
00360 }
00361 return Ok;
00362 }
00363
00364
00365
00366 if (!_which.compare("LI")) {
00367 for (j=1; j < n; ++j) {
00368 tempr = r_evals[j]; tempi = i_evals[j];
00369 if (perm)
00370 tempord = (*perm)[j];
00371 for (i=j-1; i>=0 && i_evals[i]<tempi; --i) {
00372 r_evals[i+1]=r_evals[i]; i_evals[i+1]=i_evals[i];
00373 if (perm)
00374 (*perm)[i+1]=(*perm)[i];
00375 }
00376 r_evals[i+1] = tempr; i_evals[i+1] = tempi;
00377 if (perm)
00378 (*perm)[i+1] = tempord;
00379 }
00380 return Ok;
00381 }
00382
00383
00384
00385 if (!_which.compare("CA")) {
00386
00387
00388
00389
00390
00391 for (j=1; j < n; ++j) {
00392 tempr = r_evals[j]; tempi = i_evals[j];
00393 tempord = (*perm)[j];
00394 temp=realLambda(r_evals[j],i_evals[j]);
00395 for (i=j-1; i>=0 && realLambda(r_evals[i],i_evals[i])<temp; --i) {
00396 r_evals[i+1]=r_evals[i]; i_evals[i+1]=i_evals[i];
00397 (*perm)[i+1]=(*perm)[i];
00398 }
00399 r_evals[i+1] = tempr; i_evals[i+1] = tempi; (*perm)[i+1] = tempord;
00400 }
00401 return Ok;
00402 }
00403
00404 return Undefined;
00405 }
00406
00407 template<class ScalarType, class MV, class OP>
00408 ScalarType LOCASort<ScalarType, MV, OP>::realLambda(const ScalarType er, const ScalarType ei) const {
00409
00410
00411
00412 ScalarType reLambda = (_sigma*(er*er+ei*ei) - (_sigma+_mu)*er + _mu)/ ( (er-1.0)*(er-1.0) + ei*ei);
00413 if (reLambda > _sigma) return -1.0e6;
00414 else return reLambda;
00415 }
00416
00417 }
00418
00419 #endif // ANASAZI_LOCA_SORT_HPP
00420