PLearn 0.1
UnfoldedSumOfVariable.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // PLearn (A C++ Machine Learning Library)
00004 // Copyright (C) 1998 Pascal Vincent
00005 // Copyright (C) 1999-2002 Pascal Vincent, Yoshua Bengio, Rejean Ducharme and University of Montreal
00006 // Copyright (C) 2001-2002 Nicolas Chapados, Ichiro Takeuchi, Jean-Sebastien Senecal
00007 // Copyright (C) 2002 Xiangdong Wang, Christian Dorion
00008 
00009 // Redistribution and use in source and binary forms, with or without
00010 // modification, are permitted provided that the following conditions are met:
00011 // 
00012 //  1. Redistributions of source code must retain the above copyright
00013 //     notice, this list of conditions and the following disclaimer.
00014 // 
00015 //  2. Redistributions in binary form must reproduce the above copyright
00016 //     notice, this list of conditions and the following disclaimer in the
00017 //     documentation and/or other materials provided with the distribution.
00018 // 
00019 //  3. The name of the authors may not be used to endorse or promote
00020 //     products derived from this software without specific prior written
00021 //     permission.
00022 // 
00023 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
00024 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00025 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
00026 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00027 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00028 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00029 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00030 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00031 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00032 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 // 
00034 // This file is part of the PLearn library. For more information on the PLearn
00035 // library, go to the PLearn Web site at www.plearn.org
00036 
00037 
00038 /* *******************************************************      
00039  * $Id: UnfoldedSumOfVariable.cc 6861 2007-04-09 19:04:15Z saintmlx $
00040  * This file is part of the PLearn library.
00041  ******************************************************* */
00042 
00043 #include "UnfoldedSumOfVariable.h"
00044 #include <plearn/display/DisplayUtils.h>
00045 
00046 namespace PLearn {
00047 using namespace std;
00048 
00051 PLEARN_IMPLEMENT_OBJECT(UnfoldedSumOfVariable, "Variable that sums the value of a Func evaluated on each row of a matrix.\n", 
00052                         "However, unlike the SumOfVariable, it does so by unfolding the Func (up to given maximum number\n"
00053                         "of times 'max_bag_size'), and it allows that number to be variable. Each of the unfolded Func\n"
00054                         "is applied on a different row of the input matrix. The number of rows to sum is specified on the\n"
00055                         "fly by another input, the bag_size.\n");
00056 
00057 UnfoldedSumOfVariable::UnfoldedSumOfVariable(Var inputmatrix, Var bagsize, Func the_f, int max_bagsize)
00058     : inherited(nonInputParentsOfPath(the_f->inputs,the_f->outputs) & inputmatrix & bagsize, 
00059                 the_f->outputs[0]->length(), 
00060                 the_f->outputs[0]->width()),
00061       input_matrix(inputmatrix), bag_size(bagsize),
00062       f(the_f), max_bag_size(max_bagsize)
00063 {
00064     build();
00065 }
00066 
00067 void UnfoldedSumOfVariable::build()
00068 {
00069     inherited::build();
00070     build_();
00071 }
00072 
00073 void UnfoldedSumOfVariable::build_()
00074 {
00075     if (f) {
00076         if(f->outputs.size()!=1)
00077             PLERROR("In UnfoldedSumOfVariable: function must have a single variable output (maybe you can vconcat the vars into a single one prior to calling sumOf, if this is really what you want)");
00078         f->inputs.setDontBpropHere(true);
00079         inputs.resize(max_bag_size);
00080         outputs.resize(max_bag_size);
00081         f_paths.resize(max_bag_size);
00082         for (int i=0;i<max_bag_size;i++)
00083         {
00084             inputs[i].resize(f->inputs.size());
00085             for (int j = 0; j < f->inputs.size(); j++) {
00086                 inputs[i][j] = Var(f->inputs[j]->length(), f->inputs[j]->width());
00087             }
00088             outputs[i] = f(inputs[i])[0];
00089             f_paths[i] = propagationPath(inputs[i],outputs[i]);
00090         }
00091     }
00092 }
00093 
00094 void UnfoldedSumOfVariable::declareOptions(OptionList& ol)
00095 {
00096     declareOption(ol, "f", &UnfoldedSumOfVariable::f, OptionBase::buildoption, 
00097                   "    Func that is replicated for each element of the 'bag' taken from the VMat.");
00098 
00099     declareOption(ol, "input_matrix", &UnfoldedSumOfVariable::input_matrix, OptionBase::buildoption, 
00100                   "    Var that contains the data, with multiple consecutive rows forming one bag.\n"
00101                   "    The last row of a bag has a non-missing target value.\n");
00102 
00103     declareOption(ol, "bag_size", &UnfoldedSumOfVariable::bag_size, OptionBase::buildoption, 
00104                   "    Var that gives the size of the bag (number of rows of input_matrix to consider).\n");
00105 
00106     declareOption(ol, "max_bag_size", &UnfoldedSumOfVariable::max_bag_size, OptionBase::buildoption, 
00107                   "    maximum number of examples in a bag (more than that in input_matrix will trigger a run-time error).\n");
00108 
00109     inherited::declareOptions(ol);
00110 }
00111 
00112 void UnfoldedSumOfVariable::recomputeSize(int& l, int& w) const
00113 {
00114     if (f && f->outputs.size()) {
00115         l = f->outputs[0]->length();
00116         w = f->outputs[0]->width();
00117     } else
00118         l = w = 0;
00119 }
00120 
00122 #ifdef __INTEL_COMPILER
00123 #pragma warning(disable:1419)  // Get rid of compiler warning.
00124 #endif
00125 extern void varDeepCopyField(Var& field, CopiesMap& copies);
00126 #ifdef __INTEL_COMPILER
00127 #pragma warning(default:1419)
00128 #endif
00129 
00130 
00131 void UnfoldedSumOfVariable::makeDeepCopyFromShallowCopy(CopiesMap& copies)
00132 {
00133     inherited::makeDeepCopyFromShallowCopy(copies);
00134     varDeepCopyField(input_matrix, copies);
00135     varDeepCopyField(bag_size, copies);
00136     deepCopyField(f, copies);
00137     deepCopyField(inputs, copies);
00138     deepCopyField(outputs, copies);
00139     deepCopyField(f_paths, copies);
00140 }
00141 
00142 
00143 void UnfoldedSumOfVariable::fprop()
00144 {
00145     value.clear();
00146     int bagsize = (int)bag_size->valuedata[0];
00147     if (bagsize>max_bag_size)
00148         PLERROR("UnfoldedSumOfVariable: bag size=%d > expected max. bag size(%d)",
00149                 bagsize,max_bag_size);
00150     for (int i=0;i<bagsize;i++)
00151     {
00152         inputs[i] << input_matrix->matValue(i);
00153         f_paths[i].fprop();
00154         value += outputs[i]->value;
00155     }
00156 }
00157 
00158 
00159 void UnfoldedSumOfVariable::bprop()
00160 { 
00161     int bagsize = (int)bag_size->valuedata[0];
00162     for (int i=0;i<bagsize;i++)
00163     {
00164         f_paths[i].clearGradient();
00165         outputs[i]->gradient << gradient;
00166         f_paths[i].bprop();
00167     }
00168 }
00169 
00170 
00171 void UnfoldedSumOfVariable::printInfo(bool print_gradient)
00172 {
00173     for (int i=0;i<max_bag_size;i++)
00174         f_paths[i].printInfo(print_gradient);
00175     cout << info() << " : " << getName() << "[" << (void*)this << "]" 
00176          << "(input_matrix=" << (void*)input_matrix << ", bag_size=" 
00177          << (void*)bag_size << ", ";
00178     for(int i=0; i<max_bag_size; i++) cout << (void*)outputs[i] << " ";
00179     cout << ") = " << value;
00180     if (print_gradient) cout << " gradient=" << gradient;
00181     cout << endl; 
00182 }
00183 
00184 
00185 
00186 } // end of namespace PLearn
00187 
00188 
00189 /*
00190   Local Variables:
00191   mode:c++
00192   c-basic-offset:4
00193   c-file-style:"stroustrup"
00194   c-file-offsets:((innamespace . 0)(inline-open . 0))
00195   indent-tabs-mode:nil
00196   fill-column:79
00197   End:
00198 */
00199 // 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