NEURON
zfunc.c
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 
3 /**************************************************************************
4 **
5 ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved.
6 **
7 ** Meschach Library
8 **
9 ** This Meschach Library is provided "as is" without any express
10 ** or implied warranty of any kind with respect to this software.
11 ** In particular the authors shall not be liable for any direct,
12 ** indirect, special, incidental or consequential damages arising
13 ** in any way from use of the software.
14 **
15 ** Everyone is granted permission to copy, modify and redistribute this
16 ** Meschach Library, provided:
17 ** 1. All copies contain this copyright notice.
18 ** 2. All modified copies shall carry a notice stating who
19 ** made the last modification and the date of such modification.
20 ** 3. No charge is made for this software or works derived from it.
21 ** This clause shall not be construed as constraining other software
22 ** distributed on the same medium as this software, nor is a
23 ** distribution fee considered a charge.
24 **
25 ***************************************************************************/
26 
27 /*
28  Elementary functions for complex numbers
29  -- if not already defined
30 */
31 
32 #include "zmatrix.h"
33 #include <math.h>
34 
35 static char rcsid[] = "zfunc.c,v 1.1 1997/12/04 17:56:05 hines Exp";
36 
37 #ifndef COMPLEX_H
38 
39 #ifndef zmake
40 /* zmake -- create complex number real + i*imag */
41 complex zmake(real,imag)
42 double real, imag;
43 {
44  complex w; /* == real + i*imag */
45 
46  w.re = real; w.im = imag;
47  return w;
48 }
49 #endif
50 
51 #ifndef zneg
52 /* zneg -- returns negative of z */
54 complex z;
55 {
56  z.re = - z.re;
57  z.im = - z.im;
58 
59  return z;
60 }
61 #endif
62 
63 #ifndef zabs
64 /* zabs -- returns |z| */
65 double zabs(z)
66 complex z;
67 {
68  Real x, y, tmp;
69  int x_expt, y_expt;
70 
71  /* Note: we must ensure that overflow does not occur! */
72  x = ( z.re >= 0.0 ) ? z.re : -z.re;
73  y = ( z.im >= 0.0 ) ? z.im : -z.im;
74  if ( x < y )
75  {
76  tmp = x;
77  x = y;
78  y = tmp;
79  }
80  if ( x == 0.0 ) /* then y == 0.0 as well */
81  return 0.0;
82  x = frexp(x,&x_expt);
83  y = frexp(y,&y_expt);
84  y = ldexp(y,y_expt-x_expt);
85  tmp = sqrt(x*x+y*y);
86 
87  return ldexp(tmp,x_expt);
88 }
89 #endif
90 
91 #ifndef zadd
92 /* zadd -- returns z1+z2 */
93 complex zadd(z1,z2)
94 complex z1, z2;
95 {
96  complex z;
97 
98  z.re = z1.re + z2.re;
99  z.im = z1.im + z2.im;
100 
101  return z;
102 }
103 #endif
104 
105 #ifndef zsub
106 /* zsub -- returns z1-z2 */
107 complex zsub(z1,z2)
108 complex z1, z2;
109 {
110  complex z;
111 
112  z.re = z1.re - z2.re;
113  z.im = z1.im - z2.im;
114 
115  return z;
116 }
117 #endif
118 
119 #ifndef zmlt
120 /* zmlt -- returns z1*z2 */
121 complex zmlt(z1,z2)
122 complex z1, z2;
123 {
124  complex z;
125 
126  z.re = z1.re * z2.re - z1.im * z2.im;
127  z.im = z1.re * z2.im + z1.im * z2.re;
128 
129  return z;
130 }
131 #endif
132 
133 #ifndef zinv
134 /* zmlt -- returns 1/z */
136 complex z;
137 {
138  Real x, y, tmp;
139  int x_expt, y_expt;
140 
141  if ( z.re == 0.0 && z.im == 0.0 )
142  error(E_SING,"zinv");
143  /* Note: we must ensure that overflow does not occur! */
144  x = ( z.re >= 0.0 ) ? z.re : -z.re;
145  y = ( z.im >= 0.0 ) ? z.im : -z.im;
146  if ( x < y )
147  {
148  tmp = x;
149  x = y;
150  y = tmp;
151  }
152  x = frexp(x,&x_expt);
153  y = frexp(y,&y_expt);
154  y = ldexp(y,y_expt-x_expt);
155 
156  tmp = 1.0/(x*x + y*y);
157  z.re = z.re*tmp*ldexp(1.0,-2*x_expt);
158  z.im = -z.im*tmp*ldexp(1.0,-2*x_expt);
159 
160  return z;
161 }
162 #endif
163 
164 #ifndef zdiv
165 /* zdiv -- returns z1/z2 */
166 complex zdiv(z1,z2)
167 complex z1, z2;
168 {
169  return zmlt(z1,zinv(z2));
170 }
171 #endif
172 
173 #ifndef zsqrt
174 /* zsqrt -- returns sqrt(z); uses branch with Re sqrt(z) >= 0 */
176 complex z;
177 {
178  complex w; /* == sqrt(z) at end */
179  Real alpha;
180 
181  alpha = sqrt(0.5*(fabs(z.re) + zabs(z)));
182  if (alpha!=0)
183  {
184  if (z.re>=0.0)
185  {
186  w.re = alpha;
187  w.im = z.im / (2.0*alpha);
188  }
189  else
190  {
191  w.re = fabs(z.im)/(2.0*alpha);
192  w.im = ( z.im >= 0 ) ? alpha : - alpha;
193  }
194  }
195  else
196  w.re = w.im = 0.0;
197 
198  return w;
199 }
200 #endif
201 
202 #ifndef zexp
203 /* zexp -- returns exp(z) */
205 complex z;
206 {
207  complex w; /* == exp(z) at end */
208  Real r;
209 
210  r = exp(z.re);
211  w.re = r*cos(z.im);
212  w.im = r*sin(z.im);
213 
214  return w;
215 }
216 #endif
217 
218 #ifndef zlog
219 /* zlog -- returns log(z); uses principal branch with -pi <= Im log(z) <= pi */
221 complex z;
222 {
223  complex w; /* == log(z) at end */
224 
225  w.re = log(zabs(z));
226  w.im = atan2(z.im,z.re);
227 
228  return w;
229 }
230 #endif
231 
232 #ifndef zconj
234 complex z;
235 {
236  complex w; /* == conj(z) */
237 
238  w.re = z.re;
239  w.im = - z.im;
240  return w;
241 }
242 #endif
243 
244 #endif
245 
Real im
Definition: zmatrix.h:40
#define E_SING
Definition: err.h:98
static char rcsid[]
Definition: zfunc.c:35
complex zlog(complex z)
Definition: zfunc.c:220
#define Real
Definition: machine.h:189
double ldexp()
complex zmake(double real, double imag)
Definition: zfunc.c:41
log
Definition: extdef.h:3
cos
Definition: extdef.h:3
sin
Definition: extdef.h:3
complex zmlt(complex z1, complex z2)
Definition: zfunc.c:121
complex zadd(complex z1, complex z2)
Definition: zfunc.c:93
atan2
Definition: extdef.h:3
Real re
Definition: zmatrix.h:40
double frexp()
exp
Definition: extdef.h:3
#define alpha
Definition: bkpfacto.c:43
sqrt
Definition: extdef.h:3
complex zdiv(complex z1, complex z2)
Definition: zfunc.c:166
#define error(err_num, fn_name)
Definition: err.h:73
fabs
Definition: extdef.h:3
double zabs(complex z)
Definition: zfunc.c:65
complex zneg(complex z)
Definition: zfunc.c:53
complex zinv(complex z)
Definition: zfunc.c:135
complex zsqrt(complex z)
Definition: zfunc.c:175
complex zconj(complex z)
Definition: zfunc.c:233
complex zsub(complex z1, complex z2)
Definition: zfunc.c:107
complex zexp(complex z)
Definition: zfunc.c:204