Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

SIScmplx.cc

Go to the documentation of this file.
00001 // SIScmplx.cc
00002 // SuperMix version 1.0  C++ source file
00003 //
00004 // Copyright (c) 1999 California Institute of Technology.
00005 // All rights reserved.
00006 //
00007 // Redistribution and use in source and binary forms for noncommercial
00008 // purposes are permitted provided that the above copyright notice and
00009 // this paragraph are duplicated in all such forms and that any
00010 // documentation and other materials related to such distribution and
00011 // use acknowledge that the software was developed by California
00012 // Institute of Technology. Redistribution and/or use in source or
00013 // binary forms is not permitted for any commercial purpose. Use of
00014 // this software does not include a permitted use of the Institute's
00015 // name or trademark for any purpose.
00016 //
00017 // DISCLAIMER:
00018 // THIS SOFTWARE AND/OR RELATED MATERIALS ARE PROVIDED "AS-IS" WITHOUT
00019 // WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR
00020 // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE (AS SET
00021 // FORTH IN UCC 23212-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE
00022 // LICENSED PRODUCT, HOWEVER USED.  IN NO EVENT SHALL CALTECH/JPL BE
00023 // LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING BUT NOT LIMITED TO
00024 // INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, INCLUDING ECONOMIC
00025 // DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, REGARDLESS OF
00026 // WHETHER CALTECH/JPL SHALL BE ADVISED, HAVE REASON TO KNOW, OR IN
00027 // FACT SHALL KNOW OF THE POSSIBILITY.  THE USER BEARS ALL RISK
00028 // RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE AND/OR RELATED
00029 // MATERIALS.
00030 //
00031 // Change history:
00032 // 11/16/99: Got rid of "+i-0" nonsense
00033 // 9/27/99:  Added the db io_mode, and function dtoz()
00034 // 11/10/98: added inverse trig and hypb fcns
00035 
00036 #include "SIScmplx.h"
00037 #include "global.h"
00038 #include <iostream.h>
00039 #include <iomanip.h>
00040 #include <string>
00041 #include <strstream.h>
00042 #include <math.h>
00043 
00044 
00045 //---------------------------------------------------------------------
00046 // i/o formatting static variables
00047 
00048 static Complex::io_mode _out_mode, _in_mode;
00049 
00050 static int _in_form;
00051 
00052 static string _out_prefix, _out_suffix, _out_separator;
00053 
00054 
00055 //---------------------------------------------------------------------
00056 // set output formatting
00057 
00058 Complex::io_mode Complex::out_mode()
00059 { return _out_mode; } 
00060 
00061 Complex::io_mode Complex::out_mode(Complex::io_mode m)
00062 { io_mode temp = _out_mode; _out_mode = m; return temp; } 
00063 
00064 string Complex::out_prefix()
00065 { return _out_prefix; }
00066 
00067 string Complex::out_prefix(const string & s)
00068 { string temp = _out_prefix; _out_prefix = s; return temp; }
00069 
00070 string Complex::out_prefix(const char * const s)
00071 { string temp = _out_prefix; _out_prefix = s; return temp; }
00072 
00073 string Complex::out_prefix(const char s)
00074 { string temp = _out_prefix; _out_prefix = s; return temp; }
00075 
00076 string Complex::out_separator()
00077 { return _out_separator; }
00078 
00079 string Complex::out_separator(const string & s)
00080 { string temp = _out_separator; _out_separator = s; return temp; }
00081 
00082 string Complex::out_separator(const char * const s)
00083 { string temp = _out_separator; _out_separator = s; return temp; }
00084 
00085 string Complex::out_separator(const char s)
00086 { string temp = _out_separator; _out_separator = s; return temp; }
00087 
00088 string Complex::out_suffix()
00089 { return _out_suffix; }
00090 
00091 string Complex::out_suffix(const string & s)
00092 { string temp = _out_suffix; _out_suffix = s; return temp; }
00093 
00094 string Complex::out_suffix(const char * const s)
00095 { string temp = _out_suffix; _out_suffix = s; return temp; }
00096 
00097 string Complex::out_suffix(const char s)
00098 { string temp = _out_suffix; _out_suffix = s; return temp; }
00099 
00100 void Complex::out_default()
00101 { _out_prefix = _out_separator = _out_suffix = ""; }
00102 
00103 void Complex::out_space()
00104 { _out_prefix = _out_suffix = ""; _out_separator = " "; }
00105 
00106 void Complex::out_delimited()
00107 { _out_prefix = "("; _out_separator = ","; _out_suffix = ")"; }
00108 
00109 
00110 //---------------------------------------------------------------------
00111 // set input formatting
00112 
00113 Complex::io_mode Complex::in_mode()
00114 { return _in_mode; } 
00115 
00116 Complex::io_mode Complex::in_mode(Complex::io_mode m)
00117 { io_mode temp = _in_mode; _in_mode = m; return temp; } 
00118 
00119 int Complex::in_form()
00120 { return _in_form; }
00121 
00122 int Complex::in_form(int f)
00123 { int temp = _in_form; _in_form = (f != 0); return temp; }
00124 
00125 
00126 //---------------------------------------------------------------------
00127 // i/o functions
00128 
00129 ostream & operator <<(ostream & out_file, Complex z)
00130 {
00131   ostrstream zout;
00132   zout.setf(out_file.flags());
00133   zout.precision(out_file.precision());
00134   zout.fill(out_file.fill());
00135 
00136   string separator(_out_separator);
00137 
00138   if (z.imaginary == 0.0) z.imaginary = 0.0;  // get rid of "-0" outputs
00139 
00140   switch ( _out_mode) {
00141 
00142   default:
00143   case Complex::cartesian: {
00144     if (separator == "") {
00145       if (z.imaginary < 0.0) {
00146         separator = "-i";
00147         z.imaginary = -z.imaginary;
00148       }
00149       else
00150         separator = "+i";
00151     }
00152 
00153     zout << _out_prefix << z.real << separator
00154          << z.imaginary << _out_suffix << '\000';
00155     break;
00156   }
00157 
00158   case Complex::polar: {
00159     if (separator == "") separator = " ";
00160 
00161     zout << _out_prefix << abs(z) << separator
00162          << arg(z) << _out_suffix << '\000';
00163     break;
00164   }
00165 
00166   case Complex::degree: {
00167     if (separator == "") separator = " ";
00168 
00169     zout << _out_prefix << abs(z) << separator
00170          << arg(z)/Degree << _out_suffix << '\000';
00171     break;
00172   }
00173 
00174   case Complex::db: {
00175     if (separator == "") separator = " ";
00176 
00177     zout << _out_prefix << 20*log10(abs(z)) << separator
00178          << arg(z)/Degree << _out_suffix << '\000';
00179     break;
00180   }
00181 
00182   } // switch
00183 
00184 
00185   return out_file << zout.str();
00186 }
00187 
00188 
00189 istream & operator >>(istream & in_file, Complex & z)
00190 {
00191   double re = 0, im = 0;
00192 
00193   if (_in_form == 0) {  // the default behavior
00194     in_file >> re >> im;
00195   }
00196   else {  // delimited input form
00197     char c = 0;
00198     in_file >> c;
00199     if (c == '(') {
00200       in_file >> re >> c;
00201       if (c == ',')
00202         in_file >> im >> c;
00203       if (c != ')')
00204         in_file.clear(ios::badbit);  // invalid - set state
00205     }
00206     else {
00207       in_file.putback(c);
00208       in_file >> re;
00209     }
00210   }
00211 
00212   if (in_file) z = dtoz(re,im);  // everything went well
00213   return in_file;
00214 }
00215 
00216 Complex dtoz(double re, double im)
00217 {
00218   Complex z;
00219 
00220   switch (_in_mode) {
00221 
00222   default:
00223   case Complex::cartesian: {
00224     z = Complex(re,im);
00225     break;
00226   }
00227 
00228   case Complex::db: {
00229     re = pow(10.0, re/20.0); // convert decibel magnitude
00230     // fall through to case Complex::degree
00231   }
00232 
00233   case Complex::degree: {
00234     im *= Degree;  // convert phase to radians
00235     // fall through to case Complex::polar
00236   }
00237 
00238   case Complex::polar: {
00239     if (im == 0.0)
00240       z = re;
00241     else
00242       z = polar(re,im);
00243     break;
00244   }
00245 
00246   } // switch
00247 
00248   return z;
00249 }
00250 
00251 
00252 //---------------------------------------------------------------------
00253 // functions which use <math.h>:
00254 
00255 // absolute value (magnitude):
00256 
00257 double zabs( const Complex & z )
00258 {
00259   return sqrt( z.real*z.real + z.imaginary*z.imaginary );
00260 }
00261 
00262 double zarg( const Complex & z )
00263 {
00264   return atan2( z.imaginary, z.real );
00265 }
00266 
00267 Complex log( const Complex & z )
00268 {
00269   return Complex (log(abs(z)), arg(z));
00270 }
00271 
00272 Complex exp( const Complex & z )
00273 {
00274   return polar(exp(z.real), z.imaginary);
00275 }
00276 
00277 Complex log10( const Complex & z )
00278 {
00279   return log(z)/log(10.0);
00280 }
00281 
00282 Complex pow( const Complex & z, const double d )
00283 {
00284   return polar(pow(abs(z),d), d * arg(z));
00285 }
00286 
00287 Complex pow( Complex z1, const Complex & z2 )
00288 {
00289   z1 = Complex( log(abs(z1)), arg(z1) ); // use z1 as temp variable
00290   return polar( exp(z1.real * z2.real - z1.imaginary * z2.imaginary),
00291                 z1.real * z2.imaginary + z1.imaginary * z2.real );
00292 }
00293 
00294 Complex cos( const Complex & z )
00295 {
00296   return Complex( cos(z.real)*cosh(z.imaginary), 
00297                   -sin(z.real)*sinh(z.imaginary) );
00298 }
00299 
00300 Complex sin( const Complex & z )
00301 {
00302   return Complex( sin(z.real)*cosh(z.imaginary),
00303                   cos(z.real)*sinh(z.imaginary) );
00304 }
00305 
00306 Complex tan( Complex z )
00307 {
00308   z *= 2;  // use z as a temp variable
00309   return Complex( sin(z.real), sinh(z.imaginary) )/
00310     ( cos(z.real) + cosh(z.imaginary) );
00311 }
00312 
00313 Complex cosh( const Complex & z )
00314 {
00315   return Complex( cosh(z.real)*cos(z.imaginary), 
00316                   +sinh(z.real)*sin(z.imaginary) );
00317 }
00318 
00319 Complex sinh( const Complex & z )
00320 {
00321   return Complex( sinh(z.real)*cos(z.imaginary),
00322                   cosh(z.real)*sin(z.imaginary) );
00323 }
00324 
00325 Complex tanh( Complex z )
00326 {
00327   z *= 2;  // use z as a temp variable
00328   return Complex( sinh(z.real), sin(z.imaginary) )/
00329     ( cosh(z.real) + cos(z.imaginary) );
00330 }
00331 
00332 Complex asin( const Complex & z )
00333 {
00334   return -I*log(I*z+sqrt(1-z*z));
00335 }
00336 
00337 Complex acos( const Complex & z )
00338 {
00339   return -I*log(z+I*sqrt(1-z*z));
00340 }
00341 
00342 Complex atan( Complex z )
00343 {
00344   z *= I;
00345   return log((1+z)/(1-z))/(2*I);
00346 }
00347 
00348 Complex asinh( const Complex & z )
00349 {
00350   return log(z+sqrt(z*z+1));
00351 }
00352 
00353 Complex acosh( const Complex & z )
00354 {
00355   return log(z+sqrt(z*z-1));
00356 }
00357 
00358 Complex atanh( Complex z )
00359 {
00360   return 0.5*log((1+z)/(1-z));
00361 }

Please direct comments and corrections to supermix@submm.caltech.edu
Go to the supermix home page
Generated by doxygen1.2.7