// slp.h                Section: 13.5 Single Layer Perceptron (SLP)
//      Copyright 1994, Center for Computer Vision and Visualization,
//      University of Florida.  All rights reserved.
//

#ifndef SLP_h_
#define SLP_h_

#include "Bit.h"
#include "Closure.h"
#include "DblPoint.h"
#include "Image.h"


class SLP: public IA_Closure<IA_Point<double>,int> {
private:
    IA_Point<double> slp_weight;
    double nu;

public:

    // Limiter function
    static unsigned int f( double x );


    // An uninitialized Single Layer Perceptron
    // Initialize weights to random values
    SLP( double nu, unsigned int m );

    // Classification of a point
    int operator() (const IA_Point<double> & pattern ) const;

    // Return a copy of this SLP
    IA_Closure<IA_Point<double>,int> * clone_self() const;

    // Adjust the weight of the SLP for a single pattern
    void
    adjust_weight( const IA_Point<double> & pattern,
		   const IA_Bit           & y_class );

    // Training function, does NOT reset weights to random values.
    // An implication of this fact is that the SLP can be partially
    //    trained, examined, and then trained some more.
    //
    // Each point in the domain of the image represents a pattern,
    //    the value of the image at each point is the classification
    //    of the pattern the point represents.
    // The number of times patterns is examined is returned.
    int
    train( const IA_Image<IA_Point<double>,IA_Bit> & patterns,
	   unsigned int max_iterations );

    // Read the stream for the training patterns.
    // Assume the stream has one <class> <pattern values> pair per line.
    // Max_iterations is the maximum number of times the stream values
    //    should be consulted to train to convergence.
    // The number of times the stream is constulted is returned.
    int
    train( istream & training_stream,
	   unsigned int max_iterations );

    // Answer with the current weight vector
    double learning_rate() const;

    // Answer with the current weight vector
    IA_Point<double> weight() const;
};

#endif
