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 //
00032 // sweeper.h
00033 //
00034 // class for sweeping parameter values
00035 //
00036 // 7/20/98 J.Z.
00037 //
00038 // 12/18/00: Added sweep() taking an interpolator<> range argument.
00039 // 12/18/00: Added sweep() with units argument
00040 // 3/20/00: Added npoints() to sweeper class
00041 // 3/17/00: Fixed problems with multi-parameter sweeps. Extensive comments.
00042 // 4/26/99: Added initialize member function. JSW
00043 //
00044 // ************************************************************************
00045 // Using the sweeper class:
00046 //
00047 // Sweepers manage setting one or more parameters through a desired range
00048 // of values. They are used by the class error_func to sum error term
00049 // calculations over a range of parameter values such as a frequency range.
00050 // Sweepers may prove useful in other applications as well. Here is an
00051 // example of how to use a sweeper:
00052 //
00053 // parameter p1, p2;
00054 // sweeper s;
00055 // s.sweep(p1, 0.0, 1.0, 0.1);
00056 // s.sweep(p2, 2.0, 3.0, 0.5, GHz);
00057 //
00058 // We've set up sweeper s to sweep the values of p1 and p2; p1 goes from
00059 // 0.0 to 1.0 in increments of 0.1, p2 from 2.0*GHz to 3.0*GHz in increments
00060 // of 0.5*GHz (Note that "GHz" is just a double value that sweeper uses as a
00061 // scale factor for the range and increment arguments). Thus we have defined
00062 // a 2-dimensional grid of points described by ordered pairs of (p1,p2). The
00063 // range, increment, and scale factor arguments of sweep() must evaluate to
00064 // double values; they are only read once: at the time sweep() is executed.
00065 //
00066 // We can use the sweeper s to loop through the points as follows:
00067 //
00068 // for(s.reset(); !s.finished(); s++) { your calculation here }
00069 //
00070 // s.reset() sets the two parameters to their initial values. s++ (or ++s)
00071 // sets the two parameters to the values defined by the next point in the
00072 // grid. The first call of s.sweep() determines the variable which changes
00073 // fastest (the "inner loop") as the grid is traversed; in the above example
00074 // p1 changes fastest. Each call to s++ causes the values of p1 and p2 to be
00075 // updated until the values both "wrap" back to the beginning of the
00076 // grid. At this time s.finished() returns true, and any subsequent s++
00077 // attempts would leave p1 and p2 unchanged and generate warning messages
00078 // until s.reset() is executed to set things up again.
00079 //
00080 // If the values of p1 and/or p2 are changed between calls to s++, they
00081 // will be set to their proper grid values at the next call to s++ (unless
00082 // s.finished() is true).
00083 //
00084 // In addition to the sweep() member function there is initialize(). This
00085 // member function is essentially a single-valued sweep; it ensures that
00086 // its argument parameter is set to the specified value with each call to
00087 // reset() or ++. Here's an example. Adding:
00088 //
00089 // parameter p3;
00090 // s.initialize(p3, 4.0);
00091 //
00092 // to the above code would ensure that p3 is set to 4.0 every time the
00093 // sweeper adjusts the values of p1 and p2.
00094 //
00095 // There are several ways to specify the range of values for a sweep() in
00096 // addition to the way used in the example; see the comments in the
00097 // definition of the sweeper class below. All of the various methods for
00098 // setting the sweep range using sweep() require that the range values be
00099 // fully defined at the time sweep() is executed; the arguments are only
00100 // evaluated once at the time of the sweep() call.
00101 //
00102 //
00103 // The sweeper::setup() function:
00104 //
00105 // the setup() function is called by a sweeper just after it sets parameter
00106 // values during reset() or ++. As defined, setup() does nothing, but it is
00107 // declared virtual. If you need to perform some function following the
00108 // setting of parameters to the next point on the sweep grid, then derive a
00109 // new class from class sweep and simply define the setup function in this
00110 // derived class to do whatever you wish. Example:
00111 //
00112 // class my_sweeper : public sweeper {
00113 // void setup() { setup code goes here }
00114 // };
00115 //
00116 // my_sweeper s;
00117 //
00118 // ************************************************************************
00119
00120 #ifndef SWEEPER_H
00121 #define SWEEPER_H
00122
00123 #include "parameter/real_parameter.h"
00124 #include <vector> // STL vector template class
00125 #include <list> // STL linked list template class
00126 #include "vector.h" // SuperMix numerical vector classes
00127 #include "interpolate.h" // SuperMix interpolator<> classes
00128
00129 class sweeper
00130 {
00131
00132 public:
00133
00134 // constructor takes no arguments
00135 sweeper();
00136
00137 // sweep() defines the parameters to control and the range of values.
00138 // The versions which pass a container of values make local copies of
00139 // those values; the container must be filled with the desired values
00140 // at the time sweep() is executed.
00141
00142 // Specify start, stop and increment values:
00143 void sweep(real_parameter &rp, double start, double stop, double step) ;
00144
00145 // Include a scale factor (units) for the values
00146 void sweep(real_parameter &rp, double start, double stop, double step,
00147 double units)
00148 { sweep(rp, start*units, stop*units, step*units); }
00149
00150 // Pass a C-style array of values with a length:
00151 void sweep(real_parameter &rp, double values[], int length) ;
00152
00153 // Pass a SuperMix real_vector of values:
00154 void sweep(real_parameter &rp, const real_vector & values) ;
00155
00156 // Pass an STL vector<double> of values:
00157 void sweep(real_parameter &rp, const std::vector<double> & values) ;
00158
00159 // Pass a SuperMix interpolator<>; uses the x values of the
00160 // points used in the interpolation. The interpolator must be filled and
00161 // its build() function must have been called. See interpolate.h for info
00162 // about creating and building an interpolator<>.
00163 template <class T>
00164 void sweep(real_parameter &rp, const interpolator<T> & values)
00165 {
00166 if(!values.ready()) {
00167 error::fatal("sweeper::sweep(): Must build interpolator before"
00168 "passing it to sweep().");
00169 }
00170
00171 // not the most efficient way, but it works
00172 std::vector<double> v;
00173 int n = values.size();
00174 for(int i = 0; i < n; ++i)
00175 v.push_back(values.x(i));
00176 sweep(rp, v);
00177 }
00178
00179
00180 // This gives a parameter and a value to which it will be set each time
00181 // the sweeper adjusts the values of its swept parameters.
00182 void initialize(real_parameter &rp, double value) ;
00183
00184 // Include a scale factor (units) for the value
00185 void initialize(real_parameter &rp, double value, double units)
00186 { initialize(rp, value*units); }
00187
00188
00189 // This gives the number of points in the grid over with this sweeper
00190 // sweeps. Always returns at least 1, even if no sweeps defined.
00191 int npoints() { return num_values; }
00192
00193
00194 // The following functions actually control and execute the sweep of
00195 // the parameter values:
00196
00197 // reset() - start parameter values at the beginning. Always call this
00198 // function first when you start a sweep of the parameters.
00199 void reset() ;
00200
00201 // increment operators -- go to next set of parameter values
00202 // in the sweep
00203 sweeper & operator ++(int);
00204 sweeper & operator ++() {return((*this)++);}
00205
00206 // finished() goes true when a call to ++ wraps all parameter values
00207 // back to their starting values; it is reset to false by a call to
00208 // reset(). Calls to ++ when finished() is true generate a warning
00209 // message and leave the parameter values unchanged.
00210 bool finished() {return alldone;}
00211
00212 // Derive a class from sweeper and define a useful version of this
00213 // function there if you need to perform some additional set up tasks
00214 // following the adjustment of swept parameters during a sweep
00215 // operation. This function is called by reset() and ++.
00216 virtual void setup() { }
00217
00218 // Since setup() is virtual, we need a virtual destructor:
00219 virtual ~sweeper() { }
00220
00221 private:
00222
00223 // One of these is created and pushed to a list for every call to
00224 // sweep() or initialize():
00225 class sweep_parameter
00226 {
00227 private:
00228 real_parameter * rpr ; // hold a pointer to the actual parameter
00229 bool vecmode ; // vecmode==false for startv, stopv, step;
00230 double startv, stopv, step ; // startv, stopv, step for value
00231 std::vector<double> values ; // or use a vector of values instead
00232 // (in that case vecmode==1)
00233 int num_values ; // number of values
00234 int index ; // index for current value
00235 bool wrapped ; // index wrapped to zero on last increment
00236 double getval() const ; // return current value
00237 // default constructor is hidden
00238 sweep_parameter() { }
00239 public:
00240 // constructor using startv, stopv, step
00241 sweep_parameter(real_parameter &rp, double startvp,
00242 double stopvp, double stepp);
00243 // constructor using C-style array of values
00244 sweep_parameter(real_parameter &rp, double *valp, int nump);
00245 // constructor using Frank Rice's real_vector class
00246 sweep_parameter(real_parameter &rp, const real_vector & rvec);
00247 // constructor using STL vector<double> array of values
00248 sweep_parameter(real_parameter &rp, const std::vector<double> & val);
00249 // postfix increment operator
00250 sweep_parameter & operator ++(int) ;
00251 // set parameter value without incrementing
00252 sweep_parameter & touch();
00253 // set index to zero
00254 void reset() ;
00255 // to check if value wrapped back to start
00256 bool check_wrap() { return wrapped ; }
00257 // number of points in this sweep parameter's range
00258 int npoints() { return num_values; }
00259 };
00260
00261 // Here are the actual private member variables:
00262 std::list<sweep_parameter> parms ; // the list of sweep_parameters
00263 bool alldone ; // goes true when a sweep is completed
00264 int num_values ; // total number of points in a sweep
00265 } ;
00266
00267 #endif /* SWEEPER_H */
00268
Please direct comments and corrections to
supermix@submm.caltech.edu
Go to the supermix home page
Generated by
1.2.7