PLearn 0.1
DiagonalizedFactorsProductVariable.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: DiagonalizedFactorsProductVariable.cc 8919 2008-04-30 15:06:38Z tihocan $
00040  * This file is part of the PLearn library.
00041  ******************************************************* */
00042 
00043 #include "DiagonalizedFactorsProductVariable.h"
00044 #include "Var_utils.h"
00045 #include <plearn/math/TMat_maths.h>
00046 
00047 namespace PLearn {
00048 using namespace std;
00049 
00050 
00053 PLEARN_IMPLEMENT_OBJECT(DiagonalizedFactorsProductVariable,
00054                         "Variable that represents the leftmatrix*diag(vector)*rightmatrix product",
00055                         "The three parents are respectively the left matrix U, the center vector d,\n"
00056                         "and the right matrix V. Options allow to transpose the matrices.\n"
00057                         "The output value has elements (i,j) equal to sum_k U_{ik} d_k V_{kj}\n"
00058     );
00059 
00060 DiagonalizedFactorsProductVariable::DiagonalizedFactorsProductVariable(Var left_matrix, 
00061                                                                        Var center_diagonal, 
00062                                                                        Var right_matrix,
00063                                                                        bool transpose_left_, 
00064                                                                        bool transpose_right_)
00065     : inherited(left_matrix & center_diagonal & (VarArray)right_matrix,
00066                 transpose_left_?left_matrix->width():left_matrix->length(), 
00067                 transpose_right_?right_matrix->length():right_matrix->width()),
00068       transpose_left(transpose_left_), transpose_right(transpose_right_)
00069 {
00070     build_();
00071 }
00072 
00073 void
00074 DiagonalizedFactorsProductVariable::build()
00075 {
00076     inherited::build();
00077     build_();
00078 }
00079 
00080 void
00081 DiagonalizedFactorsProductVariable::build_()
00082 {
00083     if (varray.size()) {
00084         int nl = transpose_left?leftMatrix()->length():leftMatrix()->width();
00085         int nr = transpose_right?rightMatrix()->width():rightMatrix()->length();
00086         int nc = centerDiagonal()->size();
00087         if (nl != nc || nr != nc)
00088             PLERROR("In DiagonalizedFactorsProductVariable: arguments have incompatible sizes!");
00089     }
00090 }
00091 
00092 void DiagonalizedFactorsProductVariable::recomputeSize(int& l, int& w) const
00093 {
00094     if (varray.size()) {
00095         l = transpose_left?varray[0]->width():varray[0]->length();
00096         w = transpose_right?varray[2]->length():varray[2]->width();
00097     } else
00098         l = w = 0;
00099 }
00100 
00101 void DiagonalizedFactorsProductVariable::fprop()
00102 {
00103     if (transpose_left)
00104     {
00105         if (transpose_right)
00106             diagonalizedFactorsTransposeProductTranspose(matValue,leftMatrix()->matValue,centerDiagonal()->value,rightMatrix()->matValue);
00107         else
00108             diagonalizedFactorsTransposeProduct(matValue,leftMatrix()->matValue,centerDiagonal()->value,rightMatrix()->matValue);
00109     } else {
00110         if (transpose_right)
00111             diagonalizedFactorsProductTranspose(matValue,leftMatrix()->matValue,centerDiagonal()->value,rightMatrix()->matValue);
00112         else
00113             diagonalizedFactorsProduct(matValue,leftMatrix()->matValue,centerDiagonal()->value,rightMatrix()->matValue);
00114     }
00115 }
00116 
00117 
00118 void DiagonalizedFactorsProductVariable::bprop()
00119 {
00120     if (transpose_left)
00121     {
00122         if (transpose_right)
00123         {
00124             // SINCE res[i,j] = sum_k U[k,i] d[k] V[j,k] ==>
00125             // dC/dU[k,i] = d_k * sum_j dC/dres[i,j] V[j,k]
00126             // dC/dd[k] = sum_{ij} dC/dres[i,j] U[k,i] V[j,k]
00127             // dC/dV[j,k] = d_k * sum_i dC/dres[i,j] U[k,i]
00128             diagonalizedFactorsTransposeProductTransposeBprop(matGradient,leftMatrix()->matValue,
00129                                                               centerDiagonal()->value,rightMatrix()->matValue,
00130                                                               leftMatrix()->matGradient,
00131                                                               centerDiagonal()->gradient,rightMatrix()->matGradient); 
00132         }
00133         else
00134         {
00135             // SINCE res[i,j] = sum_k U[k,i] d[k] V[k,j] ==>
00136             // dC/dU[k,i] = d_k * sum_j dC/dres[i,j] V[k,j]
00137             // dC/dd[k] = sum_{ij} dC/dres[i,j] U[k,i] V[k,j]
00138             // dC/dV[k,j] = d_k sum_i dC/dres[i,j] U[k,i]
00139             diagonalizedFactorsTransposeProductBprop(matGradient,leftMatrix()->matValue,centerDiagonal()->value,
00140                                                      rightMatrix()->matValue, leftMatrix()->matGradient,
00141                                                      centerDiagonal()->gradient,rightMatrix()->matGradient); 
00142         }
00143     } 
00144     else 
00145     {
00146         if (transpose_right)
00147         {
00148             // SINCE res[i,j] = sum_k U[i,k] d[k] V[j,k] ==>
00149             // dC/dU[i,k] = sum_j dC/dres[i,j] d_k V[j,k]
00150             // dC/dd[k] = sum_{ij} dC/dres[i,j] U[i,k] V[j,k]
00151             // dC/dV[j,k] = sum_i dC/dres[i,j] d_k U[i,k]
00152             diagonalizedFactorsProductTransposeBprop(matGradient,leftMatrix()->matValue,centerDiagonal()->value,
00153                                                      rightMatrix()->matValue, leftMatrix()->matGradient,
00154                                                      centerDiagonal()->gradient,rightMatrix()->matGradient); 
00155         }
00156         else
00157         {    
00158             // SINCE res[i,j] = sum_k U[i,k] d[k] V[k,j] ==>
00159             // dC/dU[i,k] += sum_j dC/dres[i,j] d_k V[k,j]
00160             // dC/dd[k] += sum_{ij} dC/dres[i,j] U[i,k] V[k,j]
00161             // dC/dV[k,j] += d_k * sum_i U[i,k] dC/dres[i,j] 
00162             diagonalizedFactorsProductBprop(matGradient,leftMatrix()->matValue,centerDiagonal()->value,
00163                                             rightMatrix()->matValue,leftMatrix()->matGradient,
00164                                             centerDiagonal()->gradient,rightMatrix()->matGradient);
00165         }  
00166     }
00167 }
00168 
00169 
00170 } // end of namespace PLearn
00171 
00172 
00173 /*
00174   Local Variables:
00175   mode:c++
00176   c-basic-offset:4
00177   c-file-style:"stroustrup"
00178   c-file-offsets:((innamespace . 0)(inline-open . 0))
00179   indent-tabs-mode:nil
00180   fill-column:79
00181   End:
00182 */
00183 // 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