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: SubVMatrix.cc 10002 2009-03-10 14:34:55Z tihocan $ 00039 ******************************************************* */ 00040 00041 #include "SubVMatrix.h" 00042 #include <plearn/base/tostring.h> 00043 00044 namespace PLearn { 00045 using namespace std; 00046 00047 00050 PLEARN_IMPLEMENT_OBJECT(SubVMatrix, 00051 "Views only a submatrix of a source VMatrix", 00052 ""); 00053 00055 // SubVMatrix // 00057 SubVMatrix::SubVMatrix(bool call_build_) 00058 : inherited(call_build_), 00059 istart(0), 00060 jstart(0), 00061 fistart(-1), 00062 flength(-1) 00063 { 00064 // don't call build_() when no source is set 00065 } 00066 00067 SubVMatrix::SubVMatrix(VMat the_source, 00068 int the_istart, int the_jstart, 00069 int the_length, int the_width, 00070 bool call_build_) 00071 : inherited(the_source, the_length, the_width, call_build_), 00072 istart(the_istart), jstart(the_jstart), 00073 fistart(-1), flength(-1) 00074 { 00075 if( call_build_ ) 00076 build_(); 00077 } 00078 00079 SubVMatrix::SubVMatrix(VMat the_source, 00080 real the_fistart, int the_jstart, 00081 real the_flength, int the_width, 00082 bool call_build_) 00083 : inherited(the_source, 00084 int(the_flength * the_source->length()), 00085 the_width, 00086 call_build_), 00087 istart(-1), jstart(the_jstart), 00088 fistart(the_fistart), flength(the_flength) 00089 // Note that istart will be set to the right value in build_(). 00090 { 00091 PLASSERT( the_source->length() >= 0 ); 00092 if( call_build_ ) 00093 build_(); 00094 } 00095 00097 // declareOptions // 00099 void SubVMatrix::declareOptions(OptionList &ol) 00100 { 00101 //WARNING: If you add option make sure the we correctly build the metadatadir! 00102 //search for setMetaDataDir in this file. 00103 00104 declareOption(ol, "parent", &SubVMatrix::source, OptionBase::buildoption, 00105 "DEPRECATED - Use 'source' instead."); 00106 00107 declareOption(ol, "istart", &SubVMatrix::istart, OptionBase::buildoption, 00108 "Start i coordinate (row wise)"); 00109 00110 declareOption(ol, "jstart", &SubVMatrix::jstart, OptionBase::buildoption, 00111 "Start j coordinate (column wise)"); 00112 00113 declareOption(ol, "fistart", &SubVMatrix::fistart, OptionBase::buildoption, 00114 "If provided, will override istart to" 00115 " fistart * source.length()"); 00116 00117 declareOption(ol, "flength", &SubVMatrix::flength, OptionBase::buildoption, 00118 "If provided, will override length to" 00119 " flength * source.length()"); 00120 00121 inherited::declareOptions(ol); 00122 } 00123 00125 // build // 00127 void SubVMatrix::build() 00128 { 00129 inherited::build(); 00130 build_(); 00131 } 00132 00134 // build_ // 00136 void SubVMatrix::build_() 00137 { 00138 updateMtime(source); 00139 int sl = source->length(); 00140 int sw = source->width(); 00141 00142 if (fistart >= 0) { 00143 PLASSERT( sl >= 0 ); 00144 istart = int(fistart * sl); 00145 } 00146 00147 if (flength >= 0) { 00148 PLASSERT( sl >= 0 ); 00149 length_ = int(flength * sl); 00150 } 00151 00152 if(length_ < 0) { 00153 PLASSERT( sl >= 0 ); 00154 length_ = sl - istart; 00155 } 00156 00157 if(width_ < 0 && sw >= 0) 00158 width_ = sw - jstart; 00159 00160 if((sl >= 0 && istart + length() > sl) || jstart+width() > sw) 00161 PLERROR("In SubVMatrix::build_ - Out of bounds of the source's length " 00162 "or width"); 00163 00164 // Copy the source field names. 00165 fieldinfos.resize(width()); 00166 if (source->getFieldInfos().size() > 0) 00167 for(int j=0; j<width(); j++) 00168 fieldinfos[j] = source->getFieldInfos()[jstart+j]; 00169 00170 // Copy the source string mappings. 00171 map_rs.resize(width()); 00172 map_sr.resize(width()); 00173 for (int j = jstart; j < width_ + jstart; j++) { 00174 map_rs[j - jstart] = source->getRealToStringMapping(j); 00175 map_sr[j - jstart] = source->getStringToRealMapping(j); 00176 } 00177 00178 // determine sizes 00179 if(jstart==0 && width()==source->width() && 00180 inputsize()<0 && targetsize()<0 && weightsize()<0) 00181 //We don't change the columns, so we can copy their size 00182 copySizesFrom(source); 00183 computeMissingSizeValue(false); 00184 /* 00185 if (width_ == source->width()) 00186 { 00187 if(inputsize_<0) inputsize_ = source->inputsize(); 00188 if(targetsize_<0) targetsize_ = source->targetsize(); 00189 if(weightsize_<0) weightsize_ = source->weightsize(); 00190 } else { 00191 // The width has changed: if no sizes are specified, 00192 // we assume it's all input and no target. 00193 if(targetsize_<0) targetsize_ = 0; 00194 if(weightsize_<0) weightsize_ = 0; 00195 if(inputsize_<0) inputsize_ = width_ - targetsize_ - weightsize_; 00196 } 00197 // */ 00198 00199 //* 00200 bool sizes_are_inconsistent = 00201 inputsize_ < 0 || targetsize_ < 0 || weightsize_ < 0 || 00202 inputsize_ + targetsize_ + weightsize_ + extrasize_ != width(); 00203 if( sizes_are_inconsistent ) 00204 { 00205 int source_is = source->inputsize(); 00206 int source_ts = source->targetsize(); 00207 int source_ws = source->weightsize(); 00208 bool source_sizes_are_inconsistent = 00209 source_is < 0 || source_ts < 0 || source_ws < 0 || 00210 source_is + source_ts + source_ws != source->width(); 00211 00212 // if source sizes are inconsistent too, we assume it's all input 00213 if( source_sizes_are_inconsistent ) 00214 { 00215 inputsize_ = width(); 00216 targetsize_ = 0; 00217 weightsize_ = 0; 00218 } 00219 else 00220 { 00221 // We can rely on the source sizes, and determine which columns 00222 // have been cropped 00223 if( jstart <= source_is ) 00224 { 00225 inputsize_ = min(source_is - jstart, width()); 00226 targetsize_ = min(source_ts, width() - inputsize()); 00227 weightsize_ = width() - inputsize() - targetsize(); 00228 } 00229 else if( jstart <= source_is + source_ts ) 00230 { 00231 inputsize_ = 0; 00232 targetsize_ = min(source_is + source_ts - jstart, width()); 00233 weightsize_ = width() - targetsize(); 00234 } 00235 else // jstart <= source_is + source_ts + source_ws 00236 { 00237 inputsize_ = 0; 00238 targetsize_ = 0; 00239 weightsize_ = width(); 00240 } 00241 } 00242 } 00243 // else, nothing to change 00244 00245 if(!hasMetaDataDir() && source->hasMetaDataDir()) 00246 setMetaDataDir(source->getMetaDataDir() / classname()+ 00247 "_istart=" + tostring(istart) + 00248 "_jstart=" +tostring(jstart) + 00249 "_length="+tostring(length()) + 00250 "_width="+tostring(width()) + 00251 ".metadata"); 00252 00253 // cerr << "inputsize: "<<inputsize_ << " targetsize:"<<targetsize_<<"weightsize:"<<weightsize_<<endl; 00254 } 00255 00257 // reset_dimensions // 00259 void SubVMatrix::reset_dimensions() 00260 { 00261 // This seems like an old method that is not used anymore, and should not 00262 // be used anyway as it probably does not work correctly. Keeping it with 00263 // an error message until it is removed for good, in order to possibly 00264 // detect some uses of it. 00265 PLERROR("In SubVMatrix::reset_dimensions - Not working anymore"); 00266 int delta_length = source->length()-length_; 00267 int delta_width = 0; // source->width()-width_; HACK 00268 source->reset_dimensions(); 00269 length_=source->length()-delta_length; 00270 width_=source->width()-delta_width; 00271 } 00272 00274 // getNewRow // 00276 void SubVMatrix::getNewRow(int i, const Vec& v) const 00277 { 00278 #ifdef BOUNDCHECK 00279 if(i<0 || i>=length()) 00280 PLERROR("In SubVMatrix::getNewRow(i, v) OUT OF BOUND access"); 00281 #endif 00282 source->getSubRow(i+istart, jstart, v); 00283 } 00284 00285 real SubVMatrix::get(int i, int j) const 00286 { 00287 #ifdef BOUNDCHECK 00288 if(i<0 || i>=length() || j<0 || j>=width()) 00289 PLERROR("In SubVMatrix::get(i,j) OUT OF BOUND access"); 00290 #endif 00291 return source->get(i+istart,j+jstart); 00292 } 00293 void SubVMatrix::getSubRow(int i, int j, Vec v) const 00294 { 00295 #ifdef BOUNDCHECK 00296 if(i<0 || i>=length() || j<0 || j+v.length()>width()) 00297 PLERROR("In SubVMatrix::getSubRow(i,j,v) OUT OF BOUND access"); 00298 #endif 00299 source->getSubRow(i+istart,j+jstart,v); 00300 } 00301 00302 real SubVMatrix::getStringVal(int col, const string & str) const 00303 { 00304 #ifdef BOUNDCHECK 00305 if(col<0 || col>=width()) 00306 PLERROR("In SubVMatrix::getStringVal(): OUT OF BOUND access"); 00307 #endif 00308 return source->getStringVal(jstart+col, str); 00309 } 00310 00311 string SubVMatrix::getValString(int col, real val) const 00312 { 00313 #ifdef BOUNDCHECK 00314 if(col<0 || col>=width()) 00315 PLERROR("In SubVMatrix::getValString(): OUT OF BOUND access"); 00316 #endif 00317 return source->getValString(jstart+col,val); 00318 } 00319 00320 string SubVMatrix::getString(int row, int col) const 00321 { 00322 #ifdef BOUNDCHECK 00323 if(row<0 || row>=length() || col<0 || col>=width()) 00324 PLERROR("In SubVMatrix::getString(): OUT OF BOUND access"); 00325 #endif 00326 return source->getString(row + istart, jstart+col); 00327 } 00328 00329 void SubVMatrix::getMat(int i, int j, Mat m) const 00330 { 00331 #ifdef BOUNDCHECK 00332 if(i<0 || i+m.length()>length() || j<0 || j+m.width()>width()) 00333 PLERROR("In SubVMatrix::getMat OUT OF BOUND access"); 00334 #endif 00335 source->getMat(i+istart, j+jstart, m); 00336 } 00337 00338 void SubVMatrix::put(int i, int j, real value) 00339 { 00340 #ifdef BOUNDCHECK 00341 if(i<0 || i>=length() || j<0 || j>=width()) 00342 PLERROR("In SubVMatrix::put(i,j,value) OUT OF BOUND access"); 00343 #endif 00344 return source->put(i+istart,j+jstart,value); 00345 } 00346 void SubVMatrix::putSubRow(int i, int j, Vec v) 00347 { 00348 #ifdef BOUNDCHECK 00349 if(i<0 || i>=length() || j<0 || j>=width()) 00350 PLERROR("In SubVMatrix::putSubRow(i,j,v) OUT OF BOUND access"); 00351 #endif 00352 source->putSubRow(i+istart,j+jstart,v); 00353 } 00354 00355 void SubVMatrix::putMat(int i, int j, Mat m) 00356 { 00357 #ifdef BOUNDCHECK 00358 if(i<0 || i+m.length()>length() || j<0 || j+m.width()>width()) 00359 PLERROR("In SubVMatrix::putMat(i,j,m) OUT OF BOUND access"); 00360 #endif 00361 source->putMat(i+istart, j+jstart, m); 00362 } 00363 00364 VMat SubVMatrix::subMat(int i, int j, int l, int w) 00365 { 00366 return source->subMat(istart+i,jstart+j,l,w); 00367 } 00368 00370 // dot // 00372 real SubVMatrix::dot(int i1, int i2, int inputsize) const 00373 { 00374 if(jstart==0) 00375 return source->dot(istart+i1, istart+i2, inputsize); 00376 else 00377 return inherited::dot(i1, i2, inputsize); 00378 } 00379 00380 real SubVMatrix::dot(int i, const Vec& v) const 00381 { 00382 if(jstart==0) 00383 return source->dot(istart+i, v); 00384 else 00385 return inherited::dot(i, v); 00386 } 00387 00389 // makeDeepCopyFromShallowCopy // 00391 void SubVMatrix::makeDeepCopyFromShallowCopy(CopiesMap& copies) 00392 { 00393 inherited::makeDeepCopyFromShallowCopy(copies); 00394 } 00395 00396 PP<Dictionary> SubVMatrix::getDictionary(int col) const 00397 { 00398 #ifdef BOUNDCHECK 00399 if(col<0 || col>=width()) 00400 PLERROR("In SubVMatrix::getDictionary(col) OUT OF BOUND access"); 00401 #endif 00402 return source->getDictionary(col+jstart); 00403 } 00404 00405 void SubVMatrix::getValues(int row, int col, Vec& values) const 00406 { 00407 #ifdef BOUNDCHECK 00408 if(row<0 || row>=length() || col<0 || col>=width()) 00409 PLERROR("In SubVMatrix::getValues(row,col) OUT OF BOUND access"); 00410 #endif 00411 source->getValues(row+istart,col+jstart, values); 00412 } 00413 00414 void SubVMatrix::getValues(const Vec& input, int col, Vec& values) const 00415 { 00416 #ifdef BOUNDCHECK 00417 if(col<0 || col>=width()) 00418 PLERROR("In SubVMatrix::getValues(row,col) OUT OF BOUND access"); 00419 #endif 00420 source->getValues(input.subVec(jstart, input.length()-jstart), 00421 col+jstart, values); 00422 } 00423 00424 } // end of namespace PLearn 00425 00426 00427 /* 00428 Local Variables: 00429 mode:c++ 00430 c-basic-offset:4 00431 c-file-style:"stroustrup" 00432 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00433 indent-tabs-mode:nil 00434 fill-column:79 00435 End: 00436 */ 00437 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :