📄 art_int.c
字号:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "art_def.h"
/**
* \fn float FuzzUni(float x, float y)
* \brief Returns the fuzzy union between two numbers [0,1]
* \param x one parameter
* \param y one parameter
* \return the big one
*/
float FuzzUni(float x, float y)
{
if (x>y)
{
return x;
}
else
{
return y;
}
}
/**
* \fn float FuzzInt(float x, float y)
* \brief Returns the fuzzy intersection between two numbers [0,1]
* \param x one parameter
* \param y one parameter
* \return the small one
*/
float FuzzInt(float x, float y)
{
if (x>y)
{
return y;
}
else
{
return x;
}
}
/**
* \fn float Intersect(float x, float y, int type)
* \brief return intersection
* \param x x input
* \param y y input
* \param type the network type
* \result the intersection value
*/
float Intersect(float x, float y, int type)
{
if ((type == ART_TYPE_ART1)||(type == ART_TYPE_NONE))
{
return x * y;
}
else
{
if (x > y)
{
return y;
}
else
{
return x;
}
}
}
/**
* \fn void ActivateArt(artPTR art, float *input)
* \brief Activate the ART
* Given a pointer to an art module, and a pointer to a input
* vector, calculates and sets current category activations and
* winning current winnning category number.
* \param art the ART network pointer
* \param input the input value
*/
void ActivateArt(artPTR art, float *input)
{
float sum_inputs; /**< Sum of all the input patterns */
float max_cat; /**< Largest category activation */
int win_cat; /**< Category which wins the competition */
int matchB; /**< Boolean to indicate when a match is found */
int num_elig; /**< Number of eligible nodes left */
int i,j; /**< Counters */
/**< --------------------- Check Type of Art Module ----------------------- */
if (art->type == ART_TYPE_NONE)
{
/**< If none, then category activation is just the input string ---- */
for (i = 0; i < art->num_inputs; i++)
{
*(art->cat + i) = (*(input + i));
}
return;
}
/**< Check if there are any used nodes */
else if (art->nodes_used == 0)
{
art->win_cat = -1;
return;
}
else
{
/**< ------- If art module, calculate output category activations ------- */
/**< Initially all nodes are eligible to win the competition */
num_elig = art->nodes_used;
for (i = 0; i < art->nodes_used; i++)
{
*(art->elig+i)=TRUE;
}
/**< Activate categories */
for (i = 0; i < art->nodes_used; i++)
{
*(art->sum_IW + i) = 0;
for (j = 0; j < art->num_inputs; j++)
{
/**< NOTE: Intersection depends in art type. (Fuzzy or Art1) */
*(art->sum_IW + i) += Intersect((*(*(art->weight + i) + j)), (*(input + j)), art->type);
}
*(art->cat + i) = (*(art->elig + i)) * ((*(art->sum_IW + i)) / ((float)(ALPHA) + (*(art->sum_weights + i))));
}
matchB = FALSE;
while (!matchB)
{
/**< Find most activated category */
max_cat = 0;
win_cat = 0;
for (i = 0; i < art->nodes_used; i++)
{
if (((*(art->cat + i)) > max_cat)&&((*(art->elig + i)) != 0))
{
max_cat = (*(art->cat + i));
win_cat = i;
}
}
/**< Find the sum of the inputs */
/**< When compliment coded, sum of inputs equal to half network inputs. */
if (art->style == ART_STYLE_COMPLIMENT)
{
sum_inputs = (art->num_inputs) / 2.0f;
}
else
{
sum_inputs = 0;
for (i = 0; i < art->num_inputs; i++)
{
sum_inputs += (*(input + i));
}
}
/**< Test to see if winning category meets vigilence level */
if (((*(art->sum_IW + win_cat)) / sum_inputs) >= art->vigil)
{
/**< If so, found a match */
matchB = TRUE;
/**< Set winner-take-all category activations */
for (i = 0; i < art->nodes_used; i++)
{
if (i == win_cat)
{
*(art->cat + i) = 1;
}
else
{
*(art->cat + i) = 0;
}
}
art->win_cat = win_cat;
}
else
{
/**< Otherwise, node becomes ineligible */
*(art->elig + win_cat) = FALSE;
art->num_reset++;
num_elig--;
/**< Check if any nodes still eligible */
if (num_elig == 0)
{
/* Return that no match found */
art->win_cat = -1;
return;
}
}
}
}
}
/**
* \fn int AddCats(artPTR art,int new_nodes)
* \brief Add category nodes.
* Allocates space for more category nodes and sets initial
* values for reallocted space.
* \param art ART network structure.
* \param new_nodes new category nodes.
* \retval 0 Successful
* \retval 1 Out of memory
* \note When using ARTMAP, AddMaps must be called following a
* a call to AddCats, to update mapfield size.
*/
int AddCats(artPTR art,int new_nodes)
{
int i,j;
int *tempvint; /**< Temporary pointer for copying */
float *tempvflt; /**< Temporary pointer for copying */
float **tempflt; /**< Temporary pointer for copying */
tempvflt = (float *)malloc((size_t)((art->max_nodes + new_nodes) * sizeof(float)));
if (tempvflt == NULL)
{
return 1;
}
for (i = 0; i < art->max_nodes; i++)
{
*(tempvflt + i) = *(art->cat + i);
}
free(art->cat);
art->cat = tempvflt;
tempvflt = (float *)malloc((size_t)((art->max_nodes + new_nodes) * sizeof(float)));
if (tempvflt == NULL)
{
return 1;
}
for (i = 0; i < art->max_nodes; i++)
{
*(tempvflt + i) = *(art->elig + i);
}
free(art->elig);
art->elig = tempvflt;
tempvint = (int *)malloc((size_t)((art->max_nodes + new_nodes) * sizeof(int)));
if (tempvint == NULL)
{
return 1;
}
for (i = 0; i < art->max_nodes; i++)
{
*(tempvint + i) = *(art->commit + i);
}
free(art->commit);
art->commit = tempvint;
tempflt = (float **)malloc((size_t)(((art->max_nodes + new_nodes)) * sizeof(float*)));
if (tempflt == NULL)
{
return 1;
}
tempflt[0] = (float *)malloc((size_t)(((art->max_nodes + new_nodes) * art->num_inputs) * sizeof(float)));
if (tempflt[0] == NULL)
{
free(tempflt);
return 1;
}
for(i = 1; i < (art->max_nodes + new_nodes); i++)
{
tempflt[i] = tempflt[i - 1] + art->num_inputs;
}
for (i = 0; i < art->max_nodes; i++)
{
for (j = 0; j < art->num_inputs; j++)
{
*(*(tempflt + i) + j) = *(*(art->weight + i) + j);
}
}
free(art->weight[0]);
free(art->weight);
art->weight = tempflt;
tempvflt = (float *)malloc((size_t)((art->max_nodes + new_nodes) * sizeof(float)));
if (tempvflt == NULL)
{
return 1;
}
for (i = 0; i < art->max_nodes; i++)
{
*(tempvflt + i) = *(art->sum_weights + i);
}
free(art->sum_weights);
art->sum_weights = tempvflt;
tempvflt = (float *)malloc((size_t)((art->max_nodes + new_nodes) * sizeof(float)));
if (tempvflt == NULL)
{
return 1;
}
for (i = 0; i < art->max_nodes; i++)
{
*(tempvflt + i) = *(art->sum_IW + i);
}
free(art->sum_IW);
art->sum_IW = tempvflt;
/**
* Set Initial Weight Values for new weights
*/
for (i = art->max_nodes; i < (art->max_nodes + new_nodes); i++)
{
for (j = 0; j < art->num_inputs; j++)
{
*(*(art->weight + i) + j) = 1;
}
}
/**
* Set Initial Commitments of new nodes to false
*/
for (i = art->max_nodes; i < (art->max_nodes + new_nodes); i++)
{
*(art->commit + i) = FALSE;
}
/**
* Calculate initial weight sums for new nodes
*/
for (i = art->max_nodes; i < (art->max_nodes + new_nodes); i++)
{
*(art->sum_weights + i) = 0;
for (j = 0; j < art->num_inputs; j++)
{
*(art->sum_weights + i) += (*(*(art->weight + i) + j));
}
}
/**
* Update number of available nodes
*/
art->max_nodes = art->max_nodes + new_nodes;
return 0;
}
/**
* \fn int TrainArtPat(artPTR art, float *input)
* \brief Train the network
* Given a pointer to an activated network, and a pointer to an
* input pattern, trains the Art module based on the current
* winning node and the input pattern.
* \param art the pointer of the art network
* \param input the input value
* \retval 0 Successful
* \retval 1 Out of memory
*/
int TrainArtPat(artPTR art, float *input)
{
int i; /**< Counter */
/**< ------- Train Art Module with Fast Learning and Slow Recode --------- */
/**< NOTE: Slow recode is eliminated if beta is set to one. */
/**< When there was no winning category */
if (art->win_cat == -1)
{
art->win_cat = art->nodes_used; /**< Winner becomes next unused node */
art->nodes_used++; /**< Increment used nodes counter */
/**< If hit the max number of allocated Art nodes */
/**< Allocate more space for Art nodes */
if (art->nodes_used == art->max_nodes)
{
if (AddCats(art, 25))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -