00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "Combinator.h"
00020
00021
00022 using std::ostringstream;
00023 using std::min;
00024 using std::max;
00025
00026 using namespace Marsyas;
00027
00028 const mrs_string Combinator::combinatorStrings[kNumCombinators] =
00029 {
00030 "+",
00031 "*",
00032 "max",
00033 "min"
00034 };
00035
00036 Combinator::Combinators_t Combinator::GetCombinatorIdx (const mrs_string ctrlString)
00037 {
00038 Combinators_t ret = kAdd;
00039
00040 for (mrs_natural i = 0; i < kNumCombinators; i++)
00041 {
00042 if (ctrlString == combinatorStrings[i])
00043 return (Combinators_t)i;
00044 }
00045
00046 return ret;
00047 }
00048
00049 Combinator::Combinator(mrs_string name) : MarSystem("Combinator", name)
00050 {
00052
00053
00054
00055
00056
00057 addControls();
00058 }
00059
00060 Combinator::Combinator(const Combinator& a) : MarSystem(a)
00061 {
00062
00065
00066 ctrl_combinator_ = getctrl("mrs_string/combinator");
00067 ctrl_weights_ = getctrl("mrs_realvec/weights");
00068 ctrl_numInputs_ = getctrl("mrs_natural/numInputs");
00069 }
00070
00071
00072 Combinator::~Combinator()
00073 {
00074 }
00075
00076 MarSystem*
00077 Combinator::clone() const
00078 {
00079
00080 return new Combinator(*this);
00081 }
00082
00083 void
00084 Combinator::addControls()
00085 {
00086 mrs_realvec tmp(1);
00087 tmp(0) = 1;
00088
00089 addctrl("mrs_string/combinator", "+", ctrl_combinator_);
00090 addctrl("mrs_realvec/weights", tmp, ctrl_weights_);
00091 addctrl("mrs_natural/numInputs", 1, ctrl_numInputs_);
00092
00093 setctrlState("mrs_natural/numInputs", true);
00094 }
00095
00096 void
00097 Combinator::myUpdate(MarControlPtr sender)
00098 {
00099 MRSDIAG("Combinator.cpp - Combinator:myUpdate");
00100
00102 MarSystem::myUpdate(sender);
00103
00104
00105
00106 if (ctrl_numInputs_->to<mrs_natural>())
00107 updControl ("mrs_natural/onObservations", ctrl_inObservations_->to<mrs_natural>() / ctrl_numInputs_->to<mrs_natural>());
00108 else
00109 updControl ("mrs_natural/onObservations", 0);
00110
00111 }
00112
00113 void
00114 Combinator::myProcess(realvec& in, realvec& out)
00115 {
00116 mrs_natural k,i,j;
00117 mrs_real weight = 1;
00118 mrs_bool useWeights = false;
00119
00120 const Combinators_t combi = GetCombinatorIdx (ctrl_combinator_->to<mrs_string>());
00121 const mrs_natural numInputs = ctrl_numInputs_->to<mrs_natural>();
00122
00123
00124 if(combi == kAdd)
00125 out.setval(0);
00126 if(combi == kMult)
00127 out.setval(1);
00128 if(combi == kMax)
00129 out.setval(-1.0*MAXREAL);
00130 if(combi == kMin)
00131 out.setval(MAXREAL);
00132
00133
00134 if ((inObservations_%numInputs) != 0)
00135 {
00136 MRSWARN("Combinator: dimension mismatch");
00137 MRSASSERT(false);
00138 out.setval(0);
00139 return;
00140 }
00141
00142 if (ctrl_weights_->to<mrs_realvec>().getSize () == numInputs)
00143 useWeights = true;
00144
00146 for (k = 0; k < numInputs; k++)
00147 {
00148 weight = (useWeights) ? (ctrl_weights_->to<mrs_realvec>())(k) : weight;
00149
00150 for (i = 0; i < onObservations_; i++)
00151 {
00152
00153
00154 switch (combi)
00155 {
00156 case kAdd:
00157 default:
00158 {
00159 for (j = 0; j < onSamples_; j++)
00160 out(i,j) += weight * in(i+k*onObservations_,j);
00161 break;
00162 }
00163 case kMult:
00164 {
00165 if (weight == 1.0)
00166 {
00167 for (j = 0; j < onSamples_; j++)
00168 out(i,j) *= in(i+k*onObservations_,j);
00169 }
00170 else
00171 {
00172 for (j = 0; j < onSamples_; j++)
00173 out(i,j) *= pow (in(i+k*onObservations_,j), weight);
00174 }
00175 break;
00176 }
00177 case kMax:
00178 {
00179 for (j = 0; j < onSamples_; j++)
00180 out(i,j) = max (out(i,j),in(i+k*onObservations_,j));
00181 break;
00182 }
00183 case kMin:
00184 {
00185 for (j = 0; j < onSamples_; j++)
00186 out(i,j) = min (out(i,j),in(i+k*onObservations_,j));
00187 break;
00188 }
00189 }
00190 }
00191 }
00192 }