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: SoftSlopeIntegralVariable.cc 4204 2005-10-07 19:51:47Z tihocan $ 00040 * This file is part of the PLearn library. 00041 ******************************************************* */ 00042 00043 #include "SoftSlopeIntegralVariable.h" 00044 #include "Var_utils.h" 00045 00046 namespace PLearn { 00047 using namespace std; 00048 00049 00053 PLEARN_IMPLEMENT_OBJECT(SoftSlopeIntegralVariable, 00054 "This Var computes the integral of the soft_slope function in an interval.", 00055 "Compute the integral of soft_slope(x,s,l,r) over x from a to b\n"); 00056 00057 SoftSlopeIntegralVariable::SoftSlopeIntegralVariable() 00058 : a(0), b(0), tabulated(false) 00059 { } 00060 00061 SoftSlopeIntegralVariable:: SoftSlopeIntegralVariable(Variable* smoothness, Variable* left, Variable* right, real a_, real b_, bool tabulated_) 00062 : inherited(VarArray(smoothness) & Var(left) & Var(right), 00063 smoothness->length()<left->length()?left->length():smoothness->length(), 00064 smoothness->width()<left->width()?left->width():smoothness->width()), 00065 a(a_), b(b_), tabulated(tabulated_) 00066 {} 00067 00068 void 00069 SoftSlopeIntegralVariable::declareOptions(OptionList &ol) 00070 { 00071 declareOption(ol, "a", &SoftSlopeIntegralVariable::a, OptionBase::buildoption, ""); 00072 declareOption(ol, "b", &SoftSlopeIntegralVariable::b, OptionBase::buildoption, ""); 00073 declareOption(ol, "tabulated", &SoftSlopeIntegralVariable::tabulated, OptionBase::buildoption, ""); 00074 inherited::declareOptions(ol); 00075 } 00076 00077 void SoftSlopeIntegralVariable::recomputeSize(int& l, int& w) const 00078 { 00079 l=0; 00080 w=0; 00081 if (varray.size() && varray[0] && varray[1] && varray[2]) { 00082 for (int i = 0; i < 3; i++) { 00083 if (varray[i]->length() > l) 00084 l = varray[i]->length(); 00085 if (varray[i]->width() > w) 00086 w = varray[i]->width(); 00087 } 00088 for (int i = 0; i < 3; i++) { 00089 if (varray[i]->length() != l || varray[i]->width() != w) { 00090 if (varray[i]->length() != 1 || varray[i]->width() != 1) 00091 PLERROR("Each argument of SoftSlopeIntegralVariable should either have the same length/width as the others or length 1"); 00092 } 00093 } 00094 } 00095 } 00096 00097 00098 void SoftSlopeIntegralVariable::fprop() 00099 { 00100 int n=nelems(); 00101 int n1=varray[0]->nelems(); 00102 int n2=varray[1]->nelems(); 00103 int n3=varray[2]->nelems(); 00104 real* smoothness = varray[0]->valuedata; 00105 real* left = varray[1]->valuedata; 00106 real* right = varray[2]->valuedata; 00107 00108 if (n1==n && n2==n && n3==n) 00109 for(int i=0; i<n; i++) 00110 valuedata[i] = tabulated?tabulated_soft_slope_integral(smoothness[i], left[i], right[i],a,b):soft_slope_integral(smoothness[i], left[i], right[i],a,b); 00111 else if (n1==1 && n2==n && n3==n) 00112 for(int i=0; i<n; i++) 00113 valuedata[i] = tabulated?tabulated_soft_slope_integral(*smoothness, left[i], right[i],a,b):soft_slope_integral(*smoothness, left[i], right[i],a,b); 00114 else 00115 { 00116 int m1= n1==1?0:1; 00117 int m2= n2==1?0:1; 00118 int m3= n3==1?0:1; 00119 for(int i=0; i<n; i++,smoothness+=m1,left+=m2,right+=m3) 00120 valuedata[i] = tabulated?tabulated_soft_slope_integral(*smoothness, *left, *right, a, b):soft_slope_integral(*smoothness, *left, *right, a, b); 00121 } 00122 } 00123 00124 00125 void SoftSlopeIntegralVariable::bprop() 00126 { 00127 int n=nelems(); 00128 int n1=varray[0]->nelems(); 00129 int n2=varray[1]->nelems(); 00130 int n3=varray[2]->nelems(); 00131 int m1= n1==1?0:1; 00132 int m2= n2==1?0:1; 00133 int m3= n3==1?0:1; 00134 real* smoothness = varray[0]->valuedata; 00135 real* left = varray[1]->valuedata; 00136 real* right = varray[2]->valuedata; 00137 real* dsmoothness = varray[0]->gradientdata; 00138 real* dleft = varray[1]->gradientdata; 00139 real* dright = varray[2]->gradientdata; 00140 for(int i=0; i<n; i++,smoothness+=m1,left+=m2,right+=m3,dsmoothness+=m1,dleft+=m2,dright+=m3) 00141 { 00142 if (fast_exact_is_equal(*smoothness, 0)) continue; 00143 // soft_slope_integral = 00144 // (b - a) + (softplus_primitive(-smoothness*(b-right)) - softplus_primitive(-smoothness*(b-left)) 00145 // -softplus_primitive(-smoothness*(a-right)) + softplus_primitive(-smoothness*(a-left)))/ 00146 // (smoothness*smoothness*(right-left)); 00147 // hence 00148 // 00149 // d/dsmoothness = (softplus(-smoothness*(b-right))*(right-b) + softplus(-smoothness*(b-left))*(b-left) 00150 // + softplus(-smoothness*(a-right))*(a-right) + softplus(-smoothness*(a-left))*(left-a))/ 00151 // (smoothness*smoothness*(right-left)) 00152 // - 2 * (soft_slope_integral - b + a) / smoothness 00153 //n 00154 // d/dleft = (-softplus(-smoothness*(b-left)) + softplus(-smoothness*(a-left)))/ 00155 // (smoothness*(right-left)) 00156 // + (soft_slope_integral - b + a)/ (right-left) 00157 // 00158 // d/dright = (softplus(-smoothness*(b-right)) - softplus(-smoothness*(a-right)))/(smoothness*(right-left)) 00159 // - (soft_slope_integral - b + a)/ (right-left) 00160 // 00161 real inv_smoothness = 1.0 / *smoothness; 00162 real br = (b-*right); 00163 real bl = (b-*left); 00164 real ar = (a-*right); 00165 real al = (a-*left); 00166 real t1 = tabulated?tabulated_softplus(- *smoothness*br):softplus(- *smoothness*br); 00167 real t2 = tabulated?tabulated_softplus(- *smoothness*bl):softplus(- *smoothness*bl); 00168 real t3 = tabulated?tabulated_softplus(- *smoothness*ar):softplus(- *smoothness*ar); 00169 real t4 = tabulated?tabulated_softplus(- *smoothness*al):softplus(- *smoothness*al); 00170 real inv_delta=1.0/(*right-*left); 00171 real ssiab = valuedata[i]-b+a; 00172 *dsmoothness += gradientdata[i] * 00173 ((-t1*br + t2*bl + t3*ar - t4*al)*inv_smoothness*inv_delta - 2*ssiab)*inv_smoothness; 00174 *dleft += gradientdata[i] * ((-t2 + t4)*inv_smoothness + ssiab) * inv_delta; 00175 *dright += gradientdata[i] * ((t1 - t3)*inv_smoothness - ssiab) * inv_delta; 00176 } 00177 } 00178 00179 void SoftSlopeIntegralVariable::symbolicBprop() 00180 { 00181 PLERROR("SoftSlopeIntegralVariable::symbolicBprop() not implemented"); 00182 } 00183 00184 00185 00186 } // end of namespace PLearn 00187 00188 00189 /* 00190 Local Variables: 00191 mode:c++ 00192 c-basic-offset:4 00193 c-file-style:"stroustrup" 00194 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00195 indent-tabs-mode:nil 00196 fill-column:79 00197 End: 00198 */ 00199 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :