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
1.2.7