17#include "boost/timer/timer.hpp"
20#include "Eigen/Cholesky"
23#include "Eigen/Eigenvalues"
38#include "ndarray/eigen.h"
41#define DEBUG_MATRIX2 0
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());
143 boost::timer::cpu_timer t;
145 LOGL_DEBUG(
"TRACE2.ip.diffim.KernelSolution.solve",
146 "Solving for kernel");
148 Eigen::FullPivLU<Eigen::MatrixXd> lu(mMat);
149 if (lu.isInvertible()) {
150 aVec = lu.solve(bVec);
152 LOGL_DEBUG(
"TRACE3.ip.diffim.KernelSolution.solve",
153 "Unable to determine kernel via LU");
158 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eVecValues(mMat);
159 Eigen::MatrixXd
const& rMat = eVecValues.eigenvectors();
160 Eigen::VectorXd eValues = eVecValues.eigenvalues();
162 for (
int i = 0; i != eValues.rows(); ++i) {
163 if (eValues(i) != 0.0) {
164 eValues(i) = 1.0/eValues(i);
168 aVec = rMat * eValues.asDiagonal() * rMat.transpose() * bVec;
172 LOGL_DEBUG(
"TRACE3.ip.diffim.KernelSolution.solve",
173 "Unable to determine kernel via eigen-values");
180 double time = 1e-9 * t.elapsed().wall;
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>
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");
280 unsigned int const nKernelParameters = basisList.
size();
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;
325 boost::timer::cpu_timer t;
337 startRow, startCol, endRow-startRow, endCol-startCol
338 ).array().inverse().matrix();
341 eigenTemplate.resize(eigenTemplate.rows()*eigenTemplate.cols(), 1);
342 eigenScience.resize(eigenScience.rows()*eigenScience.cols(), 1);
343 eigeniVariance.resize(eigeniVariance.rows()*eigeniVariance.cols(), 1);
352 typename std::vector<Eigen::MatrixXd>::iterator eiter = convolvedEigenList.
begin();
356 for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
363 cMat.resize(cMat.size(), 1);
369 double time = 1e-9 * t.elapsed().wall;
370 LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.build",
371 "Total compute time to do basis convolutions : %.2f s", time);
377 Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
378 typename std::vector<Eigen::MatrixXd>::iterator eiterj = convolvedEigenList.
begin();
379 typename std::vector<Eigen::MatrixXd>::iterator eiterE = convolvedEigenList.
end();
380 for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
381 cMat.col(kidxj) = eiterj->col(0);
385 cMat.col(nParameters-1).fill(1.);
388 _ivVec = eigeniVariance.col(0);
389 _iVec = eigenScience.col(0);
396 template <
typename InputT>
398 LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.solve",
399 "mMat is %d x %d; bVec is %d; cMat is %d x %d; vVec is %d; iVec is %d",
422 template <
typename InputT>
428 unsigned int const nParameters =
_aVec.size();
430 unsigned int const nKernelParameters =
432 if (nParameters != (nKernelParameters + nBackgroundParameters))
437 for (
unsigned int idx = 0; idx < nKernelParameters; idx++) {
440 str(boost::format(
"Unable to determine kernel solution %d (nan)") % idx));
442 kValues[idx] =
_aVec(idx);
444 _kernel->setKernelParameters(kValues);
454 str(boost::format(
"Unable to determine background solution %d (nan)") %
462 template <
typename InputT>
492 template <
typename InputT>
495 bool fitForBackground
500 template <
typename InputT>
511 "Error: variance less than 0.0");
515 "Error: variance equals 0.0, cannot inverse variance weight");
538 int growPix = (*kiter)->getCtr().getX();
542 for (
typename afwDet::FootprintSet::FootprintList::iterator
548 afwDet::setMaskFromFootprint(finalMask,
555 for (
auto const & foot : *(maskedFpSetGrown.
getFootprints())) {
562 ndarray::Array<int, 1, 1> maskArray =
563 ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
564 fullFp->getSpans()->flatten(maskArray, finalMask.
getArray(), templateImage.
getXY0());
565 auto maskEigen = ndarray::asEigenMatrix(maskArray);
567 ndarray::Array<InputT, 1, 1> arrayTemplate =
568 ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
569 fullFp->getSpans()->flatten(arrayTemplate, templateImage.
getArray(), templateImage.
getXY0());
570 auto eigenTemplate0 = ndarray::asEigenMatrix(arrayTemplate);
572 ndarray::Array<InputT, 1, 1> arrayScience =
573 ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
574 fullFp->getSpans()->flatten(arrayScience, scienceImage.
getArray(), scienceImage.
getXY0());
575 auto eigenScience0 = ndarray::asEigenMatrix(arrayScience);
577 ndarray::Array<afwImage::VariancePixel, 1, 1> arrayVariance =
578 ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
579 fullFp->getSpans()->flatten(arrayVariance, varianceEstimate.
getArray(), varianceEstimate.
getXY0());
580 auto eigenVariance0 = ndarray::asEigenMatrix(arrayVariance);
583 for (
int i = 0; i < maskEigen.size(); i++) {
584 if (maskEigen(i) == 0.0)
588 Eigen::VectorXd eigenTemplate(nGood);
589 Eigen::VectorXd eigenScience(nGood);
590 Eigen::VectorXd eigenVariance(nGood);
592 for (
int i = 0; i < maskEigen.size(); i++) {
593 if (maskEigen(i) == 0.0) {
594 eigenTemplate(nUsed) = eigenTemplate0(i);
595 eigenScience(nUsed) = eigenScience0(i);
596 eigenVariance(nUsed) = eigenVariance0(i);
602 boost::timer::cpu_timer t;
604 unsigned int const nKernelParameters = basisList.
size();
606 unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
615 typename std::vector<Eigen::VectorXd>::iterator eiter = convolvedEigenList.
begin();
620 for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
623 ndarray::Array<InputT, 1, 1> arrayC =
624 ndarray::allocate(ndarray::makeVector(fullFp->getArea()));
625 fullFp->getSpans()->flatten(arrayC, cimage.
getArray(), cimage.
getXY0());
626 auto eigenC0 = ndarray::asEigenMatrix(arrayC);
628 Eigen::VectorXd eigenC(nGood);
630 for (
int i = 0; i < maskEigen.size(); i++) {
631 if (maskEigen(i) == 0.0) {
632 eigenC(nUsed) = eigenC0(i);
640 double time = 1e-9 * t.elapsed().wall;
641 LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.buildWithMask",
642 "Total compute time to do basis convolutions : %.2f s", time);
645 Eigen::MatrixXd cMat(eigenTemplate.size(), nParameters);
646 typename std::vector<Eigen::VectorXd>::iterator eiterj = convolvedEigenList.
begin();
647 typename std::vector<Eigen::VectorXd>::iterator eiterE = convolvedEigenList.
end();
648 for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
649 cMat.block(0, kidxj, eigenTemplate.size(), 1) =
650 Eigen::MatrixXd(*eiterj).block(0, 0, eigenTemplate.size(), 1);
654 cMat.col(nParameters-1).fill(1.);
657 this->
_ivVec = eigenVariance.array().inverse().matrix();
658 this->
_iVec = eigenScience;
666 template <
typename InputT>
677 "Error: variance less than 0.0");
681 "Error: variance equals 0.0, cannot inverse variance weight");
697 unsigned int const nKernelParameters = basisList.
size();
699 unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
707 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
708 "Limits of good pixels after convolution: %d,%d -> %d,%d (local)",
713 unsigned int startCol = shrunkLocalBBox.
getMinX();
714 unsigned int startRow = shrunkLocalBBox.
getMinY();
715 unsigned int endCol = shrunkLocalBBox.
getMaxX();
716 unsigned int endRow = shrunkLocalBBox.
getMaxY();
721 boost::timer::cpu_timer t;
738 startRow, startCol, endRow-startRow, endCol-startCol
739 ).array().inverse().matrix();
742 eMask.resize(eMask.rows()*eMask.cols(), 1);
743 eigenTemplate.resize(eigenTemplate.rows()*eigenTemplate.cols(), 1);
744 eigenScience.resize(eigenScience.rows()*eigenScience.cols(), 1);
745 eigeniVariance.resize(eigeniVariance.rows()*eigeniVariance.cols(), 1);
748 Eigen::MatrixXd maskedEigenTemplate(eigenTemplate.rows(), 1);
749 Eigen::MatrixXd maskedEigenScience(eigenScience.rows(), 1);
750 Eigen::MatrixXd maskedEigeniVariance(eigeniVariance.rows(), 1);
752 for (
int i = 0; i < eMask.rows(); i++) {
753 if (eMask(i, 0) == 0) {
754 maskedEigenTemplate(nGood, 0) = eigenTemplate(i, 0);
755 maskedEigenScience(nGood, 0) = eigenScience(i, 0);
756 maskedEigeniVariance(nGood, 0) = eigeniVariance(i, 0);
761 eigenTemplate = maskedEigenTemplate.block(0, 0, nGood, 1);
762 eigenScience = maskedEigenScience.block(0, 0, nGood, 1);
763 eigeniVariance = maskedEigeniVariance.block(0, 0, nGood, 1);
773 typename std::vector<Eigen::MatrixXd>::iterator eiter = convolvedEigenList.
begin();
777 for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
784 cMat.resize(cMat.size(), 1);
787 Eigen::MatrixXd maskedcMat(cMat.rows(), 1);
789 for (
int i = 0; i < eMask.rows(); i++) {
790 if (eMask(i, 0) == 0) {
791 maskedcMat(nGood, 0) = cMat(i, 0);
795 cMat = maskedcMat.block(0, 0, nGood, 1);
800 double time = 1e-9 * t.elapsed().wall;
801 LOGL_DEBUG(
"TRACE3.ip.diffim.StaticKernelSolution.build",
802 "Total compute time to do basis convolutions : %.2f s", time);
808 Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
809 typename std::vector<Eigen::MatrixXd>::iterator eiterj = convolvedEigenList.
begin();
810 typename std::vector<Eigen::MatrixXd>::iterator eiterE = convolvedEigenList.
end();
811 for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
812 cMat.col(kidxj) = eiterj->col(0);
816 cMat.col(nParameters-1).fill(1.);
819 this->
_ivVec = eigeniVariance.col(0);
820 this->
_iVec = eigenScience.col(0);
830 template <
typename InputT>
841 "Error: variance less than 0.0");
845 "Error: variance equals 0.0, cannot inverse variance weight");
851 unsigned int const nKernelParameters = basisList.
size();
853 unsigned int const nParameters = nKernelParameters + nBackgroundParameters;
883 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
884 "Limits of good pixels after convolution: %d,%d -> %d,%d",
888 unsigned int const startCol = shrunkBBox.
getMinX();
889 unsigned int const startRow = shrunkBBox.
getMinY();
890 unsigned int const endCol = shrunkBBox.
getMaxX();
891 unsigned int const endRow = shrunkBBox.
getMaxY();
906 int maskStartCol = maskBox.
getMinX();
907 int maskStartRow = maskBox.
getMinY();
908 int maskEndCol = maskBox.
getMaxX();
909 int maskEndRow = maskBox.
getMaxY();
942 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
943 "Upper good pixel region: %d,%d -> %d,%d",
945 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
946 "Bottom good pixel region: %d,%d -> %d,%d",
948 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
949 "Left good pixel region: %d,%d -> %d,%d",
951 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
952 "Right good pixel region: %d,%d -> %d,%d",
966 Eigen::MatrixXd eigenTemplate(totalSize, 1);
967 Eigen::MatrixXd eigenScience(totalSize, 1);
968 Eigen::MatrixXd eigeniVariance(totalSize, 1);
969 eigenTemplate.setZero();
970 eigenScience.setZero();
971 eigeniVariance.setZero();
973 boost::timer::cpu_timer t;
976 typename std::vector<geom::Box2I>::iterator biter = boxArray.
begin();
977 for (; biter != boxArray.
end(); ++biter) {
978 int area = (*biter).getWidth() * (*biter).getHeight();
986 Eigen::MatrixXd eiVarEstimate =
imageToEigenMatrix(sVarEstimate).array().inverse().matrix();
988 eTemplate.resize(area, 1);
989 eScience.resize(area, 1);
990 eiVarEstimate.resize(area, 1);
992 eigenTemplate.block(nTerms, 0, area, 1) = eTemplate.block(0, 0, area, 1);
993 eigenScience.block(nTerms, 0, area, 1) = eScience.block(0, 0, area, 1);
994 eigeniVariance.block(nTerms, 0, area, 1) = eiVarEstimate.block(0, 0, area, 1);
1002 typename std::vector<Eigen::MatrixXd>::iterator eiter = convolvedEigenList.
begin();
1006 for (kiter = basisList.
begin(); kiter != basisList.
end(); ++kiter, ++eiter) {
1008 Eigen::MatrixXd cMat(totalSize, 1);
1012 typename std::vector<geom::Box2I>::iterator biter = boxArray.
begin();
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);
1029 double time = 1e-9 * t.elapsed().wall;
1030 LOGL_DEBUG(
"TRACE3.ip.diffim.MaskedKernelSolution.build",
1031 "Total compute time to do basis convolutions : %.2f s", time);
1037 Eigen::MatrixXd cMat(eigenTemplate.col(0).size(), nParameters);
1038 typename std::vector<Eigen::MatrixXd>::iterator eiterj = convolvedEigenList.
begin();
1039 typename std::vector<Eigen::MatrixXd>::iterator eiterE = convolvedEigenList.
end();
1040 for (
unsigned int kidxj = 0; eiterj != eiterE; eiterj++, kidxj++) {
1041 cMat.col(kidxj) = eiterj->col(0);
1045 cMat.col(nParameters-1).fill(1.);
1048 this->
_ivVec = eigeniVariance.col(0);
1049 this->
_iVec = eigenScience.col(0);
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));
1128 std::vector<double>::iterator it = min_element(risks.
begin(), risks.
end());
1129 int index = distance(risks.
begin(), it);
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());
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");
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) {
1276 throw LSST_EXCEPT(pexExcept::Exception,
"lambdaStepType in PropertySet not recognized");
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();
1309 _nkt = _spatialKernelFunction->getParameters().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++) {
1351 _spatialKernelFunction->setParameters(paramsK);
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++) {
1368 _background->setParameters(paramsB);
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;
1457 (void)_kernel->computeImage(*
image,
false, pos[0], pos[1]);
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);
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++) {
1534 pexExcept::Exception,
1536 "III. Unable to determine spatial kernel solution %d (nan). Condition number = %.3e") % idx % cNumber));
1538 kCoeffs[i][j] =
_aVec(idx++);
1542 _kernel->setSpatialParameters(kCoeffs);
1546 std::shared_ptr<ImageT>
image (
new ImageT(_kernel->getDimensions()));
1547 _kSum = _kernel->computeImage(*image,
false);
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);
1565 _background->setParameters(bgCoeffs);
#define LOGL_DEBUG(logger, message...)
#define LSST_EXCEPT_ADD(e, m)
#define LSST_EXCEPT(type,...)
Image Subtraction helper functions.
Declaration of classes to store the solution for convolution kernels.
lsst::geom::Box2I getBBox(ImageOrigin origin=PARENT) const
lsst::geom::Extent2I getDimensions() const
lsst::geom::Point2I getXY0() const
static MaskPixelT getPlaneBitMask(const std::vector< std::string > &names)
void writeFits(std::string const &fileName, daf::base::PropertySet const *metadata=nullptr, std::string const &mode="w") const
void setDoNormalize(bool doNormalize)
std::shared_ptr< lsst::afw::math::Function2< double > > SpatialFunctionPtr
double getValue(Property const prop=NOTHING) const
int getMinY() const noexcept
int getHeight() const noexcept
int getMinX() const noexcept
int getWidth() const noexcept
int getMaxX() const noexcept
int getMaxY() const noexcept
virtual double getConditionNumber(ConditionNumberType conditionType)
Eigen::MatrixXd const & getM()
KernelSolution(Eigen::MatrixXd mMat, Eigen::VectorXd bVec, bool fitForBackground)
static int _SolutionId
Unique identifier for solution.
lsst::afw::image::Image< lsst::afw::math::Kernel::Pixel > ImageT
virtual void buildWithMask(lsst::afw::image::Image< InputT > const &templateImage, lsst::afw::image::Image< InputT > const &scienceImage, lsst::afw::image::Image< lsst::afw::image::VariancePixel > const &varianceEstimate, lsst::afw::image::Mask< lsst::afw::image::MaskPixel > const &pixelMask)
virtual void buildSingleMaskOrig(lsst::afw::image::Image< InputT > const &templateImage, lsst::afw::image::Image< InputT > const &scienceImage, lsst::afw::image::Image< lsst::afw::image::VariancePixel > const &varianceEstimate, lsst::geom::Box2I maskBox)
MaskedKernelSolution(lsst::afw::math::KernelList const &basisList, bool fitForBackground)
virtual void buildOrig(lsst::afw::image::Image< InputT > const &templateImage, lsst::afw::image::Image< InputT > const &scienceImage, lsst::afw::image::Image< lsst::afw::image::VariancePixel > const &varianceEstimate, lsst::afw::image::Mask< lsst::afw::image::MaskPixel > pixelMask)
RegularizedKernelSolution(lsst::afw::math::KernelList const &basisList, bool fitForBackground, Eigen::MatrixXd const &hMat, lsst::daf::base::PropertySet const &ps)
double estimateRisk(double maxCond)
std::pair< std::shared_ptr< lsst::afw::math::LinearCombinationKernel >, lsst::afw::math::Kernel::SpatialFunctionPtr > getSolutionPair()
std::shared_ptr< lsst::afw::image::Image< lsst::afw::math::Kernel::Pixel > > makeKernelImage(lsst::geom::Point2D const &pos)
SpatialKernelSolution(lsst::afw::math::KernelList const &basisList, lsst::afw::math::Kernel::SpatialFunctionPtr spatialKernelFunction, lsst::afw::math::Kernel::SpatialFunctionPtr background, lsst::daf::base::PropertySet const &ps)
void addConstraint(float xCenter, float yCenter, Eigen::MatrixXd const &qMat, Eigen::VectorXd const &wVec)
double _background
Derived differential background estimate.
double _kSum
Derived kernel sum.
virtual std::pair< std::shared_ptr< lsst::afw::math::Kernel >, double > getSolutionPair()
void _setKernel()
Set kernel after solution.
virtual double getBackground()
virtual std::shared_ptr< lsst::afw::math::Kernel > getKernel()
Eigen::VectorXd _iVec
Vectorized I.
std::shared_ptr< lsst::afw::math::Kernel > _kernel
Derived single-object convolution kernel.
void _setKernelUncertainty()
Not implemented.
virtual std::shared_ptr< lsst::afw::image::Image< lsst::afw::math::Kernel::Pixel > > makeKernelImage()
Eigen::VectorXd _ivVec
Inverse variance.
Eigen::MatrixXd _cMat
K_i x R.
StaticKernelSolution(lsst::afw::math::KernelList const &basisList, bool fitForBackground)
virtual void build(lsst::afw::image::Image< InputT > const &templateImage, lsst::afw::image::Image< InputT > const &scienceImage, lsst::afw::image::Image< lsst::afw::image::VariancePixel > const &varianceEstimate)
Statistics makeStatistics(lsst::afw::image::Image< Pixel > const &img, lsst::afw::image::Mask< image::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl=StatisticsControl())
void convolve(OutImageT &convolvedImage, InImageT const &inImage, KernelT const &kernel, ConvolutionControl const &convolutionControl=ConvolutionControl())
std::vector< std::shared_ptr< Kernel > > KernelList
Point< double, 2 > Point2D
Eigen::MatrixXd imageToEigenMatrix(lsst::afw::image::Image< PixelT > const &img)
Turns a 2-d Image into a 2-d Eigen Matrix.
Eigen::MatrixXi maskToEigenMatrix(lsst::afw::image::Mask< lsst::afw::image::MaskPixel > const &mask)
T dynamic_pointer_cast(T... args)