##Build letter space
D <- matrix(c(1,-1,-1,-1,-1,1,1,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,-1,1,1,1,-1), nrow=5,ncol = 5)
J <- matrix(c(1,-1,-1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,-1,-1),nrow = 5,ncol = 5)
C <- matrix(c(-1,1,1,1,-1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,1,1,-1,-1,-1,1),nrow = 5,ncol = 5)
M <- matrix(c(1,1,1,1,1,-1,1,-1,-1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,1),nrow = 5,ncol = 5)

##Function to draw the letter
show.letter <- function(letter.vector){
  letter.vector[letter.vector == 1] <- "*"
  letter.vector[letter.vector == -1] <- " "
  colnames(letter.vector) <- rep("",5)
  row.names(letter.vector) <- rep("",5)
  print(letter.vector, quote = FALSE)
}

##Draw all the original letters
for (i in mget(ls(pattern = "^[A-Z]"))){show.letter(i)}
##           
##    * * * *
##  *        
##  *        
##  *        
##    * * * *
##           
##  * * * *  
##    *     *
##    *     *
##    *     *
##    * * *  
##           
##  * * * * *
##        *  
##        *  
##  *     *  
##  * * *    
##           
##  *       *
##  * *   * *
##  *   *   *
##  *       *
##  *       *
##Function to distort the letter
mutate <- function(letter.vector, number.pixel.flips){
    letter.vector[sample(length(letter.vector),number.pixel.flips)] <- letter.vector[sample(length(letter.vector),number.pixel.flips)]
    return(letter.vector)
}


mutated.C <- mutate(C, 8)
mutated.D <- mutate(D, 8)
mutated.J <- mutate(J, 8)
mutated.M <- mutate(M, 8)

##Draw all the mutated letters in alphabetical order
for (i in mget(ls(pattern = "mutated"))){show.letter(i)}
##           
##      *   *
##  * *   *  
##  * *      
##  *        
##  * * * * *
##           
##  *   * *  
##    * *   *
##    * *   *
##          *
##    * * *  
##           
##    * * * *
##        *  
##        *  
##  *       *
##  * * *    
##           
##  * *     *
##    *   * *
##  *   * * *
##  *       *
##  *       *
##Store all 4 letter pixels into a 4x25 weight matrix because each of the 4 letters contain 25 pixels. There will be a total of 25 neurons, one for each pixel.
x <- matrix(c(C,D,J,M), nrow = 4, byrow = T)

##The function that uses hebbian learning to restore the mutated letters back to original. 
hopfield <- function(current.letter, iteration, memory = w){
  w <- t(x) %*% x
  diag(w) <- 0
  for(i in 1:iteration){
    a <- w %*% as.vector(current.letter)
    current.letter <- ifelse(a>0, 1, -1)
  }
  return(show.letter(matrix(current.letter, ncol = 5, nrow = 5)))
}


##Draw all the iterations of restoration process
for (i in mget(ls(pattern = "mutated"))){
  for (iter in 1:5){
    hopfield(current.letter = i, iteration = iter)
  }
}
##           
##    * * * *
##  *        
##  *        
##  *        
##    * *   *
##           
##    * * * *
##  *        
##  *        
##  *        
##    * * * *
##           
##    * * * *
##  *        
##  *        
##  *        
##    * * * *
##           
##    * * * *
##  *        
##  *        
##  *        
##    * * * *
##           
##    * * * *
##  *        
##  *        
##  *        
##    * * * *
##           
##  * * * *  
##    *     *
##    *     *
##    *     *
##    * * *  
##           
##  * * * *  
##    *     *
##    *     *
##    *     *
##    * * *  
##           
##  * * * *  
##    *     *
##    *     *
##    *     *
##    * * *  
##           
##  * * * *  
##    *     *
##    *     *
##    *     *
##    * * *  
##           
##  * * * *  
##    *     *
##    *     *
##    *     *
##    * * *  
##           
##  * * * * *
##        *  
##        *  
##  *     *  
##  * * *    
##           
##  * * * * *
##        *  
##        *  
##  *     *  
##  * * *    
##           
##  * * * * *
##        *  
##        *  
##  *     *  
##  * * *    
##           
##  * * * * *
##        *  
##        *  
##  *     *  
##  * * *    
##           
##  * * * * *
##        *  
##        *  
##  *     *  
##  * * *    
##           
##  *       *
##  * *   * *
##  *   *   *
##  *       *
##  *       *
##           
##  *       *
##  * *   * *
##  *   *   *
##  *       *
##  *       *
##           
##  *       *
##  * *   * *
##  *   *   *
##  *       *
##  *       *
##           
##  *       *
##  * *   * *
##  *   *   *
##  *       *
##  *       *
##           
##  *       *
##  * *   * *
##  *   *   *
##  *       *
##  *       *