Marsyas
0.6.0-alpha
|
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 }