1 module des.isys.neiro.func; 2 3 import std.math; 4 5 import des.isys.neiro.traits; 6 7 interface Function(X,Y) { Y opCall( X x ) const; } 8 9 class HeavisideFunction(X,Y) : Function!(X,Y) 10 if( canComparison!X ) 11 { 12 Y a, b; 13 X lim; 14 15 this( Y a, Y b, X lim ) 16 { 17 this.a = a; 18 this.b = b; 19 this.lim = lim; 20 } 21 22 Y opCall( X x ) const { return x < lim ? a : b; } 23 } 24 25 class HeavisideMeanFunction(X,Y) : HeavisideFunction!(X,Y) 26 if( canFindMean!Y ) 27 { 28 this( Y a, Y b, X lim ) { super(a,b,lim); } 29 override Y opCall( X x ) const 30 { 31 if( x == lim ) return ( a + b ) / 2; 32 return super.opCall(x); 33 } 34 } 35 36 unittest 37 { 38 auto H = new HeavisideFunction!(float,float)(0,1,0); 39 assert( H(0) == 1 ); 40 assert( H(1) == 1 ); 41 assert( H(-1) == 0 ); 42 auto HM = new HeavisideMeanFunction!(float,float)(-1,1,0); 43 assert( HM(0) == 0 ); 44 assert( HM(10) == 1 ); 45 assert( HM(-2) == -1 ); 46 } 47 48 interface DerivativeFunction(T) : Function!(T,T) 49 if( isFloatingPoint!T ) 50 { T dx( T x ) const; } 51 52 class LinearDependence(T) : DerivativeFunction!T 53 if( isFloatingPoint!T ) 54 { 55 T k; 56 this( T k=1 ) { this.k = k; } 57 T opCall( T x ) const { return x * k; } 58 T dx( T x ) const { return k; }; 59 } 60 61 unittest 62 { 63 auto ld = new LinearDependence!float(2); 64 assert( ld(1) == 2 ); 65 assert( ld(2) == 4 ); 66 } 67 68 /+ f -> (0,1) +/ 69 class ExponentialSigmoid(T) : DerivativeFunction!T 70 if( isFloatingPoint!T ) 71 { 72 T alpha; 73 this( T alpha=1.0 ) { this.alpha = alpha; } 74 75 const 76 { 77 T opCall( T x ) 78 { return 1.0 / ( 1.0 + pow( E, -alpha * x ) ); } 79 80 T dx( T x ) 81 { 82 auto eax = pow( E, alpha * x ); 83 return alpha * eax / ( ( eax + 1 )^^2 ); 84 } 85 } 86 } 87 88 unittest 89 { 90 auto fes = new ExponentialSigmoid!float; 91 assert( fes(0) == .5 ); 92 } 93 94 /+ f -> (-1,1) +/ 95 class RationalSigmoid(T) : DerivativeFunction!T 96 if( isFloatingPoint!T ) 97 { 98 T alpha; 99 this( T alpha=1.0 ) { this.alpha = alpha; } 100 101 const 102 { 103 T opCall( T x ) 104 { return x / ( abs(x) + alpha ); } 105 106 T dx( T x ) 107 { 108 auto aax = alpha + abs(x); 109 return alpha / ( ( abs(x) + alpha )^^2 ); 110 } 111 } 112 } 113 114 unittest 115 { 116 auto frs = new RationalSigmoid!float; 117 assert( frs(0) == 0 ); 118 } 119 120 /+ f -> (-pi/2,pi/2) +/ 121 class AtanSigmoid(T) : DerivativeFunction!T 122 if( isFloatingPoint!T ) 123 { 124 const 125 { 126 T opCall( T x ) { return atan(x); } 127 T dx( T x ) { return 1.0 / ( x*x + 1.0 ); } 128 } 129 } 130 131 unittest 132 { 133 auto fas = new AtanSigmoid!float; 134 assert( fas(0) == 0 ); 135 }