00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
#include "SoftSlopeVariable.h"
00044
00045
00046
namespace PLearn {
00047
using namespace std;
00048
00049
00053
PLEARN_IMPLEMENT_OBJECT(SoftSlopeVariable,
00054
"This Var computes the soft_slope function",
00055
"The soft_slope function is a soft version of linear by parts function.\n"
00056
"(as smoothness goes to infty). More precisely it converges to a function that is\n"
00057
"0 in [-infty,left], linear in [left,right], and 1 in [right,infty], and continuous\n"
00058
"It is always monotonically increasing wrt x (positive derivative in x).\n"
00059
"If the arguments are vectors than the operation is performed element by element on all of them.\n");
00060
00061 SoftSlopeVariable:: SoftSlopeVariable(
Variable* x,
Variable* smoothness,
Variable* left,
Variable* right,
bool tabulated_)
00062 :
inherited(
VarArray(
x,smoothness) &
Var(
left) &
Var(
right),
00063
x->length()<
left->length()?
left->length():
x->length(),
00064
x->width()<
left->width()?
left->width():
x->width()), tabulated(tabulated_)
00065 {}
00066
00067
void
00068 SoftSlopeVariable::declareOptions(
OptionList &ol)
00069 {
00070
declareOption(ol,
"tabulated", &SoftSlopeVariable::tabulated, OptionBase::buildoption,
"");
00071 inherited::declareOptions(ol);
00072 }
00073
00074 void SoftSlopeVariable::recomputeSize(
int& l,
int& w)
const
00075
{
00076 l = 0;
00077 w = 0;
00078
if (varray.
size() == 4 && varray[0] && varray[1] && varray[2] && varray[3]) {
00079
for (
int i = 0; i < 4; i++) {
00080
if (varray[i]->length() > l)
00081 l = varray[i]->length();
00082
if (varray[i]->width() > w)
00083 w = varray[i]->width();
00084 }
00085
for (
int i = 0; i < 4; i++) {
00086
if (varray[i]->length() != l || varray[i]->width() != w) {
00087
if (varray[i]->length() != 1 || varray[i]->width() != 1)
00088
PLERROR(
"Each argument of SoftSlopeVariable should either have the same length/width as the others or length 1");
00089 }
00090 }
00091 }
00092 }
00093
00094
00095 void SoftSlopeVariable::fprop()
00096 {
00097
int n=
nelems();
00098
int n1=varray[0]->
nelems();
00099
int n2=varray[1]->nelems();
00100
int n3=varray[2]->nelems();
00101
int n4=varray[3]->nelems();
00102
real*
x = varray[0]->valuedata;
00103
real* smoothness = varray[1]->valuedata;
00104
real*
left = varray[2]->valuedata;
00105
real*
right = varray[3]->valuedata;
00106
00107
if (n1==n && n2==n && n3==n && n4==n)
00108
for(
int i=0; i<n; i++)
00109 valuedata[i] =
tabulated?
tabulated_soft_slope(
x[i], smoothness[i],
left[i],
right[i]):
soft_slope(
x[i], smoothness[i],
left[i],
right[i]);
00110
else if (n1==1 && n2==n && n3==n && n4==n)
00111
for(
int i=0; i<n; i++)
00112 valuedata[i] =
tabulated?
tabulated_soft_slope(*
x, smoothness[i],
left[i],
right[i]):
soft_slope(*
x, smoothness[i],
left[i],
right[i]);
00113
else
00114 {
00115
int m1= n1==1?0:1;
00116
int m2= n2==1?0:1;
00117
int m3= n3==1?0:1;
00118
int m4= n4==1?0:1;
00119
for(
int i=0; i<n; i++,
x+=m1,smoothness+=m2,
left+=m3,
right+=m4)
00120 valuedata[i] =
tabulated?
tabulated_soft_slope(*
x, *smoothness, *
left, *
right):
soft_slope(*
x, *smoothness, *
left, *
right);
00121 }
00122 }
00123
00124
00125 void SoftSlopeVariable::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 n4=varray[3]->nelems();
00132
int m1= n1==1?0:1;
00133
int m2= n2==1?0:1;
00134
int m3= n3==1?0:1;
00135
int m4= n4==1?0:1;
00136
real*
x = varray[0]->valuedata;
00137
real* smoothness = varray[1]->valuedata;
00138
real*
left = varray[2]->valuedata;
00139
real*
right = varray[3]->valuedata;
00140
real* dx = varray[0]->gradientdata;
00141
real* dsmoothness = varray[1]->gradientdata;
00142
real* dleft = varray[2]->gradientdata;
00143
real* dright = varray[3]->gradientdata;
00144
for(
int i=0; i<n; i++,
x+=m1,smoothness+=m2,
left+=m3,
right+=m4,dx+=m1,dsmoothness+=m2,dleft+=m3,dright+=m4)
00145 {
00146
if (*smoothness == 0)
continue;
00147
real inv_smoothness = 1.0 / *smoothness;
00148
real t1 =
sigmoid(- *smoothness*(*
x-*
left));
00149
real t2 =
sigmoid(- *smoothness*(*
x-*
right));
00150
real inv_delta=1.0/(*
right-*
left);
00151
real rat = (
tabulated?
tabulated_soft_slope(*
x, *smoothness, *
left, *
right):
soft_slope(*
x, *smoothness, *
left, *
right)) -1;
00152
real move = rat * inv_delta;
00153
real dss = (-t1*(*
x-*
left) + t2*(*
x-*
right))*inv_smoothness*inv_delta - rat * inv_smoothness;
00154
real dll = t1*inv_delta*inv_smoothness + move;
00155
real drr = -t2*inv_delta*inv_smoothness - move;
00156
real dxx = (-t1+t2)*inv_delta;
00157 *dx += gradientdata[i] * dxx;
00158 *dsmoothness += gradientdata[i] * dss;
00159 *dleft += gradientdata[i] * dll;
00160 *dright += gradientdata[i] * drr;
00161 }
00162 }
00163
00164 void SoftSlopeVariable::symbolicBprop()
00165 {
00166
PLERROR(
"SoftSlopeVariable::symbolicBprop() not implemented");
00167 }
00168
00169
00170
00171 }
00172
00173