PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // RandomNeighborsDifferencesVMatrix.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: RandomNeighborsDifferencesVMatrix.cc 8617 2008-03-03 17:45:54Z nouiz $ 00037 ******************************************************* */ 00038 00039 // Authors: Martin Monperrus 00040 00044 #include "RandomNeighborsDifferencesVMatrix.h" 00045 #include "VMat_computeNearestNeighbors.h" 00046 #include <plearn/math/TMat_maths.h> 00047 #include <plearn/math/random.h> 00048 00049 namespace PLearn { 00050 using namespace std; 00051 00052 00053 RandomNeighborsDifferencesVMatrix::RandomNeighborsDifferencesVMatrix() 00054 :inherited(), n_neighbors(-1), append_current_point_indexe(false), append_random_neighbors_indexes(false) 00055 /* ### Initialise all fields to their default value */ 00056 { 00057 } 00058 00059 PLEARN_IMPLEMENT_OBJECT(RandomNeighborsDifferencesVMatrix, 00060 "Computes the difference between each input row and n_neighbors random points in the source data set.", 00061 "For each row x of the source VMatrix, the resulting row will be the\n" 00062 "concatenation of n_neighbors vectors, each of which is the difference\n" 00063 "between one of the random neighbors of x in the source and x itself.\n" 00064 ); 00065 00066 void RandomNeighborsDifferencesVMatrix::getNewRow(int i, const Vec& v) const 00067 { 00068 if (width_<0) 00069 PLERROR("RandomNeighborsDifferencesVMatrix::getNewRow called but build was not done yet"); 00070 00071 // vue en matrice du vecteur de sortie, ca pointe sur les memes donnees. 00072 Mat differences = v.toMat(n_neighbors,source->width()); 00073 neighbor_row.resize(source->width()); 00074 ith_row.resize(source->width()); 00075 source->getRow(i,ith_row); 00076 int rand_index; 00077 if(append_current_point_indexe) 00078 v[n_neighbors*source->width()+1] = i; 00079 for (int k=0;k<n_neighbors;k++) 00080 { 00081 rand_index = int(uniform_sample()*source->length()); 00082 diff_k = differences(k); 00083 source->getRow(rand_index,neighbor_row); 00084 substract(neighbor_row,ith_row, diff_k); 00085 // normalize result 00086 // now it's done in ProjectionErrorVariable diff_k /= norm(diff_k); 00087 if(append_random_neighbors_indexes) 00088 v[n_neighbors*source->width()+(append_current_point_indexe?1:0)+k] = rand_index; 00089 } 00090 } 00091 00092 void RandomNeighborsDifferencesVMatrix::declareOptions(OptionList& ol) 00093 { 00094 declareOption(ol, "n_neighbors", &RandomNeighborsDifferencesVMatrix::n_neighbors, OptionBase::buildoption, 00095 "Number of nearest neighbors. Determines the width of this vmatrix, which\n" 00096 "is source->width() * n_neighbors.\n"); 00097 declareOption(ol, "append_current_point_indexe", &RandomNeighborsDifferencesVMatrix::append_current_point_indexe, OptionBase::buildoption, 00098 "Indication that the indexe of the current data point should be appended \n" 00099 "to the row of the VMatrix.\n"); 00100 declareOption(ol, "append_random_neighbors_indexes", &RandomNeighborsDifferencesVMatrix::append_random_neighbors_indexes, OptionBase::buildoption, 00101 "Indication that the indexes of the random data points should be appended \n" 00102 "to the row of the VMatrix.\n"); 00103 00104 00105 // Now call the parent class' declareOptions 00106 inherited::declareOptions(ol); 00107 } 00108 00109 void RandomNeighborsDifferencesVMatrix::build_() 00110 { 00111 if (source) 00112 // will not work if source is changed but has the same dimensions 00113 { 00114 updateMtime(source); 00115 width_ = source->width()*n_neighbors; 00116 if(append_current_point_indexe) width_ += 1; 00117 if(append_random_neighbors_indexes) width_ += n_neighbors; 00118 length_ = source->length(); 00119 } 00120 } 00121 00122 // ### Nothing to add here, simply calls build_ 00123 void RandomNeighborsDifferencesVMatrix::build() 00124 { 00125 inherited::build(); 00126 build_(); 00127 } 00128 00129 void RandomNeighborsDifferencesVMatrix::makeDeepCopyFromShallowCopy(CopiesMap& copies) 00130 { 00131 inherited::makeDeepCopyFromShallowCopy(copies); 00132 deepCopyField(neighbor_row, copies); 00133 deepCopyField(ith_row, copies); 00134 } 00135 00136 } // end of namespace PLearn 00137 00138 00139 /* 00140 Local Variables: 00141 mode:c++ 00142 c-basic-offset:4 00143 c-file-style:"stroustrup" 00144 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00145 indent-tabs-mode:nil 00146 fill-column:79 00147 End: 00148 */ 00149 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :