PLearn 0.1
SubVMatrix.cc
Go to the documentation of this file.
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 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines