Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/AimVQ.cpp
Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 1998-2011 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 "AimVQ.h"
00021 
00022 #ifdef MARSYAS_ANN
00023 #include "ANN.h"
00024 #include "static_vq_codebook.h"
00025 #endif
00026 
00027 
00028 using std::ostringstream;
00029 using namespace Marsyas;
00030 
00031 AimVQ::AimVQ(mrs_string name):MarSystem("AimVQ",name)
00032 {
00033   is_initialized = false;
00034   addControls();
00035 }
00036 
00037 AimVQ::AimVQ(const AimVQ& a): MarSystem(a)
00038 {
00039   is_initialized = false;
00040 
00041   ctrl_kd_tree_bucket_size_ = getctrl("mrs_natural/kd_tree_bucket_size");
00042   ctrl_kd_tree_error_bound_ = getctrl("mrs_real/kd_tree_error_bound");
00043   ctrl_num_codewords_to_return_ = getctrl("mrs_natural/num_codewords_to_return");
00044 }
00045 
00046 AimVQ::~AimVQ()
00047 {
00048 
00049 
00050 }
00051 
00052 MarSystem*
00053 AimVQ::clone() const
00054 {
00055   return new AimVQ(*this);
00056 }
00057 
00058 void
00059 AimVQ::addControls()
00060 {
00061   addControl("mrs_natural/kd_tree_bucket_size", 50 , ctrl_kd_tree_bucket_size_);
00062   addControl("mrs_real/kd_tree_error_bound", 1.0 , ctrl_kd_tree_error_bound_);
00063   addControl("mrs_natural/num_codewords_to_return", 1 , ctrl_num_codewords_to_return_);
00064 }
00065 
00066 void
00067 AimVQ::myUpdate(MarControlPtr sender)
00068 {
00069 
00070   (void) sender;  //suppress warning of unused parameter(s)
00071   MRSDIAG("AimVQ.cpp - AimVQ:myUpdate");
00072   ctrl_onSamples_->setValue(1, NOUPDATE);
00073 #ifdef MARSYAS_ANN
00074   ctrl_onObservations_->setValue(static_array_num_codebooks * static_array_num_codewords, NOUPDATE);
00075 #endif
00076   ctrl_osrate_->setValue(ctrl_israte_, NOUPDATE);
00077 
00078   ostringstream oss;
00079   for (int i =0; i < ctrl_onObservations_->to<mrs_natural>(); ++i)
00080     oss << "attribute,";
00081   //ctrl_onObsNames_->setValue("AimVQ_" + ctrl_inObsNames_->to<mrs_string>() , NOUPDATE);
00082   ctrl_onObsNames_->setValue(oss.str(), NOUPDATE);
00083 
00084 
00085   //
00086   // Does the MarSystem need initialization?
00087   //
00088   if (!is_initialized) {
00089     InitializeInternal();
00090     is_initialized = true;
00091   }
00092 
00093 
00094 }
00095 
00096 void
00097 AimVQ::InitializeInternal() {
00098 #ifdef MARSYAS_ANN
00099   codebooks_count_ = static_array_num_codebooks;  // Your value here
00100   codeword_count_ = static_array_num_codewords;  // Your value here
00101   codeword_length_ = static_array_codeword_length;  // Your value here
00102 
00103   // Fill the ANN points arrays with the codebooks
00104   for (int i = 0; i < codebooks_count_; ++i) {
00105     ANNpointArray points = annAllocPts(codeword_count_,codeword_length_);
00106     // The points arrays are stored here for later deallocation
00107     codebooks_.push_back(points);
00108     int index = 0;
00109     for (int j = 0; j < codeword_count_; ++j) {
00110       for (int k = 0; k < codeword_length_; ++k) {
00111         (*points)[index] = static_vq_array[i][j][k];  // take the value from your array here
00112         ++index;
00113       }
00114     }
00115     ANNkd_tree* kd_tree = new ANNkd_tree(points,
00116                                          codeword_count_,
00117                                          codeword_length_,
00118                                          ctrl_kd_tree_bucket_size_->to<mrs_natural>());
00119     sparse_coder_trees_.push_back(kd_tree);
00120   }
00121 #endif
00122 }
00123 
00124 
00125 void
00126 AimVQ::myProcess(realvec& in, realvec& out)
00127 {
00128   // cout << "AimVQ::myProcess" << endl;
00129 
00130   (void) in; // avoid unused parameter warning when MARSYAS_ANN is not enabled
00131 
00132 
00133   // Zero out the output first
00134   for (int i = 0; i < onObservations_; ++i) {
00135     out(i,0) = 0.0;
00136   }
00137 
00138 #ifdef MARSYAS_ANN
00139   mrs_natural _num_codewords_to_return = ctrl_num_codewords_to_return_->to<mrs_natural>();
00140   mrs_real _kd_tree_error_bound = ctrl_kd_tree_error_bound_->to<mrs_real>();
00141 
00142   vector<int> sparse_code;
00143   int offset = 0;
00144   realvec obsRow;
00145   for (int i = 0; i < codebooks_count_; ++i) {
00146     in.getRow(i,obsRow);
00147     ANNidxArray indices = new ANNidx[_num_codewords_to_return];
00148     ANNdistArray distances = new ANNdist[_num_codewords_to_return];
00149     sparse_coder_trees_[i]->annkSearch(obsRow.getData(),
00150                                        _num_codewords_to_return,
00151                                        indices,
00152                                        distances,
00153                                        _kd_tree_error_bound);
00154     for (int j = 0; j < _num_codewords_to_return; ++j) {
00155       sparse_code.push_back(indices[j] + offset);
00156     }
00157     offset += codeword_count_;
00158 
00159     delete indices;
00160     delete distances;
00161   }
00162 
00163   for (unsigned int j = 0; j < sparse_code.size(); ++j) {
00164     out(sparse_code[j],0) = 1.0;
00165   }
00166 #endif
00167 
00168 }