/** returns the values of the Legendre polynomials * * The polynomials are \f$L_2\f$-orthogonal on \f$[-1, 1]\f$. They satisfy * the recursion \f$P_0 (x) = 1\f$, \f$P_1 (1) = x\f$, * \f$P_k (x) = ((2 k - 1) x P_{k-1} (x) - (k - 1) P_{k-2} (x)) / k\f$. * The \f$L_2\f$-norm of \f$P_k\f$ is \f$\sqrt {2 / (2 k + 1)}\f$. */ number LegendrePoly ( size_t k, ///< index of the polynomial, \f$k \ge 0\f$ number x ///< argument of the polynomial ) { if (k == 0) return 1; else if (k == 1) return x; return ((2 * k - 1) * x * LegendrePoly (k-1, x) - (k - 1) * LegendrePoly (k - 2, x)) / k; }
/** Calc isotropic reorientational eigenmode dynamics. * See JACS 2002, 124, 4522, eq. A14 * CAVEAT: omegaK-omegaL is not "just" the intra molecular angle there. */ void Action_Matrix::CalcIredMatrix(int frameNum) { v_iterator v2idx1 = vect2_.begin(); // Store length of IRED vectors in vect2 for (std::vector<DataSet_Vector*>::const_iterator Vtmp = IredVectors_.begin(); Vtmp != IredVectors_.end(); ++Vtmp) *(v2idx1++) = sqrt( (*Vtmp)->VXYZ(frameNum) * (*Vtmp)->VXYZ(frameNum) ); // Loop over all pairs of IRED vectors. DataSet_MatrixDbl::iterator mat = Mat_->begin(); v_iterator v1idx = Mat_->v1begin(); v2idx1 = vect2_.begin(); for (std::vector<DataSet_Vector*>::iterator Vtmp = IredVectors_.begin(); Vtmp != IredVectors_.end(); ++Vtmp) { double len1 = *v2idx1; v_iterator v2idx2 = v2idx1; for (std::vector<DataSet_Vector*>::iterator Vtmp2 = Vtmp; Vtmp2 != IredVectors_.end(); ++Vtmp2) { double len2 = *(v2idx2++); double legendre = LegendrePoly(order_, (*Vtmp)->VXYZ(frameNum) * (*Vtmp2)->VXYZ(frameNum) / (len1 * len2) ); *(mat++) += legendre; if (Vtmp == Vtmp2) *(v1idx++) += legendre; } ++v2idx1; } }
/** returns the values of the normalized Legendre polynomials * * The Legendre polynomials are \f$L_2\f$-orthogonal on \f$[-1, 1]\f$. * They satisfy the recursion \f$P_0 (x) = 1\f$, \f$P_1 (1) = x\f$, * \f$(n+1) P_k (x) = (2 k - 1) x P_{k-1} (x) - (k - 1) P_{n-2} (x)\f$. * The \f$L_2\f$-norm of \f$P_k\f$ is \f$\sqrt {2 / (2 k + 1)}\f$. * This function returns \f$\sqrt {(2 k + 1) / 2} P_k (x)\f$. */ number NormalizedLegendrePoly ( size_t k, ///< index of the polynomial, \f$k \ge 0\f$ number x ///< argument of the polynomial ) { return sqrt (((number) (2 * k + 1))) * LegendrePoly (k, x); }
void LegendreSynthesis(double *c, int mx, int my, float *image, int nx, int ny) { double *x; double *Px,*Qx; double *y; double *Py,*Qy; double *sum; int mp; int np; mp = mx*my; np = nx*ny; ///////////////////////////////////////////////////////////////////////// x = (double *)calloc(nx,sizeof(double)); Px = (double *)calloc(mx*nx,sizeof(double)); Qx = (double *)calloc(mx*nx,sizeof(double)); // set x for(int i=0; i<nx; i++) { x[i] = -(2.0/nx)*((nx-1)/2.0) + i*2.0/nx; } // initialization for(int i=0; i<nx; i++) { Px[i]=1.0; Qx[i]=0.0; } for(int q=1; q<mx; q++) LegendrePoly(Px+(q-1)*nx, Qx+(q-1)*nx, Px+q*nx, Qx+q*nx, x, nx, q); for(int q=0; q<mx; q++) for(int i=0; i<nx; i++) Px[q*nx + i] /= sqrt( 2. / (2.0*q+1) ); ///////////////////////////////////////////////////////////////////////// y = (double *)calloc(ny,sizeof(double)); Py = (double *)calloc(my*ny,sizeof(double)); Qy = (double *)calloc(my*ny,sizeof(double)); // set y for(int i=0; i<ny; i++) { y[i] = -(2.0/ny)*((ny-1)/2.0) + i*2.0/ny; } // initialization for(int i=0; i<ny; i++) { Py[i]=1.0; Qy[i]=0.0; } for(int r=1; r<my; r++) LegendrePoly(Py+(r-1)*ny, Qy+(r-1)*ny, Py+r*ny, Qy+r*ny, y, ny, r); for(int r=0; r<my; r++) for(int i=0; i<ny; i++) Py[r*ny + i] /= sqrt( 2. / (2.0*r+1) ); ///////////////////////////////////////////////////////////////////////// sum = (double *)calloc(mx*ny,sizeof(double)); for(int q=0; q<mx; q++) for(int y=0; y<ny; y++) for(int r=0; r<my; r++) sum[y*mx + q] += c[r*mx + q]*Py[r*ny + y]; for(int y=0; y<ny; y++) for(int x=0; x<nx; x++) for(int q=0; q<mx; q++) image[y*nx + x] += sum[y*mx + q]*Px[q*nx + x]; free(sum); free(x); free(y); free(Px); free(Qx); free(Py); free(Qy); }
double *LegendreAnalysis(float *image, int nx, int ny, int mx, int my) { double *x; double *Px,*Qx; double *y; double *Py,*Qy; double *c; // series coefficients ///////////////////////////////////////////////////////////////////////// c = (double *)calloc(mx*my,sizeof(double)); ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// x = (double *)calloc(nx,sizeof(double)); Px = (double *)calloc(mx*nx,sizeof(double)); Qx = (double *)calloc(mx*nx,sizeof(double)); // x is an array of nx real number going from -(nx-1.0)/nx to (nx-1.0)/nx for(int i=0; i<nx; i++) x[i] = -(nx-1.0)/nx + i*2.0/nx; // initialization for(int i=0; i<nx; i++) { Px[i]=1.0; Qx[i]=0.0; } for(int q=1; q<mx; q++) LegendrePoly(Px+(q-1)*nx, Qx+(q-1)*nx, Px+q*nx, Qx+q*nx, x, nx, q); for(int q=0; q<mx; q++) for(int i=0; i<nx; i++) Px[q*nx + i] /= sqrt( 2. / (2.0*q+1) ); ///////////////////////////////////////////////////////////////////////// y = (double *)calloc(ny,sizeof(double)); Py = (double *)calloc(my*ny,sizeof(double)); Qy = (double *)calloc(my*ny,sizeof(double)); // set y for(int i=0; i<ny; i++) y[i] = -(ny-1.0)/ny + i*2.0/ny; // initialization for(int i=0; i<ny; i++) { Py[i]=1.0; Qy[i]=0.0; } for(int r=1; r<my; r++) LegendrePoly(Py+(r-1)*ny, Qy+(r-1)*ny, Py+r*ny, Qy+r*ny, y, ny, r); for(int r=0; r<my; r++) for(int i=0; i<ny; i++) Py[r*ny + i] /= sqrt( 2. / (2.0*r+1) ); ///////////////////////////////////////////////////////////////////////// double *dum; dum = (double *)calloc(ny,sizeof(double)); for(int q=0; q<mx; q++) { for(int j=0; j<ny; j++) integral_1d(Px+q*nx, image+j*nx, nx, dum+j); for(int r=0; r<my; r++) integral_1d(Py+r*ny, dum, ny, c+r*mx+q); } free(dum); //////////////////////////////////////////////////////////////////////// free(x); free(y); free(Px); free(Qx); free(Py); free(Qy); return(c); }
float *LegendreSynthesis(double *c, int nx, int ny, int nz, int mx, int my, int mz) { double *x; double *Px,*Qx; double *y; double *Py,*Qy; double *z; double *Pz,*Qz; float *image; double *sum1; double *sum2; int mp; int np; mp = mx*my; np = nx*ny; ///////////////////////////////////////////////////////////////////////// x = (double *)calloc(nx,sizeof(double)); Px = (double *)calloc(mx*nx,sizeof(double)); Qx = (double *)calloc(mx*nx,sizeof(double)); // set x for(int i=0; i<nx; i++) { x[i] = -(2.0/nx)*((nx-1)/2.0) + i*2.0/nx; } // initialization for(int i=0; i<nx; i++) { Px[i]=1.0; Qx[i]=0.0; } for(int q=1; q<mx; q++) LegendrePoly(Px+(q-1)*nx, Qx+(q-1)*nx, Px+q*nx, Qx+q*nx, x, nx, q); for(int q=0; q<mx; q++) for(int i=0; i<nx; i++) Px[q*nx + i] /= sqrt( 2. / (2.0*q+1) ); ///////////////////////////////////////////////////////////////////////// y = (double *)calloc(ny,sizeof(double)); Py = (double *)calloc(my*ny,sizeof(double)); Qy = (double *)calloc(my*ny,sizeof(double)); // set y for(int i=0; i<ny; i++) { y[i] = -(2.0/ny)*((ny-1)/2.0) + i*2.0/ny; } // initialization for(int i=0; i<ny; i++) { Py[i]=1.0; Qy[i]=0.0; } for(int r=1; r<my; r++) LegendrePoly(Py+(r-1)*ny, Qy+(r-1)*ny, Py+r*ny, Qy+r*ny, y, ny, r); for(int r=0; r<my; r++) for(int i=0; i<ny; i++) Py[r*ny + i] /= sqrt( 2. / (2.0*r+1) ); ///////////////////////////////////////////////////////////////////////// z = (double *)calloc(nz,sizeof(double)); Pz = (double *)calloc(mz*nz,sizeof(double)); Qz = (double *)calloc(mz*nz,sizeof(double)); // set z for(int i=0; i<nz; i++) { z[i] = -(2.0/nz)*((nz-1)/2.0) + i*2.0/nz; } // initialization for(int i=0; i<nz; i++) { Pz[i]=1.0; Qz[i]=0.0; } for(int s=1; s<mz; s++) LegendrePoly(Pz+(s-1)*nz, Qz+(s-1)*nz, Pz+s*nz, Qz+s*nz, z, nz, s); for(int s=0; s<mz; s++) for(int i=0; i<nz; i++) Pz[s*nz + i] /= sqrt( 2. / (2.0*s+1) ); ///////////////////////////////////////////////////////////////////////// image = (float *)calloc(nx*ny*nz,sizeof(float)); sum1 = (double *)calloc(mx*my*nz,sizeof(double)); for(int q=0; q<mx; q++) for(int r=0; r<my; r++) for(int z=0; z<nz; z++) for(int s=0; s<mz; s++) sum1[z*mp + r*mx + q] += c[s*mp+r*mx+q]*Pz[s*nz + z]; sum2 = (double *)calloc(mx*ny*nz,sizeof(double)); for(int q=0; q<mx; q++) for(int z=0; z<nz; z++) for(int y=0; y<ny; y++) for(int r=0; r<my; r++) sum2[z*mx*ny + y*mx + q] += sum1[z*mp + r*mx + q]*Py[r*ny + y]; free(sum1); for(int z=0; z<nz; z++) for(int y=0; y<ny; y++) for(int x=0; x<nx; x++) for(int q=0; q<mx; q++) image[z*np + y*nx + x] += sum2[z*mx*ny + y*mx + q]*Px[q*nx + x]; free(sum2); free(x); free(y); free(z); free(Px); free(Qx); free(Py); free(Qy); free(Pz); free(Qz); return(image); }
double *LegendreAnalysis(float *image, int nx, int ny, int nz, int mx, int my, int mz) { double *x; double *Px,*Qx; double *y; double *Py,*Qy; double *z; double *Pz,*Qz; double *c; // series coefficients int mp; int np; np = nx*ny; mp = mx*my; ///////////////////////////////////////////////////////////////////////// c = (double *)calloc(mx*my*mz,sizeof(double)); ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// x = (double *)calloc(nx,sizeof(double)); Px = (double *)calloc(mx*nx,sizeof(double)); Qx = (double *)calloc(mx*nx,sizeof(double)); // x is an array of nx real number going from -(nx-1.0)/nx to (nx-1.0)/nx for(int i=0; i<nx; i++) x[i] = -(nx-1.0)/nx + i*2.0/nx; // initialization for(int i=0; i<nx; i++) { Px[i]=1.0; Qx[i]=0.0; } for(int q=1; q<mx; q++) LegendrePoly(Px+(q-1)*nx, Qx+(q-1)*nx, Px+q*nx, Qx+q*nx, x, nx, q); for(int q=0; q<mx; q++) for(int i=0; i<nx; i++) Px[q*nx + i] /= sqrt( 2. / (2.0*q+1) ); ///////////////////////////////////////////////////////////////////////// y = (double *)calloc(ny,sizeof(double)); Py = (double *)calloc(my*ny,sizeof(double)); Qy = (double *)calloc(my*ny,sizeof(double)); // set y for(int i=0; i<ny; i++) { y[i] = -(2.0/ny)*((ny-1)/2.0) + i*2.0/ny; } // initialization for(int i=0; i<ny; i++) { Py[i]=1.0; Qy[i]=0.0; } for(int r=1; r<my; r++) LegendrePoly(Py+(r-1)*ny, Qy+(r-1)*ny, Py+r*ny, Qy+r*ny, y, ny, r); for(int r=0; r<my; r++) for(int i=0; i<ny; i++) Py[r*ny + i] /= sqrt( 2. / (2.0*r+1) ); ///////////////////////////////////////////////////////////////////////// z = (double *)calloc(nz,sizeof(double)); Pz = (double *)calloc(mz*nz,sizeof(double)); Qz = (double *)calloc(mz*nz,sizeof(double)); // set z for(int i=0; i<nz; i++) { z[i] = -(2.0/nz)*((nz-1)/2.0) + i*2.0/nz; } // initialization for(int i=0; i<nz; i++) { Pz[i]=1.0; Qz[i]=0.0; } for(int s=1; s<mz; s++) LegendrePoly(Pz+(s-1)*nz, Qz+(s-1)*nz, Pz+s*nz, Qz+s*nz, z, nz, s); for(int s=0; s<mz; s++) for(int i=0; i<nz; i++) Pz[s*nz + i] /= sqrt( 2. / (2.0*s+1) ); ///////////////////////////////////////////////////////////////////////// double *dum1d; double *dum2d; dum1d = (double *)calloc(nz,sizeof(double)); dum2d = (double *)calloc(nz*ny,sizeof(double)); for(int q=0; q<mx; q++) { for(int j=0; j<ny; j++) for(int k=0; k<nz; k++) integral_1d(Px+q*nx, image+k*np+j*nx, nx, dum2d+k*ny+j); for(int r=0; r<my; r++) { for(int k=0; k<nz; k++) integral_1d(Py+r*ny, dum2d+k*ny, ny, dum1d+k); for(int s=0; s<mz; s++) integral_1d(Pz+s*nz, dum1d, nz, c+s*mp+r*mx+q); } } free(dum1d); free(dum2d); //////////////////////////////////////////////////////////////////////// free(x); free(y); free(z); free(Px); free(Qx); free(Py); free(Qy); free(Pz); free(Qz); return(c); }