14 #include "surrogate.h" 30 virtual inline int order()
const = 0;
31 virtual inline int phiZero()
const = 0;
38 virtual inline double eval(
double dist)
const = 0;
44 virtual inline double deriv(
double dist)
const = 0;
50 virtual inline mat eval(
const mat &dists)
const = 0;
56 virtual inline mat deriv(
const mat &dists)
const = 0;
75 inline int phiZero()
const {
return mPhiZero;
77 inline double eval(
double dist)
const {
78 return dist * dist * dist;
80 inline double deriv(
double dist)
const {
81 return 3 * dist * dist;
84 return dists % dists % dists;
87 return 3 * dists % dists;
111 inline double eval(
double dist)
const {
112 return dist * dist * std::log(dist + 1e-12);
114 inline double deriv(
double dist)
const {
115 return dist * (1.0 + 2.0 * std::log(dist + 1e-12));
118 return dists % dists % arma::log(dists + 1e-12);
121 return dists % (1 + 2.0 * arma::log(dists + 1e-12));
145 inline double eval(
double dist)
const {
148 inline double deriv(
double dist)
const {
155 return arma::ones<mat>(dists.n_rows, dists.n_cols);
170 virtual inline int degree()
const = 0;
176 virtual inline int dimTail(
int dim)
const = 0;
182 virtual inline vec eval(
const vec &point)
const = 0;
188 virtual inline mat eval(
const mat &points)
const = 0;
194 virtual inline mat deriv(
const vec &point)
const = 0;
215 return arma::join_vert(arma::ones<mat>(1, X.n_cols), X);
218 vec tail = arma::ones<vec>(x.n_rows + 1);
219 tail.tail(x.n_rows) = x;
223 return arma::join_vert(arma::zeros<mat>(1, x.n_rows),
224 arma::eye<mat>(x.n_rows, x.n_rows));
248 return arma::ones<mat>(1, X.n_cols);
251 return arma::ones<mat>(1, 1);
254 return arma::zeros<mat>(1, x.n_rows);
318 template<
class RBFKernel = CubicKernel,
class PolyTail = LinearTail>
351 mNumPoints = (int)points.n_cols;
352 int n = mNumPoints + mDimTail;
353 if(mNumPoints < mDimTail) {
354 throw std::logic_error(
"Not enough points");
356 mat px = mTail.eval(points);
359 mat A = arma::zeros<mat>(n, n);
360 A(arma::span(mDimTail, n - 1), arma::span(0, mDimTail - 1)) = px.t();
361 A(arma::span(0, mDimTail - 1), arma::span(mDimTail, n - 1)) = px;
362 A(arma::span(mDimTail, n - 1), arma::span(mDimTail, n - 1)) = phi;
363 mfX.rows(mDimTail, n - 1) = funVals;
366 A += mEta*arma::eye(n, n);
370 arma::lu(L, U, P, A);
372 mL(arma::span(0, n - 1), arma::span(0, n - 1)) = L;
373 mU(arma::span(0, n - 1), arma::span(0, n - 1)) = U;
376 for(
int i = 0; i < n; i++) {
377 uvec temp = find(P.row(i) > 0.5);
381 mCenters.cols(0, mNumPoints - 1) = points;
392 RBFInterpolant(maxPoints, dim, arma::zeros(dim), arma::ones(dim)) {}
400 RBFInterpolant(maxPoints, dim, arma::zeros(dim), arma::ones(dim), eta) {}
424 mMaxPoints = maxPoints;
426 mDimTail = mTail.dimTail(dim);
428 mCenters = arma::zeros<mat>(dim, maxPoints);
429 mL = arma::zeros<mat>(maxPoints + mDimTail, maxPoints + mDimTail);
430 mU = arma::zeros<mat>(maxPoints + mDimTail, maxPoints + mDimTail);
431 mp = arma::zeros<uvec>(maxPoints + mDimTail);
432 mfX = arma::zeros<vec>(maxPoints + mDimTail);
433 mCoeffs =
vec(maxPoints + mDimTail);
438 if ((mKernel.order() - 1) > mTail.degree()) {
439 throw std::logic_error(
"Kernel and tail mismatch");
459 return fromUnitBox((
mat)mCenters.cols(0, mNumPoints - 1), mxLow, mxUp);
469 return mfX.rows(mDimTail, mDimTail + mNumPoints - 1);
473 double fX(
int i)
const {
474 return mfX(mDimTail + i);
484 if(mDirty) {
throw std::logic_error(
"RBF not updated"); }
490 if(mNumPoints < mDimTail) {
491 throw std::logic_error(
"Not enough points");
494 int n = mNumPoints + mDimTail;
495 mCoeffs = arma::solve(arma::trimatl(mL(arma::span(0, n - 1), arma::span(0, n - 1))), mfX(mp(arma::span(0, n - 1))));
496 mCoeffs = arma::solve(arma::trimatu(mU(arma::span(0, n - 1), arma::span(0, n - 1))), mCoeffs);
509 if(mNumPoints == 0) {
512 return setPoints(point, fVal);
518 int nAct = mDimTail + mNumPoints;
519 if(mNumPoints + 1 > mMaxPoints) {
520 throw std::logic_error(
"Capacity exceeded");
523 vec vx = arma::join_vert(mTail.eval(point),
525 vec u12 = arma::solve(arma::trimatl(mL(arma::span(0, nAct - 1), arma::span(0, nAct - 1))), vx.rows(mp.head(nAct)));
526 vec l21 = (arma::solve(arma::trimatl(mU(arma::span(0, nAct - 1), arma::span(0, nAct - 1)).t()), vx));
527 double u22 = mKernel.phiZero() + mEta - arma::dot(u12, l21);
529 mL(nAct, arma::span(0, nAct - 1)) = l21.t();
531 mU(arma::span(0, nAct - 1), nAct) = u12;
532 mU(nAct, nAct) = u22;
537 mCenters.col(mNumPoints) = point;
551 if(mNumPoints == 0) {
552 return setPoints(ppoints, funVals);
558 int nAct = mDimTail + mNumPoints;
559 int n = (int)funVals.n_rows;
561 throw std::logic_error(
"Use add_point instead");
563 if(mNumPoints + n > mMaxPoints) {
564 throw std::logic_error(
"Capacity exceeded");
567 auto px = mTail.eval(points);
568 mat B = arma::zeros(nAct, n);
569 B.rows(arma::span(0, mDim)) = px;
570 B.rows(mDimTail, nAct - 1) = mKernel.eval(arma::sqrt(squaredPairwiseDistance<mat>(mCenters.cols(0, mNumPoints - 1), points)));
571 mat K = mKernel.eval(arma::sqrt(squaredPairwiseDistance<mat>(points, points)));
574 K += mEta*arma::eye(n, n);
577 mat U12 = arma::solve(arma::trimatl(mL(arma::span(0, nAct - 1), arma::span(0, nAct - 1))), B.rows(mp.head(nAct)));
578 mat L21 = (arma::solve(arma::trimatl(mU(arma::span(0, nAct - 1), arma::span(0, nAct - 1)).t()), B)).t();
581 C = arma::chol(K - L21*U12,
"lower");
583 catch (std::runtime_error) {
584 std::cout <<
"Warning: Cholesky factorization failed, computing new LU from scratch..." << std::endl;
586 mfX.rows(nAct, nAct + n - 1) = funVals;
587 mCenters.cols(mNumPoints, mNumPoints + n - 1) = points;
590 setPoints(X(), mfX.rows(mDimTail, nAct + n - 1));
593 mL(arma::span(nAct, nAct + n - 1), arma::span(0, nAct - 1)) = L21;
594 mL(arma::span(nAct, nAct + n - 1), arma::span(nAct, nAct + n - 1)) = C;
595 mU(arma::span(0, nAct - 1), arma::span(nAct, nAct + n - 1)) = U12;
596 mU(arma::span(nAct, nAct + n - 1), arma::span(nAct, nAct + n - 1)) = C.t();
597 mp.rows(arma::span(nAct, nAct + n - 1)) = arma::linspace<uvec>(nAct, nAct + n - 1, n);
600 mfX.rows(nAct, nAct + n - 1) = funVals;
601 mCenters.cols(mNumPoints, mNumPoints + n - 1) = points;
615 if(mDirty) {
throw std::logic_error(
"RBF not updated. You need to call fit() first"); }
620 vec px = mTail.eval(point);
622 vec c = mCoeffs.head(mNumPoints + mDimTail);
623 return arma::dot(c.head(mDimTail), px) + arma::dot(c.tail(mNumPoints), phi);
635 if(mDirty) {
throw std::logic_error(
"RBF not updated. You need to call fit() first"); }
636 if(not (arma::all(mxLow == 0) and arma::all(mxUp == 1))) {
637 std::cout <<
"RBF uses internal scaling so distances have to be recomputed" << std::endl;
644 vec px = mTail.eval(point);
645 vec phi = mKernel.eval(dists);
646 vec c = mCoeffs.head(mNumPoints + mDimTail);
647 return arma::dot(c.head(mDimTail), px) + arma::dot(c.tail(mNumPoints), phi);
658 if(mDirty) {
throw std::logic_error(
"RBF not updated. You need to call fit() first"); }
663 mat px = mTail.eval(points);
665 (
mat)mCenters.cols(0, mNumPoints - 1), points)));
666 vec c = mCoeffs.head(mNumPoints + mDimTail);
667 return px.t() * c.head(mDimTail) + phi.t() * c.tail(mNumPoints);
679 if(mDirty) {
throw std::logic_error(
"RBF not updated. You need to call fit() first"); }
680 if(not (arma::all(mxLow == 0) and arma::all(mxUp == 1))) {
681 std::cout <<
"RBF uses internal scaling so distances have to be recomputed" << std::endl;
682 return evals(ppoints);
688 mat px = mTail.eval(points);
689 mat phi = mKernel.eval(dists);
690 vec c = mCoeffs.head(mNumPoints + mDimTail);
691 return px.t() * c.head(mDimTail) + phi.t() * c.tail(mNumPoints);
702 if(mDirty) {
throw std::logic_error(
"RBF not updated. You need to call fit() first"); }
707 mat dpx = mTail.deriv(point);
708 vec c = mCoeffs.head(mNumPoints + mDimTail);
709 vec dists = arma::sqrt(squaredPairwiseDistance<mat>(
710 mCenters.cols(0, mNumPoints - 1), point));
711 dists.elem(arma::find(dists < 1e-10)).fill(1e-10);
712 mat dsx = - mCenters.cols(0, mNumPoints - 1);
713 dsx.each_col() += point;
714 dsx.each_row() %= (mKernel.deriv(dists) % c.tail(mNumPoints)/dists).t();
715 return arma::sum(dsx, 1) + dpx.t() * c.head(mDimTail);
731 template<
class RBFKernel,
class PolyTail>
743 RBFInterpolant<RBFKernel,PolyTail>(maxPoints, dim, xLow, xUp, eta) {}
755 if(this->mNumPoints < this->mDimTail) {
756 throw std::logic_error(
"Not enough points");
759 int n = this->mNumPoints + this->mDimTail;
761 double medf = arma::median(ff.rows(this->mDimTail, n-1));
762 for(
int i=this->mDimTail; i < n; i++) {
769 this->mCoeffs = arma::solve(arma::trimatl(
770 this->mL(arma::span(0, n - 1), arma::span(0, n - 1))), ff(this->mp(arma::span(0, n - 1))));
771 this->mCoeffs = arma::solve(arma::trimatu(
772 this->mU(arma::span(0, n - 1), arma::span(0, n - 1))), this->mCoeffs );
773 this->mDirty =
false;
void addPoints(const mat &ppoints, const vec &funVals)
Method for adding multiple points with known values.
Definition: rbf.h:550
vec eval(const vec &x) const
Method for evaluating the monomial basis function for a given point.
Definition: rbf.h:250
RBFInterpolant(int maxPoints, int dim, vec xLow, vec xUp, double eta)
Constructor.
Definition: rbf.h:410
Constant polynomial tail.
Definition: rbf.h:240
Abstract class for a polynomial tail.
Definition: rbf.h:168
arma::vec vec
Default (column) vector class.
Definition: common.h:17
mat mL
Definition: rbf.h:324
vec fX() const
Method for getting the values of the current points.
Definition: rbf.h:468
arma::uvec uvec
Default unsigned (column) vector class.
Definition: common.h:22
mat deriv(const mat &dists) const
Method for evaluating the derivative of the kernel for a matrix of distances.
Definition: rbf.h:154
double deriv(double dist) const
Method for evaluating the derivative of the kernel for a given distance.
Definition: rbf.h:80
RBFInterpolant(int maxPoints, int dim)
Constructor.
Definition: rbf.h:391
int order() const
Method for getting the order of the kernel.
Definition: rbf.h:105
int mDim
Definition: rbf.h:337
void addPoint(const vec &ppoint, double funVal)
Method for adding one points with known value.
Definition: rbf.h:508
double fX(int i) const
Method for getting the value of current point number i (0 is the first)
Definition: rbf.h:473
mat deriv(const mat &dists) const
Method for evaluating the derivative of the kernel for a matrix of distances.
Definition: rbf.h:86
mat eval(const mat &X) const
Method for evaluating the monomial basis function for multiple points.
Definition: rbf.h:247
int order() const
Method for getting the order of the kernel.
Definition: rbf.h:73
vec evals(const mat &ppoints) const
Method for evaluating the surrogate model at multiple points.
Definition: rbf.h:657
Abstract class for a SOT surrogate model.
Definition: surrogate.h:25
mat mCenters
Definition: rbf.h:329
RBFInterpolantCap(int maxPoints, int dim, vec xLow, vec xUp)
Constructor with default eta.
Definition: rbf.h:751
int mMaxPoints
Definition: rbf.h:330
int degree() const
Method for getting the degree of the tail.
Definition: rbf.h:244
double deriv(double dist) const
Method for evaluating the derivative of the kernel for a given distance.
Definition: rbf.h:148
int dimTail(int dim) const
Method for the dimensionality of the polynomial space.
Definition: rbf.h:256
double eval(double dist) const
Method for evaluating the kernel for a given distance.
Definition: rbf.h:111
vec deriv(const vec &ppoint) const
Method for evaluating the derivative of the surrogate model at a point.
Definition: rbf.h:701
mat eval(const mat &dists) const
Method for evaluating the kernel for a matrix of distances.
Definition: rbf.h:83
double eval(const vec &ppoint) const
Method for evaluating the surrogate model at a point.
Definition: rbf.h:614
RBFKernel mKernel
Definition: rbf.h:322
vec eval(const vec &x) const
Method for evaluating the monomial basis function for a given point.
Definition: rbf.h:217
void fit()
Method for fitting the surrogate model.
Definition: rbf.h:754
RBFInterpolant(int maxPoints, int dim, vec xLow, vec xUp)
Constructor with default eta.
Definition: rbf.h:423
Linear kernel.
Definition: rbf.h:134
void fit()
Method for fitting the surrogate model.
Definition: rbf.h:489
int mDimTail
Definition: rbf.h:331
Capped RBF interpolant.
Definition: rbf.h:732
MatType squaredPairwiseDistance(const MatType &X, const MatType &Y)
Fast level-3 distance computation between two sets of points.
Definition: utils.h:48
vec toUnitBox(const vec &x, const vec &xLow, const vec &xUp)
Map one point to the unit box.
Definition: utils.h:66
int order() const
Method for getting the order of the kernel.
Definition: rbf.h:139
double eval(double dist) const
Method for evaluating the kernel for a given distance.
Definition: rbf.h:77
int dim() const
Method for getting the number of dimensions.
Definition: rbf.h:443
VecType squaredPointSetDistance(const VecType &x, const MatType &Y)
Fast level-2 distance computation between one point and a set of points.
Definition: utils.h:32
bool mDirty
Definition: rbf.h:333
vec evals(const mat &ppoints, const mat &dists) const
Method for evaluating the surrogate model at multiple points with known distances.
Definition: rbf.h:678
double eval(const vec &ppoint, const vec &dists) const
Method for evaluating the surrogate model at a point with known distances.
Definition: rbf.h:634
vec X(int i) const
Method for getting current point number i (0 is the first)
Definition: rbf.h:463
Linear polynomial tail.
Definition: rbf.h:207
int phiZero() const
Method for getting the value of the kernel at 0.
Definition: rbf.h:75
mat eval(const mat &X) const
Method for evaluating the monomial basis function for multiple points.
Definition: rbf.h:214
int phiZero() const
Method for getting the value of the kernel at 0.
Definition: rbf.h:142
TPS kernel.
Definition: rbf.h:100
int dimTail(int dim) const
Method for the dimensionality of the polynomial space.
Definition: rbf.h:226
void setPoints(const mat &ppoints, const vec &funVals)
Computes the initial LU decomposition.
Definition: rbf.h:346
Cubic kernel.
Definition: rbf.h:68
Abstract class for a radial kernel.
Definition: rbf.h:28
vec fromUnitBox(const vec &x, const vec &xLow, const vec &xUp)
Map one point from the unit box to another hypercube.
Definition: utils.h:94
PolyTail mTail
Definition: rbf.h:323
mat mU
Definition: rbf.h:325
vec mCoeffs
Definition: rbf.h:327
mat eval(const mat &dists) const
Method for evaluating the kernel for a matrix of distances.
Definition: rbf.h:117
int degree() const
Method for getting the degree of the tail.
Definition: rbf.h:211
int numPoints() const
Method for getting the current number of points.
Definition: rbf.h:453
Radial basis function.
Definition: rbf.h:319
double deriv(double dist) const
Method for evaluating the derivative of the kernel for a given distance.
Definition: rbf.h:114
mat deriv(const vec &x) const
Method for evaluating the derivative of the monomial basis function for a given point.
Definition: rbf.h:253
mat X() const
Method for getting the current points.
Definition: rbf.h:458
mat deriv(const vec &x) const
Method for evaluating the derivative of the monomial basis function for a given point.
Definition: rbf.h:222
SOT namespace.
Definition: sot.h:27
int phiZero() const
Method for getting the value of the kernel at 0.
Definition: rbf.h:108
vec mxUp
Definition: rbf.h:335
int mNumPoints
Definition: rbf.h:332
mat deriv(const mat &dists) const
Method for evaluating the derivative of the kernel for a matrix of distances.
Definition: rbf.h:120
RBFInterpolant(int maxPoints, int dim, double eta)
Constructor.
Definition: rbf.h:399
uvec mp
Definition: rbf.h:326
arma::mat mat
Default matrix class.
Definition: common.h:16
mat eval(const mat &dists) const
Method for evaluating the kernel for a matrix of distances.
Definition: rbf.h:151
vec mfX
Definition: rbf.h:328
vec coeffs()
Method for getting the RBF interpolation coefficients.
Definition: rbf.h:483
vec mxLow
Definition: rbf.h:334
RBFInterpolantCap(int maxPoints, int dim, vec xLow, vec xUp, double eta)
Constructor.
Definition: rbf.h:742
double eval(double dist) const
Method for evaluating the kernel for a given distance.
Definition: rbf.h:145
void reset()
Method for resetting the surrogate model.
Definition: rbf.h:448