      PROGRAM hopfield
      IMPLICIT NONE
      INTEGER N, T(50,50)
      LOGICAL Ltmp1_
      DATA T/2500*0/
      CALL memorize(T,N)
      Ltmp1_ = .TRUE.
      DO WHILE(Ltmp1_)
         CALL recall(T,N)
      END DO
      END
C
      SUBROUTINE memorize(T,N)
      IMPLICIT NONE
      REAL dmy, rnd
      INTEGER V(50), i, j, M, memory, T(50,50), N
      CHARACTER s*80
      dmy = rnd(-1)
      WRITE(*,'(A,$)') 'number of stored memories = '
      READ(*,*) M
*     N corresponds to number of neurons
      WRITE(*,'(A,$)') 'size of memories = '
      READ(*,*) N
      WRITE(*,*) 'enter M strings of N 0''s and 1''s'
      DO memory = 1, M
         WRITE(*,'(A,$)') '? '
         READ(*,'(A)') s
         CALL convert(s,N,V)
         DO i = 1, N
            DO j = 1, N
               IF(i .NE. j) THEN
                  T(i,j) = T(i,j) + (2*V(i) - 1)*(2*V(j) - 1)
               END IF
            END DO
         END DO
      END DO
      WRITE(*,*)
      END
C
      SUBROUTINE recall(T,N)
      IMPLICIT NONE
      REAL rnd
      INTEGER V(50), i, j, kbhit, k, sum, T(50,50), N
      CHARACTER s*80,kk
      LOGICAL Ltmp1_
      WRITE(*,*) 'enter a string of N 0''s and 1''s'
      WRITE(*,'(A,$)') '? '
      READ(*,'(A)') s
      CALL convert(s,N,V)
      Ltmp1_ = .TRUE.
      DO WHILE(Ltmp1_)
         DO k = 1, N
            i = int(N*rnd(0)) + 1           ! choose neuron at random
            sum = 0
            DO j = 1, N
               IF(i .NE. j) sum = sum + T(i,j)*V(j)
            END DO
            IF(sum .GT. 0) THEN
               V(i) = 1                     ! above threshold 
            ELSE
               V(i) = 0                     ! below threshold 
            END IF
         END DO
         DO i = 1, N
            WRITE(*, '(I1,$)') V(i)
         ENDDO
         WRITE(*,*)
         CALL sleep(1000)
         Ltmp1_ = kbhit() .EQ. 0
      END DO
      READ(*,'(A)') kk
      if(kk .EQ. 's') STOP
      END
C
      SUBROUTINE convert(s,N,V)
*     convert string to array of 0's and 1's
      IMPLICIT NONE
      INTEGER N, i, V(50)
      CHARACTER c, s*80
      DO i = 1, N
         c = s(i:i)
         IF(c .EQ. '0') THEN
            V(i) = 0
         ELSE
            V(i) = 1
         END IF
      END DO
      END
