35 namespace algorithms {
39 std::complex<double> c1, std::complex<double> g1, std::complex<double> m1,
40 std::complex<double> c2, std::complex<double> g2, std::complex<double> m2,
41 std::complex<double>& c3, std::complex<double>& g3,
42 std::complex<double>& m3)
99 dbg<<
"Start CalculateShift\n";
100 dbg<<
"c1,g1,m1 = "<<c1<<
" "<<g1<<
" "<<m1<<std::endl;
101 dbg<<
"c2,g2,m2 = "<<c2<<
" "<<g2<<
" "<<m2<<std::endl;
103 std::complex<double> Rg2 = std::polar(1.,2*imag(m1)) * g2;
104 double normg1 =
norm(g1);
105 double normg2 =
norm(g2);
106 std::complex<double> denom = 1.+conj(g1)*Rg2;
107 g3 = (g1+Rg2) / denom;
108 dbg<<
"g3 = "<<g3<<std::endl;
112 m3 = m1 + m2 - std::complex<double>(0.,1.)*arg(denom);
113 dbg<<
"m3 = "<<m3<<std::endl;
115 std::complex<double>
X = -c1 - g1 * conj(-c1);
116 X = exp(-m1)/sqrt(1.-normg1) * X - c2;
117 X = exp(-m2)/sqrt(1.-normg2) * (X - g2 * conj(X));
118 double normg3 =
norm(g3);
119 X /= -exp(-m3)/sqrt(1.-normg3);
120 c3 = (X + g3*conj(X)) / (1.-normg3);
121 dbg<<
"c3 = "<<c3<<std::endl;
125 const std::complex<double>& c1,
126 const std::complex<double>& g1,
127 const std::complex<double>& m1)
136 const std::complex<double>& c2,
137 const std::complex<double>& g2,
138 const std::complex<double>& m2)
163 if (imag(
_mu) != 0.) {
164 std::complex<double> r = std::polar(1.,-imag(
_mu));
174 const std::vector<PixelList>& pix,
175 const std::vector<BVec>& psf,
176 int order,
int order2,
int maxm,
178 {
return doMeasure(pix,&psf,order,order2,maxm,sigma,flag,thresh,cov); }
181 const std::vector<PixelList>& pix,
182 int order,
int order2,
int maxm,
184 {
return doMeasure(pix,0,order,order2,maxm,sigma,flag,thresh,cov); }
187 const std::vector<PixelList>& pix,
188 const std::vector<BVec>* psf,
BVec&
b,
189 int order,
int order2,
int maxm,
DMatrix* bCov)
const
191 xdbg<<
"Start MeasureShapelet: order = "<<order<<std::endl;
193 xdbg<<
"el = "<<*
this<<std::endl;
194 if (maxm < 0 || maxm > order) maxm = order;
195 xdbg<<
"order = "<<order<<
','<<order2<<
','<<maxm<<std::endl;
210 std::complex<double>
m = exp(-
_mu)/sqrt(1.-gsq);
213 const int nExp = pix.size();
214 for(
int i=0;i<nExp;++i) nTot += pix[i].size();
215 dbg<<
"ntot = "<<nTot<<
" in "<<nExp<<
" images\n";
221 for(
int k=0,n=0;k<nExp;++k) {
224 sqrt(pow(sigma,2)+pow((*psf)[k].getSigma(),2)) :
226 dbg<<
"sigma_obs["<<k<<
"] = "<<sigma_obs<<std::endl;
228 const int nPix = pix[k].size();
229 for(
int i=0;i<nPix;++i,++n) {
230 I(n) = pix[k][i].getFlux()*pix[k][i].getInverseSigma();
231 W(n) = pix[k][i].getInverseSigma();
232 std::complex<double> z1 = pix[k][i].getPos();
234 Z(n) = z2 / sigma_obs;
241 int bsize = (order+1)*(order+2)/2;
242 xdbg<<
"bsize = "<<bsize<<std::endl;
243 int bsize2 = (order2+1)*(order2+2)/2;
244 xdbg<<
"bsize2 = "<<bsize2<<std::endl;
250 tmv::Permutation P(bsize);
253 tmv::Vector<double> mvals(bsize);
254 for(
int n=0,k=0;n<=order;++n) {
255 for(
int m=n;m>=0;m-=2) {
257 if (m > 0) mvals[k++] =
m;
260 dbg<<
"mvals = "<<mvals<<std::endl;
262 dbg<<
"mvals => "<<mvals<<std::endl;
271 msize = (maxm+1)*(maxm+2)/2 + (2*maxm+1)*(order-maxm)/2;
272 dbg<<
"msize = "<<msize<<std::endl;
273 dbg<<
"mvals["<<msize-1<<
"] = "<<mvals[msize-1]<<std::endl;
274 dbg<<
"mvals["<<msize<<
"] = "<<mvals[msize]<<std::endl;
275 Assert(mvals[msize-1] == maxm);
276 Assert(mvals[msize] == maxm+1);
285 for(
int k=0,n=0,nx;k<nExp;++k,n=nx) {
286 xdbg<<
"psf = "<<(*psf)[k]<<std::endl;
287 int psforder = (*psf)[k].getOrder();
288 int newpsforder = std::max(psforder,order2);
289 xdbg<<
"psforder = "<<psforder<<std::endl;
290 xdbg<<
"newpsforder = "<<newpsforder<<std::endl;
291 const double psfsigma = (*psf)[k].getSigma();
292 xdbg<<
"sigma = "<<psfsigma<<std::endl;
293 BVec newpsf(newpsforder,psfsigma);
294 int psfsize = (*psf)[k].size();
295 int newpsfsize = newpsf.
size();
296 xdbg<<
"psfsize = "<<psfsize<<std::endl;
301 newpsf.
vec() = S * (*psf)[k].vec();
303 xdbg<<
"newpsf = "<<newpsf<<std::endl;
307 DMatrix D(newpsfsize,newpsfsize);
309 newpsf.
vec() = D * newpsf.
vec();
313 newpsf.
vec() = D * (*psf)[k].vec();
317 xdbg<<
"newpsf => "<<newpsf<<std::endl;
319 if (imag(
_mu) != 0.) {
327 newpsf.
vec() = R * newpsf.
vec();
335 newpsf.
vec() = R * (*psf)[k].vec();
338 xdbg<<
"newpsf => "<<newpsf<<std::endl;
347 const int nPix = pix[k].size();
350 makePsi(A1,Z.TMV_subVector(n,nx),order2,&W);
356 const double MAX_CONDITION = 1.e8;
360 tmv::MatrixView<double> Am = A.colRange(0,msize);
367 Am.divideUsing(tmv::QRP);
369 xdbg<<
"R diag = "<<Am.qrpd().getR().diag()<<std::endl;
371 #
if TMV_VERSION_AT_LEAST(0,65)
372 Am.qrpd().isSingular() ||
376 (Am.qrpd().getR().minAbs2Element() <
377 1.e-16 * Am.qrpd().getR().maxAbs2Element()) ||
379 DiagMatrixViewOf(Am.qrpd().getR().diag()).condition() >
381 dbg<<
"Poor condition in MeasureShapelet: \n";
382 dbg<<
"R diag = "<<Am.qrpd().getR().diag()<<std::endl;
383 dbg<<
"condition = "<<
384 DiagMatrixViewOf(Am.qrpd().getR().diag()).condition()<<
386 dbg<<
"det = "<<Am.qrpd().det()<<std::endl;
389 b.
vec().subVector(0,msize) = I/Am;
390 xdbg<<
"b = "<<b<<std::endl;
391 xdbg<<
"Norm(I) = "<<Norm(I)<<std::endl;
392 xdbg<<
"Norm(Am*b) = "<<Norm(Am*b.
vec().subVector(0,msize))<<std::endl;
393 xdbg<<
"Norm(I-Am*b) = "<<Norm(I-Am*b.
vec().subVector(0,msize))<<std::endl;
394 b.
vec().subVector(msize,bsize).setZero();
395 b.
vec() = P.transpose() * b.
vec();
396 xdbg<<
"b => "<<b<<std::endl;
400 Am.makeInverseATA(bCov->subMatrix(0,msize,0,msize));
401 *bCov = P.transpose() * (*bCov) * P;
405 Eigen::JacobiSVD<DMatrix> svd(A, Eigen::ComputeThinU | Eigen::ComputeThinV);
406 const DVector& svd_s = svd.singularValues();
407 double max = svd_s(0);
408 double min = svd_s(svd_s.size()-1);
409 if (max > MAX_CONDITION * min) {
410 xdbg<<
"Poor condition in MeasureShapelet: \n";
411 xdbg<<
"svd = "<<svd_s.transpose()<<std::endl;
412 xdbg<<
"condition = "<<max/min<<std::endl;
417 DVector temp = svd.matrixU().transpose() * I;
418 temp = svd_s.array().inverse().matrix().asDiagonal() * temp;
419 b.
vec().TMV_subVector(0,bsize) = svd.matrixV() * temp;
425 svd_s.array().square().inverse().matrix().asDiagonal() * svd.matrixV().transpose();
426 bCov->TMV_subMatrix(0,bsize,0,bsize) = svd.matrixV() * temp2;
430 dbg<<
"Calculated b vector has negative b(0):\n";
431 dbg<<
"b = "<<b<<std::endl;
435 xdbg<<
"Need to zero the rest of b\n";
436 xdbg<<
"bsize = "<<bsize<<
" b.size = "<<b.
size()<<std::endl;
438 b.
vec().TMV_subVector(bsize,b.
size()).setZero();
440 xdbg<<
"Done measure Shapelet\n";
441 xdbg<<
"b = "<<b.
vec()<<std::endl;
446 const std::vector<PixelList>& pix,
447 const std::vector<BVec>* psf,
BVec&
b,
int order,
int order2,
448 double pixScale,
DMatrix* bCov)
const
450 xdbg<<
"Start AltMeasureShapelet: order = "<<order<<std::endl;
452 xdbg<<
"el = "<<*
this<<std::endl;
453 xdbg<<
"pixScale = "<<pixScale<<std::endl;
454 const int nExp = pix.size();
456 const int bsize = (order+1)*(order+2)/2;
457 const int bsize2 = (order2+1)*(order2+2)/2;
463 std::complex<double>
m = exp(-
_mu)/sqrt(1.-gsq);
465 std::auto_ptr<DMatrix> cov1;
468 cov1.reset(
new DMatrix(bsize2,bsize2));
471 for(
int k=0;k<nExp;++k) {
472 const int nPix = pix[k].size();
478 sqrt(pow(sigma,2)+pow((*psf)[k].getSigma(),2)) :
480 dbg<<
"sigma_obs = "<<sigma_obs<<std::endl;
483 double val = pow(pixScale/sigma_obs,2) * exp(-2.*
real(
_mu)) / nExp;
484 for(
int n=0,i=0;n<=order2;++n) {
485 for(
int p=n,q=0;p>=q;--p,++q,++i) {
486 if (p!=q) { normD(i) = val/2.; normD(++i) = val/2.; }
491 for(
int i=0;i<nPix;++i) {
492 I(i) = pix[k][i].getFlux();
493 std::complex<double> z1 = pix[k][i].getPos();
495 Z(i) = z2 / sigma_obs;
502 DVector b1 = A.transpose() * I;
503 dbg<<
"b1 = "<<b1<<std::endl;
505 dbg<<
"b1 => "<<b1<<std::endl;
513 for(
int i=0;i<nPix;++i) {
514 W(i) = 1./pix[k][i].getInverseSigma();
516 DMatrix temp = normD * A.transpose() * W;
517 *cov1 = temp * temp.transpose();
521 xdbg<<
"psf = "<<(*psf)[k]<<std::endl;
522 int psforder = (*psf)[k].getOrder();
523 int newpsforder = std::max(psforder,order2);
524 xdbg<<
"psforder = "<<psforder<<std::endl;
525 xdbg<<
"newpsforder = "<<newpsforder<<std::endl;
526 const double psfsigma = (*psf)[k].getSigma();
527 xdbg<<
"sigma = "<<psfsigma<<std::endl;
528 BVec newpsf(newpsforder,psfsigma);
529 int psfsize = (*psf)[k].size();
530 int newpsfsize = newpsf.
size();
531 xdbg<<
"psfsize = "<<psfsize<<std::endl;
536 newpsf.
vec() = S * (*psf)[k].vec();
538 xdbg<<
"newpsf = "<<newpsf<<std::endl;
542 DMatrix D(newpsfsize,newpsfsize);
544 newpsf.
vec() = D * newpsf.
vec();
548 newpsf.
vec() = D * (*psf)[k].vec();
552 xdbg<<
"newpsf => "<<newpsf<<std::endl;
554 if (imag(
_mu) != 0.) {
562 newpsf.
vec() = R * newpsf.
vec();
570 newpsf.
vec() = R * (*psf)[k].vec();
573 xdbg<<
"newpsf => "<<newpsf<<std::endl;
585 b1 = C.lu().solve(b1);
587 dbg<<
"b1 /= C => "<<b1<<std::endl;
588 if (bCov) *cov1 = C.inverse() * (*cov1) * C;
590 b.
vec() += b1.TMV_subVector(0,bsize);
591 if (bCov) *bCov += cov1->TMV_subMatrix(0,bsize,0,bsize);
594 dbg<<
"Calculated b vector has negative b(0):\n";
595 dbg<<
"b = "<<b<<std::endl;
599 xdbg<<
"Need to zero the rest of b\n";
600 xdbg<<
"bsize = "<<bsize<<
" b.size = "<<b.
size()<<std::endl;
602 b.
vec().TMV_subVector(bsize,b.
size()).setZero();
604 xdbg<<
"Done (alt) measure Shapelet\n";
609 const std::vector<PixelList>& pix,
610 const std::vector<BVec>& psf,
BVec&
b,
611 int order,
int order2,
int maxm,
DMatrix* bCov)
const
615 const std::vector<PixelList>& pix,
BVec&
b,
616 int order,
int order2,
int maxm,
DMatrix* bCov)
const
620 const std::vector<PixelList>& pix,
621 const std::vector<BVec>& psf,
BVec&
b,
int order,
int order2,
622 double pixScale,
DMatrix* bCov)
const
626 const std::vector<PixelList>& pix,
BVec&
b,
int order,
int order2,
627 double pixScale,
DMatrix* bCov)
const
Eigen::VectorXcd CDVector
bool doMeasure(const std::vector< PixelList > &pix, const std::vector< BVec > *psf, int order, int order2, int maxm, double sigma, long &flag, double thresh, DMatrix *cov=0)
bool doAltMeasureShapelet(const std::vector< PixelList > &pix, const std::vector< BVec > *psf, BVec &bret, int order, int order2, double pixScale, DMatrix *bcov=0) const
void postShiftBy(const std::complex< double > &cen, const std::complex< double > &gamma, const std::complex< double > &mu)
void calculateGTransform(std::complex< double > g, int order1, int order2, DMatrix &S)
std::complex< double > _gamma
afw::table::Key< double > sigma
void makePsi(DMatrix &psi, CDVectorView z, int order, const DVector *coeff=0)
void preShiftBy(const std::complex< double > &cen, const std::complex< double > &gamma, const std::complex< double > &mu)
bool doMeasureShapelet(const std::vector< PixelList > &pix, const std::vector< BVec > *psf, BVec &bret, int order, int order2, int maxm, DMatrix *bcov=0) const
void calculateThetaTransform(double theta, int order1, int order2, DBandMatrix &R)
Eigen::MatrixXd DBandMatrix
std::complex< double > _cen
bool altMeasureShapelet(const std::vector< PixelList > &pix, const std::vector< BVec > &psf, BVec &bret, int order, int order2, double pixScale, DMatrix *bcov=0) const
void CalculateShift(std::complex< double > c1, std::complex< double > g1, std::complex< double > m1, std::complex< double > c2, std::complex< double > g2, std::complex< double > m2, std::complex< double > &c3, std::complex< double > &g3, std::complex< double > &m3)
bool measureShapelet(const std::vector< PixelList > &pix, BVec &bret, int order, int order2, int maxm, DMatrix *bcov=0) const
afw::table::Key< double > b
#define TMV_rowRange(m, i1, i2)
bool measure(const std::vector< PixelList > &pix, int order, int order2, int maxm, double sigma, long &flag, double thresh, DMatrix *cov=0)
void calculatePsfConvolve(const BVec &bpsf, int order1, int order2, double sigma, DMatrix &C)
void calculateMuTransform(double mu, int order1, int order2, DMatrix &D)
std::complex< double > _mu