PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // LinearCombinationOfScalarVariables.cc 00004 // 00005 // Copyright (C) 2009 Pascal Vincent 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 // Authors: Pascal Vincent 00036 00040 #include "LinearCombinationOfScalarVariables.h" 00041 00042 namespace PLearn { 00043 using namespace std; 00044 00047 PLEARN_IMPLEMENT_OBJECT( 00048 LinearCombinationOfScalarVariables, 00049 "Computes a linear combination of scalar variables", 00050 "Given an varray of input variables, computes sum_k coefs[k]*varray[k]->value[0] \n" 00051 "i.e. you may also include non-scalar variables, but only their first element will be used \n" 00052 ); 00053 00054 LinearCombinationOfScalarVariables::LinearCombinationOfScalarVariables() 00055 :constant_term(0), 00056 appendinputs(false) 00057 {} 00058 00059 // constructors from input variables. 00060 // NaryVariable constructor (inherited) takes a VarArray as argument. 00061 // You can either construct from a VarArray (if the number of parent Var is not 00062 // fixed, for instance), or construct a VarArray from Var by operator &: 00063 // input1 & input2 & input3. You can also do both, uncomment what you prefer. 00064 00065 // LinearCombinationOfScalarVariables::LinearCombinationOfScalarVariables(const VarArray& vararray) 00066 // ### replace with actual parameters 00067 // : inherited(vararray, this_variable_length, this_variable_width), 00068 // parameter(default_value), 00069 // ... 00070 // { 00071 // // ### You may (or not) want to call build_() to finish building the 00072 // // ### object 00073 // } 00074 00075 // LinearCombinationOfScalarVariables::LinearCombinationOfScalarVariables(Var input1, Var input2, 00076 // Var input3, ...) 00077 // ### replace with actual parameters 00078 // : inherited(input1 & input2 & input3 & ..., 00079 // this_variable_length, this_variable_width), 00080 // parameter(default_value), 00081 // ... 00082 // { 00083 // // ### You may (or not) want to call build_() to finish building the 00084 // // ### object 00085 // } 00086 00087 // constructor from input variable and parameters 00088 LinearCombinationOfScalarVariables::LinearCombinationOfScalarVariables(const VarArray& vararray, 00089 Vec the_coefs) 00090 : inherited(vararray, 1, appendinputs?(1+vararray.length()):1), 00091 coefs(the_coefs), constant_term(0), appendinputs(false) 00092 { 00093 build_(); 00094 } 00095 00096 // constructor from input variable and parameters 00097 // LinearCombinationOfScalarVariables::LinearCombinationOfScalarVariables(Var input1, Var input2, 00098 // Var input3, ..., 00099 // param_type the_parameter, ...) 00100 // ### replace with actual parameters 00101 // : inherited(input1 & input2 & input3 & ..., 00102 // this_variable_length, this_variable_width), 00103 // parameter(the_parameter), 00104 // ... 00105 // { 00106 // // ### You may (or not) want to call build_() to finish building the 00107 // // ### object 00108 // } 00109 00110 void LinearCombinationOfScalarVariables::recomputeSize(int& l, int& w) const 00111 { 00112 l = 1; 00113 if(!appendinputs) 00114 w = 1; 00115 else 00116 w = 1+varray.length(); 00117 } 00118 00119 // ### computes value from varray values 00120 void LinearCombinationOfScalarVariables::fprop() 00121 { 00122 real res = constant_term; 00123 int n = varray.length(); 00124 if(appendinputs) 00125 { 00126 for(int k=0; k<n; k++) 00127 { 00128 real val = varray[k]->valuedata[0]; 00129 valuedata[1+k] = val; 00130 res += coefs[k]*val; 00131 } 00132 } 00133 else 00134 { 00135 for(int k=0; k<n; k++) 00136 res += coefs[k]*varray[k]->valuedata[0]; 00137 } 00138 valuedata[0] = res; 00139 } 00140 00141 // ### computes varray gradients from gradient 00142 void LinearCombinationOfScalarVariables::bprop() 00143 { 00144 real gr = gradientdata[0]; 00145 for(int k=0; k<varray.length(); k++) 00146 varray[k]->gradientdata[0] += gr*coefs[k]; 00147 } 00148 00149 // ### You can implement these methods: 00150 // void LinearCombinationOfScalarVariables::bbprop() {} 00151 // void LinearCombinationOfScalarVariables::symbolicBprop() {} 00152 // void LinearCombinationOfScalarVariables::rfprop() {} 00153 00154 00155 // ### Nothing to add here, simply calls build_ 00156 void LinearCombinationOfScalarVariables::build() 00157 { 00158 inherited::build(); 00159 build_(); 00160 } 00161 00162 void LinearCombinationOfScalarVariables::makeDeepCopyFromShallowCopy(CopiesMap& copies) 00163 { 00164 inherited::makeDeepCopyFromShallowCopy(copies); 00165 deepCopyField(coefs, copies); 00166 } 00167 00168 void LinearCombinationOfScalarVariables::declareOptions(OptionList& ol) 00169 { 00170 // ### Declare all of this object's options here. 00171 // ### For the "flags" of each option, you should typically specify 00172 // ### one of OptionBase::buildoption, OptionBase::learntoption or 00173 // ### OptionBase::tuningoption. If you don't provide one of these three, 00174 // ### this option will be ignored when loading values from a script. 00175 // ### You can also combine flags, for example with OptionBase::nosave: 00176 // ### (OptionBase::buildoption | OptionBase::nosave) 00177 00178 declareOption(ol, "coefs", &LinearCombinationOfScalarVariables::coefs, 00179 OptionBase::buildoption, 00180 "The vector of coefficients for the linear combination (weights for the sum)"); 00181 00182 declareOption(ol, "constant_term", &LinearCombinationOfScalarVariables::constant_term, 00183 OptionBase::buildoption, 00184 "A constant term whose valiue will be added to the linear combination"); 00185 00186 declareOption(ol, "appendinputs", &LinearCombinationOfScalarVariables::appendinputs, 00187 OptionBase::buildoption, 00188 "If true, the values of the first element of all input variables \n" 00189 "(with which we compute the weighted sum) will be appended in the \n" 00190 "produced output vector (just after their weighted sum). \n" 00191 "Note: gradient received on those appended elements is ignored (i.e. not backpropagated).\n" 00192 " these are only useful as extra information (a decomposition of the cost) for reporting purpose"); 00193 00194 // Now call the parent class' declareOptions 00195 inherited::declareOptions(ol); 00196 } 00197 00198 void LinearCombinationOfScalarVariables::build_() 00199 { 00200 // ### This method should do the real building of the object, 00201 // ### according to set 'options', in *any* situation. 00202 // ### Typical situations include: 00203 // ### - Initial building of an object from a few user-specified options 00204 // ### - Building of a "reloaded" object: i.e. from the complete set of 00205 // ### all serialised options. 00206 // ### - Updating or "re-building" of an object after a few "tuning" 00207 // ### options have been modified. 00208 // ### You should assume that the parent class' build_() has already been 00209 // ### called. 00210 } 00211 00212 00213 } // end of namespace PLearn 00214 00215 00216 /* 00217 Local Variables: 00218 mode:c++ 00219 c-basic-offset:4 00220 c-file-style:"stroustrup" 00221 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00222 indent-tabs-mode:nil 00223 fill-column:79 00224 End: 00225 */ 00226 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :