13 #include "VectorInterpolator.h"
17 #include "linalg/Matrix.h"
18 #include "linalg/Vector.h"
19 #include "linalg/scalapack_wrapper.h"
23 #if __cplusplus >= 201103L
26 #include <boost/shared_ptr.hpp>
30 #define dposv CAROM_FC_GLOBAL(dposv, DPOSV)
34 void dposv(
char*,
int*,
int*,
double*,
int*,
double*,
int*,
int*);
41 VectorInterpolator::VectorInterpolator(
const std::vector<Vector> &
43 const std::vector<std::shared_ptr<Matrix>> & rotation_matrices,
44 const std::vector<std::shared_ptr<Vector>> & reduced_vectors,
47 std::string interp_method,
48 double closest_rbf_val,
49 bool compute_gradients) :
58 CAROM_VERIFY(reduced_vectors.size() == rotation_matrices.size());
61 for (
int i = 0; i < reduced_vectors.size(); i++)
65 d_rotated_reduced_vectors.push_back(reduced_vectors[i]);
68 std::shared_ptr<Vector> Q_tA = rotation_matrices[i]->transposeMult(
70 d_rotated_reduced_vectors.push_back(Q_tA);
75 void VectorInterpolator::obtainLambda()
84 std::unique_ptr<Vector> VectorInterpolator::obtainLogInterpolatedVector(
85 std::vector<double>& rbf)
92 if (d_gammas.size() == 0)
101 d_rotated_reduced_vectors[
d_ref_point]->distributed());
102 d_gammas.push_back(std::shared_ptr<Vector>(gamma));
107 std::shared_ptr<Vector> gamma = d_rotated_reduced_vectors[i]->minus(
109 d_gammas.push_back(gamma);
122 std::unique_ptr<Vector> log_interpolated_vector = obtainLogInterpolatedVector(
129 for (
int i = 0; i < point.
dim(); ++i)
133 std::shared_ptr<Vector> gradient_vector(obtainLogInterpolatedVector(rbf));
134 d_interpolation_gradient.push_back(gradient_vector);
139 CAROM_ERROR(
"Interpolated gradients are only implemented for \"LS\"");
144 std::shared_ptr<Vector> interpolated_vector =
146 *log_interpolated_vector);
147 return interpolated_vector;
150 std::unique_ptr<Vector> obtainInterpolatedVector(
const
151 std::vector<std::shared_ptr<Vector>> &
153 std::string interp_method, std::vector<double>& rbf)
155 Vector* interpolated_vector =
new Vector(data[0]->dim(),
156 data[0]->distributed());
157 if (interp_method ==
"LS")
159 for (
int i = 0; i < f_T.
numRows(); i++)
161 for (
int j = 0; j < rbf.size(); j++)
163 interpolated_vector->
getData()[i] += f_T(i, j) * rbf[j];
167 else if (interp_method ==
"IDW")
170 for (
int i = 0; i < data[0]->dim(); i++)
172 for (
int j = 0; j < rbf.size(); j++)
174 interpolated_vector->
getData()[i] += data[j]->getData()[i] * rbf[j];
176 interpolated_vector->
getData()[i] /= sum;
179 else if (interp_method ==
"LP")
181 for (
int i = 0; i < data[0]->dim(); i++)
183 for (
int j = 0; j < rbf.size(); j++)
185 interpolated_vector->
getData()[i] += data[j]->getData()[i] * rbf[j];
190 return std::unique_ptr<Vector>(interpolated_vector);
193 std::unique_ptr<Matrix> solveLinearSystem(
194 const std::vector<Vector> & parameter_points,
195 const std::vector<std::shared_ptr<Vector>> & data,
196 const std::string & interp_method,
197 const std::string & rbf,
double epsilon)
200 MPI_Initialized(&mpi_init);
202 MPI_Init(
nullptr,
nullptr);
205 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
208 if (interp_method ==
"LS")
211 f_T =
new Matrix(data[0]->dim(), data.size(),
false);
212 for (
int i = 0; i < f_T->numRows(); i++)
214 for (
int j = 0; j < f_T->numColumns(); j++)
216 f_T->item(i, j) = data[j]->getData()[i];
221 Matrix* B =
new Matrix(data.size(), data.size(),
false);
222 for (
int i = 0; i < B->numRows(); i++)
225 for (
int j = i + 1; j < B->numColumns(); j++)
227 double res =
obtainRBF(rbf, epsilon, parameter_points[i],
228 parameter_points[j]);
235 int gamma_size = data.size();
236 int num_elements = data[0]->dim();
239 dposv(&uplo, &gamma_size, &num_elements, B->getData(), &gamma_size,
240 f_T->getData(), &gamma_size, &info);
243 std::cout <<
"Linear solve failed. Please choose a different epsilon value." <<
246 CAROM_VERIFY(info == 0);
251 return std::unique_ptr<Matrix>(f_T);
double d_epsilon
The RBF parameter that determines the width of influence. a small epsilon: larger influential width a...
int d_ref_point
The index within the vector of parameter points to the reference point.
std::unique_ptr< Matrix > d_lambda_T
The RHS of the linear solve in tangential space.
std::vector< Vector > d_parameter_points
The sampled parameter points.
bool d_compute_gradients
Flag that determines if a gradient with respect to the parameters should be computed.
std::string d_rbf
The RBF type (gaussian, multiquadric, inverse quadratic, inverse multiquadric)
std::string d_interp_method
The interpolation method (linear solve, inverse distance weighting, lagrangian polynomials)
int numRows() const
Returns the number of rows of the Matrix on this processor.
double * getData() const
Get the vector data as a pointer.
int dim() const
Returns the dimension of the Vector on this processor.
std::shared_ptr< Vector > interpolate(const Vector &point)
Obtain the interpolated reduced vector of the unsampled parameter point.
double rbfWeightedSum(std::vector< double > &rbf)
Compute the sum of the RBF weights.
std::vector< double > obtainRBFGradientToTrainingPoints(const std::vector< Vector > ¶meter_points, const std::string &interp_method, const std::string &rbf, double epsilon, const Vector &point, const int index)
Compute the RBF gradient from the parameter points with the unsampled parameter point.
std::vector< double > obtainRBFToTrainingPoints(const std::vector< Vector > ¶meter_points, const std::string &interp_method, const std::string &rbf, double epsilon, const Vector &point)
Compute the RBF from the parameter points with the unsampled parameter point.
double obtainRBF(std::string rbf, double epsilon, const Vector &point1, const Vector &point2)
Compute the RBF between two points.