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