         }
         return errorSum
     }
-    
-    /// Applies the activation function to the hidden layer nodes.
-    private func activateHidden() {
-        switch self.activationFunction {
-        case .None:
-            for (var i = self.numHidden; i > 0; --i) {
-                self.hiddenOutputCache[i] = 0.0
-            }
-            self.hiddenOutputCache[0] = 1.0
-        case .Default:
-            for (var i = self.numHidden; i > 0; --i) {
-                self.hiddenOutputCache[i] = sigmoid(self.hiddenOutputCache[i - 1])
-            }
-            self.hiddenOutputCache[0] = 1.0
-        case .Linear:
-            for (var i = self.numHidden; i > 0; --i) {
-                self.hiddenOutputCache[i] = linear(self.hiddenOutputCache[i - 1])
-            }
-            self.hiddenOutputCache[0] = 1.0
-        case .Sigmoid, .Softmax:
-            // For Softmax, apply Sigmoid activation for hidden layers
-            for (var i = self.numHidden; i > 0; --i) {
-                self.hiddenOutputCache[i] = sigmoid(self.hiddenOutputCache[i - 1])
-            }
-            self.hiddenOutputCache[0] = 1.0
-        case .RationalSigmoid:
-            for (var i = self.numHidden; i > 0; --i) {
-                self.hiddenOutputCache[i] = rationalSigmoid(self.hiddenOutputCache[i - 1])
-            }
-            self.hiddenOutputCache[0] = 1.0
-        case .HyperbolicTangent:
-            for (var i = self.numHidden; i > 0; --i) {
-                self.hiddenOutputCache[i] = hyperbolicTangent(self.hiddenOutputCache[i - 1])
-            }
-            self.hiddenOutputCache[0] = 1.0
-        }
-    }
-    
-    /// Applies the activation function to the output layer nodes.
-    private func activateOutput() {
-        switch self.activationFunction {
-        case .None:
-            for i in 0..<self.numOutputs {
-                self.outputCache[i] = 0.0
-            }
-        case .Default:
-            for i in 0..<self.numOutputs {
-                self.outputCache[i] = sigmoid(self.outputCache[i])
-            }
-        case .Linear:
-            for i in 0..<self.numOutputs {
-                self.outputCache[i] = linear(self.outputCache[i])
-            }
-        case .Sigmoid:
-            for i in 0..<self.numOutputs {
-                self.outputCache[i] = sigmoid(self.outputCache[i])
-            }
-        case .Softmax:
-            var sum: Float = 0
-            let max = self.outputCache.maxElement()!
-            for i in 0..<self.numOutputs {
-                self.outputCache[i] = self.outputCache[i] - max
-            }
-            for i in 0..<self.numOutputs {
-                self.outputCache[i] = exp(self.outputCache[i])
-                sum += self.outputCache[i]
-            }
-            for i in 0..<self.numOutputs {
-                self.outputCache[i] = self.outputCache[i] / sum
-            }
-        case .RationalSigmoid:
-            for i in 0..<self.numOutputs {
-                self.outputCache[i] = rationalSigmoid(self.outputCache[i])
-            }
-        case .HyperbolicTangent:
-            for i in 0..<self.numOutputs {
-                self.outputCache[i] = hyperbolicTangent(self.outputCache[i])
-            }
-        }
-    }
-    
-    /// Calculates the derivative of the activation function, from the given `y` value.
-    private func activationDerivative(output: Float) -> Float {
-        switch self.activationFunction {
-        case .None:
-            return 0.0
-        case .Default:
-            return sigmoidDerivative(output)
-        case .Linear:
-            return linearDerivative(output)
-        case .Sigmoid:
-            return sigmoidDerivative(output)
-        case .Softmax:
-            return sigmoidDerivative(output)
-        case .RationalSigmoid:
-            return rationalSigmoidDerivative(output)
-        case .HyperbolicTangent:
-            return hyperbolicTangentDerivative(output)
-        }
-    }
+
     
     /// Randomizes all of the network's weights, from each layer.
     private func randomizeWeights() {
         for i in 0..<self.numHiddenWeights {
-            self.hiddenWeights[i] = randomWeight(numInputNodes: self.numInputNodes)
+            hiddenLayer.matrix[i] = randomWeight(numInputNodes: self.numInputNodes)
         }
         for i in 0..<self.numOutputWeights {
-            self.outputWeights[i] = randomWeight(numInputNodes: self.numHiddenNodes)
+            outputLayer.matrix[i] = randomWeight(numInputNodes: self.numHiddenNodes)
         }
     }
 

            self.inputIndices.append(weightIndex % self.numInputNodes)
        }
        
        self.hiddenWeights = [Float](count: self.numHiddenWeights, repeatedValue: 0)
        self.previousHiddenWeights = self.hiddenWeights
        self.outputWeights = [Float](count: outputs * self.numHiddenNodes, repeatedValue: 0)
        self.previousOutputWeights = self.outputWeights
        
        if let weights = weights {
            guard weights.count == numHiddenWeights + numOutputWeights else {

            for (inputIndex, input) in result.enumerate() {
                let outputs = try self.update(inputs: input)
                for (outputIndex, output) in outputs.enumerate() {
                    errorSum += abs(actFunction.derivative(output) * (expected[inputIndex][outputIndex] - output))
                }
            }
            if average {
