PLearn 0.1
AffineTransformVariable.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: AffineTransformVariable.cc 8770 2008-04-08 17:20:13Z tihocan $
00040  * This file is part of the PLearn library.
00041  ******************************************************* */
00042 
00043 #include "AffineTransformVariable.h"
00044 
00045 namespace PLearn {
00046 using namespace std;
00047 
00048 
00049 PLEARN_IMPLEMENT_OBJECT(
00050         AffineTransformVariable,
00051         "Affine transformation of a vector variable.",
00052         "The first input is the vector variable.\n"
00053         "The second input is the matrix of biases (on the first row) and\n"
00054         "weights (in other rows).\n"
00055         "If the first input vector is a row vector, then the result is a\n"
00056         "row vector as well. If it is a column vector, then the result is\n"
00057         "also a column vector. If it is a scalar, then the result is a\n"
00058         "column vector as well, unless the option 'force_row_vec' is set\n"
00059         "to true."
00060 );
00061 
00063 // AffineTransformVariable //
00065 AffineTransformVariable::AffineTransformVariable(Variable* vec,
00066                                                  Variable* transformation,
00067                                                  bool call_build_):
00068     inherited(vec, transformation, 
00069             vec->isScalar() || vec->isColumnVec() ? transformation->width()
00070                                                   : 1,
00071             vec->isScalar() || vec->isColumnVec() ? 1
00072                                                   : transformation->width(),
00073             call_build_),
00074     force_row_vec(false)
00075 {
00076     if (call_build_)
00077         build_();
00078 }
00079 
00081 // build //
00083 void AffineTransformVariable::build()
00084 {
00085     inherited::build();
00086     build_();
00087 }
00088 
00090 // build_ //
00092 void AffineTransformVariable::build_()
00093 {
00094     // input1 is vec from constructor
00095     if (input1 && !input1->isVec())
00096         PLERROR("In AffineTransformVariable: expecting a vector Var (row or column) as first argument");
00097 }
00098 
00100 // declareOptions //
00102 void AffineTransformVariable::declareOptions(OptionList& ol)
00103 {
00104      declareOption(ol, "force_row_vec", &AffineTransformVariable::force_row_vec,
00105                    OptionBase::buildoption,
00106         "If set to true, then the resulting vector will always be a row\n"
00107         "vector, even when the input is a column or a scalar.");
00108 
00109     inherited::declareOptions(ol);
00110 }
00111 
00113 // recomputeSize //
00115 void AffineTransformVariable::recomputeSize(int& l, int& w) const
00116 { 
00117     if (input1 && input2) {
00118         if (force_row_vec || (!input1->isScalar() && input1->isRowVec())) {
00119             // Result is a row vector.
00120             l = 1;
00121             w = input2->width();
00122         } else {
00123             // Result is a column vector.
00124             l = input2->width();
00125             w = 1;
00126         }
00127     } else
00128         l = w = 0;
00129 }
00130 
00132 // fprop //
00134 void AffineTransformVariable::fprop()
00135 {
00136     value << input2->matValue.firstRow();
00137     Mat lintransform = input2->matValue.subMatRows(1,input2->length()-1);
00138     transposeProductAcc(value, lintransform, input1->value);
00139 }
00140 
00142 // bprop //
00144 void AffineTransformVariable::bprop()
00145 {
00146     Mat&  afftr = input2->matValue;
00147     int l = afftr.length();
00148     // Vec bias = afftr.firstRow();
00149     Mat lintr = afftr.subMatRows(1,l-1);
00150 
00151     Mat& afftr_g = input2->matGradient;
00152     Vec bias_g = afftr_g.firstRow();
00153     Mat lintr_g = afftr_g.subMatRows(1,l-1);
00154 
00155     bias_g += gradient;    
00156     if(!input1->dont_bprop_here)      
00157         productAcc(input1->gradient, lintr, gradient);
00158     externalProductAcc(lintr_g, input1->value, gradient);
00159 }
00160 
00161 
00162 void AffineTransformVariable::symbolicBprop()
00163 {
00164     PLERROR("AffineTransformVariable::symbolicBprop() not implemented");
00165 }
00166 
00167 } // end of namespace PLearn
00168 
00169 
00170 /*
00171   Local Variables:
00172   mode:c++
00173   c-basic-offset:4
00174   c-file-style:"stroustrup"
00175   c-file-offsets:((innamespace . 0)(inline-open . 0))
00176   indent-tabs-mode:nil
00177   fill-column:79
00178   End:
00179 */
00180 // 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