Bladeren bron

Finished test of complex lib

Konstantin Ladutenko 10 jaren geleden
bovenliggende
commit
4ca9fca011
3 gewijzigde bestanden met toevoegingen van 347 en 4 verwijderingen
  1. 4 4
      tests/dev/test-complex-lib.cc
  2. 274 0
      tests/dev/ucomplex.cc
  3. 69 0
      tests/dev/ucomplex.h

+ 4 - 4
tests/dev/test-complex-lib.cc

@@ -1,7 +1,7 @@
 #include <complex>
 #include <string>
 #include <stdio.h>
-#include "../../ucomplex.h"
+#include "ucomplex.h"
 void output(std::string operation, complex c1, std::complex<double> c2) {
     double diff_r = c1.r - c2.real();
     double diff_i = c1.i - c2.imag();
@@ -11,8 +11,8 @@ void output(std::string operation, complex c1, std::complex<double> c2) {
 	   c1.r, c1.i,
 	   c2.real(), c2.imag());
     // Epsilon for double is 1e-16, check it 1.0 + 1e-16 = 1.0
-    //if (diff_r > 1e-16||diff_i > 1e-16) 
-    if (diff_r > 1e-15||diff_i > 1e-15) 
+    if (diff_r > 1e-16||diff_i > 1e-16) 
+	//if (diff_r > 1e-15||diff_i > 1e-15) 
 	printf("\n********\n\t\tWARNING!! Non-zero diff!!!\n********\n");
 }
 /********************************************************************/
@@ -239,7 +239,7 @@ int main() {
 
     c1 = Carc_th(a1);
     c2 = std::atanh(a2);
-    output("aTan", c1, c2);
+    output("aTanh", c1, c2);
     c1 = Carc_th(b1);
     c2 = std::atanh(b2);
     output("saTanh", c1, c2);

+ 274 - 0
tests/dev/ucomplex.cc

@@ -0,0 +1,274 @@
+//**********************************************************************************//
+//    Copyright (C) 2009-2015  Ovidio Pena <ovidio@bytesfall.com>                   //
+//                                                                                  //
+//    This file is part of scattnlay                                                //
+//                                                                                  //
+//    This program is free software: you can redistribute it and/or modify          //
+//    it under the terms of the GNU General Public License as published by          //
+//    the Free Software Foundation, either version 3 of the License, or             //
+//    (at your option) any later version.                                           //
+//                                                                                  //
+//    This program is distributed in the hope that it will be useful,               //
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of                //
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                 //
+//    GNU General Public License for more details.                                  //
+//                                                                                  //
+//    The only additional remark is that we expect that all publications            //
+//    describing work using this software, or all commercial products               //
+//    using it, cite the following reference:                                       //
+//    [1] O. Pena and U. Pal, "Scattering of electromagnetic radiation by           //
+//        a multilayered sphere," Computer Physics Communications,                  //
+//        vol. 180, Nov. 2009, pp. 2348-2354.                                       //
+//                                                                                  //
+//    You should have received a copy of the GNU General Public License             //
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.         //
+//**********************************************************************************//
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "ucomplex.h"
+
+complex Cadd(complex z1, complex z2) {
+  complex zr;
+  zr.r = z1.r + z2.r;
+  zr.i = z1.i + z2.i;
+  return zr;
+}
+
+complex Csub(complex z1, complex z2) {
+  complex zr;
+  zr.r = z1.r - z2.r;
+  zr.i = z1.i - z2.i;
+  return zr;
+}
+
+complex Cmul(complex z1, complex z2) {
+  complex zr;
+  zr.r = (z1.r*z2.r) - (z1.i*z2.i);
+  zr.i = (z1.r*z2.i) + (z1.i*z2.r);
+  return zr;
+}
+
+complex RCmul(double r, complex z) {
+  complex zr;
+  zr.r = z.r*r;
+  zr.i = z.i*r;
+  return zr;
+}
+
+complex Cdiv(complex z1, complex z2) {
+/* The following algorithm is used to properly handle
+   denominator overflow:
+
+              |  a + b(d/c)   b - a(d/c)
+              |  ---------- + ----------- I     if |d| < |c|
+   a + b I    |  c + d(d/c)   c + d(d/c)
+   -------  = |
+   c + d I    |  b + a(c/d)   -a + b(c/d)
+              |  ---------- + ----------- I     if |d| >= |c|
+              |  d + c(c/d)   d + c(c/d)
+*/
+  complex zr;
+  double tmp, denom;
+
+  if(fabs(z2.r) > fabs(z2.i)) {
+    tmp = z2.i/z2.r;
+    denom = z2.r + z2.i*tmp;
+    zr.r = (z1.r + z1.i*tmp)/denom;
+    zr.i = (z1.i - z1.r*tmp)/denom;
+  } else {
+    tmp = z2.r/z2.i;
+    denom = z2.i + z2.r*tmp;
+    zr.r = (z1.i + z1.r*tmp)/denom;
+    zr.i = (-z1.r + z1.i*tmp)/denom;
+  }
+  return zr;
+}    
+
+complex Complex(double re, double im) {
+  complex zr;
+  zr.r = re;
+  zr.i = im;
+  return zr;
+}
+
+double Cabs(complex z) {
+  double r;
+  r = sqrt((z.r*z.r) + (z.i*z.i));
+  return r;
+}
+
+double Carc(complex z) {
+  double r;
+  r = atan2(z.i, z.r);
+  return r;
+}
+
+complex Conjg(complex z) {
+  complex zr;
+  zr.r = z.r;
+  zr.i = -z.i;
+  return zr;
+}
+
+complex Cinv(complex z) {
+  complex zr;
+  double denom;
+
+  denom = (z.r*z.r) + (z.i*z.i);
+  zr.r = z.r/denom;
+  zr.i = -z.i/denom;
+  return zr;
+}
+
+complex Cexp(complex z) {
+// exp(a + ib) = exp(a)*exp(ib) = exp(a)*[cos(b) + i sin(b)]
+  complex zr;
+  double expz;
+
+  expz = exp(z.r);
+  zr.r = expz*cos(z.i);
+  zr.i = expz*sin(z.i);
+  return zr;
+}
+
+complex Clog(complex z) {
+// ln( p exp(i0)) = ln(p) + i0 + 2kpi
+  complex zr;
+  zr.r = log(Cabs(z));
+  zr.i = atan2(z.i, z.r);
+  return zr;
+}
+
+complex Csqrt(complex z) {
+  complex zr;
+  double root, q;
+
+  if((z.r != 0.0) ||(z.i != 0.0)) {
+    root = sqrt(0.5*(fabs(z.r) + Cabs(z)));
+    q = z.i/(2.0*root);
+    if(z.r >= 0.0) {
+      zr.r = root;
+      zr.i = q;
+    } else if(z.i < 0.0) {
+             zr.r = -q;
+             zr.i = -root;
+           } else {
+             zr.r =  q;
+             zr.i =  root;
+           }
+    } else zr = z;
+  return zr;
+}
+
+// complex trigonometric functions
+
+// complex cosinus
+complex Ccos(complex z) {
+// cos(x+iy) = cos(x).cos(iy) - sin(x).sin(iy)
+// cos(ix) = cosh(x) et sin(ix) = i.sinh(x)
+  complex zr;
+  zr.r = cos(z.r)*cosh(z.i);
+  zr.i = -sin(z.r)*sinh(z.i);
+  return zr;
+}
+
+// complex sinus
+complex Csin(complex z) {
+// sin(x+iy) = sin(x).cos(iy) + cos(x).sin(iy)
+// cos(ix) = cosh(x) et sin(ix) = i.sinh(x)
+  complex zr;
+  zr.r = sin(z.r)*cosh(z.i);
+  zr.i = cos(z.r)*sinh(z.i);
+  return zr;
+}
+
+// tangent
+complex Ctan(complex z) {
+  return Cdiv(Csin(z), Ccos(z));
+}
+
+// Inverse trigonometric functions
+
+// complex arc cosinus
+complex Carc_cos(complex z) {
+// arccos(z) = -i.arcch(z)
+  complex temp = Carc_ch(z);
+  return Complex(temp.i, -temp.r);
+}
+
+// complex arc sinus
+complex Carc_sin(complex z) {
+// arcsin(z) = -i.arcsh(i.z)
+  complex temp = Carc_sh(Complex(-z.i, z.r));
+  return Complex(temp.i, -temp.r);
+}
+
+// complex arc tangent
+complex Carc_tan(complex z) {
+// arctg(z) = -i.arcth(i.z)
+  complex temp = Carc_th(Complex(-z.i, z.r));
+  return Complex(temp.i, -temp.r);
+}
+
+// Hyberbolic complex functions
+
+// complex hyberbolic cosinus
+complex Cch(complex z) {
+// cosh(x+iy) = cosh(x).cosh(iy) + sinh(x).sinh(iy)
+// cosh(iy) = cos(y) et sinh(iy) = i.sin(y)
+  complex zr;
+  zr.r = cosh(z.r)*cos(z.i);
+  zr.i = sinh(z.r)*sin(z.i);
+  return zr;
+}
+
+// complex hyberbolic sinus
+complex Csh(complex z) {
+// sinh(x+iy) = sinh(x).cosh(iy) + cosh(x).sinh(iy)
+// cosh(iy) = cos(y) et sinh(iy) = i.sin(y)
+  complex zr;
+  zr.r = sinh(z.r)*cos(z.i);
+  zr.i = cosh(z.r)*sin(z.i);
+  return zr;
+}
+
+// complex hyberbolic tangent
+complex Cth(complex z) {
+// th(x) = sinh(x)/cosh(x)
+// cosh(x) > 1 qq x
+  complex temp, zr;
+  temp = Cch(z);
+  zr = Csh(z);
+  return Cdiv(zr, temp);
+}
+
+// Inverse complex hyperbolic functions
+
+// complex hyperbolic arc cosinus
+complex Carc_ch(complex z) {
+//                        _________
+// arcch(z) = -/+ ln(z + V z.z - 1 )
+  complex zr;
+  complex z2 = Cmul(z, z);
+  zr = Clog(Cadd(z, Csqrt(Complex(z2.r - 1.0, z2.i))));
+  zr.r = -zr.r;
+  zr.i = -zr.i;
+  return zr;
+}
+
+// complex hyperbolic arc sinus
+complex Carc_sh(complex z) {
+//                    ________
+// arcsh(z) = ln(z + V 1 + z.z)
+  complex z2 = Cmul(z, z);
+  return Clog(Cadd(z, Csqrt(Complex(z2.r + 1.0, z2.i))));
+}
+
+// complex hyperbolic arc tangent
+complex Carc_th(complex z) {
+// arcth(z) = 1/2 ln((z + 1)/(1 - z))
+  return RCmul(0.5, Clog(Cdiv(Complex(z.r + 1.0, z.i), Complex(1.0 - z.r, -z.i))));
+}
+

+ 69 - 0
tests/dev/ucomplex.h

@@ -0,0 +1,69 @@
+//**********************************************************************************//
+//    Copyright (C) 2009-2015  Ovidio Pena <ovidio@bytesfall.com>                   //
+//                                                                                  //
+//    This file is part of scattnlay                                                //
+//                                                                                  //
+//    This program is free software: you can redistribute it and/or modify          //
+//    it under the terms of the GNU General Public License as published by          //
+//    the Free Software Foundation, either version 3 of the License, or             //
+//    (at your option) any later version.                                           //
+//                                                                                  //
+//    This program is distributed in the hope that it will be useful,               //
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of                //
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                 //
+//    GNU General Public License for more details.                                  //
+//                                                                                  //
+//    The only additional remark is that we expect that all publications            //
+//    describing work using this software, or all commercial products               //
+//    using it, cite the following reference:                                       //
+//    [1] O. Pena and U. Pal, "Scattering of electromagnetic radiation by           //
+//        a multilayered sphere," Computer Physics Communications,                  //
+//        vol. 180, Nov. 2009, pp. 2348-2354.                                       //
+//                                                                                  //
+//    You should have received a copy of the GNU General Public License             //
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.         //
+//**********************************************************************************//
+
+typedef struct COMPLEX {double r,i;} complex;
+
+// Complex functions
+complex Cadd(complex z1, complex z2);  // addition
+complex Csub(complex z1, complex z2);  // substraction
+complex Cmul(complex z1, complex z2);  // multiplication
+complex RCmul(double r, complex z);    // double*complex
+complex Cdiv(complex z1, complex z2);  // division
+complex Complex(double r, double i);   // convert to double
+
+complex Conjg(complex z);    // conjuge
+complex Cinv(complex z);     // inverse function 1/z
+
+// Complex functions with double return values
+double Cabs(complex z);      // module
+double Carc(complex z);      // argument : z1 / z = p.e^ia
+
+// Elementary functions
+complex Cexp(complex z);    // exponential
+complex Clog(complex z);    // natural logarithm
+complex Csqrt(complex z);   // square root
+
+// Complex trigonometric functions 
+complex Ccos(complex z);    // cosinus
+complex Csin(complex z);    // sinus
+complex Ctan(complex z);    // tangent
+
+// Inverse complex trigonometric functions
+complex Carc_cos(complex z);   // arc cosinus
+complex Carc_sin(complex z);   // arc sinus
+complex Carc_tan(complex z);   // arc tangent
+
+// Hyperbolic complex functions
+complex Cch(complex z);     // hyperbolic cosinus
+complex Csh(complex z);     // hyperbolic sinus
+complex Cth(complex z);     // hyperbolic tangent
+
+// Inverse hyperbolic complex functions
+complex Carc_ch(complex z); // hyperbolic arc cosinus
+complex Carc_sh(complex z); // hyperbolic arc sinus
+complex Carc_th(complex z); // hyperbolic arc tangente
+
+