31 namespace afwGeom = lsst::afw::geom;
35 namespace algorithms {
71 Assert(
int(psi.rowsize()) >= (order+1)*(order+2)/2);
72 Assert(psi.colsize() == z.size());
73 if (coeff)
Assert(psi.colsize() == coeff->size());
79 double* rsqit = rsq.ptr();
80 double* psi00it = psi.ptr();
81 const std::complex<double>* zit = z.cptr();
82 const int zsize = z.size();
83 for(
int i=0;i<zsize;++i) {
87 if (coeff) psi.col(0) *= DiagMatrixViewOf(*coeff);
103 psi.col(1) = 2. * DiagMatrixViewOf(zr) * psi.col(0);
104 psi.col(2) = -2. * DiagMatrixViewOf(zi) * psi.col(0);
106 for(
int N=2,k=3;N<=order;++N) {
112 psi.col(k) = sqrt(1./N) * DiagMatrixViewOf(zr) * psi.col(k-N);
113 psi.col(k) += sqrt(1./N) * DiagMatrixViewOf(zi) * psi.col(k-N+1);
114 psi.col(k+1) = -sqrt(1./N) * DiagMatrixViewOf(zi) * psi.col(k-N);
115 psi.col(k+1) += sqrt(1./N) * DiagMatrixViewOf(zr) * psi.col(k-N+1);
121 psi.colRange(k,k+N-1) =
122 DiagMatrixViewOf(rsq) * psi.colRange(k-2*N-1,k-N-2);
123 psi.colRange(k,k+N-1) -= (N-1.) * psi.colRange(k-2*N-1,k-N-2);
125 for(
int m=N-2,p=N-1,q=1;
m>=0;--p,++q,
m-=2) {
128 psi.col(k) /= sqrt(pq);
129 if (q > 1) psi.col(k) -= sqrt(1.-(N-1.)/pq)*psi.col(k+2-4*N);
132 psi.colRange(k,k+2) /= sqrt(pq);
134 psi.colRange(k,k+2) -=
135 sqrt(1.-(N-1.)/pq)*psi.colRange(k+2-4*N,k+4-4*N);
148 double zi = std::imag(z);
150 psi(1) = 2. * zr * psi(0);
151 psi(2) = -2. * zi * psi(0);
153 for(
int N=2,k=3;N<=order;++N) {
154 psi(k) = sqrt(1./N) * zr * psi(k-N);
155 psi(k) += sqrt(1./N) * zi * psi(k-N+1);
156 psi(k+1) = -sqrt(1./N) * zi * psi(k-N);
157 psi(k+1) += sqrt(1./N) * zr * psi(k-N+1);
160 psi.subVector(k,k+N-1) = rsq * psi.subVector(k-2*N-1,k-N-2);
161 psi.subVector(k,k+N-1) -= (N-1.) * psi.subVector(k-2*N-1,k-N-2);
162 for(
int m=N-2,p=N-1,q=1;m>=0;--p,++q,m-=2) {
166 if (q > 1) psi(k) -= sqrt(1.-(N-1.)/pq)*psi(k+2-4*N);
169 psi.subVector(k,k+2) /= sqrt(pq);
171 psi.subVector(k,k+2) -=
172 sqrt(1.-(N-1.)/pq)*psi.subVector(k+2-4*N,k+4-4*N);
181 Assert(
int(psi.rowsize()) >= (order+3)*(order+4)/2);
182 Assert(psi.colsize() == z.size());
188 double* rsqit = rsq.ptr();
189 const std::complex<double>* zit = z.cptr();
190 const int zsize = z.size();
191 for(
int i=0;i<zsize;++i) {
197 for(
int N=order+1,k=N*(N+1)/2;N<=order+2;++N) {
198 psi.col(k) = sqrt(1./N) * DiagMatrixViewOf(zr) * psi.col(k-N);
199 psi.col(k) += sqrt(1./N) * DiagMatrixViewOf(zi) * psi.col(k-N+1);
200 psi.col(k+1) = -sqrt(1./N) * DiagMatrixViewOf(zi) * psi.col(k-N);
201 psi.col(k+1) += sqrt(1./N) * DiagMatrixViewOf(zr) * psi.col(k-N+1);
204 psi.colRange(k,k+N-1) =
205 DiagMatrixViewOf(rsq) * psi.colRange(k-2*N-1,k-N-2);
206 psi.colRange(k,k+N-1) -= (N-1.) * psi.colRange(k-2*N-1,k-N-2);
207 for(
int m=N-2,p=N-1,q=1;m>=0;--p,++q,m-=2) {
210 psi.col(k) /= sqrt(pq);
211 if (q > 1) psi.col(k) -= sqrt(1.-(N-1.)/pq)*psi.col(k+2-4*N);
214 psi.colRange(k,k+2) /= sqrt(pq);
216 psi.colRange(k,k+2) -=
217 sqrt(1.-(N-1.)/pq)*psi.colRange(k+2-4*N,k+4-4*N);
245 Assert(
int(psi.TMV_rowsize()) >= (order+1)*(order+2)/2);
246 Assert(psi.TMV_colsize() == z.size());
247 if (coeff)
Assert(psi.TMV_colsize() == coeff->size());
254 double* psi00it =
TMV_ptr(psi);
255 const std::complex<double>* zit =
TMV_cptr(z);
256 const int zsize = z.size();
257 for(
int i=0;i<zsize;++i) {
261 if (coeff) psi.col(0).array() = coeff->array() * psi.col(0).array();
277 psi.col(1).array() = zr.array() * psi.col(0).array();
278 psi.col(2).array() = (-zi).array() * psi.col(0).array();
282 for(
int N=2,k=3;N<=order;++N) {
288 psi.col(k).array() = zr.array() * psi.col(k-N).array();
289 psi.col(k).array() += zi.array() * psi.col(k-N+1).array();
290 psi.col(k+1).array() = zr.array() * psi.col(k-N+1).array();
291 psi.col(k+1).array() -= zi.array() * psi.col(k-N).array();
292 double sqrt_1_N = sqrt(1./N);
293 psi.col(k) *= sqrt_1_N;
294 psi.col(k+1) *= sqrt_1_N;
303 for(
int m=N-2,p=N-1,q=1;m>=0;--p,++q,m-=2) {
306 psi.col(k) /= sqrt(pq);
307 if (q > 1) psi.col(k) -= sqrt(1.-(N-1.)/pq)*psi.col(k+2-4*N);
322 Assert(
int(psi.TMV_rowsize()) >= (order+3)*(order+4)/2);
323 Assert(psi.TMV_colsize() == z.size());
330 const std::complex<double>* zit =
TMV_cptr(z);
331 const int zsize = z.size();
332 for(
int i=0;i<zsize;++i) {
338 for(
int N=order+1,k=N*(N+1)/2;N<=order+2;++N) {
339 psi.col(k).array() = zr.array() * psi.col(k-N).array();
340 psi.col(k).array() += zi.array() * psi.col(k-N+1).array();
341 psi.col(k+1).array() = zr.array() * psi.col(k-N+1).array();
342 psi.col(k+1).array() -= zi.array() * psi.col(k-N).array();
343 double sqrt_1_N = sqrt(1./N);
344 psi.col(k) *= sqrt_1_N;
345 psi.col(k+1) *= sqrt_1_N;
351 for(
int m=N-2,p=N-1,q=1;m>=0;--p,++q,m-=2) {
354 psi.col(k) /= sqrt(pq);
355 if (q > 1) psi.col(k) -= sqrt(1.-(N-1.)/pq)*psi.col(k+2-4*N);
372 Assert(
int(Gx.TMV_colsize()) == (order1+1)*(order1+2)/2);
373 Assert(
int(Gx.TMV_rowsize()) == (order2+1)*(order2+2)/2);
376 for(
int n=0,k=0;n<=order2;++n) for(int p=n,q=0;p>=q;--p,++q,++k) {
386 if (q>0 && n<=order1+1) Gx(k-n-2,k) = sqrt(dp)/2.;
387 if (n+1<=order1) Gx(k+n+1,k) = -sqrt(dp+1.)/2.;
389 if (n<=order1+1) Gx(k-n,k) = sqrt(dp);
390 if (q>0 && n<=order1+1) Gx(k-n-2,k) = sqrt(dq)/2.;
391 if (n+1<=order1) Gx(k+n+1,k) = -sqrt(dp+1.)/2.;
392 if (n+1<=order1) Gx(k+n+3,k) = -sqrt(dq+1.);
393 if (q>0 && n<=order1+1) Gx(k-n-1,k+1) = sqrt(dq)/2.;
394 if (n+1<=order1) Gx(k+n+2,k+1) = -sqrt(dp+1.)/2.;
396 if (n<=order1+1) Gx(k-n,k) = sqrt(dp)/2.;
397 if (q>0 && n<=order1+1) Gx(k-n-2,k) = sqrt(dq)/2.;
398 if (n+1<=order1) Gx(k+n+1,k) = -sqrt(dp+1.)/2.;
399 if (n+1<=order1) Gx(k+n+3,k) = -sqrt(dq+1.)/2.;
400 if (n<=order1+1) Gx(k-n+1,k+1) = sqrt(dp)/2.;
401 if (q>0 && n<=order1+1) Gx(k-n-1,k+1) = sqrt(dq)/2.;
402 if (n+1<=order1) Gx(k+n+2,k+1) = -sqrt(dp+1.)/2.;
403 if (n+1<=order1) Gx(k+n+4,k+1) = -sqrt(dq+1.)/2.;
411 Assert(
int(Gy.TMV_colsize()) == (order1+1)*(order1+2)/2);
412 Assert(
int(Gy.TMV_rowsize()) == (order2+1)*(order2+2)/2);
415 for(
int n=0,k=0;n<=order2;++n) for(int p=n,q=0;p>=q;--p,++q,++k) {
425 if (q>0 && n<=order1+1) Gy(k-n-1,k) = -sqrt(dp)/2.;
426 if (n+1<=order1) Gy(k+n+2,k) = sqrt(dp+1.)/2.;
428 if (q>0 && n<=order1+1) Gy(k-n-1,k) = -sqrt(dq)/2.;
429 if (n+1<=order1) Gy(k+n+2,k) = sqrt(dp+1.)/2.;
430 if (n<=order1+1) Gy(k-n,k+1) = -sqrt(dp);
431 if (q>0 && n<=order1+1) Gy(k-n-2,k+1) = sqrt(dq)/2.;
432 if (n+1<=order1) Gy(k+n+1,k+1) = -sqrt(dp+1.)/2.;
433 if (n+1<=order1) Gy(k+n+3,k+1) = sqrt(dq+1.);
435 if (n+1<=order1) Gy(k-n+1,k) = sqrt(dp)/2.;
436 if (q>0 && n<=order1+1) Gy(k-n-1,k) = -sqrt(dq)/2.;
437 if (n+1<=order1) Gy(k+n+2,k) = sqrt(dp+1.)/2.;
438 if (n+1<=order1) Gy(k+n+4,k) = -sqrt(dq+1.)/2.;
439 if (n<=order1+1) Gy(k-n,k+1) = -sqrt(dp)/2.;
440 if (q>0 && n<=order1+1) Gy(k-n-2,k+1) = sqrt(dq)/2.;
441 if (n+1<=order1) Gy(k+n+1,k+1) = -sqrt(dp+1.)/2.;
442 if (n+1<=order1) Gy(k+n+3,k+1) = sqrt(dq+1.)/2.;
451 Assert(
int(Gg1.TMV_colsize()) == (order1+1)*(order1+2)/2);
452 Assert(
int(Gg1.TMV_rowsize()) == (order2+1)*(order2+2)/2);
455 for(
int n=0,k=0;n<=order2;++n) for(int p=n,q=0;p>=q;--p,++q,++k) {
467 if (q>1 && n<=order1+2) Gg1(k-2*n-3,k) = sqrt(dp*(dp-1.))/2.;
468 if (n+2<=order1) Gg1(k+2*n+3,k) = -sqrt((dp+1.)*(dp+2.))/2.;
470 if (p>1 && n<=order1+2) Gg1(k-2*n-1,k) = sqrt(dp*(dp-1.))/2.;
471 if (q>1 && n<=order1+2) Gg1(k-2*n-3,k) = sqrt(dq*(dq-1.))/2.;
472 if (n+2<=order1) Gg1(k+2*n+3,k) = -sqrt((dp+1.)*(dp+2.))/2.;
473 if (n+2<=order1) Gg1(k+2*n+5,k) = -sqrt((dq+1.)*(dq+2.))/2.;
474 if (p>1 && n<=order1+2) Gg1(k-2*n,k+1) = -sqrt(dp*(dp-1.))/2.;
475 if (q>1 && n<=order1+2) Gg1(k-2*n-2,k+1) = sqrt(dq*(dq-1.))/2.;
476 if (n+2<=order1) Gg1(k+2*n+4,k+1) = -sqrt((dp+1)*(dp+2.))/2.;
477 if (n+2<=order1) Gg1(k+2*n+6,k+1) = sqrt((dq+1)*(dq+2.))/2.;
479 if (n<=order1+2) Gg1(k-2*n+1,k) = sqrt(dp*(dp-1.));
480 if (q>1 && n<=order1+2) Gg1(k-2*n-3,k) = sqrt(dq*(dq-1.))/2.;
481 if (n+2<=order1) Gg1(k+2*n+3,k) = -sqrt((dp+1.)*(dp+2.))/2.;
482 if (n+2<=order1) Gg1(k+2*n+7,k) = -sqrt((dq+1.)*(dq+2.));
483 if (q>1 && n<=order1+2) Gg1(k-2*n-2,k+1) = sqrt(dq*(dq-1.))/2.;
484 if (n+2<=order1) Gg1(k+2*n+4,k+1) = -sqrt((dp+1.)*(dp+2.))/2.;
486 if (n<=order1+2) Gg1(k-2*n+1,k) = sqrt(dp*(dp-1.))/2.;
487 if (q>1 && n<=order1+2) Gg1(k-2*n-3,k) = sqrt(dq*(dq-1.))/2.;
488 if (n+2<=order1) Gg1(k+2*n+3,k) = -sqrt((dp+1.)*(dp+2.))/2.;
489 if (n+2<=order1) Gg1(k+2*n+7,k) = -sqrt((dq+1.)*(dq+2.))/2.;
490 if (n<=order1+2) Gg1(k-2*n+2,k+1) = sqrt(dp*(dp-1.))/2.;
491 if (q>1 && n<=order1+2) Gg1(k-2*n-2,k+1) = sqrt(dq*(dq-1.))/2.;
492 if (n+2<=order1) Gg1(k+2*n+4,k+1) = -sqrt((dp+1.)*(dp+2.))/2.;
493 if (n+2<=order1) Gg1(k+2*n+8,k+1) = -sqrt((dq+1.)*(dq+2.))/2.;
502 Assert(
int(Gg2.TMV_colsize()) == (order1+1)*(order1+2)/2);
503 Assert(
int(Gg2.TMV_rowsize()) == (order2+1)*(order2+2)/2);
506 for(
int n=0,k=0;n<=order2;++n) for(int p=n,q=0;p>=q;--p,++q,++k) {
518 if (q>1 && n<=order1+2) Gg2(k-2*n-2,k) = -sqrt(dp*(dp-1.))/2.;
519 if (n+2<=order1) Gg2(k+2*n+4,k) = sqrt((dp+1.)*(dp+2.))/2.;
521 if (p>1 && n<=order1+2) Gg2(k-2*n,k) = -sqrt(dp*(dp-1.))/2.;
522 if (q>1 && n<=order1+2) Gg2(k-2*n-2,k) = -sqrt(dq*(dq-1.))/2.;
523 if (n+2<=order1) Gg2(k+2*n+4,k) = sqrt((dp+1.)*(dp+2.))/2.;
524 if (n+2<=order1) Gg2(k+2*n+6,k) = sqrt((dq+1.)*(dq+2.))/2.;
525 if (p>1 && n<=order1+2) Gg2(k-2*n-1,k+1) = -sqrt(dp*(dp-1.))/2.;
526 if (q>1 && n<=order1+2) Gg2(k-2*n-3,k+1) = sqrt(dq*(dq-1.))/2.;
527 if (n+2<=order1) Gg2(k+2*n+3,k+1) = -sqrt((dp+1.)*(dp+2.))/2.;
528 if (n+2<=order1) Gg2(k+2*n+5,k+1) = sqrt((dq+1.)*(dq+2.))/2.;
530 if (q>1 && n<=order1+2) Gg2(k-2*n-2,k) = -sqrt(dq*(dq-1.))/2.;
531 if (n+2<=order1) Gg2(k+2*n+4,k) = sqrt((dp+1.)*(dp+2.))/2.;
532 if (n<=order2+2) Gg2(k-2*n+1,k+1) = -sqrt(dp*(dp-1.));
533 if (q>1 && n<=order1+2) Gg2(k-2*n-3,k+1) = sqrt(dq*(dq-1.))/2.;
534 if (n+2<=order1) Gg2(k+2*n+3,k+1) = -sqrt((dp+1.)*(dp+2.))/2.;
535 if (n+2<=order1) Gg2(k+2*n+7,k+1) = sqrt((dq+1.)*(dq+2.));
537 Gg2(k-2*n+2,k) = sqrt(dp*(dp-1.))/2.;
538 if (q>1 && n<=order1+2) Gg2(k-2*n-2,k) = -sqrt(dq*(dq-1.))/2.;
539 if (n+2<=order1) Gg2(k+2*n+4,k) = sqrt((dp+1.)*(dp+2.))/2.;
540 if (n+2<=order1) Gg2(k+2*n+8,k) = -sqrt((dq+1.)*(dq+2.))/2.;
541 if (n<=order2+2) Gg2(k-2*n+1,k+1) = -sqrt(dp*(dp-1.))/2.;
542 if (q>1 && n<=order1+2) Gg2(k-2*n-3,k+1) = sqrt(dq*(dq-1.))/2.;
543 if (n+2<=order1) Gg2(k+2*n+3,k+1) = -sqrt((dp+1.)*(dp+2.))/2.;
544 if (n+2<=order1) Gg2(k+2*n+7,k+1) = sqrt((dq+1.)*(dq+2.))/2.;
553 Assert(
int(Gmu.TMV_colsize()) == (order1+1)*(order1+2)/2);
554 Assert(
int(Gmu.TMV_rowsize()) == (order2+1)*(order2+2)/2);
557 for(
int n=0,k=0;n<=order2;++n) for(int p=n,q=0;p>=q;--p,++q,++k) {
566 if (q>0 && n<=order1+2) Gmu(k-2*n-1,k) = sqrt(dp*dq);
567 if (n+2<=order1) Gmu(k+2*n+5,k) = -sqrt((dp+1.)*(dq+1.));
568 if (n<=order1) Gmu(k,k) = -1.;
570 if (q>0 && n<=order1+2) Gmu(k-2*n,k+1) = sqrt(dp*dq);
571 if (n+2<=order1) Gmu(k+2*n+6,k+1) = -sqrt((dp+1.)*(dq+1.));
572 if (n<=order1) Gmu(k+1,k+1) = -1.;
581 Assert(
int(Gth.TMV_colsize()) == (order1+1)*(order1+2)/2);
582 Assert(
int(Gth.TMV_rowsize()) == (order2+1)*(order2+2)/2);
585 for(
int n=0,k=0;n<=order2;++n) for(int p=n,q=0;p>=q;--p,++q,++k) {
592 if (p>q && n<=order1) {
593 Gth(k+1,k) = (dp-dq);
594 Gth(k,k+1) = -(dp-dq);
void setupGg1(DMatrix &Gg1, int order1, int order2)
void setupGth(DMatrix &Gth, int order1, int order2)
Eigen::Block< CDVector, Eigen::Dynamic, 1 > CDVectorView
void makePsi(DMatrix &psi, CDVectorView z, int order, const DVector *coeff=0)
#define TMV_colRange(m, j1, j2)
void setupGx(DMatrix &Gx, int order1, int order2)
void setupGy(DMatrix &Gy, int order1, int order2)
void setupGg2(DMatrix &Gg2, int order1, int order2)
void augmentPsi(DMatrix &psi, CDVectorView z, int order)
void setupGmu(DMatrix &Gmu, int order1, int order2)