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
00033 #ifndef ANASAZI_BASIC_SORT_HPP
00034 #define ANASAZI_BASIC_SORT_HPP
00035
00043 #include "AnasaziConfigDefs.hpp"
00044 #include "AnasaziSortManager.hpp"
00045 #include "Teuchos_LAPACK.hpp"
00046 #include "Teuchos_ScalarTraits.hpp"
00047
00048 namespace Anasazi {
00049
00050 template<class ScalarType, class MV, class OP>
00051 class BasicSort : public SortManager<ScalarType,MV,OP> {
00052
00053 public:
00054
00056
00067 BasicSort( const std::string which = "LM" ) {
00068 setSortType(which);
00069 }
00070
00072 virtual ~BasicSort() {};
00073
00075
00086 void setSortType( const std::string which ) {
00087 which_ = which;
00088 TEST_FOR_EXCEPTION(which_.compare("LM") && which_.compare("SM") &&
00089 which_.compare("LR") && which_.compare("SR") &&
00090 which_.compare("LI") && which_.compare("SI"), std::invalid_argument,
00091 "Anasazi::BasicSort::sort(): sorting order is not valid");
00092 };
00093
00095
00104 void sort(Eigensolver<ScalarType,MV,OP>* solver, const int n, std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &evals, std::vector<int> *perm = 0) const;
00105
00122 void sort(Eigensolver<ScalarType,MV,OP>* solver,
00123 const int n,
00124 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &r_evals,
00125 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &i_evals,
00126 std::vector<int> *perm = 0) const;
00127
00128 protected:
00129
00131
00141 std::string which_;
00142
00143 };
00144
00145 template<class ScalarType, class MV, class OP>
00146 void BasicSort<ScalarType,MV,OP>::sort(Eigensolver<ScalarType,MV,OP>* solver, const int n,
00147 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &evals,
00148 std::vector<int> *perm) const
00149 {
00150 int i=0,j=0;
00151
00152 TEST_FOR_EXCEPTION(evals.size() < (unsigned int) n,
00153 std::invalid_argument, "Anasazi::BasicSort:sort(): eigenvalue vector size isn't consistent with n.");
00154 if (perm) {
00155 TEST_FOR_EXCEPTION(perm->size() < (unsigned int) n,
00156 std::invalid_argument, "Anasazi::BasicSort:sort(): permutation vector size isn't consistent with n.");
00157 }
00158
00159
00160 int tempord=0;
00161
00162 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
00163 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
00164
00165
00166 MagnitudeType temp;
00167
00168 Teuchos::LAPACK<int,MagnitudeType> lapack;
00169
00170
00171
00172
00173 if (perm) {
00174 for (i=0; i < n; i++) {
00175 (*perm)[i] = i;
00176 }
00177 }
00178
00179
00180
00181
00182
00183 if (!which_.compare("SM")) {
00184 for (j=1; j < n; j++) {
00185 temp = evals[j];
00186 if (perm) {
00187 tempord = (*perm)[j];
00188 }
00189 MagnitudeType temp2 = MT::magnitude(evals[j]);
00190 for (i=j-1; i >=0 && MT::magnitude(evals[i]) > temp2; i--) {
00191 evals[i+1] = evals[i];
00192 if (perm) {
00193 (*perm)[i+1]=(*perm)[i];
00194 }
00195 }
00196 evals[i+1] = temp;
00197 if (perm) {
00198 (*perm)[i+1] = tempord;
00199 }
00200 }
00201 return;
00202 }
00203
00204
00205
00206 if (!which_.compare("SR")) {
00207 for (j=1; j < n; j++) {
00208 temp = evals[j];
00209 if (perm) {
00210 tempord = (*perm)[j];
00211 }
00212 for (i=j-1; i >= 0 && evals[i] > temp; i--) {
00213 evals[i+1]=evals[i];
00214 if (perm) {
00215 (*perm)[i+1]=(*perm)[i];
00216 }
00217 }
00218 evals[i+1] = temp;
00219 if (perm) {
00220 (*perm)[i+1] = tempord;
00221 }
00222 }
00223 return;
00224 }
00225
00226
00227
00228
00229
00230 TEST_FOR_EXCEPTION(!which_.compare("SI"), SortManagerError,
00231 "Anasazi::BasicSort::sort() with one arg assumes real eigenvalues");
00232
00233
00234
00235 if (!which_.compare("LM")) {
00236 for (j=1; j < n; j++) {
00237 temp = evals[j];
00238 if (perm) {
00239 tempord = (*perm)[j];
00240 }
00241 MagnitudeType temp2 = MT::magnitude(evals[j]);
00242 for (i=j-1; i >= 0 && MT::magnitude(evals[i]) < temp2; i--) {
00243 evals[i+1]=evals[i];
00244 if (perm) {
00245 (*perm)[i+1]=(*perm)[i];
00246 }
00247 }
00248 evals[i+1] = temp;
00249 if (perm) {
00250 (*perm)[i+1] = tempord;
00251 }
00252 }
00253 return;
00254 }
00255
00256
00257
00258 if (!which_.compare("LR")) {
00259 for (j=1; j < n; j++) {
00260 temp = evals[j];
00261 if (perm) {
00262 tempord = (*perm)[j];
00263 }
00264 for (i=j-1; i >= 0 && evals[i]<temp; i--) {
00265 evals[i+1]=evals[i];
00266 if (perm) {
00267 (*perm)[i+1]=(*perm)[i];
00268 }
00269 }
00270 evals[i+1] = temp;
00271 if (perm) {
00272 (*perm)[i+1] = tempord;
00273 }
00274 }
00275 return;
00276 }
00277
00278
00279
00280
00281
00282 TEST_FOR_EXCEPTION(!which_.compare("LI"), SortManagerError,
00283 "Anasazi::BasicSort::sort() with one arg assumes real eigenvalues");
00284
00285
00286 TEST_FOR_EXCEPTION(true, std::logic_error,
00287 "Anasazi::BasicSort::sort(): sorting order is not valid");
00288 }
00289
00290
00291 template<class ScalarType, class MV, class OP>
00292 void BasicSort<ScalarType,MV,OP>::sort(Eigensolver<ScalarType,MV,OP>* solver,
00293 const int n,
00294 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &r_evals,
00295 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType> &i_evals,
00296 std::vector<int> *perm) const
00297 {
00298 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
00299 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
00300
00301 TEST_FOR_EXCEPTION(r_evals.size() < (unsigned int) n || i_evals.size() < (unsigned int) n,
00302 std::invalid_argument, "Anasazi::BasicSort:sort(): real and imaginary vector sizes aren't consistent with n.");
00303 if (perm) {
00304 TEST_FOR_EXCEPTION(perm->size() < (unsigned int) n,
00305 std::invalid_argument, "Anasazi::BasicSort:sort(): permutation vector size isn't consistent with n.");
00306 }
00307 int i=0,j=0;
00308 int tempord=0;
00309
00310 MagnitudeType temp, tempr, tempi;
00311 Teuchos::LAPACK<int,MagnitudeType> lapack;
00312
00313
00314
00315 if (perm) {
00316 for (i=0; i < n; i++) {
00317 (*perm)[i] = i;
00318 }
00319 }
00320
00321
00322
00323
00324
00325 if (!which_.compare("SM")) {
00326 for (j=1; j < n; j++) {
00327 tempr = r_evals[j]; tempi = i_evals[j];
00328 if (perm) {
00329 tempord = (*perm)[j];
00330 }
00331 temp=lapack.LAPY2(r_evals[j],i_evals[j]);
00332 for (i=j-1; i>=0 && lapack.LAPY2(r_evals[i],i_evals[i]) > temp; i--) {
00333 r_evals[i+1]=r_evals[i]; i_evals[i+1]=i_evals[i];
00334 if (perm) {
00335 (*perm)[i+1]=(*perm)[i];
00336 }
00337 }
00338 r_evals[i+1] = tempr; i_evals[i+1] = tempi;
00339 if (perm) {
00340 (*perm)[i+1] = tempord;
00341 }
00342 }
00343 return;
00344 }
00345
00346
00347
00348 if (!which_.compare("SR")) {
00349 for (j=1; j < n; j++) {
00350 tempr = r_evals[j]; tempi = i_evals[j];
00351 if (perm) {
00352 tempord = (*perm)[j];
00353 }
00354 for (i=j-1; i>=0 && r_evals[i]>tempr; i--) {
00355 r_evals[i+1]=r_evals[i]; i_evals[i+1]=i_evals[i];
00356 if (perm) {
00357 (*perm)[i+1]=(*perm)[i];
00358 }
00359 }
00360 r_evals[i+1] = tempr; i_evals[i+1] = tempi;
00361 if (perm) {
00362 (*perm)[i+1] = tempord;
00363 }
00364 }
00365 return;
00366 }
00367
00368
00369
00370 if (!which_.compare("SI")) {
00371 for (j=1; j < n; j++) {
00372 tempr = r_evals[j]; tempi = i_evals[j];
00373 if (perm) {
00374 tempord = (*perm)[j];
00375 }
00376 for (i=j-1; i>=0 && i_evals[i]>tempi; i--) {
00377 r_evals[i+1]=r_evals[i]; i_evals[i+1]=i_evals[i];
00378 if (perm) {
00379 (*perm)[i+1]=(*perm)[i];
00380 }
00381 }
00382 r_evals[i+1] = tempr; i_evals[i+1] = tempi;
00383 if (perm) {
00384 (*perm)[i+1] = tempord;
00385 }
00386 }
00387 return;
00388 }
00389
00390
00391
00392 if (!which_.compare("LM")) {
00393 for (j=1; j < n; j++) {
00394 tempr = r_evals[j]; tempi = i_evals[j];
00395 if (perm) {
00396 tempord = (*perm)[j];
00397 }
00398 temp=lapack.LAPY2(r_evals[j],i_evals[j]);
00399 for (i=j-1; i>=0 && lapack.LAPY2(r_evals[i],i_evals[i])<temp; i--) {
00400 r_evals[i+1]=r_evals[i]; i_evals[i+1]=i_evals[i];
00401 if (perm) {
00402 (*perm)[i+1]=(*perm)[i];
00403 }
00404 }
00405 r_evals[i+1] = tempr; i_evals[i+1] = tempi;
00406 if (perm) {
00407 (*perm)[i+1] = tempord;
00408 }
00409 }
00410 return;
00411 }
00412
00413
00414
00415 if (!which_.compare("LR")) {
00416 for (j=1; j < n; j++) {
00417 tempr = r_evals[j]; tempi = i_evals[j];
00418 if (perm) {
00419 tempord = (*perm)[j];
00420 }
00421 for (i=j-1; i>=0 && r_evals[i]<tempr; i--) {
00422 r_evals[i+1]=r_evals[i]; i_evals[i+1]=i_evals[i];
00423 if (perm) {
00424 (*perm)[i+1]=(*perm)[i];
00425 }
00426 }
00427 r_evals[i+1] = tempr; i_evals[i+1] = tempi;
00428 if (perm) {
00429 (*perm)[i+1] = tempord;
00430 }
00431 }
00432 return;
00433 }
00434
00435
00436
00437 if (!which_.compare("LI")) {
00438 for (j=1; j < n; j++) {
00439 tempr = r_evals[j]; tempi = i_evals[j];
00440 if (perm) {
00441 tempord = (*perm)[j];
00442 }
00443 for (i=j-1; i>=0 && i_evals[i]<tempi; i--) {
00444 r_evals[i+1]=r_evals[i]; i_evals[i+1]=i_evals[i];
00445 if (perm) {
00446 (*perm)[i+1]=(*perm)[i];
00447 }
00448 }
00449 r_evals[i+1] = tempr; i_evals[i+1] = tempi;
00450 if (perm) {
00451 (*perm)[i+1] = tempord;
00452 }
00453 }
00454 return;
00455 }
00456
00457 TEST_FOR_EXCEPTION(true, std::logic_error,
00458 "Anasazi::BasicSort::sort(): sorting order is not valid");
00459 }
00460
00461
00462 }
00463
00464 #endif // ANASAZI_BASIC_SORT_HPP
00465