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: IfThenElseVariable.cc 5876 2006-06-15 14:24:49Z chapados $ 00040 * This file is part of the PLearn library. 00041 ******************************************************* */ 00042 00043 #include "IfThenElseVariable.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( 00054 IfThenElseVariable, 00055 "Variable that represents the element-wise IF-THEN-ELSE", 00056 "Variable that represents the element-wise IF-THEN-ELSE:\n" 00057 "- The first parent is the test (0 or different from 0)\n" 00058 "- The second parent is the value returned when the test is !=0,\n" 00059 "- The third parent is the value returned when the test is ==0,\n"); 00060 00061 IfThenElseVariable::IfThenElseVariable(Var IfVar, Var ThenVar, Var ElseVar) 00062 : inherited(IfVar & ThenVar & (VarArray)ElseVar,ThenVar->length(), ThenVar->width()) 00063 { 00064 build_(); 00065 } 00066 00067 void 00068 IfThenElseVariable::build() 00069 { 00070 inherited::build(); 00071 build_(); 00072 } 00073 00074 void 00075 IfThenElseVariable::build_() 00076 { 00077 if (varray.size()) { 00078 if (varray[1]->length() != varray[2]->length() || varray[1]->width() != varray[2]->width()) 00079 PLERROR("In IfThenElseVariable: ElseVar and ThenVar must have the same size"); 00080 if (!varray[0]->isScalar() && (varray[0]->length() != varray[1]->length() || varray[0]->width() != varray[1]->width())) 00081 PLERROR("In IfThenElseVariable: IfVar must either be a scalar or have the same size as ThenVar and ElseVar"); 00082 } 00083 } 00084 00085 void IfThenElseVariable::recomputeSize(int& l, int& w) const 00086 { 00087 if (varray.size()) { 00088 l = varray[1]->length(); 00089 w = varray[1]->width(); 00090 } else 00091 l = w = 0; 00092 } 00093 00094 void IfThenElseVariable::fprop() 00095 { 00096 if(If()->isScalar()) 00097 { 00098 bool test = !fast_exact_is_equal(If()->valuedata[0], 0); 00099 if (test) 00100 value << Then()->value; 00101 else 00102 value << Else()->value; 00103 } 00104 else 00105 { 00106 real* ifv = If()->valuedata; 00107 real* thenv = Then()->valuedata; 00108 real* elsev = Else()->valuedata; 00109 for (int k=0;k<nelems();k++) 00110 { 00111 if ( !fast_exact_is_equal(ifv[k], 0) ) 00112 valuedata[k]=thenv[k]; 00113 else 00114 valuedata[k]=elsev[k]; 00115 } 00116 } 00117 } 00118 00119 00120 void IfThenElseVariable::bprop() 00121 { 00122 if(If()->isScalar()) 00123 { 00124 if (!fast_exact_is_equal(If()->valuedata[0], 0)) 00125 Then()->gradient += gradient; 00126 else 00127 Else()->gradient += gradient; 00128 } 00129 else 00130 { 00131 real* ifv = If()->valuedata; 00132 real* theng = Then()->gradientdata; 00133 real* elseg = Else()->gradientdata; 00134 for (int k=0;k<nelems();k++) 00135 { 00136 if ( !fast_exact_is_equal(ifv[k], 0) ) 00137 theng[k] += gradientdata[k]; 00138 else 00139 elseg[k] += gradientdata[k]; 00140 } 00141 } 00142 } 00143 00144 00145 void IfThenElseVariable::symbolicBprop() 00146 { 00147 Var zero(length(), width()); 00148 Then()->accg(ifThenElse(If(), g, zero)); 00149 Else()->accg(ifThenElse(If(), zero, g)); 00150 } 00151 00152 00153 void IfThenElseVariable::rfprop() 00154 { 00155 if (rValue.length()==0) resizeRValue(); 00156 if(If()->isScalar()) 00157 { 00158 if (!fast_exact_is_equal(If()->valuedata[0], 0)) 00159 rValue << Then()->rValue; 00160 else 00161 rValue << Else()->rValue; 00162 } 00163 else 00164 { 00165 real* ifv = If()->valuedata; 00166 real* rthenv = Then()->rvaluedata; 00167 real* relsev = Else()->rvaluedata; 00168 for (int k=0;k<nelems();k++) 00169 { 00170 if ( !fast_exact_is_equal(ifv[k], 0) ) 00171 rvaluedata[k]=rthenv[k]; 00172 else 00173 rvaluedata[k]=relsev[k]; 00174 } 00175 } 00176 } 00177 00178 00179 00180 } // end of namespace PLearn 00181 00182 00183 /* 00184 Local Variables: 00185 mode:c++ 00186 c-basic-offset:4 00187 c-file-style:"stroustrup" 00188 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00189 indent-tabs-mode:nil 00190 fill-column:79 00191 End: 00192 */ 00193 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :