PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // PLearn (A C++ Machine Learning Library) 00004 // Copyright (C) 1998 Pascal Vincent 00005 // Copyright (C) 1999-2001 Pascal Vincent, Yoshua Bengio, Rejean Ducharme and University of Montreal 00006 // Copyright (C) 2002 Pascal Vincent, Julien Keable, Xavier Saint-Mleux 00007 // 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions are met: 00010 // 00011 // 1. Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // 00014 // 2. Redistributions in binary form must reproduce the above copyright 00015 // notice, this list of conditions and the following disclaimer in the 00016 // documentation and/or other materials provided with the distribution. 00017 // 00018 // 3. The name of the authors may not be used to endorse or promote 00019 // products derived from this software without specific prior written 00020 // permission. 00021 // 00022 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00023 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00024 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00025 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00027 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00028 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00029 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00030 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00031 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 // 00033 // This file is part of the PLearn library. For more information on the PLearn 00034 // library, go to the PLearn Web site at www.plearn.org 00035 00036 00037 /* ******************************************************* 00038 * $Id: ConcatColumnsVMatrix.cc 9297 2008-07-29 13:59:01Z nouiz $ 00039 ******************************************************* */ 00040 00041 #include "ConcatColumnsVMatrix.h" 00042 #include <plearn/base/tostring.h> 00043 00044 namespace PLearn { 00045 using namespace std; 00046 00049 PLEARN_IMPLEMENT_OBJECT(ConcatColumnsVMatrix, "ONE LINE DESCR", "NO HELP"); 00050 00051 ConcatColumnsVMatrix::ConcatColumnsVMatrix(TVec<VMat> the_sources) 00052 : sources(the_sources), 00053 no_duplicate_fieldnames(false) 00054 { 00055 if (sources.size()) 00056 build_(); 00057 } 00058 00059 ConcatColumnsVMatrix::ConcatColumnsVMatrix(VMat d1, VMat d2) 00060 : sources(2), 00061 no_duplicate_fieldnames(false) 00062 { 00063 sources[0] = d1; 00064 sources[1] = d2; 00065 build_(); 00066 } 00067 00068 00069 void ConcatColumnsVMatrix::declareOptions(OptionList &ol) 00070 { 00071 declareOption(ol, "array", &ConcatColumnsVMatrix::sources, 00072 (OptionBase::learntoption | OptionBase::nosave), 00073 "DEPRECATED - Use 'sources' instead."); 00074 00075 declareOption(ol, "sources", &ConcatColumnsVMatrix::sources, 00076 OptionBase::buildoption, 00077 "The VMat to concatenate (horizontally)."); 00078 00079 declareOption(ol, "no_duplicate_fieldnames", 00080 &ConcatColumnsVMatrix::no_duplicate_fieldnames, 00081 OptionBase::buildoption, 00082 "If set to 1, will ensure no fieldnames are duplicated by" 00083 " adding\n" 00084 "numerical values '.1', '.2', ...\n"); 00085 00086 inherited::declareOptions(ol); 00087 } 00088 00089 void ConcatColumnsVMatrix::build() 00090 { 00091 inherited::build(); 00092 build_(); 00093 } 00094 00095 void ConcatColumnsVMatrix::build_() 00096 { 00097 length_ = width_ = 0; 00098 if(sources.size()) 00099 length_ = sources[0]->length(); 00100 // else 00101 // PLERROR("ConcatColumnsVMatrix expects >= 1 underlying-sources, got 0"); 00102 00103 for(int i=0; i<sources.size(); i++) 00104 { 00105 updateMtime(sources[i]); 00106 if(sources[i]->length()!=length_ && sources[i]->length()!=-1) 00107 PLERROR("ConcatColumnsVMatrix: Problem concatenating two VMat with" 00108 " different lengths"); 00109 if(sources[i]->width() == -1) 00110 PLERROR("In ConcatColumnsVMatrix constructor. Non-fixed width" 00111 " distribution not supported"); 00112 width_ += sources[i]->width(); 00113 } 00114 00115 // Copy the original fieldinfos. Be careful if only some of the 00116 // matrices have fieldinfos 00117 fieldinfos.resize(width_); 00118 TVec<string> names; 00119 int fieldindex = 0; 00120 init_map_sr(); 00121 for (int i=0; i<sources.size(); ++i) 00122 { 00123 int len = sources[i]->getFieldInfos().size(); 00124 if (len > 0) // infos exist for this VMat 00125 { 00126 for (int j=0; j<len; ++j) { 00127 map<string,real> map = sources[i]->getStringToRealMapping(j); 00128 if (!map.empty()) 00129 setStringMapping(fieldindex, map); 00130 fieldinfos[fieldindex++] = sources[i]->getFieldInfos()[j]; 00131 } 00132 } 00133 else // infos don't exist for this VMat, use the index as the name for those fields. 00134 { 00135 len = sources[i]->width(); 00136 for(int j=0; j<len; ++j) { 00137 map<string,real> map = sources[i]->getStringToRealMapping(j); 00138 if (!map.empty()) 00139 setStringMapping(fieldindex, map); 00140 fieldinfos[fieldindex] = VMField(tostring(fieldindex)); 00141 fieldindex++; 00142 } 00143 } 00144 } 00145 if (no_duplicate_fieldnames) { 00146 unduplicateFieldNames(); 00147 } 00148 00149 computeMissingSizeValue(false); 00150 } 00151 00152 void ConcatColumnsVMatrix::getNewRow(int i, const Vec& samplevec) const 00153 { 00154 if (length_==-1) 00155 PLERROR("In ConcatColumnsVMatrix::getNewRow(int i, Vec samplevec) not supported for distributions with different (or infinite) lengths\nCall sample without index instead"); 00156 int pos = 0; 00157 for(int n=0; n<sources.size(); n++) 00158 { 00159 int nvars = sources[n]->width(); 00160 Vec samplesubvec = samplevec.subVec(pos, nvars); 00161 sources[n]->getRow(i,samplesubvec); 00162 pos += nvars; 00163 } 00164 } 00165 00166 real ConcatColumnsVMatrix::getStringVal(int col, const string & str) const 00167 { 00168 if(col>=width_) 00169 PLERROR("access out of bound. Width=%i accessed col=%i",width_,col); 00170 int pos=0,k=0; 00171 while(col>=pos+sources[k]->width()) 00172 { 00173 pos += sources[k]->width(); 00174 k++; 00175 } 00176 // return sources[k]->getStringVal(pos+col,str); 00177 return sources[k]->getStringVal(col-pos,str); 00178 } 00179 00180 string ConcatColumnsVMatrix::getValString(int col, real val) const 00181 { 00182 if(col>=width_) 00183 PLERROR("access out of bound. Width=%i accessed col=%i",width_,col); 00184 int pos=0,k=0; 00185 while(col>=pos+sources[k]->width()) 00186 { 00187 pos += sources[k]->width(); 00188 k++; 00189 } 00190 // return sources[k]->getValString(pos+col,val); 00191 return sources[k]->getValString(col-pos,val); 00192 } 00193 00194 const map<string,real>& ConcatColumnsVMatrix::getStringMapping(int col) const 00195 { 00196 if(col>=width_) 00197 PLERROR("access out of bound. Width=%i accessed col=%i",width_,col); 00198 int pos=0,k=0; 00199 while(col>=pos+sources[k]->width()) 00200 { 00201 pos += sources[k]->width(); 00202 k++; 00203 } 00204 // return sources[k]->getStringToRealMapping(pos+col); 00205 return sources[k]->getStringToRealMapping(col-pos); 00206 } 00207 00208 string ConcatColumnsVMatrix::getString(int row, int col) const 00209 { 00210 if(col>=width_) 00211 PLERROR("access out of bound. Width=%i accessed col=%i",width_,col); 00212 int pos=0,k=0; 00213 while(col>=pos+sources[k]->width()) 00214 { 00215 pos += sources[k]->width(); 00216 k++; 00217 } 00218 // return sources[k]->getString(row,pos+col); 00219 return sources[k]->getString(row,col-pos); 00220 } 00221 00222 00223 00224 real ConcatColumnsVMatrix::dot(int i1, int i2, int inputsize) const 00225 { 00226 real res = 0.; 00227 for(int k=0; ;k++) 00228 { 00229 const VMat& vm = sources[k]; 00230 int vmwidth = vm.width(); 00231 if(inputsize<=vmwidth) 00232 { 00233 res += vm->dot(i1,i2,inputsize); 00234 break; 00235 } 00236 else 00237 { 00238 res += vm->dot(i1,i2,vmwidth); 00239 inputsize -= vmwidth; 00240 } 00241 } 00242 return res; 00243 } 00244 00245 real ConcatColumnsVMatrix::dot(int i, const Vec& v) const 00246 { 00247 if (length_==-1) 00248 PLERROR("In ConcatColumnsVMatrix::getRow(int i, Vec samplevec) not supported for distributions with different (or infinite) lengths\nCall sample without index instead"); 00249 00250 real res = 0.; 00251 int pos = 0; 00252 for(int n=0; n<sources.size(); n++) 00253 { 00254 int nvars = std::min(sources[n]->width(),v.length()-pos); 00255 if(nvars<=0) 00256 break; 00257 Vec subv = v.subVec(pos, nvars); 00258 res += sources[n]->dot(i,subv); 00259 pos += nvars; 00260 } 00261 return res; 00262 } 00263 00264 PP<Dictionary> ConcatColumnsVMatrix::getDictionary(int col) const 00265 { 00266 #ifdef BOUNDCHECK 00267 if(col>=width_) 00268 PLERROR("access out of bound. Width=%i accessed col=%i",width_,col); 00269 #endif 00270 int pos=0,k=0; 00271 while(col>=pos+sources[k]->width()) 00272 { 00273 pos += sources[k]->width(); 00274 k++; 00275 } 00276 return sources[k]->getDictionary(col-pos); 00277 } 00278 00279 00280 void ConcatColumnsVMatrix::getValues(int row, int col, Vec& values) const 00281 { 00282 #ifdef BOUNDCHECK 00283 if(col>=width_) 00284 PLERROR("access out of bound. Width=%i accessed col=%i",width_,col); 00285 #endif 00286 int pos=0,k=0; 00287 while(col>=pos+sources[k]->width()) 00288 { 00289 pos += sources[k]->width(); 00290 k++; 00291 } 00292 sources[k]->getValues(row,col-pos,values); 00293 } 00294 00295 void ConcatColumnsVMatrix::getValues(const Vec& input, int col, Vec& values) const 00296 { 00297 #ifdef BOUNDCHECK 00298 if(col>=width_) 00299 PLERROR("access out of bound. Width=%i accessed col=%i",width_,col); 00300 #endif 00301 int pos=0,k=0; 00302 while(col>=pos+sources[k]->width()) 00303 { 00304 pos += sources[k]->width(); 00305 k++; 00306 } 00307 sources[k]->getValues(input.subVec(pos,sources[k]->width()), col-pos, values); 00308 } 00309 00310 void ConcatColumnsVMatrix::makeDeepCopyFromShallowCopy(CopiesMap& copies) 00311 { 00312 inherited::makeDeepCopyFromShallowCopy(copies); 00313 deepCopyField(sources, copies); 00314 } 00315 00316 void ConcatColumnsVMatrix::put(int i, int j, real value) 00317 { 00318 #ifdef BOUNDCHECK 00319 if(j>=width_) 00320 PLERROR("access out of bound. Width=%i accessed col=%i",width_,j); 00321 #endif 00322 int pos=0,k=0; 00323 while(j>=pos+sources[k]->width()) 00324 { 00325 pos += sources[k]->width(); 00326 k++; 00327 } 00328 sources[k]->put(i,j-pos,value); 00329 } 00330 00331 } // end of namespace PLearn 00332 00333 00334 /* 00335 Local Variables: 00336 mode:c++ 00337 c-basic-offset:4 00338 c-file-style:"stroustrup" 00339 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00340 indent-tabs-mode:nil 00341 fill-column:79 00342 End: 00343 */ 00344 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :