17 #include "boost/timer.hpp"
20 #include "Eigen/Cholesky"
23 #include "Eigen/Eigenvalues"
38 #include "ndarray/eigen.h"
40 #define DEBUG_MATRIX 0
41 #define DEBUG_MATRIX2 0
67 _fitForBackground(fitForBackground)
78 _fitForBackground(fitForBackground)
87 _fitForBackground(true)
100 switch (conditionType) {
103 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eVecValues(mMat);
104 Eigen::VectorXd eValues = eVecValues.eigenvalues();
105 double eMax = eValues.maxCoeff();
106 double eMin = eValues.minCoeff();
107 LOGL_DEBUG(
"TRACE3.ip.diffim.KernelSolution.getConditionNumber",
108 "EIGENVALUE eMax / eMin = %.3e", eMax / eMin);
109 return (eMax / eMin);
114 Eigen::VectorXd sValues = mMat.jacobiSvd().singularValues();
115 double sMax = sValues.maxCoeff();
116 double sMin = sValues.minCoeff();
117 LOGL_DEBUG(
"TRACE3.ip.diffim.KernelSolution.getConditionNumber",
118 "SVD eMax / eMin = %.3e", sMax / sMin);
119 return (sMax / sMin);
125 "Undefined ConditionNumberType : only EIGENVALUE, SVD allowed.");
132 Eigen::VectorXd
const& bVec) {
141 Eigen::VectorXd aVec = Eigen::VectorXd::Zero(bVec.size());
146 LOGL_DEBUG(
"TRACE2.ip.diffim.KernelSolution.solve",
147 "Solving for kernel");
149 Eigen::FullPivLU<Eigen::MatrixXd> lu(mMat);
150 if (lu.isInvertible()) {
151 aVec = lu.solve(bVec);
153 LOGL_DEBUG(
"TRACE3.ip.diffim.KernelSolution.solve",
154 "Unable to determine kernel via LU");
159 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eVecValues(mMat);
160 Eigen::MatrixXd
const& rMat = eVecValues.eigenvectors();
161 Eigen::VectorXd eValues = eVecValues.eigenvalues();
163 for (
int i = 0; i != eValues.rows(); ++i) {
164 if (eValues(i) != 0.0) {
165 eValues(i) = 1.0/eValues(i);
169 aVec = rMat * eValues.asDiagonal() * rMat.transpose() * bVec;
173 LOGL_DEBUG(
"TRACE3.ip.diffim.KernelSolution.solve",
174 "Unable to determine kernel via eigen-values");
180 double time = t.elapsed();
181 LOGL_DEBUG(
"TRACE3.ip.diffim.KernelSolution.solve",
182 "Compute time for matrix math : %.2f s", time);
194 template <
typename InputT>
197 bool fitForBackground
214 template <
typename InputT>
222 template <
typename InputT>
230 (void)_kernel->computeImage(*
image,
false);
234 template <
typename InputT>
242 template <
typename InputT>
250 template <
typename InputT>
260 template <
typename InputT>
270 "Error: variance less than 0.0");
274 "Error: variance equals 0.0, cannot inverse variance weight");
278 std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(_kernel)->getKernelList();
280 unsigned int const nKernelParameters = basisList.
size();
281 unsigned int const nBackgroundParameters = _fitForBackground ? 1 : 0;
282 unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
319 unsigned int const startCol = goodBBox.
getMinX();
320 unsigned int const startRow = goodBBox.
getMinY();
322 unsigned int endCol = goodBBox.
getMaxX() + 1;
323 unsigned int endRow = goodBBox.
getMaxY() + 1;
338 startRow, startCol, endRow-startRow, endCol-startCol
339 ).array().inverse().matrix();
342 eigenTemplate.resize(eigenTemplate.rows()*eigenTemplate.cols(), 1);
343 eigenScience.resize(eigenScience.rows()*eigenScience.cols(), 1);
344 eigeniVariance.resize(eigeniVariance.rows()*eigeniVariance.cols(), 1);
357 for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
364 cMat.resize(cMat.size(), 1);
369 double time = t.elapsed();
370 LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.build",
371 "Total compute time to do basis convolutions : %.2f s", time);
378 Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
381 for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
382 cMat.col(kidxj) = eiterj->col(0);
385 if (_fitForBackground)
386 cMat.col(nParameters-1).fill(1.);
389 _ivVec = eigeniVariance.col(0);
390 _iVec = eigenScience.col(0);
393 _mMat = _cMat.transpose() * (_ivVec.asDiagonal() * _cMat);
394 _bVec = _cMat.transpose() * (_ivVec.asDiagonal() * _iVec);
397 template <
typename InputT>
399 LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.solve",
400 "mMat is %d x %d; bVec is %d; cMat is %d x %d; vVec is %d; iVec is %d",
401 _mMat.rows(), _mMat.cols(), _bVec.size(),
402 _cMat.rows(), _cMat.cols(), _ivVec.size(), _iVec.size());
423 template <
typename InputT>
429 unsigned int const nParameters = _aVec.size();
430 unsigned int const nBackgroundParameters = _fitForBackground ? 1 : 0;
431 unsigned int const nKernelParameters =
432 std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(_kernel)->getKernelList().size();
433 if (nParameters != (nKernelParameters + nBackgroundParameters))
438 for (
unsigned int idx = 0; idx < nKernelParameters; idx++) {
441 str(
boost::format(
"Unable to determine kernel solution %d (nan)") % idx));
443 kValues[idx] = _aVec(idx);
445 _kernel->setKernelParameters(kValues);
448 new ImageT(_kernel->getDimensions())
450 _kSum = _kernel->computeImage(*
image,
false);
452 if (_fitForBackground) {
455 str(
boost::format(
"Unable to determine background solution %d (nan)") %
458 _background = _aVec(nParameters-1);
463 template <
typename InputT>
493 template <
typename InputT>
496 bool fitForBackground
501 template <
typename InputT>
512 "Error: variance less than 0.0");
516 "Error: variance equals 0.0, cannot inverse variance weight");
524 std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(this->_kernel)->getKernelList();
539 int growPix = (*kiter)->getCtr().getX();
543 for (
typename afwDet::FootprintSet::FootprintList::iterator
549 afwDet::setMaskFromFootprint(finalMask,
556 for (
auto const & foot : *(maskedFpSetGrown.
getFootprints())) {
563 ndarray::Array<int, 1, 1> maskArray =
564 ndarray::allocate(ndarray::makeVector(fullFp->
getArea()));
566 auto maskEigen = ndarray::asEigenMatrix(maskArray);
568 ndarray::Array<InputT, 1, 1> arrayTemplate =
569 ndarray::allocate(ndarray::makeVector(fullFp->
getArea()));
571 auto eigenTemplate0 = ndarray::asEigenMatrix(arrayTemplate);
573 ndarray::Array<InputT, 1, 1> arrayScience =
574 ndarray::allocate(ndarray::makeVector(fullFp->
getArea()));
576 auto eigenScience0 = ndarray::asEigenMatrix(arrayScience);
578 ndarray::Array<afwImage::VariancePixel, 1, 1> arrayVariance =
579 ndarray::allocate(ndarray::makeVector(fullFp->
getArea()));
581 auto eigenVariance0 = ndarray::asEigenMatrix(arrayVariance);
584 for (
int i = 0; i < maskEigen.size(); i++) {
585 if (maskEigen(i) == 0.0)
589 Eigen::VectorXd eigenTemplate(nGood);
590 Eigen::VectorXd eigenScience(nGood);
591 Eigen::VectorXd eigenVariance(nGood);
593 for (
int i = 0; i < maskEigen.size(); i++) {
594 if (maskEigen(i) == 0.0) {
595 eigenTemplate(nUsed) = eigenTemplate0(i);
596 eigenScience(nUsed) = eigenScience0(i);
597 eigenVariance(nUsed) = eigenVariance0(i);
606 unsigned int const nKernelParameters = basisList.
size();
607 unsigned int const nBackgroundParameters = this->_fitForBackground ? 1 : 0;
608 unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
622 for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
625 ndarray::Array<InputT, 1, 1> arrayC =
626 ndarray::allocate(ndarray::makeVector(fullFp->
getArea()));
628 auto eigenC0 = ndarray::asEigenMatrix(arrayC);
630 Eigen::VectorXd eigenC(nGood);
632 for (
int i = 0; i < maskEigen.size(); i++) {
633 if (maskEigen(i) == 0.0) {
634 eigenC(nUsed) = eigenC0(i);
641 double time = t.elapsed();
642 LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.buildWithMask",
643 "Total compute time to do basis convolutions : %.2f s", time);
647 Eigen::MatrixXd cMat(eigenTemplate.size(), nParameters);
650 for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
651 cMat.block(0, kidxj, eigenTemplate.size(), 1) =
652 Eigen::MatrixXd(*eiterj).block(0, 0, eigenTemplate.size(), 1);
655 if (this->_fitForBackground)
656 cMat.col(nParameters-1).fill(1.);
659 this->_ivVec = eigenVariance.array().inverse().matrix();
660 this->_iVec = eigenScience;
663 this->_mMat = this->_cMat.transpose() * this->_ivVec.asDiagonal() * (this->_cMat);
664 this->_bVec = this->_cMat.transpose() * this->_ivVec.asDiagonal() * (this->_iVec);
668 template <
typename InputT>
679 "Error: variance less than 0.0");
683 "Error: variance equals 0.0, cannot inverse variance weight");
687 std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(this->_kernel)->getKernelList();
699 unsigned int const nKernelParameters = basisList.
size();
700 unsigned int const nBackgroundParameters = this->_fitForBackground ? 1 : 0;
701 unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
709 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
710 "Limits of good pixels after convolution: %d,%d -> %d,%d (local)",
715 unsigned int startCol = shrunkLocalBBox.
getMinX();
716 unsigned int startRow = shrunkLocalBBox.
getMinY();
717 unsigned int endCol = shrunkLocalBBox.
getMaxX();
718 unsigned int endRow = shrunkLocalBBox.
getMaxY();
741 startRow, startCol, endRow-startRow, endCol-startCol
742 ).array().inverse().matrix();
745 eMask.resize(eMask.rows()*eMask.cols(), 1);
746 eigenTemplate.resize(eigenTemplate.rows()*eigenTemplate.cols(), 1);
747 eigenScience.resize(eigenScience.rows()*eigenScience.cols(), 1);
748 eigeniVariance.resize(eigeniVariance.rows()*eigeniVariance.cols(), 1);
751 Eigen::MatrixXd maskedEigenTemplate(eigenTemplate.rows(), 1);
752 Eigen::MatrixXd maskedEigenScience(eigenScience.rows(), 1);
753 Eigen::MatrixXd maskedEigeniVariance(eigeniVariance.rows(), 1);
755 for (
int i = 0; i < eMask.rows(); i++) {
756 if (eMask(i, 0) == 0) {
757 maskedEigenTemplate(nGood, 0) = eigenTemplate(i, 0);
758 maskedEigenScience(nGood, 0) = eigenScience(i, 0);
759 maskedEigeniVariance(nGood, 0) = eigeniVariance(i, 0);
764 eigenTemplate = maskedEigenTemplate.block(0, 0, nGood, 1);
765 eigenScience = maskedEigenScience.block(0, 0, nGood, 1);
766 eigeniVariance = maskedEigeniVariance.block(0, 0, nGood, 1);
780 for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
787 cMat.resize(cMat.size(), 1);
790 Eigen::MatrixXd maskedcMat(cMat.rows(), 1);
792 for (
int i = 0; i < eMask.rows(); i++) {
793 if (eMask(i, 0) == 0) {
794 maskedcMat(nGood, 0) = cMat(i, 0);
798 cMat = maskedcMat.block(0, 0, nGood, 1);
802 double time = t.elapsed();
803 LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.build",
804 "Total compute time to do basis convolutions : %.2f s", time);
811 Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
814 for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
815 cMat.col(kidxj) = eiterj->col(0);
818 if (this->_fitForBackground)
819 cMat.col(nParameters-1).fill(1.);
822 this->_ivVec = eigeniVariance.col(0);
823 this->_iVec = eigenScience.col(0);
826 this->_mMat = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_cMat;
827 this->_bVec = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_iVec;
833 template <
typename InputT>
844 "Error: variance less than 0.0");
848 "Error: variance equals 0.0, cannot inverse variance weight");
852 std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(this->_kernel)->getKernelList();
854 unsigned int const nKernelParameters = basisList.
size();
855 unsigned int const nBackgroundParameters = this->_fitForBackground ? 1 : 0;
856 unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
886 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
887 "Limits of good pixels after convolution: %d,%d -> %d,%d",
891 unsigned int const startCol = shrunkBBox.
getMinX();
892 unsigned int const startRow = shrunkBBox.
getMinY();
893 unsigned int const endCol = shrunkBBox.
getMaxX();
894 unsigned int const endRow = shrunkBBox.
getMaxY();
913 int maskStartCol = maskBox.
getMinX();
914 int maskStartRow = maskBox.
getMinY();
915 int maskEndCol = maskBox.
getMaxX();
916 int maskEndRow = maskBox.
getMaxY();
949 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
950 "Upper good pixel region: %d,%d -> %d,%d",
952 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
953 "Bottom good pixel region: %d,%d -> %d,%d",
955 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
956 "Left good pixel region: %d,%d -> %d,%d",
958 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
959 "Right good pixel region: %d,%d -> %d,%d",
973 Eigen::MatrixXd eigenTemplate(totalSize, 1);
974 Eigen::MatrixXd eigenScience(totalSize, 1);
975 Eigen::MatrixXd eigeniVariance(totalSize, 1);
976 eigenTemplate.setZero();
977 eigenScience.setZero();
978 eigeniVariance.setZero();
985 for (; biter != boxArray.
end(); ++biter) {
986 int area = (*biter).
getWidth() * (*biter).getHeight();
994 Eigen::MatrixXd eiVarEstimate =
imageToEigenMatrix(sVarEstimate).array().inverse().matrix();
996 eTemplate.resize(area, 1);
997 eScience.resize(area, 1);
998 eiVarEstimate.resize(area, 1);
1000 eigenTemplate.block(nTerms, 0, area, 1) = eTemplate.block(0, 0, area, 1);
1001 eigenScience.block(nTerms, 0, area, 1) = eScience.block(0, 0, area, 1);
1002 eigeniVariance.block(nTerms, 0, area, 1) = eiVarEstimate.block(0, 0, area, 1);
1014 for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
1016 Eigen::MatrixXd cMat(totalSize, 1);
1021 for (; biter != boxArray.
end(); ++biter) {
1022 int area = (*biter).
getWidth() * (*biter).getHeight();
1026 esubimage.resize(area, 1);
1027 cMat.block(nTerms, 0, area, 1) = esubimage.block(0, 0, area, 1);
1036 double time = t.elapsed();
1037 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
1038 "Total compute time to do basis convolutions : %.2f s", time);
1045 Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
1048 for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
1049 cMat.col(kidxj) = eiterj->col(0);
1052 if (this->_fitForBackground)
1053 cMat.col(nParameters-1).fill(1.);
1056 this->_ivVec = eigeniVariance.col(0);
1057 this->_iVec = eigenScience.col(0);
1060 this->_mMat = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_cMat;
1061 this->_bVec = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_iVec;
1066 template <
typename InputT>
1069 bool fitForBackground,
1070 Eigen::MatrixXd
const& hMat,
1079 template <
typename InputT>
1081 Eigen::MatrixXd vMat = this->_cMat.jacobiSvd().matrixV();
1082 Eigen::MatrixXd vMatvMatT = vMat * vMat.transpose();
1085 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eVecValues(this->_mMat);
1086 Eigen::MatrixXd
const& rMat = eVecValues.eigenvectors();
1087 Eigen::VectorXd eValues = eVecValues.eigenvalues();
1088 double eMax = eValues.maxCoeff();
1089 for (
int i = 0; i != eValues.rows(); ++i) {
1090 if (eValues(i) == 0.0) {
1093 else if ((eMax / eValues(i)) > maxCond) {
1094 LOGL_DEBUG(
"TRACE3.ip.diffim.RegularizedKernelSolution.estimateRisk",
1095 "Truncating eValue %d; %.5e / %.5e = %.5e vs. %.5e",
1096 i, eMax, eValues(i), eMax / eValues(i), maxCond);
1100 eValues(i) = 1.0 / eValues(i);
1103 Eigen::MatrixXd mInv = rMat * eValues.asDiagonal() * rMat.transpose();
1107 for (
unsigned int i = 0; i < lambdas.
size(); i++) {
1108 double l = lambdas[i];
1109 Eigen::MatrixXd mLambda = this->_mMat + l * _hMat;
1117 Eigen::VectorXd term1 = (this->_aVec.transpose() * vMatvMatT * this->_aVec);
1118 if (term1.size() != 1)
1121 double term2a = (vMatvMatT * mLambda.inverse()).
trace();
1123 Eigen::VectorXd term2b = (this->_aVec.transpose() * (mInv * this->_bVec));
1124 if (term2b.size() != 1)
1127 double risk = term1(0) + 2 * (term2a - term2b(0));
1128 LOGL_DEBUG(
"TRACE4.ip.diffim.RegularizedKernelSolution.estimateRisk",
1129 "Lambda = %.3f, Risk = %.5e",
1131 LOGL_DEBUG(
"TRACE5.ip.diffim.RegularizedKernelSolution.estimateRisk",
1132 "%.5e + 2 * (%.5e - %.5e)",
1133 term1(0), term2a, term2b(0));
1138 LOGL_DEBUG(
"TRACE3.ip.diffim.RegularizedKernelSolution.estimateRisk",
1139 "Minimum Risk = %.3e at lambda = %.3e", risks[index], lambdas[index]);
1141 return lambdas[index];
1145 template <
typename InputT>
1147 if (includeHmat ==
true) {
1148 return this->_mMat + _lambda * _hMat;
1155 template <
typename InputT>
1158 LOGL_DEBUG(
"TRACE3.ip.diffim.RegularizedKernelSolution.solve",
1159 "cMat is %d x %d; vVec is %d; iVec is %d; hMat is %d x %d",
1160 this->_cMat.rows(), this->_cMat.cols(), this->_ivVec.size(),
1161 this->_iVec.size(), _hMat.rows(), _hMat.cols());
1176 this->_mMat = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_cMat;
1177 this->_bVec = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_iVec;
1229 std::string lambdaType = _ps->getAsString(
"lambdaType");
1230 if (lambdaType ==
"absolute") {
1231 _lambda = _ps->getAsDouble(
"lambdaValue");
1233 else if (lambdaType ==
"relative") {
1234 _lambda = this->_mMat.trace() / this->_hMat.trace();
1235 _lambda *= _ps->getAsDouble(
"lambdaScaling");
1237 else if (lambdaType ==
"minimizeBiasedRisk") {
1238 double tol = _ps->getAsDouble(
"maxConditionNumber");
1239 _lambda = estimateRisk(tol);
1241 else if (lambdaType ==
"minimizeUnbiasedRisk") {
1248 LOGL_DEBUG(
"TRACE3.ip.diffim.RegularizedKernelSolution.solve",
1249 "Applying kernel regularization with lambda = %.2e", _lambda);
1262 template <
typename InputT>
1266 std::string lambdaStepType = _ps->getAsString(
"lambdaStepType");
1267 if (lambdaStepType ==
"linear") {
1268 double lambdaLinMin = _ps->getAsDouble(
"lambdaLinMin");
1269 double lambdaLinMax = _ps->getAsDouble(
"lambdaLinMax");
1270 double lambdaLinStep = _ps->getAsDouble(
"lambdaLinStep");
1271 for (
double l = lambdaLinMin; l <= lambdaLinMax; l += lambdaLinStep) {
1275 else if (lambdaStepType ==
"log") {
1276 double lambdaLogMin = _ps->getAsDouble(
"lambdaLogMin");
1277 double lambdaLogMax = _ps->getAsDouble(
"lambdaLogMax");
1278 double lambdaLogStep = _ps->getAsDouble(
"lambdaLogStep");
1279 for (
double l = lambdaLogMin; l <= lambdaLogMax; l += lambdaLogStep) {
1298 _spatialKernelFunction(spatialKernelFunction),
1299 _constantFirstTerm(false),
1309 bool isAlardLupton = _ps->getAsString(
"kernelBasisSet") ==
"alard-lupton";
1310 bool usePca = _ps->getAsBool(
"usePcaForSpatialKernel");
1311 if (isAlardLupton || usePca) {
1312 _constantFirstTerm =
true;
1316 _nbases = basisList.
size();
1320 if (_constantFirstTerm) {
1321 _nt = (_nbases - 1) * _nkt + 1 + _nbt;
1323 _nt = _nbases * _nkt + _nbt;
1326 Eigen::MatrixXd mMat(_nt, _nt);
1327 Eigen::VectorXd bVec(_nt);
1338 LOGL_DEBUG(
"TRACE3.ip.diffim.SpatialKernelSolution",
1339 "Initializing with size %d %d %d and constant first term = %s",
1341 _constantFirstTerm ?
"true" :
"false");
1346 Eigen::MatrixXd
const& qMat,
1347 Eigen::VectorXd
const& wVec) {
1349 LOGL_DEBUG(
"TRACE5.ip.diffim.SpatialKernelSolution.addConstraint",
1350 "Adding candidate at %f, %f", xCenter, yCenter);
1354 Eigen::VectorXd pK(_nkt);
1356 for (
int idx = 0; idx < _nkt; idx++) { paramsK[idx] = 0.0; }
1357 for (
int idx = 0; idx < _nkt; idx++) {
1360 pK(idx) = (*_spatialKernelFunction)(xCenter, yCenter);
1363 Eigen::MatrixXd pKpKt = (pK * pK.transpose());
1366 Eigen::MatrixXd pBpBt;
1367 Eigen::MatrixXd pKpBt;
1369 pB = Eigen::VectorXd(_nbt);
1373 for (
int idx = 0; idx < _nbt; idx++) { paramsB[idx] = 0.0; }
1374 for (
int idx = 0; idx < _nbt; idx++) {
1377 pB(idx) = (*_background)(xCenter, yCenter);
1380 pBpBt = (pB * pB.transpose());
1383 pKpBt = (pK * pB.transpose());
1406 int mb = _nt - _nbt;
1408 if (_constantFirstTerm) {
1412 _mMat(0, 0) += qMat(0,0);
1413 for(
int m2 = 1; m2 < _nbases; m2++) {
1414 _mMat.block(0, m2*_nkt-dm, 1, _nkt) += qMat(0,m2) * pK.transpose();
1416 _bVec(0) += wVec(0);
1419 _mMat.block(0, mb, 1, _nbt) += qMat(0,_nbases) * pB.transpose();
1424 for(
int m1 = m0; m1 < _nbases; m1++) {
1426 _mMat.block(m1*_nkt-dm, m1*_nkt-dm, _nkt, _nkt) +=
1427 (pKpKt * qMat(m1,m1)).triangularView<Eigen::Upper>();
1430 for(
int m2 = m1+1; m2 < _nbases; m2++) {
1431 _mMat.block(m1*_nkt-dm, m2*_nkt-dm, _nkt, _nkt) += qMat(m1,m2) * pKpKt;
1436 _mMat.block(m1*_nkt-dm, mb, _nkt, _nbt) += qMat(m1,_nbases) * pKpBt;
1440 _bVec.segment(m1*_nkt-dm, _nkt) += wVec(m1) * pK;
1445 _mMat.block(mb, mb, _nbt, _nbt) +=
1446 (pBpBt * qMat(_nbases,_nbases)).triangularView<Eigen::Upper>();
1447 _bVec.segment(mb, _nbt) += wVec(_nbases) * pB;
1471 for (
int i = 0; i < _nt; i++) {
1472 for (
int j = i+1; j < _nt; j++) {
1496 void SpatialKernelSolution::_setKernel() {
1505 for (
int i = 0; i < _nbases; i++) {
1510 "I. Unable to determine spatial kernel solution %d (nan). Condition number = %.3e") % i % cNumber));
1512 kCoeffs[i] =
_aVec(i);
1515 std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(_kernel)->getKernelList();
1525 for (
int i = 0, idx = 0; i < _nbases; i++) {
1529 if ((i == 0) && (_constantFirstTerm)) {
1534 "II. Unable to determine spatial kernel solution %d (nan). Condition number = %.3e") % idx % cNumber));
1536 kCoeffs[i][0] =
_aVec(idx++);
1539 for (
int j = 0; j < _nkt; j++) {
1544 "III. Unable to determine spatial kernel solution %d (nan). Condition number = %.3e") % idx % cNumber));
1546 kCoeffs[i][j] =
_aVec(idx++);
1560 for (
int i = 0; i < _nbt; i++) {
1561 int idx = _nt - _nbt + i;
1565 "Unable to determine spatial background solution %d (nan)") % (idx)));
1567 bgCoeffs[i] =
_aVec(idx);