casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SimButterworthBandpass.h
Go to the documentation of this file.
00001 //# SimButterworthBandpass.h: Declares a Butterworth function
00002 //# Copyright (C) 2000,2001,2002,2003
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: SimButterworthBandpass.h 20229 2008-01-29 15:19:06Z gervandiepen $
00027 
00028 #ifndef SCIMATH_SIMBUTTERWORTHBANDPASS_H
00029 #define SCIMATH_SIMBUTTERWORTHBANDPASS_H
00030 
00031 //# Includes
00032 #include <casa/aips.h>
00033 #include <casa/Containers/Block.h>
00034 #include <scimath/Functionals/Function1D.h>
00035 
00036 namespace casa { //# NAMESPACE CASA - BEGIN
00037 
00038 //# Forward Declarations
00039 template<class T> class Vector;
00040 
00041 // <summary>
00042 // a class for evaluating a Butterworth filter transfer function.
00043 // </summary>
00044 
00045 // <use visibility=export>
00046 
00047 // <reviewed reviewer="wbrouw" date="2001/11/14"
00048 // tests="tSimButterworthBandpass" demos="">
00049 // </reviewed>
00050 
00051 // <prerequisite>
00052 //   <li> <linkto class="FunctionParam">FunctionParam</linkto> class
00053 //   <li> <linkto class=Function1D>Function1D</linkto>
00054 // </prerequisite>
00055 //
00056 // <etymology>
00057 // "Butterworth" refers to the Butterworth function for describing
00058 // filter transfer functions (Butterworth, S, "On the theory of filter 
00059 // amplifiers," Wireless Engineer, vol. 7 pp. 536-541, October 1930).
00060 // "Bandpass" reflects that the transfer function is has both low and high
00061 // frequency cutoffs.  
00062 // "Sim" indicates that this implementation is not necessarily appropriate 
00063 // characterizing real bandpass filters; in the future, there may be a 
00064 // more general class called simply "Butterworth".  
00065 // </etymology>
00066 //
00067 // <synopsis>
00068 // This function class simulates the (amplitude) transfer function for a 
00069 // wideband bandpass filter constructed from the combination of a low-pass 
00070 // and a high-pass Butterworth filter.  
00071 //
00072 // In analog electronic filter design, a Butterworth low-pass filter is 
00073 // one in which the amplitude transfer function, |H(jw)| (where j = sqrt(-1) 
00074 // and w is the angular frequency), is given by:
00075 // <srcblock>
00076 //   |H(jw)| = 1 / sqrt(1 + (w/w_c)^(2*n)) 
00077 // </srcblock>
00078 // where n refers to the filter "order" and w_c is the "cutoff frequency".  
00079 // When w = w_c, the filter output is 1/sqrt(2) that of the input, and the 
00080 // higher the order, the steeper the drop off towards zero and the closer 
00081 // the approximation to a idealized step function.  
00082 //
00083 // Filter theory provides transformations for deriving transfer functions 
00084 // of high-pass and band-pass filters which reflect how the electrical 
00085 // circuits actually work.  However, to simplify this class's implementation 
00086 // and to make the transfer function behavior more predictable by the naive 
00087 // user, THIS CLASS DOES NOT ACTUALLY USE THE PROPER TRANSFORMATIONS (see 
00088 // Etymology section above).  
00089 // Instead, the Butterworth bandpass transfer function is approximated by 
00090 // low pass component, given above, combined with a pseudo high-pass function
00091 // that is of the same form but with w substituted with -w.  Both components 
00092 // are shifted such that its peak transfer point is at a given "center" 
00093 // position.  The cutoff value and order can be set independently for both
00094 // ends of the passband.  
00095 // </synopsis>
00096 //
00097 // <example>
00098 // <srcblock>
00099 //   // Create a bandpass function centered on x=0.8 and cutoffs at 0 and 2.5.
00100 //   // The orders of the drop-offs will 4 at the low end and 5 at the high
00101 //   // end.  The peak will by 1.0 by default.
00102 //   SimButterworthBandpass<Double> butt(4, 5, 0, 2.5, 0.8);
00103 //   
00104 //   Double z = butt(1);    // z = 1.0
00105 //   z = butt(0);           // z = 1/sqrt(2)
00106 //   z = butt(2.5);         // z = 1/sqrt(2)
00107 //   z = butt(-25);         // z ~ 9.24e-9 ~ 0
00108 //
00109 //   // change the low-end cutoff to -25.0
00110 //   butt.setMinCutoff(-25);
00111 //   z = butt(-25);         // z = 1/sqrt(2)
00112 // </srcblock>
00113 // </example>
00114 //
00115 // <motivation>
00116 // This class was created to simulate systemtic Butterworth bandpasses 
00117 // within the simulator tool.  It can used by the SimBJones class to vary the 
00118 // bandpass in a predictable way.  However, it has limited value for real 
00119 // filter analysis, and it is not expected to be a realistic representation
00120 // of real bandpass filters in use with radio telescopes backends.  
00121 // </motivation>
00122 //
00123 // <templating arg=T>
00124 //  <li> T should have standard numerical operators. Current
00125 //      implementation only tested for real types (and their AutoDiffs).
00126 // </templating>
00127 //
00128 // <thrown>
00129 //    <li> Assertion if indices out-of-range
00130 // </thrown>
00131 //
00132 // <todo asof="2001/11/14">
00133 //  <li> Nothing I know of
00134 // </todo>
00135 
00136 template<class T>
00137 class SimButterworthBandpass : public Function1D<T>
00138 {
00139 public:
00140     //# Enumerations
00141     // Enumeration of the function parameters
00142     enum { CENTER, MINCUTOFF, MAXCUTOFF, PEAK };
00143 
00144   //# Constructors
00145   // create a zero-th order (all-pass) Butterworth bandpass function.
00146     SimButterworthBandpass();
00147   
00148     // create a Butterworth bandpass function.
00149     SimButterworthBandpass(const uInt minord, const uInt maxord, 
00150                            const T &mincut=T(-1), const T &maxcut=T(1), 
00151                            const T &center=T(0), const T &peak=T(1));
00152   
00153     // create a fully specified Butterworth bandpass in which the 
00154     // low and high pass orders are stored in a Record
00155     explicit SimButterworthBandpass(const RecordInterface& gr,
00156                                     T mincut=T(-1), T maxcut=T(1), 
00157                                     T center=T(0), T peak=T(1));
00158 
00159     // create a copy of another Butterworth bandpass function
00160     SimButterworthBandpass(const SimButterworthBandpass &other);
00161   
00162     // copy(deep) another Butterworth function
00163     SimButterworthBandpass<T> &
00164     operator=(const SimButterworthBandpass<T> &other);
00165   
00166   // Destructor
00167     virtual ~SimButterworthBandpass();
00168 
00169 
00170     //# Operators    
00171     // Evaluate the bandpass at "x".
00172     virtual T eval(const typename FunctionTraits<T>::ArgType *x) const;
00173 
00174   //# Member functions
00175   // set the center of the bandpass.  This is the x-ordinate value that 
00176   // evaluates to the peak of the function.  
00177     void setCenter(const T &x) { param_p[CENTER] = x; } 
00178 
00179     // return the center of the bandpass.  This is the x-ordinate value that 
00180     // evaluates to the peak of the function.  
00181     const T &getCenter() const { return param_p[CENTER]; }
00182 
00183     // set the characteristic minimum (high-pass) cutoff value.  At this 
00184     // x-ordinate value, the function has a value reduced 30 dB from its 
00185     // peak.  
00186     void setMinCutoff(const T &x) { param_p[MINCUTOFF] = x; } 
00187 
00188     // set the characteristic maximum (low-pass) cutoff value.  At this 
00189     // x-ordinate value, the function has a value reduced 30 dB from its 
00190     // peak.  
00191     void setMaxCutoff(const T &x) { param_p[MAXCUTOFF] = x; } 
00192 
00193     // set the order of the Butterworth function for the minimum (high-pass)
00194     // portion of the bandpass
00195     void setMinOrder(uInt order) { nl_p = order; }
00196 
00197     // set the order of the Butterworth function for the maximum (low-pass)
00198     // portion of the bandpass
00199     void setMaxOrder(uInt order) { nh_p = order; }
00200 
00201     // return the characteristic minimum (high-pass) cutoff value.  At this 
00202     // x-ordinate value, the function has a value reduced 30 dB from its 
00203     // peak.  
00204     const T &getMinCutoff() const { return param_p[MINCUTOFF]; }
00205 
00206     // return the characteristic maximum (low-pass) cutoff value.  At this 
00207     // x-ordinate value, the function has a value reduced 30 dB from its 
00208     // peak.  
00209     const T &getMaxCutoff() const { return param_p[MAXCUTOFF]; }
00210 
00211     // return the order of the Butterworth function for the minimum (high-pass)
00212     // portion of the bandpass
00213     uInt getMinOrder() const { return nl_p; }
00214 
00215     // return the order of the Butterworth function for the maximum (low-pass)
00216     // portion of the bandpass
00217     uInt getMaxOrder() const { return nh_p; }
00218 
00219     // set the scale of the function by setting its peak value.  By default,
00220     // the peak value is T(1);
00221     void setPeak(T val) { param_p[PEAK] = val; } 
00222 
00223     // return the scale of the function
00224     const T &getPeak() const { return param_p[PEAK]; }
00225   
00226     // get/set the function mode.  This is an alternate way to get/set the 
00227     // non-coefficient data for this function.  The supported record fields 
00228     // are as follows:
00229     // <pre>
00230     // Field Name     Type            Role
00231     // -------------------------------------------------------------------
00232     // minOrder   TpInt   the order of the Butterworth function for the 
00233     //                    minimum (high-pass) portion of the bandpass
00234     // maxOrder   TpInt   the order of the Butterworth function for the 
00235     //                    maximum (low-pass) portion of the bandpass
00236     // An exception is thrown if either value is less than zero
00237     // </pre>
00238     // <group>
00239     virtual void setMode(const RecordInterface& mode);
00240     virtual void getMode(RecordInterface& mode) const;
00241     // </group>
00242 
00243     // return True if the implementing function supports a mode.  This
00244     // implementation always returns True.
00245     virtual Bool hasMode() const;
00246 
00247     // clone this function
00248     virtual Function<T> *clone() const {
00249         return new SimButterworthBandpass<T>(*this); 
00250     }
00251 
00252 private:
00253     //# Non-parameter Data
00254     // Minimum order
00255     uInt nl_p;
00256     // Maximum order
00257     uInt nh_p;
00258 
00259   //# Make members of parent classes known.
00260 protected:
00261   using Function<T>::param_p;
00262 public:
00263   using Function<T>::nparameters;
00264 };
00265 
00266 
00267 } //# NAMESPACE CASA - END
00268 
00269 #ifndef CASACORE_NO_AUTO_TEMPLATES
00270 #include <scimath/Functionals/SimButterworthBandpass.tcc>
00271 #endif //# CASACORE_NO_AUTO_TEMPLATES
00272 #endif