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: SubMatVariable.cc 5694 2006-05-29 12:48:46Z chapados $ 00040 * This file is part of the PLearn library. 00041 ******************************************************* */ 00042 00043 #include "ExtendedVariable.h" 00044 #include "SubMatVariable.h" 00045 //#include "Var_utils.h" 00046 00047 namespace PLearn { 00048 using namespace std; 00049 00050 00053 PLEARN_IMPLEMENT_OBJECT( 00054 SubMatVariable, 00055 "Takes a submatrix of an input variable", 00056 "This Variable performs creates a view of a subset of an input variable.\n" 00057 "The starting row and column in the input variable must be specified, as\n" 00058 "well as the new number of rows and columns.\n" 00059 "\n" 00060 "Variables of this kind can also be created from C++ through the subMat\n" 00061 "function.\n"); 00062 00063 SubMatVariable::SubMatVariable(Variable* v, int i, int j, int the_length, int the_width) 00064 : inherited(v, the_length, the_width), 00065 startk(i*v->width()+j), 00066 length_(the_length), 00067 width_(the_width), 00068 i_(i), 00069 j_(j) 00070 { 00071 build_(); 00072 } 00073 00074 void SubMatVariable::build() 00075 { 00076 inherited::build(); 00077 build_(); 00078 } 00079 00080 void SubMatVariable::build_() 00081 { 00082 if (input) { 00083 // input is v from constructor 00084 if(i_ < 0 || i_ + length() > input->length() || j_ < 0 || j_ + width() > input->width()) 00085 PLERROR("In SubMatVariable: requested sub-matrix is out of matrix bounds"); 00086 startk = i_ * input->width() + j_; 00087 } 00088 } 00089 00090 void 00091 SubMatVariable::declareOptions(OptionList &ol) 00092 { 00093 declareOption( 00094 ol, "length_", &SubMatVariable::length_, OptionBase::buildoption, 00095 "New length (number of rows) of the SubVMatrix variable"); 00096 00097 declareOption( 00098 ol, "width_", &SubMatVariable::width_, OptionBase::buildoption, 00099 "New width (number of columns) of the SubVMatrix variable"); 00100 00101 declareOption( 00102 ol, "i_", &SubMatVariable::i_, OptionBase::buildoption, 00103 "Starting ROW in the input variable"); 00104 00105 declareOption( 00106 ol, "j_", &SubMatVariable::j_, OptionBase::buildoption, 00107 "Starting COLUMN in the input variable"); 00108 00109 declareOption( 00110 ol, "startk", &SubMatVariable::startk, OptionBase::learntoption, 00111 "Should not be set directly: this is equal to the starting element\n" 00112 "in the INPUT MATRIX corresponding to the settings of i_ and j_."); 00113 00114 inherited::declareOptions(ol); 00115 } 00116 00117 void SubMatVariable::recomputeSize(int& l, int& w) const 00118 { l=length_; w=width_; } 00119 00120 void SubMatVariable::fprop() 00121 { 00122 if(width()==input->width()) // optimized version for this special case 00123 { 00124 real* inputdata = input->valuedata+startk; 00125 for(int k=0; k<nelems(); k++) 00126 valuedata[k] = inputdata[k]; 00127 } 00128 else // general version 00129 { 00130 real* inputrowdata = input->valuedata+startk; 00131 int thisk=0; 00132 for(int i=0; i<length(); i++) 00133 { 00134 for(int j=0; j<width(); j++) 00135 valuedata[thisk++] = inputrowdata[j]; 00136 inputrowdata += input->width(); 00137 } 00138 } 00139 } 00140 00141 00142 void SubMatVariable::bprop() 00143 { 00144 if(width()==input->width()) // optimized version for this special case 00145 { 00146 real* inputgradient = input->gradientdata+startk; 00147 for(int k=0; k<nelems(); k++) 00148 inputgradient[k] += gradientdata[k]; 00149 } 00150 else // general version 00151 { 00152 real* inputrowgradient = input->gradientdata+startk; 00153 int thisk=0; 00154 for(int i=0; i<length(); i++) 00155 { 00156 for(int j=0; j<width(); j++) 00157 inputrowgradient[j] += gradientdata[thisk++]; 00158 inputrowgradient += input->width(); 00159 } 00160 } 00161 } 00162 00163 00164 void SubMatVariable::bbprop() 00165 { 00166 if (input->diaghessian.length()==0) 00167 input->resizeDiagHessian(); 00168 if(width()==input->width()) // optimized version for this special case 00169 { 00170 real* inputdiaghessian = input->diaghessian.data()+startk; 00171 for(int k=0; k<nelems(); k++) 00172 inputdiaghessian[k] += diaghessiandata[k]; 00173 } 00174 else // general version 00175 { 00176 real* inputrowdiaghessian = input->diaghessiandata+startk; 00177 int thisk=0; 00178 for(int i=0; i<length(); i++) 00179 { 00180 for(int j=0; j<width(); j++) 00181 inputrowdiaghessian[j] += diaghessiandata[thisk++]; 00182 inputrowdiaghessian += input->width(); 00183 } 00184 } 00185 } 00186 00187 00188 void SubMatVariable::symbolicBprop() 00189 { 00190 int i = startk/input->width(); 00191 int j = startk%input->width(); 00192 int topextent = i; 00193 int bottomextent = input->length()-(i+length()); 00194 int leftextent = j; 00195 int rightextent = input->width()-(j+width()); 00196 input->accg(extend(g,topextent,bottomextent,leftextent,rightextent)); 00197 } 00198 00199 00200 void SubMatVariable::rfprop() 00201 { 00202 if (rValue.length()==0) resizeRValue(); 00203 if(width()==input->width()) // optimized version for this special case 00204 { 00205 real* inputrdata = input->rvaluedata+startk; 00206 for(int k=0; k<nelems(); k++) 00207 rvaluedata[k] = inputrdata[k]; 00208 } 00209 else // general version 00210 { 00211 real* inputrowrdata = input->rvaluedata+startk; 00212 int thisk=0; 00213 for(int i=0; i<length(); i++) 00214 { 00215 for(int j=0; j<width(); j++) 00216 rvaluedata[thisk++] = inputrowrdata[j]; 00217 inputrowrdata += input->width(); 00218 } 00219 } 00220 } 00221 00222 } // end of namespace PLearn 00223 00224 00225 /* 00226 Local Variables: 00227 mode:c++ 00228 c-basic-offset:4 00229 c-file-style:"stroustrup" 00230 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00231 indent-tabs-mode:nil 00232 fill-column:79 00233 End: 00234 */ 00235 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :