bpro.c 3.6 KB
Newer Older
Emmanuel Bertin's avatar
Emmanuel Bertin committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
 				bpro.c

*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
*	Part of:	Any back-propagation-ANN-oriented software
*
*	Author:		E.BERTIN (IAP)
*
*	Contents:	Routines for BP-neural network management ("read-only"
*			mode).
*
*	Requirements:	The LDACTools.
*
*	Last modify:	13/12/2002
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/

#ifdef HAVE_CONFIG_H
#include        "config.h"
#endif

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

#include	"define.h"
#include	"globals.h"
#include	"fits/fitscat.h"
#include	"bpro.h"

/******************************** play_bpann *********************************/
/*
Single forward pass through the ANN.
*/
void	play_bpann(bpannstruct *bpann, NFLOAT *invec, NFLOAT *outvec)
  {
   NFLOAT	u, *neuroni,*neuronj, *weight;
   int		i,j,l,lp,ll, lflag;

  ll = bpann->nlayers-1;
  memcpy(bpann->neuron[0], invec, bpann->nn[0]*sizeof(float));
  lflag = bpann->linearoutflag;
  for (lp=0,l=1; lp<ll; l++, lp++)
    {
    neuronj = bpann->neuron[l];
    weight = bpann->weight[lp];
    for (j=bpann->nn[l]; j--; neuronj++)
      {	/* note we don't touch the "bias" neuron (=-1) */
      neuroni = bpann->neuron[lp];
      u = *(weight++)**(neuroni++);
      for (i=bpann->nn[lp]; i--;)	/* The last one is the bias */
        u += *(weight++)**(neuroni++);
      if (l == ll)
        *(outvec++)= lflag?u:SIGMOID(u);
      else
        *neuronj = SIGMOID(u);
      }
    }

  return;
  }


/******************************* loadtab_bpann *******************************/
/*
Load the relevant ANN structure (using the LDACTools).
*/
bpannstruct	*loadtab_bpann(tabstruct *tab, char *filename)
  {
   bpannstruct	*bpann;
   keystruct	*key;
   char		*head, str[80];
   int		l;

/* OK, we now allocate memory for the ANN structure itself */
  QCALLOC(bpann, bpannstruct, 1);
/* Load important scalars (which are stored as FITS keywords) */
  head = tab->headbuf;
  if (fitsread(head, "BPNLAYER", &bpann->nlayers, H_INT, T_LONG) != RETURN_OK)
    error(EXIT_FAILURE, "*Error*: incorrect BP-ANN header in ", filename);
  if (fitsread(head, "BPLINEAR",&bpann->linearoutflag, H_INT,T_LONG)!=RETURN_OK)
    bpann->linearoutflag = 0;
/* Load all vectors!! */
  read_keys(tab, NULL, NULL, 0, NULL);
/* Now interpret the result */
  if (!(key = name_to_key(tab, "NNEUR_PER_LAYER")))
    error(EXIT_FAILURE, "*Error*: incorrect BP-ANN header in ", filename);
  bpann->nn = key->ptr; key->ptr = 0;
  QMALLOC(bpann->neuron, NFLOAT *, bpann->nlayers);
  QMALLOC(bpann->weight, NFLOAT *, bpann->nlayers-1);
  for (l=0; l<bpann->nlayers-1; l++)
    {
    QMALLOC(bpann->neuron[l], NFLOAT, bpann->nn[l]+1);
    bpann->neuron[l][bpann->nn[l]] = -1.0;
    sprintf(str, "WEIGHT_LAYER%d", l+1);
    if (!(key = name_to_key(tab, str)))
      error(EXIT_FAILURE, "*Error*: incorrect BP-ANN header in ", filename);
    bpann->weight[l] = key->ptr; key->ptr = 0;
    }

  QMALLOC(bpann->neuron[l], NFLOAT, bpann->nn[l]); /* no bias in this layer */

  return bpann;
  }


/******************************** free_bpann *********************************/
/*
Free all memory modules allocated for a Back-Propagation ANN structure.*/
void    free_bpann(bpannstruct *bpann)

  {
   int          i;

/* Loop over the "true" layers */
  for (i=0; i<bpann->nlayers-1; i++)
    {
    free(bpann->neuron[i]);
    free(bpann->weight[i]);
    }

  free(bpann->neuron[i]);       /* Because of the input layer */

/* Then free pointers of pointers */
  free(bpann->neuron);
  free(bpann->weight);
  free(bpann->nn);

/* And finally free the ANN structure itself */
  free(bpann);

  return;
  }