def update(self, X, Y, a):
        layers = self.layers
        epsilon = self.epsilon
        length = len(layers)
        
        # decode vector theta
        theta = np.empty((length-1),dtype=object)
        theta_vec = self.theta
        
        flag = 0        
        for i in range(0,length-1):
            size = layers[i+1] * (layers[i]+1)
            theta[i]=theta_vec[flag:(flag+size)].reshape(layers[i+1],-1)
            flag = flag+size
        
        # record vector for converge condition
        grad = np.empty((length-1), dtype=object)
        derivative = np.empty((length-1),dtype=object)
        
        # perform forward propogation
        error = np.empty((length),dtype=object)

        # activation 0~ l-1, with bias node
        activation = self.activation
        error[length-1] = a - Y.reshape(-1,1)
        # calculate error for each layer
        for j in range(length-2,0,-1):
            p1 = np.dot(theta[j].T,error[j+1])
            p2 = np.multiply(activation[j], (1-activation[j]))
            error[j]= np.multiply(p1,p2)
            if j > 1:
                error[j]= error[j][1:]
        
        #IMPORTANT: This step makes the network only update from non-zero observed outputs. Typical NN's do not do this.
        error[length-1][Y==0.0] == 0.0
        
        # calculate gradient
        grad[length-2] = np.dot(error[length-1],activation[length-2].T)
    
        for k in range(length-3,-1,-1):
            grad[k] = np.dot(error[k+1],activation[k].T)
            if k == 0:
                grad[k] = grad[k][1:,:]

        # compute partial derivative
        for i in range(length-2,-1,-1):
            row, col = theta[i].shape
            temp = np.c_[np.zeros((row,1)),self.regLambda * theta[i][:,1:]]
            derivative[i] = grad[i] + temp

        # update weights
        for i in range(0,length-1):
            theta[i] = theta[i] - self.learningRate * derivative[i]
    
        # unroll matrices into a single vector
        theta_vec = np.array([])
        for i in range(0,length-1):
            theta_vec = np.append(theta_vec, theta[i].flatten())

        # calculate cost func
        self.theta = np.copy(theta_vec)
Constructor for GetInfoAction.
dataset/ETHPy150Open dkotfis/NeuRL/src/nn.py/NeuralNet.update--crossover with--dataset/ETHPy150Open googlearchive/git-rv/getinfo.py/GetInfoAction.__init__