32 namespace afwGeom = lsst::afw::geom;
36 namespace algorithms {
59 if (
_b.size() == v.size()) {
61 }
else if (
_b.size() > v.size()) {
62 _b.TMV_subVector(0,v.size()) = v;
63 _b.TMV_subVector(v.size(),
_b.size()).setZero();
65 xdbg<<
"Warning truncating information in BVec::setValues\n";
66 _b = v.TMV_subVector(0,
_b.size());
73 for(
int n=1,k=1;n<=N;++n) {
74 for(
int m=n;
m>=0;
m-=2) {
85 std::complex<double> z,
int order1,
int order2,
DMatrix& T)
87 const int size1 = (order1+1)*(order1+2)/2;
88 const int size2 = (order2+1)*(order2+2)/2;
89 Assert(
int(T.TMV_colsize()) >= size1);
90 Assert(
int(T.TMV_rowsize()) >= size2);
95 T.TMV_diagpart(0,0,std::min(size1,size2)).TMV_setAllTo(1.);
103 std::complex<double> zo2 = -z/2.;
104 std::vector<std::vector<std::complex<double> > > f(
105 order2+1,std::vector<std::complex<double> >(order1+1));
108 for(
int p=1;p<=order2;++p) {
109 f[p][0] = f[p-1][0]*(-zo2)/
sqrtn(p);
111 for(
int s=0;s<order1;++s) {
112 f[0][s+1] = std::conj(zo2)*f[0][s]/
sqrtn(s+1);
113 for(
int p=1;p<=order2;++p) {
114 f[p][s+1] = (
sqrtn(p)*f[p-1][s] + std::conj(zo2)*f[p][s])/
119 for(
int n=0,pq=0;n<=order2;++n) {
120 for(
int p=n,q=0;p>=q;--p,++q,++pq) {
121 double* Tpq =
TMV_ptr(T.col(pq));
123 const std::vector<std::complex<double> >& fp = f[p];
124 const std::vector<std::complex<double> >& fq = f[q];
125 for(
int nn=0,st=0;nn<=order1;++nn) {
126 for(
int s=nn,t=0;s>=t;--s,++t,++st) {
127 std::complex<double> t1 = fp[s] * std::conj(fq[t]);
133 Tpq[st+1] = std::imag(t1);
140 Tpq1[st] = -2.*std::imag(t1);
142 std::complex<double> t2 = fq[s] * std::conj(fp[t]);
144 Tpq[st+1]= std::imag(t1) + std::imag(t2);
145 Tpq1[st] = -std::imag(t1) + std::imag(t2);
158 const int order1 = order;
159 const int order2 = order+2;
160 const int size1 = (order1+1)*(order1+2)/2;
162 Assert(
int(T.TMV_colsize()) >= size1);
163 Assert(
int(T.TMV_rowsize()) >= (order2+1)*(order2+2)/2);
165 if (z == 0.0)
return;
167 std::complex<double> zo2 = -z/2.;
168 std::vector<std::vector<std::complex<double> > > f(
169 order2+1,std::vector<std::complex<double> >(order1+1));
172 for(
int p=1;p<=order2;++p) {
173 f[p][0] = f[p-1][0]*(-zo2)/
sqrtn(p);
175 for(
int s=0;s<order1;++s) {
176 f[0][s+1] = std::conj(zo2)*f[0][s]/
sqrtn(s+1);
177 for(
int p=1;p<=order2;++p) {
178 f[p][s+1] = (
sqrtn(p)*f[p-1][s] + std::conj(zo2)*f[p][s])/
183 for(
int n=order1+1,pq=size1;n<=order2;++n) {
184 for(
int p=n,q=0;p>=q;--p,++q,++pq) {
185 const std::vector<std::complex<double> >& fp = f[p];
186 const std::vector<std::complex<double> >& fq = f[q];
187 double* Tpq =
TMV_ptr(T.col(pq));
189 for(
int nn=0,st=0;nn<=order1;++nn) {
190 for(
int s=nn,t=0;s>=t;--s,++t,++st) {
191 std::complex<double> t1 = fp[s] * std::conj(fq[t]);
197 Tpq[st+1] = std::imag(t1);
202 Tpq1[st] = -2.*std::imag(t1);
204 std::complex<double> t2 = fq[s] * std::conj(fp[t]);
206 Tpq[st+1]= std::imag(t1) + std::imag(t2);
207 Tpq1[st] = -std::imag(t1) + std::imag(t2);
229 const int size1 = (order1+1)*(order1+2)/2;
230 const int size2 = (order2+1)*(order2+2)/2;
231 Assert(
int(D.TMV_colsize()) >= size1);
232 Assert(
int(D.TMV_rowsize()) >= size2);
267 D.TMV_diagpart(0,0,std::min(size1,size2)).TMV_setAllTo(1.);
271 double tmu = tanh(mu);
272 double smu = 1./cosh(mu);
274 int minorder = std::min(order1,order2);
275 double Dqq = exp(-mu)*smu;
278 for(
int n=0,pq=0;n<=order2;++n) {
279 for(
int p=n,q=0;p>=q;--p,++q,++pq) {
280 double* Dpq =
TMV_ptr(D.col(pq));
281 double* Dpq_n =
TMV_ptr(D.col(pq-n));
282 double* Dpq_n_2 = q>0?
TMV_ptr(D.col(pq-n-2)):0;
283 double* Dpq1 = p>q?
TMV_ptr(D.col(pq+1)):0;
285 if (p > 0) Dqq *= tmu;
288 for(
int m=1,st=1;
m<=minorder;++
m) {
289 for(
int s=
m,t=0;s>=t;--s,++t,++st) {
295 temp = -tmu*
sqrtn(s)*Dpq[st-2*
m-1];
297 temp += smu*
sqrtn(q)*Dpq_n_2[st-
m-2];
318 const int order1 = order;
319 const int order2 = order+2;
320 const int size1 = (order1+1)*(order1+2)/2;
322 Assert(
int(D.TMV_colsize()) >= size1);
323 Assert(
int(D.TMV_rowsize()) >= (order2+1)*(order2+2)/2);
325 if (mu == 0.0)
return;
327 double tmu = tanh(mu);
328 double smu = 1./cosh(mu);
330 double Dqq = exp(-mu)*smu;
331 for(
int q=order1/2;q>0;--q) Dqq *= tmu;
332 for(
int n=order1+1,pq=size1;n<=order2;++n) {
333 for(
int p=n,q=0;p>=q;--p,++q,++pq) {
334 double* Dpq =
TMV_ptr(D.col(pq));
335 double* Dpq_n =
TMV_ptr(D.col(pq-n));
336 double* Dpq_n_2 = q>0?
TMV_ptr(D.col(pq-n-2)):0;
337 double* Dpq1 = p>q?
TMV_ptr(D.col(pq+1)):0;
339 if (p > 0) Dqq *= tmu;
342 for(
int m=1,st=1;
m<=order1;++
m) {
343 for(
int s=
m,t=0;s>=t;--s,++t,++st) {
349 temp = -tmu*
sqrtn(s)*Dpq[st-2*
m-1];
351 temp += smu*
sqrtn(q)*Dpq_n_2[st-
m-2];
356 if (s!=t) Dpq1[st+1] = temp;
368 const int order1 = order+2;
369 const int order2 = order;
371 const int size2 = (order2+1)*(order2+2)/2;
372 Assert(
int(D.TMV_colsize()) == (order1+1)*(order1+2)/2);
373 Assert(
int(D.TMV_rowsize()) == size2);
375 if (mu == 0.0)
return;
377 double tmu = tanh(mu);
378 double smu = 1./cosh(mu);
380 for(
int n=0,pq=0;n<=order2;++n) {
381 for(
int p=n,q=0;p>=q;--p,++q,++pq) {
382 double* Dpq =
TMV_ptr(D.col(pq));
383 double* Dpq_n =
TMV_ptr(D.col(pq-n));
384 double* Dpq_n_2 = q>0?
TMV_ptr(D.col(pq-n-2)):0;
385 double* Dpq1 = p>q?
TMV_ptr(D.col(pq+1)):0;
386 for(
int m=order2+1,st=size2;
m<=order1;++
m) {
387 for(
int s=
m,t=0;s>=t;--s,++t,++st) {
393 temp = -tmu*
sqrtn(s)*Dpq[st-2*
m-1];
395 temp += smu*
sqrtn(q)*Dpq_n_2[st-
m-2];
400 if (s!=t) Dpq1[st+1] = temp;
420 double theta,
int order1,
int order2,
DBandMatrix& R)
422 const int size1 = (order1+1)*(order1+2)/2;
423 const int size2 = (order2+1)*(order2+2)/2;
424 Assert(
int(R.TMV_colsize()) >= size1);
425 Assert(
int(R.TMV_rowsize()) >= size2);
430 R.TMV_diagpart(0,0,std::min(size1,size2)).TMV_setAllTo(1.);
434 int minorder = std::min(order1,order2);
435 std::vector<std::complex<double> > expimt(minorder+1);
437 if (minorder > 0) expimt[1] = std::polar(1.,theta);
438 for(
int m=2;
m<=minorder;++
m) expimt[
m] = expimt[
m-1] * expimt[1];
440 for(
int n=0,pq=0;n<=minorder;++n) {
441 for(
int p=n,q=0,
m=n;p>=q;--p,++q,++pq,
m-=2) {
445 R(pq,pq) =
real(expimt[m]);
446 R(pq,pq+1) = -imag(expimt[m]);
447 R(pq+1,pq) = imag(expimt[m]);
448 R(pq+1,pq+1) =
real(expimt[m]);
469 std::complex<double> g,
int order1,
int order2,
DMatrix& S)
471 const int size1 = (order1+1)*(order1+2)/2;
472 const int size2 = (order2+1)*(order2+2)/2;
473 Assert(
int(S.TMV_colsize()) >= size1);
474 Assert(
int(S.TMV_rowsize()) >= size2);
490 S.TMV_diagpart(0,0,std::min(size1,size2)).TMV_setAllTo(1.);
494 double absg = std::abs(g);
496 std::vector<std::complex<double> > phase(order1+order2+1);
498 std::complex<double> ph = -std::conj(g)/absg;
501 for(
int i=1;i<=order1+order2;++i) phase[i] = phase[i-1]*ph;
504 double se = sqrt(1.-normg);
506 std::vector<std::vector<double> > f(
507 order2+1,std::vector<double>(order1+1,0.));
511 for(
int p=2;p<=order2;p+=2) {
512 f[p][0] = f[p-2][0]*(-te/2.)*
sqrtn(p*(p-1))/double(p/2);
515 for(
int s=0;s<order1;++s) {
519 for(
int p=s%2+1;p<=order2;p+=2) {
520 double temp =
sqrtn(p)*se*f[p-1][s];
521 if (s>0) temp +=
sqrtn(s)*te*f[p][s-1];
527 for(
int n=0,pq=0;n<=order2;++n) {
528 for(
int p=n,q=0;p>=q;--p,++q,++pq) {
529 const std::vector<double>& fp = f[p];
530 const std::vector<double>& fq = f[q];
531 double* Spq =
TMV_ptr(S.col(pq));
532 double* Spq1 = p>q?
TMV_ptr(S.col(pq+1)):0;
533 for(
int nn=n%2,st=(nn==0?0:1);nn<=order1;nn+=2,st+=nn) {
534 for(
int s=nn,t=0;s>=t;--s,++t,++st) {
536 double s0 = fp[s] * fq[t];
538 int iphase = s-t-p+q;
539 std::complex<double> s1 = s0 *
542 std::conj(phase[-iphase/2]));
549 Spq[st+1] = std::imag(s1);
556 Spq1[st] = -2.*std::imag(s1);
560 std::complex<double> s2 = s0 *
563 std::conj(phase[-iphase/2]));
565 Spq[st+1] = std::imag(s1) + std::imag(s2);
566 Spq1[st] = -std::imag(s1) + std::imag(s2);
579 const int order1 = order;
580 const int order2 = order+2;
581 const int size1 = (order1+1)*(order1+2)/2;
583 Assert(
int(S.TMV_colsize()) == size1);
584 Assert(
int(S.TMV_rowsize()) == (order2+1)*(order2+2)/2);
586 if (g == 0.0)
return;
588 double absg = std::abs(g);
590 std::vector<std::complex<double> > phase(order1+order2+1);
592 std::complex<double> ph = -std::conj(g)/absg;
593 for(
int i=1;i<=order1+order2;++i) phase[i] = phase[i-1]*ph;
596 double se = sqrt(1.-normg);
598 std::vector<std::vector<double> > f(
599 order2+1,std::vector<double>(order1+1,0.));
603 for(
int p=2;p<=order2;p+=2) {
604 f[p][0] = f[p-2][0]*(-te/2.)*
sqrtn(p*(p-1))/double(p/2);
607 for(
int s=0;s<order1;++s) {
611 for(
int p=s%2+1;p<=order2;p+=2) {
612 double temp =
sqrtn(p)*se*f[p-1][s];
613 if (s>0) temp +=
sqrtn(s)*te*f[p][s-1];
619 for(
int n=order1+1,pq=size1;n<=order2;++n) {
620 for(
int p=n,q=0;p>=q;--p,++q,++pq) {
621 const std::vector<double>& fp = f[p];
622 const std::vector<double>& fq = f[q];
623 double* Spq =
TMV_ptr(S.col(pq));
624 double* Spq1 = p>q?
TMV_ptr(S.col(pq+1)):0;
625 for(
int nn=n%2,st=(nn==0?0:1);nn<=order1;nn+=2,st+=nn) {
626 for(
int s=nn,t=0;s>=t;--s,++t,++st) {
628 double s0 = fp[s] * fq[t];
629 int iphase = s-t-p+q;
630 std::complex<double> s1 = s0 *
633 std::conj(phase[-iphase/2]));
640 Spq[st+1] = std::imag(s1);
645 Spq1[st] = -2.*std::imag(s1);
649 std::complex<double> s2 = s0 *
652 std::conj(phase[-iphase/2]));
654 Spq1[st] = -std::imag(s1) + std::imag(s2);
655 Spq[st+1] = std::imag(s1) + std::imag(s2);
691 Assert(
int(C.TMV_colsize()) >= (order1+1)*(order2+2)/2);
692 Assert(
int(C.TMV_rowsize()) >= (order2+1)*(order2+2)/2);
693 Assert(
int(bpsf.
size()) == (order3+1)*(order3+2)/2);
722 double B = sqrt(1-D);
724 std::vector<std::vector<std::vector<double> > > H(
725 order1+1,std::vector<std::vector<double> >(
726 order2+1,std::vector<double>(order3+1)));
729 for(
int u=0;u<=order3;++u) {
730 if (u>0) H[0][0][u] = -A * H[0][0][u-1];
731 for(
int p=1;p<=order2;++p)
732 H[0][p][u] = B*
sqrtn(p+u)/
sqrtn(p)*H[0][p-1][u];
734 for(
int s=0;s<order1;++s) {
736 for(
int p=1;p<=order2;++p)
737 H[s+1][p][0] = A*
sqrtn(p)*H[s][p-1][0]/
sqrtn(s+1);
738 for(
int u=1;u<=order3;++u) {
739 H[s+1][0][u] = B*
sqrtn(u)*H[s][0][u-1]/
sqrtn(s+1);
740 for(
int p=1;p<=order2;++p)
741 H[s+1][p][u] = (A*
sqrtn(p)*H[s][p-1][u] +
748 for(
int n=0;n<=order2;++n) {
749 for(
int p=n,q=0;p>=q;(p==q?++pq:pq+=2),--p,++q) {
752 double* Cpq =
TMV_ptr(C.col(pq));
753 double* Cpq1 = p>q?
TMV_ptr(C.col(pq+1)):0;
755 for(
int nn=0;nn<=order1;++nn) {
756 for(
int s=nn,t=0;s>=t;(s==t?++st:st+=2),--s,++t) {
763 const std::vector<double>& Hsp = H[s][p];
764 const std::vector<double>& Hsq = H[s][q];
765 const std::vector<double>& Htp = H[t][p];
766 const std::vector<double>& Htq = H[t][q];
768 int parity = (n+nn)%2;
769 for(
int upv=0;upv<=order3;++upv,uv0+=upv) {
770 if (upv % 2 != parity)
continue;
777 if (umv >= 0 && umv <= upv) {
789 double temp = Hsp[u]*Htq[v]*bpsfv[uv];
799 double tempr = Hsp[u]*Htq[v];
800 double tempi = tempr * bpsfv[uv+1];
817 if (pmq != 0 && umv <= upv) {
835 double tempr = Hsq[u]*Htp[v];
836 double tempi = tempr * bpsfv[uv+1];
851 if (umv > 0 && umv <= upv) {
863 double tempr = Hsp[v]*Htq[u];
864 double tempi = -tempr * bpsfv[uv+1];
881 if (smt != 0) Cpq[st+1] = Cpqst1;
884 if (smt != 0) Cpq1[st+1] = Cpq1st1;
888 Assert(st ==
int(C.TMV_colsize()));
891 Assert(pq ==
int(C.TMV_rowsize()));
void augmentMuTransformCols(double mu, int order, DMatrix &D)
void assignTo(BVec &bvec) const
virtual void assignTo(BVec &bvec) const =0
void applyPsf(const BVec &bpsf, BVec &b)
BVec & operator=(const AssignableToBVec &rhs)
void calculateGTransform(std::complex< double > g, int order1, int order2, DMatrix &S)
void applyG(std::complex< double > g, BVec &b)
afw::table::Key< double > sigma
void augmentZTransformCols(std::complex< double > z, int order, DMatrix &T)
void calculateZTransform(std::complex< double > z, int order1, int order2, DMatrix &T)
void setValues(const DVector &v)
void setSigma(double sigma)
void applyZ(std::complex< double > z, BVec &b)
void calculateThetaTransform(double theta, int order1, int order2, DBandMatrix &R)
void augmentMuTransformRows(double mu, int order, DMatrix &D)
Eigen::MatrixXd DBandMatrix
void augmentGTransformCols(std::complex< double > g, int order, DMatrix &S)
void applyMu(double mu, BVec &b)
afw::table::Key< double > b
void calculatePsfConvolve(const BVec &bpsf, int order1, int order2, double sigma, DMatrix &C)
void calculateMuTransform(double mu, int order1, int order2, DMatrix &D)
void applyTheta(double theta, BVec &b)