Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Stokhos_Lanczos.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Stokhos Package
4 //
5 // Copyright 2009 NTESS and the Stokhos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef STOKHOS_LANCZOS_HPP
11 #define STOKHOS_LANCZOS_HPP
12 
13 #include "Teuchos_Array.hpp"
17 
18 namespace Stokhos {
19 
20  template <typename ord_type, typename val_type>
22  public:
23  typedef ord_type ordinal_type;
24  typedef val_type value_type;
26 
27  WeightedVectorSpace(const vector_type& weights) :
28  w(weights),
29  n(weights.length())
30  {
31  }
32 
34 
35  vector_type create_vector() const { return vector_type(n); }
36 
37  value_type
38  inner_product(const vector_type& u, const vector_type& v) const {
40  for (ordinal_type j=0; j<n; j++)
41  val += w[j]*u[j]*v[j];
42  return val;
43  }
44 
45  void
46  add2(const value_type& a, const vector_type& u1,
47  const value_type& b, const vector_type& u2, vector_type& v) const {
48  for (ordinal_type j=0; j<n; j++)
49  v[j] = a*u1[j] + b*u2[j];
50  }
51 
52  void
53  add3(const value_type& a, const vector_type& u1,
54  const value_type& b, const vector_type& u2,
55  const value_type& c, const vector_type& u3, vector_type& v) const {
56  for (ordinal_type j=0; j<n; j++)
57  v[j] = a*u1[j] + b*u2[j] +c*u3[j];
58  }
59 
60  protected:
61 
62  const vector_type& w;
64 
65  };
66 
88  template <typename vectorspace_type, typename operator_type>
89  class Lanczos {
90  public:
91 
96 
98  static void compute(ordinal_type k,
99  const vectorspace_type& vs,
100  const operator_type& A,
101  const vector_type& u_init,
102  matrix_type& u,
105  Teuchos::Array<value_type>& nrm_sqrd) {
106  beta[0] = 1.0;
107 
108  // u[i-1], u[i], u[i+1]
109  vector_type u0, u1, u2;
110 
111  // set starting vector
112  u0 = Teuchos::getCol(Teuchos::View, u, 0);
113  u0.assign(u_init);
114  u1 = u0;
115 
116  value_type nrm;
117  vector_type v = vs.create_vector();
118  for (ordinal_type i=0; i<k; i++) {
119 
120  // Compute (u_i,u_i)
121  nrm_sqrd[i] = vs.inner_product(u1, u1);
122 
123  // Compute v = A*u_i
124  A.apply(u1, v);
125 
126  // Compute (v,u_i)
127  nrm = vs.inner_product(u1, v);
128 
129  // Compute alpha = (v,u_i) / (u_i,u_i)
130  alpha[i] = nrm / nrm_sqrd[i];
131 
132  // Compute beta = (u_i,u_i) / (u_{i-1}.u_{i-1})
133  if (i > 0)
134  beta[i] = nrm_sqrd[i] / nrm_sqrd[i-1];
135 
136  // Compute u_{i+1} = v - alpha_i*u_i - beta_i*u_{i-1}
137  if (i < k-1) {
138  u2 = Teuchos::getCol(Teuchos::View, u, i+1);
139  if (i == 0)
140  vs.add2(value_type(1), v, -alpha[i], u1, u2);
141  else
142  vs.add3(value_type(1), v, -alpha[i], u1, -beta[i], u0, u2);
143  gramSchmidt(i+1, vs, u, u2);
144  }
145 
146  // std::cout << "i = " << i
147  // << " alpha = " << alpha[i] << " beta = " << beta[i]
148  // << " nrm = " << nrm_sqrd[i] << std::endl;
149  TEUCHOS_TEST_FOR_EXCEPTION(nrm_sqrd[i] < 0, std::logic_error,
150  "Stokhos::LanczosProjPCEBasis::lanczos(): "
151  << " Polynomial " << i << " out of " << k
152  << " has norm " << nrm_sqrd[i] << "!");
153 
154  // Shift -- these are just pointer copies
155  u0 = u1;
156  u1 = u2;
157 
158  }
159  }
160 
163  const vectorspace_type& vs,
164  const operator_type& A,
165  const vector_type& u_init,
166  matrix_type& u,
169  Teuchos::Array<value_type>& nrm_sqrd) {
170 
171  // u[i-1], u[i], u[i+1]
172  vector_type u0, u1, u2;
173 
174  // set starting vector
175  u0 = Teuchos::getCol(Teuchos::View, u, 0);
176  u0.assign(u_init);
177  u1 = u0;
178 
179  vector_type v = vs.create_vector();
180  for (ordinal_type i=0; i<k; i++) {
181 
182  // Compute (u_i,u_i)
183  beta[i] = std::sqrt(vs.inner_product(u1, u1));
184  u1.scale(1.0/beta[i]);
185  nrm_sqrd[i] = value_type(1.0);
186 
187  // Compute v = A*u_i
188  A.apply(u1, v);
189 
190  // Compute (v,u_i)
191  alpha[i] = vs.inner_product(u1, v);
192 
193  // Compute u_{i+1} = v - alpha_i*u_i - beta_i*u_{i-1}
194  if (i < k-1) {
195  u2 = Teuchos::getCol(Teuchos::View, u, i+1);
196  if (i == 0)
197  vs.add2(value_type(1), v, -alpha[i], u1, u2);
198  else
199  vs.add3(value_type(1), v, -alpha[i], u1, -beta[i], u0, u2);
200  gramSchmidt(i+1, vs, u, u2);
201  }
202 
203  // std::cout << "i = " << i
204  // << " alpha = " << alpha[i] << " beta = " << beta[i]
205  // << " nrm = " << nrm_sqrd[i] << std::endl;
206  TEUCHOS_TEST_FOR_EXCEPTION(nrm_sqrd[i] < 0, std::logic_error,
207  "Stokhos::LanczosProjPCEBasis::lanczos(): "
208  << " Polynomial " << i << " out of " << k
209  << " has norm " << nrm_sqrd[i] << "!");
210 
211  // Shift -- these are just pointer copies
212  u0 = u1;
213  u1 = u2;
214 
215  }
216  }
217 
219  static void gramSchmidt(ordinal_type k, const vectorspace_type& vs,
220  matrix_type& u, vector_type& u2) {
221  vector_type u0;
222  value_type nrm, dp;
223  for (ordinal_type i=0; i<k; i++) {
224  u0 = Teuchos::getCol(Teuchos::View, u, i);
225  nrm = vs.inner_product(u0, u0);
226  dp = vs.inner_product(u2, u0);
227  vs.add2(value_type(1), u2, -dp/nrm, u0, u2);
228  }
229  }
230 
231  };
232 }
233 
234 #endif // STOKHOS_LANCZOS_HPP
235 
KOKKOS_INLINE_FUNCTION PCE< Storage > sqrt(const PCE< Storage > &a)
Teuchos::SerialDenseVector< ordinal_type, value_type > vector_type
operator_type::ordinal_type ordinal_type
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
static void gramSchmidt(ordinal_type k, const vectorspace_type &vs, matrix_type &u, vector_type &u2)
Gram-Schmidt orthogonalization routine.
int scale(const ScalarType alpha)
static void compute(ordinal_type k, const vectorspace_type &vs, const operator_type &A, const vector_type &u_init, matrix_type &u, Teuchos::Array< value_type > &alpha, Teuchos::Array< value_type > &beta, Teuchos::Array< value_type > &nrm_sqrd)
Compute Lanczos basis.
value_type inner_product(const vector_type &u, const vector_type &v) const
Teuchos::SerialDenseVector< ordinal_type, value_type > vector_type
operator_type::value_type value_type
Teuchos::SerialDenseMatrix< ordinal_type, value_type > matrix_type
vector_type create_vector() const
Applies Lanczos procedure to a given matrix.
expr val()
WeightedVectorSpace(const vector_type &weights)
void add2(const value_type &a, const vector_type &u1, const value_type &b, const vector_type &u2, vector_type &v) const
static void computeNormalized(ordinal_type k, const vectorspace_type &vs, const operator_type &A, const vector_type &u_init, matrix_type &u, Teuchos::Array< value_type > &alpha, Teuchos::Array< value_type > &beta, Teuchos::Array< value_type > &nrm_sqrd)
Compute Lanczos basis.
void add3(const value_type &a, const vector_type &u1, const value_type &b, const vector_type &u2, const value_type &c, const vector_type &u3, vector_type &v) const
SerialDenseMatrix< OrdinalType, ScalarType > & assign(const SerialDenseMatrix< OrdinalType, ScalarType > &Source)