'/
NORMALISATION FOR ANnet FUNCTION

This script contains the normalisation procedure to be used by the 
  ANnet function.

Specifications:
norm()     --> Fun: returns the normalised value of a vector
norm.inv() --> Fun: returns the normalised inversed value of a vector
colMax()   --> Fun: returns the maximum value of a matrix by columns
colMin()   --> Fun: returns the minimum value of a matrix by columns
X          --> The input (scalar, vector or matrix) to be processed

Possible Normalisation Functions
  Feature scaling [0:1]
  Feature scaling [-1:1]
  Standard Score

Author: Arthur Hrast Essenfelder
E-mail: arthur.essenfelder@unive.it

Version: 1.0
Last update on: 04/12/2015
/'


#Loading Libraries & Functions =========================================
#Libraries
# ======================================================================



#Normalisation Function ------------------------------------------------
norm = function(Input.Data, Norm.Method, Xmax, Xmin, Xmean, XstDev) {
  
  #Get values
  X = Input.Data;
  m = NROW(X);
  n = NCOL(X);
  
  #Checking for missing parameters
  if (missing(Xmax))   { Xmax   = colMax(X); }
  if (missing(Xmin))   { Xmin   = colMin(X); }
  if (missing(Xmean))  { Xmean  = colMeans(X); }
  if (missing(XstDev)) { library("fBasics"); XstDev = colStdevs(X); }
  
  #Converting to a matrix input
  Xmax   = matrix(Xmax,    m, n, byrow=TRUE);
  Xmin   = matrix(Xmin,    m, n, byrow=TRUE);
  Xmean  = matrix(Xmean,   m, n, byrow=TRUE);
  XstDev = matrix(XstDev,  m, n, byrow=TRUE);
  
  #Calculating the normalised values
  if (Norm.Method == "Feature scaling [0:1]") {
    norm = ((X - Xmin) / (Xmax - Xmin)); 
  } else if (Norm.Method == "Feature scaling [-1:1]") {
    norm = 2. * ((X - Xmin) / (Xmax - Xmin)) - 1.;
  } else if (Norm.Method == "Standard Score") {
    norm   = (X - Xmean) / XstDev;
  } else {
    norm = X - X; # ZERO
  }
  
  return(norm);
  
}
#-----------------------------------------------------------------------



#Normalisation Function - Inverse --------------------------------------
norm.inv = function(Input.Data, Norm.Method, Xmax, Xmin, Xmean, XstDev) {
  
  #Get values
  X     = Input.Data;
  m     = NROW(X);
  n     = NCOL(X);
  
  #Checking for missing parameters
  if (Norm.Method == "Feature scaling [0:1]" || 
      Norm.Method == "Feature scaling [-1:1]") {
    if (missing(Xmax) || missing(Xmin)) {
      stop("Error! Missing Xmax and/or Xmin inputs.");
    } else { #Converting to a matrix input
      Xmax   = matrix(Xmax,    m, n, byrow=TRUE);
      Xmin   = matrix(Xmin,    m, n, byrow=TRUE);
    }
  } else if (Norm.Method == "Standard Score") {
    if (missing(Xmean) || missing(XstDev)) {
      stop("Error! Missing Xmean and/or XstDev inputs.");
    } else { #Converting to a matrix input
      Xmean  = matrix(Xmean,   m, n, byrow=TRUE);
      XstDev = matrix(XstDev,  m, n, byrow=TRUE);
    }
  }
  
  #Calculating the normalised values
  if (Norm.Method == "Feature scaling [0:1]") {
    norm.inv = (X * (Xmax - Xmin)) + Xmin;
  } else if (Norm.Method == "Feature scaling [-1:1]") {
    norm.inv = (((X + 1.) * (Xmax - Xmin)) / (2.)) + Xmin;
  } else if (Norm.Method == "Standard Score") {
    norm.inv = (X * XstDev) + Xmean;
  } else {
    norm.inv = X - X; # ZERO
  }
  
  return(norm.inv);
  
}
#-----------------------------------------------------------------------



#colMax Function -------------------------------------------------------
colMax = function(Input.Data) {
  
  #Get values
  X = Input.Data;
  
  #Calculate colMax
  colMax = apply(X, 2, function(x) max(x, na.rm = TRUE));
  
  return (colMax);
  
}
#-----------------------------------------------------------------------



#colMin Function -------------------------------------------------------
colMin = function(Input.Data) {
  
  #Get values
  X = Input.Data;
  
  #Calculate colMax
  colMin = apply(X, 2, function(x) min(x, na.rm = TRUE));
  
  return (colMin);
  
}
#-----------------------------------------------------------------------