Subject: spiral-user-init-1

From: [email-masked]
Date: Mon, 21 Dec 98 17:22:44 EST

/*--------------------------last modified in 11/2/1992---------*/
#include "spiral.h"

#include <stdio.h>
#include <stdlib.h>
#include <math.h> 

#define fac_2 2
#define fac_3 6
#define fac_4 24
#define fac_5 120
#define fac_6 720
#define fac_7 5040

extern double sqrt(), log(), log10();

/***--- These 2 are the original functions that works on
        a range of [-0.5,+0.5]        ---***/

/***--- float Sigmoid(float x) 
        {
	  return ( (1.0 / (1.0 + AM_EXP((double)-x))) - 0.5);
	}

        float SigmoidPrime(float x)
	{
	x = Sigmoid(x);
	return ( 0.25 - (x * x));
	}
---***/

/*---------------------------------------------------*/
/* The function considered here is tanh()            */
/*---------------------------------------------------*/

float Sigmoid(float x)               /*  [-1.0,1.0]  */
{
  return(tanh((double) x)); 

/*--or-- return ( (2.0 / (1.0 + AM_EXP((double)-x))) - 1.0); -----*/
}

float SigmoidPrime(float x)
{
  x = Sigmoid(x);
  return(1.0 - (x * x));
}

float TaylorSeries(float x)
{
  return((float)(x + (x*x*x)/fac_3 + (x*x*x*x*x)/fac_5 + 
		 (x*x*x*x*x*x*x)/fac_7)               
	 /(1.0 + (x*x)/fac_2 + (x*x*x*x)/fac_4 + (x*x*x*x*x*x)/fac_6)); 
}

/*-------------------------------------------------------------------------*/
#define alpha 1                         /*  alpha = k                      */
#define x_0  (1.0/2.0)                  /*  = k/(1+k)                      */
#define top ((1.0 - x_0) * x_0)         /*  =(1 - x_0) x_0^k         */
/*-------------------------------------------------------------------------*/
/*-----------------------------------------------------------*/
/* The following is a piecewise-rational function:           */
/*                                (due to me and Sibert)     */
/* f(x) = 1.0 - ((1-x_0) x_0^k)/ x^k                         */
/* alpha = k = 1,2,...                                       */
/*-----------------------------------------------------------*/

float absol(float value)
{
  if (value < 0.0)
    return(-1.0 * value);
  else
    return(value);
}

float Pwrfunc(float x)
{
  float func;
  if (x == 0)
    return 0.0;
  if (x <= x_0 && x >= -x_0)      
    return (x);
  if (absol(x) > x_0)
    {
      func = 1.0 - (top / absol(x));
      if (x > x_0)               
	return (func);
      else
	{
	  if (x < -x_0)       
	    return (-func);
	}
    }
}

/*----------------------------------------------------------- */
/* The 1st derivative is:
/* f'(x) = k((1 - x_0)x_0^k)/ x^(k+1)                         */
/* where k=1,2,... and x_0 = k/(1+k)                          */
/*----------------------------------------------------------- */

float PwrPrimefunc(float x)
{
  if (x == 0.0)
    return 0.0;
  if (x <= x_0 && x >= -x_0)      
    return (1.0);
  return(top / absol(x * x));     /*.......... for k=1 ........ */
}

/*=======================================*/
/* Another piecewise-rational function takes on the following
   form  g(x) = x / (1 + |x|) .  Dave Elliott's .
-----------------------------------------*/

float PWR_2(float x)
{
  return(x / (1.0 + absol(x)));
}

/*---------------------------------------*/
/* The above function is differentiable everywhere with
   a derivative:
         g'(x) = 1 / (1+ |x|)^2 .
-----------------------------------------*/

float PWR_2_prime(float x)
{
  return(1.0 / ((1.0 + absol(x)) * (1.0 + absol(x))));
}

/*=================================================================*/
/*     The following 2 functions uses Taylor Series to approximate */
/*           Tanh(x) and Tanh'(x) , f(x)                           */
/*-----------------------------------------------------------------*/

float SigmoidApprox(float x)
{
  float temp_var=0.0, func;

  temp_var = ((float)(x + (x*x*x)/fac_3 + (x*x*x*x*x)/fac_5 + 
		      (x*x*x*x*x*x*x)/fac_7)               
	      /(1.0 + (x*x)/fac_2 + (x*x*x*x)/fac_4 + (x*x*x*x*x*x)/fac_6));
/***------------------------------------------------------***/
/*** Testing at the far end edges of the function ....... ***/
/***         (Optional)                                   ***/
/***------------------------------------------------------***/
  if (temp_var >= 0.97 || temp_var <= -0.97)         
    {                                                
      func = 1.0 - (top / x * x);          
      if (x >= 0.0)                                  
	return (func);                               
      else                                           
	return (-func);                              
    }                                                
  else                                               
    return(temp_var);
}

/*------f'(x)-------------------------------------*/

float SigmoidApproxPrime(float x)
{
  x = SigmoidApprox (x);
  return(1.0 - (x * x));
}

float signum(float x)
{
  if (x > 0.0)
    return 1.0;
  else
    {
      if (x < 0.0)
	return -1.0;
      else
	{
	  if (x == 0)
	    return 0.0;
	}
    }
} 

float LinearAND(float x)
{
 return (log(absol(x) + 1.0) * signum(x));
}

float LinearANDprime(float x)
{
  return ((1.0 /(absol(x) + 1.0)) * signum(x));
}

/*==================================================================*/

float L2Error (float *target, float *output, float *credit, int n)
{
  float mag_squared = 0.0;
  int i;

  for(i=0;i<n;i++) {
    credit[i] = target[i] - output[i];
    mag_squared += credit[i] * credit[i];
  }/* end for */

  return( mag_squared / 2.0 );
}

float L1Error (float *target, float *output, float *credit, int n)
{
  float mag = 0.0;
  int i;

  for(i=0;i<n;i++) {
    float val, diff;

    diff = target[i] - output[i] ;

    if (diff == 0.0)
      val = 0.0 ;
    else
      val = ( diff < 0.0 ) ? -1.0 : 1.0 ;

    credit[i] = val;
    mag += AM_FABS(diff);
  }/* end for */

  return( mag );
}

/*
**----------------------------------------------------------------------
**
**  Asymmetric thresholded squared error
**
**----------------------------------------------------------------------
*/

#define DELTA 0.150

#define GI 1.384   /* Credit multiplier for an Inhibited node */
#define GA 1.384   /* Credit multiplier for an Active node */

#define GIdb2 0.692
#define GAdb2 0.692

float asymmError(float *target, float *output, float *credit, int nx)
{
  float e;
  double t, total_error = 0.0;
  unsigned int k;
  
  for (k=0; k<nx; ++k) {
    
    e = output[k] - target[k];    
    
    if ( e < -DELTA ) {
      t = e + DELTA;
      credit[k] = -GA * t;
      total_error += GAdb2*t*t;
    } else if ( e <= DELTA )
      credit[k] = 0.0;
    else {
      t = e - DELTA;
      credit[k] = -GI * t;
      total_error += GIdb2*t*t;
    }
    
  }
  
  return( total_error );
}

void user_init()
{
  spiral_set_random_init_range(0.5);

  spiral_set_learning_rate(0.1); 
}