My Project  0.0.16
QUCS Mapping
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
cmplx.cpp
Go to the documentation of this file.
1 /*
2  * cmplx.cpp - complex number class implementation
3  *
4  * Copyright (C) 2003, 2004, 2005, 2006, 2007 Stefan Jahn <stefan@lkcc.org>
5  * Copyright (C) 2006 Gunther Kraut <gn.kraut@t-online.de>
6  *
7  * This is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * This software is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this package; see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  *
22  * $Id: cmplx.cpp 1825 2011-03-11 20:42:14Z ela $
23  *
24  */
25 
31 #if HAVE_CONFIG_H
32 # include <config.h>
33 #endif
34 
35 #include <math.h>
36 
37 #include "real.h"
38 #include "cmplx.h"
39 
45 cmplx::cmplx (nr_double_t real, nr_double_t imag) {
46  r = real;
47  i = imag;
48 }
49 
56  r = 0.0;
57  i = 0.0;
58 }
59 
63 cmplx::cmplx (const cmplx& z) {
64  r = z.r;
65  i = z.i;
66 }
67 
73 nr_double_t cmplx::abs (void) {
74  return xhypot (r, i);
75 }
76 
83 nr_double_t abs (const cmplx z) {
84  return xhypot (z.r, z.i);
85 }
86 
93 nr_double_t cmplx::norm (void) {
94  return r * r + i * i;
95 }
96 
102 nr_double_t cmplx::arg (void) {
103  return atan2 (i, r);
104 }
105 
113 nr_double_t arg (const cmplx z) {
114  return atan2 (z.i, z.r);
115 }
116 
122 nr_double_t cmplx::real (void) {
123  return r;
124 }
125 
132 nr_double_t real (const cmplx z) {
133  return z.r;
134 }
135 
141 nr_double_t cmplx::imag (void) {
142  return i;
143 }
144 
151 nr_double_t imag (const cmplx z) {
152  return z.i;
153 }
154 
162  return cmplx (r, -i);
163 }
164 
171 cmplx conj (const cmplx z) {
172  return cmplx (z.r, -z.i);
173 }
174 
179  return cmplx (r, i);
180 }
181 
186  return cmplx (-r, -i);
187 }
188 
193  r += z2.r;
194  i += z2.i;
195  return *this;
196 }
197 
201 cmplx& cmplx::operator+=(const nr_double_t r2) {
202  r += r2;
203  return *this;
204 }
205 
210  r -= z2.r;
211  i -= z2.i;
212  return *this;
213 }
214 
218 cmplx& cmplx::operator-=(const nr_double_t r2) {
219  r -= r2;
220  return *this;
221 }
222 
227 cmplx& cmplx::operator*=(const nr_double_t r2) {
228  r *= r2;
229  i *= r2;
230  return *this;
231 }
232 
237 cmplx& cmplx::operator/=(const nr_double_t r2) {
238  r /= r2;
239  i /= r2;
240  return *this;
241 }
242 
246 cmplx operator+(const cmplx z1, const cmplx z2) {
247  return cmplx (z1.r + z2.r, z1.i + z2.i);
248 }
249 
253 cmplx operator+(const nr_double_t r1, const cmplx z2) {
254  return cmplx (r1 + z2.r, z2.i);
255 }
256 
260 cmplx operator+(const cmplx z1, const nr_double_t r2) {
261  return cmplx (z1.r + r2, z1.i);
262 }
263 
267 cmplx operator-(const cmplx z1, const cmplx z2) {
268  return cmplx (z1.r - z2.r, z1.i - z2.i);
269 }
270 
274 cmplx operator-(const nr_double_t r1, const cmplx z2) {
275  return cmplx (r1 - z2.r, -z2.i);
276 }
277 
281 cmplx operator-(const cmplx z1, const nr_double_t r2) {
282  return cmplx (z1.r - r2, z1.i);
283 }
284 
288 cmplx operator*(const cmplx z1, const nr_double_t r2) {
289  return cmplx (z1.r * r2, z1.i * r2);
290 }
291 
295 cmplx operator*(const nr_double_t r1, const cmplx z2) {
296  return cmplx (z2.r * r1, z2.i * r1);
297 }
298 
302 cmplx operator*(const cmplx z1, const cmplx z2) {
303  return cmplx (z1.r * z2.r - z1.i * z2.i, z1.i * z2.r + z1.r * z2.i);
304 }
305 
310 cmplx operator/(const cmplx z1, const nr_double_t r2) {
311  return cmplx (z1.r / r2, z1.i / r2);
312 }
313 
317 cmplx operator/(const cmplx z1, const cmplx z2) {
318 #if 0
319  nr_double_t n = norm (z2);
320  return cmplx ((z1.r * z2.r + z1.i * z2.i) / n,
321  (z1.i * z2.r - z1.r * z2.i) / n);
322 #else /* avoid numerical overflow and underrun */
323  nr_double_t r, i, n, d;
324  if (fabs (z2.r) > fabs (z2.i)) {
325  n = z2.i / z2.r;
326  d = z2.r + z2.i * n;
327  r = (z1.r + z1.i * n) / d;
328  i = (z1.i - z1.r * n) / d;
329  }
330  else {
331  n = z2.r / z2.i;
332  d = z2.r * n + z2.i;
333  r = (z1.r * n + z1.i) / d;
334  i = (z1.i * n - z1.r) / d;
335  }
336  return cmplx (r, i);
337 #endif
338 }
339 
344 #if 0
345  nr_double_t n1, n2;
346  n1 = norm (z);
347  n2 = (r * z.r + i * z.i) / n1;
348  i = (i * z.r - r * z.i) / n1;
349  r = n2;
350 #else /* avoid numerical overflow and underrun */
351  nr_double_t n, d, t;
352  if (fabs (z.r) > fabs (z.i)) {
353  n = z.i / z.r;
354  d = z.r + z.i * n;
355  t = (r + i * n) / d;
356  i = (i - r * n) / d;
357  r = t;
358  }
359  else {
360  n = z.r / z.i;
361  d = z.r * n + z.i;
362  t = (r * n + i) / d;
363  i = (i * n - r) / d;
364  r = t;
365  }
366 #endif
367  return *this;
368 }
369 
373 cmplx operator/(const nr_double_t r1, const cmplx z2) {
374 #if 0
375  nr_double_t n = norm (z2);
376  return cmplx (r1 * z2.r / n, -r1 * z2.i / n);
377 #else /* avoid numerical overflow and underrun */
378  nr_double_t r, i, n, d;
379  if (fabs (z2.r) > fabs (z2.i)) {
380  n = z2.i / z2.r;
381  d = z2.r + z2.i * n;
382  r = r1 / d;
383  i = -n * r1 / d;
384  }
385  else {
386  n = z2.r / z2.i;
387  d = z2.r * n + z2.i;
388  r = r1 * n / d;
389  i = -r1 / d;
390  }
391  return cmplx (r, i);
392 #endif
393 }
394 
399  r = z.r;
400  i = z.i;
401  return *this;
402 }
403 
407 cmplx& cmplx::operator=(const nr_double_t x) {
408  r = x;
409  i = 0.0;
410  return *this;
411 }
412 
417  nr_double_t n;
418  n = r * z.r - i * z.i;
419  i = i * z.r + r * z.i;
420  r = n;
421  return *this;
422 }
423 
424 #ifdef DEBUG
425 #include <stdio.h>
430 void cmplx::print (void) {
431  fprintf (stderr, "%+.2e,%+.2e ", (double) r, (double) i);
432 }
433 #endif /* DEBUG */