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 // sdata_interp.cc 00032 // 00033 // FRR 10/7/99 00034 // 00035 // 11/16/99: supports new circuit noise calculations 00036 // 00037 // ******************************************************************** 00038 00039 #include "sdata_interp.h" 00040 00041 S_interp & S_interp::add_S(double f, const Matrix & S, double Zn) 00042 { 00043 if((S.Lmode != Index_1) && (S.Rmode != Index_1) && (S.Lsize != N) && (S.Rsize != N)) { 00044 error::warning("S_interp::add_S(): improperly sized S matrix argument"); 00045 return *this; 00046 } 00047 00048 if(Znorm_ <= 0.0) Znorm_ = device::Z0; 00049 if(Zn == Znorm_ || Zn <= 0.0) 00050 s.add(f,S); 00051 else 00052 s.add(f,S_renormalize(S,Znorm_,Zn)); 00053 return *this; 00054 } 00055 00056 00057 S_interp & S_interp::add_S(double f, const sdata & Sd) 00058 { 00059 add_S(f, Sd.S, Sd.get_znorm()); 00060 return *this; 00061 } 00062 00063 00064 S_interp & S_interp::add_SC(double f, const sdata & Sd) 00065 { 00066 if(Sd.size() != N || Sd.mode() != Index_1) { 00067 error::warning("S_interp::add_SC(): incompatible sdata argument"); 00068 return *this; 00069 } 00070 00071 if(Sd.get_znorm() == Znorm_ || Sd.get_znorm() == 0) { 00072 // no renormalization required 00073 s.add(f, Sd.S); 00074 c.add(f, Sd.C); 00075 } 00076 else { 00077 // must renormalize sdata first 00078 sdata temp(Sd, Znorm_); 00079 s.add(f, temp.S); 00080 c.add(f, temp.C); 00081 } 00082 00083 noise_ = true; 00084 return *this; 00085 } 00086 00087 00088 S_interp & S_interp::add_SC(double f, const Matrix & S, const Matrix & C, double Zn) 00089 { 00090 if((S.Lmode != Index_1) && (S.Rmode != Index_1) && (S.Lsize != N) && (S.Rsize != N)) { 00091 error::warning("S_interp::add_SC(): improperly sized S matrix argument"); 00092 return *this; 00093 } 00094 if((C.Lmode != Index_1) && (C.Rmode != Index_1) && (C.Lsize != N) && (C.Rsize != N)) { 00095 error::warning("S_interp::add_SC(): improperly sized C matrix argument"); 00096 return *this; 00097 } 00098 00099 if(Znorm_ <= 0.0) Znorm_ = device::Z0; 00100 if(Zn == Znorm_ || Zn <= 0.0) { 00101 // renormalization not needed - just add the matrices to the interpolators 00102 s.add(f,S); 00103 c.add(f,C); 00104 } 00105 else { 00106 // need to renormalize first; use an sdata to accomplish this 00107 sdata temp(N); 00108 temp.set_znorm(Zn); 00109 temp.S = S; 00110 temp.C = C; 00111 temp.change_norm(Znorm_); 00112 s.add(f,temp.S); 00113 c.add(f,temp.C); 00114 } 00115 00116 return *this; 00117 } 00118 00119 00120 bool S_interp::touchstone(const char * name, double f_scale) 00121 { 00122 touchstone_read d; 00123 if(!d.open(name, N, f_scale)) return false; 00124 00125 if(Znorm_ <= 0.0) Znorm_ = device::Z0; 00126 double f; 00127 Matrix S; 00128 00129 // read in the S matrix data and rebuild the S interpolator 00130 while(d.Svalue(f,S)) add_S(f,S); 00131 s.build(); 00132 00133 // if a 2-port, there may also be noise data 00134 if(N == 2 && d.has_noise()) { 00135 noise_ = true; 00136 00137 // here's where we fetch and convert the noise data: 00138 Matrix C(2); 00139 touchstone_read::noise N; 00140 double To = 290.0*Kelvin; 00141 double Zo = device::Z0; 00142 while(d.get_noise(f,N)) { 00143 S = s(f); 00144 // renormalize S to device::Z0 if necessary 00145 if (Znorm_ != Zo) S = S_renormalize(S,Zo,Znorm_); 00146 00147 double Tmin = To * (pow(10.0, N.Fmin/10.0) - 1.0); // noise figure to T 00148 double t = (4.0*To*N.Reff/Zo)/norm(1 + N.Gopt); // an intermediate calc 00149 00150 C[1][1] = Tmin*(norm(S[1][1]) - 1) + t*norm(1 - S[1][1]*N.Gopt); 00151 C[2][2] = norm(S[2][1])*(Tmin + t*norm(N.Gopt)); 00152 C[1][2] = zconj(S[2][1])*(S[1][1]*(Tmin + t*norm(N.Gopt)) - t*zconj(N.Gopt)); 00153 C[2][1] = zconj(C[1][2]); 00154 00155 // if necessary renormalize C to Znorm_ 00156 if (Znorm_ != Zo) { 00157 Matrix F = identity_matrix(2,Index_1); 00158 double rho = sqrt(Znorm_ / Zo) ; 00159 double Sigma = 0.5*(1./rho + rho) ; 00160 double Delta = 0.5*(1./rho - rho) ; 00161 F = Sigma*F - Delta*S; 00162 C = F*C*dagger(F); 00163 } 00164 00165 // put result into the interpolation 00166 c.add(f,C); 00167 00168 } // while() 00169 c.build(); 00170 00171 } // if 00172 00173 return d.good() && s.ready() && (!noise_ || c.ready()); 00174 } 00175 00176 00177 // ******************************************************************** 00178 00179 sdata_interp::sdata_interp(int ports, const abstract_real_parameter & f) 00180 : nport(ports), pf(&f), S(ports) 00181 { 00182 if(ports <= 0) error::fatal("sdata_interp: must be constructed with ports > 0"); 00183 info.source = false; 00184 } 00185 00186 00187 bool sdata_interp::copy(const S_interp & s) 00188 { 00189 if (s.ports() != size()) { 00190 error::warning("sdata_interp::copy(): argument has incorrect number of ports."); 00191 return false; 00192 } 00193 else { 00194 S = s; 00195 return true; 00196 } 00197 } 00198 00199 00200 void sdata_interp::recalc_S() 00201 { 00202 if (!ready()) { 00203 error::warning("sdata_interp::recalc(): interpolator is empty or not ready"); 00204 return; 00205 } 00206 00207 // perform the interpolation and put in nport's sdata object 00208 if(S.fill(data,*pf)) { 00209 // data.C has been filled; adjust normalization and return 00210 data.change_norm(device::Z0); 00211 } 00212 else { 00213 // only data.S has been filled; data.C has stale values 00214 if(data.get_znorm() != device::Z0) { 00215 data.S = S_renormalize(data.S, device::Z0, data.get_znorm()); 00216 data.set_znorm(device::Z0); 00217 } 00218 } 00219 } 00220 00221 void sdata_interp::recalc() 00222 { 00223 // recalc_S() also interpolates C matrix if available 00224 recalc_S(); 00225 00226 // if recalc_S didn't generate a C matrix, then generate a passive one 00227 if(!S.has_noise()) data.passive_noise(device::f, device::T); 00228 } 00229 00230 00231 // ******************************************************************** 00232 00233 void S_to_sdata(sdata & SD, const Matrix & S, double Zn) 00234 { 00235 SD.S = S; 00236 SD.set_znorm(Zn); 00237 SD.passive_noise(device::f, device::T); 00238 SD.B = 0.0; 00239 } 00240 00241 00242 Matrix S_renormalize(const Matrix & S, double Znew, double Zold) 00243 { 00244 if(Znew == Zold) 00245 return S; 00246 else { 00247 // assumes S is square with indexing mode Index_1 00248 int N = S.Lmaxindex(); 00249 double r = (Zold - Znew)/(Zold + Znew); 00250 Matrix i = identity_matrix(N); 00251 return solve((i + r*S), (r*i + S)); 00252 } 00253 }
Please direct comments and corrections to
supermix@submm.caltech.edu
Go to the supermix home page
Generated by
1.2.7