PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // MixtureVMatrix.cc 00004 // 00005 // Copyright (C) 2008 Pascal Lamblin 00006 // 00007 // Redistribution and use in source and binary forms, with or without 00008 // modification, are permitted provided that the following conditions are met: 00009 // 00010 // 1. Redistributions of source code must retain the above copyright 00011 // notice, this list of conditions and the following disclaimer. 00012 // 00013 // 2. Redistributions in binary form must reproduce the above copyright 00014 // notice, this list of conditions and the following disclaimer in the 00015 // documentation and/or other materials provided with the distribution. 00016 // 00017 // 3. The name of the authors may not be used to endorse or promote 00018 // products derived from this software without specific prior written 00019 // permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00022 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00023 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00024 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00025 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00026 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 // 00032 // This file is part of the PLearn library. For more information on the PLearn 00033 // library, go to the PLearn Web site at www.plearn.org 00034 00035 // Authors: Pascal Lamblin 00036 00040 #include "MixtureVMatrix.h" 00041 00042 namespace PLearn { 00043 using namespace std; 00044 00045 00046 PLEARN_IMPLEMENT_OBJECT( 00047 MixtureVMatrix, 00048 "Mixes several underlying source VMat, with ponderation.", 00049 "" 00050 ); 00051 00052 MixtureVMatrix::MixtureVMatrix(): 00053 n_sources(0), 00054 period_length(0) 00055 { 00056 } 00057 00058 void MixtureVMatrix::getNewRow(int i, const Vec& v) const 00059 { 00060 // The source it comes from 00061 int source = period[i % period_length]; 00062 // The number of previous samples of the same source in the same period 00063 int occurrence = occurrences[i % period_length]; 00064 // The index in this source 00065 int index = (i/period_length)*weights[source] + occurrence; 00066 00067 sources[source]->getRow(index % sources[source].length(), v); 00068 } 00069 00070 void MixtureVMatrix::declareOptions(OptionList& ol) 00071 { 00072 // declareOption(ol, "myoption", &MixtureVMatrix::myoption, 00073 // OptionBase::buildoption, 00074 // "Help text describing this option"); 00075 00076 declareOption(ol, "sources", &MixtureVMatrix::sources, 00077 OptionBase::buildoption, 00078 "The VMat to mix"); 00079 00080 declareOption(ol, "weights", &MixtureVMatrix::weights, 00081 OptionBase::buildoption, 00082 "Weights of the different sources.\n" 00083 "If weights[0]==2 and weights[1]==2, then there will be\n" 00084 "twice as many exambles coming from sources[0] than from\n" 00085 "sources[1], regardless of the sources' length." 00086 ); 00087 00088 declareOption(ol, "n_sources", &MixtureVMatrix::n_sources, 00089 OptionBase::learntoption, 00090 "Number of sources"); 00091 00092 declareOption(ol, "period_length", &MixtureVMatrix::period_length, 00093 OptionBase::learntoption, 00094 "sum(weights)"); 00095 00096 declareOption(ol, "period", &MixtureVMatrix::period, 00097 OptionBase::learntoption, 00098 "Sequence of sources to select, ensuring the proportion of\n" 00099 "sources and their homogeneity ." 00100 ); 00101 00102 // Now call the parent class' declareOptions 00103 inherited::declareOptions(ol); 00104 } 00105 00106 void MixtureVMatrix::build_() 00107 { 00108 n_sources = sources.size(); 00109 if (n_sources == 0) 00110 return; 00111 00112 PLCHECK_MSG(sources.size() == weights.size(), 00113 "You should provide as many weights as sources"); 00114 00115 PLCHECK_MSG(length_ >= 0, 00116 "You should provide a length greater than 0"); 00117 00118 width_ = sources[0]->width(); 00119 for (int i=1; i<n_sources; i++) 00120 PLCHECK_MSG(sources[i]->width() == width_, 00121 "All sources should have the same width"); 00122 00123 if (inputsize_<0 || targetsize_<0 || weightsize_<0 || extrasize_<0 00124 || inputsize_ + targetsize_ + weightsize_ + extrasize_ != width_) 00125 { 00126 inputsize_ = sources[0]->inputsize(); 00127 targetsize_ = sources[0]->targetsize(); 00128 weightsize_ = sources[0]->weightsize(); 00129 extrasize_ = sources[0]->extrasize(); 00130 } 00131 00132 period_length = sum(weights); 00133 period.resize(period_length); 00134 occurrences.resize(period_length); 00135 00136 bool incorrect_period = false; 00137 for (int i=0; i<n_sources; i++) 00138 if (period.count(i) != weights[i]) 00139 { 00140 incorrect_period = true; 00141 break; 00142 } 00143 00144 if (incorrect_period) 00145 buildPeriod(); 00146 for(int i=0;i<sources.length();i++) 00147 updateMtime(sources[i]); 00148 } 00149 00150 void MixtureVMatrix::buildPeriod() 00151 { 00152 TVec<int> ideal_count(n_sources); 00153 TVec<int> actual_count(n_sources); 00154 TVec<int> sources_count(n_sources); 00155 00156 for (int i=0; i<period_length; i++) 00157 { 00158 // Find the source that is the most underrepresented 00159 ideal_count += weights; 00160 00161 int max = 0; 00162 int argmax = -1; 00163 for (int j=0; j<n_sources; j++) 00164 { 00165 if (ideal_count[j] - actual_count[j] > max) 00166 { 00167 argmax = j; 00168 max = ideal_count[j] - actual_count[j]; 00169 } 00170 } 00171 PLASSERT(argmax >= 0); 00172 00173 period[i] = argmax; 00174 actual_count[argmax] += period_length; 00175 occurrences[i] = sources_count[argmax]; 00176 sources_count[argmax]++; 00177 } 00178 00179 #ifdef BOUNDCHECK 00180 for (int i=0; i<n_sources; i++) 00181 { 00182 PLASSERT(period.count(i) == weights[i]); 00183 PLASSERT( (i==0 && occurrences[0]==0) 00184 || period.subVec(0,i-1).count(period[i]) == occurrences[i]); 00185 } 00186 #endif 00187 } 00188 00189 // ### Nothing to add here, simply calls build_ 00190 void MixtureVMatrix::build() 00191 { 00192 inherited::build(); 00193 build_(); 00194 } 00195 00196 void MixtureVMatrix::makeDeepCopyFromShallowCopy(CopiesMap& copies) 00197 { 00198 inherited::makeDeepCopyFromShallowCopy(copies); 00199 00200 deepCopyField(sources, copies); 00201 deepCopyField(weights, copies); 00202 deepCopyField(period, copies); 00203 deepCopyField(occurrences, copies); 00204 } 00205 00206 } // end of namespace PLearn 00207 00208 00209 /* 00210 Local Variables: 00211 mode:c++ 00212 c-basic-offset:4 00213 c-file-style:"stroustrup" 00214 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00215 indent-tabs-mode:nil 00216 fill-column:79 00217 End: 00218 */ 00219 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :