93 const typename Teuchos::ScalarTraits<typename V::scalar_type>::magnitudeType tolerance = 1e-7,
94 const int eigNormalizationFreq = 1,
95 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::null,
96 const bool computeSpectralRadius =
true) {
97 typedef typename V::scalar_type ST;
98 typedef Teuchos::ScalarTraits<typename V::scalar_type> STS;
99 typedef typename Teuchos::ScalarTraits<typename V::scalar_type>::magnitudeType MT;
101 bool verbose = (out != Teuchos::null);
105 *out <<
" powerMethodWithInitGuess:" << endl;
108 const ST zero =
static_cast<ST
>(0.0);
109 const ST one =
static_cast<ST
>(1.0);
111 ST lambdaMaxOld = one;
115 TEUCHOS_TEST_FOR_EXCEPTION(norm == zero, std::runtime_error,
116 "Ifpack2::PowerMethod::powerMethodWithInitGuess: The initial guess "
117 "has zero norm. This could be either because Tpetra::Vector::"
118 "randomize filled the vector with zeros (if that was used to "
119 "compute the initial guess), or because the norm2 method has a "
120 "bug. The first is not impossible, but unlikely.");
123 *out <<
" Original norm1(x): " << x->norm1()
124 <<
", norm2(x): " << norm << endl;
127 x->scale(one / norm);
130 *out <<
" norm1(x.scale(one/norm)): " << x->norm1() << endl;
134 y = Teuchos::rcp(
new V(A.getRangeMap()));
143 if (computeSpectralRadius) {
147 *out <<
" PowerMethod using spectral radius route" << endl;
149 for (
int iter = 0; iter < numIters - 1; ++iter) {
151 *out <<
" Iteration " << iter << endl;
154 x->elementWiseMultiply(STS::one(), D_inv, *y, STS::zero());
156 if (((iter + 1) % eigNormalizationFreq == 0) && (iter < numIters - 2)) {
160 *out <<
" norm is zero; returning zero" << endl;
161 *out <<
" Power method terminated after " << iter <<
" iterations." << endl;
165 lambdaMaxOld = lambdaMax;
166 lambdaMax = pow(norm, Teuchos::ScalarTraits<MT>::one() / eigNormalizationFreq);
167 if (Teuchos::ScalarTraits<ST>::magnitude(lambdaMax - lambdaMaxOld) < tolerance * Teuchos::ScalarTraits<ST>::magnitude(lambdaMax)) {
169 *out <<
" lambdaMax: " << lambdaMax << endl;
170 *out <<
" Power method terminated after " << iter <<
" iterations." << endl;
173 }
else if (verbose) {
174 *out <<
" lambdaMaxOld: " << lambdaMaxOld << endl;
175 *out <<
" lambdaMax: " << lambdaMax << endl;
176 *out <<
" |lambdaMax-lambdaMaxOld|/|lambdaMax|: " << Teuchos::ScalarTraits<ST>::magnitude(lambdaMax - lambdaMaxOld) / Teuchos::ScalarTraits<ST>::magnitude(lambdaMax) << endl;
179 x->scale(one / norm);
183 *out <<
" lambdaMax: " << lambdaMax << endl;
189 *out <<
" norm is zero; returning zero" << endl;
190 *out <<
" Power method terminated after " << numIters <<
" iterations." << endl;
194 x->scale(one / norm);
196 y->elementWiseMultiply(STS::one(), D_inv, *y, STS::zero());
197 lambdaMax = y->norm2();
203 *out <<
" PowerMethod using largest eigenvalue route" << endl;
205 for (
int iter = 0; iter < numIters - 1; ++iter) {
207 *out <<
" Iteration " << iter << endl;
210 y->elementWiseMultiply(STS::one(), D_inv, *y, STS::zero());
212 if (((iter + 1) % eigNormalizationFreq == 0) && (iter < numIters - 2)) {
213 xDinvAx = x->dot(*y);
214 if (xDinvAx == zero) {
216 *out <<
" xDinvAx is zero; returning zero" << endl;
217 *out <<
" Power method terminated after " << iter <<
" iterations." << endl;
221 lambdaMaxOld = lambdaMax;
222 lambdaMax = pow(xDinvAx, Teuchos::ScalarTraits<MT>::one() / eigNormalizationFreq);
223 if (Teuchos::ScalarTraits<ST>::magnitude(lambdaMax - lambdaMaxOld) < tolerance * Teuchos::ScalarTraits<ST>::magnitude(lambdaMax)) {
225 *out <<
" lambdaMax: " << lambdaMax << endl;
226 *out <<
" Power method terminated after " << iter <<
" iterations." << endl;
229 }
else if (verbose) {
230 *out <<
" lambdaMaxOld: " << lambdaMaxOld << endl;
231 *out <<
" lambdaMax: " << lambdaMax << endl;
232 *out <<
" |lambdaMax-lambdaMaxOld|/|lambdaMax|: " << Teuchos::ScalarTraits<ST>::magnitude(lambdaMax - lambdaMaxOld) / Teuchos::ScalarTraits<ST>::magnitude(lambdaMax) << endl;
237 x->scale(one / norm);
241 *out <<
" lambdaMax: " << lambdaMax << endl;
247 *out <<
" norm is zero; returning zero" << endl;
248 *out <<
" Power method terminated after " << numIters <<
" iterations." << endl;
252 x->scale(one / norm);
254 y->elementWiseMultiply(STS::one(), D_inv, *y, STS::zero());
255 lambdaMax = y->dot(*x);
259 *out <<
" lambdaMax: " << lambdaMax << endl;
260 *out <<
" Power method terminated after " << numIters <<
" iterations." << endl;
279 typedef typename V::device_type::execution_space dev_execution_space;
280 typedef typename V::local_ordinal_type LO;
284 if (nonnegativeRealParts) {
285 auto x_lcl = x.getLocalViewDevice(Tpetra::Access::ReadWrite);
286 auto x_lcl_1d = Kokkos::subview(x_lcl, Kokkos::ALL(), 0);
288 const LO lclNumRows =
static_cast<LO
>(x.getLocalLength());
289 Kokkos::RangePolicy<dev_execution_space, LO> range(0, lclNumRows);
290 PositivizeVector<
decltype(x_lcl_1d), LO> functor(x_lcl_1d);
291 Kokkos::parallel_for(range, functor);
317 const typename Teuchos::ScalarTraits<typename V::scalar_type>::magnitudeType tolerance = 1e-7,
318 const int eigNormalizationFreq = 1,
319 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::null,
320 const bool computeSpectralRadius =
true) {
321 typedef typename V::scalar_type ST;
322 typedef Teuchos::ScalarTraits<typename V::scalar_type> STS;
324 bool verbose = (out != Teuchos::null);
327 *out <<
"powerMethod:" << std::endl;
330 const ST zero =
static_cast<ST
>(0.0);
332 Teuchos::RCP<V> x = Teuchos::rcp(
new V(A.getDomainMap()));
338 ST lambdaMax =
powerMethodWithInitGuess(A, D_inv, numIters, x, y, tolerance, eigNormalizationFreq, out, computeSpectralRadius);
347 if (STS::real(lambdaMax) < STS::real(zero)) {
349 *out <<
"real(lambdaMax) = " << STS::real(lambdaMax) <<
" < 0; "
350 "try again with a different random initial guess"
361 lambdaMax =
powerMethodWithInitGuess(A, D_inv, numIters, x, y, tolerance, eigNormalizationFreq, out, computeSpectralRadius);
V::scalar_type powerMethodWithInitGuess(const OperatorType &A, const V &D_inv, const int numIters, Teuchos::RCP< V > x, Teuchos::RCP< V > y, const typename Teuchos::ScalarTraits< typename V::scalar_type >::magnitudeType tolerance=1e-7, const int eigNormalizationFreq=1, Teuchos::RCP< Teuchos::FancyOStream > out=Teuchos::null, const bool computeSpectralRadius=true)
Use the power method to estimate the maximum eigenvalue of A*D_inv, given an initial guess vector x.
Definition Ifpack2_PowerMethod.hpp:88
V::scalar_type powerMethod(const OperatorType &A, const V &D_inv, const int numIters, Teuchos::RCP< V > y, const typename Teuchos::ScalarTraits< typename V::scalar_type >::magnitudeType tolerance=1e-7, const int eigNormalizationFreq=1, Teuchos::RCP< Teuchos::FancyOStream > out=Teuchos::null, const bool computeSpectralRadius=true)
Use the power method to estimate the maximum eigenvalue of A*D_inv.
Definition Ifpack2_PowerMethod.hpp:313
void computeInitialGuessForPowerMethod(V &x, const bool nonnegativeRealParts)
Fill x with random initial guess for power method.
Definition Ifpack2_PowerMethod.hpp:278