[ return ]

funcs.c



/*
 *  File : funcs.c
 *
 * [DEFINE DESCRIPTION = Various functions for NSL]
 *
 *   Andrew H. Fagg
 *   5/10/91
 *
 *    Useful library routines for work in NSL.
 *    Includes :
 *       Random weight generators.
 *       Useful functions on vectors and matrices
 *
 */


#include "nsl_include.h"
#include <stream.h>
#include <math.h>
#include "alib.h"



/*
 * float random_value()
 *
 *  Return = a random number between [-1.0, 1.0].
 *
 */

float random_value()
{
  return(((float)(rand() % 30001)/ 15000.0) - 1.0);
}


/*
 * float random()        //OVERLOAD CALL: random: funcs.c(?), funcs.c(?)
 *
 *  Return = a random number between [0.0, 1.0).
 *
 */

float randomv()
{
  return((float)(rand() % 30000)/ 30000.0);
}


nsl_vector& random(nsl_vector& vec)
{
  int i;
  int j;

  i = vec.get_xn();

  for(j = 0; j < i; ++j)
    vec.elem(j) = (float) drand48();
  return vec;
}

overload nsl_matrix& random(nsl_matrix& mat)
{
  int i;
  int j;

  int xn = mat.get_xn();
  int yn = mat.get_yn();

  for(i = 0; i < xn; ++i)
    for(j = 0; j < yn; ++j)
      mat.elem(i,j) = (float) drand48();
  return mat;
}



/*
 *   nsl_vector square(nsl_vector& a)
 *
 *  Square each element in a vector.
 *
 */

nsl_vector square(nsl_vector& a)
{
  int i;
  int j;

  i = a.get_xn();

  nsl_vector out(i);

  for(j = 0; j < i; ++j)
    {
      out.elem(j) = a.elem(j) * a.elem(j);
    }
  return(out);
}


/*
 *  nsl_vector sqrt(nsl_vector& a)
 *
 *    Take the square-root of each element in a vector.
 *
 */

nsl_vector sqrt(nsl_vector& a)
{
  int i;
  int j;

  i = a.get_xn();

  nsl_vector out(i);

  for(j = 0; j < i; ++j)
    {
      out.elem(j) = sqrt(a.elem(j));
    }
  return(out);
}


/*
 *  nsl_vector abs(nsl_vector& a)
 *
 *   Take the absolute value of each element of a vector.
 */

nsl_vector abs(nsl_vector& a)
{
  int i;
  int len;

  len = a.get_xn();

  nsl_vector out(len);

  for(i = 0; i < len; ++i)
    out.elem(i) = fabs(a.elem(i));
  return(out);
}


/*
 *  nsl_vector apply_func(nsl_vector& a, double (*func)(double))        //OVERLOAD CALL: apply_func: funcs.c(?), funcs.c(?)
 *
 *    Apply a function to each element of a vector.  Returns 
 *  a new vector.
 */

nsl_vector apply_func(nsl_vector& a, double (*func)(double))

{
  int i;
  int len;

  len = a.get_xn();

  nsl_vector out(len);

  for(i = 0; i < len; ++i)
    out.elem(i) = (func)(a.elem(i));
  return(out);
}


/*
 *  nsl_matrix apply_func(nsl_matrix& a, double (*func)(double))        //OVERLOAD CALL: apply_func: funcs.c(?), funcs.c(?)
 *
 *    Apply a function to each element of a matrix.  Returns a
 *  new matrix.
 */

nsl_matrix apply_func(nsl_matrix& a, double (*func)(double))

{
  int i, j;
  int len1;
  int len2;
  
  len1 = a.get_xn();
  len2 = a.get_yn();

  nsl_matrix out(len1, len2);

  for(i = 0; i < len1; ++i)
    for(j = 0; j < len2; ++j)
      out.elem(i,j) = (func)(a.elem(i,j));
  return(out);
}




/*
 *  nsl_vector sigmoid(nsl_vector& vec)
 *
 *   In place, apply the sigmoid function to each element of <vec>.
 *
 *  Return = a pointer to the modified vector.
 *
 */

nsl_vector sigmoid(nsl_vector& vec)

{
  int i;
  int xn;

  xn = vec.get_xn();
  nsl_vector out(xn);

  for(i = 0; i < xn; ++i)
    {
      out.elem(i) = (1.0 / (1.0 + exp(-vec.elem(i))));
    }
  return out;
}


/*
 *  void randomize(nsl_vector& vec)        //OVERLOAD CALL: randomize: funcs.c(?), funcs.c(?)
 *
 *    Set the values of <vec> to random numbers in the range [-1.0, 1.0].
 *
 */

void randomize(nsl_vector& vec)

{
  int i;
  int init;
  int limit;

  init = vec.get_x0();
  limit = vec.get_x1();
  for(i = init; i <= limit; ++i)
    {
      vec.elem(i) = random_value();
    }
}


/*
 *  overload void randomize(nsl_matrix& mat)        //OVERLOAD CALL: randomize: funcs.c(?), funcs.c(?)
 *
 *    Set the values of <mat> to random numbers in the range [-1.0, 1.0].
 *
 */

overload void randomize(nsl_matrix& mat)

{
  int i, j;
  int x0, x1;
  int y0, y1;

  x0 = mat.get_x0();
  x1 = mat.get_x1();
  y0 = mat.get_y0();
  y1 = mat.get_y1();

  for(i = x0; i <= x1; ++i)
    for(j = y0; j <= y1; ++j)
      {
	mat.elem(i,j) = random_value();
      }
}





/*
  * nsl_vector threshlog(nsl_vector& vec, float offset)        //OVERLOAD CALL: threshlog: funcs.c(?), funcs.c(?)
  *
  *  Out(i) = ky1                     if vec(i) < kx1
  *         = ky2 + ln(1+vec(i)-kx1)  otherwise
  *
  */

nsl_vector threshlog(nsl_vector& vec, float kx1, float ky1, float ky2)
{
  int n;
  int i;

  n = vec.get_xn();
  nsl_vector out(n);
  for(i = 0; i < n; ++i)
    {
      if(vec.elem(i) < kx1)
	out.elem(i) = ky1;
      else
	out.elem(i) = log(1.0 + vec.elem(i) - kx1) + ky2;
    }
  return out;
}


/*
  * nsl_data threshlog(nsl_data& dat, float kx1, float ky1, float ky2)        //OVERLOAD CALL: threshlog: funcs.c(?), funcs.c(?)
  *
  *  Same as above.
  *
  */

nsl_data threshlog(nsl_data& dat, float kx1, float ky1, float ky2)
{
  nsl_data out;

  if(dat.elem() < kx1)
    out.elem() = ky1;
  else
    out.elem() = log(1.0 + dat.elem() - kx1) + ky2;
  return out;
}


/*
  * nsl_vector threshlogmax(nsl_vector& vec, float kx1, float ky1, float ky2,        //OVERLOAD CALL: threshlogmax: funcs.c(?), funcs.c(?)
  *             float ky3)
  *
  *  Out(i) = ky1                     if vec(i) < kx1
  *         = ky2 + ln(1+vec(i)-kx1)  if < ky3
  *         = ky3                     otherwise
  *
  */

nsl_vector threshlogmax(nsl_vector& vec, float kx1, float ky1, float ky2,
			float ky3)
{
  int n;
  int i;

  n = vec.get_xn();
  nsl_vector out(n);
  for(i = 0; i < n; ++i)
    {
      if(vec.elem(i) < kx1)
	out.elem(i) = ky1;
      else
	{
	  out.elem(i) = log(1.0 + vec.elem(i) - kx1) + ky2;
	  if(out.elem(i) > ky3)
	    out.elem(i) = ky3;
	}
    }
  return out;
}


/*
  * nsl_data threshlogmax(nsl_data& dat, float kx1, float ky1, float ky2,        //OVERLOAD CALL: threshlogmax: funcs.c(?), funcs.c(?)
  *   float ky3)
  *
  *  Same as above.
  *
  */

nsl_data threshlogmax(nsl_data& dat, float kx1, float ky1, float ky2,
		      float ky3)
{
  nsl_data out;

  if(dat.elem() < kx1)
    out.elem() = ky1;
  else
    {
      out.elem() = log(1.0 + dat.elem() - kx1) + ky2;
      if(out.elem() > ky3)
	out.elem() = ky3;
    }
  return out;
}




/*
  * nsl_vector elevatedSAT(nsl_vector& vec, float kx1, float kx2,         //OVERLOAD CALL: elevatedSAT: funcs.c(?), funcs.c(?)
  *             float ky1, float ky2, float ky3)
  *
  *  Out(i) = ky1                     if vec(i) < kx1
  *         = ky3                     if vec(i) > kx2
  *         = linear interpolation    if in between
  *
  */

nsl_vector elevatedSAT(nsl_vector& vec, float kx1, float kx2, 
			float ky1, float ky2, float ky3)
{
  int n;
  int i;


  if(kx2 == kx1)		/* Check divisor */
    {
      cout << "threshlogmax: kx1 and kx2 must be different.\n";
      exit (1);
    }

  n = vec.get_xn();
  nsl_vector out(n);		/* Create output vector */

  for(i = 0; i < n; ++i)	/* Fill each element */
    {
      if(vec.elem(i) <= kx1)
	out.elem(i) = ky1;
      else
	{
	  if(vec.elem(i) >= kx2)
	    out.elem(i) = ky3;
	  else
	    {
	      out.elem(i) = (vec.elem(i)-kx1)*(ky3-ky2)/(kx2-kx1) + ky2;
	    }
	}
    }
  return out;
}


/*
  * nsl_data elevatedSAT(nsl_data& dat, float kx1, float kx2,         //OVERLOAD CALL: elevatedSAT: funcs.c(?), funcs.c(?)
  *   float ky1, float ky2, float ky3)
  *
  *  Same as above.
  *
  */

nsl_data elevatedSAT(nsl_data& dat, float kx1, float kx2, float ky1, float ky2,
		      float ky3)
{
  if(kx2 == kx1)		/* Check divisor */
    {
      cout << "threshlogmax: kx1 and kx2 must be different.\n";
      exit (1);
    }

  nsl_data out;

  if(dat.elem() <= kx1)
	out.elem() = ky1;
  else
    {
      if(dat.elem() >= kx2)
	out.elem() = ky3;
      else
	{
	  out.elem() = (dat.elem()-kx1)*(ky3-ky2)/(kx2-kx1) + ky2;
	}
    }
  return out;
}





/*
  * nsl_vector threshexp(nsl_vector& vec, float kx1,         //OVERLOAD CALL: threshexp: funcs.c(?), funcs.c(?)
  *             float ky1, float ky2, float gain)
  *
  *  Out(i) = ky1                     if vec(i) <= kx1
  *         = pow(x-kx1,gain)+ky2     otherwise
  *
  */

nsl_vector threshexp(nsl_vector& vec, float kx1, 
			float ky1, float ky2, float gain)
{
  int n;
  int i;

  n = vec.get_xn();
  nsl_vector out(n);		/* Create output vector */

  for(i = 0; i < n; ++i)	/* Fill each element */
    {
      if(vec.elem(i) <= kx1)
	out.elem(i) = ky1;
      else
	{
	  out.elem(i) = pow(vec.elem(i)-kx1, gain) + ky2;
	}
    }
  return out;
}


/*
  * nsl_data threshexp(nsl_data& dat, float kx1,         //OVERLOAD CALL: threshexp: funcs.c(?), funcs.c(?)
  *   float ky1, float ky2, float gain)
  *
  *  Same as above.
  *
  */

nsl_data threshexp(nsl_data& dat, float kx1, float ky1, float ky2,
		      float gain)
{
  nsl_data out;

  if(dat.elem() <= kx1)
	out.elem() = ky1;
  else
    {
      out.elem() = pow(dat.elem()-kx1, gain) + ky2;
    }
  return out;
}




[ return ]