PLearn 0.1
|
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 :