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
1.2.7