PLearn 0.1
RemapLastColumnVMatrix.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: RemapLastColumnVMatrix.cc 8617 2008-03-03 17:45:54Z nouiz $
00039  ******************************************************* */
00040 
00041 #include "RemapLastColumnVMatrix.h"
00042 
00043 namespace PLearn {
00044 using namespace std;
00045 
00046 
00049 PLEARN_IMPLEMENT_OBJECT(RemapLastColumnVMatrix, "ONE LINE DESC", "NO HELP");
00050 
00051 RemapLastColumnVMatrix::RemapLastColumnVMatrix(bool call_build_)
00052     : inherited(call_build_), if_equals_val(0), then_val(0), else_val(0)
00053 {
00054     if( call_build_ )
00055         build_();
00056 }
00057 
00058 RemapLastColumnVMatrix::RemapLastColumnVMatrix(VMat the_source,
00059                                                Mat the_mapping,
00060                                                bool call_build_)
00061     : inherited (the_source,
00062                  the_source->length(),
00063                  the_source->width()+the_mapping.width()-2,
00064                  call_build_),
00065       mapping(the_mapping)
00066 {
00067     if( call_build_ )
00068         build_();
00069 }
00070 
00071 RemapLastColumnVMatrix::RemapLastColumnVMatrix(VMat the_source,
00072                                                real if_equals_value,
00073                                                real then_value,
00074                                                real else_value,
00075                                                bool call_build_)
00076     : inherited(the_source,
00077                 the_source->length(),
00078                 the_source->width(),
00079                 call_build_),
00080       if_equals_val(if_equals_value),
00081       then_val(then_value),
00082       else_val(else_value)
00083 {
00084     if( call_build_ )
00085         build_();
00086 }
00087 
00088 void RemapLastColumnVMatrix::build()
00089 {
00090     inherited::build();
00091     build_();
00092 }
00093 
00094 void RemapLastColumnVMatrix::build_()
00095 {
00096     int n_extra = mapping.width() - 2;
00097     if( mapping.isEmpty() )
00098         width_=source->width();
00099     else
00100         width_=source->width() + n_extra;
00101 
00102     updateMtime(source);
00103 
00104     if( !mapping.isEmpty() && n_extra > 0 )
00105     {
00106         // width() is different from source->width(),
00107         int n_last = source->width()-1;
00108 
00109         // determine sizes
00110         int source_is = source->inputsize();
00111         int source_ts = source->targetsize();
00112         int source_ws = source->weightsize();
00113 
00114         bool specified_sizes_are_inconsistent =
00115             inputsize_ < 0 || targetsize_ < 0 || weightsize_ <0 ||
00116             inputsize_ + targetsize_ + weightsize_ != width();
00117 
00118         if( specified_sizes_are_inconsistent )
00119         {
00120             if( source_is < 0 || source_ts < 0 || source_ws < 0 ||
00121                 source_is + source_ts + source_ws != source->width() )
00122             {
00123                 //source sizes are inconsistent, everything is input (default)
00124                 inputsize_ = width();
00125                 targetsize_ = 0;
00126                 weightsize_ = 0;
00127             }
00128             else if( n_last < source_is )
00129             {
00130                 // last column is input, remapped columns are considered input
00131                 // other sizes are 0
00132                 inputsize_ = source_is + n_extra;
00133                 targetsize_ = 0;
00134                 weightsize_ = 0;
00135             }
00136             else if( n_last < source_is + source_ts )
00137             {
00138                 // last column is target, remapped columns are
00139                 // considered target other sizes are set from source
00140                 inputsize_ = source_is;
00141                 targetsize_ = source_ts + n_extra;
00142                 weightsize_ = 0;
00143             }
00144             else
00145             {
00146                 inputsize_ = source_is;
00147                 targetsize_ = source_ts;
00148                 weightsize_ = source_ws + n_extra;
00149             }
00150         }
00151         // else don't modify specified sizes
00152 
00153         // set fieldname for added columns
00154         TVec<string> source_fieldnames = source->fieldNames();
00155         string last_fieldname = source_fieldnames[n_last];
00156         TVec<string> fieldnames( source_fieldnames.copy() );
00157         fieldnames.resize( width() );
00158         for( int i=0 ; i<=n_extra ; i++ )
00159         {
00160             fieldnames[n_last+i] = last_fieldname + "_" + tostring(i);
00161         }
00162         declareFieldNames( fieldnames );
00163 
00164     }
00165     setMetaInfoFromSource();
00166 }
00167 
00168 void RemapLastColumnVMatrix::declareOptions(OptionList &ol)
00169 {
00170     declareOption(ol, "underlying_distr",
00171                   &RemapLastColumnVMatrix::source,
00172                   OptionBase::buildoption,
00173                   "DEPRECATED - Use 'source' instead.");
00174 
00175     declareOption(ol, "mapping", &RemapLastColumnVMatrix::mapping,
00176                   OptionBase::buildoption, "");
00177 
00178     declareOption(ol, "if_equals_val", &RemapLastColumnVMatrix::if_equals_val,
00179                   OptionBase::buildoption, "");
00180 
00181     declareOption(ol, "then_val", &RemapLastColumnVMatrix::then_val,
00182                   OptionBase::buildoption, "");
00183 
00184     declareOption(ol, "else_val", &RemapLastColumnVMatrix::else_val,
00185                   OptionBase::buildoption, "");
00186 
00187     inherited::declareOptions(ol);
00188 }
00189 
00190 void RemapLastColumnVMatrix::getNewRow(int i, const Vec& samplevec) const
00191 {
00192 #ifdef BOUNDCHECK
00193     if(i<0 || i>=length())
00194         PLERROR("In RemapLastColumnVMatrix::getNewRow OUT OF BOUNDS");
00195     if(samplevec.length()!=width())
00196         PLERROR("In RemapLastColumnVMatrix::getNewRow samplevec.length()\n"
00197                 "must be equal to the VMat's width (%d != %d).\n",
00198                 samplevec.length(), width());
00199 #endif
00200     if(mapping.isEmpty()) // use if-then-else mapping
00201     {
00202         source->getRow(i,samplevec);
00203         real& lastelem = samplevec.lastElement();
00204         if(fast_exact_is_equal(lastelem, if_equals_val))
00205             lastelem = then_val;
00206         else
00207             lastelem = else_val;
00208     }
00209     else // use mapping matrix
00210     {
00211         int source_width = source->width();
00212         int replacement_width = mapping.width()-1;
00213         source->getRow(i,samplevec.subVec(0,source_width));
00214         real val = samplevec[source_width-1];
00215         int k;
00216         for(k=0; k<mapping.length(); k++)
00217         {
00218             if(fast_exact_is_equal(mapping(k,0), val))
00219             {
00220                 samplevec.subVec(source_width-1,replacement_width)
00221                     << mapping(k).subVec(1,replacement_width);
00222                 break;
00223             }
00224         }
00225         if(k>=mapping.length())
00226             PLERROR("In RemapLastColumnVMatrix::getNewRow - there is a value"
00227                     " in the\n"
00228                     "last column that does not have any defined mapping.\n");
00229     }
00230 }
00231 
00232 } // end of namespace PLearn
00233 
00234 
00235 /*
00236   Local Variables:
00237   mode:c++
00238   c-basic-offset:4
00239   c-file-style:"stroustrup"
00240   c-file-offsets:((innamespace . 0)(inline-open . 0))
00241   indent-tabs-mode:nil
00242   fill-column:79
00243   End:
00244 */
00245 // 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