10a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim/* Copyright (c) 2008-2011 Octasic Inc.
20a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   Written by Jean-Marc Valin */
30a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim/*
40a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   Redistribution and use in source and binary forms, with or without
50a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   modification, are permitted provided that the following conditions
60a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   are met:
70a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim
80a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   - Redistributions of source code must retain the above copyright
90a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   notice, this list of conditions and the following disclaimer.
100a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim
110a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   - Redistributions in binary form must reproduce the above copyright
120a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   notice, this list of conditions and the following disclaimer in the
130a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   documentation and/or other materials provided with the distribution.
140a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim
150a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
160a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
170a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
180a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
190a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
200a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
210a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
220a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
230a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
240a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
250a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
260a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim*/
270a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim
280a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim#ifndef _MLP_TRAIN_H_
290a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim#define _MLP_TRAIN_H_
300a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim
310a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim#include <math.h>
320a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim#include <stdlib.h>
330a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim
340a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Limdouble tansig_table[501];
350a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Limstatic inline double tansig_double(double x)
360a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim{
370a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim    return 2./(1.+exp(-2.*x)) - 1.;
380a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim}
390c2090c324e4f2ba2a8621c8b083559bab74c7c5Felicia Limstatic inline void build_tansig_table(void)
400a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim{
410a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim    int i;
420a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim    for (i=0;i<501;i++)
430a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim        tansig_table[i] = tansig_double(.04*(i-250));
440a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim}
450a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim
460a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Limstatic inline double tansig_approx(double x)
470a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim{
480a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim    int i;
490a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim    double y, dy;
500a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim    if (x>=10)
510a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim        return 1;
520a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim    if (x<=-10)
530a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim        return -1;
540a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim    i = lrint(25*x);
550a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim    x -= .04*i;
560a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim    y = tansig_table[250+i];
570a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim    dy = 1-y*y;
580a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim    y = y + x*dy*(1 - y*x);
590a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim    return y;
600a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim}
610a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim
620c2090c324e4f2ba2a8621c8b083559bab74c7c5Felicia Limstatic inline float randn(float sd)
630a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim{
640a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   float U1, U2, S, x;
650a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   do {
660a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim      U1 = ((float)rand())/RAND_MAX;
670a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim      U2 = ((float)rand())/RAND_MAX;
680a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim      U1 = 2*U1-1;
690a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim      U2 = 2*U2-1;
700a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim      S = U1*U1 + U2*U2;
710a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   } while (S >= 1 || S == 0.0f);
720a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   x = sd*sqrt(-2 * log(S) / S) * U1;
730a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim   return x;
740a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim}
750a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim
760a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim
770a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Limtypedef struct {
780a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim    int layers;
790a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim    int *topo;
800a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim    double **weights;
810a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim    double **best_weights;
820a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim    double *in_rate;
830a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim} MLPTrain;
840a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim
850a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim
860a1406acbe87c63044e9da7e0ab41bcbfa704f3dFelicia Lim#endif /* _MLP_TRAIN_H_ */
87