📄 art_int.c
字号:
return 1;
}
}
*(art->commit + art->nodes_used) = TRUE; /* Note it as now used */
/**< Set winner-take-all category activations */
for (i = 0; i < art->nodes_used; i++)
{
if (i == art->win_cat)
{
*(art->cat + i) = 1;
}
else
{
*(art->cat + i) = 0;
}
}
/**< Fast learning for uncommited node. (beta = 1) */
for (i = 0; i < art->num_inputs; i++)
{
*(*(art->weight + art->win_cat) + i) = Intersect((*(input + i)), (*(*(art->weight + art->win_cat) + i)), art->type);
}
}
else
{
/**< Slow Recoding for commited node. (beta < 1) */
for (i = 0; i < art->num_inputs; i++)
{
*(*(art->weight + art->win_cat) + i) = ((art->beta) * Intersect((*(input + i)), (*(*(art->weight+art->win_cat) + i)), art->type)) + ((1 - (art->beta)) * (*(*(art->weight + art->win_cat) + i)));
}
}
/**< Calculate Art weight sum for speeding up later calculations */
*(art->sum_weights + art->win_cat) = 0;
for (i = 0; i < art->num_inputs; i++)
{
*(art->sum_weights + art->win_cat) += (*(*(art->weight + art->win_cat)+i));
}
return 0;
}
/**
* \fn int AddMaps(mapPTR map)
* \brief Add map to ARTMAP network
* When using ARTMAP, this procedure needs to be called everytime
* either the Art-A or Art-B networks change size (see AddCats).
* Allocates space for more mapfield nodes based on the new sizes
* of the Art-A and Art-B networks and sets initial values for
* the newly allocated nodes and weights.
* \param map the map to be added
* \retval 0 Successful
* \retval 1 Out of memory
*/
int AddMaps(mapPTR map)
{
float *tempfltv; /**< Temporary pointer for copying */
float **tempflt; /**< Temporary pointer for copying */
int i,j; /**< Counters */
tempflt=(float **)malloc((size_t)((map->artA.max_nodes) * sizeof(float *)));
if (tempflt == NULL)
{
return 1;
}
tempflt[0] = (float *)malloc((size_t)((map->artA.max_nodes * map->artB.max_nodes) * sizeof(float)));
if (tempflt[0] == NULL)
{
free(tempflt);
return 1;
}
for(i = 1; i < map->artA.max_nodes; i++)
{
tempflt[i] = tempflt[i-1] + map->artB.max_nodes;
}
for (i = 0; i < map->maxA_nodes; i++)
{
for (j = 0; j < map->maxB_nodes; j++)
{
*(*(tempflt + i) + j) = *(*(map->map_weight + i) + j);
}
}
free(map->map_weight[0]);
free(map->map_weight);
map->map_weight = tempflt;
tempfltv = (float *)malloc((size_t)(map->artB.max_nodes * sizeof(float)));
if (tempfltv == NULL)
{
return 1;
}
for (i = 0; i < map->maxB_nodes; i++)
{
*(tempfltv + i) = *(map->map + i);
}
free(map->map);
map->map = tempfltv;
/**< Set initial weights of all new mapfield nodes */
for (i = map->maxA_nodes; i < (map->artA.max_nodes); i++)
{
for (j = 0; j < map->artB.max_nodes; j++)
{
*(*(map->map_weight + i) + j) = 1;
}
}
for (i = 0; i < map->artA.max_nodes; i++)
{
for (j = map->maxB_nodes; j < (map->artB.max_nodes); j++)
{
*(*(map->map_weight + i) + j) = 1;
}
}
/**< Update mapfield values */
map->maxA_nodes = map->artA.max_nodes;
map->maxB_nodes = map->artB.max_nodes;
return 0;
}
/**
* \fn int TrainMapPat(mapPTR map, patPTR pat)
* \brief Train the mapfield network
* Given a pointer to a mapfield, and a pointer to a single
* pattern trains the mapfield network on the pattern.
* \param map the mapfield pointer
* \param pat the pattern pointer
* \retval 0 Successful
* \retval 1 Out of memory
*/
int TrainMapPat(mapPTR map, patPTR pat)
{
float sum_inputs; /**< Sum of all the active inputs */
float sum_cat; /**< Sum of all the active Art-B categories */
float sum_map; /**< Sum of activations of map nodes */
int doneB; /**< Boolean to signal when done with pattern */
int i; /**< Counters */
/**< -------------- First activate and train Art-B network --------------- */
/**< Find winning Art-B category */
ActivateArt(&map->artB, pat->output);
/**< If Art-B not of type ART_TYPE_NONE train it */
if (map->artB.type != ART_TYPE_NONE)
{
if (TrainArtPat(&map->artB, pat->output))
{
return 1;
}
/**< Check if TrainArtPat allocated new space for ArtB */
if (map->maxB_nodes != map->artB.max_nodes)
{
if (AddMaps(map))
{
return 1;
}
}
}
/**< -------- Find an Art-A category that meets mapfield vigilence -------- */
doneB = FALSE; /* Haven't found one yet */
map->artA.vigil = map->base_vigil; /* Reset vigilence to base level */
while (!doneB)
{
/**< Find the winning category */
ActivateArt(&map->artA, pat->input);
/**< When no previously used Art-A node was able to win, a new Art-A node */
/**< is created and trained on the mapfield */
if (map->artA.win_cat == -1)
{
/**< Train New Unused Node in ArtA Module */
if (TrainArtPat(&map->artA, pat->input))
{
return 1;
}
/**< Train mapfield weights for new node */
for (i = 0; i < map->artB.nodes_used; i++)
{
*(*(map->map_weight + map->artA.win_cat) + i) = (*(map->artB.cat + i));
}
/**< Check if TrainArtPat allocated new space for ArtA */
if (map->maxA_nodes != map->artA.max_nodes)
{
if (AddMaps(map))
{
return 1;
}
}
doneB = TRUE;
}
/**< Otherwise check map vigilence for the used node */
else
{
/**< Calculate Mapfield Activations */
for (i = 0; i < map->artB.nodes_used; i++)
{
/**< For each mapfield node */
*(map->map + i) = (*(*(map->map_weight + map->artA.win_cat) + i));
}
sum_map = 0;
sum_cat = 0;
for (i = 0; i < map->artB.nodes_used; i++)
{
sum_map += FuzzInt((*(map->map + i)), (*(map->artB.cat + i)));
sum_cat += FuzzUni((*(map->map + i)), (*(map->artB.cat + i)));
}
if (map->artB.type != ART_TYPE_NONE)
{
sum_cat = 1;
}
/**< Calculate sum of inputs */
sum_inputs = 0; /**< Note: When compliment coded, */
for (i = 0; i < map->artA.num_inputs; i++) /**< sum of inputs is equal to */
{
sum_inputs += (*(pat->input + i)); /**< half the network inputs. */
}
/**< Check vigilence at mapfield */
if ((sum_map / sum_cat) < map->vigil)
{
/**< If mapfield mismatch then ArtA isn't done */
doneB = FALSE;
/**< Error causes increase in Art-A vigilence unless doing so exceeds */
/**< the highest vigilence level. If this is the case, then mismatch */
/**< was caused by inconsistent or noisy data so ignore and go on. */
map->artA.vigil = ((*(map->artA.sum_IW + map->artA.win_cat)) / sum_inputs) + 0.0001f;
if (map->artA.vigil > 1.0)
{
doneB = TRUE;
}
else
{
map->num_mismatch++;
}
}
else
{
/**< Train mapfield weights */
for (i = 0; i < map->artB.nodes_used; i++)
{
*(*(map->map_weight + map->artA.win_cat) + i) = (*(map->artB.cat + i));
}
/**< Train ArtA Module */
if (TrainArtPat(&map->artA, pat->input))
{
return 1;
}
/**< Check if TrainArtPat allocated new space for ArtA */
if (map->maxA_nodes != map->artA.max_nodes)
{
if (AddMaps(map))
{
return 1;
}
}
doneB = TRUE;
}
}
}
return 0;
}
/**
* \fn int Compliment(setTYPE *set, int input_style, int output_style)
* \brief compilement codes members
* Compilement codes members of a pettern set, when specified,
* allocated space for the compliment coded patterns.
* \param set the set
* \param input_style input style
* \param output_style output style
* \retval 0 Successful
* \retval 1 out of memory
*/
int Compliment(setTYPE *set, int input_style, int output_style)
{
float *tempflt;
int i,j;
/**< If compliment coding is requested of the input patterns */
if (input_style == ART_STYLE_COMPLIMENT)
{
/**< Allocate space for compliment coded inputs and copy old inputs */
for (j = 0; j < set->num_patterns; j++)
{
tempflt = (float *)malloc((size_t)((2 * set->num_inputs) * sizeof(float)));
if (tempflt == NULL)
{
return 1;
}
for (i = 0; i < set->num_inputs; i++)
{
*(tempflt + i) = *(set->pattern[j].input + i);
}
free(set->pattern[j].input);
set->pattern[j].input = tempflt;
/**< Complement coding input patterns in new space */
for (i = 0; i < set->num_inputs; i++)
{
*(set->pattern[j].input + (i + set->num_inputs)) = (1 - (*(set->pattern[j].input + i)));
}
}
set->style_inputs = ART_STYLE_COMPLIMENT;
}
/**< If compliment coding is requested of the output patterns */
if (output_style == ART_STYLE_COMPLIMENT)
{
/**< Allocate space for compliment coded outputs and copy old outputs */
for (j = 0; j < set->num_patterns; j++)
{
tempflt = (float *)malloc((size_t)((2 * set->num_outputs) * sizeof(float)));
if (tempflt == NULL)
{
return 1;
}
for (i = 0; i < set->num_outputs; i++)
{
*(tempflt + i) = *(set->pattern[j].output + i);
}
free(set->pattern[j].output);
set->pattern[j].output = tempflt;
/**< Complement coding output patterns in new space */
for (i = 0; i < set->num_outputs; i++)
{
*(set->pattern[j].output + (i + set->num_outputs)) = (1 - (*(set->pattern[j].output + i)));
}
}
set->style_outputs = ART_STYLE_COMPLIMENT;
}
return 0;
}
/**
* \fn int CheckNetSet(netPTR net, setPTR set)
* \brief Check the net compatible
* Given a pointer to a network and a pointer to a pattern set
* checks to make sure they are compatible.
* \param net the network
* \param set the set
* \retval 0 No errors, they are compatible
* \retval 3 NODE_ANALOG inputs given to NODE_BINARY network
* \retval 4 Input Size Incompatible
* \retval 5 Output Size Incompatible
* \retval 6 No output patterns for ARTMAP network
* \retval 7 Memory Allocation failure (out of memory)
*/
int CheckNetSet(netPTR net, setPTR set)
{
if (net->type == ART)
{
/**< Check Art Component Input Type Compatibility */
if ((net->art.type == ART_TYPE_ART1)&&(set->type_inputs == NODE_ANALOG))
{
return 3;
}
if ((net->art.style == ART_STYLE_NONE)&&(net->num_inputs != set->num_inputs))
{
return 4;
}
if ((net->art.style == ART_STYLE_COMPLIMENT)&&(net->num_inputs != 2 * (set->num_inputs)))
{
return 4;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -