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

complex_interp.cc

Go to the documentation of this file.
00001 // SuperMix version 1.0  C++ source file
00002 //
00003 // Copyright (c) 1999 California Institute of Technology.
00004 // All rights reserved.
00005 //
00006 // Redistribution and use in source and binary forms for noncommercial
00007 // purposes are permitted provided that the above copyright notice and
00008 // this paragraph are duplicated in all such forms and that any
00009 // documentation and other materials related to such distribution and
00010 // use acknowledge that the software was developed by California
00011 // Institute of Technology. Redistribution and/or use in source or
00012 // binary forms is not permitted for any commercial purpose. Use of
00013 // this software does not include a permitted use of the Institute's
00014 // name or trademark for any purpose.
00015 //
00016 // DISCLAIMER:
00017 // THIS SOFTWARE AND/OR RELATED MATERIALS ARE PROVIDED "AS-IS" WITHOUT
00018 // WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR
00019 // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE (AS SET
00020 // FORTH IN UCC 23212-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE
00021 // LICENSED PRODUCT, HOWEVER USED.  IN NO EVENT SHALL CALTECH/JPL BE
00022 // LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING BUT NOT LIMITED TO
00023 // INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, INCLUDING ECONOMIC
00024 // DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, REGARDLESS OF
00025 // WHETHER CALTECH/JPL SHALL BE ADVISED, HAVE REASON TO KNOW, OR IN
00026 // FACT SHALL KNOW OF THE POSSIBILITY.  THE USER BEARS ALL RISK
00027 // RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE AND/OR RELATED
00028 // MATERIALS.
00029 //
00030 // ********************************************************************
00031 // complex_interp.cc
00032 //
00033 // Change history:
00034 //
00035 // 7/6/99:   Huge modifications to interface and implementation
00036 // 9/15/98:  Made the output of zn conditional on error::messages
00037 // 7/28/98:  Added <iostream.h>, since SIScmplx.h doesn't any more
00038 // 2/12/98:  Added constructor from a real_table (JZ)
00039 
00040 #include <iostream.h>
00041 #include <math.h>
00042 #include "global.h"
00043 #include "error.h"
00044 #include "SIScmplx.h"
00045 #include "units.h"
00046 #include "device.h"
00047 #include "complex_interp.h"
00048 #include "io.h"
00049 
00050 // ----------------------------------------------
00051 // Constructing the complex_interp object
00052 
00053 // Constructors with no supplied data
00054 //
00055 complex_interp::complex_interp(const abstract_real_parameter &xp) :
00056   interpolator<complex>(), xparam(&xp)
00057 { }
00058 
00059 complex_interp::complex_interp() :
00060   interpolator<complex>(), xparam(0)
00061 { }
00062 
00063 
00064 // Constructors from input file or stream
00065 //
00066 
00067 complex_interp::complex_interp(const abstract_real_parameter &xp,
00068                                const char * const name, double x_unit,
00069                                double y_unit, int ycol, bool ignore_ws ) :
00070   interpolator<complex>(), xparam(&xp)
00071 { file(name, x_unit, y_unit, ycol, ignore_ws); }
00072 
00073 complex_interp::complex_interp(const abstract_real_parameter &xp,
00074                                istream & s, double x_unit,
00075                                double y_unit, int ycol, bool ignore_ws ) :
00076   interpolator<complex>(), xparam(&xp)
00077 { file(s, x_unit, y_unit, ycol, ignore_ws); }
00078 
00079 
00080 // Constructor from datafile
00081 //
00082 complex_interp::complex_interp(const datafile &df, int xcol, 
00083                                int ycol1, int ycol2, 
00084                                const abstract_real_parameter &xp, 
00085                                complex_interp::data_mode dmode) :
00086   interpolator<complex>(), xparam(&xp)
00087 {  
00088   // construct from the table associated with datafile
00089   construct(*(df.table()), xcol, ycol1, ycol2, dmode) ;
00090 }
00091 
00092 // Constructor from real_matrix
00093 //
00094 complex_interp::complex_interp(const real_matrix &rt, int xrow, 
00095                                int yrow1, int yrow2, 
00096                                const abstract_real_parameter &xp, 
00097                                complex_interp::data_mode dmode) :
00098   interpolator<complex>(), xparam(&xp)
00099 {  
00100   construct(rt, xrow, yrow1, yrow2, dmode) ;
00101 }
00102 
00103 // Construct from a complex_matrix
00104 //
00105 complex_interp::complex_interp(const complex_matrix &ct, int xrow, 
00106                                int yrow,
00107                                const abstract_real_parameter &xp) :
00108   interpolator<complex>(), xparam(&xp)
00109 {
00110   construct(ct, xrow, yrow) ;
00111 }
00112 
00113 // This does the real construction work - from real table data
00114 //
00115 void complex_interp::construct(const real_matrix &rt, int xrow, int yrow1,
00116                                int yrow2, complex_interp::data_mode dmode)
00117 {
00118   int npts = rt.Rmaxindex()-rt.Rminindex()+1 ; // how many data points ?
00119   int nrow = rt.Lmaxindex()-rt.Lminindex()+1 ; // how many rows ?
00120 
00121   // see if the constructor arguments are reasonable
00122 
00123   if(npts < 1 || nrow < 1) {
00124     error::warning(
00125     "in complex_interp constructor: table contains no data !") ;
00126     return ;
00127   }
00128   if(npts < 2) {
00129     error::warning(
00130     "in complex_interp constructor: table contains insufficient data!") ;
00131     return ;
00132   }
00133   if(nrow < 3) {
00134     error::warning(
00135     "in complex_interp constructor: table needs to have at least 3 rows !");
00136     return ;
00137   }
00138   if(xrow < rt.Lminindex() || xrow > rt.Lmaxindex()) {
00139     error::warning(
00140     "in complex_interp constructor: x row number out of range !") ;
00141     return ;
00142   }
00143   if(yrow1 < rt.Lminindex() || yrow1 > rt.Lmaxindex()) {
00144     error::warning(
00145     "in complex_interp constructor: y1 row number out of range !") ;
00146     return ;
00147   }
00148   if(yrow2 < rt.Lminindex() || yrow2 > rt.Lmaxindex()) {
00149     error::warning(
00150     "in complex_interp constructor: y2 row number out of range !") ;
00151     return ;
00152   }
00153 
00154   // pass the tests, so 
00155   // add the data points to the interpolator
00156 
00157   Complex yval ;
00158   for(int icol=rt.Rminindex(); icol<=rt.Rmaxindex(); icol++) {
00159     switch(dmode) {
00160     case CARTESIAN:
00161       yval = Complex(rt[yrow1][icol], rt[yrow2][icol]) ;
00162       break;
00163     case POLAR:
00164       yval = polar(rt[yrow1][icol], rt[yrow2][icol]) ;
00165       break;
00166     case DB:
00167       yval = polar(pow(10.0, 0.05*rt[yrow1][icol]), rt[yrow2][icol]*Degree) ;
00168       break;
00169     }
00170  
00171     add(rt[xrow][icol],yval);
00172   }
00173 
00174   build();
00175 }
00176 
00177 // This does the real construction work - from complex table data
00178 //
00179 void complex_interp::construct(const complex_matrix &ct, int xrow, int yrow)
00180 {
00181   int npts = ct.Rmaxindex()-ct.Rminindex()+1 ; // how many data points ?
00182   int nrow = ct.Lmaxindex()-ct.Lminindex()+1 ; // how many rows ?
00183 
00184   // see if the constructor arguments are reasonable
00185 
00186   if(npts < 1 || nrow < 1) {
00187     error::warning(
00188     "in complex_interp constructor: table contains no data !") ;
00189     return ;
00190   }
00191   if(npts < 2) {
00192     error::warning(
00193     "in complex_interp constructor: table contains insufficient data!") ;
00194     return ;
00195   }
00196   if(nrow < 2) {
00197     error::warning(
00198     "in complex_interp constructor: table needs to have at least 2 rows !");
00199     return ;
00200   }
00201   if(xrow < ct.Lminindex() || xrow > ct.Lmaxindex()) {
00202     error::warning(
00203     "in complex_interp constructor: x row number out of range !") ;
00204     return ;
00205   }
00206   if(yrow < ct.Lminindex() || yrow > ct.Lmaxindex()) {
00207     error::warning(
00208     "in complex_interp constructor: y row number out of range !") ;
00209     return ;
00210   }
00211 
00212   // pass the tests, so 
00213   // add the data points to the interpolator
00214 
00215   for(int icol=ct.Rminindex(); icol<=ct.Rmaxindex(); icol++) {
00216     add(ct[xrow][icol].real,ct[yrow][icol]);
00217   }
00218 
00219   build();
00220 }
00221 
00222 
00223 // ----------------------------------------------
00224 // read in data from an input stream or file
00225 
00226 complex_interp & complex_interp::file(istream & s, double xu, double yu, int yc, bool ws)
00227 {
00228   if(!s) {
00229     error::warning("complex_interp: couldn't read from input.");
00230     return *this;
00231   }
00232 
00233   data_parser d(s);
00234   unsigned n = d.skip_parse();
00235   if(!n) {
00236     error::warning("complex_interp: no data found in input.");
00237     return *this;
00238   }
00239 
00240   while(n) {
00241     double x;
00242     Vector y;
00243     int m;
00244 
00245     m = d.convert(x, y, xu, yu);
00246     if(m < yc) {
00247       error::warning("complex_interp: input stream doesn't have enough columns of data.");
00248     }
00249     else {
00250       add(x,y.read(yc));
00251     }
00252 
00253     n = (ws) ? d.skip_parse() : d.parse();
00254   }
00255   build();
00256   return *this;
00257 }
00258 
00259 
00260 complex_interp & 
00261 complex_interp::file(const char * const name, double xu, double yu, int yc, bool ws)
00262 {
00263   ifstream f(name);
00264   if(!f) {
00265     error::warning("complex_interp: couldn't open file", name);
00266     return *this;
00267   }
00268   file(f,xu,yu,yc,ws);
00269   return *this;
00270 }
00271 
00272 
00273 // ----------------------------------------------
00274 // read in data from a Touchstone-formatted 1-port file
00275 
00276 complex_interp & complex_interp::touchstone(const char * const name, char conversion)
00277 {
00278   // use a touchstone_read object to read file
00279   touchstone_read file;
00280   if ( !file.open(name,1) ) {
00281     // couldn't open file properly. file issues a warning with details
00282     error::warning("complex_interp::touchstone(): couldn't deal with file", name);
00283     return *this;  // this line won't get executed unless you change the one above
00284   }
00285 
00286   // file opened ok, so read data into the interpolator
00287   Matrix M;
00288   double f;
00289 
00290   switch ( conversion ) {
00291   default:
00292     // unrecognized character
00293     error::warning("complex_interp::touchstone(): unknown conversion option; using S");
00294     // fall through to case 'S'
00295   case 'S':
00296   case 's':
00297     // use S parameter
00298     while ( file.Svalue(f,M) ) add(f,M[1][1]);
00299     break;
00300   case 'Z':
00301   case 'z':
00302     // use Z value
00303     while ( file.Zvalue(f,M) ) add(f,M[1][1]);
00304     break;
00305   case 'Y':
00306   case 'y':
00307     // use Y value
00308     while ( file.Yvalue(f,M) ) add(f,M[1][1]);
00309     break;
00310   }
00311 
00312   build();
00313   parameter(device::f);
00314   return *this;
00315 }
00316 
00317 
00318 // ----------------------------------------------
00319 // Return an interpolated value:
00320 // Define the get() virtual function for abstract_complex_parameter
00321 
00322 Complex complex_interp::get() const
00323 {
00324   if(!(ready() && xparam)) {
00325     error::warning(
00326     "attempted use of a complex_interp object that was not properly constructed");
00327     return(0.) ;
00328   }
00329 
00330   return (*this)(xparam->get());
00331 }

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