PLearn 0.1
ConcatColumnsVMatrix.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: 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 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines