import numpy as np

def build_k_indices(y, k_fold, seed):
    """Function to build k indices for k-fold.

    Args:
        y      (numpy array): Matrix output of size N x 1.
        k_fold (int)        : The value k, of k-fold cross validation.
        seed   (int)        : Integer value to seed the random generator.

    Returns:
        k_indices (numpy array) : Matrix of K x floor(N/K), as indices for unbiased test error of K-cross Validation.
    """

    num_row    = y.shape[0]
    interval   = int(num_row / k_fold)
    np.random.seed(seed)
    indices    = np.random.permutation(num_row)
    k_indices  = np.array([indices[k * interval: (k + 1) * interval]
                 for k in range(k_fold)])
    return k_indices

def cross_validation(y, x, k_indices, k):
    """Function to split training data and test data using K-cross validation based on given k_indices.

    Args:
        y         (numpy array): Matrix output of size N x 1.
        tx        (numpy array): Matrix input of size N x D.
        k_indices (numpy array): Matrix of K x floor(N/K), as indices for unbiased test error of K-cross Validation.
        k         (int)        : For choosing index in the k_indices

    Returns:
        x_train (numpy array) : Matrix input (features) for training set with size of (ratio*N) x D.
        y_train (numpy array) : Matrix output for training set with size of (ratio*N) x 1.
        x_test  (numpy array) : Matrix input (features) for testing set with size of ((1-ratio)*N) x D.
        y_test  (numpy array) : Matrix output for testing set with size of ((1-ratio)*N) x 1.
    """
    
    train_set_indices               = np.ones(x.shape[0], dtype = bool)
    train_set_indices[k_indices[k]] = False

    x_train = x[train_set_indices]
    y_train = y[train_set_indices]
    
    x_test  = x[k_indices[k]]
    y_test  = y[k_indices[k]]
    
    return x_train, y_train, x_test, y_test

import numpy as np

def build_k_indices(y, k_fold, seed):
    """Function to build k indices for k-fold.

    Args:
        y      (numpy array): Matrix output of size N x 1.
        k_fold (int)        : The value k, of k-fold cross validation.
        seed   (int)        : Integer value to seed the random generator.

    Returns:
        k_indices (numpy array) : Matrix of K x floor(N/K), as indices for unbiased test error of K-cross Validation.
    """

    num_row    = y.shape[0]
    interval   = int(num_row / k_fold)
    np.random.seed(seed)
    indices    = np.random.permutation(num_row)
    k_indices  = np.array([indices[k * interval: (k + 1) * interval]
                 for k in range(k_fold)])
    return k_indices

def cross_validation(y, x, k_indices, k):
    """Function to split training data and test data using K-cross validation based on given k_indices.

    Args:
        y         (numpy array): Matrix output of size N x 1.
        tx        (numpy array): Matrix input of size N x D.
        k_indices (numpy array): Matrix of K x floor(N/K), as indices for unbiased test error of K-cross Validation.
        k         (int)        : For choosing index in the k_indices

    Returns:
        x_train (numpy array) : Matrix input (features) for training set with size of (ratio*N) x D.
        y_train (numpy array) : Matrix output for training set with size of (ratio*N) x 1.
        x_test  (numpy array) : Matrix input (features) for testing set with size of ((1-ratio)*N) x D.
        y_test  (numpy array) : Matrix output for testing set with size of ((1-ratio)*N) x 1.
    """
    
    train_set_indices               = np.ones(x.shape[0], dtype = bool)
    train_set_indices[k_indices[k]] = False

    x_train = x[train_set_indices]
    y_train = y[train_set_indices]
    
    x_test  = x[k_indices[k]]
    y_test  = y[k_indices[k]]
    
    return x_train, y_train, x_test, y_test

Function to build k indices for k-fold.      Args:         y      (numpy array): Matrix output of size N x 1.         k_fold (int)        : The value k, of k-fold cross validation.         seed   (int)        : Integer value to seed the random generator.      Returns:         k_indices (numpy array) : Matrix of K x floor(N/K), as indices for unbiased test error of K-cross Validation. Function to split training data and test data using K-cross validation based on given k_indices.      Args:         y         (numpy array): Matrix output of size N x 1.         tx        (numpy array): Matrix input of size N x D.         k_indices (numpy array): Matrix of K x floor(N/K), as indices for unbiased test error of K-cross Validation.         k         (int)        : For choosing index in the k_indices      Returns:         x_train (numpy array) : Matrix input (features) for training set with size of (ratio*N) x D.         y_train (numpy array) : Matrix output for training set with size of (ratio*N) x 1.         x_test  (numpy array) : Matrix input (features) for testing set with size of ((1-ratio)*N) x D.         y_test  (numpy array) : Matrix output for testing set with size of ((1-ratio)*N) x 1.