source: Sophya/trunk/SophyaLib/Samba/lambuilder.cc@ 518

Last change on this file since 518 was 518, checked in by ansari, 26 years ago

Introduction de SpherePosition and SphereCoordSys, and Initiator for module Samba - Reza+I. Grivell 26/10/99

File size: 7.3 KB
RevLine 
[461]1#include <math.h>
2#include "lambuilder.h"
3#include <iostream.h>
4
[518]5double Lambda2Builder::bignorm = 1.e268; // = 1e-20*1.d288
6
[461]7Lambda2Builder::Lambda2Builder(){}
8
9Lambda2Builder::Lambda2Builder(double theta, int lmax, int mmax):
10 LambdaBuilder(theta, lmax, mmax){
11 fact_=0;
12 w_=0;
13 ix_=0;
14}
15
16Lambda2Builder::Lambda2Builder(const Lambda2Builder& lb):
17 LambdaBuilder(lb){
18 fact_=lb.fact_;
19 w_=lb.w_;
20 ix_=lb.ix_;
21}
22
23void Lambda2Builder::reset(){
24 LambdaBuilder::reset();
25 fact_=0;
26 w_=0;
27 ix_=0;
28}
29
30double Lambda2Builder::lam2lmp(int flip){
31 if (flip < 0){
32 return -fact_*par_lm_*(w_+ix_);
33 } else{
34 return lam2lmp();
35 }
36}
37
38double Lambda2Builder::lam2lmp(int l, int m){
39 if ((l <= lmax_ && l==l_+1 && m==m_) ||
40 (m <= mmax_ && m==m_+1 && l==m && l_==lmax_)){
41 step();
42 return lam2lmp();
43 } else if (l==l_ && m==m_){
44 return lam2lmp();
45 } else if ((l < l_ && m <= mmax_) || (m == m_ && l < l_) || m<m_){
46 reset();
47 while (l != l_ || m != m_){
48 step();
49 }
50 return lam2lmp();
51 } else if (l <= lmax_ && m <= mmax_ && (m > m_ || (m==m_ && l > l_))){
52 while (l != l_ || m != m_){
53 step();
54 }
55 return lam2lmp();
56 } else{
57 return -1;
58 }
59}
60
61double Lambda2Builder::lam2lmp(int l, int m, int flip){
62
63 if ((l <= lmax_ && l==l_+1 && m==m_) ||
64 (m <= mmax_ && m==m_+1 && l==m && l_==lmax_)){
65 step();
66 return lam2lmp(flip);
67 } else if (l==l_ && m==m_){
68 return lam2lmp(flip);
69 } else if ((l < l_ && m <= mmax_) || (m == m_ && l < l_) || m<m_){
70 reset();
71 while (l != l_ || m != m_){
72 step();
73 }
74 return lam2lmp(flip);
75 } else if (l <= lmax_ && m <= mmax_ && (m > m_ || (m==m_ && l > l_))){
76 while (l != l_ || m != m_){
77 step();
78 }
79 return lam2lmp(flip);
80 } else{
81 return -1;
82 }
83}
84
85double Lambda2Builder::lam2lmm(int flip){
86 if (flip < 0){
87 return -fact_*par_lm_*(w_-ix_);
88 } else{
89 return lam2lmp();
90 }
91}
92
93double Lambda2Builder::lam2lmm(int l, int m){
94 if ((l <= lmax_ && l==l_+1 && m==m_) ||
95 (m <= mmax_ && m==m_+1 && l==m && l_==lmax_)){
96 step();
97 return lam2lmm();
98 } else if (l==l_ && m==m_){
99 return lam2lmm();
100 } else if ((l < l_ && m <= mmax_) || (m == m_ && l < l_) || m<m_){
101 reset();
102 while (l != l_ || m != m_){
103 step();
104 }
105 return lam2lmm();
106 } else if (l <= lmax_ && m <= mmax_ && (m > m_ || (m==m_ && l > l_))){
107 while (l != l_ || m != m_){
108 step();
109 }
110 return lam2lmm();
111 } else{
112 return -1;
113 }
114}
115
116double Lambda2Builder::lam2lmm(int l, int m, int flip){
117 if ((l <= lmax_ && l==l_+1 && m==m_) ||
118 (m <= mmax_ && m==m_+1 && l==m && l_==lmax_)){
119 step();
120 return lam2lmm(flip);
121 } else if (l==l_ && m==m_){
122 return lam2lmm(flip);
123 } else if ((l < l_ && m <= mmax_) || (m == m_ && l < l_) || m<m_){
124 reset();
125 while (l != l_ || m != m_){
126 step();
127 }
128 return lam2lmm(flip);
129 } else if (l <= lmax_ && m <= mmax_ && (m > m_ || (m==m_ && l > l_))){
130 while (l != l_ || m != m_){
131 step();
132 }
133 return lam2lmm(flip);
134 } else{
135 return -1;
136 }
137}
138
139void Lambda2Builder::step(){
140 if (l_>=lmax_ && m_>=mmax_){return;}
141 if (l_==lmax_){//move on to the next m and calculate l=m
142 LambdaBuilder::step();
143 if (l_>=2){
144 w_=-2.*(m_*(2.*m_+1.)-m_*(m_-1.)/sth_/sth_)*lamlm_;
145 ix_=-2.*m_*(m_-1.)*cth_/sth_/sth_*lamlm_;
146 fact_=sqrt(1./(m_-1.)/m_/(m_+1.)/(m_+2.));
147 } else{
148 w_=0;
149 ix_=0;
150 fact_=0;
151 }
152 } else{
153 double lastlamlm=lamlm_;
154 LambdaBuilder::step();
155 if (l_>=2){
156 w_=-2.*(-((l_-m_*m_)/sth_/sth_+.5*l_*(l_-1.))*lamlm_+
157 (l_+m_)*cth_/sth_/sth_*sqrt((2.*l_+1.)/(2.*l_-1.)*(l_-m_)/(l_+m_))*
158 lastlamlm);
159 ix_=-2.*m_/sth_/sth_*((l_-1.)*cth_*lamlm_-(l_+m_)*
160 sqrt((2.*l_+1.)/(2.*l_-1.)*(l_-m_)/(l_+m_))*
161 lastlamlm);
162 fact_=sqrt(1./(l_-1.)/l_/(l_+1.)/(l_+2.));
163 } else{
164 w_=0;
165 ix_=0;
166 fact_=0;
167 }
168 }
169}
170
171LambdaBuilder::LambdaBuilder(){}
172
173LambdaBuilder::LambdaBuilder(double theta, int lmax, int mmax){
174 lmax_=lmax;
175 mmax_=mmax;
176 l_=0;
177 m_=0;
178 lamlm_=1. / sqrt(4.*M_PI);
179 cth_=cos(theta);
180 sth_=sin(theta);
181 lammm_=1. / sqrt(4.*M_PI) *bignorm;
182 par_lm_=1.;
183 lam_0_=0.;
184 lam_1_=1./bignorm;
185 a_rec_=sqrt(3.);
186 b_rec_=0;
187 fm2_=0;
188}
189
190LambdaBuilder::LambdaBuilder(const LambdaBuilder& lb){
191 lmax_=lb.lmax_;
192 mmax_=lb.mmax_;
193 l_=lb.l_;
194 m_=lb.m_;
195 lamlm_=lb.lamlm_;
196 cth_=lb.cth_;
197 sth_=lb.sth_;
198 lammm_=lb.lammm_;
199 par_lm_=lb.par_lm_;
200 lam_0_=lb.lam_0_;
201 lam_1_=lb.lam_1_;
202 a_rec_=lb.a_rec_;
203 b_rec_=lb.b_rec_;
204 fm2_=lb.fm2_;
205}
206
207void LambdaBuilder::reset(){
208 l_=0;
209 m_=0;
210 lamlm_=1. / sqrt(4.*M_PI);
211 lammm_=1. / sqrt(4.*M_PI) *bignorm;
212 par_lm_=1.;
213 lam_0_=0.;
214 lam_1_=1./bignorm;
215 a_rec_=sqrt(3.);
216 b_rec_=0;
217 fm2_=0;
218}
219
220double LambdaBuilder::lamlm(int flip){
221 if (flip < 0){
222 return par_lm_*lamlm();
223 } else{
224 return lamlm();
225 }
226}
227
228double LambdaBuilder::lamlm(int l, int m){
229 if ((l <= lmax_ && l==l_+1 && m==m_) ||
230 (m <= mmax_ && m==m_+1 && l==m && l_==lmax_)){
231 step();
232 return lamlm();
233 } else if (l==l_ && m==m_){
234 return lamlm_;
235 } else if ((l < l_ && m <= mmax_) || (m == m_ && l < l_) || m<m_){
236 reset();
237 while (l != l_ || m != m_){
238 step();
239 }
240 return lamlm();
241 } else if (l <= lmax_ && m <= mmax_ && (m > m_ || (m==m_ && l > l_))){
242 while (l != l_ || m != m_){
243 step();
244 }
245 return lamlm();
246 } else{
247 return -1;
248 }
249}
250
251double LambdaBuilder::lamlm(int l, int m, int flip){
252 if ((l <= lmax_ && l==l_+1 && m==m_) ||
253 (m <= mmax_ && m==m_+1 && l==m && l_==lmax_)){
254 step();
255 return lamlm(flip);
256 } else if (l==l_ && m==m_){
257 return lamlm(flip);
258 } else if ((l < l_ && m <= mmax_) || (m == m_ && l < l_) || m<m_){
259 reset();
260 while (l != l_ || m != m_){
261 step();
262 }
263 return lamlm(flip);
264 } else if (l <= lmax_ && m <= mmax_ && (m > m_ || (m==m_ && l > l_))){
265 while (l != l_ || m != m_){
266 step();
267 }
268 return lamlm(flip);
269 } else{
270 return -1;
271 }
272}
273
274void LambdaBuilder::step(){
275 /*-----------------------------------------------------------------------
276 computes lambda_lm(theta) in an optimal fashion
277 looping over m
278 For example, if nlmax =3 and nmmax=3 the order is
279 (l,m)=(0,0),(1,0),(2,0),(3,0),(1,1),(2,1),(3,1),(2,2),(3,2),(3,3)
280 -----------------------------------------------------------------------*/
281 if (l_>=lmax_ && m_>=mmax_){return;}
282 if (l_==lmax_){//move on to the next m and calculate l=m
283 m_=m_+1;
284 l_=m_;
285 double f2m = 2. * m_;
286 fm2_ = ((double) m_)*m_;
287 par_lm_ = 1.; // = (-1)^(l+m)
288 if (m_ >= 1) { /* lambda_0_0 for m>0*/
289 lammm_ = - lammm_ * sth_ * sqrt( (f2m+1.)/ f2m );
290 }
291 lamlm_ = lammm_ / bignorm;
292 lam_0_ = 0.;
293 lam_1_ = 1. / bignorm; /*small number --> to avoid overflow*/
294 a_rec_ = sqrt( f2m + 3.);
295 b_rec_ = 0.;
296 } else{
297 l_=l_+1;
298 par_lm_ = - par_lm_; /* = (-1)^(l+m)*/
299 double lam_2 = (cth_ * lam_1_ - b_rec_ * lam_0_) * a_rec_;
300 // cout<<lam_2<<" "<<cth_<<" "<<lam_1_<<" "<<b_rec_<<" "<<lam_0_<<" "<<a_rec_<<endl;
301 //actual lambda_lm (small and big numbers cancel out)
302 lamlm_ = lam_2 * lammm_;
303
304 b_rec_ = 1. / a_rec_;
305 double fl2 = (l_+1.)*(l_+1.);
306 a_rec_ = sqrt( (4. * fl2 - 1.) / (fl2-fm2_) );
307 // cout <<fl2<<" "<<fm2<<endl;
308 lam_0_ = lam_1_;
309 lam_1_ = lam_2;
310 }
311}
Note: See TracBrowser for help on using the repository browser.