head	1.2;
access;
symbols;
locks; strict;
comment	@ * @;


1.2
date	94.07.21.03.42.25;	author rjj;	state Exp;
branches;
next	1.1;

1.1
date	94.07.01.01.18.05;	author rjj;	state Exp;
branches;
next	;


desc
@Initial implementation for the Hopfield Neural Network algorithm.  Buggy!
@


1.2
log
@Minor changes for testing purposes.
@
text
@// hopfield.c - 
//


#include "PSIter.h"
#include "UcharDI.h"
#include "IntDI.h"
#include "ClosureI.h"
#include "DDTempl.h"
#include "IntConvolutions.h"
#include "ClosureDT.h"

#include "scale-to-uchar.h"


static int one[120] =  {0,0,0,0,1,1,0,0,0,0,
			0,0,0,0,1,1,0,0,0,0,
			0,0,0,0,1,1,0,0,0,0,
			0,0,0,0,1,1,0,0,0,0,
			0,0,0,0,1,1,0,0,0,0,
			0,0,0,0,1,1,0,0,0,0,   
			0,0,0,0,1,1,0,0,0,0,
			0,0,0,0,1,1,0,0,0,0,
			0,0,0,0,1,1,0,0,0,0,
			0,0,0,0,1,1,0,0,0,0,
			0,0,0,0,1,1,0,0,0,0,
			0,0,0,0,1,1,0,0,0,0};


static int two[120] =  {1,1,1,1,1,1,1,1,1,1,
			1,1,1,1,1,1,1,1,1,1,
			1,1,0,0,0,0,0,0,1,1,
			0,0,0,0,0,0,0,1,1,1,
			0,0,0,0,0,0,1,1,1,0,
			0,0,0,0,0,1,1,0,0,0,  
			0,0,1,1,1,1,0,0,0,0,
			0,1,1,1,1,0,0,0,0,0,
			1,1,0,0,0,0,0,0,0,0,
			1,1,0,0,0,0,0,0,1,1,
			1,1,1,1,1,1,1,1,1,1,
			1,1,1,1,1,1,1,1,1,1};


static int three[120] ={0,1,1,1,1,1,1,1,0,0,
			0,1,1,1,1,1,1,1,1,0,
			0,0,0,0,0,0,0,1,1,0,
			0,0,0,0,0,0,0,1,1,0,
			0,0,0,0,0,0,0,1,1,0,
			0,0,0,0,0,1,1,1,0,0,
			0,0,0,0,0,1,1,1,0,0, 
			0,0,0,0,0,0,0,1,1,0,
			0,0,0,0,0,0,0,1,1,0,
			0,0,0,0,0,0,0,1,1,0,
			0,1,1,1,1,1,1,1,1,0,
			0,1,1,1,1,1,1,1,0,0};


static int four[120] = {0,1,1,0,0,0,0,1,1,0,
			0,1,1,0,0,0,0,1,1,0,
			0,1,1,0,0,0,0,1,1,0,
			0,1,1,0,0,0,0,1,1,0,
			0,1,1,0,0,0,0,1,1,0,
			0,1,1,1,1,1,1,1,1,1,  
			0,1,1,1,1,1,1,1,1,1,
			0,0,0,0,0,0,0,1,1,0,
			0,0,0,0,0,0,0,1,1,0,
			0,0,0,0,0,0,0,1,1,0,
			0,0,0,0,0,0,0,1,1,0,
			0,0,0,0,0,0,0,1,1,0};


static int nine[120]=  {0,1,1,1,1,1,1,1,1,0,
			0,1,1,1,1,1,1,1,1,0,
			0,1,1,0,0,0,0,1,1,0,
			0,1,1,0,0,0,0,1,1,0,
			0,1,1,0,0,0,0,1,1,0,
			0,1,1,1,1,1,1,1,1,0,  
			0,1,1,1,1,1,1,1,1,0,
			0,0,0,0,0,0,0,1,1,0,
			0,0,0,0,0,0,0,1,1,0,
			0,0,0,0,0,0,0,1,1,0,
			0,0,0,0,0,0,0,1,1,0,
			0,0,0,0,0,0,0,1,1,0};


static int X[120] =     {1,1,0,0,0,0,0,0,1,1,
			 1,1,0,0,0,0,0,0,1,1,
			 0,1,1,0,0,0,0,1,1,0,
			 0,0,1,1,0,0,1,1,0,0,
			 0,0,1,1,0,0,1,1,0,0,
			 0,0,0,1,1,1,1,0,0,0,  
			 0,0,0,0,1,1,0,0,0,0,
			 0,0,0,1,1,1,1,0,0,0,
			 0,0,1,1,0,0,1,1,0,0,
			 0,1,1,0,0,0,0,1,1,0,
			 1,1,0,0,0,0,0,0,1,1,
			 1,1,0,0,0,0,0,0,1,1};

IA_Image<IA_Point<int>,int>
f(IA_Image<IA_Point<int>,int> image1, IA_Image<IA_Point<int>,int> image2)
{
    IA_Image<IA_Point<int>,int> image3(image1.domain(),0);

    IA_PSIter<IA_Point<int> > iter(image1.domain());

    IA_Point<int> iterp;

    while(iter(iterp))     {
	if(image1(iterp) == 0) 	 {
	    image3[iterp] = image2[iterp];
	}        else	 {
	    if(image1(iterp) > 0)	     {
		image3[iterp] = 1;
	    } 	   else	     {
		image3[iterp] = -1;
	    }
	}
    }

    return image3;
}


IA_Image<IA_Point<int>,int>  corrupt(IA_Image<IA_Point<int>,int> image)
{

    IA_Image<IA_Point<int>,int> corrupted_image(image.domain(),0);

    unsigned short seed[3];
    long seconds;

    seconds = time((long *) 0);
    memcpy(seed, &seconds, sizeof(seconds));

    seed48(seed);

    IA_PSIter<IA_Point<int> > psi(image.domain());
    IA_Point<int> ip;

    while(psi(ip)) {
	if( lrand48() % 10000 < 1000)	    {
	    corrupted_image[ip] = (image[ip] + 1) % 2;
	} else	{
	    corrupted_image[ip] = image[ip];
	}
    }
    return corrupted_image;
}  /* end corrupt */


int random_select(IA_Set<IA_Point<int> > rps, IA_Point<int> &rpt)
{
    int n,pick;
    n = rps.card();

    if(n == 0)     {
	return 0;
    }   else     {
	pick = int (lrand48() % n);
	rpt = rps.index(pick);
	return 1;
    }
}


class hop_temp_image: public IA_ClosureI<IA_Point<int>,int>  {
private:
    IA_Point<int> h_i;
    IA_Image<IA_Point<int>,int> h_e;

public:
    hop_temp_image(IA_Set<IA_Point<int> > ps,
		   IA_Image<IA_Point<int>,int> e,
		   const IA_Point<int>& i):
    IA_ClosureI<IA_Point<int>,int>(ps) {
	h_e = e;
	h_i = i;
    }

    int operator() (const IA_Point<int>& j) const  {
	return h_e(IA_Point<int>(h_i[0],j[0]));
    }   

    IA_ClosureI<IA_Point<int>,int> *clone_self() const {
	return new hop_temp_image(*this);
    }
};

  
class hop_temp: public IA_ClosureDT<IA_Image<IA_Point<int>,int> >  {
private:
    IA_Set<IA_Point<int> > ps;
    IA_Image<IA_Point<int>,int> e;

public:
    hop_temp(const IA_Set<IA_Point<int> >& _ps, IA_Image<IA_Point<int>,int> _e)
    :IA_ClosureDT<IA_Image<IA_Point<int>,int> >(_ps),e(_e),ps(_ps){}

    IA_Image<IA_Point<int>,int> operator() (const IA_Point<int>& i) const {
	return IA_Image<IA_Point<int>,int>(hop_temp_image(ps,e,i));
    }
        
    IA_ClosureDT<IA_Image<IA_Point<int>,int> > *clone_self() const {
	return new hop_temp(*this);
    }
};


IA_Image<IA_Point<int>,int>
crank(IA_Image<IA_Point<int>,int> a,IA_Image<IA_Point<int>,int> ee)
{
    IA_Set<IA_Point<int> > inps(IA_Point<int>(0),IA_Point<int>(119));
    IA_Image<IA_Point<int>,int> aa(inps,0),cc(inps,0);

    int u,v;

    for(u=0;u<12;u++)       {
	for(v=0;v<10;v++)	  {
	    aa[IA_Point<int>(10*u+v)] = a[IA_Point<int>(u,v)];
	}
    }

    IA_Image<IA_Point<int>,int> b(aa.domain(),0);
    hop_temp t(aa.domain(),ee);

    IA_Point<int> pt;
    IA_Set<IA_Point<int> > yps;

    int count = 0;
    while(aa != b)      {
	cout << "crank0\n"; cout.flush();
	yps = aa.domain();

	b = aa;
	while(random_select(yps,pt))	  {
	    if(count % 120 == 0)	      {
		cout << "crank\n"; cout.flush();
	    }
	    count++;
#if 0
	    cc = f(linear_product(aa,t),aa);
#else
	    IA_Set<IA_Point<int> > ips( pt );
	    cc = f( linear_product(aa,t, ips),
		    aa.restrict( ips ) );
#endif
	    aa[pt] = cc[pt];
	    yps /= IA_Set<IA_Point<int> >(pt);
	}
    }


    IA_Set<IA_Point<int> > outps(IA_Point<int>(0,0),IA_Point<int>(11,9));

    IA_Image<IA_Point<int>,int> out(outps,0);

    for(u=0;u<12;u++)      {
	for(v=0;v<10;v++)	  {
	    out[IA_Point<int>(u,v)] = aa[IA_Point<int>(10*u+v)];
	}
    }
    return out;
}


main() {
    IA_Set<IA_Point<int> >
	eps(IA_Point<int>(0,0),IA_Point<int>(11,9)),
	eps1(IA_Point<int>(0),IA_Point<int>(119));

    IA_Image<IA_Point<int>,int>
	e0(eps,one,120),
	e1(eps,two,120),
	e2(eps,three,120),
	e3(eps,four,120),
	e4(eps,nine,120),
	e5(eps,X,120);

    IA_Image<IA_Point<int>,int>
	e0f(eps1,one,120),
	e1f(eps1,two,120),
	e2f(eps1,three,120),
	e3f(eps1,four,120),
	e4f(eps1,nine,120),
	e5f(eps1,X,120);

    e0f = 2*e0f - 1;
    e1f = 2*e1f - 1;
    e2f = 2*e2f - 1;
    e3f = 2*e3f - 1;
    e4f = 2*e4f - 1;
    e5f = 2*e5f - 1;

    IA_Set<IA_Point<int> > eps2(IA_Point<int>(0,0),IA_Point<int>(119,119));

    IA_Image<IA_Point<int>,int> e(eps2,0);  // The weight image

    int i,j;
    for(i=0;i<120;i++) {
	for(j=0;j<120;j++) {
	    if(i != j) {
		e[IA_Point<int>(i,j)] =
		    e0f(IA_Point<int>(i))*e0f(IA_Point<int>(j))
		    + e1f(IA_Point<int>(i))*e1f(IA_Point<int>(j))
		    +e2f(IA_Point<int>(i))*e2f(IA_Point<int>(j))
		    +e3f(IA_Point<int>(i))*e3f(IA_Point<int>(j))
		    +e4f(IA_Point<int>(i))*e4f(IA_Point<int>(j))
		    +e5f(IA_Point<int>(i))*e5f(IA_Point<int>(j));
	    }
	}
    }

    scale_to_uchar( e ).write_PGM( "dsp_weights.pgm" );

    char choice;
    choice = ' ';

    IA_Image<IA_Point<int>,int> a;


    printf("Hopfield Neural Net Simulation\n");
    printf("Select an input pattern from 1, 2, 3, 4, 9, X.      q = Exit\n");

    while((choice = getchar()) != 'q')  {
	getchar();
	switch(choice) 	{
	case '1':
//	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(e0,1)));
	    a = corrupt(e0);
//	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(a,1)));
	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(crank(a,e),1)));
	    break;
	case '2':
//	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(e1,1)));
	    a = corrupt(e1);
//	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(a,1)));
	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(crank(a,e),1)));
	    break;
        case '3':
//	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(e2,1)));
	    a = corrupt(e2);
//	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(a,1)));
	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(crank(a,e),1)));
	    break;
	case '4':
//	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(e3,1)));
	    a = corrupt(e3);
//	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(a,1)));
	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(crank(a,e),1)));
	    break;
	case '9':
//	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(e4,1)));
	    a = corrupt(e4);
//	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(a,1)));
	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(crank(a,e),1)));
	    break;
	case 'x':
	case 'X':
//	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(e5,1)));
	    a = corrupt(e5);
//	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(a,1)));
	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(crank(a,e),1)));
	    break;
	case 'q': printf("Bye\n");
	    break;
	default:
	    printf("Can't deal with that character.\n\n");
	    break;
	}
	printf("Another ?      Choices: 1, 2, 3, 4, 9, X        q = Exit\n");
    }
}
@


1.1
log
@Initial revision
@
text
@a4 7
//#include<stdio.h>
//#include<string.h>
//#include<stdlib.h>
//#include<sys/types.h>
//#include<sys/time.h>

//#include "imagealgebra.h"
d13 3
d234 1
d240 1
a240 1
	    b = aa;
d242 5
d296 1
a296 1
    IA_Image<IA_Point<int>,int> e(eps2,0);
d299 3
a301 3
    for(i=0;i<120;i++)      {
	for(j=0;j<120;j++)	  {
	    if(i != j)	      {
d303 6
a308 6
		    e0f[IA_Point<int>(i)]*e0f[IA_Point<int>(j)]
		    + e1f[IA_Point<int>(i)]*e1f[IA_Point<int>(j)]
		    +e2f[IA_Point<int>(i)]*e2f[IA_Point<int>(j)]
		    +e3f[IA_Point<int>(i)]*e3f[IA_Point<int>(j)]
		    +e4f[IA_Point<int>(i)]*e4f[IA_Point<int>(j)]
		    +e5f[IA_Point<int>(i)]*e5f[IA_Point<int>(j)];
d313 2
d328 1
a328 1
	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(e0,1)));
d330 1
a330 1
	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(a,1)));
d334 1
a334 1
	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(e1,1)));
d336 1
a336 1
	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(a,1)));
d340 1
a340 1
	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(e2,1)));
d342 1
a342 1
	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(a,1)));
d346 1
a346 1
	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(e3,1)));
d348 1
a348 1
	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(a,1)));
d352 1
a352 1
	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(e4,1)));
d354 1
a354 1
	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(a,1)));
d359 1
a359 1
	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(e5,1)));
d361 1
a361 1
	    display(IA_Image<IA_Point<int>,u_char>(chi_ge(a,1)));
@
