• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

/Users/jmonk/Physics/ForIA/src/AnalysisTools/Wavelet.cxx

Go to the documentation of this file.
00001 #include "ForIA/AnalysisTools/Wavelet.hh"
00002 
00003 #include "boost/lexical_cast.hpp"
00004 
00005 #include <cmath>
00006 
00007 #include <stdexcept>
00008 //#include <iostream>
00009 
00010 namespace ForIA{
00012   Wavelet::Wavelet(): m_doInitialise(true), m_haveSetRangeStart(false), m_haveSetRangeEnd(false),
00013   m_nSubSamples(0), m_wavelet(0), m_workspace(0){
00014     
00015   }
00016   
00018   Wavelet::~Wavelet(){
00019     if(m_workspace) gsl_wavelet_workspace_free(m_workspace);
00020     if(m_wavelet) gsl_wavelet_free(m_wavelet);
00021   }
00022   
00024   void Wavelet::initialise(){
00025     
00026     m_nSegments = m_grid.size();
00027     
00028     if(!m_haveSetRangeStart || !m_haveSetRangeEnd){
00029       throw std::runtime_error("Wavelet: Cannot initialise without first setting co-ordinate range of input sequence");
00030     }
00031     
00032     if( ((m_nSegments-1) & m_nSegments)){ 
00033       throw std::runtime_error("Number of segments must be radix 2.  Number given is " + 
00034                                boost::lexical_cast<std::string>(m_nSegments));
00035       return;
00036     }
00037   
00038     m_range = m_max - m_min;
00039     
00040     m_freqMax = 0.5 * (double)m_nSegments / m_range;
00041     
00042     m_freqMin = 0.5 / m_range;
00043     
00044     m_nSubSamples = 0;
00045     
00046     int tmp = m_nSegments;
00047     
00048     while(tmp >>= 1) ++m_nSubSamples;
00049     
00050 //    m_nSubSamples = log2(m_nSegments);
00051         
00052     m_workspace = gsl_wavelet_workspace_alloc(m_nSegments);
00053     
00054     m_wavelet = gsl_wavelet_alloc(gsl_wavelet_daubechies_centered, 4);
00055   
00056     m_bands.clear();
00057     
00058     unsigned int kMax=1;
00059     
00060     unsigned int index=1;
00061     
00062     double freqMin = m_freqMin;
00063     double freqMax = freqMin * 2.;
00064     
00065     unsigned int scale = m_nSegments;
00066     
00067     double physScale = m_range;
00068     
00069     for(unsigned int j=0; j!= nSubBands(); ++j){
00070       
00071       m_bands.push_back(FrequencyBand());
00072       
00073       m_bands.back().m_parent = this;
00074       m_bands.back().m_level = nSubBands() - j;
00075       m_bands.back().m_lowerFreq = freqMin;
00076       m_bands.back().m_upperFreq = freqMax;
00077       m_bands.back().m_physScale = physScale;
00078       
00079       m_bands.back().m_scale = scale;
00080       
00081       double tau_min = m_min;
00082       double tau_incr = m_range / (double)kMax;
00083       double tau_max = tau_min + tau_incr;
00084       
00085       for(unsigned int k=0; k != kMax; ++k){
00086         
00087         m_bands.back().m_coefficients.push_back(Coefficient());
00088         m_bands.back().m_coefficients.back().m_arrayPosition=index;
00089         m_bands.back().m_coefficients.back().m_level = m_bands.back().level();
00090         m_bands.back().m_coefficients.back().m_index = k;
00091         m_bands.back().m_coefficients.back().m_upper = tau_max;
00092         m_bands.back().m_coefficients.back().m_lower = tau_min;
00093         
00094         m_bands.back().m_coefficients.back().m_scale = scale;
00095         
00096         tau_min = tau_max;
00097         tau_max += tau_incr;
00098         
00099         ++index;
00100       }
00101       
00102       freqMin = freqMax;
00103       freqMax *= 2.;
00104       kMax *= 2;
00105       scale /= 2;
00106       physScale *= 0.5;
00107     }    
00108     
00109     m_doInitialise = false;
00110     
00111     return;
00112   }
00113   
00115   void Wavelet::setRangeStart(double min){
00116     if(!m_doInitialise){
00117       throw std::runtime_error("Wavelet: Cannot set start range of co-ordinate after initialisation!");
00118     }
00119     
00120     m_min = min;
00121     
00122     m_haveSetRangeStart = true;
00123     return;
00124   }
00125   
00127   void Wavelet::setRangeEnd(double max){
00128     if(!m_doInitialise){
00129       throw std::runtime_error("Wavelet: Cannot set end range of co-ordinate after initialisation!");
00130     }
00131     
00132     m_max = max;
00133     
00134     m_haveSetRangeEnd = true;
00135     return;
00136   }
00137   
00139   unsigned int Wavelet::nSubBands()const{
00140     return m_nSubSamples;
00141   }
00142   
00144   const Wavelet::FrequencyBand &Wavelet::frequencyBand(unsigned int level)const{
00145     unsigned int index = nSubBands() - level;
00146     return m_bands[index];
00147   }
00148   
00150   const Wavelet::Coefficient &Wavelet::coefficient(unsigned int level, unsigned int index)const{
00151     return frequencyBand(level).coefficient(index);
00152   }
00153   
00155   void Wavelet::setGrid(const vector<double> &grid){
00156         
00157     m_grid = grid;
00158     
00159     if(m_doInitialise) initialise();
00160     
00161     if(m_grid.size() != m_nSegments){
00162       throw std::runtime_error("Number of segments has changed since initialisation! Was first called with " + 
00163                                boost::lexical_cast<std::string>(m_nSegments) + 
00164                                " segments, now being called with " + boost::lexical_cast<std::string>(m_grid.size()));
00165     }
00166     
00167     vector<double> output(grid.begin(), grid.end());
00168         
00169     int status = gsl_wavelet_transform_forward(m_wavelet, &(output[0]), 1, m_nSegments, m_workspace);
00170     
00171     if(status != GSL_SUCCESS){
00172       throw std::runtime_error("Wavelet transform failed due to either lack of memory or data that is not radix 2!");
00173     }
00174             
00175     m_smoothing = output[0];
00176     
00177     unsigned int index=1;
00178     
00179     for(vector<FrequencyBand>::iterator band = m_bands.begin();
00180         band != m_bands.end(); ++band){
00181     
00182       band->m_doEnergy = true;
00183       band->m_doVar = true;
00184       band->m_doAv = true;
00185       for(vector<Coefficient>::iterator coeff = band->m_coefficients.begin();
00186           coeff != band->m_coefficients.end(); ++coeff){
00187                 
00188         coeff->m_magnitude = output[index];
00189 
00190         ++index;
00191       }
00192              
00193     }
00194     
00195     return;
00196   }
00197   
00199   void Wavelet::invert(vector<double> &sequence)const{
00200     
00201     if(sequence.size() != m_nSegments){
00202       throw std::runtime_error("Number of segments in sequence to be inverted (" + 
00203                                boost::lexical_cast<string>(sequence.size()) + ") does not match wavelet (" + 
00204                                boost::lexical_cast<string>(m_nSegments) + ")");
00205     }
00206         
00207     gsl_wavelet_transform_inverse(m_wavelet, &(sequence[0]), 1, m_nSegments, m_workspace);
00208     
00209     return;
00210   }
00211   
00213   MessageBox &operator << (MessageBox &box, const Wavelet::FrequencyBand &freq){
00214     box.setTitle("Wavelet Frequency Band");
00215     
00216     box.addEntry("Level", freq.level());
00217     box.addEntry("Scale factor", freq.scale());
00218     box.addEntry("Physical scale", freq.physicalScale());
00219     box.addEntry("Number of Coefficients", freq.nCoefficients());
00220     box.addEntry("Frequency range", "{ " + boost::lexical_cast<string>(freq.lower_frequency()) + ", " + 
00221                  boost::lexical_cast<string>(freq.upper_frequency()) + "}");
00222     
00223     return box;
00224   }
00225   
00227   std::ostream &operator << (std::ostream &out, const Wavelet::FrequencyBand &freq){
00228     MessageBox tmp;
00229     
00230     tmp<<freq;
00231     out<<tmp;
00232     
00233     return out;
00234   }
00235   
00236 }
00237 
00238 

Generated on Mon Jul 30 2012 16:56:35 for ForIA by  doxygen 1.7.2