def update_weights(inputs, weights, category_num, learn_rate):
    """
    This function returns a new weight matrix which has learned the input for the category and whether or not it was
    changed
    :param inputs: A vector which has the length of the number of features in the network. It contains the signal input
        into the network
    :param weights: A matrix of size num_features-by-num_categories which holds the current weights of the network
    :param category_num: The current category for the encoding of the current input range [0, num_categories)
    :param learn_rate: The learning rate at which the network learns new inputs. [0, 1]
    :return: updated_weights, changed. updated_weights is a matrix of num_features-by-num_categories containing the
        updated weights. changed is a binary number which confers whether or not the weight matrix was changed
    """

    num_features, num_categories = weights.shape

    assert len(inputs) == num_features, 'The length of the inputs and the rows of the weights do not match'
    assert (category_num >= 1) or (category_num < num_categories), \
        'The category must be in the range [1, num_categories]'

    changed = 0
    for i in range(num_features):
        if inputs[i] < weights[i, category_num - 1]:
            weights[i, category_num - 1] = learn_rate * inputs[i] + (1 - learn_rate) * weights[i, category_num - 1]
            changed = 1
    return weights, changed