PLearn 0.1
LocalNeighborsDifferencesVMatrix.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // LocalNeighborsDifferencesVMatrix.cc
00004 //
00005 // Copyright (C) 2004 Martin Monperrus
00006 //
00007 // Redistribution and use in source and binary forms, with or without
00008 // modification, are permitted provided that the following conditions are met:
00009 //
00010 //  1. Redistributions of source code must retain the above copyright
00011 //     notice, this list of conditions and the following disclaimer.
00012 //
00013 //  2. Redistributions in binary form must reproduce the above copyright
00014 //     notice, this list of conditions and the following disclaimer in the
00015 //     documentation and/or other materials provided with the distribution.
00016 //
00017 //  3. The name of the authors may not be used to endorse or promote
00018 //     products derived from this software without specific prior written
00019 //     permission.
00020 //
00021 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
00022 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00023 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
00024 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00025 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00026 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00027 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00028 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00029 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031 //
00032 // This file is part of the PLearn library. For more information on the PLearn
00033 // library, go to the PLearn Web site at www.plearn.org
00034 
00035 /* *******************************************************
00036  * $Id: LocalNeighborsDifferencesVMatrix.cc 8617 2008-03-03 17:45:54Z nouiz $
00037  ******************************************************* */
00038 
00039 // Authors: Martin Monperrus
00040 
00044 #include "LocalNeighborsDifferencesVMatrix.h"
00045 #include "VMat_computeNearestNeighbors.h"
00046 #include <plearn/math/TMat_maths.h>
00047 
00048 namespace PLearn {
00049 using namespace std;
00050 
00051 
00052 LocalNeighborsDifferencesVMatrix::LocalNeighborsDifferencesVMatrix()
00053     :inherited(), n_neighbors(-1), concat_neighbors(false), append_indexes(false)
00054     /* ### Initialise all fields to their default value */
00055 {
00056 }
00057 
00058 PLEARN_IMPLEMENT_OBJECT(LocalNeighborsDifferencesVMatrix,
00059                         "Computes the difference between each input row and its nearest neighbors.",
00060                         "For each row x of the source VMatrix, the resulting row will be the\n"
00061                         "concatenation of n_neighbors vectors, each of which is the difference\n"
00062                         "between one of the nearest neighbors of x in the source and x itself.\n"
00063     );
00064 
00065 void LocalNeighborsDifferencesVMatrix::getNewRow(int i, const Vec& v) const
00066 {
00067     if (width_<0)
00068         PLERROR("LocalNeighborsDifferencesVMatrix::getNewRow called but build was not done yet");
00069     if (concat_neighbors)
00070     {
00071         // resize des varaibles
00072         //v.resize(source->width()); //we assume that the vector has already the good size
00073         neighbor_row.resize(source->width());
00074         ith_row.resize(source->width());
00075         diff_k = v;
00076         // recuperation de ce qu'il faut
00077         source->getRow(i,ith_row);
00078         source->getRow(neighbors(i,n_neighbors-1),neighbor_row);
00079 
00080         // on renvoie la valeur
00081         substract(neighbor_row,ith_row, diff_k);
00082 
00083         if(append_indexes)
00084         {
00085             v[source->width()] = i;
00086             v[source->width()+1] = neighbors(i,n_neighbors-1);
00087         }
00088         if(append_neighbors)
00089         {
00090             v.subVec(source->width()+(append_indexes?2:0),source->width()) << neighbor_row;
00091         }
00092 
00093     }
00094     else
00095     {
00096         // vue en matrice du vecteur de sortie, ca pointe sur les memes donnees.
00097         Mat differences = v.toMat(n_neighbors,source->width());
00098         neighbor_row.resize(source->width());
00099         ith_row.resize(source->width());
00100         source->getRow(i,ith_row);
00101         for (int k=0;k<n_neighbors;k++)
00102         {
00103             diff_k = differences(k);
00104             source->getRow(neighbors(i,k),neighbor_row);
00105             substract(neighbor_row,ith_row, diff_k);
00106             // normalize result
00107             // now it's done in ProjectionErrorVariable diff_k /= norm(diff_k);
00108 
00109             if(append_neighbors)
00110             {
00111                 v.subVec(n_neighbors*source->width()+(append_indexes?n_neighbors+1:0)+k*source->width(),source->width()) << neighbor_row;
00112             }
00113 
00114         }
00115 
00116         if(append_indexes)
00117         {
00118             v[n_neighbors*source->width()] = i;
00119             for(int k=0; k<n_neighbors; k++)
00120                 v[n_neighbors*source->width()+k+1] = neighbors(i,k);
00121         }
00122     }
00123 
00124 }
00125 
00126 void LocalNeighborsDifferencesVMatrix::declareOptions(OptionList& ol)
00127 {
00128     declareOption(ol, "n_neighbors", &LocalNeighborsDifferencesVMatrix::n_neighbors, OptionBase::buildoption,
00129                   "Number of nearest neighbors. Determines the width of this vmatrix, which\n"
00130                   "is source->width() * n_neighbors.\n");
00131     declareOption(ol, "concat_neighbors", &LocalNeighborsDifferencesVMatrix::concat_neighbors, OptionBase::buildoption,
00132                   "If false, returns the concatenation of nearest neighbors(x) -x  from 1 to n_neighbors , else, returns the n_neighbor nearest neighbor(x) - x\n"
00133                   "(I know, it doesn't make sense. This should be corrected...)");
00134     declareOption(ol, "append_indexes", &LocalNeighborsDifferencesVMatrix::append_indexes, OptionBase::buildoption,
00135                   "Indication that the indexes of the current data point and of the k nearest neighbors\n"
00136                   "should be appended to the row of the VMatrix.\n");
00137     declareOption(ol, "append_neighbors", &LocalNeighborsDifferencesVMatrix::append_indexes, OptionBase::buildoption,
00138                   "Indication that the neighbor vectors of the k nearest neighbors\n"
00139                   "should be appended to the row of the VMatrix.\n");
00140 
00141     // Now call the parent class' declareOptions
00142     inherited::declareOptions(ol);
00143 }
00144 
00145 void LocalNeighborsDifferencesVMatrix::build_()
00146 {
00147     // find the nearest neighbors, if not done already
00148     if (source && (neighbors.length()==0 || source->length()!=length_ || source->width()*n_neighbors!=width_))
00149         // will not work if source is changed but has the same dimensions
00150     {
00151         if (concat_neighbors)
00152         {
00153             width_ = source->width();
00154             if(append_indexes) width_ += 2;
00155             if(append_neighbors) width_ += source->width();
00156         }
00157         else
00158         {
00159             width_ = source->width()*n_neighbors;
00160             if(append_indexes) width_ += n_neighbors+1;
00161             if(append_neighbors) width_ += source->width()*n_neighbors;
00162         }
00163 
00164         length_ = source->length();
00165         neighbors.resize(source->length(),n_neighbors);
00166         a_row.resize(source->width());
00167         for (int i=0;i<source->length();i++)
00168         {
00169             source->getRow(i,a_row);
00170             TVec<int> neighbors_of_i = neighbors(i);
00171             computeNearestNeighbors(source,a_row,neighbors_of_i,i);
00172         }
00173     }
00174 
00175     updateMtime(source);
00176 }
00177 
00178 // ### Nothing to add here, simply calls build_
00179 void LocalNeighborsDifferencesVMatrix::build()
00180 {
00181     inherited::build();
00182     build_();
00183 }
00184 
00185 void LocalNeighborsDifferencesVMatrix::makeDeepCopyFromShallowCopy(CopiesMap& copies)
00186 {
00187     inherited::makeDeepCopyFromShallowCopy(copies);
00188     deepCopyField(neighbor_row, copies);
00189     deepCopyField(ith_row, copies);
00190     deepCopyField(a_row, copies);
00191     deepCopyField(neighbors, copies);
00192 }
00193 
00194 } // end of namespace PLearn
00195 
00196 
00197 /*
00198   Local Variables:
00199   mode:c++
00200   c-basic-offset:4
00201   c-file-style:"stroustrup"
00202   c-file-offsets:((innamespace . 0)(inline-open . 0))
00203   indent-tabs-mode:nil
00204   fill-column:79
00205   End:
00206 */
00207 // 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