Anasazi Version of the Day
Loading...
Searching...
No Matches
AnasaziStatusTestSpecTrans.hpp
1// @HEADER
2// *****************************************************************************
3// Anasazi: Block Eigensolvers Package
4//
5// Copyright 2004 NTESS and the Anasazi contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef ANASAZI_STATUS_TEST_SPECTRANS_HPP
11#define ANASAZI_STATUS_TEST_SPECTRANS_HPP
12
13#include "AnasaziTypes.hpp"
16
17using Teuchos::RCP;
18
19namespace Anasazi {
20namespace Experimental {
21
22 template<class ScalarType, class MV, class OP>
23 class StatusTestSpecTrans : public StatusTest<ScalarType,MV,OP> {
24
25 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
26 typedef MultiVecTraits<ScalarType,MV> MVT;
27 typedef OperatorTraits<ScalarType,MV,OP> OPT;
28
29 public:
30
31 // Constructor
32 StatusTestSpecTrans(MagnitudeType tol, int quorum = -1, ResType whichNorm = RES_2NORM, bool scaled = true, bool throwExceptionOnNan = true, const RCP<const OP> Mop = Teuchos::null);
33
34 // Destructor
35 virtual ~StatusTestSpecTrans() {};
36
37 // Check whether the test passed or failed
38 TestStatus checkStatus(Eigensolver<ScalarType,MV,OP> *solver);
39
40 // Return the result of the most recent checkStatus call
41 TestStatus getStatus() const { return state_; }
42
43 // Get the indices for the vectors that passed the test
44 std::vector<int> whichVecs() const { return ind_; }
45
46 // Get the number of vectors that passed the test
47 int howMany() const { return ind_.size(); }
48
49 void setQuorum (int quorum) {
50 state_ = Undefined;
51 quorum_ = quorum;
52 }
53
54 int getQuorum() const { return quorum_; }
55
56 void setTolerance(MagnitudeType tol)
57 {
58 state_ = Undefined;
59 tol_ = tol;
60 }
61
62 MagnitudeType getTolerance() const { return tol_; }
63
64 void setWhichNorm(ResType whichNorm)
65 {
66 state_ = Undefined;
67 whichNorm_ = whichNorm;
68 }
69
70 ResType getWhichNorm() const { return whichNorm_; }
71
72 void setScale(bool relscale)
73 {
74 state_ = Undefined;
75 scaled_ = relscale;
76 }
77
78 bool getScale() const { return scaled_; }
79
80 // Informs the status test that it should reset its internal configuration to the uninitialized state
81 void reset()
82 {
83 ind_.resize(0);
84 state_ = Undefined;
85 }
86
87 // Clears the results of the last status test
88 void clearStatus() { reset(); };
89
90 // Output formatted description of stopping test to output stream
91 std::ostream & print(std::ostream &os, int indent=0) const;
92
93 private:
94 TestStatus state_;
95 MagnitudeType tol_;
96 std::vector<int> ind_;
97 int quorum_;
98 bool scaled_;
99 enum ResType whichNorm_;
100 bool throwExceptionOnNaN_;
101 RCP<const OP> M_;
102
103 const MagnitudeType ONE;
104 };
105
106
107
108 template <class ScalarType, class MV, class OP>
109 StatusTestSpecTrans<ScalarType,MV,OP>::StatusTestSpecTrans(MagnitudeType tol, int quorum, ResType whichNorm, bool scaled, bool throwExceptionOnNaN, const RCP<const OP> Mop)
110 : state_(Undefined),
111 tol_(tol),
112 quorum_(quorum),
113 scaled_(scaled),
114 whichNorm_(whichNorm),
115 throwExceptionOnNaN_(throwExceptionOnNaN),
116 M_(Mop),
117 ONE(Teuchos::ScalarTraits<MagnitudeType>::one())
118 {}
119
120
121
122 template <class ScalarType, class MV, class OP>
123 TestStatus StatusTestSpecTrans<ScalarType,MV,OP>::checkStatus( Eigensolver<ScalarType,MV,OP>* solver )
124 {
125 typedef Teuchos::ScalarTraits<MagnitudeType> MT;
126 typedef TraceMinBase<ScalarType,MV,OP> TS;
127
128 // Cast the eigensolver to a TraceMin solver
129 // Throw an exception if this fails
130 TS* tm_solver = dynamic_cast<TS*>(solver);
131 TEUCHOS_TEST_FOR_EXCEPTION(tm_solver == 0, std::invalid_argument, "The status test for spectral transformations currently only works for the trace minimization eigensolvers. Sorry!");
132
133 // Get the residual Ax-\lambda Bx, which is not computed when there's a spectral transformation
134 // TraceMin computes Bx-1/\lambda Ax
135 TraceMinBaseState<ScalarType,MV> state = tm_solver->getState();
136
137 size_t nvecs = state.ritzShifts->size();
138 std::vector<int> curind(nvecs);
139 for(size_t i=0; i<nvecs; i++)
140 curind[i] = i;
141
142 RCP<const MV> locKX, locMX, locX;
143 RCP<MV> R;
144 locX = MVT::CloneView(*state.X,curind);
145 if(state.KX != Teuchos::null)
146 locKX = MVT::CloneView(*state.KX,curind);
147 else
148 locKX = locX;
149 if(state.MX != Teuchos::null)
150 locMX = MVT::CloneView(*state.MX,curind);
151 else
152 locMX = locX;
153 R = MVT::CloneCopy(*locKX,curind);
154
155 std::vector<MagnitudeType> evals(nvecs);
156 for(size_t i=0; i<nvecs; i++)
157 evals[i] = ONE/(*state.T)[i];
158 MVT::MvScale(*R,evals);
159 MVT::MvAddMv(-ONE,*R,ONE,*locMX,*R);
160
161 // Compute the norms
162 std::vector<MagnitudeType> res(nvecs);
163 switch (whichNorm_) {
164 case RES_2NORM:
165 {
166 MVT::MvNorm(*R,res);
167 break;
168 }
169 case RES_ORTH:
170 {
171 RCP<MV> MR = MVT::Clone(*R,nvecs);
172 OPT::Apply(*M_,*R,*MR);
173 MVT::MvDot(*R,*MR,res);
174 for(size_t i=0; i<nvecs; i++)
175 res[i] = MT::squareroot(res[i]);
176 break;
177 }
178 case RITZRES_2NORM:
179 {
180 TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, "The trace minimization solvers do not define a Ritz residual. Please choose a different residual type");
181 break;
182 }
183 }
184
185 // if appropriate, scale the norms by the magnitude of the eigenvalue estimate
186 if(scaled_)
187 {
188 for(size_t i=0; i<nvecs; i++)
189 res[i] /= std::abs(evals[i]);
190 }
191
192 // test the norms
193 ind_.resize(0);
194 for(size_t i=0; i<nvecs; i++)
195 {
196 TEUCHOS_TEST_FOR_EXCEPTION( MT::isnaninf(res[i]), ResNormNaNError,
197 "StatusTestSpecTrans::checkStatus(): residual norm is nan or inf" );
198 if(res[i] < tol_)
199 ind_.push_back(i);
200 }
201 int have = ind_.size();
202 int need = (quorum_ == -1) ? nvecs : quorum_;
203 state_ = (have >= need) ? Passed : Failed;
204 return state_;
205 }
206
207
208
209 template <class ScalarType, class MV, class OP>
210 std::ostream& StatusTestSpecTrans<ScalarType,MV,OP>::print(std::ostream& os, int indent) const
211 {
212 std::string ind(indent,' ');
213 os << ind << "- StatusTestSpecTrans: ";
214 switch (state_) {
215 case Passed:
216 os << "Passed\n";
217 break;
218 case Failed:
219 os << "Failed\n";
220 break;
221 case Undefined:
222 os << "Undefined\n";
223 break;
224 }
225 os << ind << " (Tolerance, WhichNorm,Scaled,Quorum): "
226 << "(" << tol_;
227 switch (whichNorm_) {
228 case RES_ORTH:
229 os << ",RES_ORTH";
230 break;
231 case RES_2NORM:
232 os << ",RES_2NORM";
233 break;
234 case RITZRES_2NORM:
235 os << ",RITZRES_2NORM";
236 break;
237 }
238 os << "," << (scaled_ ? "true" : "false")
239 << "," << quorum_
240 << ")\n";
241
242 if (state_ != Undefined) {
243 os << ind << " Which vectors: ";
244 if (ind_.size() > 0) {
245 for(size_t i=0; i<ind_.size(); i++) os << ind_[i] << " ";
246 os << std::endl;
247 }
248 else
249 os << "[empty]\n";
250 }
251 return os;
252 }
253
254}} // end of namespace
255
256#endif
A status test for testing the norm of the eigenvectors residuals.
Abstract base class for trace minimization eigensolvers.
Types and exceptions used within Anasazi solvers and interfaces.
Namespace Anasazi contains the classes, structs, enums and utilities used by the Anasazi package.
ResType
Enumerated type used to specify which residual norm used by residual norm status tests.
TestStatus
Enumerated type used to pass back information from a StatusTest.