//*******************************************************************************
// CSC 143 Computer Programming II Spring 1999 Instructor: Keith Hughes
//
// Homework 3
// File : \\Venus\katy\CIS143\Homework3\AdalineNetwork\adaline.cpp
//
// Purpose : Implementation file for AdalineNet class.
//
// Author : Hsin-yi F. Berg
// Date : 5/9/1999 Sun.
// Last Update: 5/28/1999 Fri.
// Update Note: None
//*******************************************************************************

#include "adaline.h"
#include "NeuralNet.h"
#include <iostream.h>
#include <assert.h>

// weight of the link, defined in base.h
extern const double WEIGHT;
// the learning rate of Adaline network, usually it's 0.25 - 0.50
const double LEARNINGRATE = 0.5;
// the value of the bias node for calculation purpose only
const double BIASNODEVALUE = 1.0;

/*
    Function definitions for class AdalineNet
*/

/*
    AdalineNet::AdalineNet()

    Default constructor for an AdalineNet. AdalineNet is created empty.
*/

AdalineNet::AdalineNet()

{
    learning_rate = LEARNINGRATE;
}

/*
    AdalineNet::AdalineNet(int sizeInputLayer)

    Constructor for an AdalineNet.
    Takes an int argument sizeInputLayer to set the number of Neurons in the
    input layer. This function will then create a fully connected AdalineNet
    with two Layers and specified number of Neurons in the input Layer.
*/

AdalineNet::AdalineNet(int sizeInputLayer)

{
    // BuildStructure will do the job
    BuildStructure(sizeInputLayer);
    learning_rate = LEARNINGRATE;
}

/*
    void AdalineNet::BuildStructure(int sizeInputLayer)

    private utility.
    Takes an int argument sizeInputLayer to create a fully connected AdalineNet
    with two Neuron Layers. sizeInputLayer determines how many Neurons are there
    in the input Layer, and there is only one Neuron in the output Layer.
*/

void AdalineNet::BuildStructure(int sizeInputLayer)

{
    // allocate 2 NeuronLayers, input and output Layers
    SetHowManyNeuronLayers(2);

    // Set the size of each layer, output layer has one Neuron only,
    // inputlayer has specified numbers of neurons + 1 (bias node)

    // The bias node (the last one in the input Neuron array which has
    // an index "sizeInputLayer") has a permanent value set to BIASNODEVALUE.
    // For some misterious reason, this node has to been there for our 
    // calculating algorithm to work. This value cannot be modified.
    SetSizeOfNeuronLayer(0, sizeInputLayer + 1);    // set size of input Layer
    SetSizeOfNeuronLayer(1, 1);                     // set size of output Layer

    // fully connect the Adaline Network.
    InterConnect();
    // Interconnect will also allocate the right amount of LinkLayers 
    // and Links in each layer.

    // set the value of bias node
    SetInputValue(sizeInputLayer, BIASNODEVALUE);
}

/*
    AdalineNet::~AdalineNet()

    Destructor for an AdalineNet.
*/

AdalineNet::~AdalineNet()

{}

/*
    void AdalineNet::SetSizeOfInputLayer(int numInputLayer)

    Set the number of Neurons in the input layer.
    This function will create a fully connected AdalineNet with two Layers
    and right amount of Neurons in the input layer and output Layer.
    See note for BuildStructure(number)
*/

void AdalineNet::SetSizeOfInputLayer(int numInputLayer)

{
    // call private utilty
    BuildStructure(numInputLayer);
}

/*
    void NeuralNet::SetInputValue(int whichNeuron, double Value)

    Set the value of a specific Neuron in AdalineNet
*/

void AdalineNet::SetInputValue(int whichNeuron, double Value)

{
    NeuralNet::SetInputValue(whichNeuron, Value);
}

/*
    double NeuralNet::GetOutputValue(int whichNeuron)

    Get the value of a specific Neuron in AdalineNet
*/

double AdalineNet::GetOutputValue(int whichNeuron) const

{
    return NeuralNet::GetOutputValue(whichNeuron);
}

/*
    void NeuralNet::Fire(void)

    Fire the whole AdalineNet
*/

void AdalineNet::Fire(void)

{
    NeuralNet::Fire();
}

/*
    void AdalineNet::DesiredOutput(double desired_value)

    This function will calculate the error of the output Neuron
    according to the desired value.
    The network should be fired first.
*/

void AdalineNet::DesiredOutput(double desired_value)

{
    // Assuming that the network has been fired already

    // The only Neuron in the output Layer should have value desired_value
    // Therefore, we calculate the "error" of the only output Neuron (index 0)
    // and the desired value
    double error = desired_value - GetOutputValue(0);

    // Set the error of the output Neuron to computed error
    neuronLayers[1].SetError(0, error);
    // note: neuronLayer is a protected member in the base class
}

/*
    void AdalineNet::Learn()

    This function will propagate the error of output Neuron
    back to its input Links, adjust the weight of each Link
    using the rate supplied.
*/

void AdalineNet::Learn()

{
    // Call learn() of the only output Neuron from the output Layer.
    // neuronLayers[1].GetNeurons()[0] will get the only neuron
    // that's in the output Layer.
    (neuronLayers[1].GetNeurons())[0].Learn(learning_rate);
}

/*
    void AdalineNet::SetLearningRate(double rate)

    Set the learning rate of this Adaline Network.
*/

void AdalineNet::SetLearningRate(double rate)

{
    learning_rate = rate;
}

/*
    double AdalineNet::GetLearningRate()

    Get the learning rate of this Adaline Network.
*/

double AdalineNet::GetLearningRate()

{
    return learning_rate;
}

// ps: Print(ostream& out) needs to be redefined, so the bias node
// will not be printed.

/*
    void AdalineNet::ReadFromFile(istream &in)

    Read data into this AdalineNet instance from file specified by "in"
*/

void AdalineNet::ReadFromFile(istream &in)

{
    NeuralNet::ReadFromFile(in);
}
    
/*
    void AdalineNet::WriteToFile(ostream &out)

    Write data of this AdalineNet instance to file specified by "out"
*/

void AdalineNet::WriteToFile(ostream &out)

{
    NeuralNet::WriteToFile(out);
}


Back    Top