12#include "linearsolvers.h"
18RBFSpline::RBFSpline(
const DataTable& samples, RadialBasisFunctionType type,
20 : RBFSpline(samples, type, false)
24RBFSpline::RBFSpline(
const DataTable& samples, RadialBasisFunctionType type,
25 DenseMatrix w,
double e)
29 dim(samples.getNumVariables()),
30 numSamples(samples.getNumSamples())
32 if (type == RadialBasisFunctionType::THIN_PLATE_SPLINE)
34 fn = std::shared_ptr<RadialBasisFunction>(
new ThinPlateSpline());
37 else if (type == RadialBasisFunctionType::MULTIQUADRIC)
39 fn = std::shared_ptr<RadialBasisFunction>(
new Multiquadric());
41 else if (type == RadialBasisFunctionType::INVERSE_QUADRIC)
43 fn = std::shared_ptr<RadialBasisFunction>(
new InverseQuadric());
45 else if (type == RadialBasisFunctionType::INVERSE_MULTIQUADRIC)
47 fn = std::shared_ptr<RadialBasisFunction>(
new InverseMultiquadric());
49 else if (type == RadialBasisFunctionType::GAUSSIAN)
51 fn = std::shared_ptr<RadialBasisFunction>(
new Gaussian());
56 fn = std::shared_ptr<RadialBasisFunction>(
new ThinPlateSpline());
62RBFSpline::RBFSpline(
const DataTable& samples, RadialBasisFunctionType type,
63 bool normalized,
double e)
65 normalized(normalized),
67 dim(samples.getNumVariables()),
68 numSamples(samples.getNumSamples())
70 if (type == RadialBasisFunctionType::THIN_PLATE_SPLINE)
72 fn = std::shared_ptr<RadialBasisFunction>(
new ThinPlateSpline());
74 else if (type == RadialBasisFunctionType::MULTIQUADRIC)
76 fn = std::shared_ptr<RadialBasisFunction>(
new Multiquadric());
78 else if (type == RadialBasisFunctionType::INVERSE_QUADRIC)
80 fn = std::shared_ptr<RadialBasisFunction>(
new InverseQuadric());
82 else if (type == RadialBasisFunctionType::INVERSE_MULTIQUADRIC)
84 fn = std::shared_ptr<RadialBasisFunction>(
new InverseMultiquadric());
86 else if (type == RadialBasisFunctionType::GAUSSIAN)
88 fn = std::shared_ptr<RadialBasisFunction>(
new Gaussian());
93 fn = std::shared_ptr<RadialBasisFunction>(
new ThinPlateSpline());
106 A.setZero(numSamples, numSamples);
108 b.setZero(numSamples, 1);
111 for (
auto it1 = samples.cbegin(); it1 != samples.cend(); ++it1, ++
i)
116 for (
auto it2 = samples.cbegin(); it2 != samples.cend(); ++it2, ++j)
118 double val = fn->eval(
dist(*it1, *it2));
128 double y = it1->getY();
145 DenseMatrix P = computePreconditionMatrix();
147 DenseMatrix Ap = P *
A;
148 DenseMatrix bp = P * b;
154 std::cout <<
"Computing RBF weights using dense solver." << std::endl;
155 std::cout <<
"The radius of the RBF is equal to " << e << std::endl;
171 weights =
A.colPivHouseholderQr().solve(b);
174 double err = (
A * weights - b).norm() / b.norm();
175 std::cout <<
"Error: " << std::setprecision(10) << err << std::endl;
184double RBFSpline::eval(DenseVector x)
const
186 std::vector<double> y;
188 for (
int i = 0;
i < x.rows();
i++)
196double RBFSpline::eval(std::vector<double> x)
const
198 assert(x.size() == dim);
199 double fval, sum = 0, sumw = 0;
202 for (
auto it = samples.cbegin(); it != samples.cend(); ++it, ++
i)
204 fval = fn->eval(
dist(x, it->getX()));
205 sumw += weights(
i) * fval;
209 return normalized ? sumw / sum : sumw;
267DenseMatrix RBFSpline::computePreconditionMatrix()
const
270 P.setZero(numSamples, numSamples);
273 int sigma = std::max(1.0,
274 std::floor(0.1 * numSamples));
277 for (
auto it1 = samples.cbegin(); it1 != samples.cend(); ++it1, ++
i)
279 Point p1(it1->getX());
281 std::vector<Point> shifted_points;
284 for (
auto it2 = samples.cbegin(); it2 != samples.cend(); ++it2, ++j)
286 Point p2(it2->getX());
289 shifted_points.push_back(p3);
292 std::sort(shifted_points.begin(), shifted_points.end());
294 std::vector<Point> points;
295 std::vector<int> indices;
297 for (
int j = 0; j < sigma; j++)
299 Point
p(shifted_points.at(j));
300 indices.push_back(
p.getIndex());
302 p2.setIndex(
p.getIndex());
310 for (
int k = 0; k < 1; k++)
312 Point
p(shifted_points.at(shifted_points.size() - 1 - k));
313 indices.push_back(
p.getIndex());
315 p2.setIndex(
p.getIndex());
316 points.push_back(p2);
320 int m = points.size();
328 assert(points.front().getIndex() ==
i);
330 for (
int k1 = 0; k1 < m; k1++)
332 for (
int k2 = 0; k2 < m; k2++)
334 Point
p = points.at(k1) - points.at(k2);
335 B(k1, k2) = fn->eval(
p.dist());
342 Eigen::JacobiSVD<DenseMatrix>
svd(B, Eigen::ComputeThinU | Eigen::ComputeThinV);
346 for (
unsigned int j = 0; j < numSamples; j++)
348 auto it = find(indices.begin(), indices.end(), j);
350 if (it != indices.end())
352 int k = it - indices.begin();
355 assert(points.at(k).getIndex() == j);
366double RBFSpline::dist(std::vector<double> x, std::vector<double> y)
const
368 assert(x.size() == y.size());
371 for (
unsigned int i = 0;
i < x.size();
i++)
373 sum += (x.at(
i) - y.at(
i)) * (x.at(
i) - y.at(
i));
376 return std::sqrt(sum);
382double RBFSpline::dist(DataPoint x, DataPoint y)
const
384 return dist(x.getX(), y.getX());
387bool RBFSpline::dist_sort(DataPoint x, DataPoint y)
const
389 std::vector<double> zeros(x.getDimX(), 0);
390 DataPoint origin(zeros, 0.0);
391 double x_dist =
dist(x, origin);
392 double y_dist =
dist(y, origin);
393 return (x_dist < y_dist);
double dist(const std::vector< double > x, const std::vector< double > y)
Info<< endl;Info<< "*********************************************************"<< endl;Info<< "Performing test for the parameterized BC inverse solver"<< endl;Info<< endl;word outputFolder="./ITHACAoutput/parameterizedBCtest_RBFparameter/";volScalarField gTrueField=example_paramBC.list2Field(example_paramBC.gTrue);ITHACAstream::exportSolution(gTrueField, "1", outputFolder, "gTrue");Eigen::VectorXd rbfWidth=EigenFunctions::ExpSpaced(0.001, 100, rbfWidthTest_size);ITHACAstream::exportMatrix(rbfWidth, "rbfShapeParameters", "eigen", outputFolder);Eigen::VectorXd residualNorms;residualNorms.resize(rbfWidthTest_size);Eigen::VectorXd heatFluxL2norm(rbfWidthTest_size);Eigen::VectorXd heatFluxLinfNorm=heatFluxL2norm;Eigen::VectorXd condNumber=heatFluxL2norm;Eigen::MatrixXd singVal;for(int i=0;i< rbfWidthTest_size;i++){ Info<< "*********************************************************"<< endl;Info<< "RBF parameter "<< rbfWidth(i)<< endl;Info<< "Test "<< i+1<< endl;Info<< endl;example_paramBC.set_gParametrized("rbf", rbfWidth(i));example_paramBC.parameterizedBCoffline(1);example_paramBC.parameterizedBC("fullPivLU");volScalarField gParametrizedField=example_paramBC.list2Field(example_paramBC.g);ITHACAstream::exportSolution(gParametrizedField, std::to_string(i+1), outputFolder, "gParametrized");volScalarField &T(example_paramBC._T());ITHACAstream::exportSolution(T, std::to_string(i+1), outputFolder, "T");residualNorms(i)=Foam::sqrt(example_paramBC.residual.squaredNorm());Eigen::MatrixXd A=example_paramBC.Theta.transpose() *example_paramBC.Theta;Eigen::JacobiSVD< Eigen::MatrixXd > svd(A, Eigen::ComputeThinU|Eigen::ComputeThinV)