Hello people,
I am rather puzzled by this problem I am having with doubles here. The
code seems to execute correctly for awhile and then all a sudden
printfing out my doubles, I get -1.#IND00 which seems to be an
indeterminate or -infinity or something of the such.
I am coding an IAC network and the problem occurs only in learning mode
when the values approach 1.00 (the values SHOULD stay between between
-0.2 and 1.0, but they occasionally go beyond 1.0 which doesn't make
sense to me either but I'm thinking this is all part of the same
problem.
I do NOT have any sort of division in my program so it can not be a
problem of dividing 0/0 like i've seen mentioned on some posts
reporting the -1.#IND00 problem. I tried the _fpreset function to see
if it was a fpu stack poping problem but it doesn't seem to help
either. I also tried global optimizations (/Og) without success.
I am at a loss to understand why this bombs. The activation of nodes is
the first thing that goes kaput. The weights with which we calculate
the activation of nodes stay in the range -0.5 and 2.0. The magnitude
seems reasonable.
Any help would be greatly appreciated. I can post the rest of the code
if you guys need it. This is the core of the calculation. The rest of
the code only really calls these guys.
#include "iac.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/* Create a iac network and allocates memory for it */
iac IacCreate(int nodeqty, int connectionqty, double learningrate)
{
iac network;
int x = 0;
network.learnin grate = learningrate;
network.nodeqty = nodeqty;
network.nodes = (node*) malloc(sizeof(n ode)*nodeqty);
network.connect ionqty = connectionqty;
network.connect ions = (connection*)
malloc(sizeof(c onnection)*conn ectionqty);
return network;
}
/* Destroys a iac network by freeing all memory allocated for it */
void IacDestroy(iac network)
{
if(network.conn ections != NULL){free(netw ork.connections );}
if(network.node s != NULL){free(netw ork.nodes);}
return;
}
/* We cycle activation through the network */
iac IacCycle(iac network)
{
int x = 0;
double max = 0;
double min = 0;
double activation = 0;
double decay = 0;
double rest = 0;
double netinput = 0;
for(x = 0; x < network.nodeqty ; x++)
{
max = network.nodes[x].max;
min = network.nodes[x].min;
decay = network.nodes[x].decay;
rest = network.nodes[x].rest;
activation = network.nodes[x].activation;
netinput = IacNodeNetInput (network, x);
if(netinput > 0)
{
network.nodes[x].activation += (max - activation)*net input -
decay*(activati on - rest);
}
else
{
network.nodes[x].activation += (activation - min)*netinput -
decay*(activati on - rest);
}
}
return network;
}
/* We cycle activation through the network many times */
iac IacCycles(iac network, int iteration)
{
int x = 0;
for(x = 0; x < iteration; x++)
{
network = IacCycle(networ k);
}
return network;
}
/* We cycle activation a single time through the network */
iac IacLearningCycl e(iac network)
{
// network = IacCycle(networ k);
network = IacWeightsAdjus t(network);
return network;
}
iac IacLearningCycl es(iac network, int iteration)
{
int x = 0;
for(x = 0; x < iteration; x++)
{
network = IacLearningCycl e(network);
}
return network;
}
/* We cycle activation through the network */
iac IacWeightsAdjus t(iac network)
{
int x = 0;
double activation1 = 0.0;
double activation2 = 0.0;
double learningrate = network.learnin grate;
// double average;
for(x = 0; x < network.connect ionqty; x++)
{
activation1 =
network.nodes[network.connect ions[x].connectedto1].activation;
activation2 =
network.nodes[network.connect ions[x].connectedto2].activation;
// average = (activation1 + activation2)/2;
network.connect ions[x].weight +=
learningrate*(( activation1)*(a ctivation2));
}
return network;
}
/* We calculate the net input for the node to process */
double IacNodeNetInput (iac network, int nodetoprocess)
{
int x = 0;
int connectedto1 = 0;
int connectedto2 = 0;
double netinput = 0.0;
for(x = 0; x < network.connect ionqty; x++)
{
connectedto1 = network.connect ions[x].connectedto1;
connectedto2 = network.connect ions[x].connectedto2;
if(connectedto1 == nodetoprocess)
{
netinput += network.connect ions[x].weight *
network.nodes[connectedto2].activation;
}
else if(connectedto2 == nodetoprocess)
{
netinput += network.connect ions[x].weight *
network.nodes[connectedto1].activation;
}
}
return netinput;
}
/* We activate a certain node */
iac IacNodeActivate (iac network, char* concept)
{
int x = 0;
for(x = 0; x < network.nodeqty ; x++)
{
if(!strcmp(netw ork.nodes[x].concept, concept))
{
network.nodes[x].activation = 1.0;
return network;
}
}
return network;
}
/* We inhibit a certain node */
iac IacNodeInhibit( iac network, char* concept)
{
int x = 0;
for(x = 0; x < network.nodeqty ; x++)
{
if(!strcmp(netw ork.nodes[x].concept, concept))
{
network.nodes[x].activation = -1.0;
return network;
}
}
return network;
}
/* We reinforce the pattern */
iac IacPatternActiv ate(iac network, char** concepts, int conceptqty)
{
int x = 0;
for(x = 0; x < conceptqty; x++)
{
network = IacNodeActivate (network, concepts[x]);
}
return network;
}
/* We weaken the pattern */
iac IacPatternInhib it(iac network, char** concepts, int conceptqty)
{
int x = 0;
for(x = 0; x < conceptqty; x++)
{
network = IacNodeInhibit( network, concepts[x]);
}
return network;
}
/* We zero all the node activations */
iac IacNetworkZero( iac network)
{
int x = 0;
for(x = 0; x < network.nodeqty ; x++)
{
network.nodes[x].activation = 0.0;
}
return network;
}
/* Correlate concepts together and leaves no residual trace running
around
the network. We do not want our pattern to be associated with any
other
pattern */
iac IacCorrelateZer o(iac network, char** concepts, int conceptqty)
{
network = IacPatternActiv ate(network, concepts, conceptqty);
network = IacLearningCycl e(network);
network = IacNetworkZero( network);
return network;
}
/* Correlate concepts together but leaves a residual activation running
around the network. This allows for patterns to be associated
together
in what resembles a type of context association. */
iac IacCorrelateRes idual(iac network, char** concepts, int conceptqty)
{
network = IacPatternActiv ate(network, concepts, conceptqty);
network = IacLearningCycl e(network);
return network;
}
/* Decorrelate concepts and leaves no residual trace running around
the network. We do not want our pattern to be associated with any
other
pattern */
iac IacDecorrelateZ ero(iac network, char** concepts, int conceptqty)
{
network = IacPatternInhib it(network, concepts, conceptqty);
network = IacLearningCycl e(network);
network = IacNetworkZero( network);
return network;
}
/* Correlate concepts together but leaves a residual activation running
around the network. This allows for patterns to be associated
together
in what resembles a type of context association. */
iac IacDecorrelateR esidual(iac network, char** concepts, int
conceptqty)
{
network = IacPatternInhib it(network, concepts, conceptqty);
network = IacLearningCycl e(network);
return network;
}
/* Consult the network */
iac IacConsult(iac network, char** concepts, int conceptqty)
{
network = IacPatternActiv ate(network, concepts, conceptqty);
network = IacCycles(netwo rk, 2000);
return network;
}
iac IacNodeAdd(iac network, char* concept)
{
int x = 0;
int temp = 0;
int nodenumber = 0;
/* We create a new node and initialize its attributes */
network.nodes = (node*) realloc(network .nodes,
sizeof(node)*(n etwork.nodeqty+ 1));
strcpy(network. nodes[network.nodeqty].concept, concept);
network.nodes[network.nodeqty].activation = 0.0;
network.nodes[network.nodeqty].decay = 0.1;
network.nodes[network.nodeqty].rest = -0.1;
network.nodes[network.nodeqty].max = 1.0;
network.nodes[network.nodeqty].min = -0.2;
/* We link the newly created node to all the other nodes (except
itself) */
network.connect ions = (connection*) realloc(network .connections,
sizeof(connecti on)*(network.co nnectionqty+net work.nodeqty));
temp = network.connect ionqty + network.nodeqty ;
for(x = network.connect ionqty; x < temp; x++)
{
network.connect ions[x].connectedto1 = network.nodeqty ;
network.connect ions[x].connectedto2 = nodenumber;
network.connect ions[x].weight = -0.1;
nodenumber++;
}
network.connect ionqty = temp;
network.nodeqty += 1;
return network;
}
bool IacConceptExist s(iac network, char* concept)
{
int x = 0;
for(x = 0; x < network.nodeqty ; x++)
{
if(!strcmp(netw ork.nodes[x].concept, concept)){retur n true;}
}
return false;
}
/* Prints out all nodes content to terminal */
void NodesPrint(iac network)
{
int x = 0;
printf("******* *************** *************** *******Nodes\n" );
for(x = 0; x < network.nodeqty ; x++)
{
printf("Concept : %s\t\t activation: %f\n",
network.nodes[x].concept, network.nodes[x].activation);
}
printf("******* *************** *************** ************\n\ n");
}
/* Prints out all weights content to terminal */
void WeightsPrint(ia c network)
{
int x = 0;
printf("******* *************** *************** *****Weights\n" );
for(x = 0; x < network.connect ionqty; x++)
{
printf("Connect ion weight between %i-%i: %f\n",
network.connect ions[x].connectedto1,
network.connect ions[x].connectedto2, network.connect ions[x].weight);
}
printf("******* *************** *************** ************\n\ n");
}
Regards
Jean-François Michaud
I am rather puzzled by this problem I am having with doubles here. The
code seems to execute correctly for awhile and then all a sudden
printfing out my doubles, I get -1.#IND00 which seems to be an
indeterminate or -infinity or something of the such.
I am coding an IAC network and the problem occurs only in learning mode
when the values approach 1.00 (the values SHOULD stay between between
-0.2 and 1.0, but they occasionally go beyond 1.0 which doesn't make
sense to me either but I'm thinking this is all part of the same
problem.
I do NOT have any sort of division in my program so it can not be a
problem of dividing 0/0 like i've seen mentioned on some posts
reporting the -1.#IND00 problem. I tried the _fpreset function to see
if it was a fpu stack poping problem but it doesn't seem to help
either. I also tried global optimizations (/Og) without success.
I am at a loss to understand why this bombs. The activation of nodes is
the first thing that goes kaput. The weights with which we calculate
the activation of nodes stay in the range -0.5 and 2.0. The magnitude
seems reasonable.
Any help would be greatly appreciated. I can post the rest of the code
if you guys need it. This is the core of the calculation. The rest of
the code only really calls these guys.
#include "iac.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/* Create a iac network and allocates memory for it */
iac IacCreate(int nodeqty, int connectionqty, double learningrate)
{
iac network;
int x = 0;
network.learnin grate = learningrate;
network.nodeqty = nodeqty;
network.nodes = (node*) malloc(sizeof(n ode)*nodeqty);
network.connect ionqty = connectionqty;
network.connect ions = (connection*)
malloc(sizeof(c onnection)*conn ectionqty);
return network;
}
/* Destroys a iac network by freeing all memory allocated for it */
void IacDestroy(iac network)
{
if(network.conn ections != NULL){free(netw ork.connections );}
if(network.node s != NULL){free(netw ork.nodes);}
return;
}
/* We cycle activation through the network */
iac IacCycle(iac network)
{
int x = 0;
double max = 0;
double min = 0;
double activation = 0;
double decay = 0;
double rest = 0;
double netinput = 0;
for(x = 0; x < network.nodeqty ; x++)
{
max = network.nodes[x].max;
min = network.nodes[x].min;
decay = network.nodes[x].decay;
rest = network.nodes[x].rest;
activation = network.nodes[x].activation;
netinput = IacNodeNetInput (network, x);
if(netinput > 0)
{
network.nodes[x].activation += (max - activation)*net input -
decay*(activati on - rest);
}
else
{
network.nodes[x].activation += (activation - min)*netinput -
decay*(activati on - rest);
}
}
return network;
}
/* We cycle activation through the network many times */
iac IacCycles(iac network, int iteration)
{
int x = 0;
for(x = 0; x < iteration; x++)
{
network = IacCycle(networ k);
}
return network;
}
/* We cycle activation a single time through the network */
iac IacLearningCycl e(iac network)
{
// network = IacCycle(networ k);
network = IacWeightsAdjus t(network);
return network;
}
iac IacLearningCycl es(iac network, int iteration)
{
int x = 0;
for(x = 0; x < iteration; x++)
{
network = IacLearningCycl e(network);
}
return network;
}
/* We cycle activation through the network */
iac IacWeightsAdjus t(iac network)
{
int x = 0;
double activation1 = 0.0;
double activation2 = 0.0;
double learningrate = network.learnin grate;
// double average;
for(x = 0; x < network.connect ionqty; x++)
{
activation1 =
network.nodes[network.connect ions[x].connectedto1].activation;
activation2 =
network.nodes[network.connect ions[x].connectedto2].activation;
// average = (activation1 + activation2)/2;
network.connect ions[x].weight +=
learningrate*(( activation1)*(a ctivation2));
}
return network;
}
/* We calculate the net input for the node to process */
double IacNodeNetInput (iac network, int nodetoprocess)
{
int x = 0;
int connectedto1 = 0;
int connectedto2 = 0;
double netinput = 0.0;
for(x = 0; x < network.connect ionqty; x++)
{
connectedto1 = network.connect ions[x].connectedto1;
connectedto2 = network.connect ions[x].connectedto2;
if(connectedto1 == nodetoprocess)
{
netinput += network.connect ions[x].weight *
network.nodes[connectedto2].activation;
}
else if(connectedto2 == nodetoprocess)
{
netinput += network.connect ions[x].weight *
network.nodes[connectedto1].activation;
}
}
return netinput;
}
/* We activate a certain node */
iac IacNodeActivate (iac network, char* concept)
{
int x = 0;
for(x = 0; x < network.nodeqty ; x++)
{
if(!strcmp(netw ork.nodes[x].concept, concept))
{
network.nodes[x].activation = 1.0;
return network;
}
}
return network;
}
/* We inhibit a certain node */
iac IacNodeInhibit( iac network, char* concept)
{
int x = 0;
for(x = 0; x < network.nodeqty ; x++)
{
if(!strcmp(netw ork.nodes[x].concept, concept))
{
network.nodes[x].activation = -1.0;
return network;
}
}
return network;
}
/* We reinforce the pattern */
iac IacPatternActiv ate(iac network, char** concepts, int conceptqty)
{
int x = 0;
for(x = 0; x < conceptqty; x++)
{
network = IacNodeActivate (network, concepts[x]);
}
return network;
}
/* We weaken the pattern */
iac IacPatternInhib it(iac network, char** concepts, int conceptqty)
{
int x = 0;
for(x = 0; x < conceptqty; x++)
{
network = IacNodeInhibit( network, concepts[x]);
}
return network;
}
/* We zero all the node activations */
iac IacNetworkZero( iac network)
{
int x = 0;
for(x = 0; x < network.nodeqty ; x++)
{
network.nodes[x].activation = 0.0;
}
return network;
}
/* Correlate concepts together and leaves no residual trace running
around
the network. We do not want our pattern to be associated with any
other
pattern */
iac IacCorrelateZer o(iac network, char** concepts, int conceptqty)
{
network = IacPatternActiv ate(network, concepts, conceptqty);
network = IacLearningCycl e(network);
network = IacNetworkZero( network);
return network;
}
/* Correlate concepts together but leaves a residual activation running
around the network. This allows for patterns to be associated
together
in what resembles a type of context association. */
iac IacCorrelateRes idual(iac network, char** concepts, int conceptqty)
{
network = IacPatternActiv ate(network, concepts, conceptqty);
network = IacLearningCycl e(network);
return network;
}
/* Decorrelate concepts and leaves no residual trace running around
the network. We do not want our pattern to be associated with any
other
pattern */
iac IacDecorrelateZ ero(iac network, char** concepts, int conceptqty)
{
network = IacPatternInhib it(network, concepts, conceptqty);
network = IacLearningCycl e(network);
network = IacNetworkZero( network);
return network;
}
/* Correlate concepts together but leaves a residual activation running
around the network. This allows for patterns to be associated
together
in what resembles a type of context association. */
iac IacDecorrelateR esidual(iac network, char** concepts, int
conceptqty)
{
network = IacPatternInhib it(network, concepts, conceptqty);
network = IacLearningCycl e(network);
return network;
}
/* Consult the network */
iac IacConsult(iac network, char** concepts, int conceptqty)
{
network = IacPatternActiv ate(network, concepts, conceptqty);
network = IacCycles(netwo rk, 2000);
return network;
}
iac IacNodeAdd(iac network, char* concept)
{
int x = 0;
int temp = 0;
int nodenumber = 0;
/* We create a new node and initialize its attributes */
network.nodes = (node*) realloc(network .nodes,
sizeof(node)*(n etwork.nodeqty+ 1));
strcpy(network. nodes[network.nodeqty].concept, concept);
network.nodes[network.nodeqty].activation = 0.0;
network.nodes[network.nodeqty].decay = 0.1;
network.nodes[network.nodeqty].rest = -0.1;
network.nodes[network.nodeqty].max = 1.0;
network.nodes[network.nodeqty].min = -0.2;
/* We link the newly created node to all the other nodes (except
itself) */
network.connect ions = (connection*) realloc(network .connections,
sizeof(connecti on)*(network.co nnectionqty+net work.nodeqty));
temp = network.connect ionqty + network.nodeqty ;
for(x = network.connect ionqty; x < temp; x++)
{
network.connect ions[x].connectedto1 = network.nodeqty ;
network.connect ions[x].connectedto2 = nodenumber;
network.connect ions[x].weight = -0.1;
nodenumber++;
}
network.connect ionqty = temp;
network.nodeqty += 1;
return network;
}
bool IacConceptExist s(iac network, char* concept)
{
int x = 0;
for(x = 0; x < network.nodeqty ; x++)
{
if(!strcmp(netw ork.nodes[x].concept, concept)){retur n true;}
}
return false;
}
/* Prints out all nodes content to terminal */
void NodesPrint(iac network)
{
int x = 0;
printf("******* *************** *************** *******Nodes\n" );
for(x = 0; x < network.nodeqty ; x++)
{
printf("Concept : %s\t\t activation: %f\n",
network.nodes[x].concept, network.nodes[x].activation);
}
printf("******* *************** *************** ************\n\ n");
}
/* Prints out all weights content to terminal */
void WeightsPrint(ia c network)
{
int x = 0;
printf("******* *************** *************** *****Weights\n" );
for(x = 0; x < network.connect ionqty; x++)
{
printf("Connect ion weight between %i-%i: %f\n",
network.connect ions[x].connectedto1,
network.connect ions[x].connectedto2, network.connect ions[x].weight);
}
printf("******* *************** *************** ************\n\ n");
}
Regards
Jean-François Michaud
Comment