/* * 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; }