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 // mixer_helper.h 00032 // 00033 // mixer_helper.h holds the private members and classes defined within 00034 // the mixer class. 00035 // 00036 // THIS FILE IS MEANT TO BE INCLUDED ONLY BY mixer.h AND WITHIN THE 00037 // DEFINITION OF CLASS mixer !!! 00038 // 00039 // holds classes mixer::balancer and mixer::analyzer 00040 // 00041 // F. Rice 12/15/98 00042 // 00043 // 7/21/99: Changed balancer to be derived from newton vice nonlin_sys 00044 // 00045 // ******************************************************************** 00046 00047 // Here are the private member data and functions of class mixer: 00048 00049 // class mixer : public data_ptr_nport 00050 private: 00051 00052 void auto_state(); // fix invalid junction states or exit. 00053 void recalc(); // the small signal mixer analysis. 00054 void changed() // tell the caculators that the mixer has 00055 { // changed, so their structures will be rebuilt. 00056 balance_.changed(); ssignal_.changed(); tsignal_.changed(); 00057 balance_not_ok_flag = (num_junctions != 0); 00058 } 00059 00060 static unsigned global_mixer_index; // used to detect multiple mixer circuits 00061 int max_harmonics; // how many harmonics 00062 int num_junctions; // how many junctions 00063 double LO_saved; // the LO freq used at last balance time 00064 int balance_init_flag; // if nonzero, balance() initializes states 00065 int auto_balance_flag; // if nonzero, recalc() will call balance() 00066 int balance_not_ok_flag; // something changed since last balance 00067 00068 nport *bias_circuit, *if_circuit, *rf_circuit; // the linear circuit objects 00069 std::vector <nport *> term; // rf_circuit port terminators for balance 00070 std::vector<generator> default_term; // default Z0 terminators for RF circuit 00071 std::vector <junction *> junc; // the junction objects 00072 00073 // ******************************************************************** 00074 00075 // This is the class which actually performs the linear balance operation. 00076 // It uses a multidimensional Newton-Raphson algorithm inherited from 00077 // class newton. 00078 00079 class balancer : private newton 00080 { 00081 public: 00082 00083 balancer(mixer &);// The constructor 00084 00085 int operator()(); // Perform a harmonic balance of the mixer, using 00086 // the current operating state as a starting point. 00087 00088 void i_state(); // initialize the junction operating states using 00089 // the linear circuit voltages, but do not balance 00090 00091 inline void changed() { must_rebuild = 1; } 00092 // tell balancer that the mixer circuit has 00093 // changed, so that it will rebuild its internal 00094 // structures on the next balance. This must be called 00095 // anytime num_junctions, max_harmonics, rf_circuit, 00096 // or term changes. 00097 00098 balancer & parameters( 00099 int MAXITS, // maximum number of iterations 00100 double TOLF, // single voltage balance error tolerance 00101 double TOLMIN, // variance of all voltages from balance tolerance 00102 double TOLX, // change in a single voltage step tolerance 00103 double ALF // if variance of all voltages changes by less than 00104 // this, assume at a local minimum of the error function 00105 ); 00106 00107 int iterations() // the number of iterations required by the most recent 00108 { return iter; } // balance operation. 00109 00110 private: 00111 // member functions: 00112 void init(); // set up balancer to start the balance 00113 void calc(); // calculate currents and derivatives 00114 void rebuild(); // if reqd, rebuild data structures and clear must_rebuild. 00115 void fill_data(); // fetch all the linear circuit sdatas 00116 00117 // data: 00118 mixer & mix; // reference to this mixer object 00119 int must_rebuild; // flag to tell init() to rebuild data 00120 real_vector ival; // temporarily hold junction currents 00121 int iter; // iteration counter 00122 std::vector<const Matrix*> pY; // will point to junction Ymn 00123 std::vector<sdata> linear; // will hold linear circuit sdatas 00124 vector<generator> default_term; // our Z0 terminations 00125 circuit temp; // hold the terminated RF circuit 00126 struct 00127 { 00128 // these values define the internal representation for the vectors 00129 // used by the newton member functions: 00130 int length, // the length of newton::xlast 00131 harm_inc, // index increment to step to next harmonic 00132 junc_inc, // index increment to step to next junction 00133 imag_inc; // index increment to step to imaginary part 00134 } 00135 rep; // the scheme is established by init() 00136 00137 // helper functions (n is a junction index, m is a harmonic number): 00138 inline int index(int n, int m); // calculate location in representation 00139 inline complex B(int n, int m); // linear source vector element 00140 inline complex S(int n1, int n2, int m); // linear S matrix element 00141 inline complex Y(int n, int m1, int m2); // junction Y matrix element 00142 complex SV(int n, int m, const real_vector & V); // S*V matrix element 00143 00144 00145 // more helpers: these functions move junction state data to and from the 00146 // internal newton vector representations: 00147 void to_rep(real_vector & rep, const Vector & state, int n); 00148 void fm_rep(Vector & state, const real_vector & rep, int n); 00149 00150 }; // class mixer::balancer 00151 00152 friend class mixer::balancer; 00153 00154 // ******************************************************************** 00155 00156 // This is the class which performs the small signal and noise analysis 00157 // of a previously balanced mixer 00158 00159 class analyzer 00160 { 00161 public: 00162 00163 analyzer(mixer &);// The constructor 00164 00165 const sdata & operator()(); // Perform the small signal and noise 00166 // analyses and return the resulting sdata object 00167 00168 inline void changed() { must_rebuild = 1; } 00169 // tell analyzer that the mixer circuit has 00170 // changed, so that it will rebuild its internal 00171 // structures on the next call. This must be called 00172 // anytime num_junctions, max_harmonics, rf_circuit, 00173 // or term changes. 00174 00175 analyzer & terminate_rf(int); // tell analyzer whether or not it should 00176 // terminate the rf circuit with balance terminators 00177 // when performing the analysis. 00178 // Nonzero argument: terminate first 00179 // Zero argument: don't terminate 00180 // Applies to all subsequent calls to operator (). 00181 00182 private: 00183 // member functions: 00184 void rebuild(); // if reqd, rebuild data structures and clear must_rebuild. 00185 void fill_data(); // fetch all the component circuit and junction sdatas 00186 00187 // data: 00188 sdata result; // the results of the analysis 00189 mixer & mix; // reference to this mixer object 00190 int must_rebuild; // flag to rebuild data 00191 int terminate_flag; // must terminate rf circuit if set 00192 std::vector<sdata> linear_p; // will hold linear circuit sdatas for h>=0 00193 std::vector<sdata> linear_m; // will hold linear circuit sdatas for h<0 00194 std::vector<sdata> junctions; // will hold junction response sdatas 00195 circuit temp; // hold the terminated RF circuit, if required 00196 Matrix T_, X_, Y_; // temporaries 00197 int h_low, h_high, h_size, m_low, m_high, n_low; // limits for indexes 00198 00199 // helper functions (n is a port index, m a junction index, h a harmonic number) 00200 // ranges on the indices: 00201 // h in: { -mix.max_harmonics, +mix.max_harmonics } 00202 // m in: { m_low, m_high }, where: m_high - m_low + 1 = mix.num_junctions 00203 // n in: if (h == 0): { mix.num_junctions + 1, mix.if_circuit->size() } 00204 // if (h != 0 && terminate_flag == 0): 00205 // { mix.num_junctions + 1, mix.rf_circuit->size() } 00206 // if (h != 0 && terminate_flag != 0): 00207 // { } 00208 00209 int n_high(int h); // return maximum external port index at harmonic h 00210 inline int Delta(int i, int j) // Kronecker Delta 00211 { return (i == j); } 00212 00213 inline complex & S11(int n1, int n2, int h); // linear S joining two ports 00214 inline complex & S12(int n, int m, int h); // linear S joining junction to port 00215 inline complex & S21(int m, int n, int h); // linear S joining port to junction 00216 inline complex & S22(int m1, int m2, int h); // linear S joining two junctions 00217 00218 inline complex & C11(int n1, int n2, int h); // linear C joining two ports 00219 inline complex & C12(int n, int m, int h); // linear C joining junction to port 00220 inline complex & C21(int m, int n, int h); // linear C joining port to junction 00221 inline complex & C22(int m1, int m2, int h); // linear C joining two junctions 00222 00223 inline complex & S(int n1, int n2, int h1, int h2); // access result S matrix 00224 inline complex & C(int n1, int n2, int h1, int h2); // access result C matrix 00225 00226 inline complex & Sj(int m, int h1, int h2); // junction S matrix element 00227 inline complex & Cj(int m, int h1, int h2); // junction C matrix element 00228 00229 inline complex & T(int m1, int m2, int h1, int h2); // access T_ matrix 00230 inline complex & X(int n, int m, int h1, int h2); // access X_ matrix 00231 inline complex & Y(int n, int m, int h1, int h2); // access Y_ matrix 00232 00233 inline complex * Xrow(int n, int h); 00234 inline int Xcol(int m, int h); 00235 inline complex * Yrow(int n, int h); 00236 inline int Ycol(int m, int h); 00237 00238 void calc_T(); // calculate the T_ matrix 00239 void calc_X(); // calculate the X_ matrix 00240 void calc_Y(); // calculate the Y_ matrix 00241 00242 }; // mixer::analyzer 00243 00244 friend class mixer::analyzer; 00245 00246 mixer::balancer balance_; // the actual balancer object 00247 mixer::analyzer ssignal_; // the small signal analysis object 00248 mixer::analyzer tsignal_; // the analysis object for terminated rf_circuit ports 00249 00250 // end of the private section of class mixer
Please direct comments and corrections to
supermix@submm.caltech.edu
Go to the supermix home page
Generated by
1.2.7