// hopfield.h           Section: 13.2
//      Copyright 1994, Center for Computer Vision and Visualization,
//      University of Florida.  All rights reserved.
// Here we declare the main Hopfield functions and data structures.
//

#ifndef _hopfield_h_
#define _hopfield_h_

#include "IntDI.h"
#include "ClosureDT.h"


/////////////////////////////////////////////////////////////////////////
// Hopfield_hard_limiter()
// This function implements the hard limiter function  f()  as
//    defined for the Hopfield algorithm.
// a_lp_t == linear_product( a, t )
//
IA_Image<IA_Point<int>,int>
Hopfield_hard_limiter( const IA_Image<IA_Point<int>,int> & a_lp_t,
		       const IA_Image<IA_Point<int>,int> & a      );



/////////////////////////////////////////////////////////////////////////
// calculate_hopfield_weights()
// This function calculates the weight array, which is of size NxN
//
// NOTE: Ref: The C++ Programming Language, p. 129
void
calculate_hopfield_weights(
    const IA_Image<IA_Point<int>,int> & examplars,
    int ** w, // w is NxN
    const unsigned int N );



/////////////////////////////////////////////////////////////////////////
// class HopfieldTemplate
// Declare the Hopfield template, which is based on the examplars.
// We assume the examplars are all of the same cardinality.
// NOTE: The copy constructor must be defined for correct
//       execution with the iac++ library.  This is because this
//       object allocates memory internally (weights_p).
//
class HopfieldTemplate: public IA_ClosureDT<IA_Image<IA_Point<int>,int> >
{
private:
    int ** weights_p;  // NxN array of the w[i,j] weight values
    unsigned int  N;   // Number of nodes in the neural network

public:
    HopfieldTemplate( const HopfieldTemplate & ); // copy constructor

    // Initialize the template with the 
    HopfieldTemplate( IA_Image<IA_Point<int>,int> * e_array,
		      unsigned int                  e_array_size );

    // This constructor can be used when the weight array has
    //    been previously calculated.
    HopfieldTemplate( 
	const IA_Image<IA_Point<int>,int> & weight_image_ );

    // Clean up needs to be declared;
    ~HopfieldTemplate();

    // Return a 1D image which is of cardanality N
    // This image, say im, has the property that
    //    im( oneDpoint ) == 0
    IA_Image<IA_Point<int>,int>
    operator() ( const IA_Point<int> & oneDpoint ) const;

    IA_ClosureDT<IA_Image<IA_Point<int>,int> > *  clone_self() const;

    // Return the weight_image we are based on.
    // This is here simply to allow inspection of the weight image
    //    defined by this construction
    IA_Image<IA_Point<int>,int>  weight_image() const;
};

#endif
