13 #include "Interpolator.h"
17 #include "linalg/Matrix.h"
18 #include "linalg/scalapack_wrapper.h"
22 #if __cplusplus >= 201103L
25 #include <boost/shared_ptr.hpp>
32 Interpolator::Interpolator(std::vector<Vector*> parameter_points,
33 std::vector<Matrix*> rotation_matrices,
36 std::string interp_method,
37 double closest_rbf_val)
39 CAROM_VERIFY(parameter_points.size() == rotation_matrices.size());
40 CAROM_VERIFY(parameter_points.size() > 1);
41 CAROM_VERIFY(rbf ==
"G" || rbf ==
"IQ" || rbf ==
"IMQ");
42 CAROM_VERIFY(interp_method ==
"LS" || interp_method ==
"IDW"
43 || interp_method ==
"LP");
44 CAROM_VERIFY(closest_rbf_val >= 0.0 && closest_rbf_val <= 1.0);
48 MPI_Initialized(&mpi_init);
50 MPI_Init(
nullptr,
nullptr);
53 MPI_Comm_rank(MPI_COMM_WORLD, &d_rank);
54 MPI_Comm_size(MPI_COMM_WORLD, &d_num_procs);
56 d_parameter_points = parameter_points;
57 d_rotation_matrices = rotation_matrices;
58 d_ref_point = ref_point;
61 d_interp_method = interp_method;
65 Interpolator::~Interpolator()
72 std::string interp_method, std::string rbf,
double epsilon,
Vector* point)
74 std::vector<double> rbfs;
75 if (interp_method ==
"LS")
77 for (
int i = 0; i < parameter_points.size(); i++)
79 rbfs.push_back(
obtainRBF(rbf, epsilon, point, parameter_points[i]));
82 else if (interp_method ==
"IDW")
84 bool distance_is_zero =
false;
85 for (
int i = 0; i < parameter_points.size(); i++)
87 rbfs.push_back(
obtainRBF(rbf, epsilon, point, parameter_points[i]));
88 if (rbfs.back() == 1.0)
90 distance_is_zero =
true;
95 for (
int i = 0; i < rbfs.size(); i++)
104 else if (interp_method ==
"LP")
106 for (
int i = 0; i < parameter_points.size(); i++)
110 for (
int j = 0; j < parameter_points.size(); j++)
117 Vector numerator_vec, denomenator_vec;
118 point->
minus(*parameter_points[j], numerator_vec);
119 parameter_points[i]->
minus(*parameter_points[j], denomenator_vec);
120 double numerator = numerator_vec.
norm();
121 double denomenator = denomenator_vec.
norm();
125 coeff = (numerator / denomenator);
130 coeff *= (numerator / denomenator);
133 rbfs.push_back(coeff);
142 for (
int i = 0; i < rbf.size(); i++)
153 point1->
minus(*point2, diff);
154 double eps_norm_squared = epsilon * epsilon * diff.
norm2();
160 res = std::exp(-eps_norm_squared);
163 else if (rbf ==
"IQ")
165 res = 1.0 / (1.0 + eps_norm_squared);
168 else if (rbf ==
"IMQ")
170 res = 1.0 / std::sqrt(1.0 + eps_norm_squared);
177 std::string rbf,
double closest_rbf_val)
179 double closest_point_dist = INT_MAX;
181 for (
int i = 0; i < parameter_points.size(); i++)
183 for (
int j = 0; j < parameter_points.size(); j++)
191 parameter_points[i]->
minus(*parameter_points[j], diff);
192 double dist = diff.
norm2();
193 if (dist < closest_point_dist)
195 closest_point_dist = dist;
200 epsilon = std::sqrt(-std::log(closest_rbf_val) / diff.
norm2());
203 else if (rbf ==
"IQ")
205 epsilon = std::sqrt(((1.0 / closest_rbf_val) - 1.0) / diff.
norm2());
208 else if (rbf ==
"IMQ")
210 epsilon = std::sqrt((std::pow(1.0 / closest_rbf_val, 2) - 1.0) / diff.
norm2());
221 std::vector<Matrix*> bases,
228 MPI_Initialized(&mpi_init);
230 MPI_Init(
nullptr,
nullptr);
233 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
234 MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
236 std::vector<Matrix*> rotation_matrices;
240 for (
int i = 0; i < parameter_points.size(); i++)
242 CAROM_VERIFY(bases[i]->numRows() == bases[ref_point]->numRows());
243 CAROM_VERIFY(bases[i]->numColumns() == bases[ref_point]->numColumns());
244 CAROM_VERIFY(bases[i]->distributed() == bases[ref_point]->distributed());
250 Matrix* identity_matrix =
new Matrix(bases[i]->numColumns(),
251 bases[i]->numColumns(),
false);
252 for (
int j = 0; j < identity_matrix->
numColumns(); j++) {
253 identity_matrix->
item(j, j) = 1.0;
255 rotation_matrices.push_back(identity_matrix);
271 SerialSVD(basis_mult_basis, basis_right, sv, basis);
278 MPI_Bcast(basis_right->
getData(),
283 Matrix* rotation_matrix = basis->
mult(basis_right);
285 delete basis_mult_basis;
288 rotation_matrices.push_back(rotation_matrix);
291 return rotation_matrices;
double * getData() const
Get the matrix data as a pointer.
int numColumns() const
Returns the number of columns in the Matrix. This method will return the same value from each process...
Matrix * transposeMult(const Matrix &other) const
Multiplies the transpose of this Matrix with other and returns the product, reference version.
Matrix * mult(const Matrix &other) const
Multiplies this Matrix with other and returns the product, reference version.
const double & item(int row, int col) const
Const Matrix member access. Matrix data is stored in row-major format.
int numRows() const
Returns the number of rows of the Matrix on this processor.
double norm() const
Form the norm of this.
Vector * minus(const Vector &other) const
Subtracts other and this and returns the result, reference version.
double norm2() const
Form the squared norm of this.
double rbfWeightedSum(std::vector< double > &rbf)
Compute the sum of the RBF weights.
double convertClosestRBFToEpsilon(std::vector< Vector * > parameter_points, std::string rbf, double closest_rbf_val)
Convert closest RBF value to an epsilon value.
void SerialSVD(Matrix *A, Matrix *U, Vector *S, Matrix *V)
Computes the SVD of a undistributed matrix in serial.
std::vector< double > obtainRBFToTrainingPoints(std::vector< Vector * > parameter_points, std::string interp_method, std::string rbf, double epsilon, Vector *point)
Compute the RBF from the parameter points with the unsampled parameter point.
std::vector< Matrix * > obtainRotationMatrices(std::vector< Vector * > parameter_points, std::vector< Matrix * > bases, int ref_point)
Obtain the rotation matrices for all the parameter points using the basis of the reference point.
double obtainRBF(std::string rbf, double epsilon, Vector *point1, Vector *point2)
Compute the RBF between two points.