def generate_noisy_gaussian(center, std_dev, height, x_domain, noise_domain,
                            n_datapoints):
    """
    Generate a gaussian with some aspect of noise.

    Input:
        center = central x value
        std_dev = standard deviation of the function
        height = height (y-off set) of the function
        noise_range = uniform random distribution of noise from perfect gauss function
        x_range = absolute domain of the gaussian function 
        n_datapoints = total number of input datapoints of gaussian function
    Output: x_values,y_values
        x_values = the x-axial array of the gaussian function within the domain
        y_values = the y-axial array of the gaussian function within the domain
    """
    # Type check.
    center = valid.validate_float_value(center)
    std_dev = valid.validate_float_value(std_dev, greater_than=0)
    height = valid.validate_float_value(height)
    x_domain = valid.validate_float_array(x_domain, shape=(2,), size=2)
    noise_domain = valid.validate_float_array(noise_domain, shape=(2,), size=2)
    n_datapoints = valid.validate_int_value(n_datapoints, greater_than=0)

    # Generate the gaussian function and map to an output with the input
    # parameters.
    x_values, y_values = generate_gaussian(center, std_dev, height,
                                           x_domain=x_domain,
                                           n_datapoints=n_datapoints)

    # Imbue the gaussian with random noise.
    y_values = misc.generate_noise(y_values, noise_domain,
                                   distribution='uniform')

    return x_values, y_values
def generate_noisy_bessel_1st(order,
                              x_domain,
                              noise_domain,
                              n_datapoints,
                              distribution='uniform'):
    """
    This function generates a noisy bessel function of the first kind given
    a real order.

    Input:
    order = The real order of the bessel function
    x_domain = The range of x_values that should be plotted.
    noise_domain = The domain the noise is allowed to spread around.
    n_datapoints = The number of data points that is desired.
    distribution = The method of noise distribution.

    Output:
    y_output = The values of the function after noise.    
    """

    # Type check.
    order = valid.validate_float_value(order)
    x_domain = valid.validate_float_array(x_domain, shape=(2, ), size=2)
    noise_domain = valid.validate_float_array(noise_domain,
                                              shape=(2, ),
                                              size=2)
    distribution = valid.validate_string(distribution)

    # Generate the input values. Make sure the first element is the lower
    # element.
    x_domain = np.sort(x_domain)
    x_input = np.random.uniform(x_domain[0], x_domain[-1], n_datapoints)

    # Generate values for the bessel function.
    y_output = bessel_function_1st(x_input, order)

    # Imbue the values with noise.
    y_output = misc.generate_noise(y_output,
                                   noise_domain,
                                   distribution=distribution)

    # Sort the values for ease of plotting and computation.
    sort_index = np.argsort(x_input)
    x_input = x_input[sort_index]
    y_output = y_output[sort_index]

    return np.array(x_input, dtype=float), np.array(y_output, dtype=float)
def generate_noisy_dual_dimension_gaussian(centers,
                                           std_devs,
                                           height,
                                           n_datapoints,
                                           x_domain,
                                           y_domain,
                                           noise_domain,
                                           dimensions=2):
    """
    This generates a noisy 2D gaussian.
    """

    # Type check
    dimensions = valid.validate_int_value(dimensions, greater_than=0)
    centers = valid.validate_float_array(centers,
                                         shape=(dimensions, ),
                                         size=dimensions)
    std_devs = valid.validate_float_array(std_devs,
                                          shape=(dimensions, ),
                                          size=dimensions,
                                          deep_validate=True,
                                          greater_than=0)
    height = valid.validate_float_value(height)
    n_datapoints = valid.validate_int_value(n_datapoints, greater_than=0)
    x_domain = valid.validate_float_array(x_domain, shape=(2, ), size=2)
    y_domain = valid.validate_float_array(y_domain, shape=(2, ), size=2)
    noise_domain = valid.validate_float_array(noise_domain,
                                              shape=(2, ),
                                              size=2)

    # Generate the 2D gaussian.
    points = generate_dual_dimension_gaussian(centers, std_devs, height,
                                              n_datapoints, x_domain, y_domain)

    # Imbue the z points (2 index) with noise.
    points[2] = misc.generate_noise(points[2], noise_domain)

    return points
def generate_noisy_multigaussian(center_list, std_dev_list, height_list,
                                 noise_domain_list, x_domain, n_datapoints,
                                 gaussian_count=None, cumulative_noise=False):
    """
    Generate multiple gaussians with some aspect of noise within one 
    dataset.

    Input:
    center_list = list of central x values
    std_dev_list = list of standard deviations of the functions
    height_list = list of heights (y-off set) of the functions
    noise_domain_list = list of uniform random distribution of noise 
        from perfect gauss function
    x_domain_list = absolute domains of the gaussian functions
    n_datapoints = total number of datapoints
    n_datapoints_list = list of number of datapoints (overrides 
        n_datapoints)
    gaussian_count = the number of gaussian functions to be made
    cumulative_noise = if each gaussian has noise (True), or just the 
         entire set (False).

    Output: x_values,y_values
    x_values = the x-axial array of the gaussian function within the 
        domain
    y_values = the y-axial array of the gaussian function within the 
        domain
    """

    # Assume the center list is the highest priority (but check the
    # std_dev) for double checking the gaussian count.
    if (gaussian_count is None):
        gaussian_count = len(center_list)
        # Double check with std_dev
        if ((gaussian_count != len(std_dev_list)) or
                (len(std_dev_list) != len(center_list))):
            raise InputError('The number of gaussians to generate is not '
                             'known, nor can it be accurately derived from '
                             'the inputs given.    --Kyubey')

    # Type check.
    center_list = valid.validate_float_array(center_list, size=gaussian_count)
    std_dev_list = valid.validate_float_array(
        std_dev_list, size=gaussian_count)
    height_list = valid.validate_float_array(height_list, size=gaussian_count)
    noise_domain_list = valid.validate_float_array(noise_domain_list,
                                                   shape=(gaussian_count, 2))
    x_domain = valid.validate_float_array(x_domain,
                                          shape=(2,), size=2)
    cumulative_noise = valid.validate_boolean_value(cumulative_noise)
    n_datapoints = valid.validate_int_value(n_datapoints, greater_than=0)

    # Type check optional elements
    gaussian_count = valid.validate_int_value(gaussian_count, greater_than=0)
    cumulative_noise = valid.validate_boolean_value(cumulative_noise)

    # Initialize initial variables.
    x_values = []
    y_values = []

    # Check how to distribute noise.
    if (cumulative_noise):
        # Each gaussian must be generated on its own.
        for gaussiandex in range(gaussian_count):
            # Generate gaussian.
            temp_x_values, temp_y_values = \
                generate_gaussian(center_list[gaussiandex],
                                  std_dev_list[gaussiandex],
                                  height_list[gaussiandex],
                                  x_domain,
                                  np.ceil(n_datapoints / gaussian_count))
            temp_y_values = misc.generate_noise(temp_y_values,
                                                noise_domain_list[gaussiandex],
                                                distribution='uniform')
            # Store for return
            x_values = np.append([x_values], [temp_x_values], axis=0)
            y_values = np.append([y_values], [temp_y_values], axis=0)

        # Maximize the values, discarding everything lower than.
        x_values = np.amax(x_values, axis=0)
        y_values = np.amax(y_values, axis=0)

    else:
        # Generate noise of every point after gaussian generation.
        # Generate gaussian
        x_values, y_values = generate_multigaussian(center_list, std_dev_list,
                                                    height_list, x_domain,
                                                    gaussian_count,
                                                    np.ceil(n_datapoints /
                                                            gaussian_count))

        # Generate noise. Warn the user that only the first noise domain is
        # being used.
        kyubey_warning(OutputWarning, ('Only the first element of the '
                                       'noise_domian_list is used if '
                                       'cumulative_noise is False.'
                                       '    --Kyubey'))
        y_values = misc.generate_noise(y_values, noise_domain_list[0],
                                       distribution='uniform')

    return np.array(x_values, dtype=float), np.array(y_values, dtype=float)