41 #ifndef DTK_LOCALMLSPROBLEM_IMPL_HPP 42 #define DTK_LOCALMLSPROBLEM_IMPL_HPP 53 #include <Teuchos_LAPACK.hpp> 54 #include <Teuchos_SerialDenseSolver.hpp> 55 #include <Teuchos_SerialDenseVector.hpp> 63 template <
class Basis,
int DIM>
65 const Teuchos::ArrayView<const double> &target_center,
66 const Teuchos::ArrayView<const unsigned> &source_lids,
67 const Teuchos::ArrayView<const double> &source_centers,
const Basis &basis,
69 : d_shape_function( source_lids.size() )
71 DTK_REQUIRE( 0 == source_centers.size() % DIM );
72 DTK_REQUIRE( 0 == target_center.size() % DIM );
75 int num_sources = source_lids.size();
77 Teuchos::SerialDenseMatrix<int, double> P;
78 Teuchos::SerialDenseVector<int, double> target_poly;
81 Teuchos::SerialDenseMatrix<int, double> phi( num_sources, num_sources );
82 Teuchos::ArrayView<const double> source_center_view;
84 for (
int i = 0; i < num_sources; ++i )
86 source_center_view = source_centers( DIM * source_lids[i], DIM );
88 target_center.getRawPtr(), source_center_view.getRawPtr() );
93 Teuchos::Array<int> poly_ids( 1, 0 );
95 P.reshape( num_sources, poly_id + 1 );
96 for (
int i = 0; i < num_sources; ++i )
98 source_center_view = source_centers( DIM * source_lids[i], DIM );
99 P( i, poly_id ) = polynomialCoefficient( 0, source_center_view );
104 bool full_rank =
false;
106 int total_poly = std::min( num_poly, num_sources );
107 for (
int j = 1; j < total_poly; ++j )
110 P.reshape( num_sources, poly_id + 1 );
111 for (
int i = 0; i < num_sources; ++i )
113 source_center_view = source_centers( DIM * source_lids[i], DIM );
114 P( i, poly_id ) = polynomialCoefficient( j, source_center_view );
118 full_rank = isFullRank( P );
123 poly_ids.push_back( j );
130 P.reshape( num_sources, poly_id );
135 poly_size = poly_ids.size();
136 target_poly.resize( poly_size );
137 for (
int i = 0; i < poly_size; ++i )
139 target_poly( i ) = polynomialCoefficient( poly_ids[i], target_center );
143 Teuchos::SerialDenseMatrix<int, double> b( poly_size, num_sources );
144 b.multiply( Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, P, phi, 0.0 );
147 Teuchos::SerialDenseMatrix<int, double> A( poly_size, poly_size );
150 Teuchos::SerialDenseMatrix<int, double> work( num_sources, poly_size );
151 work.multiply( Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, phi, P, 0.0 );
152 A.multiply( Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, P, work, 0.0 );
156 Teuchos::LAPACK<int, double> lapack;
157 double A_rcond = std::numeric_limits<double>::epsilon();
158 Teuchos::Array<double> work( 4 * A.numCols() );
159 Teuchos::SerialDenseVector<int, double> s( poly_size );
164 Teuchos::Array<int> ipiv( std::min( A.numRows(), A.numCols() ) );
165 Teuchos::SerialDenseMatrix<int, double> LU_A( A );
166 lapack.GETRF( LU_A.numRows(), LU_A.numCols(), LU_A.values(), LU_A.numRows(),
167 ipiv.getRawPtr(), &info );
168 DTK_CHECK( 0 == info );
170 Teuchos::Array<int> iwork( A.numCols() );
171 lapack.GECON(
'1', LU_A.numCols(), LU_A.values(), LU_A.numRows(),
172 A.normOne(), &A_rcond, work.getRawPtr(), iwork.getRawPtr(),
174 DTK_CHECK( 0 == info );
177 lapack.GELSS( A.numRows(), A.numCols(), b.numCols(), A.values(),
178 A.numRows(), b.values(), b.numRows(), s.values(), A_rcond,
179 &rank, work.getRawPtr(), -1, &info );
180 DTK_CHECK( 0 == info );
183 work.resize( work[0] );
184 lapack.GELSS( A.numRows(), A.numCols(), b.numCols(), A.values(),
185 A.numRows(), b.values(), b.numRows(), s.values(), A_rcond,
186 &rank, work.getRawPtr(), work.size(), &info );
187 DTK_CHECK( 0 == info );
190 Teuchos::SerialDenseMatrix<int, double> shape_matrix(
191 Teuchos::View, d_shape_function.getRawPtr(), 1, 1,
192 d_shape_function.size() );
193 shape_matrix.multiply( Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, target_poly,
199 template <
class Basis,
int DIM>
201 const int coeff,
const Teuchos::ArrayView<const double> ¢er )
const 221 return center[0] * center[1];
224 return center[0] * center[2];
227 return center[1] * center[2];
230 return center[0] * center[0];
233 return center[1] * center[1];
236 return center[2] * center[2];
244 template <
class Basis,
int DIM>
246 const Teuchos::SerialDenseMatrix<int, double> &matrix )
const 249 Teuchos::SerialDenseMatrix<int, double> A = matrix;
252 int full_rank = std::min( A.numRows(), A.numCols() );
255 Teuchos::LAPACK<int, double> lapack;
256 Teuchos::Array<double> S( full_rank );
257 Teuchos::SerialDenseMatrix<int, double> U( A.numRows(), A.numRows() );
258 Teuchos::SerialDenseMatrix<int, double> VT( A.numCols(), A.numCols() );
259 Teuchos::Array<double> work( full_rank );
260 Teuchos::Array<double> rwork( full_rank );
262 lapack.GESVD(
'A',
'A', A.numRows(), A.numCols(), A.values(), A.numRows(),
263 S.getRawPtr(), U.values(), U.numRows(), VT.values(),
264 VT.numRows(), work.getRawPtr(), -1, rwork.getRawPtr(),
266 DTK_CHECK( 0 == info );
268 work.resize( work[0] );
269 rwork.resize( work.size() );
270 lapack.GESVD(
'A',
'A', A.numRows(), A.numCols(), A.values(), A.numRows(),
271 S.getRawPtr(), U.values(), U.numRows(), VT.values(),
272 VT.numRows(), work.getRawPtr(), work.size(),
273 rwork.getRawPtr(), &info );
274 DTK_CHECK( 0 == info );
277 double epsilon = std::numeric_limits<double>::epsilon();
278 double delta = S[0] * epsilon;
279 int rank = std::count_if( S.begin(), S.end(),
280 [=](
double s ) {
return ( s > delta ); } );
282 return ( rank == full_rank );
291 #endif // end DTK_LOCALMLSPROBLEM_IMPL_HPP Local moving least square problem.
static double evaluateValue(const RadialBasis &basis, const double radius, const double x)
Compute the value of the basis at the given value.
Assertions and Design-by-Contract for error handling.
Eucliden distance function.
Policy class for spline interpolation basis functions.
Local moving least square problem about a single target center using quadratic polynomials.
Euclidean distance function.