This is Neuron.m in view mode; [Download] [Up]
/* =======================================================
Neural Network Classes for the NeXT Computer
Written by: Ralph Zazula
University of Arizona
zazula@bonehead.tucson.az.us (NeXT Mail)
==========================================================*/
/*$Log: Neuron.m,v $
Revision 1.4 92/01/14 21:19:46 zazula
Check in before starting HashTable mod
Revision 1.3 92/01/02 14:04:31 zazula
Faster linked-list for connections
No more Storage object
Revision 1.2 92/01/02 12:41:34 zazula
Initial version - support for stochastic networks via temperature T
*/
#import "Neuron.h"
#import <appkit/nextstd.h>
#import "math.h"
//----------------------------------------------------------
@implementation Neuron
- inputs { return inputs; }
- setType:(int)type { nodeType = type; return self; }
- (int)getType { return nodeType; }
- setTemp:(double)newT { T = newT; return self; }
- (double)getTemp { return T; }
- setRandom:theRandom { random = theRandom; return self; }
- setSymmetric:(BOOL)sym { Symmetric = sym; return self; }
- (BOOL)getSymmetric { return Symmetric; }
//----------------------------------------------------------
- (double)activation:(double)net
{
double temp;
if(random == nil) random = [[Random alloc] init];
switch (nodeType) {
case Binary :
if(T > 0.0)
temp = ([random percent] <= 1.0/(1.0+exp(-2*net/T))) ? 1.0 : 0.0;
else
temp = (net > 0.5) ? 1.0 : 0.0;
break;
case Sigmoid :
temp = 1.0/(1.0+exp(-net));
break;
case Sign :
if(T > 0.0)
temp = ([random percent] <= 1.0/(1.0+exp(-2*net/T))) ? 1.0 : -1.0;
else
temp = (net > 0.0) ? 1.0 : -1.0;
break;
case Tanh :
if(T > 0.0)
temp = tanh(net/T);
else
temp = tanh(net);
break;
}
return temp;
}
//----------------------------------------------------------
- init
{
[super init];
lastOutput = 0.0;
nodeType = Sigmoid; // default node type
T = 0.0; // default temperature
head = tail = NULL; // initialize the linked-list of connections
Symmetric = NO; // default Symmetric connection status
return self;
}
//-----------------------------------------------------------
- step
// update the output value based on our inputs
{
int i = 0;
connection *C;
double temp=0.0; // use temp variable to allow for feedback
C = head;
while(C != NULL) {
temp += C->weight*[C->source lastOutput];
C = (connection *)C->next;
}
lastOutput = [self activation:temp];
return self;
}
//-----------------------------------------------------------
- (double)lastOutput
{
return lastOutput;
}
//-----------------------------------------------------------
- connect:sender
{
if(random == nil) random = [[Random alloc] init];
return [self connect:sender withWeight:[random percent]/10.0];
}
//-----------------------------------------------------------
- connect:sender withWeight:(double)weight
//
// adds sender to the list of inputs
// we should check to make sure sender is a Neruon
// also need to check if it is already in the list
//
{
connection *C;
C = (connection *)malloc(sizeof(connection));
if(head == NULL) {
head = C;
}
else {
tail->next = C;
}
tail = C;
C->source = sender;
C->weight = weight;
C->next = NULL;
return self;
}
//-----------------------------------------------------------
- (double)getWeightFor:source
{
int i=0;
connection *C;
C = head;
while((C != NULL) && (C->source != source))
C = (connection *)C->next;
if(C != NULL) { // if C==NULL, source isn't an input
return C->weight;
}
else {
fprintf(stderr,"connection not found in getWeightFor:\n");
return NAN;
}
}
//-----------------------------------------------------------
- setWeightFor:source to:(double)weight
{
int i=0;
connection *C;
C = head;
while((C != NULL) && (C->source != source))
C = (connection *)C->next;
if(C != NULL) { // if C==NULL, source isn't an input
C->weight = weight;
return self;
}
else {
fprintf(stderr,"connection not found in setWeightFor:to:\n");
return nil;
}
}
//-----------------------------------------------------------
- setOutput:(double)output
{
lastOutput = output;
return self;
}
//-----------------------------------------------------------
- changeWeightFor:source by:(double)delta
{
int i=0;
connection *C;
C = head;
while((C != NULL) && (C->source != source))
C = (connection *)C->next;
if(C != NULL) { // if C==NULL, source isn't an input
C->weight += delta;
if(Symmetric) // for symmetric connections
[source setWeightFor:self to:C->weight];
return self;
}
else {
fprintf(stderr,"connection not found in changeWeightfor:by:\n");
// printf("connection not found in changeWeightfor:by:\n");
return nil;
}
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.