     case InvalidWeightsError(String)
 }
 
-
-/// This enum will hold all the supported Activation Functions
-public enum ActivationFunction {
-    
-    case None
-    case Sigmoid
-    case Linear
-    case Gaussian
-    case RationalSigmoid
-    case HyperbolicTangent
-    
-}
-
-///Struct that evaluates an activation function
-public struct ActivationFunctionEvaluator {
-    
-    /// evaluate an activation function with the specific input
-    /// - Parameters:
-    ///     - aFunc: is the Transfer function to be excuted
-    ///     - input: the input of the activation function
-    static func evaluate(aFunc: ActivationFunction, input:Float) -> Float {
-        
-        switch aFunc {
-            
-        case .None :
-            return 0.0
-        case .Linear:
-            return linear(input)
-        case .Sigmoid:
-            return sigmoid(input)
-        case .Gaussian:
-            return gaussian(input)
-        case .RationalSigmoid:
-            return rationalSigmoid(input)
-        case .HyperbolicTangent:
-            return hyperbolicTangent(input)
-            
-        }
-    }
-    
-    
-    
-    /// evaluate the derivative of an activation function with the specific input
-    /// - Parameters:
-    ///     - aFunc: is the Transfer function to be excuted
-    ///     - input: the input of the activation function
-    static func evaluateDerivative(aFunc: ActivationFunction, input:Float) -> Float {
-        
-        
-        switch aFunc {
-            
-        case .None :
-            return 0.0
-        case .Linear:
-            return linearDerivative(input)
-        case .Sigmoid:
-            return sigmoidDerivative(input)
-        case .Gaussian:
-            return gaussianDerivative(input)
-        case .RationalSigmoid:
-            return rationalSigmoidDerivative(input)
-        case .HyperbolicTangent:
-            return hyperbolicTangentDerivative(input)
-        }
-    }
-    
-    
-    /*Transfer function and definitions */
-    
-    static private func sigmoid(x:Float) -> Float {
-        
-        return 1 / (1 + exp(-x))
-    }
-    
-    static private func sigmoidDerivative(x:Float) -> Float {
-        
-        return sigmoid(x) * (1 - sigmoid(x))
-    }
-    
-    
-    static private func linear(x:Float) -> Float {
-        
-        return x
-    }
-    
-    static private func linearDerivative(x:Float) -> Float {
-        
-        return 1.0
-    }
-    
-    
-    static private func gaussian(x:Float) -> Float {
-        
-        return exp(-pow(x, 2.0))
-    }
-    
-    
-    static private func gaussianDerivative(x:Float) -> Float {
-        
-        return -2.0 * gaussian(x) * x
-    }
-    
-    static private func rationalSigmoid(x:Float) -> Float {
-        
-        return x / (1.0 + sqrt(1.0 + x * x))
-    }
-    
-    
-    static private func rationalSigmoidDerivative(x:Float) -> Float {
-        
-        let val = sqrt(1.0 + x * x)
-        
-        return 1.0 / (val * (1.0 + val))
-    }
-    
-    static private func hyperbolicTangent(x:Float) -> Float {
-        
-        return tanh(x)//(1 - exp(-2 * x))/(1 + exp(-2 * x))
-    }
-    
-    
-    static private func hyperbolicTangentDerivative(x:Float) -> Float {
-        
-        return 1.0 / pow(cosh(x), 2.0)
-    }
-}
-
-
+/// A 3-Layer Feed-Forward Artificial Neural Network
 public final class FFNN {
     
     /// The number of input nodes to the network (read only).

    }
    
    /// Trains the network by comparing its most recent output to the given 'answers', adjusting the network's weights as needed.
    /// - parameter answer: The 'correct' desired output for the most recent update to the network, as an array of `Float`s.
    /// - returns: The total calculated error from the most recent update.
    public func backpropagate(answer answer: [Float]) throws -> Float {
        // Verify valid answer
        guard answer.count == self.numOutputs else {

        let randomFloat = Float(arc4random_uniform(rangeInt)) - Float(rangeInt / 2)
        return randomFloat / 1_000_000
    }
}

/// An enum containing all supported activation functions.
public enum ActivationFunction {
    /// No activation function (returns zero)
    case None
    /// Default activation function (sigmoid)
    case Default
    /// Linear activation function (raw sum)
    case Linear
    /// Sigmoid activation function
    case Sigmoid
    /// Gaussian activation function
    case Gaussian
    /// Rational sigmoid activation function
    case RationalSigmoid
    /// Hyperbolic tangent activation function
    case HyperbolicTangent
}

/// Struct that evaluates an activation function
private struct ActivationFunctionEvaluator {
    
    /// Evaluates an activation function with the specific input.
    /// - Parameters:
    ///     - aFunc: The activation function to be excuted.
    ///     - input: The input of the activation function.
    static func evaluate(aFunc: ActivationFunction, input:Float) -> Float {
        switch aFunc {
        case .None:
            return 0.0
        case .Default:
            return sigmoid(input)
        case .Linear:
            return linear(input)
        case .Sigmoid:
            return sigmoid(input)
        case .Gaussian:
            return gaussian(input)
        case .RationalSigmoid:
            return rationalSigmoid(input)
        case .HyperbolicTangent:
            return hyperbolicTangent(input)
        }
    }
    
    /// Evaluates the derivative of an activation function with the specific input.
    /// - Parameters:
    ///     - aFunc: The desired activation function.
    ///     - input: The value at which to calculate the activation function's derivative.
    static func evaluateDerivative(aFunc: ActivationFunction, input:Float) -> Float {
        switch aFunc {
        case .None:
            return 0.0
        case .Default:
            return sigmoidDerivative(input)
        case .Linear:
            return linearDerivative(input)
        case .Sigmoid:
            return sigmoidDerivative(input)
        case .Gaussian:
            return gaussianDerivative(input)
        case .RationalSigmoid:
            return rationalSigmoidDerivative(input)
        case .HyperbolicTangent:
            return hyperbolicTangentDerivative(input)
        }
    }
    
    
    // MARK: Activation Functions and Derivatives
    
    /// Sigmoid activation function
    static private func sigmoid(x:Float) -> Float {
        return 1 / (1 + exp(-x))
    }
    /// Derivative for the sigmoid activation function
    static private func sigmoidDerivative(x:Float) -> Float {
        return sigmoid(x) * (1 - sigmoid(x))
    }
    
    /// Linear activation function (raw sum)
    static private func linear(x:Float) -> Float {
        return x
    }
    
    /// Derivative for the linear activation function
    static private func linearDerivative(x:Float) -> Float {
        return 1.0
    }
    
    /// Gaussian activation function
    static private func gaussian(x:Float) -> Float {
        return exp(-(x * x))
    }
    
    /// Derivative for the Gaussian activation function
    static private func gaussianDerivative(x:Float) -> Float {
        return -2.0 * gaussian(x) * x
    }
    
    /// Rational sigmoid activation function
    static private func rationalSigmoid(x:Float) -> Float {
        return x / (1.0 + sqrt(1.0 + x * x))
    }

    /// Derivative for the rational sigmoid activation function
    static private func rationalSigmoidDerivative(x:Float) -> Float {
        let val = sqrt(1.0 + x * x)
        return 1.0 / (val * (1.0 + val))
    }
    
    /// Hyperbolic tangen activation function
    static private func hyperbolicTangent(x:Float) -> Float {
        return tanh(x)//(1 - exp(-2 * x))/(1 + exp(-2 * x))
    }
    
    /// Derivative for the hyperbolic tangent activation function
    static private func hyperbolicTangentDerivative(x:Float) -> Float {
        return 1.0 / (cosh(x) * cosh(x))
    }
    
}
