PLearn 0.1
|
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 :