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);
355 for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
362 cMat.resize(cMat.size(), 1);
367 double time = t.elapsed();
368 LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.build",
369 "Total compute time to do basis convolutions : %.2f s", time);
376 Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
379 for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
380 cMat.col(kidxj) = eiterj->col(0);
383 if (_fitForBackground)
384 cMat.col(nParameters-1).fill(1.);
387 _ivVec = eigeniVariance.col(0);
388 _iVec = eigenScience.col(0);
391 _mMat = _cMat.transpose() * (_ivVec.asDiagonal() * _cMat);
392 _bVec = _cMat.transpose() * (_ivVec.asDiagonal() * _iVec);
395 template <
typename InputT>
397 LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.solve",
398 "mMat is %d x %d; bVec is %d; cMat is %d x %d; vVec is %d; iVec is %d",
399 _mMat.rows(), _mMat.cols(), _bVec.size(),
400 _cMat.rows(), _cMat.cols(), _ivVec.size(), _iVec.size());
421 template <
typename InputT>
427 unsigned int const nParameters = _aVec.size();
428 unsigned int const nBackgroundParameters = _fitForBackground ? 1 : 0;
429 unsigned int const nKernelParameters =
430 std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(_kernel)->getKernelList().size();
431 if (nParameters != (nKernelParameters + nBackgroundParameters))
436 for (
unsigned int idx = 0; idx < nKernelParameters; idx++) {
439 str(
boost::format(
"Unable to determine kernel solution %d (nan)") % idx));
441 kValues[idx] = _aVec(idx);
443 _kernel->setKernelParameters(kValues);
446 new ImageT(_kernel->getDimensions())
448 _kSum = _kernel->computeImage(*
image,
false);
450 if (_fitForBackground) {
453 str(
boost::format(
"Unable to determine background solution %d (nan)") %
456 _background = _aVec(nParameters-1);
461 template <
typename InputT>
491 template <
typename InputT>
494 bool fitForBackground
499 template <
typename InputT>
510 "Error: variance less than 0.0");
514 "Error: variance equals 0.0, cannot inverse variance weight");
522 std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(this->_kernel)->getKernelList();
537 int growPix = (*kiter)->getCtr().getX();
541 for (
typename afwDet::FootprintSet::FootprintList::iterator
547 afwDet::setMaskFromFootprint(finalMask,
554 for (
auto const & foot : *(maskedFpSetGrown.
getFootprints())) {
561 ndarray::Array<int, 1, 1> maskArray =
562 ndarray::allocate(ndarray::makeVector(fullFp->
getArea()));
564 auto maskEigen = ndarray::asEigenMatrix(maskArray);
566 ndarray::Array<InputT, 1, 1> arrayTemplate =
567 ndarray::allocate(ndarray::makeVector(fullFp->
getArea()));
569 auto eigenTemplate0 = ndarray::asEigenMatrix(arrayTemplate);
571 ndarray::Array<InputT, 1, 1> arrayScience =
572 ndarray::allocate(ndarray::makeVector(fullFp->
getArea()));
574 auto eigenScience0 = ndarray::asEigenMatrix(arrayScience);
576 ndarray::Array<afwImage::VariancePixel, 1, 1> arrayVariance =
577 ndarray::allocate(ndarray::makeVector(fullFp->
getArea()));
579 auto eigenVariance0 = ndarray::asEigenMatrix(arrayVariance);
582 for (
int i = 0; i < maskEigen.size(); i++) {
583 if (maskEigen(i) == 0.0)
587 Eigen::VectorXd eigenTemplate(nGood);
588 Eigen::VectorXd eigenScience(nGood);
589 Eigen::VectorXd eigenVariance(nGood);
591 for (
int i = 0; i < maskEigen.size(); i++) {
592 if (maskEigen(i) == 0.0) {
593 eigenTemplate(nUsed) = eigenTemplate0(i);
594 eigenScience(nUsed) = eigenScience0(i);
595 eigenVariance(nUsed) = eigenVariance0(i);
604 unsigned int const nKernelParameters = basisList.
size();
605 unsigned int const nBackgroundParameters = this->_fitForBackground ? 1 : 0;
606 unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
618 for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
621 ndarray::Array<InputT, 1, 1> arrayC =
622 ndarray::allocate(ndarray::makeVector(fullFp->
getArea()));
624 auto eigenC0 = ndarray::asEigenMatrix(arrayC);
626 Eigen::VectorXd eigenC(nGood);
628 for (
int i = 0; i < maskEigen.size(); i++) {
629 if (maskEigen(i) == 0.0) {
630 eigenC(nUsed) = eigenC0(i);
637 double time = t.elapsed();
638 LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.buildWithMask",
639 "Total compute time to do basis convolutions : %.2f s", time);
643 Eigen::MatrixXd cMat(eigenTemplate.size(), nParameters);
646 for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
647 cMat.block(0, kidxj, eigenTemplate.size(), 1) =
648 Eigen::MatrixXd(*eiterj).block(0, 0, eigenTemplate.size(), 1);
651 if (this->_fitForBackground)
652 cMat.col(nParameters-1).fill(1.);
655 this->_ivVec = eigenVariance.array().inverse().matrix();
656 this->_iVec = eigenScience;
659 this->_mMat = this->_cMat.transpose() * this->_ivVec.asDiagonal() * (this->_cMat);
660 this->_bVec = this->_cMat.transpose() * this->_ivVec.asDiagonal() * (this->_iVec);
664 template <
typename InputT>
675 "Error: variance less than 0.0");
679 "Error: variance equals 0.0, cannot inverse variance weight");
683 std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(this->_kernel)->getKernelList();
695 unsigned int const nKernelParameters = basisList.
size();
696 unsigned int const nBackgroundParameters = this->_fitForBackground ? 1 : 0;
697 unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
705 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
706 "Limits of good pixels after convolution: %d,%d -> %d,%d (local)",
711 unsigned int startCol = shrunkLocalBBox.
getMinX();
712 unsigned int startRow = shrunkLocalBBox.
getMinY();
713 unsigned int endCol = shrunkLocalBBox.
getMaxX();
714 unsigned int endRow = shrunkLocalBBox.
getMaxY();
737 startRow, startCol, endRow-startRow, endCol-startCol
738 ).array().inverse().matrix();
741 eMask.resize(eMask.rows()*eMask.cols(), 1);
742 eigenTemplate.resize(eigenTemplate.rows()*eigenTemplate.cols(), 1);
743 eigenScience.resize(eigenScience.rows()*eigenScience.cols(), 1);
744 eigeniVariance.resize(eigeniVariance.rows()*eigeniVariance.cols(), 1);
747 Eigen::MatrixXd maskedEigenTemplate(eigenTemplate.rows(), 1);
748 Eigen::MatrixXd maskedEigenScience(eigenScience.rows(), 1);
749 Eigen::MatrixXd maskedEigeniVariance(eigeniVariance.rows(), 1);
751 for (
int i = 0; i < eMask.rows(); i++) {
752 if (eMask(i, 0) == 0) {
753 maskedEigenTemplate(nGood, 0) = eigenTemplate(i, 0);
754 maskedEigenScience(nGood, 0) = eigenScience(i, 0);
755 maskedEigeniVariance(nGood, 0) = eigeniVariance(i, 0);
760 eigenTemplate = maskedEigenTemplate.block(0, 0, nGood, 1);
761 eigenScience = maskedEigenScience.block(0, 0, nGood, 1);
762 eigeniVariance = maskedEigeniVariance.block(0, 0, nGood, 1);
774 for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
781 cMat.resize(cMat.size(), 1);
784 Eigen::MatrixXd maskedcMat(cMat.rows(), 1);
786 for (
int i = 0; i < eMask.rows(); i++) {
787 if (eMask(i, 0) == 0) {
788 maskedcMat(nGood, 0) = cMat(i, 0);
792 cMat = maskedcMat.block(0, 0, nGood, 1);
796 double time = t.elapsed();
797 LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.build",
798 "Total compute time to do basis convolutions : %.2f s", time);
805 Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
808 for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
809 cMat.col(kidxj) = eiterj->col(0);
812 if (this->_fitForBackground)
813 cMat.col(nParameters-1).fill(1.);
816 this->_ivVec = eigeniVariance.col(0);
817 this->_iVec = eigenScience.col(0);
820 this->_mMat = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_cMat;
821 this->_bVec = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_iVec;
827 template <
typename InputT>
838 "Error: variance less than 0.0");
842 "Error: variance equals 0.0, cannot inverse variance weight");
846 std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(this->_kernel)->getKernelList();
848 unsigned int const nKernelParameters = basisList.
size();
849 unsigned int const nBackgroundParameters = this->_fitForBackground ? 1 : 0;
850 unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
880 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
881 "Limits of good pixels after convolution: %d,%d -> %d,%d",
885 unsigned int const startCol = shrunkBBox.
getMinX();
886 unsigned int const startRow = shrunkBBox.
getMinY();
887 unsigned int const endCol = shrunkBBox.
getMaxX();
888 unsigned int const endRow = shrunkBBox.
getMaxY();
907 int maskStartCol = maskBox.
getMinX();
908 int maskStartRow = maskBox.
getMinY();
909 int maskEndCol = maskBox.
getMaxX();
910 int maskEndRow = maskBox.
getMaxY();
943 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
944 "Upper good pixel region: %d,%d -> %d,%d",
946 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
947 "Bottom good pixel region: %d,%d -> %d,%d",
949 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
950 "Left good pixel region: %d,%d -> %d,%d",
952 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
953 "Right good pixel region: %d,%d -> %d,%d",
967 Eigen::MatrixXd eigenTemplate(totalSize, 1);
968 Eigen::MatrixXd eigenScience(totalSize, 1);
969 Eigen::MatrixXd eigeniVariance(totalSize, 1);
970 eigenTemplate.setZero();
971 eigenScience.setZero();
972 eigeniVariance.setZero();
979 for (; biter != boxArray.
end(); ++biter) {
980 int area = (*biter).
getWidth() * (*biter).getHeight();
988 Eigen::MatrixXd eiVarEstimate =
imageToEigenMatrix(sVarEstimate).array().inverse().matrix();
990 eTemplate.resize(area, 1);
991 eScience.resize(area, 1);
992 eiVarEstimate.resize(area, 1);
994 eigenTemplate.block(nTerms, 0, area, 1) = eTemplate.block(0, 0, area, 1);
995 eigenScience.block(nTerms, 0, area, 1) = eScience.block(0, 0, area, 1);
996 eigeniVariance.block(nTerms, 0, area, 1) = eiVarEstimate.block(0, 0, area, 1);
1006 for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
1008 Eigen::MatrixXd cMat(totalSize, 1);
1013 for (; biter != boxArray.
end(); ++biter) {
1014 int area = (*biter).
getWidth() * (*biter).getHeight();
1018 esubimage.resize(area, 1);
1019 cMat.block(nTerms, 0, area, 1) = esubimage.block(0, 0, area, 1);
1028 double time = t.elapsed();
1029 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
1030 "Total compute time to do basis convolutions : %.2f s", time);
1037 Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
1040 for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
1041 cMat.col(kidxj) = eiterj->col(0);
1044 if (this->_fitForBackground)
1045 cMat.col(nParameters-1).fill(1.);
1048 this->_ivVec = eigeniVariance.col(0);
1049 this->_iVec = eigenScience.col(0);
1052 this->_mMat = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_cMat;
1053 this->_bVec = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_iVec;
1058 template <
typename InputT>
1061 bool fitForBackground,
1062 Eigen::MatrixXd
const& hMat,
1071 template <
typename InputT>
1073 Eigen::MatrixXd vMat = this->_cMat.jacobiSvd().matrixV();
1074 Eigen::MatrixXd vMatvMatT = vMat * vMat.transpose();
1077 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eVecValues(this->_mMat);
1078 Eigen::MatrixXd
const& rMat = eVecValues.eigenvectors();
1079 Eigen::VectorXd eValues = eVecValues.eigenvalues();
1080 double eMax = eValues.maxCoeff();
1081 for (
int i = 0; i != eValues.rows(); ++i) {
1082 if (eValues(i) == 0.0) {
1085 else if ((eMax / eValues(i)) > maxCond) {
1086 LOGL_DEBUG(
"TRACE3.ip.diffim.RegularizedKernelSolution.estimateRisk",
1087 "Truncating eValue %d; %.5e / %.5e = %.5e vs. %.5e",
1088 i, eMax, eValues(i), eMax / eValues(i), maxCond);
1092 eValues(i) = 1.0 / eValues(i);
1095 Eigen::MatrixXd mInv = rMat * eValues.asDiagonal() * rMat.transpose();
1099 for (
unsigned int i = 0; i < lambdas.
size(); i++) {
1100 double l = lambdas[i];
1101 Eigen::MatrixXd mLambda = this->_mMat + l * _hMat;
1109 Eigen::VectorXd term1 = (this->_aVec.transpose() * vMatvMatT * this->_aVec);
1110 if (term1.size() != 1)
1113 double term2a = (vMatvMatT * mLambda.inverse()).
trace();
1115 Eigen::VectorXd term2b = (this->_aVec.transpose() * (mInv * this->_bVec));
1116 if (term2b.size() != 1)
1119 double risk = term1(0) + 2 * (term2a - term2b(0));
1120 LOGL_DEBUG(
"TRACE4.ip.diffim.RegularizedKernelSolution.estimateRisk",
1121 "Lambda = %.3f, Risk = %.5e",
1123 LOGL_DEBUG(
"TRACE5.ip.diffim.RegularizedKernelSolution.estimateRisk",
1124 "%.5e + 2 * (%.5e - %.5e)",
1125 term1(0), term2a, term2b(0));
1130 LOGL_DEBUG(
"TRACE3.ip.diffim.RegularizedKernelSolution.estimateRisk",
1131 "Minimum Risk = %.3e at lambda = %.3e", risks[index], lambdas[index]);
1133 return lambdas[index];
1137 template <
typename InputT>
1139 if (includeHmat ==
true) {
1140 return this->_mMat + _lambda * _hMat;
1147 template <
typename InputT>
1150 LOGL_DEBUG(
"TRACE3.ip.diffim.RegularizedKernelSolution.solve",
1151 "cMat is %d x %d; vVec is %d; iVec is %d; hMat is %d x %d",
1152 this->_cMat.rows(), this->_cMat.cols(), this->_ivVec.size(),
1153 this->_iVec.size(), _hMat.rows(), _hMat.cols());
1168 this->_mMat = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_cMat;
1169 this->_bVec = this->_cMat.transpose() * this->_ivVec.asDiagonal() * this->_iVec;
1221 std::string lambdaType = _ps->getAsString(
"lambdaType");
1222 if (lambdaType ==
"absolute") {
1223 _lambda = _ps->getAsDouble(
"lambdaValue");
1225 else if (lambdaType ==
"relative") {
1226 _lambda = this->_mMat.trace() / this->_hMat.trace();
1227 _lambda *= _ps->getAsDouble(
"lambdaScaling");
1229 else if (lambdaType ==
"minimizeBiasedRisk") {
1230 double tol = _ps->getAsDouble(
"maxConditionNumber");
1231 _lambda = estimateRisk(tol);
1233 else if (lambdaType ==
"minimizeUnbiasedRisk") {
1240 LOGL_DEBUG(
"TRACE3.ip.diffim.RegularizedKernelSolution.solve",
1241 "Applying kernel regularization with lambda = %.2e", _lambda);
1254 template <
typename InputT>
1258 std::string lambdaStepType = _ps->getAsString(
"lambdaStepType");
1259 if (lambdaStepType ==
"linear") {
1260 double lambdaLinMin = _ps->getAsDouble(
"lambdaLinMin");
1261 double lambdaLinMax = _ps->getAsDouble(
"lambdaLinMax");
1262 double lambdaLinStep = _ps->getAsDouble(
"lambdaLinStep");
1263 for (
double l = lambdaLinMin; l <= lambdaLinMax; l += lambdaLinStep) {
1267 else if (lambdaStepType ==
"log") {
1268 double lambdaLogMin = _ps->getAsDouble(
"lambdaLogMin");
1269 double lambdaLogMax = _ps->getAsDouble(
"lambdaLogMax");
1270 double lambdaLogStep = _ps->getAsDouble(
"lambdaLogStep");
1271 for (
double l = lambdaLogMin; l <= lambdaLogMax; l += lambdaLogStep) {
1290 _spatialKernelFunction(spatialKernelFunction),
1291 _constantFirstTerm(false),
1301 bool isAlardLupton = _ps->getAsString(
"kernelBasisSet") ==
"alard-lupton";
1302 bool usePca = _ps->getAsBool(
"usePcaForSpatialKernel");
1303 if (isAlardLupton || usePca) {
1304 _constantFirstTerm =
true;
1308 _nbases = basisList.
size();
1312 if (_constantFirstTerm) {
1313 _nt = (_nbases - 1) * _nkt + 1 + _nbt;
1315 _nt = _nbases * _nkt + _nbt;
1318 Eigen::MatrixXd mMat(_nt, _nt);
1319 Eigen::VectorXd bVec(_nt);
1330 LOGL_DEBUG(
"TRACE3.ip.diffim.SpatialKernelSolution",
1331 "Initializing with size %d %d %d and constant first term = %s",
1333 _constantFirstTerm ?
"true" :
"false");
1338 Eigen::MatrixXd
const& qMat,
1339 Eigen::VectorXd
const& wVec) {
1341 LOGL_DEBUG(
"TRACE5.ip.diffim.SpatialKernelSolution.addConstraint",
1342 "Adding candidate at %f, %f", xCenter, yCenter);
1346 Eigen::VectorXd pK(_nkt);
1348 for (
int idx = 0; idx < _nkt; idx++) { paramsK[idx] = 0.0; }
1349 for (
int idx = 0; idx < _nkt; idx++) {
1352 pK(idx) = (*_spatialKernelFunction)(xCenter, yCenter);
1355 Eigen::MatrixXd pKpKt = (pK * pK.transpose());
1358 Eigen::MatrixXd pBpBt;
1359 Eigen::MatrixXd pKpBt;
1361 pB = Eigen::VectorXd(_nbt);
1365 for (
int idx = 0; idx < _nbt; idx++) { paramsB[idx] = 0.0; }
1366 for (
int idx = 0; idx < _nbt; idx++) {
1369 pB(idx) = (*_background)(xCenter, yCenter);
1372 pBpBt = (pB * pB.transpose());
1375 pKpBt = (pK * pB.transpose());
1398 int mb = _nt - _nbt;
1400 if (_constantFirstTerm) {
1404 _mMat(0, 0) += qMat(0,0);
1405 for(
int m2 = 1; m2 < _nbases; m2++) {
1406 _mMat.block(0, m2*_nkt-dm, 1, _nkt) += qMat(0,m2) * pK.transpose();
1408 _bVec(0) += wVec(0);
1411 _mMat.block(0, mb, 1, _nbt) += qMat(0,_nbases) * pB.transpose();
1416 for(
int m1 = m0; m1 < _nbases; m1++) {
1418 _mMat.block(m1*_nkt-dm, m1*_nkt-dm, _nkt, _nkt) +=
1419 (pKpKt * qMat(m1,m1)).triangularView<Eigen::Upper>();
1422 for(
int m2 = m1+1; m2 < _nbases; m2++) {
1423 _mMat.block(m1*_nkt-dm, m2*_nkt-dm, _nkt, _nkt) += qMat(m1,m2) * pKpKt;
1428 _mMat.block(m1*_nkt-dm, mb, _nkt, _nbt) += qMat(m1,_nbases) * pKpBt;
1432 _bVec.segment(m1*_nkt-dm, _nkt) += wVec(m1) * pK;
1437 _mMat.block(mb, mb, _nbt, _nbt) +=
1438 (pBpBt * qMat(_nbases,_nbases)).triangularView<Eigen::Upper>();
1439 _bVec.segment(mb, _nbt) += wVec(_nbases) * pB;
1463 for (
int i = 0; i < _nt; i++) {
1464 for (
int j = i+1; j < _nt; j++) {
1488 void SpatialKernelSolution::_setKernel() {
1497 for (
int i = 0; i < _nbases; i++) {
1502 "I. Unable to determine spatial kernel solution %d (nan). Condition number = %.3e") % i % cNumber));
1504 kCoeffs[i] =
_aVec(i);
1507 std::dynamic_pointer_cast<afwMath::LinearCombinationKernel>(_kernel)->getKernelList();
1517 for (
int i = 0, idx = 0; i < _nbases; i++) {
1521 if ((i == 0) && (_constantFirstTerm)) {
1526 "II. Unable to determine spatial kernel solution %d (nan). Condition number = %.3e") % idx % cNumber));
1528 kCoeffs[i][0] =
_aVec(idx++);
1531 for (
int j = 0; j < _nkt; j++) {
1536 "III. Unable to determine spatial kernel solution %d (nan). Condition number = %.3e") % idx % cNumber));
1538 kCoeffs[i][j] =
_aVec(idx++);
1552 for (
int i = 0; i < _nbt; i++) {
1553 int idx = _nt - _nbt + i;
1557 "Unable to determine spatial background solution %d (nan)") % (idx)));
1559 bgCoeffs[i] =
_aVec(idx);