Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/RBF.cpp
Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 1998-2006 George Tzanetakis <gtzan@cs.uvic.ca>
00003 **
00004 ** This program is free software; you can redistribute it and/or modify
00005 ** it under the terms of the GNU General Public License as published by
00006 ** the Free Software Foundation; either version 2 of the License, or
00007 ** (at your option) any later version.
00008 **
00009 ** This program is distributed in the hope that it will be useful,
00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 ** GNU General Public License for more details.
00013 **
00014 ** You should have received a copy of the GNU General Public License
00015 ** along with this program; if not, write to the Free Software
00016 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017 */
00018 
00019 #include "../common_source.h"
00020 #include "RBF.h"
00021 #include <cmath>
00022 #include <algorithm>
00023 
00024 using namespace std;
00025 using namespace Marsyas;
00026 
00027 //#define MTLB_DBG_LOG
00028 
00029 RBF::RBF(mrs_string name):MarSystem("RBF", name)
00030 {
00031   addControls();
00032 }
00033 
00034 RBF::RBF(const RBF& a) : MarSystem(a)
00035 {
00036   ctrl_RBFtype_ = getctrl("mrs_string/RBFtype");
00037   ctrl_Beta_ = getctrl("mrs_real/Beta");
00038   ctrl_symmetricIn_ = getctrl("mrs_bool/symmetricIn");
00039 }
00040 
00041 RBF::~RBF()
00042 {
00043 }
00044 
00045 MarSystem*
00046 RBF::clone() const
00047 {
00048   return new RBF(*this);
00049 }
00050 
00051 void
00052 RBF::addControls()
00053 {
00054   addctrl("mrs_string/RBFtype", "Gaussian", ctrl_RBFtype_);
00055   ctrl_RBFtype_->setState(true);
00056 
00057   addctrl("mrs_real/Beta", 1.0, ctrl_Beta_);
00058 
00059   addctrl("mrs_bool/symmetricIn", false, ctrl_symmetricIn_);
00060 }
00061 
00062 mrs_real
00063 RBF::GaussianRBF(const mrs_real val) const
00064 {
00065   //as defined in:
00066   //http://en.wikipedia.org/wiki/Radial_basis_function
00067   return exp(-1.0*val*val*ctrl_Beta_->to<mrs_real>());
00068 }
00069 
00070 mrs_real
00071 RBF::MultiquadraticRBF(const mrs_real val) const
00072 {
00073   //as defined in:
00074   //http://en.wikipedia.org/wiki/Radial_basis_function
00075   mrs_real beta = ctrl_Beta_->to<mrs_real>();
00076   return sqrt(val*val+beta*beta);
00077 }
00078 
00079 mrs_real
00080 RBF::ThinPlateSplineRBF(const mrs_real val) const
00081 {
00082   //as defined in:
00083   //http://en.wikipedia.org/wiki/Radial_basis_function
00084   return val*val*log(val);
00085 }
00086 
00087 void
00088 RBF::myUpdate(MarControlPtr sender)
00089 {
00090   (void) sender;  //suppress warning of unused parameter(s)
00091   RBFtype_ = ctrl_RBFtype_->to<mrs_string>();
00092   if(RBFtype_ == "Gaussian")
00093     RBFfunc_ = &RBF::GaussianRBF;
00094   else if(RBFtype_ == "Multiquadratic")
00095     RBFfunc_ = &RBF::MultiquadraticRBF;
00096   else if(RBFtype_ == "ThinPlateSpline")
00097     RBFfunc_ = &RBF::ThinPlateSplineRBF;
00098   else
00099   {
00100     RBFfunc_ = NULL;
00101     MRSWARN("RBF::myUpdate - unsupported RBF function: " + RBFtype_);
00102   }
00103 
00104   ctrl_onObservations_->setValue(ctrl_inObservations_, NOUPDATE);
00105   ctrl_onSamples_->setValue(ctrl_inSamples_, NOUPDATE);
00106   ctrl_osrate_->setValue(ctrl_israte_, NOUPDATE); //[?]
00107   ostringstream oss;
00108   mrs_string inObsNames = ctrl_inObsNames_->to<mrs_string>();
00109   for (mrs_natural i = 0; i < inObservations_; ++i)
00110   {
00111     mrs_string inObsName;
00112     mrs_string temp;
00113     inObsName = inObsNames.substr(0, inObsNames.find(","));
00114     temp = inObsNames.substr(inObsNames.find(",")+1, inObsNames.length());
00115     inObsNames = temp;
00116     oss << "RBF_" << RBFtype_ << "_" << inObsName << ",";
00117   }
00118   ctrl_onObsNames_->setValue(oss.str(), NOUPDATE);
00119 }
00120 
00121 void
00122 RBF::myProcess(realvec& in, realvec& out)
00123 {
00124   mrs_natural o,t;
00125   mrs_real res;
00126 
00127   if(ctrl_symmetricIn_->isTrue())
00128   {
00129     mrs_natural endLoop = min(inSamples_, inObservations_); // just to be sure...
00130     MRSASSERT(in.getRows () >= endLoop);
00131     MRSASSERT(in.getCols () >= endLoop);
00132     for(t=0; t<endLoop; ++t)
00133     {
00134       for(o=0; o<=t; ++o)
00135       {
00136         if(this->RBFfunc_)
00137         {
00138           res = (this->*RBFfunc_)(in(o,t));
00139           //check for NaN and Inf results
00140           if(res != res)
00141           {
00142             MRSERR("RBF::myProcess(): calculation of RBF(x) @" << prefix_ << " is returning NaN/Inf for x(" << o << "," << t << ") = " << in(o,t));
00143           }
00144           else if(res == 0)
00145           {
00146             MRSERR("RBF::myProcess(): calculation of RBF(x) @" << prefix_ << " is returning 0 for x(" << o <<"," << t << ") = " << in(o,t));
00147           }
00148           out(o,t) = res;
00149         }
00150         else
00151           out(o,t) = in(o,t); //just bypass data, unmodified
00152 
00153         //symmetry
00154         out(t,o) = out(o,t);
00155       }
00156     }
00157   }
00158   else
00159   {
00160     for(t=0; t<inSamples_; ++t)
00161     {
00162       for(o=0; o<inObservations_; ++o)
00163       {
00164         if(this->RBFfunc_)
00165         {
00166           res = (this->*RBFfunc_)(in(o,t));
00167           //check for NaN and Inf results
00168           if(res != res)
00169           {
00170             MRSERR("RBF::myProcess(): calculation of RBF(x) @" << prefix_ << " is returning NaN/Inf for x(" << o << "," << t << ") = " << in(o,t));
00171           }
00172           else if(res == 0)
00173           {
00174             MRSERR("RBF::myProcess(): calculation of RBF(x) @" << prefix_ << " is returning 0 for x(" << o <<"," << t << ") = " << in(o,t));
00175           }
00176           out(o,t) = res;
00177         }
00178         else
00179           out(o,t) = in(o,t); //just bypass data, unmodified
00180       }
00181     }
00182   }
00183 #ifdef MARSYAS_MATLAB
00184 #ifdef MTLB_DBG_LOG
00185   MATLAB_PUT(name_, "name");
00186   MATLAB_PUT(out, "out");
00187   MATLAB_EVAL("if (length(out)>1) figure(1);imagesc(out);title(name);colorbar; end");
00188 #endif
00189 #endif
00190 }