Anasazi Version of the Day
Loading...
Searching...
No Matches
AnasaziHelperTraits.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_HELPER_TRAITS_HPP
11#define ANASAZI_HELPER_TRAITS_HPP
12
17#include "AnasaziConfigDefs.hpp"
18#include "AnasaziTypes.hpp"
19#include "Teuchos_LAPACK.hpp"
20
21namespace Anasazi {
22
30 template <class ScalarType>
32 {
33 public:
34
36
39 static void sortRitzValues(
40 const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>& rRV,
41 const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>& iRV,
42 std::vector<Value<ScalarType> >* RV, std::vector<int>* RO, std::vector<int>* RI );
43
45
48 static void scaleRitzVectors(
49 const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>& iRV,
50 Teuchos::SerialDenseMatrix<int, ScalarType>* S );
51
53
55 static void computeRitzResiduals(
56 const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>& iRV,
57 const Teuchos::SerialDenseMatrix<int, ScalarType>& S,
58 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>* RR);
59
60 };
61
62
63 template<class ScalarType>
65 const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>& rRV,
66 const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>& iRV,
67 std::vector<Value<ScalarType> >* RV, std::vector<int>* RO, std::vector<int>* RI )
68 {
69 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
70 MagnitudeType MT_ZERO = Teuchos::ScalarTraits<MagnitudeType>::zero();
71
72 int curDim = (int)rRV.size();
73 int i = 0;
74
75 // Clear the current index.
76 RI->clear();
77
78 // Place the Ritz values from rRV and iRV into the RV container.
79 while( i < curDim ) {
80 if ( iRV[i] != MT_ZERO ) {
81 //
82 // We will have this situation for real-valued, non-Hermitian matrices.
83 (*RV)[i].set(rRV[i], iRV[i]);
84 (*RV)[i+1].set(rRV[i+1], iRV[i+1]);
85
86 // Make sure that complex conjugate pairs have their positive imaginary part first.
87 if ( (*RV)[i].imagpart < MT_ZERO ) {
88 // The negative imaginary part is first, so swap the order of the ritzValues and ritzOrders.
90 (*RV)[i] = (*RV)[i+1];
91 (*RV)[i+1] = tmp_ritz;
92
93 int tmp_order = (*RO)[i];
94 (*RO)[i] = (*RO)[i+1];
95 (*RO)[i+1] = tmp_order;
96
97 }
98 RI->push_back(1); RI->push_back(-1);
99 i = i+2;
100 } else {
101 //
102 // The Ritz value is not complex.
103 (*RV)[i].set(rRV[i], MT_ZERO);
104 RI->push_back(0);
105 i++;
106 }
107 }
108 }
109
110
111 template<class ScalarType>
113 const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>& iRV,
114 Teuchos::SerialDenseMatrix<int, ScalarType>* S )
115 {
116 ScalarType ST_ONE = Teuchos::ScalarTraits<ScalarType>::one();
117
118 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
119 MagnitudeType MT_ZERO = Teuchos::ScalarTraits<MagnitudeType>::zero();
120
121 Teuchos::LAPACK<int,MagnitudeType> lapack_mag;
122 Teuchos::BLAS<int,ScalarType> blas;
123
124 int i = 0, curDim = S->numRows();
125 ScalarType temp;
126 ScalarType* s_ptr = S->values();
127 while( i < curDim ) {
128 if ( iRV[i] != MT_ZERO ) {
129 temp = lapack_mag.LAPY2( blas.NRM2( curDim, s_ptr+i*curDim, 1 ),
130 blas.NRM2( curDim, s_ptr+(i+1)*curDim, 1 ) );
131 blas.SCAL( curDim, ST_ONE/temp, s_ptr+i*curDim, 1 );
132 blas.SCAL( curDim, ST_ONE/temp, s_ptr+(i+1)*curDim, 1 );
133 i = i+2;
134 } else {
135 temp = blas.NRM2( curDim, s_ptr+i*curDim, 1 );
136 blas.SCAL( curDim, ST_ONE/temp, s_ptr+i*curDim, 1 );
137 i++;
138 }
139 }
140 }
141
142 template<class ScalarType>
144 const std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>& iRV,
145 const Teuchos::SerialDenseMatrix<int, ScalarType>& S,
146 std::vector<typename Teuchos::ScalarTraits<ScalarType>::magnitudeType>* RR )
147 {
148 typedef typename Teuchos::ScalarTraits<ScalarType>::magnitudeType MagnitudeType;
149 MagnitudeType MT_ZERO = Teuchos::ScalarTraits<MagnitudeType>::zero();
150
151 Teuchos::LAPACK<int,MagnitudeType> lapack_mag;
152 Teuchos::BLAS<int,ScalarType> blas;
153
154 int i = 0;
155 int s_stride = S.stride();
156 int s_rows = S.numRows();
157 int s_cols = S.numCols();
158 ScalarType* s_ptr = S.values();
159
160 while( i < s_cols ) {
161 if ( iRV[i] != MT_ZERO ) {
162 (*RR)[i] = lapack_mag.LAPY2( blas.NRM2(s_rows, s_ptr + i*s_stride, 1),
163 blas.NRM2(s_rows, s_ptr + (i+1)*s_stride, 1) );
164 (*RR)[i+1] = (*RR)[i];
165 i = i+2;
166 } else {
167 (*RR)[i] = blas.NRM2(s_rows, s_ptr + i*s_stride, 1);
168 i++;
169 }
170 }
171 }
172
173#ifdef HAVE_TEUCHOS_COMPLEX
174 // Partial template specializations for the complex scalar type.
175
183 template <class T>
184 class HelperTraits<std::complex<T> >
185 {
186 public:
187 static void sortRitzValues(
188 const std::vector<T>& rRV,
189 const std::vector<T>& iRV,
190 std::vector<Value<std::complex<T> > >* RV,
191 std::vector<int>* RO, std::vector<int>* RI );
192
193 static void scaleRitzVectors(
194 const std::vector<T>& iRV,
195 Teuchos::SerialDenseMatrix<int, std::complex<T> >* S );
196
197 static void computeRitzResiduals(
198 const std::vector<T>& iRV,
199 const Teuchos::SerialDenseMatrix<int, std::complex<T> >& S,
200 std::vector<T>* RR );
201 };
202
203 template<class T>
204 void HelperTraits<std::complex<T> >::sortRitzValues(
205 const std::vector<T>& rRV,
206 const std::vector<T>& iRV,
207 std::vector<Value<std::complex<T> > >* RV,
208 std::vector<int>* RO, std::vector<int>* RI )
209 {
210 (void)RO;
211 int curDim = (int)rRV.size();
212 int i = 0;
213
214 // Clear the current index.
215 RI->clear();
216
217 // Place the Ritz values from rRV and iRV into the RV container.
218 while( i < curDim ) {
219 (*RV)[i].set(rRV[i], iRV[i]);
220 RI->push_back(0);
221 i++;
222 }
223 }
224
225 template<class T>
226 void HelperTraits<std::complex<T> >::scaleRitzVectors(
227 const std::vector<T>& iRV,
228 Teuchos::SerialDenseMatrix<int, std::complex<T> >* S )
229 {
230 (void)iRV;
231 typedef std::complex<T> ST;
232 ST ST_ONE = Teuchos::ScalarTraits<ST>::one();
233
234 Teuchos::BLAS<int,ST> blas;
235
236 int i = 0, curDim = S->numRows();
237 ST temp;
238 ST* s_ptr = S->values();
239 while( i < curDim ) {
240 temp = blas.NRM2( curDim, s_ptr+i*curDim, 1 );
241 blas.SCAL( curDim, ST_ONE/temp, s_ptr+i*curDim, 1 );
242 i++;
243 }
244 }
245
246 template<class T>
247 void HelperTraits<std::complex<T> >::computeRitzResiduals(
248 const std::vector<T>& iRV,
249 const Teuchos::SerialDenseMatrix<int, std::complex<T> >& S,
250 std::vector<T>* RR )
251 {
252 (void)iRV;
253 Teuchos::BLAS<int,std::complex<T> > blas;
254
255 int s_stride = S.stride();
256 int s_rows = S.numRows();
257 int s_cols = S.numCols();
258 std::complex<T>* s_ptr = S.values();
259
260 for (int i=0; i<s_cols; ++i ) {
261 (*RR)[i] = blas.NRM2(s_rows, s_ptr + i*s_stride, 1);
262 }
263 }
264#endif
265
266} // end Anasazi namespace
267
268
269#endif // ANASAZI_HELPER_TRAITS_HPP
Anasazi header file which uses auto-configuration information to include necessary C++ headers.
Types and exceptions used within Anasazi solvers and interfaces.
Class which defines basic traits for working with different scalar types.
static void computeRitzResiduals(const std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > &iRV, const Teuchos::SerialDenseMatrix< int, ScalarType > &S, std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > *RR)
Helper function for correctly computing the Ritz residuals of the projected eigenproblem.
static void scaleRitzVectors(const std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > &iRV, Teuchos::SerialDenseMatrix< int, ScalarType > *S)
Helper function for correctly scaling the eigenvectors of the projected eigenproblem.
static void sortRitzValues(const std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > &rRV, const std::vector< typename Teuchos::ScalarTraits< ScalarType >::magnitudeType > &iRV, std::vector< Value< ScalarType > > *RV, std::vector< int > *RO, std::vector< int > *RI)
Helper function for correctly storing the Ritz values when the eigenproblem is non-Hermitian.
Anasazi's templated virtual class for constructing an operator that can interface with the OperatorTr...
Operator()
Default constructor.
Namespace Anasazi contains the classes, structs, enums and utilities used by the Anasazi package.
This struct is used for storing eigenvalues and Ritz values, as a pair of real values.