1e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org/* Copyright (c) 2008-2011 Octasic Inc.
2e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   Written by Jean-Marc Valin */
3e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org/*
4e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   Redistribution and use in source and binary forms, with or without
5e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   modification, are permitted provided that the following conditions
6e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   are met:
7e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
8e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   - Redistributions of source code must retain the above copyright
9e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   notice, this list of conditions and the following disclaimer.
10e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
11e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   - Redistributions in binary form must reproduce the above copyright
12e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   notice, this list of conditions and the following disclaimer in the
13e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   documentation and/or other materials provided with the distribution.
14e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
15e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
19e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org*/
27e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
28e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifndef _MLP_TRAIN_H_
29e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#define _MLP_TRAIN_H_
30e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
31e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include <math.h>
32e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include <stdlib.h>
33e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
34e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgdouble tansig_table[501];
35e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic inline double tansig_double(double x)
36e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{
37e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org	return 2./(1.+exp(-2.*x)) - 1.;
38e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org}
39e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic inline void build_tansig_table()
40e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{
41e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org	int i;
42e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org	for (i=0;i<501;i++)
43e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org		tansig_table[i] = tansig_double(.04*(i-250));
44e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org}
45e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
46e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic inline double tansig_approx(double x)
47e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{
48e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org	int i;
49e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org	double y, dy;
50e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org	if (x>=10)
51e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org		return 1;
52e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org	if (x<=-10)
53e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org		return -1;
54e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org	i = lrint(25*x);
55e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org	x -= .04*i;
56e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org	y = tansig_table[250+i];
57e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org	dy = 1-y*y;
58e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org	y = y + x*dy*(1 - y*x);
59e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org	return y;
60e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org}
61e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
62e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orginline float randn(float sd)
63e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{
64e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   float U1, U2, S, x;
65e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   do {
66e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      U1 = ((float)rand())/RAND_MAX;
67e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      U2 = ((float)rand())/RAND_MAX;
68e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      U1 = 2*U1-1;
69e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      U2 = 2*U2-1;
70e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      S = U1*U1 + U2*U2;
71e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   } while (S >= 1 || S == 0.0f);
72e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   x = sd*sqrt(-2 * log(S) / S) * U1;
73e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   return x;
74e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org}
75e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
76e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
77e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgtypedef struct {
78e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org	int layers;
79e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org	int *topo;
80e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org	double **weights;
81e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org	double **best_weights;
82e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org	double *in_rate;
83e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} MLPTrain;
84e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
85e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
86e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif /* _MLP_TRAIN_H_ */
87