PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // StackedSplitter.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: StackedSplitter.cc 6861 2007-04-09 19:04:15Z saintmlx $ 00037 ******************************************************* */ 00038 00039 // Authors: Olivier Delalleau 00040 00044 #include "NoSplitSplitter.h" 00045 #include "StackedSplitter.h" 00046 00047 namespace PLearn { 00048 using namespace std; 00049 00051 // StackedSplitter // 00053 StackedSplitter::StackedSplitter() 00054 : last_k_init(-1) 00055 { 00056 } 00057 00058 PLEARN_IMPLEMENT_OBJECT(StackedSplitter, 00059 "Applies additional splitters on the splits of a first splitter.", 00060 "Each set of a split of the initial splitter is split again by another splitter,\n" 00061 "which is different for each set. If no splitter is given for some set, then this\n" 00062 "set remains unchanged.\n" 00063 ); 00064 00066 // declareOptions // 00068 void StackedSplitter::declareOptions(OptionList& ol) 00069 { 00070 // ### Declare all of this object's options here 00071 // ### For the "flags" of each option, you should typically specify 00072 // ### one of OptionBase::buildoption, OptionBase::learntoption or 00073 // ### OptionBase::tuningoption. Another possible flag to be combined with 00074 // ### is OptionBase::nosave 00075 00076 declareOption(ol, "initial_splitter", &StackedSplitter::initial_splitter, OptionBase::buildoption, 00077 "The initial splitter to be used."); 00078 00079 declareOption(ol, "top_splitters", &StackedSplitter::top_splitters, OptionBase::buildoption, 00080 "The splitters applied on each set of the initial splitter. One must provide\n" 00081 "initial_splitters->nSetsPerSplit() splitters (*0 means no splitter)."); 00082 00083 // Now call the parent class' declareOptions 00084 inherited::declareOptions(ol); 00085 } 00086 00088 // build // 00090 void StackedSplitter::build() 00091 { 00092 inherited::build(); 00093 build_(); 00094 } 00095 00097 // build_ // 00099 void StackedSplitter::build_() 00100 { 00101 // ### This method should do the real building of the object, 00102 // ### according to set 'options', in *any* situation. 00103 // ### Typical situations include: 00104 // ### - Initial building of an object from a few user-specified options 00105 // ### - Building of a "reloaded" object: i.e. from the complete set of all serialised options. 00106 // ### - Updating or "re-building" of an object after a few "tuning" options have been modified. 00107 // ### You should assume that the parent class' build_() has already been called. 00108 if (initial_splitter && top_splitters.isNotEmpty()) { 00109 if (initial_splitter->nSetsPerSplit() != top_splitters.length()) 00110 PLERROR("In StackedSplitter::build_ - initial_splitter->nSetsPerSplit() != top_splitters.length()"); 00111 // Replace each null splitter with a NoSplitSplitter 00112 for (int i = 0; i < top_splitters.length(); i++) 00113 if (!top_splitters[i]) 00114 top_splitters[i] = new NoSplitSplitter(); 00115 // Make sure all splitters have a consistent number of splits. 00116 int ns = top_splitters[0]->nsplits(); 00117 for (int i = 1; i < top_splitters.length(); i++) 00118 if (top_splitters[i]->nsplits() != ns) 00119 PLERROR("In StackedSplitter::build_ - All splitters in 'top_splitters' must give the same number of splits"); 00120 } 00121 } 00122 00124 // getSplit // 00126 TVec<VMat> StackedSplitter::getSplit(int k) 00127 { 00128 TVec<VMat> result; 00129 int k_init = k / top_splitters[0]->nsplits(); 00130 int k_top = k % top_splitters[0]->nsplits(); 00131 if (k_init != last_k_init) { 00132 // We need to recompute the split given by the initial splitter. 00133 last_split_init = initial_splitter->getSplit(k_init); 00134 last_k_init = k_init; 00135 // Assign each set to its top splitter. 00136 for (int i = 0; i < top_splitters.length(); i++) { 00137 top_splitters[i]->setDataSet(last_split_init[i]); 00138 } 00139 } 00140 for (int i = 0; i < top_splitters.length(); i++) { 00141 result->append(top_splitters[i]->getSplit(k_top)); 00142 } 00143 return result; 00144 } 00145 00147 // makeDeepCopyFromShallowCopy // 00149 void StackedSplitter::makeDeepCopyFromShallowCopy(CopiesMap& copies) 00150 { 00151 inherited::makeDeepCopyFromShallowCopy(copies); 00152 00153 // ### Call deepCopyField on all "pointer-like" fields 00154 // ### that you wish to be deepCopied rather than 00155 // ### shallow-copied. 00156 // ### ex: 00157 // deepCopyField(trainvec, copies); 00158 00159 // ### Remove this line when you have fully implemented this method. 00160 PLERROR("StackedSplitter::makeDeepCopyFromShallowCopy not fully (correctly) implemented yet!"); 00161 } 00162 00164 // nSetsPerSplit // 00166 int StackedSplitter::nSetsPerSplit() const 00167 { 00168 int count = 0; 00169 for (int i = 0; i < top_splitters.length(); i++) { 00170 count += top_splitters[i]->nSetsPerSplit(); 00171 } 00172 return count; 00173 } 00174 00176 // nsplits // 00178 int StackedSplitter::nsplits() const 00179 { 00180 return initial_splitter->nsplits() * top_splitters[0]->nsplits(); 00181 } 00182 00184 // setDataSet // 00186 void StackedSplitter::setDataSet(VMat the_dataset) { 00187 initial_splitter->setDataSet(the_dataset); 00188 // Reset 'last_k_init' since the dataset has changed. 00189 last_k_init = -1; 00190 } 00191 00192 } // end of namespace PLearn 00193 00194 00195 /* 00196 Local Variables: 00197 mode:c++ 00198 c-basic-offset:4 00199 c-file-style:"stroustrup" 00200 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00201 indent-tabs-mode:nil 00202 fill-column:79 00203 End: 00204 */ 00205 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :