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);