text:
import numpy as np
import pickle
import os
import csv # write_carry_dataset_statistics
import pandas as pd # plot_carry_dataset_statistics
import matplotlib.pyplot as plt # plot_carry_dataset_statistics
import random # import_random_sampled_carry_datasets
import config

def create_dir(directory):
    if not os.path.exists(directory):
        os.makedirs(directory)

def get_result_digits(operand_digits, operator, result_mode='fit'):
    if result_mode == 'fit':
        if operator == 'add':
            result_digits = operand_digits + 1
        if operator == 'subtract':
            result_digits = operand_digits
        if operator == 'multiply':
            result_digits = operand_digits * 2
        if operator == 'divide':
            result_digits = operand_digits
        if operator == 'modulo':
            result_digits = operand_digits

    if result_mode == 'same':
        result_digits = operand_digits * 2 # The maximum result digits
    return result_digits

def get_str_bin(int_dec):
    '''
    Parameters
    ----------
    int_dec: int. a decimal number.

    Returns
    -------
    str_bin: str. the string of int_dec
    - If int_dec >=0, then no sign character in str_bin.
    - If int_dec < 0, then '-' becomes the first character of str_bin.
    '''
    if int_dec >= 0:
        str_bin = bin(int_dec)[2:]
    else:
        str_bin =  bin(int_dec)[0] + bin(int_dec)[3:]
    return str_bin

def get_int_dec(str_bin):
    '''
    Parameters
    ----------
    str_bin : str. the string of a binary number

    Returns
    -------
    int_dec : int. decimal interger.
    '''
    int_dec = int(str_bin, 2)
    return int_dec

def get_op_symbol(operator):
    if operator == 'add':
        return '+'
    elif operator == 'subtract':
        return '-'
    elif operator == 'multiply':
        return '*'
    elif operator == 'divide':
        return '/'
    elif operator == 'modulo':
        return r'%'
    else:
        return None

def get_np_bin(str_bin, np_bin_digits):
    '''
    Parameters
    ----------
    str_bin

    Return
    ------
    np_bin: numpy.ndarry. binary number. The smaller index, the higher digit.
    '''
    assert str_bin[0] != '-'

    np_bin = np.zeros((np_bin_digits), dtype=config.np_type()) # Should be initialized as 0.

    for i in range(1, len(str_bin)+1):
        np_bin[-i] = int(str_bin[-i])

    return np_bin

def get_leading_zeros(operand):
    '''
    Parameters
    ----------
    operand : np.ndarray. 1-dimension. shape==(operand_digits).

    Returns
    -------
    n_leading_zeros : int. The number of leading zeros.
    - If operand is [0,0,1,1,0,1], the number of leading zeros is 2.
    '''
    operand_digits = operand.shape[0]
    n_leading_zeros = 0
    for i in range(operand_digits):
        if operand[i] == 0:
            n_leading_zeros = n_leading_zeros + 1
        else:
            break
    return n_leading_zeros

def get_carry_ds_stat_path():
    carry_ds_stat_path = '{}/{}'.format(config.dir_data(), config.carry_dataset_statistics_name())
    return carry_ds_stat_path

def get_KL_fold_CV_sets(np_input, np_target, i_iteration, n_outer_folds=5, n_inner_folds=5):
    '''
    Parameters
    -----
    np_input : numpy.ndarray. shape=(n_examples, dim_input).
    np_target : numpy.ndarray. shape=(n_examples, dim_target).
    i_iteration : The iteration index of cross validation.
     - i_iteration should range from 0 to (n_outer_folds * n_inner_folds - 1)
    n_outer_folds : int. The number of outer folds.
    n_inner_folds : int. The number of inner folds.

    Returns
    -----
    (input_train, input_dev, input_test, target_train, target_dev, target_test) :
     - For each element, numpy.ndarray. shape=(n_examples, dim).
    '''
    if (i_iteration < 0) or (i_iteration >= n_outer_folds * n_inner_folds):
        raise ValueError("i_iteration should range from 0 to (n_outer_folds * n_inner_folds - 1)")

    # Get the indices of outer folds and inner folds.
    i_outer_fold = i_iteration // n_outer_folds
    i_inner_fold = i_iteration % n_outer_folds

    ds_size = np_input.shape[0]
    outer_fold_size = ds_size // n_outer_folds
    inner_fold_size = (ds_size - outer_fold_size) // n_inner_folds

    # Get the start and end indices of the test set.
    i_start_test = i_outer_fold * outer_fold_size
    if i_outer_fold < n_outer_folds - 1:
        i_end_test = (i_outer_fold + 1) * outer_fold_size
    else:
        # Without this flow control, the remainders are never included in the test set.
        i_end_test = ds_size

    # Get the test set.
    input_test = np_input[i_start_test:i_end_test,:]
    target_test = np_target[i_start_test:i_end_test,:]

    # Get the inner dataset
    inner_input_dataset = np.concatenate((np_input[:i_start_test,:], np_input[i_end_test:,:]), axis=0)
    inner_target_dataset = np.concatenate((np_target[:i_start_test,:], np_target[i_end_test:,:]), axis=0)

    # Get the inner fold size
    inner_ds_size = inner_input_dataset.shape[0]
    inner_fold_size = inner_ds_size // n_inner_folds

    # Get the start and end indices of the dev set.
    i_start_dev = i_inner_fold * inner_fold_size
    i_end_dev = (i_inner_fold + 1) * inner_fold_size

    # Get the dev set.
    input_dev = inner_input_dataset[i_start_dev:i_end_dev,:]
    target_dev = inner_target_dataset[i_start_dev:i_end_dev,:]

    # Get the train set.
    input_train = np.concatenate((inner_input_dataset[:i_start_dev,:], inner_input_dataset[i_end_dev:,:]), axis=0)
    target_train = np.concatenate((inner_target_dataset[:i_start_dev,:], inner_target_dataset[i_end_dev:,:]), axis=0)

    return (input_train, input_dev, input_test,
            target_train, target_dev, target_test)

def get_KL_fold_CV_sets_from_carry_datasets(operand_digits, operator, i_iteration, n_outer_folds=5, n_inner_folds=5):
    '''
    Parameters
    -----
    operand_digits : int. The number of each operand digits.
    operator : str. One of 'add', 'subtract', 'multiply', 'divide', 'modulo'
    i_iteration : The iteration index of cross validation.
     - i_iteration should range from 0 to (n_outer_folds * n_inner_folds - 1)
    n_outer_folds : int. The number of outer folds.
    n_inner_folds : int. The number of inner folds.

    Returns
    -----
    (input_train, input_dev, input_test, target_train, target_dev, target_test) :
     - For each element, numpy.ndarray. shape=(n_examples, dim).
    splited_carry_datasets : dict.
     - {n_carries:
            {'input': {'train': numpy.ndarray,
                        'dev': numpy.ndarray,
                        'test': numpy.ndarray},
            'output': {'train': numpy.ndarray,
                        'dev': numpy.ndarray,
                        'test': numpy.ndarray}, ...
            }
        }
     -
    '''
    carry_datasets = import_carry_datasets(operand_digits, operator)

    input_train_list = list()
    target_train_list = list()
    input_dev_list = list()
    target_dev_list = list()
    input_test_list = list()
    target_test_list = list()

    splited_carry_datasets = dict()

    for carries in carry_datasets.keys():
        np_input = carry_datasets[carries]['input']
        np_target = carry_datasets[carries]['output']

        (input_train, input_dev, input_test,
         target_train, target_dev, target_test) = get_KL_fold_CV_sets(np_input, np_target, i_iteration, n_outer_folds, n_inner_folds)

        input_train_list.append(input_train)
        target_train_list.append(target_train)
        input_dev_list.append(input_dev)
        target_dev_list.append(target_dev)
        input_test_list.append(input_test)
        target_test_list.append(target_test)

        # Initialize a dict for the number of carries
        splited_carry_datasets[carries] = dict()
        splited_carry_datasets[carries]['input'] = dict()
        splited_carry_datasets[carries]['output'] = dict()

        splited_carry_datasets[carries]['input']['train'] = input_train
        splited_carry_datasets[carries]['output']['train'] = target_train
        splited_carry_datasets[carries]['input']['dev'] = input_dev
        splited_carry_datasets[carries]['output']['dev'] = target_dev
        splited_carry_datasets[carries]['input']['test'] = input_test
        splited_carry_datasets[carries]['output']['test'] = target_test

    input_train = np.concatenate(input_train_list, axis=0)
    target_train = np.concatenate(target_train_list, axis=0)
    input_dev = np.concatenate(input_dev_list, axis=0)
    target_dev = np.concatenate(target_dev_list, axis=0)
    input_test = np.concatenate(input_test_list, axis=0)
    target_test = np.concatenate(target_test_list, axis=0)

    return (input_train, input_dev, input_test,
            target_train, target_dev, target_test,
            splited_carry_datasets)

def np_io2str_op(np_input, np_output, operator):
    '''
    Parameters
    ------
    np_input : np.ndarray. 1-dimension. shape==(2 * operand_digits).
    np_output : np.ndarray. 1-dimension. shape==(output_digits).

    Returns
    ------
    str_operation : str.
    - If np_input == [0, 0, 1, 1, 0, 1] and np_output == [0, 1, 1, 0],
        then str_op == '001+101=0110'.
    '''
    operand_digits = np_input.shape[0] // 2
    str_op1 = str()
    str_op2 = str()
    for i in range(operand_digits):
        str_op1 = str_op1 + str(int(np_input[i]))
        str_op2 = str_op2 + str(int(np_input[operand_digits + i]))

    result_digits = np_output.shape[0]
    str_result = str()
    for i in range(result_digits):
        str_result = str_result + str(int(np_output[i]))

    str_operation = '{op1} {operator} {op2} = {result}'.format(
        op1=str_op1,
        op2=str_op2,
        operator=get_op_symbol(operator),
        result=str_result
    )

    return str_operation

def less_than(operand1, operand2):
    '''
    Parameters
    ----------
    operand1 : np.ndarray. 1-dimension. shape==(operand_digits).
    operand2 : np.ndarray. 1-dimension. shape==(operand_digits).

    Returns
    -------
    is_less_than : bool. operand1 < operand2.
    '''
    operand_digits = operand1.shape[0]
    for i in range(operand_digits):
        if operand1[i] > operand2[i]:
            return False
        if operand1[i] < operand2[i]:
            return True
    # All same digits
    return False

def str_binary_operation(str_operand1, str_operator, str_operand2):
    int_dec_operand1 = get_int_dec(str_operand1)
    int_dec_operand2 = get_int_dec(str_operand2)
    if str_operator in ['add', '+']:
        int_dec_result = int_dec_operand1 + int_dec_operand2
    if str_operator in ['subtract', '-']:
        int_dec_result = int_dec_operand1 - int_dec_operand2
    if str_operator in ['multiply', '*']:
        int_dec_result = int_dec_operand1 * int_dec_operand2
    if str_operator in ['divide', '/', '//']:
        int_dec_result = int_dec_operand1 // int_dec_operand2
    if str_operator in ['modulo', '%']:
        int_dec_result = int_dec_operand1 % int_dec_operand2
    str_bin_result = get_str_bin(int_dec_result)
    return str_bin_result

def shuffle_io_pairs(l1, l2):
    assert len(l1) == len(l2)
    p = np.random.permutation(len(l1))
    return l1[p], l2[p]

def add_two_digits(digit1, digit2, carry):
    '''
    Parameters
    ----------
    digit1 : int. digit1 in [0, 1].
    digit2 : int. digit2 in [0, 1].
    carry : the carry from the lower addtion.

    Returns
    -------
    carry : the carry for the next digit addition.
    result : the current digit result of addition.
    '''
    digit_sum = digit1 + digit2 + carry

    if digit_sum == 3:
        (carry, result) = (1, 1)
    if digit_sum == 2:
        (carry, result) = (1, 0)
    if digit_sum == 1:
        (carry, result) = (0, 1)
    if digit_sum == 0:
        (carry, result) = (0, 0)

    return (carry, result)

def add_two_numbers(operand1, operand2, result_mode='fit'):
    '''
    Parameters
    ----------
    operand1 : np.dnarray. 1-dimension.
    operand2 : np.dnarray. 1-dimension. This should have the same dimension as operand2.

    Returns
    -------
    result : np.dnarray. 1-dimension. The result of addtion.
    n_carries : int. The number of carries occurred while addition.
    '''
    operand_digits = operand1.shape[0]
    result_digits = get_result_digits(operand_digits, 'add', result_mode='fit')
    result = np.zeros((result_digits), dtype=config.np_type())
    carry = 0
    n_carries = 0
    for i in range(1, operand_digits + 1):
        (carry, digit_result) = add_two_digits(operand1[-i], operand2[-i], carry)
        n_carries = n_carries + carry
        result[-i] = digit_result
        if i == (operand_digits): # Last digit
            result[-(i+1)] = carry

    # Concatenate in front of the array.
    if result_mode == 'same':
        final_result_digits = get_result_digits(operand_digits, 'add', result_mode=result_mode)
        leading_zeros = np.zeros((final_result_digits - result_digits), dtype=config.np_type())
        result = np.concatenate((leading_zeros, result))

    return (result, n_carries)

def subtract_two_numbers(operand1, operand2, result_mode='fit'):
    '''
    Parameters
    ----------
    operand1 : np.ndarray. 1-dimension. shape==(operand_digits).
    operand2 : np.ndarray. 1-dimension. shape==(operand_digits).
    - Always operand1 >= operand2.

    Returns
    -------
    result : np.ndarray. result = operand1 - operand2. 1-D. shape==(operand_digits).
    - Beacuse operand1 >= operand2, result >= 0.
    n_carries : int. The number of carries that occurred while subtraction.
    '''
    operand_digits = operand1.shape[0]
    result_digits = get_result_digits(operand_digits, 'subtract', result_mode='fit')
    cp_operand1 = np.copy(operand1)
    cp_operand2 = np.copy(operand2)
    result = np.zeros((result_digits), dtype=config.np_type())
    n_carries = 0
    for i in range(1, operand_digits + 1):
        if cp_operand1[-i] >= cp_operand2[-i]:
            result[-i] = cp_operand1[-i] - cp_operand2[-i]
        else:
            for j in range(i + 1, operand_digits + 1):
                n_carries = n_carries + 1
                if cp_operand1[-j] == 1:
                    cp_operand1[-j] = 0
                    for k in range(i + 1, j):
                        cp_operand1[-k] = 1
                    break
            result[-i] = 1

    # Concatenate in front of the array.
    if result_mode == 'same':
        final_result_digits = get_result_digits(operand_digits, 'subtract', result_mode=result_mode)
        leading_zeros = np.zeros((final_result_digits - result_digits), dtype=config.np_type())
        result = np.concatenate((leading_zeros, result))

    return (result, n_carries)

def multiply_two_numbers(operand1, operand2, result_mode='fit'):
    '''
    Parameters
    ----------
    operand1 : np.ndarray. 1-dimension. shape==(operand_digits).
    operand2 : np.ndarray. 1-dimension. shape==(operand_digits).

    Returns
    -------
    result : np.ndarray. result = operand1 - operand2. 1-D. shape==(operand_digits).
    n_carries : int. The number of carries that occurred while multiplication.
    '''
    operand_digits = operand1.shape[0]
    result_digits = get_result_digits(operand_digits, 'multiply', result_mode='fit')
    result = np.zeros((result_digits), dtype=config.np_type()) # To return
    carry_buffer = np.zeros((result_digits), dtype=config.np_type()) # To save carries while addition

    # The multiplying phase
    multiply_result_to_sum = np.zeros((operand_digits, result_digits), dtype=config.np_type())
    for i in range(operand_digits):
        if operand2[-(i+1)] == 1:
            start_index = (result_digits - operand_digits - i)
            end_index = (result_digits - i)
            multiply_result_to_sum[i, start_index:end_index] = operand1

    # The summation and carrying phase
    n_carries = 0 # total carries in one multiplication operation.
    for i in range(1, result_digits+1):
        digit_wise_sum = np.sum(multiply_result_to_sum[:,-i]) + carry_buffer[-i]
        carry, remainder = divmod(digit_wise_sum, 2)
        n_carries = n_carries + carry
        if i < result_digits: # except the last digit
            carry_buffer[-(i+1)] = carry
        result[-i] = remainder

    # Concatenate in front of the array.
    if result_mode == 'same':
        final_result_digits = get_result_digits(operand_digits, 'multiply', result_mode=result_mode)
        leading_zeros = np.zeros((final_result_digits - result_digits), dtype=config.np_type())
        result = np.concatenate((leading_zeros, result))

    return (result, n_carries)

def divide_two_numbers(operand1, operand2, result_mode='fit'):
    '''
    Parameters
    ----------
    operand1 : np.ndarray. 1-dimension. shape==(operand_digits).
    operand2 : np.ndarray. 1-dimension. shape==(operand_digits).
    - operand2 must not be zero.

    Returns
    -------
    result : np.ndarray. result = operand1 // operand2. 1-D. shape==(operand_digits)
    n_carries : int. The number of carries that occurred while multiplication.
    remainder : np.ndarray. shape==(operand_digits).
    '''
    operand_digits = operand1.shape[0]
    result_digits = get_result_digits(operand_digits, 'divide', result_mode='fit')
    result = np.zeros((result_digits), dtype=config.np_type())

    leading_zeros = get_leading_zeros(operand2)
    valid_operand2_digits = operand_digits - leading_zeros

    division_steps = operand_digits - valid_operand2_digits + 1

    n_total_carries = 0
    for i in range(division_steps):
        division_index = valid_operand2_digits + i - 1
        division_range = division_index + 1

        # Assignment: local_divide_operand1
        local_divide_operand1 = np.zeros((division_range), dtype=config.np_type())
        if i == 0:
            local_divide_operand1 = operand1[:division_range]
        else:
            local_divide_operand1[:division_index] = local_subtract_result
            local_divide_operand1[division_index] = operand1[division_index]

        # Assignment: local_divide_operand2
        local_divide_operand2 = np.zeros((division_range), dtype=config.np_type())
        local_divide_operand2[-valid_operand2_digits:] = operand2[-valid_operand2_digits:]
        #local_divide_operand2[-division_range:] = operand2[-division_range:]

        # Division: If condition. less_than
        # Subtraction: Get a remainder
        if less_than(local_divide_operand1, local_divide_operand2):
            result[division_index] = 0 # Division result
            local_subtract_result = np.copy(local_divide_operand1[:division_range]) # Get the remainder
            n_carries = 0
        else:
            result[division_index] = 1 # Division result
            local_subtract_result, n_carries = subtract_two_numbers(local_divide_operand1, local_divide_operand2, result_mode='fit') # Get the remainder

        n_total_carries = n_total_carries + n_carries

    remainder = local_subtract_result

    # Concatenate in front of the array.
    if result_mode == 'same':
        final_result_digits = get_result_digits(operand_digits, 'divide', result_mode=result_mode)
        leading_zeros = np.zeros((final_result_digits - result_digits), dtype=config.np_type())
        result = np.concatenate((leading_zeros, result))

    return (result, n_carries, remainder)

def modulo_two_numbers(operand1, operand2, result_mode='fit'):
    '''
    Parameters
    ----------
    operand1 : np.ndarray. 1-dimension. shape==(operand_digits).
    operand2 : np.ndarray. 1-dimension. shape==(operand_digits).
    - operand2 must not be zero.

    Returns
    -------
    result : np.ndarray. result = operand1 % operand2. 1-D. shape==(operand_digits).
    n_carries : int. The number of carries that occurred while multiplication.
    remainder : np.ndarray. shape==(operand_digits).
    '''
    operand_digits = operand1.shape[0]
    result_digits = get_result_digits(operand_digits, 'modulo', result_mode='fit')

    _, n_carries, result = divide_two_numbers(operand1, operand2)

    # Concatenate in front of the array.
    if result_mode == 'same':
        final_result_digits = get_result_digits(operand_digits, 'modulo', result_mode='same')
        leading_zeros = np.zeros((final_result_digits - result_digits), dtype=config.np_type())
        result = np.concatenate((leading_zeros, result))

    return (result, n_carries)

def operate_two_numbers(operand1, operand2, operator, result_mode='fit'):
    '''
    Parameters
    ----------
    operand1 : np.ndarray. 1-dimension. shape==(operand_digits).
    operand2 : np.ndarray. 1-dimension. shape==(operand_digits).
    operator : str. ['add', 'substract', 'multiply', 'divide', 'modulo']

    Returns
    -------
    return_vector : The reult of an operation.
    - For division, the size of it will be 3 but the size of the others will be 2.
    '''
    if operator == 'add':
        return_vector = add_two_numbers(operand1, operand2, result_mode)
    if operator == 'subtract':
        return_vector = subtract_two_numbers(operand1, operand2, result_mode)
    if operator == 'multiply':
        return_vector = multiply_two_numbers(operand1, operand2, result_mode)
    if operator == 'divide':
        return_vector = divide_two_numbers(operand1, operand2, result_mode)
    if operator == 'modulo':
        return_vector = modulo_two_numbers(operand1, operand2, result_mode)

    return return_vector

def generate_random_datasets(operand_digits):
    '''
    Parameters
    ----------
    operand_digits: int. the number of the digits of an operand.

    Returns
    -------
    zero_output_dataset: dict.
    - zero_output_dataset['input']: numpy.ndarray. shape == (n_operations, operand_digits * 2).
    - zero_output_dataset['output']: numpy.ndarray. shape == (n_operations, result_digits).
    one_output_dataset: dict.
    - one_output_dataset['input']: numpy.ndarray. shape == (n_operations, operand_digits * 2).
    - one_output_dataset['output']: numpy.ndarray. shape == (n_operations, result_digits).
    random_output_dataset: dict.
    - random_output_dataset['input']: numpy.ndarray. shape == (n_operations, operand_digits * 2).
    - random_output_dataset['output']: numpy.ndarray. shape == (n_operations, result_digits).
    '''
    zero_output_dataset = {'input':list(), 'output':list()}
    one_output_dataset = {'input':list(), 'output':list()}
    fixed_random_output_dataset = {'input':list(), 'output':list()}
    random_output_dataset = {'input':list(), 'output':list()}

    result_digits = get_result_digits(operand_digits, 'add', result_mode='same')

    # Get a fixed numpy.ndarray binary random integer.
    np_bin_fixed_rand_output = get_np_bin(get_str_bin(np.random.randint(2**result_digits)), result_digits).reshape(1,-1)

    for dec_op1 in range(2**operand_digits):
        for dec_op2 in range(2**operand_digits):
            # Get numpy.ndarray binary operands.
            np_bin_op1 = get_np_bin(get_str_bin(dec_op1), operand_digits)
            np_bin_op2 = get_np_bin(get_str_bin(dec_op2), operand_digits)

            # Get a numpy.ndarray binary random integer.
            np_bin_rand_output = get_np_bin(get_str_bin(np.random.randint(2**result_digits)), result_digits).reshape(1,-1)

            # Append the input of addition.
            input = np.concatenate((np_bin_op1, np_bin_op2)).reshape(1,-1)
            zero_output_dataset['input'].append(input)
            one_output_dataset['input'].append(input)
            fixed_random_output_dataset['input'].append(input)
            random_output_dataset['input'].append(input)

            # Append the output of addition.
            zero_output_dataset['output'].append(np.zeros((1, result_digits), dtype=config.np_type()))
            one_output_dataset['output'].append(np.ones((1, result_digits), dtype=config.np_type()))
            fixed_random_output_dataset['output'].append(np_bin_fixed_rand_output)
            random_output_dataset['output'].append(np_bin_rand_output)

    # List to one numpy.ndarray
    zero_output_dataset['input'] = np.concatenate(zero_output_dataset['input'], axis=0)
    zero_output_dataset['output'] = np.concatenate(zero_output_dataset['output'], axis=0)
    one_output_dataset['input'] = np.concatenate(one_output_dataset['input'], axis=0)
    one_output_dataset['output'] = np.concatenate(one_output_dataset['output'], axis=0)
    fixed_random_output_dataset['input'] = np.concatenate(fixed_random_output_dataset['input'], axis=0)
    fixed_random_output_dataset['output'] = np.concatenate(fixed_random_output_dataset['output'], axis=0)
    random_output_dataset['input'] = np.concatenate(random_output_dataset['input'], axis=0)
    random_output_dataset['output'] = np.concatenate(random_output_dataset['output'], axis=0)

    # Shuffle the pairs of input and output of op_dataset.
    zero_output_dataset['input'], zero_output_dataset['output'] = shuffle_io_pairs(zero_output_dataset['input'], zero_output_dataset['output'])
    one_output_dataset['input'], one_output_dataset['output'] = shuffle_io_pairs(one_output_dataset['input'], one_output_dataset['output'])
    fixed_random_output_dataset['input'], fixed_random_output_dataset['output'] = shuffle_io_pairs(fixed_random_output_dataset['input'], fixed_random_output_dataset['output'])
    random_output_dataset['input'], random_output_dataset['output'] = shuffle_io_pairs(random_output_dataset['input'], random_output_dataset['output'])

    return zero_output_dataset, one_output_dataset, fixed_random_output_dataset, random_output_dataset

def generate_datasets(operand_digits, operator, result_mode='fit', ordered_operands=False):
    '''
    Parameters
    ----------
    operand_digits: int. the number of the digits of an operand.
    operator: str. one of ['add', 'subtract', 'multiply', 'divide', 'modulo'].
    result_mode : str. one of ['fit', 'same'].
    - 'fit' : result_digits == the minumum number of varying result digits.
    - 'same' : result_digits of the five opertors has the same number of digits.
    ordered_operands : bool. Suppose two operands (a,b) such that a + b, a - b..
    - If a >= b, ordered_operands == True.
    - Otherwise, ordered_operands == False.

    Returns
    -------
    op_dataset: dict.
    - op_dataset['input']: numpy.ndarray. shape == (n_operations, operand_digits * 2).
    - op_dataset['output']: numpy.ndarray. shape == (n_operations, result_digits).
    carry_datasets: dict.
    - carry_datasets[n_carries]['input']: numpy.ndarray. shape == (n_operations, operand_digits * 2).
    -- Input dataset for n_carries subtraction.
    - carry_datasets[n_carries]['output']: numpy.ndarray. shape == (n_operations, result_digits).
    -- Output dataset for n_carries subtraction.
    -- result_digits == operand_digits
    '''
    op_dataset = {'input':list(), 'output':list()}
    carry_datasets = dict()

    for dec_op1 in range(2**operand_digits):
        for dec_op2 in range(2**operand_digits):
            # Get numpy.ndarray binary operands.
            np_bin_op1 = get_np_bin(get_str_bin(dec_op1), operand_digits)
            np_bin_op2 = get_np_bin(get_str_bin(dec_op2), operand_digits)

            # Arithemetic operation phase
            if operator == 'add':
                if ordered_operands:
                    if dec_op1 < dec_op2:
                        continue
                result, n_carries = add_two_numbers(np_bin_op1, np_bin_op2, result_mode)
            if operator == 'subtract':
                if dec_op1 < dec_op2:
                    continue
                result, n_carries = subtract_two_numbers(np_bin_op1, np_bin_op2, result_mode)
            if operator == 'multiply':
                if ordered_operands:
                    if dec_op1 < dec_op2:
                        continue
                result, n_carries = multiply_two_numbers(np_bin_op1, np_bin_op2, result_mode)
            if operator == 'divide':
                if ordered_operands:
                    if dec_op1 < dec_op2:
                        continue
                if dec_op2 == 0:
                    continue
                result, n_carries, _ = divide_two_numbers(np_bin_op1, np_bin_op2, result_mode)
            if operator == 'modulo':
                if ordered_operands:
                    if dec_op1 < dec_op2:
                        continue
                if dec_op2 == 0:
                    continue
                result, n_carries = modulo_two_numbers(np_bin_op1, np_bin_op2, result_mode)

            # Create a list to store operations
            if n_carries not in carry_datasets:
                carry_datasets[n_carries] = dict()
                carry_datasets[n_carries]['input'] = list()
                carry_datasets[n_carries]['output'] = list()

            # Append the input of addition.
            input = np.concatenate((np_bin_op1, np_bin_op2)).reshape(1,-1)
            op_dataset['input'].append(input)
            carry_datasets[n_carries]['input'].append(input)

            # Append the output of addition.
            output = result.reshape(1,-1)
            op_dataset['output'].append(output)
            carry_datasets[n_carries]['output'].append(output)

    # List to one numpy.ndarray
    op_dataset['input'] = np.concatenate(op_dataset['input'], axis=0)
    op_dataset['output'] = np.concatenate(op_dataset['output'], axis=0)

    for key in carry_datasets.keys():
        carry_datasets[key]['input'] = np.concatenate(carry_datasets[key]['input'], axis=0)
        carry_datasets[key]['output'] = np.concatenate(carry_datasets[key]['output'], axis=0)

    # Shuffle the pairs of input and output of op_dataset.
    op_dataset['input'], op_dataset['output'] = shuffle_io_pairs(op_dataset['input'], op_dataset['output'])

    for n_carries in carry_datasets.keys():
        carry_datasets[n_carries]['input'], carry_datasets[n_carries]['output'] = shuffle_io_pairs(carry_datasets[n_carries]['input'], carry_datasets[n_carries]['output'])

    return op_dataset, carry_datasets

def generate_and_save_all_datasets(result_mode, ordered_operands):
    for operator in config.operators_list():
        for operand_digits in config.operand_digits_list():
            op_dataset, carry_datasets = generate_datasets(operand_digits, operator, result_mode, ordered_operands)
            save_op_dataset(op_dataset, operand_digits, operator)
            save_carry_datasets(carry_datasets, operand_digits, operator)
    for operand_digits in config.operand_digits_list():
        random_datasets = generate_random_datasets(operand_digits)
        save_random_datasets(random_datasets, operand_digits)

def save_op_dataset(op_dataset, operand_digits, operator):
    save_dir = 'data/{}-bit/{}'.format(operand_digits, operator)
    create_dir(save_dir)
    save_path = '{}/op_dataset.pickle'.format(save_dir)

    with open(save_path, 'wb') as f:
        pickle.dump(op_dataset, f)

    print("Saved in '{}'.".format(save_path))

def save_carry_datasets(carry_datasets, operand_digits, operator):
    save_dir = 'data/{}-bit/{}'.format(operand_digits, operator)
    create_dir(save_dir)

    # Ordered carry datasets
    save_path = '{}/carry_datasets.pickle'.format(save_dir)
    with open(save_path, 'wb') as f:
        pickle.dump(carry_datasets, f)
    print("Saved in '{}'.".format(save_path))

    # Ordered carry datasets
    '''shuffle_carry_datasets(carry_datasets)
    save_path = '{}/shuffled_carry_datasets.pickle'.format(save_dir)
    with open(save_path, 'wb') as f:
        pickle.dump(carry_datasets, f)
    print("Saved in '{}'.".format(save_path))'''

def save_random_datasets(random_datasets, operand_digits):
    (zero_output_dataset, one_output_dataset,
        fixed_random_output_dataset,
        random_output_dataset) = random_datasets

    # zero_output_dataset
    save_dir = '{}/{}-bit/{}'.format(config.dir_data(), operand_digits, 'zero')
    create_dir(save_dir)
    save_path = '{}/op_dataset.pickle'.format(save_dir)
    with open(save_path, 'wb') as f:
        pickle.dump(zero_output_dataset, f)
    print("Saved in '{}'.".format(save_path))

    # one_output_dataset
    save_dir = '{}/{}-bit/{}'.format(config.dir_data(), operand_digits, 'one')
    create_dir(save_dir)
    save_path = '{}/op_dataset.pickle'.format(save_dir)
    with open(save_path, 'wb') as f:
        pickle.dump(one_output_dataset, f)
    print("Saved in '{}'.".format(save_path))

    # fixed_random_output_dataset
    save_dir = '{}/{}-bit/{}'.format(config.dir_data(), operand_digits, 'fixed_random')
    create_dir(save_dir)
    save_path = '{}/op_dataset.pickle'.format(save_dir)
    with open(save_path, 'wb') as f:
        pickle.dump(fixed_random_output_dataset, f)
    print("Saved in '{}'.".format(save_path))

    # random_output_dataset
    save_dir = '{}/{}-bit/{}'.format(config.dir_data(), operand_digits, 'random')
    create_dir(save_dir)
    save_path = '{}/op_dataset.pickle'.format(save_dir)
    with open(save_path, 'wb') as f:
        pickle.dump(random_output_dataset, f)
    print("Saved in '{}'.".format(save_path))

def shuffle_carry_datasets(carry_datasets):
    '''
    Shuffle the given carry_datasets.
    '''
    for carries in carry_datasets.keys():
        carry_ds_size = carry_datasets[carries]['input'].shape[0]
        randomize = np.arange(carry_ds_size)
        np.random.shuffle(randomize)
        carry_datasets[carries]['input'] = carry_datasets[carries]['input'][randomize]
        carry_datasets[carries]['output'] = carry_datasets[carries]['output'][randomize]

def print_carry_datasets_info(carry_datasets):
    data_len_list = list()
    for key in carry_datasets.keys():
        data_len_list.append(carry_datasets[key]['input'].shape[0])
    total_operations = sum(data_len_list)

    for key in carry_datasets.keys():
        print('{}-carry dataset'.format(key))

        print('- #input dimension: {}'.format(carry_datasets[key]['input'].shape[1]))
        print('- #output dimension: {}'.format(carry_datasets[key]['output'].shape[1]))
        print('- #operations: {}'.format(carry_datasets[key]['input'].shape[0]))
        print('- Perceptage of {}-carry operations: {} %'.format(
            key, (carry_datasets[key]['input'].shape[0] / total_operations * 100)))

def get_carry_dataset_info_list(carry_datasets, operator):
    data_len_list = list()
    for key in carry_datasets.keys():
        data_len_list.append(carry_datasets[key]['input'].shape[0])
    total_operations = sum(data_len_list)

    carry_dataset_info_list = list()

    for n_carries in carry_datasets.keys():
        carry_dataset_info = dict()

        carry_dataset_info['operator'] = operator
        carry_dataset_info['carries'] = n_carries
        carry_dataset_info['operand digits'] = carry_datasets[n_carries]['input'].shape[1] // 2
        carry_dataset_info['input dimension'] = carry_datasets[n_carries]['input'].shape[1]
        carry_dataset_info['output dimension'] = carry_datasets[n_carries]['output'].shape[1]
        carry_dataset_info['carry operations'] = carry_datasets[n_carries]['input'].shape[0]
        carry_dataset_info['total operations'] = total_operations
        carry_dataset_info['carry percentage'] = (carry_datasets[n_carries]['input'].shape[0] / total_operations * 100)

        carry_dataset_info_list.append(carry_dataset_info)

    return carry_dataset_info_list

def write_carry_dataset_statistics(ordered_operands):
    carry_dataset_info_list = list()
    csv_file_path = get_carry_ds_stat_path()
    create_dir(config.dir_data())

    for operator in config.operators_list():
        for operand_digits in config.operand_digits_list():
            carry_datasets = generate_datasets(operand_digits, operator, ordered_operands=ordered_operands)
            carry_dataset_info_list = carry_dataset_info_list + get_carry_dataset_info_list(carry_datasets, operator)

    with open(csv_file_path, mode='w') as csv_file:
        fieldnames = ['operator', 'operand digits',
                      'input dimension', 'output dimension', 'total operations',
                     'carries', 'carry operations', 'carry percentage']
        writer = csv.DictWriter(csv_file, fieldnames=fieldnames)

        writer.writeheader()
        for carry_dataset_info in carry_dataset_info_list:
            writer.writerow(carry_dataset_info)

    print('{} saved!'.format(csv_file_path))

def plot_carry_dataset_statistics(mode='save', file_format='svg'):
    df_carry_ds_stat = pd.read_csv(get_carry_ds_stat_path())
    df_carry_ds_stat = df_carry_ds_stat[['operator', 'operand digits', 'carries', 'carry percentage']]
    for operand_digits in config.operand_digits_list():
        plt.title('Percentage of operations by required carries ({}-digit operand)'.format(operand_digits))
        plt.xlabel('Carries')
        plt.ylabel('Percentage (%)')
        plt.grid(axis='y')
        plt.yticks(np.arange(0, 101, step=10))
        plt.ylim(0, 101)
        for operator in config.operators_list():
            if operator == 'modulo':
                break
            if operator == 'divide':
                operator_label = 'divide/modulo'
            else:
                operator_label = operator

            df = df_carry_ds_stat.loc[(df_carry_ds_stat['operator'] == operator) & (df_carry_ds_stat['operand digits'] == operand_digits)]
            df = df[['carries', 'carry percentage']]

            plt.plot(df['carries'], df['carry percentage'], ':o', label=operator_label)
            #plt.bar(df['carries'], df['carry percentage'], label=operator)
            plt.legend()
        if mode == 'show':
            plt.show()
        if mode == 'save':
            create_dir(config.dir_plot_fig())
            plot_fig_path = '{}/carry_dataset_statistics_{}-digit_operand.{}'.format(config.dir_plot_fig(), operand_digits, file_format)
            plt.savefig(plot_fig_path)
            print('{} saved!'.format(plot_fig_path))
        plt.clf()

def import_op_dataset(operator, operand_digits, train_ratio, dev_ratio, test_ratio):
    input_train_list = list()
    input_dev_list = list()
    input_test_list = list()
    target_train_list = list()
    target_dev_list = list()
    target_test_list = list()

    splited_carry_datasets = dict()

    carry_datasets = import_carry_datasets(operand_digits, operator)

    for carries in carry_datasets.keys():
        # Initialize a dict for the number of carries
        splited_carry_datasets[carries] = dict()
        splited_carry_datasets[carries]['input'] = dict()
        splited_carry_datasets[carries]['output'] = dict()

        # Get the size of a carry dataset
        carry_ds_size = carry_datasets[carries]['input'].shape[0]

        # Shuffle input and output data
        randomize = np.arange(carry_ds_size)
        np.random.shuffle(randomize)
        carry_datasets[carries]['input'] = carry_datasets[carries]['input'][randomize]
        carry_datasets[carries]['output'] = carry_datasets[carries]['output'][randomize]

        # Make a training set.
        train_end_index = int(carry_ds_size * train_ratio)
        input_train = carry_datasets[carries]['input'][:train_end_index,:]
        target_train = carry_datasets[carries]['output'][:train_end_index,:]
        input_train_list.append(input_train)
        target_train_list.append(target_train)
        splited_carry_datasets[carries]['input']['train'] = input_train
        splited_carry_datasets[carries]['output']['train'] = target_train

        # Make a development set.
        dev_end_index = int(carry_ds_size * (train_ratio + dev_ratio))

        if dev_ratio != 0:
            input_dev = carry_datasets[carries]['input'][train_end_index:dev_end_index,:]
            target_dev = carry_datasets[carries]['output'][train_end_index:dev_end_index,:]
            splited_carry_datasets[carries]['input']['dev'] = input_dev
            splited_carry_datasets[carries]['output']['dev'] = target_dev
        else:
            input_dev = input_train
            target_dev = target_train
            splited_carry_datasets[carries]['input']['dev'] = input_train
            splited_carry_datasets[carries]['output']['dev'] = target_train

        input_dev_list.append(input_dev)
        target_dev_list.append(target_dev)

        # Maek a test set.
        if test_ratio != 0:
            input_test = carry_datasets[carries]['input'][dev_end_index:,:]
            target_test = carry_datasets[carries]['output'][dev_end_index:,:]
            input_test_list.append(input_test)
            target_test_list.append(target_test)
            splited_carry_datasets[carries]['input']['test'] = input_test
            splited_carry_datasets[carries]['output']['test'] = target_test
        else:
            input_test = input_train
            target_test = target_train
            splited_carry_datasets[carries]['input']['test'] = input_train
            splited_carry_datasets[carries]['output']['test'] = target_train

        input_test_list.append(input_test)
        target_test_list.append(target_test)

    input_train = np.concatenate(input_train_list, axis=0)
    target_train = np.concatenate(target_train_list, axis=0)
    input_dev = np.concatenate(input_dev_list, axis=0)
    target_dev = np.concatenate(target_dev_list, axis=0)
    input_test = np.concatenate(input_test_list, axis=0)
    target_test = np.concatenate(target_test_list, axis=0)

    return (input_train, input_dev, input_test,
            target_train, target_dev, target_test,
            splited_carry_datasets)

def import_carry_datasets(operand_digits, operator):
    '''
    Parameters
    ----------
    operand_digits: int. The number of digits of an operand.
    operantor: str. one of ['add', 'substract', 'multiply', 'divide', 'modulo']

    Returns
    -------
    carry_datasets: dict.
    - carry_datasets[n_carries]['input']: shape == (n_operations, input_dim).
    - carry_datasets[n_carries]['output']: shape == (n_operations, output_dim).
    '''
#    if shuffled:
#        import_path = 'data/{}-bit/{}/shuffled_carry_datasets.pickle'.format(operand_digits, operator)
#    else:
#        import_path = 'data/{}-bit/{}/carry_datasets.pickle'.format(operand_digits, operator)

    import_path = 'data/{}-bit/{}/carry_datasets.pickle'.format(operand_digits, operator)

    with open(import_path, 'rb') as f:
        carry_datasets = pickle.load(f)

    #print("Imported from '{}'.".format(import_path))

    return carry_datasets

def import_random_sampled_carry_datasets(operand_digits, operator, n_samples):
    '''
    "Import carry datasets that `n_samples` operations are sampled from each carry dataset."

    Parameters
    ----------
    operand_digits: int. The number of digits of an operand.
    operantor: str. one of ['add', 'substract', 'multiply', 'divide', 'modulo'].
    n_samples : int. The number of operations to sample from each carry.

    Returns
    -------
    carry_datasets : dict. Carry datasets that `n_samples` operations are sampled from each carry dataset.
    - carry_datasets[n_carries]['input']: shape == (n_samples, input_dim) or (n_operations, input_dim).
    - carry_datasets[n_carries]['output']: shape == (n_samples, output_dim) or (n_operations, output_dim).
    - If `n_samples` > n_operations in a carry dataset, then import all operations in it.
    '''
    carry_datasets = import_carry_datasets(operand_digits, operator)
    for n_carries in carry_datasets.keys():
        n_operations = carry_datasets[n_carries]['input'].shape[0]

        if n_samples > n_operations:
            sampled_indexes = random.sample(range(n_operations), n_operations)
        else:
            sampled_indexes = random.sample(range(n_operations), n_samples)

        carry_datasets[n_carries]['input'] = carry_datasets[n_carries]['input'][sampled_indexes,:]
        carry_datasets[n_carries]['output'] = carry_datasets[n_carries]['output'][sampled_indexes,:]

    return carry_datasets

def test_func_add_two_numbers():
    is_all_correct = True
    for operand_digits in config.operand_digits_list():
        # varying part
        result_digits = get_result_digits(operand_digits, 'add')
        for dec_op1 in range(2**operand_digits):
            for dec_op2 in range(2**operand_digits):
                # varying part
                bin_result = get_str_bin(dec_op1 + dec_op2)
                np_bin_result = get_np_bin(bin_result, result_digits)

                np_bin_op1 = get_np_bin(get_str_bin(dec_op1), operand_digits)
                np_bin_op2 = get_np_bin(get_str_bin(dec_op2), operand_digits)
                np_bin_result_algo, _ = add_two_numbers(np_bin_op1, np_bin_op2)

                is_equal = np.array_equal(np_bin_result, np_bin_result_algo)
                is_all_correct = is_all_correct and is_equal
    return is_all_correct

def test_func_subtract_two_numbers():
    is_all_correct = True
    for operand_digits in config.operand_digits_list():
        # varying part
        result_digits = get_result_digits(operand_digits, 'subtract')
        for int_dec_operand1 in range(2**operand_digits):
            for int_dec_operand2 in range(2**operand_digits):
                if int_dec_operand1 >= int_dec_operand2: # Only these cases are dealth with.
                    # varying part
                    bin_result = get_str_bin(int_dec_operand1 - int_dec_operand2)
                    np_result = get_np_bin(bin_result, result_digits)

                    np_operand1 = get_np_bin(get_str_bin(int_dec_operand1), operand_digits)
                    np_operand2 = get_np_bin(get_str_bin(int_dec_operand2), operand_digits)
                    np_bin_result_algo, _ = subtract_two_numbers(np_operand1, np_operand2)

                    is_equal = np.array_equal(np_result, np_bin_result_algo)
                    is_all_correct = is_all_correct and is_equal
    return is_all_correct

def test_func_multiply_two_numbers():
    is_all_correct = True
    for operand_digits in config.operand_digits_list():
        # varying part
        result_digits = get_result_digits(operand_digits, 'multiply')
        for int_dec_operand1 in range(2**operand_digits):
            for int_dec_operand2 in range(2**operand_digits):
                # varying part
                bin_result = get_str_bin(int_dec_operand1 * int_dec_operand2)
                np_result = get_np_bin(bin_result, result_digits)

                np_operand1 = get_np_bin(get_str_bin(int_dec_operand1), operand_digits)
                np_operand2 = get_np_bin(get_str_bin(int_dec_operand2), operand_digits)
                np_bin_result_algo, _ = multiply_two_numbers(np_operand1, np_operand2)

                is_equal = np.array_equal(np_result, np_bin_result_algo)
                is_all_correct = is_all_correct and is_equal
    return is_all_correct

def test_func_divide_two_numbers():
    is_all_correct = True
    for operand_digits in config.operand_digits_list():
        # varying part
        result_digits = get_result_digits(operand_digits, 'divide')
        for int_dec_operand1 in range(2**operand_digits):
            for int_dec_operand2 in range(1, 2**operand_digits): # Exclude `int_dec_operand2 = 0`
                # varying part
                bin_result = get_str_bin(int_dec_operand1 // int_dec_operand2)
                np_result = get_np_bin(bin_result, result_digits)

                np_operand1 = get_np_bin(get_str_bin(int_dec_operand1), operand_digits)
                np_operand2 = get_np_bin(get_str_bin(int_dec_operand2), operand_digits)
                np_bin_result_algo, _, _ = divide_two_numbers(np_operand1, np_operand2)

                is_equal = np.array_equal(np_result, np_bin_result_algo)
                is_all_correct = is_all_correct and is_equal
    return is_all_correct

def test_func_modulo_two_numbers():
    is_all_correct = True
    for operand_digits in config.operand_digits_list():
        # varying part
        result_digits = get_result_digits(operand_digits, 'modulo')
        for int_dec_operand1 in range(2**operand_digits):
            for int_dec_operand2 in range(1, 2**operand_digits): # Exclude `int_dec_operand2 = 0`
                # varying part
                bin_result = get_str_bin(int_dec_operand1 % int_dec_operand2)
                np_result = get_np_bin(bin_result, result_digits)

                np_operand1 = get_np_bin(get_str_bin(int_dec_operand1), operand_digits)
                np_operand2 = get_np_bin(get_str_bin(int_dec_operand2), operand_digits)
                np_bin_result_algo, _ = modulo_two_numbers(np_operand1, np_operand2)

                is_equal = np.array_equal(np_result, np_bin_result_algo)
                is_all_correct = is_all_correct and is_equal
    return is_all_correct

def test_multiply_symmetric_carries():
    '''
    Purpose : To test whether the number of carries while multipication is same for a * b and b * a.
    Result  : The number of carries is always same for a * b and b * a.
    '''
    is_all_symmetric = True
    for operand_digits in config.operand_digits_list():
        for int_dec_operand1 in range(2**operand_digits):
            for int_dec_operand2 in range(2**operand_digits):
                operand1 = get_np_bin(get_str_bin(int_dec_operand1), operand_digits)
                operand2 = get_np_bin(get_str_bin(int_dec_operand2), operand_digits)
                result1, _ = multiply_two_numbers(operand1, operand2)
                result2, _ = multiply_two_numbers(operand2, operand1)

                is_equal = np.array_equal(result1, result2)
                is_all_symmetric = is_all_symmetric and is_equal
    return is_all_symmetric

def test_import_random_sampled_carry_datasets(n_samples=10):
    '''
    "To test the function `import_random_sampled_carry_datasets`"
    '''
    is_all_correct = True

    for operand_digits in config.operand_digits_list():
        for operator in config.operators_list():
            carry_datasets = import_random_sampled_carry_datasets(operand_digits, operator, n_samples)
            for n_carries in carry_datasets.keys():
                n_operations = carry_datasets[n_carries]['input'].shape[0]
                for i_operation in range(n_operations):
                    operand1 = carry_datasets[n_carries]['input'][i_operation, :operand_digits]
                    operand2 = carry_datasets[n_carries]['input'][i_operation, operand_digits:]
                    result = carry_datasets[n_carries]['output'][i_operation, :]

                    result_by_computing = operate_two_numbers(operand1, operand2, operator)[0] # Get the first element

                    is_equal = np.array_equal(result, result_by_computing)
                    if not is_equal:
                        print(operand1)
                        print(operand2)
                        print(result)
                        print(result_by_computing)
                        print('================')

                    is_all_correct = is_all_correct and is_equal

    return is_all_correct

### OLD

def import_data(operator, input_bits, mode=''):
    '''
    operator: 'add', 'subtract', 'multiply', 'divide', 'modulo'
    '''
    dir_data_request = '{}/{}-bit/{}'.format(config.dir_data(), input_bits, operator)
    input_train_path = '{}/input_train.pickle'.format(dir_data_request)
    input_dev_path = '{}/input_dev.pickle'.format(dir_data_request)
    input_test_path = '{}/input_test.pickle'.format(dir_data_request)
    output_train_path = '{}/output_train.pickle'.format(dir_data_request)
    output_dev_path = '{}/output_dev.pickle'.format(dir_data_request)
    output_test_path = '{}/output_test.pickle'.format(dir_data_request)

    with open(input_train_path, 'rb') as f:
        input_train = pickle.load(f)
        #print('Imported from {}.'.format(input_train_path))
    with open(input_dev_path, 'rb') as f:
        input_dev = pickle.load(f)
        #print('Imported from {}.'.format(input_dev_path))
    with open(input_test_path, 'rb') as f:
        input_test = pickle.load(f)
        #print('Imported from {}.'.format(input_test_path))
    with open(output_train_path, 'rb') as f:
        output_train = pickle.load(f)
        #print('Imported from {}.'.format(output_train_path))
    with open(output_dev_path, 'rb') as f:
        output_dev = pickle.load(f)
        #print('Imported from {}.'.format(output_dev_path))
    with open(output_test_path, 'rb') as f:
        output_test = pickle.load(f)
        #print('Imported from {}.'.format(output_test_path))

    return (input_train, input_dev, input_test,
           output_train, output_dev, output_test)

max_stars_repo_name: sungjae-cho/arithmetic-jordan-net

max_issues_repo_name: sungjae-cho/arithmetic-jordan-net

max_forks_repo_name: sungjae-cho/arithmetic-jordan-net


text:
import gym
import numpy as np
import matplotlib.pyplot as plt

''' First-visit Monte Carlo sampling of value function, under some policy pi
'''

def main():

    env = gym.make('Blackjack-v0')

    # Init some useful variables:
    n_states = [s.n for s in env.observation_space]   # [players current sum, dealer's one showing card, player holds a usable ace]
    n_actions = env.action_space.n

    maxiter = int(100*1e3)

    # Initialize given policy to be evaluated: stick if sum >= 20, else hit
    policy = np.zeros(n_states, dtype=int)
    policy[:21,:,:] = 1
    policy[21:,:,:] = 0

    # Initialize arbitrary state-value function
    V = np.zeros(n_states)

    # empty list for all s \in S
    returns = np.frompyfunc(list, 0, 1)(np.empty(n_states, dtype=object))

    for i in range(maxiter):

        if not i%1000:
            print(f'it:{i}')

        obs = env.reset()  # obs is a tuple: (player_sum, dealer_card, useable_ace)
        s = tuple([int(si) for si in obs])
        done = False

        # dictionary state:cummulative_reward to store cummulative rewards for each episode
        G = {}

        # Generate episode using given policy
        while not done:

            # evaluate policy and play
            obs, reward, done, _ = env.step( policy[s] )
            # decode next state
            sn = tuple([int(si) for si in obs])

            # consider only the first state, in case the same state appears in the same trajectory
            if not s in G:
                G[s] = 0

            # accumulates the future reward for all states in past state
            for si in G.keys():
                G[si] += reward

            s = sn

        # for all state in episode:
        #   1. append cummulative reward to Returns(s)
        #   2. Update value function V(s) = average(Returns(s))
        for si,G_si in G.items():
            returns[si].append(G_si)
            V[si] = np.average(returns[si])

    fig = plt.figure(figsize=(10,4))
    plt.subplot(121)
    plt.imshow( V[12:22,1:,0], vmin=-1, vmax=1, extent=[1,11,21,12] )
    plt.colorbar()
    plt.xlabel('Dealer first card')
    plt.ylabel('Player sum')
    plt.title('Value - Expected cummulative reward \n(NO usable ace)')

    plt.subplot(122)
    plt.imshow( V[12:22,1:,1], vmin=-1, vmax=1, extent=[1,11,21,12] )
    plt.colorbar()
    plt.xlabel('Dealer first card')
    plt.ylabel('Player sum')
    plt.title('Value - Expected cummulative reward \n(usable ace)')
    plt.show()

if __name__ == "__main__":
    main()

ext: py

reason: import numpy


text:
import openpyxl
import pandas as pd
import numpy as np

import seaborn as sns
import matplotlib.pyplot as plt

import sklearn.preprocessing
from sklearn.cluster import KMeans
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler, StandardScaler
from sklearn.datasets.samples_generator import make_blobs

#-----------------------------------------------------------------------------

def acquire_heart():
    '''Takes the heart disease CSV
    turns csv into a readable pandas dataframe'''
    # Get the csv
    df = pd.read_csv('heart.csv')
    # return pandas df
    return df

#-----------------------------------------------------------------------------
# Official clean functions
def clean_heart_data(df):
    '''Takes in pandas dataframe
    renames columns using renaming function
    creates new columns using create features function
    bin large features using binning function
    returnn cleaned pandas dataframe'''
    # rename
    df = rename_features(df)
    # create
    df = create_features(df)
    # bin
    df = bin_large_data(df)
    # return cleaned dataframe
    return df
#-----------------------------------------------------------------------------
# sub clean funcitons that feed into official cleaning function

def rename_features(df):
    '''Takes pandas dataframe and renames columns'''
    # rename all columns
    df.columns = ['age','is_male', 'chest_pain', 'resting_bp', 'cholestoral', 'blood_sugar_above_120',
              'resting_electocardio', 'max_heart_rate', 'exercise_angina', 'rest_angina', 'slope',
              'count_major_vessels', 'defect_type', 'has_heart_disease']
    return df

def create_features(df):
    '''Takes in df
    creates new features for ratios
    between chest pain, age, heart rate, and cholestoral'''
    # chest pain and age ratio
    df['chest_age_ratio'] = df.chest_pain/df.age
    # age and cholestoral ratio
    df['age_chol_ratio'] = df.age/df.cholestoral
    # age and heart rate ratio
    df['age_heart_ratio'] = df.age/df.max_heart_rate
    # chest pain and cholestoral ratio
    df['chest_chol_ratio'] = df.chest_pain/df.cholestoral
    # cholestoral and heart rate ratio
    df['chol_heart_ratio'] = df.cholestoral/df.max_heart_rate
    # chest pain and heart rate ratio
    df['chest_heart_ratio'] = df.chest_pain/df.max_heart_rate
    # return pandas datafram
    return df

def bin_large_data(df):
    '''Takes in df and bins larger datas
    set labels for each bin
    returns pandas dataframe'''
    # create age bins
    df['age_groups'] = pd.cut(df.age,
                            bins = [29,35,40,45,50,55,60,65,70,75,80],
                            labels = ['Below 35', '35-40', '40-45', "45-50",
                                      "50-55", '55-60', '60-65', '65-70',
                                      '70-75', '75-80'])
    # bin cholestoral
    df['levels_of_chol'] = pd.cut(df.cholestoral,
                            bins = [0,200,240,800],
                            labels = ['Desireable', 'Boarderline High', 'High'])
    # bin heart rate
    df['heart_rate_levels'] = pd.cut(df.max_heart_rate,
                            bins = [0,120,130,140,180,250],
                            labels = ['Normal', 'Elevated', 'High Stage 1',
                                      'High Stage 2', 'Hypertensive Crisis'])
    # return pandas data frame
    return df

#-----------------------------------------------------------------------------

# Split the Data into Tain, Test, and Validate.

def split_heart_disease(df):
    '''This fuction takes in a df
    splits into train, test, validate
    return: three pandas dataframes: train, validate, test
    '''
    # split the focused zillow data
    train_validate, test = train_test_split(df, test_size=.2, random_state=1234)
    train, validate = train_test_split(train_validate, test_size=.3,
                                       random_state=1234)
    return train, validate, test

# Split the data into X_train, y_train, X_vlaidate, y_validate, X_train, and y_train

def split_train_validate_test(train, validate, test):
    ''' This function takes in train, validate and test
    splits them into X and y versions
    returns X_train, X_validate, X_test, y_train, y_validate, y_test'''
    X_train = train.drop(columns = ['has_heart_disease'])
    y_train = pd.DataFrame(train.has_heart_disease)
    X_validate = validate.drop(columns=['has_heart_disease'])
    y_validate = pd.DataFrame(validate.has_heart_disease)
    X_test = test.drop(columns=['has_heart_disease'])
    y_test = pd.DataFrame(test.has_heart_disease)
    return X_train, X_validate, X_test, y_train, y_validate, y_test

#-----------------------------------------------------------------------------

# Scale the Data

def scale_my_data(train, validate, test):
    scale_columns = ['Global_Sales', 'Year']
    scaler = MinMaxScaler()
    scaler.fit(train[scale_columns])

    train_scaled = scaler.transform(train[scale_columns])
    validate_scaled = scaler.transform(validate[scale_columns])
    test_scaled = scaler.transform(test[scale_columns])
    #turn into dataframe
    train_scaled = pd.DataFrame(train_scaled)
    validate_scaled = pd.DataFrame(validate_scaled)
    test_scaled = pd.DataFrame(test_scaled)

    return train_scaled, validate_scaled, test_scaled

#-----------------------------------------------------------------------------

# Focused Data

def focused_game_sales(df):
    '''
    takes in train
    sets sepecific features to focus on
    returns a focused data frame in a pandas dataframe
    '''
    # choose features to focus on
    features = [
    'Year','level_of_success',
    'Nintendo','Playstation','Xbox','Computer','Sega','Other',
    'Action_Adventure', 'Simulation', 'Sports', 'Misc', 'Role_Playing', 'Shooter',
    'Strategy']
    # the target is level of success
    # return a df based only on these features
    df2 = df[features]
    return df2

def split_focused_game_sales(df2):
    '''This fuction takes in a df
    splits into train, test, validate
    return: three pandas dataframes: train, validate, test
    '''
    # split the focused zillow data
    train_validate2, test2 = train_test_split(df2, test_size=.2, random_state=1234)
    train2, validate2 = train_test_split(train_validate2, test_size=.3,
                                       random_state=1234)
    return train2, validate2, test2

def split_train2_validate2_test2(train2, validate2, test2):
    ''' This function takes in train, validate and test
    splits them into X and y versions
    returns X_train, X_validate, X_test, y_train, y_validate, y_test'''
    X_train = train.drop(columns = ['level_of_success'])
    y_train = pd.DataFrame(train.level_of_success)
    X_validate = validate.drop(columns=['level_of_success'])
    y_validate = pd.DataFrame(validate.level_of_success)
    X_test = test.drop(columns=['level_of_success'])
    y_test = pd.DataFrame(test.level_of_success)
    return X_train2, X_validate2, X_test2, y_train2, y_validate2, y_test2


text:
from __future__ import division

__author__ = "Manu Airaksinen, manu.airaksinen@aalto.fi"

import os
import numpy as np
import tensorflow as tf

def get_frames(x,wl,hop):
    Nframes = int(np.ceil(x.shape[0]/hop))
    X = np.zeros((Nframes,int(wl)),dtype=np.float32)
    pad = np.zeros(int(wl/2),dtype=np.float32)
    x = np.concatenate((pad, x, pad))
    for i in range(Nframes):
        X[i,:] = x[i*hop:i*hop+wl]

    return X

def onehot(f0_vec,minf0=50,maxf0=500,Nbins=351):
    f0_onehot = np.zeros((f0_vec.shape[0],Nbins),dtype=np.float32)
    f0vec = np.exp(np.linspace(np.log(minf0),np.log(maxf0),Nbins-1))
    for i in range(f0_vec.shape[0]):
        if f0_vec[i] > 0.0:
            IND = np.argmin(np.abs(f0vec-f0_vec[i]))
            f0_onehot[i,IND] = 1.0
        else:
            f0_onehot[i,-1] = 1.0

    f0_onehot = np.reshape(f0_onehot,[1,-1,Nbins])
    return f0_onehot

def getF0fromActivations(f0_act,minf0=50,maxf0=500,Nbins=351):
    f0_gen = np.zeros((f0_act.shape[0]),dtype=np.float32)
    f0vec = np.exp(np.linspace(np.log(minf0),np.log(maxf0),Nbins-1))
    for i in range(f0_act.shape[0]):
        ind = np.argmax(f0_act[i,:])
        if ind < Nbins-1:
            f0_gen[i] = f0vec[ind]
        else:
            f0_gen[i] = 0
    return f0_gen

max_stars_repo_name: mairaksi/PiENet

max_issues_repo_name: zsscode/PiENet

max_forks_repo_name: zsscode/PiENet


text:
"""Test the trajectory integration"""
import functools

import chex
import jax
import jax.numpy as jnp
import numpy as np
from absl.testing import absltest, parameterized

import blackjax.mcmc.integrators as integrators
import blackjax.mcmc.metrics as metrics
import blackjax.mcmc.proposal as proposal
import blackjax.mcmc.termination as termination
import blackjax.mcmc.trajectory as trajectory

divergence_threshold = 1000

class TrajectoryTest(chex.TestCase):
    @chex.all_variants(with_pmap=False)
    @parameterized.parameters([(0.0001, False), (1000, True)])
    def test_dynamic_progressive_integration_divergence(
        self, step_size, should_diverge
    ):
        rng_key = jax.random.PRNGKey(0)

        def potential_fn(x):
            return -jax.scipy.stats.norm.logpdf(x)

        position = 1.0
        inverse_mass_matrix = jnp.array([1.0])

        (
            momentum_generator,
            kinetic_energy_fn,
            uturn_check_fn,
        ) = metrics.gaussian_euclidean(inverse_mass_matrix)

        integrator = integrators.velocity_verlet(potential_fn, kinetic_energy_fn)
        (
            new_criterion_state,
            update_criterion_state,
            is_criterion_met,
        ) = termination.iterative_uturn_numpyro(uturn_check_fn)

        trajectory_integrator = trajectory.dynamic_progressive_integration(
            integrator,
            kinetic_energy_fn,
            update_criterion_state,
            is_criterion_met,
            divergence_threshold,
        )

        # Initialize
        direction = 1
        initial_state = integrators.new_integrator_state(
            potential_fn, position, momentum_generator(rng_key, position)
        )
        initial_energy = initial_state.potential_energy + kinetic_energy_fn(
            initial_state.momentum
        )
        termination_state = new_criterion_state(initial_state, 10)
        max_num_steps = 100

        _, _, _, is_diverging, _ = self.variant(trajectory_integrator)(
            rng_key,
            initial_state,
            direction,
            termination_state,
            max_num_steps,
            step_size,
            initial_energy,
        )

        assert is_diverging.item() is should_diverge

    def test_dynamic_progressive_equal_recursive(self):
        rng_key = jax.random.PRNGKey(23132)

        def potential_fn(x):
            return (1.0 - x[0]) ** 2 + 1.5 * (x[1] - x[0] ** 2) ** 2

        inverse_mass_matrix = jnp.asarray([[1.0, 0.5], [0.5, 1.25]])
        (
            momentum_generator,
            kinetic_energy_fn,
            uturn_check_fn,
        ) = metrics.gaussian_euclidean(inverse_mass_matrix)

        integrator = integrators.velocity_verlet(potential_fn, kinetic_energy_fn)
        (
            new_criterion_state,
            update_criterion_state,
            is_criterion_met,
        ) = termination.iterative_uturn_numpyro(uturn_check_fn)
        (
            integrator,
            kinetic_energy_fn,
            update_criterion_state,
            is_criterion_met,
            uturn_check_fn,
        ) = (
            jax.jit(x)
            for x in (
                integrator,
                kinetic_energy_fn,
                update_criterion_state,
                is_criterion_met,
                uturn_check_fn,
            )
        )

        trajectory_integrator = trajectory.dynamic_progressive_integration(
            integrator,
            kinetic_energy_fn,
            update_criterion_state,
            is_criterion_met,
            divergence_threshold,
        )
        buildtree_integrator = trajectory.dynamic_recursive_integration(
            integrator,
            kinetic_energy_fn,
            uturn_check_fn,
            divergence_threshold,
        )

        for _ in range(50):
            (
                rng_key,
                rng_direction,
                rng_tree_depth,
                rng_step_size,
                rng_position,
                rng_momentum,
            ) = jax.random.split(rng_key, 6)
            direction = jax.random.choice(rng_direction, jnp.array([-1, 1]))
            tree_depth = jax.random.choice(rng_tree_depth, np.arange(2, 5))
            initial_state = integrators.new_integrator_state(
                potential_fn,
                jax.random.normal(rng_position, [2]),
                jax.random.normal(rng_momentum, [2]),
            )
            step_size = jnp.abs(jax.random.normal(rng_step_size, [])) * 0.1
            initial_energy = initial_state.potential_energy + kinetic_energy_fn(
                initial_state.momentum
            )

            termination_state = new_criterion_state(initial_state, tree_depth)
            (
                proposal0,
                trajectory0,
                _,
                is_diverging0,
                has_terminated0,
            ) = trajectory_integrator(
                rng_key,
                initial_state,
                direction,
                termination_state,
                2**tree_depth,
                step_size,
                initial_energy,
            )

            (
                _,
                proposal1,
                trajectory1,
                is_diverging1,
                has_terminated1,
            ) = buildtree_integrator(
                rng_key,
                initial_state,
                direction,
                tree_depth,
                step_size,
                initial_energy,
            )
            # Assert that the trajectory being built is the same
            jax.tree_map(
                functools.partial(np.testing.assert_allclose, rtol=1e-5),
                trajectory0,
                trajectory1,
            )
            assert is_diverging0 == is_diverging1
            assert has_terminated0 == has_terminated1
            # We dont expect the proposal to be the same (even with the same PRNGKey
            # as the order of selection is different). but the property associate
            # with the full trajectory should be the same.
            np.testing.assert_allclose(proposal0.weight, proposal1.weight, rtol=1e-5)
            np.testing.assert_allclose(
                proposal0.sum_log_p_accept, proposal1.sum_log_p_accept, rtol=1e-5
            )

    @chex.all_variants(with_pmap=False)
    @parameterized.parameters(
        [
            (0.0000000001, False, False, 10),
            (1, False, True, 2),
            (100000, True, True, 1),
        ],
    )
    def test_dynamic_progressive_expansion(
        self, step_size, should_diverge, should_turn, expected_doublings
    ):
        rng_key = jax.random.PRNGKey(0)

        def potential_fn(x):
            return 0.5 * x**2

        position = 0.0
        inverse_mass_matrix = jnp.array([1.0])

        (
            momentum_generator,
            kinetic_energy_fn,
            uturn_check_fn,
        ) = metrics.gaussian_euclidean(inverse_mass_matrix)

        integrator = integrators.velocity_verlet(potential_fn, kinetic_energy_fn)
        (
            new_criterion_state,
            update_criterion_state,
            is_criterion_met,
        ) = termination.iterative_uturn_numpyro(uturn_check_fn)

        trajectory_integrator = trajectory.dynamic_progressive_integration(
            integrator,
            kinetic_energy_fn,
            update_criterion_state,
            is_criterion_met,
            divergence_threshold,
        )

        expand = trajectory.dynamic_multiplicative_expansion(
            trajectory_integrator, uturn_check_fn
        )

        state = integrators.new_integrator_state(
            potential_fn, position, momentum_generator(rng_key, position)
        )
        energy = state.potential_energy + kinetic_energy_fn(state.momentum)
        initial_proposal = proposal.Proposal(state, energy, 0.0, -np.inf)
        initial_termination_state = new_criterion_state(state, 10)
        initial_trajectory = trajectory.Trajectory(
            state,
            state,
            state.momentum,
            0,
        )
        initial_expansion_state = trajectory.DynamicExpansionState(
            0, initial_proposal, initial_trajectory, initial_termination_state
        )

        expansion_state, (is_diverging, is_turning) = self.variant(expand)(
            rng_key, initial_expansion_state, energy, step_size
        )

        assert is_diverging == should_diverge
        assert expansion_state.step == expected_doublings
        assert is_turning == should_turn

if __name__ == "__main__":
    absltest.main()

max_stars_repo_name: rlouf/blackjax

max_issues_repo_name: rlouf/blackjax

max_forks_repo_name: rlouf/blackjax

reason: import numpy,import jax


text:
import numpy as np
import os
import shutil
import hashlib

from glob import glob

# A basic folder cache for Numpy objects
class BasicCache:
    # type = "lifo", "fifo", "fill"
    def __init__(self, cache_dir, size=10000, scheme="fill", clear=True, overwrite=False):
        self.basedir = os.path.abspath(cache_dir)
        self.size = size
        self.scheme = scheme
        self.overwrite = overwrite
        self.cache = {}
        self.times = []

        if clear:
            self.clear()

        os.makedirs(self.basedir, exist_ok=True)
        self._load_existing_cache()

    def key_hash(self, key):
        return hashlib.sha224(key.encode()).hexdigest()

    def _load_existing_cache(self):
        # We only cache numpy objects
        flist = glob(os.path.join(self.basedir, "*.npz"))

        for f in flist:
            h = os.path.splitext(os.path.basename(f))[0]

            if len(self.cache) < self.size:
                self.cache[h] = f
                self.times.append(h)

    def _get_filename(self, key):
        h = self.key_hash(key)
        return os.path.join(self.basedir, "{}.npz".format(h)), h

    def _prune_cache(self):
        # Remove an item from the cache according to scheme
        if len(self.cache) >= self.size:
            if self.scheme == "lifo":
                rm_idx = self.times.pop()
            elif self.scheme == "fifo":
                rm_idx = self.times.pop(0)
            else:
                return False

            rm_file = self.cache[rm_idx]
            # Remove the cached file
            if os.path.exists(rm_file):
                os.remove(rm_file)

            del self.cache[rm_idx]
        return True

    def clear(self):
        if os.path.exists(self.basedir):
            shutil.rmtree(self.basedir)

    def isin(self, key):
        _, h = self._get_filename(key)
        return h in self.times

    def __len__(self):
        return len(self.cache)

    def __getitem__(self, key):
        _, h = self._get_filename(key)

        if self.isin(key):
            fname = self.cache[h]
            data = np.load(fname, allow_pickle=True)

            if "arr_0" in data.files:
                return data["arr_0"]
            else:
                return {f: data[f] for f in data.files}

    def __setitem__(self, key, value):
        fname, h = self._get_filename(key)

        # Only add the item if it isn't already in the cache
        if (self.overwrite and h in self.times) or self._prune_cache():
            if isinstance(value, dict):
                np.savez(fname, **value)
            else:
                np.savez(fname, value)

            self.cache[h] = fname

            if h not in self.times:
                self.times.append(h)

if __name__=="__main__":
    cache = BasicCache("tmp_cache", size=100, scheme="fill", clear=True)

    # Create 120 random objects and cache them (only 100 should cache)
    for i in range(0, 120):
        cache[i] = np.random.rand(4, 4)

    for i in range(0, 120):
        data = cache[i]

        if data is not None:
            print(f"Retrieved {i} = {data.shape} form cache")
        else:
            print(f"{i} not in cache")

    cache2 = BasicCache("tmp_cache", size=100, scheme="fill", clear=False, overwrite=True)
    cache[45] = np.random.rand(10, 10)
    print(f"Retrieved without overwrite {cache[45].shape}")
    cache2[45] = np.random.rand(10, 10)
    print(f"Retrieved with overwrite {cache2[45].shape}")


text:
# coding: utf-8
# Copyright (c) Liam Huber
# Distributed under the terms of "New BSD License", see the LICENSE file.

import unittest
import numpy as np
from pygge.descriptors import PILArray, MangledDescriptor, TwoDee, Positive, Alignment

class Foo:
    man1 = MangledDescriptor('man1')
    man2 = MangledDescriptor('man2')
    td = TwoDee('td')
    pos = Positive('pos')
    allowable_values = [1, '2', [3, 4, 5], 'foo']
    location = Alignment('location')

    def __init__(self, td=None, td2=None, pos=None, location='upper left'):
        self.td = td
        self.td2 = td2
        self.pos = pos
        self.location = location

class TestDescriptors(unittest.TestCase):

    def setUp(self):
        self.foo = Foo()

    def test_pilarray(self):
        r = (10*np.random.rand(3)).view(PILArray)

        # Make sure math casting works
        self.assertTrue(np.all(isinstance(n, int) for n in r.inttuple))
        self.assertIsInstance(2.2 * r, PILArray)
        self.assertIsInstance(r + np.array([1, 2, 3]), PILArray)
        self.assertIsInstance(r + [1, 2, 3], PILArray)
        self.assertIsInstance(r + (1, 2, 3), PILArray)

        self.assertRaises(ValueError, getattr, np.random.rand(3, 3).view(PILArray), 'inttuple')  # Wrong shape

    def test_mangled_descriptor(self):
        # Ensure descriptor can be used multiple times on multiple instances without overwriting itself
        self.bar = Foo()

        self.foo.man1 = 'f1'
        self.foo.man2 = 'f2'
        self.bar.man1 = 'b1'

        self.assertEqual(self.foo.man1, 'f1')
        self.assertEqual(self.foo.man2, 'f2')
        self.assertEqual(self.bar.man1, 'b1')

    def test_twodee(self):
        td = TwoDee('name')
        td = [1, 2]
        self.assertRaises(ValueError, setattr, self.foo, 'td', [1, 2, 3])  # Too long

    def test_positive(self):
        pos = Positive('name')
        pos = [1, 2]
        self.assertRaises(ValueError, setattr, self.foo, 'pos', [1, 2, 3])  # Too long
        self.assertRaises(ValueError, setattr, self.foo, 'pos', [1, 0])  # Has a zero
        self.assertRaises(ValueError, setattr, self.foo, 'pos', [-1, 2])  # Has a negative

    def test_location(self):
        self.foo.location = 'upper left'
        self.assertTrue(self.foo.location.is_upper_left)
        self.assertFalse(self.foo.location.is_center)
        self.foo.location = 'center'
        self.assertFalse(self.foo.location.is_upper_left)
        self.assertTrue(self.foo.location.is_center)
        self.assertRaises(ValueError, setattr, self.foo, 'location', 'not a valid location')

max_stars_repo_name: liamhuber/pygge

max_issues_repo_name: liamhuber/pygge

max_forks_repo_name: liamhuber/pygge


text:
import numpy as np
import scipy.io
import matplotlib.pyplot as plt
from linearRegCost import linearRegCostFunction
from trainLinearReg import trainLinearReg
from learningCurve import learningCurve
from polyMappingFeature import poly_features, feature_normalize
from polyLearningCurve import poly_learning_curve
from validationCurve import validation_curve

############### (1) Loading and visualizing data ###################
print("Loading train/validation/test data set")

# Load training data
data = scipy.io.loadmat("data/ex5data1.mat")
X = data["X"]  # X: (12, 1)
y = data["y"]  # y: (12, 1)
X_vali = data["Xval"]  # X_vali: (21, 1)
y_vali = data["yval"]  # X_vali: (21, 1)
X_test = data["Xtest"]  # X_test: (21, 1)
y_test = data["ytest"]  # y_test: (21, 1)
m = X.shape[0]
X = np.hstack((np.ones((m, 1)), X))  # X: (m, n+1)

# Visualize training data set
print("\nVisualize training data set")
plt.plot(X[:, 1:], y, "x", color="red", markersize=15)
plt.xlabel("Change in water level (x)")
plt.ylabel("Water flowing out of dam (y)")
plt.show()

input("Press Enter to continue...")  # Stop for a moment

################ (2) Regularized linear regression cost #################
print("\nCompute cost function for regularized linear regression")

# Initialize parameter & add bias to X
theta = np.ones(shape=(X.shape[1], 1))

# Compute cost function
J, _ = linearRegCostFunction(theta, X, y, 1)

print(f'Cost at theta = [1 ; 1]: {J} \n(this value should be about 303.993192)')
input("Press Enter to continue...")  # Stop for a moment

################## (3) Regularized linear regression Gradient #################
print("\nCompute Gradient function for regularized linear regression")

# Initialize parameter & add bias to X
theta = np.ones(shape=(X.shape[1], 1))

# Compute cost function
(J, grad) = linearRegCostFunction(theta, X, y, 1)

print(f'Gradient at theta = [1 ; 1]: {grad[0, 0]}, {grad[1, 0]} '
      '\n(this value should be about [-15.303016; 598.250744])\n')
input("Press Enter to continue...")  # Stop for a moment

################# (4) Train linear regression ################
print("\nVisualize hypothesis lines trained by training data set.")
# Train linear regression with lambdas = 0
lambdas = 0
train_theta = trainLinearReg(X, y, lambdas)

# Plot hypothesis line fits to the data
plt.plot(X[:, 1:], y, "x", color="red", markersize=10)
plt.xlabel("Change in water level (x)")
plt.ylabel("Water flowing out of dam (y)")
plt.plot(X[:, 1], np.dot(X, train_theta), "--", color="blue", linewidth=3)
plt.show()
input("Press Enter to continue...")  # Stop for a moment

################### (5) Learning curve for linear regression #############
# Learning curve: represent Errors values of training and cross validation
# depending on each number of training example (from 1 to m)
print(f"\nVisualize learning curve for linear regression")
# Initialize parameter
lambdas = 0
X_vali = np.hstack((np.ones((X_vali.shape[0], 1)), X_vali))  # X_vali: (m_vali, n+1)
X_test = np.hstack((np.ones((X_test.shape[0], 1)), X_test))  # X_test: (m_test, n+1)

# Compute train and cv errors set
(error_train, error_val) = learningCurve(X, y, X_vali, y_vali, lambdas)

# Visualize train and cross validation ERRORS set
plt.plot(range(1, m+1), error_train, "-", color="blue")
plt.plot(range(1, m+1), error_val, "-", color="red")
plt.xlabel("Number of training example")
plt.ylabel("Cost function value")
plt.legend(("Training error", "Cross validation error"))
plt.show()

input("Press Enter to continue...")  # Stop for a moment

#################### (6) Feature mapping for Polynomial Regression ####################
print(f"\nMapping from linear regression to polynomial regression")
p = 8

# Mapping X from linear to p's polynomial & normalize
X_poly = poly_features(data["X"].reshape(X.shape[0]), p)
X_poly, mu, sigma = feature_normalize(X_poly)  # Normalize X -> X_poly: (m, p)
X_poly = np.hstack((np.ones((X_poly.shape[0], 1)), X_poly))  # X_poly: (m, p+1)

# Mapping X_test from linear to p's polynomial & normalize
X_poly_test = poly_features(data["Xtest"].reshape(X_test.shape[0]), p)
X_poly_test, _, _ = feature_normalize(X_poly_test)  # Normalize X
X_poly_test = np.hstack((np.ones((X_poly_test.shape[0], 1)), X_poly_test))  # X_poly_test: (m_test, p+1)

# Mapping X_vali from linear to p's polynomial & normalize
X_poly_vali = poly_features(data["Xval"].reshape(X_vali.shape[0]), p)
X_poly_vali, _, _ = feature_normalize(X_poly_vali)  # Normalize X
X_poly_vali = np.hstack((np.ones((X_poly_vali.shape[0], 1)), X_poly_vali))  # X_poly_vali (m_vali, p+1)

print(f"Normalized training example 1:\n{X_poly[1, :]}")
input(f"Press Enter to continue...")  # Stop for a moment

############## (7) Learning curve for the polynomial regression ###############
print(f"\nPlot learning curve for polynomial regression without regularization")
# Without regularization
lambdas = 0
poly_learning_curve(X, X_poly, y, X_poly_vali, y_vali, lambdas, p)

input(f"Press Enter to continue...")  # Stop for a moment

# With regularization
print(f"\nPlot learning curve for polynomial regression with regularization (lambdas=1)")
lambdas = 1
poly_learning_curve(X, X_poly, y, X_poly_vali, y_vali, lambdas, p)

# As a result, regularization help to solve overfitting problem by look at second plot
# Error of train and cv tend to be right on when m=4
input(f"Press Enter to continue...")  # Stop for a moment

################ (8) Select lambdas on Validation dataset #################
# Select best lambda based on polynomial regression by computing error of train and validation dataset
print(f"\nTest various value of lambdas on validation dataset --> Select the best lambda")
# Compute error of train and validation dataset based on diff value of lambda
lambda_vec, error_train, error_vali = validation_curve(X_poly, y, X_poly_vali, y_vali)

# Visualize error corresponding to value of lambdas
plt.plot(lambda_vec, error_train, color="blue", linewidth=2)
plt.plot(lambda_vec, error_vali, color="red", linewidth=2)
plt.xlabel("Lambda")
plt.ylabel("Error (cost function) values")
plt.legend(("Training set error", "Validation set error"))
plt.show()

# Showing error (Cost value) result relating to lambdas value
print(f"Lambda\tTraining error\tValidation error")
for i in range(len(lambda_vec)):
      print(f'{lambda_vec[i]}\t{error_train[i]}\t{error_vali[i]}')

# Result: as lambdas = 1, the error of training and validation dataset are nearly the same (Solving overfitting)
# --> lambda = 1 is the best value to apply for regularization
# (NOTE) Error: cost value (Not diff between y and predicting val)

reason: import numpy,import scipy


text:
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 25 22:07:43 2018

@author: the.kim
"""

import tensorflow as tf
import numpy as np
from tensorflow.python.ops import variable_scope
from tensorflow.python.ops import init_ops
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import variables
from tensorflow.python.ops import variables
from tensorflow.contrib.rnn.python.ops import rnn_cell

res = []

with tf.Session() as sess:
    with variable_scope.variable_scope("other", initializer=init_ops.constant_initializer(0.5)) as vs:
        x = array_ops.zeros([1,3])
        c = array_ops.zeros([1,2])
        h = array_ops.zeros([1,2])
        state = (c,h)
        cell = rnn_cell.LayerNormBasicLSTMCell(2,layer_norm=False)
        g, out_m = cell(x,state)
        sess.run([variables.global_variables_initializer()])
        res = sess.run( [g,out_m], { x.name: np.array([[1.,1.,1.]]), c.name: 0.1 * np.asarray([[0,1]]), h.name: 0.1*np.asarray([[2,3]]) })

print( res[1].c )
print( res[1].h )

max_stars_repo_name: aimldl/coding

max_issues_repo_name: aimldl/coding

max_forks_repo_name: aimldl/coding


text:
import numpy as np
from matplotlib import pyplot as plt
import time

class Plotter:
	def __init__(self, id):
		self.id = id
		self.initialize_canvas()

	def initialize_canvas(self):
		plt.ion()
		self.fig = plt.figure()
		self.ay = self.fig.add_subplot(211)
		self.dline, = plt.plot([0], [0])
		# ay.set_xlim([-1, 99])
		# ay.set_ylim([0,220])
		self.ax = self.fig.add_subplot(212)
		self.dlinef, = plt.plot([0], [0])
		plt.show(block=False)

		self.data1 = np.array([0])
		self.freq = np.array([0])

	def update_canvas(self, time, data, data2):
		self.dline.set_xdata(time)
		self.dline.set_ydata(data)
		self.ay.set_xlim([min(time), max(time)])
		self.ay.set_ylim([min(data), max(data)])

		# self.dlinef.set_xdata(self.freq)
		# self.dlinef.set_ydata(10 * np.log(self.data1))
		# self.ax.set_xlim([min(self.freq), max(self.freq)])
		# self.ax.set_ylim([-20, 20.0])

		self.dlinef.set_xdata(time)
		self.dlinef.set_ydata(data2)
		self.ax.set_xlim([min(time), max(time)])
		self.ax.set_ylim([min(data2), max(data2)])

		self.fig.canvas.draw()

	def update_canvasf(self, freq, data1):
		self.freq = freq
		self.data1 = data1

max_stars_repo_name: GEverding/touchVision

max_issues_repo_name: GEverding/touchVision

max_forks_repo_name: GEverding/touchVision


text:
import cv2
import numpy as np

def Homography(img, prev_img):

    if prev_img is None:
        return

    orb = cv2.ORB_create()
    kpt1, des1 = orb.detectAndCompute(prev_img, None)
    kpt2, des2 = orb.detectAndCompute(img, None)

    bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
    matches = bf.match(des1, des2)
    matches = sorted(matches, key=lambda x: x.distance)

    src_pts = np.float32([kpt1[m.queryIdx].pt for m in matches]).reshape(-1, 1, 2)
    dst_pts = np.float32([kpt2[m.trainIdx].pt for m in matches]).reshape(-1, 1, 2)

    M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
    return M

max_stars_repo_name: youngbin-ro/Homography-Based-MOTDT

max_issues_repo_name: youngbin-ro/MOTDT-original

max_forks_repo_name: youngbin-ro/MOTDT-original