37 _interpolationCount = 0;
46 _interpolationCount = 0;
62 _eigenTime += after - _before;
69 _varianceTime += after - _before;
76 _searchTime += after - _before;
83 _iterationTime += after - _before;
90 _totalTime += after - _beginning;
91 _interpolationCount += i;
95 std::cout <<
"\nSearch time " << _searchTime <<
"\n";
96 std::cout <<
"Eigen time " << _eigenTime <<
"\n";
97 std::cout <<
"Variance time " << _varianceTime <<
"\n";
98 std::cout <<
"Iteration time " << _iterationTime <<
"\n";
99 std::cout <<
"Total time " << _totalTime <<
"\n";
100 std::cout <<
"Number of interpolations " << _interpolationCount <<
"\n";
107 _npts = dt.template getSize<0>();
108 _dimensions = dt.template getSize<1>();
111 _inn = allocate(ndarray::makeVector(_npts));
116 _data = allocate(ndarray::makeVector(_room, _dimensions));
120 _tree = allocate(ndarray::makeVector(_room, 4));
122 for (i = 0; i < _npts; i++) {
126 _organize(_inn, _npts, -1, -1);
136 ndarray::Array<const T, 1, 1>
const &v,
int n_nn)
const {
139 "Asked for more neighbors than kd tree contains\n");
144 "Asked for zero or a negative number of neighbors\n");
147 if (neighdex.getNumElements() !=
static_cast<ndarray::Size
>(n_nn)) {
149 "Size of neighdex does not equal n_nn in KdTree.findNeighbors\n");
152 if (dd.getNumElements() !=
static_cast<ndarray::Size
>(n_nn)) {
154 "Size of dd does not equal n_nn in KdTree.findNeighbors\n");
159 _neighborCandidates = allocate(ndarray::makeVector(n_nn));
160 _neighborDistances = allocate(ndarray::makeVector(n_nn));
162 _neighborsWanted = n_nn;
164 for (i = 0; i < n_nn; i++) _neighborDistances[i] = -1.0;
166 start = _findNode(v);
168 _neighborDistances[0] = _distance(v, _data[start]);
169 _neighborCandidates[0] = start;
172 for (i = 1; i < 4; i++) {
173 if (_tree[start][i] >= 0) {
174 _lookForNeighbors(v, _tree[start][i], start);
178 for (i = 0; i < n_nn; i++) {
179 neighdex[i] = _neighborCandidates[i];
180 dd[i] = _neighborDistances[i];
186 if (ipt >= _npts || ipt < 0) {
188 "Asked for point that does not exist in KdTree\n");
191 if (idim >= _dimensions || idim < 0) {
193 "KdTree does not have points of that many dimensions\n");
196 return _data[ipt][idim];
201 if (ipt >= _npts || ipt < 0) {
203 "Asked for point that does not exist in KdTree\n");
211 if (v.getNumElements() !=
static_cast<ndarray::Size
>(_dimensions)) {
213 "You are trying to add a point of the incorrect dimensionality to KdTree\n");
216 int i, j, node, dim, dir;
219 dim = _tree[node][DIMENSION] + 1;
220 if (dim == _dimensions) dim = 0;
222 if (_npts == _room) {
223 ndarray::Array<T, 2, 2> dbuff = allocate(ndarray::makeVector(_npts, _dimensions));
224 ndarray::Array<int, 2, 2> tbuff = allocate(ndarray::makeVector(_npts, 4));
226 dbuff.deep() = _data;
227 tbuff.deep() = _tree;
231 _tree = allocate(ndarray::makeVector(_room, 4));
232 _data = allocate(ndarray::makeVector(_room, _dimensions));
234 for (i = 0; i < _npts; i++) {
235 for (j = 0; j < _dimensions; j++) _data[i][j] = dbuff[i][j];
236 for (j = 0; j < 4; j++) _tree[i][j] = tbuff[i][j];
240 _tree[_npts][DIMENSION] = dim;
241 _tree[_npts][PARENT] = node;
242 i = _tree[node][DIMENSION];
244 if (_data[node][i] > v[i]) {
245 if (_tree[node][LT] >= 0) {
247 "Trying to add to KdTree in a node that is already occupied\n");
249 _tree[node][LT] = _npts;
252 if (_tree[node][GEQ] >= 0) {
254 "Trying to add to KdTree in a node that is already occupied\n");
256 _tree[node][GEQ] = _npts;
259 _tree[_npts][LT] = -1;
260 _tree[_npts][GEQ] = -1;
261 for (i = 0; i < _dimensions; i++) {
262 _data[_npts][i] = v[i];
267 i = _walkUpTree(_tree[_npts - 1][PARENT], dir, _npts - 1);
268 if (i != _masterParent) {
280 if (dex < 0 || dex >= _npts) {
282 "Asked for tree information on point that does not exist\n");
285 if (v.getNumElements() != 4) {
287 "Need to pass a 4-element ndarray into KdTree.getTreeNode()\n");
290 v[0] = _tree[dex][DIMENSION];
291 v[1] = _tree[dex][LT];
292 v[2] = _tree[dex][GEQ];
293 v[3] = _tree[dex][PARENT];
298 if (_npts == 1 && _tree[0][PARENT] < 0 && _masterParent == 0) {
308 for (i = 0; i < _npts; i++) isparent.
push_back(0);
311 for (i = 0; i < _npts; i++) {
312 if (_tree[i][PARENT] < 0) j++;
315 std::cout <<
"_tree FAILURE " << j <<
" _masterParents\n";
319 for (i = 0; i < _npts; i++) {
320 if (_tree[i][PARENT] >= 0) {
321 isparent[_tree[i][PARENT]]++;
325 for (i = 0; i < _npts; i++) {
326 if (isparent[i] > 2) {
327 std::cout <<
"_tree FAILURE " << i <<
" is parent to " << isparent[i] <<
"\n";
332 for (i = 0; i < _npts; i++) {
333 if (_tree[i][PARENT] >= 0) {
334 if (_tree[_tree[i][PARENT]][LT] == i)
338 output = _walkUpTree(_tree[i][PARENT], j, i);
340 if (output != _masterParent) {
346 if (output != _masterParent)
353void KdTree<T>::_organize(ndarray::Array<int, 1, 1>
const &use,
int ct,
int parent,
int dir) {
354 int i, j, k, l, idim, daughter;
355 T mean, var, varbest;
366 for (i = 0; i < _dimensions; i++) {
369 for (j = 0; j < ct; j++) {
370 mean += _data[use[j]][i];
371 var += _data[use[j]][i] * _data[use[j]][i];
373 mean = mean / double(ct);
374 var = var / double(ct) - mean * mean;
375 if (i == 0 || var > varbest || (var == varbest && parent >= 0 && i > _tree[parent][DIMENSION])) {
389 toSortElement.
push_back(_data[use[0]][idim]);
392 for (i = 1; i < ct; i++) {
393 toSortElement[0] = _data[use[i]][idim];
394 toSortElement[1] =
T(use[i]);
402 while (k > 0 && toSort[k][0] == toSort[k - 1][0]) k--;
404 while (l < ct - 1 && toSort[l][0] == toSort[ct / 2][0]) l++;
406 if ((ct / 2 - k) < (l - ct / 2) || l == ct - 1)
411 for (i = 0; i < ct; i++) {
412 use[i] =
int(toSort[i][1]);
416 if (parent >= 0) _tree[parent][dir] = daughter;
417 _tree[daughter][DIMENSION] = idim;
418 _tree[daughter][PARENT] = parent;
421 _organize(use[ndarray::view(j + 1, use.getSize<0>())], ct - j - 1, daughter, GEQ);
423 _tree[daughter][GEQ] = -1;
426 _organize(use, j, daughter, LT);
428 _tree[daughter][LT] = -1;
434 if (parent >= 0) _tree[parent][dir] = daughter;
436 idim = _tree[parent][DIMENSION] + 1;
438 if (idim >= _dimensions) idim = 0;
440 _tree[daughter][DIMENSION] = idim;
441 _tree[daughter][LT] = -1;
442 _tree[daughter][GEQ] = -1;
443 _tree[daughter][PARENT] = parent;
447 _masterParent = daughter;
452int KdTree<T>::_findNode(ndarray::Array<const T, 1, 1>
const &v)
const {
453 int consider,
next, dim;
455 dim = _tree[_masterParent][DIMENSION];
457 if (v[dim] < _data[_masterParent][dim])
458 consider = _tree[_masterParent][LT];
460 consider = _tree[_masterParent][GEQ];
467 dim = _tree[consider][DIMENSION];
468 if (v[dim] < _data[consider][dim])
469 next = _tree[consider][LT];
471 next = _tree[consider][GEQ];
478void KdTree<T>::_lookForNeighbors(ndarray::Array<const T, 1, 1>
const &v,
int consider,
int from)
const {
482 dd = _distance(v, _data[consider]);
484 if (_neighborsFound < _neighborsWanted || dd < _neighborDistances[_neighborsWanted - 1]) {
485 for (j = 0; j < _neighborsFound && _neighborDistances[j] < dd; j++)
488 for (i = _neighborsWanted - 1; i > j; i--) {
489 _neighborDistances[i] = _neighborDistances[i - 1];
490 _neighborCandidates[i] = _neighborCandidates[i - 1];
493 _neighborDistances[j] = dd;
494 _neighborCandidates[j] = consider;
496 if (_neighborsFound < _neighborsWanted) _neighborsFound++;
499 if (_tree[consider][PARENT] == from) {
502 i = _tree[consider][DIMENSION];
503 dd = v[i] - _data[consider][i];
504 if ((dd <= _neighborDistances[_neighborsFound - 1] || _neighborsFound < _neighborsWanted) &&
505 _tree[consider][LT] >= 0) {
506 _lookForNeighbors(v, _tree[consider][LT], consider);
509 dd = _data[consider][i] - v[i];
510 if ((dd <= _neighborDistances[_neighborsFound - 1] || _neighborsFound < _neighborsWanted) &&
511 _tree[consider][GEQ] >= 0) {
512 _lookForNeighbors(v, _tree[consider][GEQ], consider);
518 if (_tree[consider][LT] == from) {
524 j = _tree[consider][going];
527 i = _tree[consider][DIMENSION];
530 dd = v[i] - _data[consider][i];
532 dd = _data[consider][i] - v[i];
534 if (dd <= _neighborDistances[_neighborsFound - 1] || _neighborsFound < _neighborsWanted) {
535 _lookForNeighbors(v, j, consider);
540 if (_tree[consider][PARENT] >= 0) {
541 _lookForNeighbors(v, _tree[consider][PARENT], consider);
547int KdTree<T>::_walkUpTree(
int target,
int dir,
int root)
const {
557 if (_data[root][_tree[
target][DIMENSION]] >= _data[
target][_tree[
target][DIMENSION]]) {
561 if (_data[root][_tree[
target][DIMENSION]] < _data[
target][_tree[
target][DIMENSION]]) {
566 if (_tree[
target][PARENT] >= 0) {
571 output = output * _walkUpTree(_tree[
target][PARENT], i, root);
583 if (target < 0 || target >= _npts) {
585 "You are trying to remove a point that doesn't exist from KdTree\n");
590 "There is only one point left in this KdTree. You cannot call removePoint\n");
593 int nl, nr, i, j, k, side;
598 if (_tree[
target][LT] >= 0) {
600 _count(_tree[
target][LT], &nl);
603 if (_tree[
target][GEQ] >= 0) {
605 _count(_tree[
target][GEQ], &nr);
608 if (nl == 0 && nr == 0) {
609 k = _tree[
target][PARENT];
611 if (_tree[k][LT] ==
target)
613 else if (_tree[k][GEQ] ==
target)
617 else if ((nl == 0 && nr > 0) || (nr == 0 && nl > 0)) {
623 k = _tree[
target][PARENT];
625 if (_tree[k][LT] ==
target) {
626 _tree[k][LT] = _tree[
target][side];
627 _tree[_tree[k][LT]][PARENT] = k;
630 _tree[k][GEQ] = _tree[
target][side];
631 _tree[_tree[k][GEQ]][PARENT] = k;
634 _masterParent = _tree[
target][side];
635 _tree[_tree[
target][side]][PARENT] = -1;
644 k = _tree[
target][PARENT];
646 _masterParent = _tree[
target][side];
647 _tree[_masterParent][PARENT] = -1;
649 if (_tree[k][LT] ==
target) {
650 _tree[k][LT] = _tree[
target][side];
651 _tree[_tree[k][LT]][PARENT] = k;
653 _tree[k][GEQ] = _tree[
target][side];
654 _tree[_tree[k][GEQ]][PARENT] = k;
658 root = _tree[
target][3 - side];
664 for (i =
target + 1; i < _npts; i++) {
665 for (j = 0; j < 4; j++) _tree[i - 1][j] = _tree[i][j];
667 for (j = 0; j < _dimensions; j++) _data[i - 1][j] = _data[i][j];
670 for (i = 0; i < _npts; i++) {
671 for (j = 1; j < 4; j++) {
672 if (_tree[i][j] >
target) _tree[i][j]--;
676 if (_masterParent >
target) _masterParent--;
690 if (_tree[where][LT] >= 0) {
692 _count(_tree[where][LT], ct);
694 if (_tree[where][GEQ] >= 0) {
696 _count(_tree[where][GEQ], ct);
701void KdTree<T>::_reassign(
int target) {
704 where = _masterParent;
705 if (_data[
target][_tree[where][DIMENSION]] < _data[where][_tree[where][DIMENSION]])
710 k = _tree[where][dir];
713 if (_data[
target][_tree[where][DIMENSION]] < _data[where][_tree[where][DIMENSION]])
717 k = _tree[where][dir];
724 _tree[
target][DIMENSION] = _tree[
where][DIMENSION] + 1;
726 if (_tree[
target][DIMENSION] == _dimensions) _tree[
target][DIMENSION] = 0;
730void KdTree<T>::_descend(
int root) {
731 if (_tree[root][LT] >= 0) _descend(_tree[root][LT]);
732 if (_tree[root][GEQ] >= 0) _descend(_tree[root][GEQ]);
738double KdTree<T>::_distance(ndarray::Array<const T, 1, 1>
const &p1,
739 ndarray::Array<const T, 1, 1>
const &p2)
const {
743 dd = p1.template getSize<0>();
745 for (i = 0; i < dd; i++) ans += (p1[i] - p2[i]) * (p1[i] - p2[i]);
757 _covariogram = covarIn;
759 _npts = dataIn.template getSize<0>();
760 _dimensions = dataIn.template getSize<1>();
766 _function = allocate(ndarray::makeVector(_npts, 1));
768 if (ff.getNumElements() !=
static_cast<ndarray::Size
>(_npts)) {
770 "You did not pass in the same number of data points as function values\n");
773 for (i = 0; i < _npts; i++) _function[i][0] = ff[i];
775 _krigingParameter = T(1.0);
780 _kdTree.Initialize(dataIn);
782 _npts = _kdTree.getNPoints();
787 ndarray::Array<T, 1, 1>
const &mx, ndarray::Array<T, 1, 1>
const &ff,
790 ndarray::Array<T, 2, 2> normalizedData;
792 _covariogram = covarIn;
794 _npts = dataIn.template getSize<0>();
795 _dimensions = dataIn.template getSize<1>();
799 if (ff.getNumElements() !=
static_cast<ndarray::Size
>(_npts)) {
801 "You did not pass in the same number of data points as function values\n");
804 if (mn.getNumElements() !=
static_cast<ndarray::Size
>(_dimensions) ||
805 mx.getNumElements() !=
static_cast<ndarray::Size
>(_dimensions)) {
807 "Your min/max values have different dimensionality than your data points\n");
810 _krigingParameter = T(1.0);
813 _krigingParameter = T(1.0);
815 _max = allocate(ndarray::makeVector(_dimensions));
816 _min = allocate(ndarray::makeVector(_dimensions));
820 normalizedData = allocate(ndarray::makeVector(_npts, _dimensions));
821 for (i = 0; i < _npts; i++) {
822 for (j = 0; j < _dimensions; j++) {
823 normalizedData[i][j] = (dataIn[i][j] - _min[j]) / (_max[j] - _min[j]);
828 _kdTree.Initialize(normalizedData);
830 _npts = _kdTree.getNPoints();
832 _function = allocate(ndarray::makeVector(_npts, 1));
833 for (i = 0; i < _npts; i++) _function[i][0] = ff[i];
839 _covariogram = covarIn;
841 _npts = dataIn.template getSize<0>();
842 _dimensions = dataIn.template getSize<1>();
847 if (ff.template getSize<0>() !=
static_cast<ndarray::Size
>(_npts)) {
849 "You did not pass in the same number of data points as function values\n");
852 _nFunctions = ff.template getSize<1>();
853 _function = allocate(ndarray::makeVector(_npts, _nFunctions));
854 _function.deep() = ff;
856 _krigingParameter = T(1.0);
862 _kdTree.Initialize(dataIn);
864 _npts = _kdTree.getNPoints();
869 ndarray::Array<T, 1, 1>
const &mx, ndarray::Array<T, 2, 2>
const &ff,
872 ndarray::Array<T, 2, 2> normalizedData;
874 _covariogram = covarIn;
876 _npts = dataIn.template getSize<0>();
877 _dimensions = dataIn.template getSize<1>();
882 if (ff.template getSize<0>() !=
static_cast<ndarray::Size
>(_npts)) {
884 "You did not pass in the same number of data points as function values\n");
887 if (mn.getNumElements() !=
static_cast<ndarray::Size
>(_dimensions) ||
888 mx.getNumElements() !=
static_cast<ndarray::Size
>(_dimensions)) {
890 "Your min/max values have different dimensionality than your data points\n");
893 _krigingParameter = T(1.0);
896 _krigingParameter = T(1.0);
898 _max = allocate(ndarray::makeVector(_dimensions));
899 _min = allocate(ndarray::makeVector(_dimensions));
903 normalizedData = allocate(ndarray::makeVector(_npts, _dimensions));
904 for (i = 0; i < _npts; i++) {
905 for (j = 0; j < _dimensions; j++) {
906 normalizedData[i][j] = (dataIn[i][j] - _min[j]) / (_max[j] - _min[j]);
911 _kdTree.Initialize(normalizedData);
912 _npts = _kdTree.getNPoints();
913 _nFunctions = ff.template getSize<1>();
914 _function = allocate(ndarray::makeVector(_npts, _nFunctions));
915 _function.deep() = ff;
930 ndarray::Array<int, 1, 1> indices)
const {
931 if (_nFunctions != 1) {
933 "Your function value array does not have enough room for all of the functions "
934 "in your GaussianProcess.\n");
937 if (pts.template getSize<1>() !=
static_cast<ndarray::Size
>(_dimensions)) {
939 "Your pts array is constructed for points of the wrong dimensionality.\n");
942 if (pts.template getSize<0>() != indices.getNumElements()) {
944 "You did not put enough room in your pts array to fit all the points "
945 "you asked for in your indices array.\n");
948 if (fn.template getSize<0>() != indices.getNumElements()) {
950 "You did not provide enough room in your function value array "
951 "for all of the points you requested in your indices array.\n");
954 for (ndarray::Size i = 0; i < indices.template getSize<0>(); i++) {
955 pts[i] = _kdTree.getData(indices[i]);
957 fn[i] = _function[indices[i]][0];
958 if (_useMaxMin == 1) {
959 for (
int j = 0; j < _dimensions; j++) {
960 pts[i][j] *= (_max[j] - _min[j]);
961 pts[i][j] += _min[j];
969 ndarray::Array<int, 1, 1> indices)
const {
970 if (fn.template getSize<1>() !=
static_cast<ndarray::Size
>(_nFunctions)) {
972 "Your function value array does not have enough room for all of the functions "
973 "in your GaussianProcess.\n");
976 if (pts.template getSize<1>() !=
static_cast<ndarray::Size
>(_dimensions)) {
978 "Your pts array is constructed for points of the wrong dimensionality.\n");
981 if (pts.template getSize<0>() != indices.getNumElements()) {
983 "You did not put enough room in your pts array to fit all the points "
984 "you asked for in your indices array.\n");
987 if (fn.template getSize<0>() != indices.getNumElements()) {
989 "You did not provide enough room in your function value array "
990 "for all of the points you requested in your indices array.\n");
993 for (ndarray::Size i = 0; i < indices.template getSize<0>(); i++) {
994 pts[i] = _kdTree.getData(indices[i]);
996 for (
int j = 0; j < _nFunctions; j++) {
997 fn[i][j] = _function[indices[i]][j];
999 if (_useMaxMin == 1) {
1000 for (
int j = 0; j < _dimensions; j++) {
1001 pts[i][j] *= (_max[j] - _min[j]);
1002 pts[i][j] += _min[j];
1008template <
typename T>
1010 int numberOfNeighbors)
const {
1011 if (_nFunctions > 1) {
1013 "You need to call the version of GaussianProcess.interpolate() "
1014 "that accepts mu and variance arrays (which it populates with results). "
1015 "You are interpolating more than one function.");
1018 if (numberOfNeighbors <= 0) {
1020 "Asked for zero or negative number of neighbors\n");
1023 if (numberOfNeighbors > _kdTree.getNPoints()) {
1025 "Asked for more neighbors than you have data points\n");
1028 if (
variance.getNumElements() !=
static_cast<ndarray::Size
>(_nFunctions)) {
1030 "Your variance array is the incorrect size for the number "
1031 "of functions you are trying to interpolate\n");
1034 if (vin.getNumElements() !=
static_cast<ndarray::Size
>(_dimensions)) {
1036 "You are interpolating at a point with different dimensionality than you data\n");
1042 ndarray::Array<T, 1, 1> covarianceTestPoint;
1043 ndarray::Array<int, 1, 1> neighbors;
1044 ndarray::Array<double, 1, 1> neighborDistances, vv;
1046 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
covariance, bb, xx;
1047 Eigen::LDLT<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > ldlt;
1051 bb.resize(numberOfNeighbors, 1);
1052 xx.resize(numberOfNeighbors, 1);
1054 covariance.resize(numberOfNeighbors, numberOfNeighbors);
1056 covarianceTestPoint = allocate(ndarray::makeVector(numberOfNeighbors));
1058 neighbors = allocate(ndarray::makeVector(numberOfNeighbors));
1060 neighborDistances = allocate(ndarray::makeVector(numberOfNeighbors));
1062 vv = allocate(ndarray::makeVector(_dimensions));
1063 if (_useMaxMin == 1) {
1069 for (i = 0; i < _dimensions; i++) vv[i] = (vin[i] - _min[i]) / (_max[i] - _min[i]);
1074 _kdTree.findNeighbors(neighbors, neighborDistances, vv, numberOfNeighbors);
1076 _timer.addToSearch();
1079 for (i = 0; i < numberOfNeighbors; i++) fbar += _function[neighbors[i]][0];
1080 fbar = fbar / double(numberOfNeighbors);
1082 for (i = 0; i < numberOfNeighbors; i++) {
1083 covarianceTestPoint[i] = (*_covariogram)(vv, _kdTree.getData(neighbors[i]));
1086 (*_covariogram)(_kdTree.getData(neighbors[i]), _kdTree.getData(neighbors[i])) + _lambda;
1088 for (j = i + 1; j < numberOfNeighbors; j++) {
1089 covariance(i, j) = (*_covariogram)(_kdTree.getData(neighbors[i]), _kdTree.getData(neighbors[j]));
1094 _timer.addToIteration();
1099 for (i = 0; i < numberOfNeighbors; i++) bb(i, 0) = _function[neighbors[i]][0] - fbar;
1101 xx = ldlt.solve(bb);
1102 _timer.addToEigen();
1106 for (i = 0; i < numberOfNeighbors; i++) {
1107 mu += covarianceTestPoint[i] * xx(i, 0);
1110 _timer.addToIteration();
1112 variance(0) = (*_covariogram)(vv, vv) + _lambda;
1114 for (i = 0; i < numberOfNeighbors; i++) bb(i) = covarianceTestPoint[i];
1116 xx = ldlt.solve(bb);
1118 for (i = 0; i < numberOfNeighbors; i++) {
1119 variance(0) -= covarianceTestPoint[i] * xx(i, 0);
1124 _timer.addToVariance();
1125 _timer.addToTotal(1);
1130template <
typename T>
1132 ndarray::Array<T, 1, 1>
const &vin,
int numberOfNeighbors)
const {
1133 if (numberOfNeighbors <= 0) {
1135 "Asked for zero or negative number of neighbors\n");
1138 if (numberOfNeighbors > _kdTree.getNPoints()) {
1140 "Asked for more neighbors than you have data points\n");
1143 if (vin.getNumElements() !=
static_cast<ndarray::Size
>(_dimensions)) {
1145 "You are interpolating at a point with different dimensionality than you data\n");
1148 if (mu.getNumElements() !=
static_cast<ndarray::Size
>(_nFunctions) ||
1149 variance.getNumElements() !=
static_cast<ndarray::Size
>(_nFunctions)) {
1151 "Your mu and/or var arrays are improperly sized for the number of functions "
1152 "you are interpolating\n");
1158 ndarray::Array<T, 1, 1> covarianceTestPoint;
1159 ndarray::Array<int, 1, 1> neighbors;
1160 ndarray::Array<double, 1, 1> neighborDistances, vv;
1162 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
covariance, bb, xx;
1163 Eigen::LDLT<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > ldlt;
1167 bb.resize(numberOfNeighbors, 1);
1168 xx.resize(numberOfNeighbors, 1);
1169 covariance.resize(numberOfNeighbors, numberOfNeighbors);
1170 covarianceTestPoint = allocate(ndarray::makeVector(numberOfNeighbors));
1171 neighbors = allocate(ndarray::makeVector(numberOfNeighbors));
1172 neighborDistances = allocate(ndarray::makeVector(numberOfNeighbors));
1174 vv = allocate(ndarray::makeVector(_dimensions));
1176 if (_useMaxMin == 1) {
1182 for (i = 0; i < _dimensions; i++) vv[i] = (vin[i] - _min[i]) / (_max[i] - _min[i]);
1187 _kdTree.findNeighbors(neighbors, neighborDistances, vv, numberOfNeighbors);
1189 _timer.addToSearch();
1191 for (i = 0; i < numberOfNeighbors; i++) {
1192 covarianceTestPoint[i] = (*_covariogram)(vv, _kdTree.getData(neighbors[i]));
1195 (*_covariogram)(_kdTree.getData(neighbors[i]), _kdTree.getData(neighbors[i])) + _lambda;
1197 for (j = i + 1; j < numberOfNeighbors; j++) {
1198 covariance(i, j) = (*_covariogram)(_kdTree.getData(neighbors[i]), _kdTree.getData(neighbors[j]));
1203 _timer.addToIteration();
1208 for (ii = 0; ii < _nFunctions; ii++) {
1210 for (i = 0; i < numberOfNeighbors; i++) fbar += _function[neighbors[i]][ii];
1211 fbar = fbar / double(numberOfNeighbors);
1213 for (i = 0; i < numberOfNeighbors; i++) bb(i, 0) = _function[neighbors[i]][ii] - fbar;
1214 xx = ldlt.solve(bb);
1218 for (i = 0; i < numberOfNeighbors; i++) {
1219 mu[ii] += covarianceTestPoint[i] * xx(i, 0);
1224 _timer.addToEigen();
1226 variance[0] = (*_covariogram)(vv, vv) + _lambda;
1228 for (i = 0; i < numberOfNeighbors; i++) bb(i) = covarianceTestPoint[i];
1230 xx = ldlt.solve(bb);
1232 for (i = 0; i < numberOfNeighbors; i++) {
1233 variance[0] -= covarianceTestPoint[i] * xx(i, 0);
1239 _timer.addToVariance();
1240 _timer.addToTotal(1);
1243template <
typename T>
1245 int numberOfNeighbors)
const {
1246 if (_nFunctions > 1) {
1248 "You need to call the version of GaussianProcess.selfInterpolate() "
1249 "that accepts mu and variance arrays (which it populates with results). "
1250 "You are interpolating more than one function.");
1253 if (
variance.getNumElements() !=
static_cast<ndarray::Size
>(_nFunctions)) {
1255 "Your variance array is the incorrect size for the number "
1256 "of functions you are trying to interpolate\n");
1259 if (numberOfNeighbors <= 0) {
1261 "Asked for zero or negative number of neighbors\n");
1264 if (numberOfNeighbors + 1 > _kdTree.getNPoints()) {
1266 "Asked for more neighbors than you have data points\n");
1269 if (dex < 0 || dex >= _kdTree.getNPoints()) {
1271 "Asked to self interpolate on a point that does not exist\n");
1277 ndarray::Array<T, 1, 1> covarianceTestPoint;
1278 ndarray::Array<int, 1, 1> selfNeighbors;
1279 ndarray::Array<double, 1, 1> selfDistances;
1280 ndarray::Array<int, 1, 1> neighbors;
1281 ndarray::Array<double, 1, 1> neighborDistances;
1283 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
covariance, bb, xx;
1284 Eigen::LDLT<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > ldlt;
1288 bb.resize(numberOfNeighbors, 1);
1289 xx.resize(numberOfNeighbors, 1);
1290 covariance.resize(numberOfNeighbors, numberOfNeighbors);
1291 covarianceTestPoint = allocate(ndarray::makeVector(numberOfNeighbors));
1292 neighbors = allocate(ndarray::makeVector(numberOfNeighbors));
1293 neighborDistances = allocate(ndarray::makeVector(numberOfNeighbors));
1295 selfNeighbors = allocate(ndarray::makeVector(numberOfNeighbors + 1));
1296 selfDistances = allocate(ndarray::makeVector(numberOfNeighbors + 1));
1300 _kdTree.findNeighbors(selfNeighbors, selfDistances, _kdTree.getData(dex), numberOfNeighbors + 1);
1302 _timer.addToSearch();
1304 if (selfNeighbors[0] != dex) {
1306 "Nearest neighbor search in selfInterpolate did not find self\n");
1314 for (i = 0; i < numberOfNeighbors; i++) {
1315 neighbors[i] = selfNeighbors[i + 1];
1316 neighborDistances[i] = selfDistances[i + 1];
1320 for (i = 0; i < numberOfNeighbors; i++) fbar += _function[neighbors[i]][0];
1321 fbar = fbar / double(numberOfNeighbors);
1323 for (i = 0; i < numberOfNeighbors; i++) {
1324 covarianceTestPoint[i] = (*_covariogram)(_kdTree.getData(dex), _kdTree.getData(neighbors[i]));
1327 (*_covariogram)(_kdTree.getData(neighbors[i]), _kdTree.getData(neighbors[i])) + _lambda;
1329 for (j = i + 1; j < numberOfNeighbors; j++) {
1330 covariance(i, j) = (*_covariogram)(_kdTree.getData(neighbors[i]), _kdTree.getData(neighbors[j]));
1334 _timer.addToIteration();
1339 for (i = 0; i < numberOfNeighbors; i++) bb(i, 0) = _function[neighbors[i]][0] - fbar;
1340 xx = ldlt.solve(bb);
1341 _timer.addToEigen();
1345 for (i = 0; i < numberOfNeighbors; i++) {
1346 mu += covarianceTestPoint[i] * xx(i, 0);
1349 variance(0) = (*_covariogram)(_kdTree.getData(dex), _kdTree.getData(dex)) + _lambda;
1351 for (i = 0; i < numberOfNeighbors; i++) bb(i) = covarianceTestPoint[i];
1353 xx = ldlt.solve(bb);
1355 for (i = 0; i < numberOfNeighbors; i++) {
1356 variance(0) -= covarianceTestPoint[i] * xx(i, 0);
1360 _timer.addToVariance();
1361 _timer.addToTotal(1);
1366template <
typename T>
1368 int dex,
int numberOfNeighbors)
const {
1369 if (mu.getNumElements() !=
static_cast<ndarray::Size
>(_nFunctions) ||
1370 variance.getNumElements() !=
static_cast<ndarray::Size
>(_nFunctions)) {
1372 "Your mu and/or var arrays are improperly sized for the number of functions "
1373 "you are interpolating\n");
1376 if (numberOfNeighbors <= 0) {
1378 "Asked for zero or negative number of neighbors\n");
1381 if (numberOfNeighbors + 1 > _kdTree.getNPoints()) {
1383 "Asked for more neighbors than you have data points\n");
1386 if (dex < 0 || dex >= _kdTree.getNPoints()) {
1388 "Asked to self interpolate on a point that does not exist\n");
1394 ndarray::Array<T, 1, 1> covarianceTestPoint;
1395 ndarray::Array<int, 1, 1> selfNeighbors;
1396 ndarray::Array<double, 1, 1> selfDistances;
1397 ndarray::Array<int, 1, 1> neighbors;
1398 ndarray::Array<double, 1, 1> neighborDistances;
1400 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
covariance, bb, xx;
1401 Eigen::LDLT<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > ldlt;
1405 bb.resize(numberOfNeighbors, 1);
1406 xx.resize(numberOfNeighbors, 1);
1407 covariance.resize(numberOfNeighbors, numberOfNeighbors);
1408 covarianceTestPoint = allocate(ndarray::makeVector(numberOfNeighbors));
1409 neighbors = allocate(ndarray::makeVector(numberOfNeighbors));
1410 neighborDistances = allocate(ndarray::makeVector(numberOfNeighbors));
1412 selfNeighbors = allocate(ndarray::makeVector(numberOfNeighbors + 1));
1413 selfDistances = allocate(ndarray::makeVector(numberOfNeighbors + 1));
1417 _kdTree.findNeighbors(selfNeighbors, selfDistances, _kdTree.getData(dex), numberOfNeighbors + 1);
1419 _timer.addToSearch();
1421 if (selfNeighbors[0] != dex) {
1423 "Nearest neighbor search in selfInterpolate did not find self\n");
1431 for (i = 0; i < numberOfNeighbors; i++) {
1432 neighbors[i] = selfNeighbors[i + 1];
1433 neighborDistances[i] = selfDistances[i + 1];
1436 for (i = 0; i < numberOfNeighbors; i++) {
1437 covarianceTestPoint[i] = (*_covariogram)(_kdTree.getData(dex), _kdTree.getData(neighbors[i]));
1440 (*_covariogram)(_kdTree.getData(neighbors[i]), _kdTree.getData(neighbors[i])) + _lambda;
1442 for (j = i + 1; j < numberOfNeighbors; j++) {
1443 covariance(i, j) = (*_covariogram)(_kdTree.getData(neighbors[i]), _kdTree.getData(neighbors[j]));
1447 _timer.addToIteration();
1452 for (ii = 0; ii < _nFunctions; ii++) {
1454 for (i = 0; i < numberOfNeighbors; i++) fbar += _function[neighbors[i]][ii];
1455 fbar = fbar / double(numberOfNeighbors);
1457 for (i = 0; i < numberOfNeighbors; i++) bb(i, 0) = _function[neighbors[i]][ii] - fbar;
1458 xx = ldlt.solve(bb);
1462 for (i = 0; i < numberOfNeighbors; i++) {
1463 mu[ii] += covarianceTestPoint[i] * xx(i, 0);
1467 _timer.addToEigen();
1469 variance[0] = (*_covariogram)(_kdTree.getData(dex), _kdTree.getData(dex)) + _lambda;
1471 for (i = 0; i < numberOfNeighbors; i++) bb(i) = covarianceTestPoint[i];
1473 xx = ldlt.solve(bb);
1475 for (i = 0; i < numberOfNeighbors; i++) {
1476 variance[0] -= covarianceTestPoint[i] * xx(i, 0);
1483 _timer.addToVariance();
1484 _timer.addToTotal(1);
1487template <
typename T>
1489 ndarray::Array<T, 2, 2>
const &queries)
const {
1492 ndarray::Size nQueries = queries.template getSize<0>();
1494 if (_nFunctions != 1) {
1496 "Your mu and variance arrays do not have room for all of the functions "
1497 "as you are trying to interpolate\n");
1500 if (mu.getNumElements() != nQueries ||
variance.getNumElements() != nQueries) {
1502 "Your mu and variance arrays do not have room for all of the points "
1503 "at which you are trying to interpolate your function.\n");
1506 if (queries.template getSize<1>() !=
static_cast<ndarray::Size
>(_dimensions)) {
1508 "The points you passed to batchInterpolate are of the wrong "
1509 "dimensionality for your Gaussian Process\n");
1513 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> batchCovariance, batchbb, batchxx;
1514 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> queryCovariance;
1515 Eigen::LDLT<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > ldlt;
1517 ndarray::Array<T, 1, 1> v1;
1521 v1 = allocate(ndarray::makeVector(_dimensions));
1522 batchbb.resize(_npts, 1);
1523 batchxx.resize(_npts, 1);
1524 batchCovariance.resize(_npts, _npts);
1525 queryCovariance.resize(_npts, 1);
1527 for (i = 0; i < _npts; i++) {
1528 batchCovariance(i, i) = (*_covariogram)(_kdTree.getData(i), _kdTree.getData(i)) + _lambda;
1529 for (j = i + 1; j < _npts; j++) {
1530 batchCovariance(i, j) = (*_covariogram)(_kdTree.getData(i), _kdTree.getData(j));
1531 batchCovariance(j, i) = batchCovariance(i, j);
1534 _timer.addToIteration();
1536 ldlt.compute(batchCovariance);
1539 for (i = 0; i < _npts; i++) {
1540 fbar += _function[i][0];
1542 fbar = fbar / T(_npts);
1544 for (i = 0; i < _npts; i++) {
1545 batchbb(i, 0) = _function[i][0] - fbar;
1547 batchxx = ldlt.solve(batchbb);
1548 _timer.addToEigen();
1550 for (ndarray::Size ii = 0; ii < nQueries; ii++) {
1551 for (i = 0; i < _dimensions; i++) v1[i] = queries[ii][i];
1552 if (_useMaxMin == 1) {
1553 for (i = 0; i < _dimensions; i++) v1[i] = (v1[i] - _min[i]) / (_max[i] - _min[i]);
1556 for (i = 0; i < _npts; i++) {
1557 mu(ii) += batchxx(i) * (*_covariogram)(v1, _kdTree.getData(i));
1560 _timer.addToIteration();
1562 for (ndarray::Size ii = 0; ii < nQueries; ii++) {
1563 for (i = 0; i < _dimensions; i++) v1[i] = queries[ii][i];
1564 if (_useMaxMin == 1) {
1565 for (i = 0; i < _dimensions; i++) v1[i] = (v1[i] - _min[i]) / (_max[i] - _min[i]);
1568 for (i = 0; i < _npts; i++) {
1569 batchbb(i, 0) = (*_covariogram)(v1, _kdTree.getData(i));
1570 queryCovariance(i, 0) = batchbb(i, 0);
1572 batchxx = ldlt.solve(batchbb);
1574 variance[ii] = (*_covariogram)(v1, v1) + _lambda;
1576 for (i = 0; i < _npts; i++) {
1577 variance[ii] -= queryCovariance(i, 0) * batchxx(i);
1583 _timer.addToVariance();
1584 _timer.addToTotal(nQueries);
1587template <
typename T>
1589 ndarray::Array<T, 2, 2>
const &queries)
const {
1592 ndarray::Size nQueries = queries.template getSize<0>();
1594 if (mu.template getSize<0>() != nQueries ||
variance.template getSize<0>() != nQueries) {
1596 "Your output arrays do not have room for all of the points at which "
1597 "you are interpolating your functions.\n");
1600 if (mu.template getSize<1>() !=
static_cast<ndarray::Size
>(_nFunctions) ||
1601 variance.template getSize<1>() !=
static_cast<ndarray::Size
>(_nFunctions)) {
1603 "Your output arrays do not have room for all of the functions you are "
1607 if (queries.template getSize<1>() !=
static_cast<ndarray::Size
>(_dimensions)) {
1609 "The points at which you are interpolating your functions have the "
1610 "wrong dimensionality.\n");
1614 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> batchCovariance, batchbb, batchxx;
1615 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> queryCovariance;
1616 Eigen::LDLT<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > ldlt;
1618 ndarray::Array<T, 1, 1> v1;
1622 v1 = allocate(ndarray::makeVector(_dimensions));
1623 batchbb.resize(_npts, 1);
1624 batchxx.resize(_npts, 1);
1625 batchCovariance.resize(_npts, _npts);
1626 queryCovariance.resize(_npts, 1);
1628 for (i = 0; i < _npts; i++) {
1629 batchCovariance(i, i) = (*_covariogram)(_kdTree.getData(i), _kdTree.getData(i)) + _lambda;
1630 for (j = i + 1; j < _npts; j++) {
1631 batchCovariance(i, j) = (*_covariogram)(_kdTree.getData(i), _kdTree.getData(j));
1632 batchCovariance(j, i) = batchCovariance(i, j);
1636 _timer.addToIteration();
1638 ldlt.compute(batchCovariance);
1640 _timer.addToEigen();
1642 for (ifn = 0; ifn < _nFunctions; ifn++) {
1644 for (i = 0; i < _npts; i++) {
1645 fbar += _function[i][ifn];
1647 fbar = fbar / T(_npts);
1648 _timer.addToIteration();
1650 for (i = 0; i < _npts; i++) {
1651 batchbb(i, 0) = _function[i][ifn] - fbar;
1653 batchxx = ldlt.solve(batchbb);
1654 _timer.addToEigen();
1656 for (ndarray::Size ii = 0; ii < nQueries; ii++) {
1657 for (i = 0; i < _dimensions; i++) v1[i] = queries[ii][i];
1658 if (_useMaxMin == 1) {
1659 for (i = 0; i < _dimensions; i++) v1[i] = (v1[i] - _min[i]) / (_max[i] - _min[i]);
1662 for (i = 0; i < _npts; i++) {
1663 mu[ii][ifn] += batchxx(i) * (*_covariogram)(v1, _kdTree.getData(i));
1669 _timer.addToIteration();
1670 for (ndarray::Size ii = 0; ii < nQueries; ii++) {
1671 for (i = 0; i < _dimensions; i++) v1[i] = queries[ii][i];
1672 if (_useMaxMin == 1) {
1673 for (i = 0; i < _dimensions; i++) v1[i] = (v1[i] - _min[i]) / (_max[i] - _min[i]);
1676 for (i = 0; i < _npts; i++) {
1677 batchbb(i, 0) = (*_covariogram)(v1, _kdTree.getData(i));
1678 queryCovariance(i, 0) = batchbb(i, 0);
1680 batchxx = ldlt.solve(batchbb);
1682 variance[ii][0] = (*_covariogram)(v1, v1) + _lambda;
1684 for (i = 0; i < _npts; i++) {
1685 variance[ii][0] -= queryCovariance(i, 0) * batchxx(i);
1691 _timer.addToVariance();
1692 _timer.addToTotal(nQueries);
1695template <
typename T>
1697 ndarray::Array<T, 2, 2>
const &queries)
const {
1700 ndarray::Size nQueries = queries.template getSize<0>();
1702 if (_nFunctions != 1) {
1704 "Your output array does not have enough room for all of the functions "
1705 "you are trying to interpolate.\n");
1708 if (queries.template getSize<1>() !=
static_cast<ndarray::Size
>(_dimensions)) {
1710 "The points at which you are trying to interpolate your function are "
1711 "of the wrong dimensionality.\n");
1714 if (mu.getNumElements() != nQueries) {
1716 "Your output array does not have enough room for all of the points "
1717 "at which you are trying to interpolate your function.\n");
1721 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> batchCovariance, batchbb, batchxx;
1722 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> queryCovariance;
1723 Eigen::LDLT<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > ldlt;
1725 ndarray::Array<T, 1, 1> v1;
1729 v1 = allocate(ndarray::makeVector(_dimensions));
1731 batchbb.resize(_npts, 1);
1732 batchxx.resize(_npts, 1);
1733 batchCovariance.resize(_npts, _npts);
1734 queryCovariance.resize(_npts, 1);
1736 for (i = 0; i < _npts; i++) {
1737 batchCovariance(i, i) = (*_covariogram)(_kdTree.getData(i), _kdTree.getData(i)) + _lambda;
1738 for (j = i + 1; j < _npts; j++) {
1739 batchCovariance(i, j) = (*_covariogram)(_kdTree.getData(i), _kdTree.getData(j));
1740 batchCovariance(j, i) = batchCovariance(i, j);
1743 _timer.addToIteration();
1745 ldlt.compute(batchCovariance);
1748 for (i = 0; i < _npts; i++) {
1749 fbar += _function[i][0];
1751 fbar = fbar / T(_npts);
1753 for (i = 0; i < _npts; i++) {
1754 batchbb(i, 0) = _function[i][0] - fbar;
1756 batchxx = ldlt.solve(batchbb);
1757 _timer.addToEigen();
1759 for (ndarray::Size ii = 0; ii < nQueries; ii++) {
1760 for (i = 0; i < _dimensions; i++) v1[i] = queries[ii][i];
1761 if (_useMaxMin == 1) {
1762 for (i = 0; i < _dimensions; i++) v1[i] = (v1[i] - _min[i]) / (_max[i] - _min[i]);
1766 for (i = 0; i < _npts; i++) {
1767 mu(ii) += batchxx(i) * (*_covariogram)(v1, _kdTree.getData(i));
1770 _timer.addToIteration();
1771 _timer.addToTotal(nQueries);
1774template <
typename T>
1776 ndarray::Array<T, 2, 2>
const &queries)
const {
1779 ndarray::Size nQueries = queries.template getSize<0>();
1781 if (mu.template getSize<0>() != nQueries) {
1783 "Your output array does not have enough room for all of the points "
1784 "at which you want to interpolate your functions.\n");
1787 if (mu.template getSize<1>() !=
static_cast<ndarray::Size
>(_nFunctions)) {
1789 "Your output array does not have enough room for all of the functions "
1790 "you are trying to interpolate.\n");
1793 if (queries.template getSize<1>() !=
static_cast<ndarray::Size
>(_dimensions)) {
1795 "The points at which you are interpolating your functions do not "
1796 "have the correct dimensionality.\n");
1800 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> batchCovariance, batchbb, batchxx;
1801 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> queryCovariance;
1802 Eigen::LDLT<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > ldlt;
1804 ndarray::Array<T, 1, 1> v1;
1808 v1 = allocate(ndarray::makeVector(_dimensions));
1810 batchbb.resize(_npts, 1);
1811 batchxx.resize(_npts, 1);
1812 batchCovariance.resize(_npts, _npts);
1813 queryCovariance.resize(_npts, 1);
1815 for (i = 0; i < _npts; i++) {
1816 batchCovariance(i, i) = (*_covariogram)(_kdTree.getData(i), _kdTree.getData(i)) + _lambda;
1817 for (j = i + 1; j < _npts; j++) {
1818 batchCovariance(i, j) = (*_covariogram)(_kdTree.getData(i), _kdTree.getData(j));
1819 batchCovariance(j, i) = batchCovariance(i, j);
1823 _timer.addToIteration();
1825 ldlt.compute(batchCovariance);
1827 _timer.addToEigen();
1829 for (ifn = 0; ifn < _nFunctions; ifn++) {
1831 for (i = 0; i < _npts; i++) {
1832 fbar += _function[i][ifn];
1834 fbar = fbar / T(_npts);
1836 _timer.addToIteration();
1838 for (i = 0; i < _npts; i++) {
1839 batchbb(i, 0) = _function[i][ifn] - fbar;
1841 batchxx = ldlt.solve(batchbb);
1842 _timer.addToEigen();
1844 for (ndarray::Size ii = 0; ii < nQueries; ii++) {
1845 for (i = 0; i < _dimensions; i++) v1[i] = queries[ii][i];
1846 if (_useMaxMin == 1) {
1847 for (i = 0; i < _dimensions; i++) v1[i] = (v1[i] - _min[i]) / (_max[i] - _min[i]);
1851 for (i = 0; i < _npts; i++) {
1852 mu[ii][ifn] += batchxx(i) * (*_covariogram)(v1, _kdTree.getData(i));
1858 _timer.addToTotal(nQueries);
1861template <
typename T>
1865 if (_nFunctions != 1) {
1867 "You are calling the wrong addPoint; you need a vector of functions\n");
1870 if (vin.getNumElements() !=
static_cast<ndarray::Size
>(_dimensions)) {
1872 "You are trying to add a point of the wrong dimensionality to "
1873 "your GaussianProcess.\n");
1876 ndarray::Array<T, 1, 1> v;
1877 v = allocate(ndarray::makeVector(_dimensions));
1879 for (i = 0; i < _dimensions; i++) {
1881 if (_useMaxMin == 1) {
1882 v[i] = (v[i] - _min[i]) / (_max[i] - _min[i]);
1886 if (_npts == _room) {
1887 ndarray::Array<T, 2, 2> buff;
1888 buff = allocate(ndarray::makeVector(_npts, _nFunctions));
1889 buff.deep() = _function;
1892 _function = allocate(ndarray::makeVector(_room, _nFunctions));
1893 for (i = 0; i < _npts; i++) {
1894 for (j = 0; j < _nFunctions; j++) {
1895 _function[i][j] = buff[i][j];
1900 _function[_npts][0] = f;
1902 _kdTree.addPoint(v);
1903 _npts = _kdTree.getNPoints();
1906template <
typename T>
1908 if (vin.getNumElements() !=
static_cast<ndarray::Size
>(_dimensions)) {
1910 "You are trying to add a point of the wrong dimensionality to "
1911 "your GaussianProcess.\n");
1914 if (f.template getSize<0>() !=
static_cast<ndarray::Size
>(_nFunctions)) {
1916 "You are not adding the correct number of function values to "
1917 "your GaussianProcess.\n");
1922 ndarray::Array<T, 1, 1> v;
1923 v = allocate(ndarray::makeVector(_dimensions));
1925 for (i = 0; i < _dimensions; i++) {
1927 if (_useMaxMin == 1) {
1928 v[i] = (v[i] - _min[i]) / (_max[i] - _min[i]);
1932 if (_npts == _room) {
1933 ndarray::Array<T, 2, 2> buff;
1934 buff = allocate(ndarray::makeVector(_npts, _nFunctions));
1935 buff.deep() = _function;
1938 _function = allocate(ndarray::makeVector(_room, _nFunctions));
1939 for (i = 0; i < _npts; i++) {
1940 for (j = 0; j < _nFunctions; j++) {
1941 _function[i][j] = buff[i][j];
1945 for (i = 0; i < _nFunctions; i++) _function[_npts][i] = f[i];
1947 _kdTree.addPoint(v);
1948 _npts = _kdTree.getNPoints();
1951template <
typename T>
1955 _kdTree.removePoint(dex);
1957 for (i = dex; i < _npts; i++) {
1958 for (j = 0; j < _nFunctions; j++) {
1959 _function[i][j] = _function[i + 1][j];
1962 _npts = _kdTree.getNPoints();
1965template <
typename T>
1967 _krigingParameter = kk;
1970template <
typename T>
1972 _covariogram = covar;
1975template <
typename T>
1980template <
typename T>
1985template <
typename T>
1988template <
typename T>
1990 ndarray::Array<const T, 1, 1>
const &p2)
const {
1991 std::cout <<
"by the way, you are calling the wrong operator\n";
1996template <
typename T>
1999template <
typename T>
2004template <
typename T>
2006 _ellSquared = ellSquared;
2009template <
typename T>
2011 ndarray::Array<const T, 1, 1>
const &p2)
const {
2013 for (ndarray::Size i = 0; i < p1.template getSize<0>(); i++) {
2014 d += (p1[i] - p2[i]) * (p1[i] - p2[i]);
2017 d = d / _ellSquared;
2018 return T(
exp(-0.5 * d));
2021template <
typename T>
2024template <
typename T>
2030template <
typename T>
2032 ndarray::Array<const T, 1, 1>
const &p2)
const {
2034 double num, denom1, denom2, arg;
2036 dim = p1.template getSize<0>();
2038 num = 2.0 * _sigma0;
2039 denom1 = 1.0 + 2.0 * _sigma0;
2040 denom2 = 1.0 + 2.0 * _sigma0;
2042 for (i = 0; i < dim; i++) {
2043 num += 2.0 * p1[i] * p2[i] * _sigma1;
2044 denom1 += 2.0 * p1[i] * p1[i] * _sigma1;
2045 denom2 += 2.0 * p2[i] * p2[i] * _sigma1;
2048 arg = num /
::sqrt(denom1 * denom2);
2049 return T(2.0 * (
::asin(arg)) / 3.141592654);
2052template <
typename T>
2057template <
typename T>
2062#define INSTANTIATEGP(T) \
2063 template class KdTree<T>; \
2064 template class GaussianProcess<T>; \
2065 template class Covariogram<T>; \
2066 template class SquaredExpCovariogram<T>; \
2067 template class NeuralNetCovariogram<T>;
Key< Flag > const & target
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
table::Key< double > sigma1
The parent class of covariogram functions for use in Gaussian Process interpolation.
virtual T operator()(ndarray::Array< const T, 1, 1 > const &p1, ndarray::Array< const T, 1, 1 > const &p2) const
Actually evaluate the covariogram function relating two points you want to interpolate from.
GaussianProcessTimer & getTimes() const
Give the user acces to _timer, an object keeping track of the time spent on various processes within ...
void setLambda(T lambda)
set the value of the hyperparameter _lambda
int getDim() const
return the dimensionality of data points stored in the GaussianProcess
void setKrigingParameter(T kk)
Assign a value to the Kriging paramter.
void addPoint(ndarray::Array< T, 1, 1 > const &vin, T f)
Add a point to the pool of data used by GaussianProcess for interpolation.
void batchInterpolate(ndarray::Array< T, 1, 1 > mu, ndarray::Array< T, 1, 1 > variance, ndarray::Array< T, 2, 2 > const &queries) const
Interpolate a list of query points using all of the input data (rather than nearest neighbors)
GaussianProcess(const GaussianProcess &)=delete
T interpolate(ndarray::Array< T, 1, 1 > variance, ndarray::Array< T, 1, 1 > const &vin, int numberOfNeighbors) const
Interpolate the function value at one point using a specified number of nearest neighbors.
T selfInterpolate(ndarray::Array< T, 1, 1 > variance, int dex, int numberOfNeighbors) const
This method will interpolate the function on a data point for purposes of optimizing hyper parameters...
void removePoint(int dex)
This will remove a point from the data set.
void setCovariogram(std::shared_ptr< Covariogram< T > > const &covar)
Assign a different covariogram to this GaussianProcess.
void getData(ndarray::Array< T, 2, 2 > pts, ndarray::Array< T, 1, 1 > fn, ndarray::Array< int, 1, 1 > indices) const
Return a sub-sample the data underlying the Gaussian Process.
int getNPoints() const
return the number of data points stored in the GaussianProcess
This is a structure for keeping track of how long the interpolation methods spend on different parts ...
void addToSearch()
Adds time to _searchTime.
void addToVariance()
Adds time to _varianceTime.
void addToIteration()
Adds time to _iterationTime.
void start()
Starts the timer for an individual call to an interpolation routine.
void display()
Displays the current values of all times and _interpolationCount.
void reset()
Resets all of the data members of GaussianProcessTimer to zero.
void addToEigen()
Adds time to _eigenTime.
void addToTotal(int i)
Adds time to _totalTime and adds counts to _interpolationCount.
The data for GaussianProcess is stored in a KD tree to facilitate nearest-neighbor searches.
void removePoint(int dex)
Remove a point from the tree.
void findNeighbors(ndarray::Array< int, 1, 1 > neighdex, ndarray::Array< double, 1, 1 > dd, ndarray::Array< const T, 1, 1 > const &v, int n_nn) const
Find the nearest neighbors of a point.
void addPoint(ndarray::Array< const T, 1, 1 > const &v)
Add a point to the tree.
void Initialize(ndarray::Array< T, 2, 2 > const &dt)
Build a KD Tree to store the data for GaussianProcess.
void getTreeNode(ndarray::Array< int, 1, 1 > const &v, int dex) const
Return the _tree information for a given data point.
int getNPoints() const
return the number of data points stored in the tree
T getData(int ipt, int idim) const
Return one element of one node on the tree.
void setSigma0(double sigma0)
set the _sigma0 hyper parameter
~NeuralNetCovariogram() override
T operator()(ndarray::Array< const T, 1, 1 > const &, ndarray::Array< const T, 1, 1 > const &) const override
Actually evaluate the covariogram function relating two points you want to interpolate from.
void setSigma1(double sigma1)
set the _sigma1 hyper parameter
void setEllSquared(double ellSquared)
set the _ellSquared hyper parameter (the square of the characteristic length scale of the covariogram...
~SquaredExpCovariogram() override
T operator()(ndarray::Array< const T, 1, 1 > const &, ndarray::Array< const T, 1, 1 > const &) const override
Actually evaluate the covariogram function relating two points you want to interpolate from.
static DateTime now(void)
Return current time as a DateTime.
Reports errors that are due to events beyond the control of the program.