00001 #ifndef EXPANDER_H
00002 #define EXPANDER_H
00003
00004 #include <vector>
00005 #include <complex>
00006 #include <iostream>
00007 #include "parametermap.h"
00008 #include "message.h"
00009 #include "histogram1d.h"
00010 #include "histogram3d.h"
00011 #include "harmonic_expansion.h"
00012 #include "sf.h"
00013 #include "constants.h"
00014 #include "utils.h"
00015 #include "tnt_array1d.h"
00016 #include "corr3d_histo.h"
00017 #include "corr3d_ylm.h"
00018 #include "sou3d_histo.h"
00019 #include "sou3d_ylm.h"
00020 #include "sou1d_histo.h"
00021 #include "linalg.h"
00022 #include "integratevec.h"
00023
00024 using namespace TNT;
00025 using namespace parameter;
00026 using namespace std;
00027
00028
00029
00030
00031
00032
00033
00034
00035 CCorrFtn3dSphr expand( const CCorrFtn3dHisto& corrin, const parameterMap m );
00036 CCorrFtn3dHisto recombine( const CCorrFtn3dSphr& corrin, const parameterMap m );
00037 CSourceFtn3dSphr<CSourceFtn1dHisto> expand( const CSourceFtn3dHisto& souin, const parameterMap m );
00038 CSourceFtn3dHisto recombine( const CSourceFtn3dSphr<CSourceFtn1dHisto>& souin, const parameterMap m );
00039
00040 template< class THisto1d >
00041 class CCart2SphrExpander {
00042
00043 public:
00044
00045
00046
00047 CCart2SphrExpander( void ):
00048 num_int_vec( 9 ), l_list( num_int_vec ),
00049 m_list( num_int_vec ), reim_list( num_int_vec ),
00050 mtx_list( num_int_vec ){}
00051
00052
00053
00054 int lmax;
00055 int ndata;
00056 int nr;
00057 bool generate_full_covmtx;
00058
00059 bool xflipflag;
00060 bool yflipflag;
00061 bool zflipflag;
00062 double symfactor;
00063
00064
00066 bool Read( const parameterMap& m ){
00067 CONST_CAST(lmax,int) = parameter::getI(m,"lmax",0);
00068 CONST_CAST(num_int_vec,int) = parameter::getI(m,"num_int_vec",9);
00069 CONST_CAST(generate_full_covmtx,bool) = parameter::getB(m,"generate_full_covmtx",false);
00070 return true;
00071 }
00072
00073
00075 bool Write( parameterMap& m ){
00076 parameter::set(m,"lmax",lmax);
00077 parameter::set(m,"num_int_vec",num_int_vec);
00078 parameter::set(m,"generate_full_covmtx",generate_full_covmtx);
00079 return true;
00080 }
00081
00082
00084 bool convert( const CHistogram3d& sou, CSphericalHarmonicExpansion< THisto1d >& targ, bool skip_odd_l=true ){
00085
00086
00087
00088
00089 targ.lmax=lmax;
00090 targ.skip_odd_l=skip_odd_l;
00091
00092 double dr=(sou.dx+sou.dy+sou.dz)/3.0;
00093 double rmax=std::min(std::min(sou.rightBinEdgeX(sou.nx),sou.rightBinEdgeY(sou.ny)),sou.rightBinEdgeZ(sou.nz));
00094 nr = iround<double>((rmax-dr/2.0)/dr);
00095 int lstep=1; if (skip_odd_l) lstep=2;
00096 for (int l=0; l<=lmax; l+=lstep){
00097 for (int m=0; m<=l; ++m){
00098 {
00099 CSphericalHarmonicBasisFunction key(l,m,true);
00100 THisto1d obj;
00101 obj.l=l;
00102 obj.m=m;
00103 obj.realpart=true;
00104 obj.redim(nr);
00105 obj.setFixedWidthBins(dr,dr/2);
00106 targ.insert(make_pair(key,obj));
00107 }
00108 if (m!=0) {
00109 CSphericalHarmonicBasisFunction key(l,m,false);
00110 THisto1d obj;
00111 obj.l=l;
00112 obj.m=m;
00113 obj.realpart=false;
00114 obj.redim(nr);
00115 obj.setFixedWidthBins(dr,dr/2);
00116 targ.insert(make_pair(key,obj));
00117 }
00118 }
00119 }
00120
00121 ndata = sou.ndata;
00122 setSymmetryFactorAndFlags( sou, skip_odd_l );
00123 cout << " Some CCart2SphrExpander properties"<<endl;
00124 cout << " dr: " << dr<< "; rmax: " <<rmax << endl;
00125 cout << " ndata: " << ndata<< "; size: " <<targ.size()<< "; size/num_int_vec+1: " << targ.size()/num_int_vec+1<< endl;
00126 cout << " num_int_vec = " << num_int_vec<<"; nr = "<<nr<<endl;
00127 cout << endl;
00128
00129 typename CSphericalHarmonicExpansion< THisto1d>::iterator chunk_start=targ.begin();
00130 typename CSphericalHarmonicExpansion< THisto1d>::iterator element;
00131 int ielement;
00132 int ichunk=0;
00133 while ( chunk_start!=targ.end() ){
00134 resizeLists(0);
00135 ielement=0;
00136 for ( element = chunk_start; (element!=targ.end())&&(ielement<num_int_vec); ++element ) {
00137 l_list.push_back(element->first.l);
00138 m_list.push_back(element->first.m);
00139 reim_list.push_back(element->first.realpart);
00140 ++ielement;
00141 }
00142 int chunk_size=l_list.size();
00143
00144 MESSAGE << " Building matrix group #" << ichunk << " chunk_size: "<<chunk_size<<ENDM_INFO;
00145 setUpMtxList( chunk_size, nr, ndata );
00146 buildCart2SphrMtx( sou, targ.begin()->second );
00147 MESSAGE << " Building CSphericalHarmonicExpansion ..." << ENDM_INFO;
00148 MESSAGE << " ielement l m Real" << ENDM_INFO;
00149 ielement=0;
00150 for ( element=chunk_start; (element!=targ.end())&&(ielement<num_int_vec); ++element ) {
00151 MESSAGE << " " << ielement << " "
00152 << l_list[ielement] <<" " << m_list[ielement] <<" "
00153 << reim_list[ielement] ;
00154 element->second.data = mtx_list[ielement]*sou.data;
00155 MESSAGE << " data done ... " ;
00156 element->second.covmtx = ErrorsToCovmtx(mtx_list[ielement],sou.uncert);
00157 MESSAGE << "covmtx done ... " ;
00158 element->second.syncUncert();
00159 MESSAGE << "uncert done ... " << ENDM_INFO;
00160 CONST_CAST(element->second.covmtx_is_active,bool)=true;
00161 ++ielement;
00162 }
00163 chunk_start=element;
00164 ++ichunk;
00165 }
00166 return true;
00167 }
00168
00169
00171 bool convert( const CSphericalHarmonicExpansion< THisto1d >& sou, CHistogram3d& targ ){
00172 nr=sou.begin()->second.ndata;
00173 double dr=sou.begin()->second.binWidth(0);
00174 double rmax=sou.begin()->second.leftBinEdge(nr);
00175 int Nx=nr;
00176 double x0=dr/2.0;
00177 if (!sou.skip_odd_l) {Nx=2*nr;x0=-rmax+dr/2.;}
00178
00179
00180
00181 for (typename CSphericalHarmonicExpansion<THisto1d>::const_iterator it=sou.begin();it!=sou.end();++it){
00182 if (!it->second.fixed_width_bins){
00183 MESSAGE << "CSphericalHarmonicExpansion term "
00184 << it->first.l<<" "<<it->first.m<<" "<<it->first.realpart
00185 << " does not have fixed width bins" << ENDM_FATAL;
00186 return false;
00187 }
00188 if (it->second.ndata!=nr){
00189 MESSAGE << "CSphericalHarmonicExpansion term "
00190 << it->first.l<<" "<<it->first.m<<" "<<it->first.realpart
00191 <<" does not have same number of bins as other terms: "
00192 << nr << " vs. "<<it->second.ndata<<ENDM_FATAL;
00193 return false;
00194 }
00195 if (abs(it->second.binWidth(0)-dr)>0.001*dr){
00196 MESSAGE << "CSphericalHarmonicExpansion term "
00197 << it->first.l<<" "<<it->first.m<<" "<<it->first.realpart
00198 <<" does not have same bin size as other terms: "
00199 << it->second.binWidth(0) << " vs. "<<dr <<ENDM_FATAL;
00200 return false;
00201 }
00202 }
00203
00204
00205 targ.nx=Nx;
00206 targ.ny=2*nr;
00207 targ.nz=2*nr;
00208 targ.dx=dr;
00209 targ.dy=dr;
00210 targ.dz=dr;
00211 targ.xoffset=x0;
00212 targ.yoffset=-rmax+dr/2.;
00213 targ.zoffset=-rmax+dr/2.;
00214 targ.redim(targ.nx*targ.ny*targ.nz);
00215 targ.ixzero=targ.findBin(targ.dx/2.,targ.dx,targ.xoffset);
00216 targ.iyzero=targ.findBin(targ.dy/2.,targ.dy,targ.yoffset);
00217 targ.izzero=targ.findBin(targ.dz/2.,targ.dz,targ.zoffset);
00218
00219 lmax=sou.lmax;
00220 ndata=targ.ndata;
00221
00222 setSymmetryFactorAndFlags( targ, sou.skip_odd_l );
00223 cout << " Unexpanding ... " << endl;
00224
00225 Array1D<double> data(ndata,0.0);
00226 Array1D<double> error(ndata,0.0);
00227 Array1D<bool> dud(ndata,false);
00228
00229 typename CSphericalHarmonicExpansion<THisto1d>::const_iterator chunk_start=sou.begin();
00230 typename CSphericalHarmonicExpansion<THisto1d>::const_iterator element;
00231 int ielement;
00232 int ichunk=0;
00233 while ( chunk_start!=sou.end() ){
00234
00235 resizeLists(0);
00236 ielement=0;
00237 for ( element=chunk_start; (element!=sou.end())&&(ielement<num_int_vec); ++element){
00238 l_list.push_back(element->first.l);
00239 m_list.push_back(element->first.m);
00240 reim_list.push_back(element->first.realpart);
00241 ++ielement;
00242 }
00243 int chunk_size=l_list.size();
00244
00245 MESSAGE << " Building matrix group #" << ichunk << " chunk_size: "<<chunk_size<<ENDM_INFO;
00246 setUpMtxList( chunk_size, ndata, nr );
00247 buildSphr2CartMtx( sou.begin()->second, targ );
00248 MESSAGE << " Building CHistogram3d ..." << ENDM_INFO;
00249 MESSAGE << " ielement l m Real" << ENDM_INFO;
00250 ielement=0;
00251 for ( element=chunk_start; (element!=sou.end())&&(ielement<num_int_vec); ++element ) {
00252 MESSAGE << " " << ielement << " "
00253 << l_list[ielement] <<" " << m_list[ielement] <<" "
00254 << reim_list[ielement] <<" "<<ENDM_INFO;
00255
00256 Array1D<double> tdat, terr;
00257 tdat=mtx_list[ielement]*(element->second.data);
00258 terr=CovmtxToErrors(mtx_list[ielement],element->second.covmtx);
00259
00260 for (int j=0;j<ndata;++j){
00261 data[j] += tdat[j];
00262 if (generate_full_covmtx) {
00263
00264 } else {
00265 error[j] = sqrt(error[j]*error[j]+terr[j]*terr[j]);
00266 }
00267 }
00268 ++ielement;
00269 }
00270 chunk_start=element;
00271 ++ichunk;
00272 }
00273
00274 for (int i=0;i<targ.nx;++i){
00275 for (int j=0;j<targ.ny;++j){
00276 for (int k=0;k<targ.nz;++k){
00277
00278 double len1,len2,len3,len4,len5,len6,len7,len8, maxlen;
00279 len1=length( targ.leftBinEdgeX(i)/2.0, targ.leftBinEdgeY(j)/2.0, targ.leftBinEdgeZ(k)/2.0 );
00280 len2=length( targ.rightBinEdgeX(i)/2.0, targ.leftBinEdgeY(j)/2.0, targ.leftBinEdgeZ(k)/2.0 );
00281 len3=length( targ.leftBinEdgeX(i)/2.0, targ.rightBinEdgeY(j)/2.0, targ.leftBinEdgeZ(k)/2.0 );
00282 len4=length( targ.leftBinEdgeX(i)/2.0, targ.leftBinEdgeY(j)/2.0, targ.rightBinEdgeZ(k)/2.0 );
00283 len5=length( targ.rightBinEdgeX(i)/2.0, targ.rightBinEdgeY(j)/2.0, targ.leftBinEdgeZ(k)/2.0 );
00284 len6=length( targ.rightBinEdgeX(i)/2.0, targ.leftBinEdgeY(j)/2.0, targ.rightBinEdgeZ(k)/2.0 );
00285 len7=length( targ.leftBinEdgeX(i)/2.0, targ.rightBinEdgeY(j)/2.0, targ.rightBinEdgeZ(k)/2.0 );
00286 len8=length( targ.rightBinEdgeX(i)/2.0, targ.rightBinEdgeY(j)/2.0, targ.rightBinEdgeZ(k)/2.0 );
00287 maxlen=MAXF(MAXF(MAXF(len1,len2),MAXF(len3,len4)),MAXF(MAXF(len5,len6),MAXF(len7,len8)));
00288 if (maxlen>sou.begin()->second.rightBinEdge(nr)) dud[targ.whatIndex(i,j,k)]=true;
00289 }
00290 }
00291 }
00292
00293 for (int i=0;i<ndata;++i){if (dud[i]) {data[i]=1.0;error[i]=1.0;}}
00294
00295 targ.data = data;
00296 targ.uncert = error;
00297 targ.covmtx_is_active=false;
00298 return true;
00299 }
00300
00301 private:
00302
00303
00304
00305 void resizeLists( int nSize ){
00306 l_list.resize( nSize );
00307 m_list.resize( nSize );
00308 reim_list.resize( nSize );
00309 mtx_list.resize( nSize );
00310 }
00311
00312
00313
00314 void setSymmetryFactorAndFlags( const CHistogram3d& sou, bool skip_odd_l ){
00315 symfactor = 1.0;
00316 xflipflag = false;
00317 yflipflag = false;
00318 zflipflag = false;
00319 if (skip_odd_l) {
00320
00321 if (sou.ixzero==0) {xflipflag=true;symfactor*=2.0;}
00322 if (sou.iyzero==0) {yflipflag=true;symfactor*=2.0;}
00323 if (sou.izzero==0) {zflipflag=true;symfactor*=2.0;}
00324 }
00325 MESSAGE << " Zero Bins are (" << sou.ixzero << ", "
00326 << sou.iyzero << ", " << sou.izzero
00327 << ") so setting CExpander symmetry factor to "
00328 <<symfactor<<ENDM_INFO;
00329 }
00330
00331
00332
00333 void setUpMtxList( int nSize, int nrows, int ncols ){
00334 mtx_list.resize(0);
00335 for (int i=0;i<nSize;++i){
00336 Array2D<double> temp(nrows,ncols,0.0);
00337 mtx_list.push_back(temp);
00338 }
00339 }
00340
00341
00342 void buildSphr2CartMtx( const CHistogram1d& souTerm, const CHistogram3d& targ ){
00343 double factor=SQRTFOURPI/targ.binVolume();
00344 double qmin, qmax;
00345 int l,m;
00346 bool reim;
00347
00348
00349 CIntegrateVector J;
00350 J.SetNDim(3);
00351 J.SetNumFunc(mtx_list.size());
00352 J.SetMaxPts(10000);
00353
00354 cout << " Radial bin counter: "<<flush;
00355 for (int n=0;n<nr;++n){
00356 rlo=souTerm.leftBinEdge(n);
00357 rhi=souTerm.rightBinEdge(n);
00358
00359 cout << n <<" "<<flush;
00360
00361 int iSmin=targ.ixzero;
00362 int iSmax=targ.nx;
00363
00364 for (int iS=iSmin;iS<iSmax;++iS){
00365
00366
00367 xlo=targ.midBinX(iS)-targ.dx/2.0;
00368 xhi=targ.midBinX(iS)+targ.dx/2.0;
00369
00370
00371 int iOmin=targ.iyzero;
00372 int iOmax=targ.ny;
00373
00374 for (int iO=iOmin;iO<iOmax;++iO){
00375
00376
00377 ylo=targ.midBinY(iO)-targ.dy/2.0;
00378 yhi=targ.midBinY(iO)+targ.dy/2.0;
00379
00380
00381 int iLmin=targ.izzero;
00382 int iLmax=targ.nz;
00383
00384 for (int iL=iLmin;iL<iLmax;++iL){
00385
00386
00387 zlo=targ.midBinZ(iL)-targ.dz/2.0;
00388 zhi=targ.midBinZ(iL)+targ.dz/2.0;
00389
00390 qmax=length(xhi,yhi,zhi);
00391 qmin=length(xlo,ylo,zlo);
00392
00393 if (((qmin<=souTerm.midBin(n))&&(qmax>=souTerm.midBin(n)))||
00394 ((qmin<=rhi)&&(qmax>=rhi))||
00395 ((qmin<=rlo)&&(qmax>=rlo))){
00396
00397
00398 J.SetLimits(0,xlo,xhi);
00399 J.SetLimits(1,ylo,yhi);
00400 J.SetLimits(2,zlo,zhi);
00401
00402
00403 J.Compute(this,sphr2CartMtxIntegrand);
00404
00405
00406 for (unsigned int ilist=0;ilist<mtx_list.size();++ilist){
00407 l=l_list[ilist];
00408 m=m_list[ilist];
00409 reim=reim_list[ilist];
00410
00411
00412 int a =targ.whatIndex( iS, iO, iL );
00413 int a_y =targ.whatIndex( iS, targ.flipBinY(iO), iL );
00414 int a_z =targ.whatIndex( iS, iO, targ.flipBinZ(iL) );
00415 int a_yz =targ.whatIndex( iS, targ.flipBinY(iO), targ.flipBinZ(iL) );
00416
00417 int a_x =targ.whatIndex( targ.flipBinX(iS), iO, iL );
00418 int a_xy =targ.whatIndex( targ.flipBinX(iS), targ.flipBinY(iO), iL );
00419 int a_xz =targ.whatIndex( targ.flipBinX(iS), iO, targ.flipBinZ(iL) );
00420 int a_xyz=targ.whatIndex( targ.flipBinX(iS), targ.flipBinY(iO), targ.flipBinZ(iL) );
00421
00422 double mtxelement = factor*J.GetResults(ilist);
00423 if (reim) {
00424
00425 mtx_list[ilist][a][n] = mtxelement;
00426 if (!yflipflag) mtx_list[ilist][a_y][n] = mtxelement;
00427 if (!zflipflag) mtx_list[ilist][a_z][n] = NEGONE_TO_THE(l+m) * mtxelement;
00428 if (!(yflipflag&&zflipflag)) mtx_list[ilist][a_yz][n] = NEGONE_TO_THE(l+m) * mtxelement;
00429 if (!xflipflag) mtx_list[ilist][a_x][n] = NEGONE_TO_THE(m) * mtxelement;
00430 if (!(xflipflag&&yflipflag)) mtx_list[ilist][a_xy][n] = NEGONE_TO_THE(m) * mtxelement;
00431 if (!(xflipflag&&zflipflag)) mtx_list[ilist][a_xz][n] = NEGONE_TO_THE(l) * mtxelement;
00432 if (!(xflipflag&&(yflipflag&&zflipflag))) mtx_list[ilist][a_xyz][n] = NEGONE_TO_THE(l) * mtxelement;
00433
00434 } else {
00435
00436 mtx_list[ilist][a][n] = mtxelement;
00437 if (!yflipflag) mtx_list[ilist][a_y][n] = -1.0 * mtxelement;
00438 if (!zflipflag) mtx_list[ilist][a_z][n] = NEGONE_TO_THE(l+m) * mtxelement;
00439 if (!(yflipflag&&zflipflag)) mtx_list[ilist][a_yz][n] = -NEGONE_TO_THE(l+m) * mtxelement;
00440 if (!xflipflag) mtx_list[ilist][a_x][n] = -NEGONE_TO_THE(m) * mtxelement;
00441 if (!(xflipflag&&yflipflag)) mtx_list[ilist][a_xy][n] = NEGONE_TO_THE(m) * mtxelement;
00442 if (!(xflipflag&&zflipflag)) mtx_list[ilist][a_xz][n] = -NEGONE_TO_THE(l) * mtxelement;
00443 if (!(xflipflag&&(yflipflag&&zflipflag))) mtx_list[ilist][a_xyz][n] = NEGONE_TO_THE(l) * mtxelement;
00444 }
00445 }
00446 }
00447 }
00448 }
00449 }
00450 }
00451 cout <<endl;
00452 }
00453
00454
00455
00456 void buildCart2SphrMtx( const CHistogram3d& sou, const CHistogram1d& targTerm ){
00457 double factor=1.0/SQRTFOURPI/targTerm.binWidth(0);
00458 double qmin, qmax;
00459 int l,m;
00460 bool reim;
00461
00462
00463 CIntegrateVector J;
00464 J.SetNDim(3);
00465 J.SetNumFunc(mtx_list.size());
00466 J.SetMaxPts(10000);
00467
00468 cout << " Radial bin counter: "<<flush;
00469 for (int n=0;n<nr;n++){
00470 rlo=targTerm.leftBinEdge(n);
00471 rhi=targTerm.rightBinEdge(n);
00472
00473 cout << n <<" "<<flush;
00474
00475 int iSmin=sou.ixzero;
00476 int iSmax=sou.nx;
00477
00478 for (int iS=iSmin;iS<iSmax;iS++){
00479
00480
00481 xlo=sou.midBinX(iS)-sou.dx/2.0;
00482 xhi=sou.midBinX(iS)+sou.dx/2.0;
00483
00484
00485 int iOmin=sou.iyzero;
00486 int iOmax=sou.ny;
00487
00488 for (int iO=iOmin;iO<iOmax;iO++){
00489
00490
00491 ylo=sou.midBinY(iO)-sou.dy/2.0;
00492 yhi=sou.midBinY(iO)+sou.dy/2.0;
00493
00494
00495 int iLmin=sou.izzero;
00496 int iLmax=sou.nz;
00497
00498 for (int iL=iLmin;iL<iLmax;iL++){
00499
00500
00501 zlo=sou.midBinZ(iL)-sou.dz/2.0;
00502 zhi=sou.midBinZ(iL)+sou.dz/2.0;
00503
00504 qmax=length(xhi,yhi,zhi);
00505 qmin=length(xlo,ylo,zlo);
00506
00507 if (((qmin<=targTerm.midBin(n))&&(qmax>=targTerm.midBin(n)))||
00508 ((qmin<=rhi)&&(qmax>=rhi))||
00509 ((qmin<=rlo)&&(qmax>=rlo))){
00510
00511
00512 J.SetLimits(0,xlo,xhi);
00513 J.SetLimits(1,ylo,yhi);
00514 J.SetLimits(2,zlo,zhi);
00515
00516
00517 J.Compute(this,cart2SphrMtxIntegrand);
00518
00519
00520 for (unsigned int ilist=0;ilist<mtx_list.size();ilist++){
00521 l=l_list[ilist];
00522 m=m_list[ilist];
00523 reim=reim_list[ilist];
00524
00525
00526 int a =sou.whatIndex( iS, iO, iL );
00527 int a_x =sou.whatIndex( sou.flipBinX(iS), iO, iL );
00528 int a_y =sou.whatIndex( iS, sou.flipBinY(iO), iL );
00529 int a_z =sou.whatIndex( iS, iO, sou.flipBinZ(iL) );
00530 int a_xy =sou.whatIndex( sou.flipBinX(iS), sou.flipBinY(iO), iL );
00531 int a_xz =sou.whatIndex( sou.flipBinX(iS), iO, sou.flipBinZ(iL) );
00532 int a_yz =sou.whatIndex( iS, sou.flipBinY(iO), sou.flipBinZ(iL) );
00533 int a_xyz=sou.whatIndex( sou.flipBinX(iS), sou.flipBinY(iO), sou.flipBinZ(iL) );
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547 double mtxelement = factor*J.GetResults(ilist);
00548 if (reim) {
00549
00550 mtx_list[ilist][n][a] += mtxelement;
00551 mtx_list[ilist][n][a_x] += NEGONE_TO_THE(m) * mtxelement;
00552 mtx_list[ilist][n][a_y] += mtxelement;
00553 mtx_list[ilist][n][a_z] += NEGONE_TO_THE(l+m) * mtxelement;
00554 mtx_list[ilist][n][a_xy] += NEGONE_TO_THE(m) * mtxelement;
00555 mtx_list[ilist][n][a_xz] += NEGONE_TO_THE(l) * mtxelement;
00556 mtx_list[ilist][n][a_yz] += NEGONE_TO_THE(l+m) * mtxelement;
00557 mtx_list[ilist][n][a_xyz] += NEGONE_TO_THE(l) * mtxelement;
00558
00559 } else {
00560
00561 mtx_list[ilist][n][a] += mtxelement;
00562 mtx_list[ilist][n][a_x] += -NEGONE_TO_THE(m) * mtxelement;
00563 mtx_list[ilist][n][a_y] += -1.0 * mtxelement;
00564 mtx_list[ilist][n][a_z] += NEGONE_TO_THE(l+m) * mtxelement;
00565 mtx_list[ilist][n][a_xy] += NEGONE_TO_THE(m) * mtxelement;
00566 mtx_list[ilist][n][a_xz] += -NEGONE_TO_THE(l) * mtxelement;
00567 mtx_list[ilist][n][a_yz] += -NEGONE_TO_THE(l+m) * mtxelement;
00568 mtx_list[ilist][n][a_xyz] += NEGONE_TO_THE(l) * mtxelement;
00569 }
00570
00571 }
00572
00573 }
00574
00575 }
00576
00577 }
00578
00579 }
00580
00581 }
00582
00583 cout <<endl;
00584
00585 }
00586
00587
00588
00589
00591 double rInner( double x, double y ){return sqrt(MAXF(0.,rlo*rlo-x*x-y*y));}
00592 double rOuter( double x, double y ){return sqrt(MAXF(0.,rhi*rhi-x*x-y*y));}
00593
00595
00596 static void cart2SphrMtxIntegrand(void* classptr, int* ndim, double* q, int* numfunc, double* f){
00597 CCart2SphrExpander<THisto1d> *cls = (CCart2SphrExpander<THisto1d>*)classptr;
00598 double qrad=cls->length(q[0],q[1],q[2]);
00599 double qfact;
00600 if (qrad<1e-6) qfact=0.0; else qfact=1.0/qrad/qrad;
00601 double_complex ylm;
00602 for (unsigned int il=0; il<cls->mtx_list.size(); ++il){
00603 int l=cls->l_list[il];
00604 int m=cls->m_list[il];
00605 bool reim=cls->reim_list[il];
00606 if ((qrad<=cls->rhi)&&(qrad>=cls->rlo)) {
00607 ylm=SpherHarmonics::Ylm(l,m,q[0],q[1],q[2]);
00608 if (reim) {f[il]=real(ylm)*qfact;}
00609 else {f[il]=-imag(ylm)*qfact;}
00610 } else {
00611 f[il]=0.0;
00612 }
00613 }
00614 }
00615
00617
00618 static void sphr2CartMtxIntegrand(void* classptr, int* ndim, double* q, int* numfunc, double* f){
00619 CCart2SphrExpander<THisto1d> *cls = (CCart2SphrExpander<THisto1d>*)classptr;
00620 double qrad=cls->length(q[0],q[1],q[2]);
00621 double_complex ylm;
00622 for (unsigned int il=0; il<cls->mtx_list.size(); ++il){
00623 int l=cls->l_list[il];
00624 int m=cls->m_list[il];
00625 bool reim=cls->reim_list[il];
00626 if ((qrad<=cls->rhi)&&(qrad>=cls->rlo)) {
00627 ylm=SpherHarmonics::Ylm(l,m,q[0],q[1],q[2]);
00628 if (m==0) {
00629 if (reim) {f[il]=real(ylm);}
00630 else {f[il]=0.0;}
00631 } else {
00632 if (reim) {f[il]=2.0*real(ylm);}
00633 else {f[il]=-2.0*imag(ylm);}
00634 }
00635 } else {
00636 f[il]=0.0;
00637 }
00638 }
00639 }
00640
00641
00643 double length( double qS, double qO, double qL ){return sqrt(qS*qS+qO*qO+qL*qL);}
00644 double lengthsqr( double qS, double qO, double qL ){return (qS*qS+qO*qO+qL*qL);}
00645
00646
00647
00648 int num_int_vec;
00649 vector< int > l_list;
00650 vector< int > m_list;
00651 vector< bool > reim_list;
00652 vector< Array2D< double > > mtx_list;
00653
00654 double xlo, xhi, ylo, yhi, zlo, zhi, rlo, rhi;
00655
00656 };
00657
00658 #endif