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 // simple_error_func.h 00032 // 00033 // Contains the abstract class "error_func_parameters", which provides an 00034 // implementation of the parameter manipution virtual functions of class 00035 // abstract_error_func, by controlling the values of program variables 00036 // of type parameter. 00037 // 00038 // 4/21/99 by John Ward 00039 // 00040 // Based on err_func.h written 7/22/98 J.Z. 00041 // 00042 // 9/11/00: Changed class name to error_func_parameters; included typedef 00043 // 9/8/00: Inlined simple_error_func::vary_parameter::get(), set(). Some 00044 // general rearrangement of functionality. 00045 // 00046 // ************************************************************************ 00047 // class error_func_parameters 00048 // 00049 // Class error_func_parameters implements the required parameter interface 00050 // to an optimizer derived from class minimizer (see optimizer.h). It 00051 // interfaces the elements of the real_vector parameter lists of the virtual 00052 // member functions set_parms(), get_parms(), etc., of class 00053 // abstract_error_func with individual program variables of class parameter. 00054 // 00055 // By using an error function derived from this class, an optimizer can 00056 // indirectly control the values of any number of program variables 00057 // contained in parameter class objects. Since most variables controlling 00058 // the behavior of the various SuperMix circuit elements are parameter 00059 // objects, the interface provided by error_func_parameters is powerful 00060 // enough for most optimization needs. 00061 // 00062 // Class error_func_parameters does not, however, provide code for actual 00063 // calculation of an error function value (absract_error_func::func_value()). 00064 // This function must be defined in a class derived from error_func_parameters. 00065 // An error function which does this is class "error_func", defined in 00066 // error_func.h. It provides a ready to use, powerful error function 00067 // capability suitable for many optimization problems. 00068 // 00069 // 00070 // USAGE: 00071 // 00072 // Use class err_func, derived from class error_func_parameters, or 00073 // derive a new class of your own from error_func_parameters. 00074 // 00075 // 00076 // CONTROLLING PROGRAM PARAMETER VARIABLES 00077 // 00078 // Assume you are using the error function class ef_class, which is 00079 // derived from class error_func_parameters. Then you can give your 00080 // optimizer control of various program parameters using the vary() 00081 // member function as in the following example: 00082 // 00083 // Assume your program has to optimize a resistance R, a length L, and 00084 // a coupling parameter K. In order to be manipulated by your error 00085 // function, these variables must be held in objects of type "parameter"; 00086 // they may be global, local, or members of some class object or objects: 00087 // 00088 // parameter R, L, K; // these are the variables to optimize 00089 // 00090 // Assume that the appropriate units for R and L are ohms and centimeters, 00091 // respectively; assume K is a pure number between 0 and 1. As you are 00092 // familiar with the units definitions in the header file units.h, you 00093 // give your error function control of R, L, and K as follows: 00094 // 00095 // ef_class ef; // declare your error function object 00096 // 00097 // R = ef.vary(10, 25, 100, Ohm); // Range: 10*Ohm <= R <= 100*Ohm 00098 // // Initial value: R = 25*Ohm 00099 // 00100 // L = ef.vary(0, .1, 1.2, Centi*Meter); 00101 // 00102 // K = ef.vary(0, .5, 1.0); // no units needed for K 00103 // 00104 // The vary() member function returns a pointer to abstract_real_parameter; 00105 // the assignment actually causes the parameter on the left hand side of 00106 // the equal sign to "shadow" the abstract_real_parameter, so its value 00107 // changes along with changes to the value of the shadowed variable. The 00108 // pointer refers to an internal variable created within the error function 00109 // object; each call to vary() creates another internal variable. Calls by 00110 // the optimizer to ef.set_parms() change the values of the internal 00111 // variables; the shadowing mechanism causes these changes to in turn 00112 // change the values of the variables R, L and K. 00113 // 00114 // 00115 // INTERFACE TO THE OPTIMIZER 00116 // 00117 // The member functions of class abstract_error_func described in 00118 // optimizer.h provide the interface between an optimization routine and 00119 // the error function's control of the program parameters. The following 00120 // functions, declared virtual in abstract_error_func, are implemented by 00121 // class error_func_parameters: 00122 // set_parms() get_min_parms() get_units() 00123 // get_parms() get_max_parms() size() 00124 // get_parms_user() get_init_parms() 00125 // 00126 // The get_.. functions return real_vectors with index mode Index_1; the 00127 // number of valid elements is equal to the number of calls to vary() 00128 // executed since the error function was created, one element for each 00129 // vary() call. The first valid element corresponds to the program 00130 // variable associated with the first vary() call, the last valid element 00131 // to the most recent vary() call. The same scheme applies, of course, to 00132 // the real_vector argument of set_parms(). 00133 // 00134 // Continuing with the previous example, where we have initialized R,L,K to 00135 // 25*Ohm, 0.1*Centi*Meter, and 0.5, respectively, a call to ef.get_parms() 00136 // would return a real_vector V with contents: 00137 // 00138 // V = ef.get_parms(); 00139 // V[1] == 25*Ohm; V[2] == 0.1*Centi*Meter; V[3] == 0.5; 00140 // 00141 // Calls to other get_.. functions would return: 00142 // 00143 // V = ef.get_parms_user(); 00144 // V[1] == 25.0; V[2] == 0.1; V[3] == 0.5; 00145 // 00146 // V = ef.get_units(); 00147 // V[1] == Ohm; V[2] == Centi*Meter; V[3] == 1.0; 00148 // 00149 // V = ef.get_min_parms(); 00150 // V[1] == 10*Ohm; V[2] == 0.0*Centi*Meter; V[3] == 0.0; 00151 // 00152 // etc. 00153 // 00154 // 00155 // CONTROLLING A COMPLEX-VALUED VARIABLE 00156 // 00157 // Often you will need an optimization of a complex variable. Since the 00158 // optimizer classes are designed to manipulate real-valued variables, 00159 // you need to map two real variables into your complex variable. To do 00160 // this you simply use the class complex_parameter, defined in header file 00161 // parameter/complex_parameter.h, which has the capability of shadowing two 00162 // abstract_real_parameters. 00163 // 00164 // Example: 00165 // complex_parameter C; // the variable we need to optimize 00166 // 00167 // First save the return values from two vary() calls: 00168 // abstract_real_parameter *p1, *p2; 00169 // p1 = ef.vary(...); 00170 // p2 = ef.vary(...); 00171 // 00172 // Here's where the optimizer gets control of the variable: 00173 // // either control the real and imaginary parts (Cartesian scheme): 00174 // C.shadow(*p1, *p2); 00175 // // or control the magnitude and phase(radians) (polar scheme): 00176 // C.shadow(*p1, *p2, complex_parameter::POLAR); 00177 // 00178 // The arguments you provide to the vary() calls will, of course, depend 00179 // on how you plan to control the complex number, ie: Cartesian or polar 00180 // scheme. 00181 // 00182 // ************************************************************************ 00183 00184 #ifndef SIMPLE_ERR_FUNC_H 00185 #define SIMPLE_ERR_FUNC_H 00186 00187 #include "optimizer.h" 00188 #include "vector.h" 00189 #include <list> 00190 00191 // Need to use parameters for the "vary" method. 00192 #include "parameter/abstract_real_parameter.h" 00193 00194 00195 class error_func_parameters : public abstract_error_func 00196 { 00197 00198 public: 00199 00200 // The vary() member function gives error_func_parameter objects the mechanism 00201 // to actually control parameter values external to it, thus giving an 00202 // optimizer routine control through the abstract_error_func interface. 00203 00204 // Each call to the vary command creates a new internal abstract_real_parameter 00205 // object which can have its value controlled by an optimizer. The vary command 00206 // returns a pointer to the abstract_real_parameter it creates, so that external 00207 // parameter variables may shadow it (using assignment). 00208 00209 // vary() allows the user to enter parameters in any convenient units, specifying 00210 // the scaling factor as the last parameter. Note: min > max and units <= 0.0 00211 // are fatal errors. 00212 00213 abstract_real_parameter * vary(double min, double init, double max, 00214 double units = 1.0) ; 00215 00216 00217 // What follows are the implementations of the abstract parameter manipulation 00218 // member functions required to be defined for a class derived from 00219 // abstract_error_func (see optimizer.h). The following functions return 00220 // Index_1 real vectors with parameter values. The sizes of the real_vectors 00221 // may exceed the number of valid elements, but maxindex() will be correctly 00222 // set to the maximum valid element index. 00223 00224 // Return the current parameter values in machine units. 00225 real_vector get_parms() { return parms; } 00226 00227 // Return the current parameter values in user-friendly units. 00228 real_vector get_parms_user(); 00229 00230 // Return the minimum allowed parameter values in machine units. 00231 real_vector get_min_parms() { return minimum; } 00232 00233 // Return the minimum allowed parameter values in machine units. 00234 real_vector get_max_parms() { return maximum; } 00235 00236 // Return the initial parameter values in machine units. 00237 real_vector get_initial_parms() { return initial; } 00238 00239 // Return the scaling factors to use in get_parms_user(). 00240 real_vector get_units() { return units; } 00241 00242 // Return the number of parameters to be varied. 00243 int size() { return num_parms; } 00244 00245 // Set parameter values, taking a vector with any type of indexing. Here is 00246 // how the mapping between a parameter and a real_vector index works: the lowest 00247 // valid index corresponds to the parameter associated with the first vary() 00248 // call; the last valid index corresponds to the parameter associated with the 00249 // most recent vary() call. 00250 void set_parms(const real_vector & pv) ; 00251 00252 // constructor 00253 error_func_parameters(bool no_limits_flag = false) : 00254 abstract_error_func(no_limits_flag), 00255 minimum(0,Index_1), 00256 maximum(0,Index_1), 00257 initial(0,Index_1), 00258 parms(0,Index_1), 00259 units(0,Index_1), 00260 num_parms(0) 00261 { } 00262 00263 00264 private: 00265 00266 // This class is just a double wrapped in an abstract_real_parameter. 00267 // It is needed so that an external parameter that must be varied 00268 // during the course of an optimization can shadow it. 00269 class vary_parameter : public abstract_real_parameter 00270 { 00271 private: 00272 // The value of the parameter 00273 double value ; 00274 00275 public: 00276 00277 // The constructor needs an initial value. 00278 vary_parameter(double initial) : value(initial) { } 00279 00280 // Return the parameter value. 00281 double get() const { return value; } 00282 00283 // Set the parameter value. 00284 void set(double x) { value = x; } 00285 } ; 00286 00287 // WARNING: current needs to be a list<>, since we take pointers to the 00288 // individual vary_parameter elements which must remain valid as the list 00289 // is expanded. 00290 00291 // Current parameter values: 00292 std::list<vary_parameter> current; 00293 00294 // Store information about the parameters in vectors. 00295 // Minimum and maximum parameter values. 00296 real_vector minimum; 00297 real_vector maximum; 00298 00299 // Initial parameter values. 00300 real_vector initial; 00301 00302 // Current parameter values. 00303 real_vector parms; 00304 00305 // Parameter units, or scaling factor. 00306 real_vector units; 00307 00308 // The number of parameters added to the parameter vectors. 00309 int num_parms; 00310 00311 // Return a limited init so that min <= init <= max. Used by vary(). 00312 double limit(double min, double init, double max) 00313 { return (init < min) ? min : ((init > max) ? max : init); } 00314 00315 } ; 00316 00317 typedef error_func_parameters simple_error_func; // backward compatibility 00318 00319 #endif /* SIMPLE_ERR_FUNC_H */
Please direct comments and corrections to
supermix@submm.caltech.edu
Go to the supermix home page
Generated by
1.2.7