Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/FanOutIn.cpp
Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 1998-2010 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 "FanOutIn.h"
00020 #include <algorithm>
00021 
00022 using std::ostringstream;
00023 using std::vector;
00024 using std::max;
00025 using std::min;
00026 
00027 using namespace Marsyas;
00028 
00029 FanOutIn::FanOutIn(mrs_string name):MarSystem("FanOutIn", name)
00030 {
00031   isComposite_ = true;
00032   wrongOutConfig_ = false;
00033   addControls();
00034 }
00035 
00036 FanOutIn::FanOutIn(const FanOutIn& a):MarSystem(a)
00037 {
00038   ctrl_combinator_ = getctrl("mrs_string/combinator");
00039   wrongOutConfig_ = false;
00040 }
00041 
00042 FanOutIn::~FanOutIn()
00043 {
00044   deleteSlices();
00045 }
00046 
00047 void
00048 FanOutIn::deleteSlices()
00049 {
00050   vector<realvec *>::const_iterator iter;
00051   for (iter= slices_.begin(); iter != slices_.end(); iter++)
00052   {
00053     delete *(iter);
00054   }
00055   slices_.clear();
00056 }
00057 
00058 MarSystem*
00059 FanOutIn::clone() const
00060 {
00061   return new FanOutIn(*this);
00062 }
00063 
00064 void
00065 FanOutIn::addControls()
00066 {
00067   addctrl("mrs_natural/disable", -1);
00068   setctrlState("mrs_natural/disable", true);
00069   addctrl("mrs_natural/enable", -1);
00070   setctrlState("mrs_natural/enable", true);
00071 
00072   addctrl("mrs_string/enableChild", "");
00073   setctrlState("mrs_string/enableChild", true);
00074   addctrl("mrs_string/disableChild", "");
00075   setctrlState("mrs_string/disableChild", true);
00076 
00077   addctrl("mrs_string/combinator", "+", ctrl_combinator_);
00078 }
00079 
00080 void
00081 FanOutIn::myUpdate(MarControlPtr sender)
00082 {
00083   child_count_t child_count = marsystems_.size();
00084   if (enabled_.getSize() != child_count)
00085   {
00086     enabled_.create(child_count);
00087     enabled_.setval(1.0);
00088   }
00089 
00090   //check child MarSystems to disable (passed as a string)
00091   disableChild_ = getctrl("mrs_string/disableChild")->to<mrs_string>();
00092   disableChildIndex_ = -1;
00093   for (mrs_natural i=0; i < (mrs_natural)marsystems_.size(); ++i)
00094   {
00095     mrs_string s;
00096     s = marsystems_[i]->getType() + "/" + marsystems_[i]->getName();
00097     if (disableChild_ == s)
00098       disableChildIndex_ = i;
00099   }
00100   if (disableChildIndex_ != -1)
00101   {
00102     enabled_(disableChildIndex_) = 0.0;
00103     setctrl("mrs_string/disableChild", "");
00104   }
00105   if (disableChild_ == "all")
00106   {
00107     for (mrs_natural i=0; i < (mrs_natural)marsystems_.size(); ++i)
00108     {
00109       enabled_(i) = 0.0;
00110       setctrl("mrs_string/disableChild", "");
00111     }
00112   }
00113 
00114   //check child MarSystem to disable (passed as an index)
00115   disable_ = getctrl("mrs_natural/disable")->to<mrs_natural>();
00116   if (disable_ != -1 && disable_ < (mrs_natural) child_count)
00117   {
00118     enabled_(disable_) = 0.0;
00119     setctrl("mrs_natural/disable", -1);
00120   }
00121   else
00122     setctrl("mrs_natural/disable", -1);
00123 
00124   //check child MarSystems to enable (passed as a string)
00125   enableChild_ = getctrl("mrs_string/enableChild")->to<mrs_string>();
00126   enableChildIndex_ = -1;
00127   for (mrs_natural i=0; i < (mrs_natural)marsystems_.size(); ++i)
00128   {
00129     mrs_string s;
00130     s = marsystems_[i]->getType() + "/" + marsystems_[i]->getName();
00131     if (enableChild_ == s)
00132       enableChildIndex_ = i;
00133   }
00134   if (enableChildIndex_ != -1)
00135   {
00136     enabled_(enableChildIndex_) = 1.0;
00137     setctrl("mrs_string/enableChild", "");
00138   }
00139   //check child MarSystem to enable (passed as an index)
00140   enable_ = getctrl("mrs_natural/enable")->to<mrs_natural>();
00141   if (enable_ != -1 && enable_ < (mrs_natural) child_count)
00142   {
00143     enabled_(enable_) = 1.0;
00144     setctrl("mrs_natural/enable", -1);
00145   }
00146   else
00147     setctrl("mrs_natural/enable", -1);
00148 
00149   if (child_count)
00150   {
00151     wrongOutConfig_ = false;
00152 
00153     //propagate in flow controls to first child
00154     marsystems_[0]->setctrl("mrs_natural/inObservations", inObservations_);
00155     marsystems_[0]->setctrl("mrs_natural/inSamples", inSamples_);
00156     marsystems_[0]->setctrl("mrs_real/israte", israte_);
00157     marsystems_[0]->setctrl("mrs_string/inObsNames", inObsNames_);
00158     marsystems_[0]->update();
00159 
00160     // update dataflow component MarSystems in order
00161     for (child_count_t i=1; i < child_count; ++i)
00162     {
00163       marsystems_[i]->setctrl("mrs_natural/inSamples", marsystems_[0]->getctrl("mrs_natural/inSamples"));
00164       marsystems_[i]->setctrl("mrs_natural/inObservations", marsystems_[0]->getctrl("mrs_natural/inObservations"));
00165       marsystems_[i]->setctrl("mrs_real/israte", marsystems_[0]->getctrl("mrs_real/israte"));
00166       marsystems_[i]->setctrl("mrs_string/inObsNames", marsystems_[0]->getctrl("mrs_string/inObsNames"));
00167       marsystems_[i]->update(sender);
00168 
00169       if(marsystems_[i]->getctrl("mrs_natural/onSamples")->to<mrs_natural>() !=
00170           marsystems_[0]->getctrl("mrs_natural/onSamples")->to<mrs_natural>() ||
00171           marsystems_[i]->getctrl("mrs_natural/onObservations")->to<mrs_natural>() !=
00172           marsystems_[0]->getctrl("mrs_natural/onObservations")->to<mrs_natural>())
00173       {
00174         //MRSERR("FanInOut::myUpdate - child MarSystem " + marsystems_[i]->getPrefix() +
00175         //  " ouput configuration is not the same as the one from the first child MarSystem(" +
00176         //  marsystems_[0]->getPrefix() + " ! Outputing zero valued result...");
00177         wrongOutConfig_ = true;
00178       }
00179     }
00180 
00181     // forward flow propagation
00182     setctrl(ctrl_onSamples_, marsystems_[0]->getctrl("mrs_natural/onSamples")->to<mrs_natural>());
00183     setctrl(ctrl_onObservations_, marsystems_[0]->getctrl("mrs_natural/onObservations")->to<mrs_natural>());
00184     setctrl(ctrl_osrate_, marsystems_[0]->getctrl("mrs_real/osrate")->to<mrs_real>());
00185     ostringstream oss;
00186     oss << marsystems_[0]->getctrl("mrs_string/onObsNames");
00187     setctrl(ctrl_onObsNames_, oss.str());
00188 
00189     // update buffers between components
00190     if (slices_.size() < child_count)
00191       slices_.resize(child_count, NULL);
00192     for (child_count_t i=0; i< child_count; ++i)
00193     {
00194       if (slices_[i] != NULL)
00195       {
00196         if ((slices_[i])->getRows() != marsystems_[i]->getctrl("mrs_natural/onObservations")->to<mrs_natural>()  ||
00197             (slices_[i])->getCols() != marsystems_[i]->getctrl("mrs_natural/onSamples")->to<mrs_natural>())
00198         {
00199           delete slices_[i];
00200           slices_[i] = new realvec(marsystems_[i]->getctrl("mrs_natural/onObservations")->to<mrs_natural>(),
00201                                    marsystems_[i]->getctrl("mrs_natural/onSamples")->to<mrs_natural>());
00202         }
00203       }
00204       else
00205       {
00206         slices_[i] = new realvec(marsystems_[i]->getctrl("mrs_natural/onObservations")->to<mrs_natural>(),
00207                                  marsystems_[i]->getctrl("mrs_natural/onSamples")->to<mrs_natural>());
00208       }
00209       (slices_[i])->setval(0.0);
00210     }
00211   }
00212   else //if composite is empty...
00213     MarSystem::myUpdate(sender);
00214 }
00215 
00216 void
00217 FanOutIn::myProcess(realvec& in, realvec& out)
00218 {
00219   child_count_t child_count = marsystems_.size();
00220   if(child_count)
00221   {
00222     if(ctrl_combinator_->to<mrs_string>() == "+")
00223       out.setval(0); //identity operator
00224     if(ctrl_combinator_->to<mrs_string>() == "*")
00225       out.setval(1); //identity operator
00226     if(ctrl_combinator_->to<mrs_string>() == "max")
00227       out.setval(-1.0*MAXREAL);
00228     if(ctrl_combinator_->to<mrs_string>() == "min")
00229       out.setval(MAXREAL);
00230 
00231     if(wrongOutConfig_)
00232     {
00233       //if there is  a child with a non matching output configuration, just output zeros
00234       MRSERR("FanInOut::myUpdate - at least one child MarSystem ouput \
00235                          configuration is not the same as the one from the first child \
00236                          MarSystem! Outputing zero valued result...");
00237       out.setval(0);
00238       return;
00239     }
00240 
00241     for (child_count_t i = 0; i < child_count; ++i)
00242     {
00243       if (enabled_(i))
00244       {
00245         marsystems_[i]->process(in, *(slices_[i]));
00246         if(ctrl_combinator_->to<mrs_string>() == "+")
00247         {
00248           out += *(slices_[i]);
00249         }
00250         if(ctrl_combinator_->to<mrs_string>() == "*")
00251         {
00252           out *= *(slices_[i]);
00253         }
00254         if(ctrl_combinator_->to<mrs_string>() == "max")
00255         {
00256           for(mrs_natural l=0; l<out.getRows(); ++l)
00257             for(mrs_natural c=0; c<out.getCols(); ++c)
00258               out(l,c) = max(out(l,c), (*(slices_[i]))(l,c));
00259         }
00260         if(ctrl_combinator_->to<mrs_string>() == "min")
00261         {
00262           for(mrs_natural l=0; l<out.getRows(); ++l)
00263             for(mrs_natural c=0; c<out.getCols(); ++c)
00264               out(l,c) = min(out(l,c), (*(slices_[i]))(l,c));
00265         }
00266       }
00267     }
00268   }
00269   else //composite has no children!
00270   {
00271     MRSWARN("FanOutIn::process: composite has no children MarSystems - passing input to output without changes.");
00272     out = in;
00273   }
00274 }