source: MML/trunk/machine/SOLEIL/common/naff/nafflib/complexe.c @ 4

Last change on this file since 4 was 4, checked in by zhangj, 11 years ago

Initial import--MML version from SOLEIL@2013

File size: 13.5 KB
Line 
1/* Astronomie et Systemes dynamiques                            */
2/* M. GASTINEAU  Bureau des Longitudes, Paris 15/07/98          */
3/* ensemble de fonctions inlines traitant uniquement les complexes */
4/* v0.97 M. GASTINEAU 15/02/99: ajout des fonctions trigonometrique*/
5/* v0.97 M. GASTINEAU 22/03/99: ajout de i_compl_powreel        */
6
7#include "modnaff.h"
8
9#ifndef __COMPLEXE_H
10#define __COMPLEXE_H
11#include "complexe.h"
12
13/*----------------IMPLEMENTATION--------------------------------*/
14
15/*----------------i_compl_cmplx---------------------------------*/
16/*Construit un complexe a partir de deux doubles(retourne c=a+i*b)*/
17/*--------------------------------------------------------------*/
18 void i_compl_cmplx(t_complexe *c, double a,double b)
19{
20 c->reel=a;
21 c->imag=b;
22}
23
24
25/*----------------module----------------------------------------*/
26/* retourne le module du nombre complexe c                      */
27/*--------------------------------------------------------------*/
28 double    i_compl_module(t_complexe c)
29{
30 return hypot(c.reel,c.imag);
31}
32
33 double    i_compl_angle(t_complexe c)
34{
35 /*return atan2(c.imag/module(c),c.reel/module(c));*/
36 return atan2(c.imag,c.reel);
37}
38
39/*----------------i_compl_add-----------------------------------*/
40/* addition de deux nombres complexes c1 et c2 : c1+c2          */
41/*--------------------------------------------------------------*/
42 t_complexe i_compl_add(const t_complexe c1,const t_complexe c2)
43{
44 t_complexe c;
45 i_compl_cmplx(&c, c1.reel+c2.reel,c1.imag+c2.imag);
46 return c;
47}
48
49/*----------------i_compl_padd----------------------------------*/
50/* addition de deux nombres complexes c1 et c2 : c1+=c2         */
51/*--------------------------------------------------------------*/
52 void i_compl_padd(t_complexe *c1,t_complexe *c2)
53{
54 c1->reel += c2->reel;
55 c1->imag += c2->imag;
56}
57
58/*----------------i_compl_paddconst-----------------------------*/
59/* addition de deux nombres complexes c1 et c2 : c1+=c2         */
60/*--------------------------------------------------------------*/
61 void i_compl_paddconst(t_complexe *c1,t_complexe c2)
62{
63 c1->reel += c2.reel;
64 c1->imag += c2.imag;
65}
66
67/*----------------i_compl_mul----------------------------------*/
68/* multiplication de deux nombres complexes c1 et c2 : c1*c2   */
69/*-------------------------------------------------------------*/
70 t_complexe i_compl_mul(const t_complexe c1,const t_complexe c2)
71{
72 t_complexe c;
73 i_compl_cmplx(&c, c1.reel*c2.reel-c1.imag*c2.imag,c1.reel*c2.imag+c1.imag*c2.reel);
74 return c;
75}
76
77/*----------------i_compl_pmul---------------------------------*/
78/* multiplication de deux nombres complexes c1 et c2 : c1*=c2  */
79/*-------------------------------------------------------------*/
80 void i_compl_pmul(t_complexe *c1,t_complexe *c2)
81{
82 double creel=c1->reel;
83 c1->reel=creel*c2->reel-c1->imag*c2->imag;
84 c1->imag =creel*c2->imag+c1->imag*c2->reel;
85}
86
87/*----------------i_compl_muldoubl-----------------------------*/
88/* multiplication d'un double c1 d'un nombre complexe c2: c1*c2*/
89/*-------------------------------------------------------------*/
90 t_complexe i_compl_muldoubl(const double c1, const t_complexe c2)
91{
92 t_complexe c;
93 c.reel = c1*c2.reel;
94 c.imag = c1*c2.imag;
95 return c;
96}
97
98/*----------------i_compl_pmuldoubl----------------------------*/
99/* multiplication d'un double c1 d'un nombre complexe c2: c2*=c1*/
100/*-------------------------------------------------------------*/
101 void i_compl_pmuldoubl(t_complexe *c2, double* const c1)
102{
103 c2->reel *= *c1;
104 c2->imag *= *c1;
105}
106
107/*----------------i_compl_pdivdoubl----------------------------*/
108/* division d'un double c1 d'un nombre complexe c2: c2/=c1     */
109/*-------------------------------------------------------------*/
110 void i_compl_pdivdoubl(t_complexe *c2, double *c1)
111{
112 c2->reel /= *c1;
113 c2->imag /= *c1;
114}
115
116/*----------------i_compl_conj---------------------------------*/
117/*retourne le conjugue de c1                                   */
118/*-------------------------------------------------------------*/
119 t_complexe i_compl_conj(t_complexe *c1)
120{
121 t_complexe c;
122 i_compl_cmplx(&c, c1->reel, - (c1->imag) );
123 return c;
124}
125
126/*----------------i_compl_pdiv---------------------------------*/
127/* division de deux complexes : c1/=c2                         */
128/*-------------------------------------------------------------*/
129 void i_compl_pdiv(t_complexe * const c1,const t_complexe * const c2)
130{
131        double ratio, den;
132        double abr, abi, cr;
133   
134        if( (abr = c2->reel) < 0.)
135                abr = - abr;
136        if( (abi = c2->imag) < 0.)
137                abi = - abi;
138        if( abr <= abi )
139                {
140                ratio = (double)c2->reel / c2->imag ;
141                den = c2->imag * (1 + ratio*ratio);
142                cr = (c1->reel*ratio + c1->imag) / den;
143                c1->imag = (c1->imag*ratio - c1->reel) / den;
144                }
145
146        else
147                {
148                ratio = (double)c2->imag / c2->reel ;
149                den = c2->reel * (1 + ratio*ratio);
150                cr = (c1->reel + c1->imag*ratio) / den;
151                c1->imag = (c1->imag - c1->reel*ratio) / den;
152                }
153        c1->reel = cr;
154}
155
156/*----------------i_compl_div2d--------------------------------*/
157/* division d'un reel par un complexe c1/(c2_r+i*c2_i)         */
158/*-------------------------------------------------------------*/
159t_complexe i_compl_div2d(const double c1, 
160                                       const double c2_r, 
161                                       const double c2_i)
162{
163        register double ratio, den;
164        register double abr, abi;
165    t_complexe zres;
166   
167        if( (abr = c2_r) < 0.)
168                abr = - abr;
169        if( (abi = c2_i) < 0.)
170                abi = - abi;
171        if( abr <= abi )
172                {
173                ratio = (double)c2_r / c2_i ;
174                den = c2_i * (1 + ratio*ratio);
175                zres.reel = (c1*ratio) / den;
176                zres.imag =  - c1 / den;
177                }
178
179        else
180                {
181                ratio = (double)c2_i / c2_r ;
182                den = c2_r * (1 + ratio*ratio);
183                zres.reel = c1 / den;
184                zres.imag =  (- c1*ratio) / den;
185                }
186    return zres;
187}
188
189/*----------------i_compl_div4d--------------------------------*/
190/* division de deux complexes : (c1_r+i*c1_i)/(c2_r+i*c2_i)    */
191/*-------------------------------------------------------------*/
192t_complexe i_compl_div4d(register const double c1_r,register const double c1_i,
193                                       register const double  c2_r,register const double c2_i)
194{
195        register double ratio, den;
196        register double abr, abi;
197    t_complexe zres;
198   
199        if( (abr = c2_r) < 0.)
200                abr = - abr;
201        if( (abi = c2_i) < 0.)
202                abi = - abi;
203        if( abr <= abi )
204                {
205                ratio = (double)c2_r / c2_i ;
206                den = c2_i * (1 + ratio*ratio);
207                zres.reel = (c1_r*ratio + c1_i) / den;
208                zres.imag = (c1_i*ratio - c1_r) / den;
209                }
210
211        else
212                {
213                ratio = (double)c2_i / c2_r ;
214                den = c2_r * (1 + ratio*ratio);
215                zres.reel = (c1_r + c1_i*ratio) / den;
216                zres.imag = (c1_i - c1_r*ratio) / den;
217                }
218 return zres; 
219}
220
221/*----------------i_compl_div----------------------------------*/
222/* division de deux complexes : c1/c2                          */
223/*-------------------------------------------------------------*/
224t_complexe i_compl_div(const t_complexe c1,const t_complexe c2)
225{
226 t_complexe c=c1;
227 i_compl_pdiv(&c,&c2);
228 return c;
229}
230
231
232/*----------------i_compl_pow2d--------------------------------*/
233/*retourne la puissance (p_r+i*p_i)**b                         */
234/*-------------------------------------------------------------*/
235t_complexe i_compl_pow2d(const double p_r, const double p_i,int n)
236{
237        register unsigned long u;
238        register double t;
239        register double q_r=1,q_i=0,x_r,x_i;
240    t_complexe zq;
241   
242        if(n == 0)
243                goto done;
244        if(n < 0)
245                {
246                n = -n;
247                zq = i_compl_div2d(1,p_r,p_i);
248                x_r = zq.reel;
249                x_i = zq.imag;
250                }
251        else
252                {
253                x_r = p_r;
254                x_i = p_i;
255                }
256
257        for(u = n; ; )
258                {
259                if(u & 01)
260                        {
261                        t = q_r * x_r - q_i * x_i;
262                        q_i = q_r * x_i + q_i * x_r;
263                        q_r = t;
264                        }
265                if(u >>= 1)
266                        {
267                        t = x_r * x_r - x_i * x_i;
268                        x_i = 2 * x_r * x_i;
269                        x_r = t;
270                        }
271                else
272                        break;
273                }
274 done:
275        zq.reel=q_r;
276        zq.imag=q_i;
277        return zq;
278}
279
280
281/*----------------i_compl_powreel------------------------------*/
282/*retourne la puissance a**b avec b reel                       */
283/*-------------------------------------------------------------*/
284/* v0.97 M. GASTINEAU 22/03/99: ajout de i_compl_powreel       */
285t_complexe i_compl_powreel(const t_complexe z,double p_dK)
286{
287 double dMod = pow(i_compl_module(z),p_dK);
288 double dAngle = p_dK*i_compl_angle(z);
289 t_complexe zRes;
290 zRes.reel=dMod*cos(dAngle);
291 zRes.imag=dMod*sin(dAngle);
292 return zRes;
293}
294
295/*----------------i_compl_pow----------------------------------*/
296/*retourne la puissance a**b                                   */
297/*-------------------------------------------------------------*/
298 t_complexe i_compl_pow(const t_complexe a,int n)
299{
300#if 1
301        unsigned long u;
302        double t;
303        t_complexe q={1.0, 0.0}, x;
304
305        if(n == 0)
306                goto done;
307        if(n < 0)
308                {
309                n = -n;
310                x.reel = 1.0;
311                x.imag=0.0;
312                i_compl_pdiv(&x, &a);
313                }
314        else
315                {
316                x.reel = a.reel;
317                x.imag = a.imag;
318                }
319
320        for(u = n; ; )
321                {
322                if(u & 01)
323                        {
324                        t = q.reel * x.reel - q.imag * x.imag;
325                        q.imag = q.reel * x.imag + q.imag * x.reel;
326                        q.reel = t;
327                        }
328                if(u >>= 1)
329                        {
330                        t = x.reel * x.reel - x.imag * x.imag;
331                        x.imag = 2 * x.reel * x.imag;
332                        x.reel = t;
333                        }
334                else
335                        break;
336                }
337 done:
338        return q;
339#else
340        t_complexe q;
341
342        if(n == 0)
343        {
344         q.reel=1;
345         q.imag=0;
346        }
347        else
348        {
349         double dpow=pow(i_compl_module(a),n);
350         double anglea=i_compl_angle(a);
351         q.reel=dpow*cos(anglea*n);
352         q.imag=dpow*sin(anglea*n);
353        }
354        return q;
355#endif /*0*/
356}
357
358/*----------------expcomplexe-----------------------------------*/
359/* calcule et retourne exp(c1)                                  */
360/*--------------------------------------------------------------*/
361/* v0.96 M. GASTINEAU 04/09/98 : ajout */
362t_complexe i_compl_exp(t_complexe c1)
363{
364 t_complexe r;
365 double expx;
366 expx = exp(c1.reel);
367 r.reel = expx * cos(c1.imag);
368 r.imag = expx * sin(c1.imag);
369 return r;
370}
371
372
373/*----------------i_compl_psub----------------------------------*/
374/* soustrait de deux nombres complexes c1 et c2 : c1-=c2        */
375/*--------------------------------------------------------------*/
376/*v0.96 M. GASTINEAU 01/12/98 : ajout */
377void i_compl_psub(t_complexe *c1,t_complexe *c2) 
378{
379 c1->reel -= c2->reel;
380 c1->imag -= c2->imag;
381}
382
383/*----------------i_compl_sub----------------------------------*/
384/* soustrait de deux nombres complexes c1 et c2 : c1-c2        */
385/*-------------------------------------------------------------*/
386/*v0.96 M. GASTINEAU 01/12/98 : ajout */
387t_complexe i_compl_sub(t_complexe c1,t_complexe c2)
388{
389 t_complexe c;
390 c.reel = c1.reel - c2.reel;
391 c.imag = c1.imag - c2.imag;
392 return c;
393}
394
395
396/*----------------i_compl_cos----------------------------------*/
397/* retourne le cosinus de c1 (cos x  cosh y  -  i sin x sinh y)*/ 
398/*-------------------------------------------------------------*/
399/* v0.97 M. GASTINEAU 15/02/99: ajout */
400t_complexe i_compl_cos(t_complexe c1)
401{
402 t_complexe c;
403 c.reel = cos(c1.reel)*cosh(c1.imag);
404 c.imag = -sin(c1.reel)*sinh(c1.imag);
405 return c;
406}
407
408/*----------------i_compl_sin----------------------------------*/
409/* retourne le sinus de c1 (= sin x  cosh y  +  i cos x sinh y)*/
410/*-------------------------------------------------------------*/
411/* v0.97 M. GASTINEAU 15/02/99: ajout */
412t_complexe i_compl_sin(t_complexe c1)
413{
414 t_complexe c;
415 c.reel = sin(c1.reel)*cosh(c1.imag);
416 c.imag = cos(c1.reel)*sinh(c1.imag);
417 return c;
418}
419
420/*----------------i_compl_cosh---------------------------------*/
421/* retourne le cosinus hyperbolique de c1                      */
422/* (= cosh x  cos y  +  i sinh x sin y)                        */
423/*-------------------------------------------------------------*/
424/* v0.97 M. GASTINEAU 15/02/99: ajout */
425t_complexe i_compl_cosh(t_complexe c1)
426{
427 t_complexe c;
428 c.reel = cosh(c1.reel)*cos(c1.imag);
429 c.imag = sinh(c1.reel)*sin(c1.imag);
430 return c;
431}
432
433/*----------------i_compl_sinh---------------------------------*/
434/* retourne le sinus hyperbolique de c1                        */
435/* (= sinh x  cos y  +  i cosh x sin y)                        */
436/*-------------------------------------------------------------*/
437/* v0.97 M. GASTINEAU 15/02/99: ajout */
438t_complexe i_compl_sinh(t_complexe c1)
439{
440 t_complexe c;
441 c.reel = sinh(c1.reel)*cos(c1.imag);
442 c.imag = cosh(c1.reel)*sin(c1.imag);
443 return c;
444}
445
446/*----------------i_compl_tan----------------------------------*/
447/* retourne la tangente de c1                                  */
448/*-------------------------------------------------------------*/
449/* v0.97 M. GASTINEAU 15/02/99: ajout */
450t_complexe i_compl_tan(t_complexe c1)
451{
452 t_complexe c;
453 double u2=2.E0*c1.reel;
454 double v2=2.E0*c1.imag;
455 double denom=cos(u2)+cosh(v2);
456 c.reel = sin(u2)/denom;
457 c.imag = sinh(v2)/denom;
458 return c;
459}
460
461/*----------------i_compl_tanh---------------------------------*/
462/* retourne la tangente hyperbolique de c1                     */
463/*-------------------------------------------------------------*/
464/* v0.97 M. GASTINEAU 15/02/99: ajout */
465t_complexe i_compl_tanh(t_complexe c1)
466{
467 t_complexe c;
468 double u2=2.E0*c1.reel;
469 double v2=2.E0*c1.imag;
470 double denom=cos(u2)+cosh(v2);
471 c.reel = sinh(u2)/denom;
472 c.imag = sin(v2)/denom;
473 return c;
474}
475
476/*----------------i_compl_log----------------------------------*/
477/* retourne le logarithme de c1                                */
478/*-------------------------------------------------------------*/
479/* v0.97 M. GASTINEAU 15/02/99: ajout */
480t_complexe i_compl_log(t_complexe c1)
481{
482 t_complexe c;
483 c.reel = log(i_compl_module(c1));
484 c.imag = i_compl_angle(c1);
485 return c;
486}
487
488/*----------------i_compl_log10--------------------------------*/
489/* retourne le logarithme  base 10 de c1                       */
490/*-------------------------------------------------------------*/
491/* v0.97 M. GASTINEAU 15/02/99: ajout */
492t_complexe i_compl_log10(t_complexe c1)
493{
494 t_complexe c;
495 double norm=log(10);
496 c.reel = log(i_compl_module(c1))/norm;
497 c.imag = i_compl_angle(c1)/norm;
498 return c;
499}
500
501#endif
Note: See TracBrowser for help on using the repository browser.