PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // Isomap.cc 00004 // 00005 // Copyright (C) 2004 Olivier Delalleau 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: Isomap.cc 9118 2008-06-11 15:29:17Z tihocan $ 00037 ******************************************************* */ 00038 00039 // Authors: Olivier Delalleau 00040 00043 #include <plearn/ker/DistanceKernel.h> 00044 #include <plearn/ker/GeodesicDistanceKernel.h> 00045 #include "Isomap.h" 00046 00047 namespace PLearn { 00048 using namespace std; 00049 00051 // Isomap // 00053 Isomap::Isomap() 00054 : geodesic_file(""), 00055 geodesic_method("dijkstra"), 00056 knn(10) 00057 { 00058 kernel_is_distance = true; 00059 // Default distance kernel is the classical Euclidean distance. 00060 distance_kernel = new DistanceKernel(2); 00061 min_eigenvalue = 0; 00062 } 00063 00064 PLEARN_IMPLEMENT_OBJECT(Isomap, 00065 "Performs ISOMAP dimensionality reduction.", 00066 "Be careful that when looking for the 'knn' nearest neighbors of a point x,\n" 00067 "we consider all points from the training data D, including x itself if it\n" 00068 "belongs to D. Thus, to obtain the same result as with the classical ISOMAP\n" 00069 "algorithm, one should use one more neighbor.\n" 00070 "Note also that when used out-of-sample, this will result in a different output\n" 00071 "than an algorithm applying the same formula, but considering one less neighbor.\n" 00072 ); 00073 00075 // declareOptions // 00077 void Isomap::declareOptions(OptionList& ol) 00078 { 00079 // ### Declare all of this object's options here 00080 // ### For the "flags" of each option, you should typically specify 00081 // ### one of OptionBase::buildoption, OptionBase::learntoption or 00082 // ### OptionBase::tuningoption. Another possible flag to be combined with 00083 // ### is OptionBase::nosave 00084 00085 // declareOption(ol, "myoption", &Isomap::myoption, OptionBase::buildoption, 00086 // "Help text describing this option"); 00087 // ... 00088 00089 declareOption(ol, "knn", &Isomap::knn, OptionBase::buildoption, 00090 "The number of nearest neighbors considered."); 00091 00092 declareOption(ol, "distance_kernel", &Isomap::distance_kernel, OptionBase::buildoption, 00093 "The kernel used to compute the input space distances."); 00094 00095 declareOption(ol, "geodesic_file", &Isomap::geodesic_file, OptionBase::buildoption, 00096 "If provided, the geodesic distances will be saved in this file in binary format."); 00097 00098 declareOption(ol, "geodesic_method", &Isomap::geodesic_method, OptionBase::buildoption, 00099 "'floyd' or 'djikstra': the method to compute the geodesic distances." 00100 "(cf. GeodesicDistanceKernel)"); 00101 00102 // Now call the parent class' declareOptions 00103 inherited::declareOptions(ol); 00104 00105 // Modify some options from KernelPCA so as to hide them. 00106 redeclareOption(ol, "kernel_is_distance", &Isomap::kernel_is_distance, OptionBase::nosave, 00107 "In ISOMAP, the kernel is always a distance"); 00108 00109 redeclareOption(ol, "kernel", &Isomap::kpca_kernel, OptionBase::learntoption, 00110 "The underlying KPCA kernel is now obtained from 'distance_kernel'."); 00111 00112 } 00113 00115 // build // 00117 void Isomap::build() 00118 { 00119 inherited::build(); 00120 build_(); 00121 } 00122 00124 // build_ // 00126 void Isomap::build_() 00127 { 00128 // Obtain the "real" KPCA kernel by computing the geodesic distances from 00129 // the 'distance_kernel'. 00130 // We have to do this iff: 00131 // 1. A 'distance_kernel' is provided, and 00132 // 2. either: 00133 // 2.a. the 'kpca_kernel' field is not set, or 00134 // 2.b. the 'kpca_kernel' field is not a GeodesicDistanceKernel acting on 'distance_kernel'. 00135 // This is to ensure that a loaded 'kpca_kernel' won't be overwritten. 00136 if (distance_kernel && 00137 (!kpca_kernel || 00138 (dynamic_cast<GeodesicDistanceKernel*>((Kernel*) kpca_kernel))->distance_kernel != distance_kernel)) { 00139 this->kpca_kernel = new GeodesicDistanceKernel(distance_kernel, knn, geodesic_file, true, geodesic_method); 00140 // We have modified the KPCA kernel, we must rebuild the KPCA. 00141 inherited::build(); 00142 } 00143 if (kpca_kernel) 00144 kpca_kernel->report_progress = report_progress; 00145 } 00146 00148 // forget // 00150 void Isomap::forget() 00151 { 00152 inherited::forget(); 00153 } 00154 00156 // makeDeepCopyFromShallowCopy // 00158 void Isomap::makeDeepCopyFromShallowCopy(CopiesMap& copies) 00159 { 00160 inherited::makeDeepCopyFromShallowCopy(copies); 00161 deepCopyField(distance_kernel, copies); 00162 } 00163 00164 } // end of namespace PLearn 00165 00166 00167 /* 00168 Local Variables: 00169 mode:c++ 00170 c-basic-offset:4 00171 c-file-style:"stroustrup" 00172 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00173 indent-tabs-mode:nil 00174 fill-column:79 00175 End: 00176 */ 00177 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :