source: Sophya/trunk/Poubelle/DPC:FitsIOServer/Samba/lambuilder.cc@ 658

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

no message

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