# Common imports
import numpy as np
import pandas as pd

def FrankeFunction(x,y):
	term1 = 0.75*np.exp(-(0.25*(9*x-2)**2) - 0.25*((9*y-2)**2))
	term2 = 0.75*np.exp(-((9*x+1)**2)/49.0 - 0.1*(9*y+1))
	term3 = 0.5*np.exp(-(9*x-7)**2/4.0 - 0.25*((9*y-3)**2))
	term4 = -0.2*np.exp(-(9*x-4)**2 - (9*y-7)**2)
	return term1 + term2 + term3 + term4

def create_X(x, y, n ):
	if len(x.shape) > 1:
		x = np.ravel(x)
		y = np.ravel(y)

	N = len(x)
	l = int((n+1)*(n+2)/2)		# Number of elements in beta
	X = np.ones((N,l))

	for i in range(1,n+1):
		q = int((i)*(i+1)/2)
		for k in range(i+1):
			X[:,q+k] = (x**(i-k))*(y**k)

	return X

# Making meshgrid of datapoints and compute Franke's function
n = 4
N = 1000
x = np.sort(np.random.uniform(0, 1, N))
y = np.sort(np.random.uniform(0, 1, N))
z = FrankeFunction(x, y)
X = create_X(x, y, n=n)

Xpd = pd.DataFrame(X)
Xpd = Xpd - Xpd.mean()
correlation_matrix = Xpd.cov()
print(correlation_matrix)


# pylint: disable=W0223
# IMPORTS SECTION #

import numpy as np
import torch
from torch.autograd import Variable

# SYNTHETIC DATA PREPARATION #

x_values = [i for i in range(11)]

x_train = np.array(x_values, dtype=np.float32)
x_train = x_train.reshape(-1, 1)

y_values = [2 * i + 1 for i in x_values]

y_train = np.array(y_values, dtype=np.float32)
y_train = y_train.reshape(-1, 1)

# DEFINING THE NETWORK FOR REGRESSION #

class LinearRegression(torch.nn.Module):
    def __init__(self, inputSize, outputSize):
        super(LinearRegression, self).__init__()
        self.linear = torch.nn.Linear(inputSize, outputSize)

    def forward(self, x):
        out = self.linear(x)
        return out

def main():
    # SECTION FOR HYPERPARAMETERS #

    inputDim = 1
    outputDim = 1
    learningRate = 0.01
    epochs = 100

    # INITIALIZING THE MODEL #

    model = LinearRegression(inputDim, outputDim)

    # FOR GPU #
    if torch.cuda.is_available():
        model.cuda()

    # INITIALIZING THE LOSS FUNCTION AND OPTIMIZER #

    criterion = torch.nn.MSELoss()
    optimizer = torch.optim.SGD(model.parameters(), lr=learningRate)

    # TRAINING STEP #

    for epoch in range(epochs):
        # Converting inputs and labels to Variable
        if torch.cuda.is_available():
            inputs = Variable(torch.from_numpy(x_train).cuda())
            labels = Variable(torch.from_numpy(y_train).cuda())
        else:
            inputs = Variable(torch.from_numpy(x_train))
            labels = Variable(torch.from_numpy(y_train))

        optimizer.zero_grad()
        outputs = model(inputs)

        loss = criterion(outputs, labels)

        loss.backward()
        optimizer.step()
        print("epoch {}, loss {}".format(epoch, loss.item()))

    # EVALUATION AND PREDICTION #

    with torch.no_grad():
        if torch.cuda.is_available():
            predicted = model(Variable(torch.from_numpy(x_train).cuda())).cpu().data.numpy()
        else:
            predicted = model(Variable(torch.from_numpy(x_train))).data.numpy()
        print(predicted)

    # SAVING THE MODEL #
    torch.save(model.state_dict(), "tests/resources/linear_state_dict.pt")
    torch.save(model, "tests/resources/linear_model.pt")


import tensorflow as tf
import tensorflow_probability as tfp
import keras.backend as K
import numpy as np

def gaussian_layer(layer):

    dim_layer = len(layer.get_shape())
    param1, param2 = tf.unstack(layer, num=dim_layer, axis=-1)
    param1 = tf.expand_dims(param1, -1)
    param2 = tf.expand_dims(param2, -1)

    #apply softplus to bound between -1 and 1
    mu = tf.keras.activations.linear(param1)
    #mean =  tf.keras.activations.softsign(a)
    var = tf.keras.activations.elu(param2) + 1
    #b = tf.nn.elu(a) + 1

    out_tensor = tf.concat((mu, var), axis = dim_layer-1)

    return out_tensor

def gaussian_layer_2d(layer):

    dim_layer = len(layer.get_shape())
    param1, param2 = tf.unstack(layer, num=dim_layer, axis=-1)
    param1 = tf.expand_dims(param1, -1)
    param2 = tf.expand_dims(param2, -1)

    mu = tf.keras.activations.linear(param1)
    #mean =  tf.keras.activations.softsign(a)
    var = tf.keras.activations.elu(param2) + 1

    out_tensor = tf.concat((mu, var), axis = dim_layer-1)

    return out_tensor

def gaussian_loss(y_true, y_pred):

  par1, par2 = tf.unstack(y_pred, num=2, axis=-1)
  mu = tf.expand_dims(par1, -1)
  var = tf.expand_dims(par2, -1)
  dist = tfp.distributions.Normal(loc=mu, scale=var)
  #dist = tfp.distributions.Normal(loc=mu, scale=sigma)

  return tf.reduce_mean(-dist.log_prob(y_true))

def gaussian_nll(ytrue, ypreds):
    """Keras implmementation of multivariate Gaussian negative loglikelihood loss function.
    This implementation implies diagonal covariance matrix.

    Parameters
    ----------
    ytrue: tf.tensor of shape [n_samples, n_dims]
        ground truth values
    ypreds: tf.tensor of shape [n_samples, n_dims*2]
        predicted mu and logsigma values (e.g. by your neural network)

    Returns
    -------
    neg_log_likelihood: float
        negative loglikelihood averaged over samples

    This loss can then be used as a target loss for any keras model, e.g.:
        model.compile(loss=gaussian_nll, optimizer='Adam')

    """

    #n_dims = int(int(ypreds.shape[1])/2)

    #mu = ypreds[:, 0:n_dims]
    #logsigma = ypreds[:, n_dims:]
    dims = ypreds.shape[1]
    mu = ypreds[:,0:1]
    logsigma = ypreds[:, 1:]

    mse = -0.5*K.sum(K.square((ytrue-mu)/K.exp(logsigma)),axis=1)
    sigma_trace = -K.sum(logsigma, axis=1)
    log2pi = -0.5*dims*np.log(2*np.pi)

    log_likelihood = mse+sigma_trace+log2pi

    return K.mean(-log_likelihood)


import numpy as np
import math

def rosenbrock(x):
    a = x[0:x.size - 1] ** 2 - x[1:x.size]
    b = x - 1
    return -(100 * np.inner(a, a) + np.inner(b, b))

def schwefel(x):
    fit = 0
    for i in range(x.size):
        fit += (x[0:i+1].sum()) ** 2
    return -fit

def ackley(x):
    return -(-20 * np.exp(-0.2 * np.sqrt(np.inner(x, x) / x.size)) - np.exp(
        np.cos(2 * np.pi * x).sum() / x.size) + 20 + np.e)

alpha = [1.00, 1.20, 3.00, 3.20]
A = np.array([[10.00, 3.00, 17.00, 3.50, 1.70, 8.00],
              [0.05, 10.00, 17.00, 0.10, 8.00, 14.00],
              [3.00, 3.50, 1.70, 10.00, 17.00, 8.00],
              [17.00, 8.00, 0.05, 10.00, 0.10, 14.00]])
P = 0.0001 * np.array([[1312, 1696, 5569, 124, 8283, 5886],
                       [2329, 4135, 8307, 3736, 1004, 9991],
                       [2348, 1451, 3522, 2883, 3047, 6650],
                       [4047, 8828, 8732, 5743, 1091, 381]])
def hartmann(x):
    """6d Hartmann test function
        input bounds:  0 <= xi <= 1, i = 1..6
        global optimum: (0.20169, 0.150011, 0.476874, 0.275332, 0.311652, 0.6573),
        min function value = -3.32237
    """
    external_sum = 0
    for i in range(4):
        internal_sum = 0
        for j in range(6):
            internal_sum = internal_sum + A[i, j] * (x[j] - P[i, j]) ** 2
        external_sum = external_sum + alpha[i] * np.exp(-internal_sum)

    return -external_sum

def Levy(x):
    # ref: http://www.sfu.ca/~ssurjano/levy.html
    x = np.array(x)
    w = [1.0 + (xi - 1.0) / 4.0 for xi in x]

    s0 = (math.sin(math.pi * w[0])) ** 2

    s1 = 0.0
    d = x.size
    for i in range(d - 1):
        s1 += (((w[i] - 1.0) ** 2) * (1.0 + 10.0 * (math.sin(math.pi * w[i] + 1.0)) ** 2))

    s2 = ((w[d - 1] - 1.0) ** 2) * (1.0 + (math.sin(2.0 * math.pi * w[d - 1])) ** 2)

    return -(s0 + s1 + s2)

def Rastrigin(x):
    #ref: http://www.sfu.ca/~ssurjano/rastr.html
    x = np.array(x)
    sum = 10.0 * x.size
    for xi in x:
        sum += ( xi**2 - 10.0 * math.cos(2.0*math.pi * xi)  )
    return -sum

def Hartmann6D(x):
    # ref https://www.sfu.ca/~ssurjano/hart6.html
    alpha = [1.0, 1.2, 3.0, 3.2];
    A = [[10, 3, 17, 3.5, 1.7, 8],
         [0.05, 10, 17, 0.1, 8, 14],
         [3, 3.5, 1.7, 10, 17, 8],
         [17, 8, 0.05, 10, 0.1, 14]]

    # 10^(-4) *
    P = [
        [1312, 1696, 5569, 124, 8283, 5886],
        [2329, 4135, 8307, 3736, 1004, 9991],
        [2348, 1451, 3522, 2883, 3047, 6650],
        [4047, 8828, 8732, 5743, 1091, 381]]

    outer = 0.0
    for ii in range(4):
        inner = 0.0
        for jj in range(6):
            xj = x[jj]
            Aij = A[ii][jj]
            Pij = P[ii][jj] * 1.0e-4
            inner = inner + Aij * (xj - Pij) ** 2;
        new = alpha[ii] * np.exp(-inner);
        outer = outer + new;

    y = -(2.58 + outer) / 1.94;
    return -y


"""

Path Planner with B-Spline

author: Atsushi Sakai (@Atsushi_twi)

"""

import numpy as np
import matplotlib.pyplot as plt
import scipy.interpolate as scipy_interpolate

def approximate_b_spline_path(x: list, y: list, n_path_points: int,
                              degree: int = 3) -> tuple:
    """
    approximate points with a B-Spline path

    :param x: x position list of approximated points
    :param y: y position list of approximated points
    :param n_path_points: number of path points
    :param degree: (Optional) B Spline curve degree
    :return: x and y position list of the result path
    """
    t = range(len(x))
    x_tup = scipy_interpolate.splrep(t, x, k=degree)
    y_tup = scipy_interpolate.splrep(t, y, k=degree)

    x_list = list(x_tup)
    x_list[1] = x + [0.0, 0.0, 0.0, 0.0]

    y_list = list(y_tup)
    y_list[1] = y + [0.0, 0.0, 0.0, 0.0]

    ipl_t = np.linspace(0.0, len(x) - 1, n_path_points)
    rx = scipy_interpolate.splev(ipl_t, x_list)
    ry = scipy_interpolate.splev(ipl_t, y_list)

    return rx, ry

def interpolate_b_spline_path(x: list, y: list, n_path_points: int,
                              degree: int = 3) -> tuple:
    """
    interpolate points with a B-Spline path

    :param x: x positions of interpolated points
    :param y: y positions of interpolated points
    :param n_path_points: number of path points
    :param degree: B-Spline degree
    :return: x and y position list of the result path
    """
    ipl_t = np.linspace(0.0, len(x) - 1, len(x))
    spl_i_x = scipy_interpolate.make_interp_spline(ipl_t, x, k=degree)
    spl_i_y = scipy_interpolate.make_interp_spline(ipl_t, y, k=degree)

    travel = np.linspace(0.0, len(x) - 1, n_path_points)
    return spl_i_x(travel), spl_i_y(travel)

def main():
    print(__file__ + " start!!")
    # way points
    way_point_x = [-1.0, 3.0, 4.0, 2.0, 1.0]
    way_point_y = [0.0, -3.0, 1.0, 1.0, 3.0]
    n_course_point = 100  # sampling number

    rax, ray = approximate_b_spline_path(way_point_x, way_point_y,
                                         n_course_point)
    rix, riy = interpolate_b_spline_path(way_point_x, way_point_y,
                                         n_course_point)

    # show results
    plt.plot(way_point_x, way_point_y, '-og', label="way points")
    plt.plot(rax, ray, '-r', label="Approximated B-Spline path")
    plt.plot(rix, riy, '-b', label="Interpolated B-Spline path")
    plt.grid(True)
    plt.legend()
    plt.axis("equal")
    plt.show()

if __name__ == '__main__':
    main()


#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

import math
import numpy as np

# Basic trigonometry
# -----------------------------------------------------------------

def normalize(v, tolerance=0.00001):
    mag2 = sum(n * n for n in v)
    if abs(mag2 - 1.0) > tolerance:
        mag = math.sqrt(mag2)
        if mag == 0.0:
            return None
        v = tuple(n / mag for n in v)
    return np.array(v)

def dot(v1, v2):
    n = 0
    lim = min( len(v1) , len(v2) )
    for i in range(lim):
        n += v1[i] * v2[i]
    return n

def length(v):
    return math.sqrt(sum(n * n for n in v))

def distance(A, B):
    ab = np.array(B) - np.array(A)
    return np.sqrt( ab[0] * ab[0] + ab[1] * ab[1] )

def perpendicular(A, B):
    ab = np.array(B) - np.array(A)
    dir_ab = normalize(ab)
    return np.array([-dir_ab[1], dir_ab[0]])

def rotate(xy, deg, anchor=[0, 0]):
    radians = math.radians(deg)
    x, y = xy

    x = x - anchor[0]
    y = y - anchor[1]
    cos_rad = math.cos(radians)
    sin_rad = math.sin(radians)
    qx = anchor[0] + cos_rad * x + sin_rad * y
    qy = anchor[1] + -sin_rad * x + cos_rad * y

    return np.array([qx, qy])

def clamp(value, min_value, max_value):
    return max(min(value, max_value), min_value)

def transform(xy, rotate = 0, scale = [1,1], translate = [0,0], anchor=[0, 0]):
    x, y = xy

    if scale != [1, 1] or rotate != 0:
        radians = math.radians(rotate)
        if isinstance(scale, tuple) or isinstance(scale, list):
            scale_x, scale_y = scale
        else:
            scale_x, scale_y = scale, scale

        x = x - anchor[0]
        y = y - anchor[1]

        cos_theta = math.cos(radians)
        sin_theta = math.sin(radians)
        nx = x * cos_theta - y * sin_theta
        ny = x * sin_theta + y * cos_theta

        nx *= scale_x
        ny *= scale_y

        nx += anchor[0]
        ny += anchor[1]
    else:
        nx = x
        ny = y

    nx += translate[0]
    ny += translate[1]
    return [nx, ny]

def remap(value, in_min, in_max, out_min, out_max):
    in_span = in_max - in_min
    out_span = out_max - out_min

    value = float(value - in_min)
    if value != 0:
        value /= float(in_span)
    return out_min + (value * out_span)

def lerp(A, B, t):
    A = np.array(A)
    B = np.array(B)
    return A * (1.0 - t) + B * t

# Path operations
# -----------------------------------------------------------------

def points_length(points):
    result = 0
    for (x1, y1), (x2, y2) in zip(points, points[1:]):
        result += math.hypot(x2 - x1, y2 - y1)
    return result

def path_length(path):
    return sum([points_length(path) for path in path], 0)

def join_path(path, tolerance):
    if len(path) < 2:
        return path
    result = [list(path[0])]
    for path in path[1:]:
        x1, y1 = result[-1][-1]
        x2, y2 = path[0]
        d = hypot(x2 - x1, y2 - y1)
        if d <= tolerance:
            result[-1].extend(path)
        else:
            result.append(list(path))
    return result

# Convertions
# -----------------------------------------------------------------

def polar2xy(center, angle, radius):
    a = math.radians(angle)
    rx = 1.0
    ry = 1.0
    if isinstance(radius, tuple) or isinstance(radius, list):
        rx = radius[0]
        ry = radius[1]
    else:
        rx = radius
        ry = radius
    return np.array([   center[0] + rx * math.cos(a),
                        center[1] + ry * math.sin(a)    ])

def xy2polar(center, pos):
    ab = np.array(pos) - np.array(center)

    dist = np.sqrt( ab[0] * ab[0] + ab[1] * ab[1] )

    angle = math.atan2(ab[1], ab[0])
    return [math.degrees(angle), dist]

# Bezier controls
# -----------------------------------------------------------------

def lineProp( pointA, pointB ):
    lengthX = pointB[0] - pointA[0]
    lengthY = pointB[1] - pointA[1]
    return math.sqrt( math.pow(lengthX, 2) + math.pow(lengthY, 2)), math.atan2(lengthY, lengthX)

def controlPoint( current, _previous, _next, reverse ):
    p = _previous
    n = _next

    if _previous is None:
        p = current
    if _next is None:
        n = current

    smoothing = 0.2
    o = lineProp(p, n)

    angle = o[1]
    if reverse:
        angle += math.pi
    length = o[0] * smoothing

    x = current[0] + math.cos(angle) * length
    y = current[1] + math.sin(angle) * length

    return [x, y]

def bezierCommand( point, i, a ):
    #  start control point
    cpsX, cpsY = controlPoint(a[i - 1], a[i - 2], point, False)

    #  end control point
    if i + 1 >= len(a):
        cpeX, cpeY = controlPoint(point, a[i - 1], None, True)
    else:
        cpeX, cpeY = controlPoint(point, a[i - 1], a[i + 1], True)

    return ' C ' + str(cpsX) + ',' + str(cpsY) + " " + str(cpeX) + "," + str(cpeY) + " " + str(point[0]) + "," + str(point[1])

# Collisions

#  https://github.com/openframeworks/openFrameworks/blob/patch-release/libs/openFrameworks/graphics/ofPolyline.inl#L622
def pointInside( pos, points ):
    counter = 0

    # double xinters;
    p1 = [0.0, 0.0]
    p2 = [0.0, 0.0]

    N = len(points)

    p1 = points[0]

    for i in range(1, N + 1):
        p2 = points[i % N]

        if pos[1] > min(p1[1], p2[1]):
            if pos[1] <= max(p1[1], p2[1]):
                if pos[0] <= max(p1[0], p2[0]):
                    if p1[1] != p2[1]:
                        xinters = (pos[1] - p1[1]) * (p2[0] - p1[0]) / (p2[1] - p1[1]) + p1[0]
                        if p1[0] == p2[0] or pos[0] <= xinters:
                            counter += 1
        p1 = p2

    return counter % 2 != 0

# https://github.com/openframeworks/openFrameworks/blob/master/libs/openFrameworks/math/ofMath.h#L435
def linesIntersection(line1Start, line1End, line2Start, line2End):
    intersection = [0.0, 0.0]
    diffLA = np.array(line1End) - np.array(line1Start)
    compareA = diffLA[0] * line1Start[1] - diffLA[1] * line1Start[0]
    if ( ( diffLA[0]*line2Start[1] - diffLA[1]*line2Start[0] ) < compareA ) ^ ( ( diffLA[0]*line2End[1] - diffLA[1]*line2End[0] ) < compareA ):

        diffLB = np.array(line2End) - np.array(line2Start)
        compareB = diffLB[0] * line2Start[1] - diffLB[1] * line2Start[0]
        if ( ( diffLB[0]*line1Start[1] - diffLB[1]*line1Start[0] ) < compareB ) ^ ( ( diffLB[0]*line1End[1] - diffLB[1]*line1End[0]) < compareB ):
            lDetDivInv = 1 / ((diffLA[0] * diffLB[1]) - (diffLA[1] * diffLB[0]))
            intersection[0] =  -((diffLA[0] * compareB) - (compareA * diffLB[0])) * lDetDivInv
            intersection[1] =  -((diffLA[1] * compareB) - (compareA * diffLB[1])) * lDetDivInv
            return intersection

    return None

# PARSING SVGs files

def dom2dict(element):
    """Converts DOM elements to dictionaries of attributes."""
    keys = list(element.attributes.keys())
    values = [val.value for val in list(element.attributes.values())]
    return dict(list(zip(keys, values)))

#  From Andy Port's svgpathtools
# https://github.com/mathandy/svgpathtools/blob/master/svgpathtools/parser.py#L221
#
def _parse_transform_substr(transform_substr):

    type_str, value_str = transform_substr.split('(')
    value_str = value_str.replace(',', ' ')
    values = list(map(float, filter(None, value_str.split(' '))))

    transform = np.identity(3)
    if 'matrix' in type_str:
        if not _check_num_parsed_values(values, [6]):
            return transform

        transform[0:2, 0:3] = np.array([values[0:6:2], values[1:6:2]])

    elif 'translate' in transform_substr:
        if not _check_num_parsed_values(values, [1, 2]):
            return transform

        transform[0, 2] = values[0]
        if len(values) > 1:
            transform[1, 2] = values[1]

    elif 'scale' in transform_substr:
        if not _check_num_parsed_values(values, [1, 2]):
            return transform

        x_scale = values[0]
        y_scale = values[1] if (len(values) > 1) else x_scale
        transform[0, 0] = x_scale
        transform[1, 1] = y_scale

    elif 'rotate' in transform_substr:
        if not _check_num_parsed_values(values, [1, 3]):
            return transform

        angle = values[0] * np.pi / 180.0
        if len(values) == 3:
            offset = values[1:3]
        else:
            offset = (0, 0)
        tf_offset = np.identity(3)
        tf_offset[0:2, 2:3] = np.array([[offset[0]], [offset[1]]])
        tf_rotate = np.identity(3)
        tf_rotate[0:2, 0:2] = np.array([[np.cos(angle), -np.sin(angle)], [np.sin(angle), np.cos(angle)]])
        tf_offset_neg = np.identity(3)
        tf_offset_neg[0:2, 2:3] = np.array([[-offset[0]], [-offset[1]]])

        transform = tf_offset.dot(tf_rotate).dot(tf_offset_neg)

    elif 'skewX' in transform_substr:
        if not _check_num_parsed_values(values, [1]):
            return transform

        transform[0, 1] = np.tan(values[0] * np.pi / 180.0)

    elif 'skewY' in transform_substr:
        if not _check_num_parsed_values(values, [1]):
            return transform

        transform[1, 0] = np.tan(values[0] * np.pi / 180.0)
    else:
        # Return an identity matrix if the type of transform is unknown, and warn the user
        warnings.warn('Unknown SVG transform type: {0}'.format(type_str))

    return transform

def parse_transform(el, transform_str):
    """Converts a valid SVG transformation string into a 3x3 matrix.
    If the string is empty or null, this returns a 3x3 identity matrix"""
    if not transform_str:
        return np.identity(3)
    elif not isinstance(transform_str, str):
        raise TypeError('Must provide a string to parse')

    transform_substrs = transform_str.split(')')[:-1]
    for transform_substr in transform_substrs:

        type_str, value_str = transform_substr.split('(')
        value_str = value_str.replace(',', ' ')
        values = list(map(float, filter(None, value_str.split(' '))))

        if 'translate' in transform_substr:
            x_translate = float(values[0])
            y_translate = float(values[1])
            el = el.getTranslated(x_translate, y_translate)

        elif 'scale' in transform_substr:
            x_scale = float(values[0])
            y_scale = float(values[1]) if (len(values) > 1) else x_scale
            el = el.getScaled(x_scale, y_scale)

        elif 'rotate' in transform_substr:
            deg = float(values[0])
            el = el.getRotated(deg)

        # elif 'skewX' in transform_substr:
        #     if not _check_num_parsed_values(values, [1]):
        #         return transform

        #     transform[0, 1] = np.tan(values[0] * np.pi / 180.0)

        # elif 'skewY' in transform_substr:
        #     if not _check_num_parsed_values(values, [1]):
        #         return transform

        #     transform[1, 0] = np.tan(values[0] * np.pi / 180.0)
        else:
            # Return an identity matrix if the type of transform is unknown, and warn the user
            warnings.warn('Unknown SVG transform type: {0}'.format(type_str))

    return el

#  COLOR

# stackoverflow.com/questions/214359/converting-hex-color-to-rgb-and-vice-versa
def hex2rgb(value):
    """Converts a hexadeximal color string to an RGB 3-tuple
    EXAMPLE
    -------
    >>> hex2rgb('#0000FF')
    (0, 0, 255)
    """
    value = value.lstrip('#')
    lv = len(value)
    return tuple(int(value[i:i+lv//3], 16) for i in range(0, lv, lv//3))

def rgb2gray(rgb):
    # print(rgb)
    r, g, b = rgb[0], rgb[1], rgb[2]
    gray = 0.2989 * r + 0.5870 * g + 0.1140 * b

    return gray

def hex2gray(value):
    return rgb2gray(hex2rgb(value))

def hex2fill(value):
    value = hex2gray(value)
    return value < 50.0


######################################################
#
# Generate Harmonics data
#
######################################################
import numpy as np

def generate(sineCoeffArray, sinePeriodsArray, cosineCoeffArray, cosinePeriodsArray, timeSteps, tStart = 0):

	if (len(sineCoeffArray) != len(sinePeriodsArray)):
		raise Exception('sineCoeffArray and sinePeriodsArray must be of the same length.')

	if (len(cosineCoeffArray) != len(cosinePeriodsArray)):
		raise Exception('cosineCoeffArray and cosinePeriodsArray must be of the same length.')

	outputArray = np.zeros(timeSteps)
	T = float(timeSteps)
	for i in range(tStart, timeSteps):
		value = 0.0
		for j in range(0, len(sineCoeffArray)):
			value += (sineCoeffArray[j] * np.sin(i * sinePeriodsArray[j] * 2.0 * np.pi / T ))

		for k in range(0, len(cosineCoeffArray)):
			value += (cosineCoeffArray[k] * np.cos(i * cosinePeriodsArray[k] * 2.0 * np.pi / T))

		outputArray[i] = value

	return outputArray


from scipy import stats
from sklearn.metrics import mean_squared_error
import numpy as np

def pearson(y, pred):
    pear = stats.pearsonr(y, pred)
    pear_value = pear[0]
    pear_p_val = pear[1]
    print("Pearson correlation is {} and related p_value is {}".format(pear_value, pear_p_val))
    return pear_value

def spearman(y, pred):
    spear = stats.spearmanr(y, pred)
    spear_value = spear[0]
    spear_p_val = spear[1]
    print("Spearman correlation is {} and related p_value is {}".format(spear_value, spear_p_val))
    return spear_value

def mse(y, pred):
    err = mean_squared_error(y, pred)
    print("Mean squared error is {}".format(err))
    return err

def squared_error(y,pred):
    errs = []
    for i in range(y.shape[0]):
        err = (y[i]-pred[i]) * (y[i]-pred[i])
        errs.append(err)
    return np.asarray(errs)


import numpy as np

def edge(size, frequency, angle, beta=0):
    '''Generate an image with periodic edges.

    Parameters
    ----------
    size : tuple
        width and height of the output image
    frequency : float
        the frequency of the pulse train, in cycles per pixel
    angle : float
        value in degrees indicating the orientation of the sinusoid
    beta : float
        value of the Kaiser window 'beta' parameter

    Returns
    -------
    numpy.ndarray
        the generated output image
    '''
    if frequency < 0:
        raise ValueError('Frequency must be a positive value.')

    omega = 2.0 * np.pi * frequency / np.min(size)
    theta = np.deg2rad(angle)

    y, x = np.meshgrid(np.arange(size[1]), np.arange(size[0]))
    u = x * np.cos(theta) + y * np.sin(theta)
    out = np.cos(omega*u)
    out[out >= 0] = 1
    out[out < 0] = 0

    return out


#!/usr/bin/env python3
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0, 21000, 1000)
r = np.log(0.5)
t1 = 5730
t2 = 1600
y1 = np.exp((r / t1) * x)
y2 = np.exp((r / t2) * x)

fig, ax = plt.subplots()
plt.plot(x, y1, 'r--', label='C-14')
plt.plot(x, y2, 'g', label='Ra-226')
plt.axis([0, 20000, 0.0, 1.0])
ax.set_title("Exponential Decay of Radioactive Elements", va='bottom')
plt.xlabel('Time (years)')
plt.ylabel('Fraction Remaining')
plt.legend(framealpha=1, frameon=True)
plt.show()


import numpy as np

hid_activations = ['relu', 'logsig', 'tanh']
out_activations = ['linear', 'softmax', 'logsig']

## general activations

def relu(X):
    return np.where(X > 0, X, 0)

def drelu(X):
    return np.where(X > 0, 1, 0)

def logsig(X):
    return 1 / (1 + np.exp(-X))

def dlogsig(X):
    return logsig(X) * (1 - logsig(X))

def tanh(X):
    return np.tanh(X)

def dtanh(X):
    return 1 / np.cosh(X) ** 2

## output-only activations

def linear(X):
    return X

def dlinear(X):
    return np.ones(X.shape)

def softmax(X):
    return (np.exp(X) / np.sum(np.exp(X)))

def dsoftmax(X):
    out = np.zeros(X.shape)
    out[np.argmax(X)] = np.exp(X[np.argmax(X)]) / np.sum(np.exp(X))
    return out

## cost functions

def MSE(D, Y):
    return np.sum((D - Y) ** 2, axis=0)

def CE(D, Y):
    return -np.sum(np.log(Y) * D, axis=0)


"""
Authors: Aditya Jain
Contact : https://adityajain.me
"""

import numpy as np

class KNeighborsClassifier():
	"""
	K Nearest Neighbors Classifier which classifies sample point based on majority of k nearby sample classes

	Parameters
	----------
	n_neighbors : integer (Default 5), number of neighbors to consider

	metric : str ( 'minkowski', 'euclidean', 'manhatten' ) (Default : 'minkowski')

	p : integer (Default 2), metric used in minkowski distance

	normalize : boolean, normalize data before calculating distance

	"""

	def __init__(self, n_neighbors=5, metric='minkowski', p=2, normalize=False):
		self.__n_neighbors = n_neighbors
		self.__X = None
		self.__y = None
		self.__normalize = normalize
		self.__metric = { 'minkowski': self.__minkowski, 'euclidean':self.__euclidean, 'manhatten':self.__manhatten }[metric]
		self.__p = p
		self.__n_classes = None
		self.__means = None
		self.__std = None

	def __euclidean(self,X1,X2):
		return np.sqrt(np.sum(np.square(X1-X2),axis=1))

	def __manhatten(self,X1,X2):
		return np.sum(np.abs(X1-X2),axis=1)

	def __minkowski(self,X1,X2):
		return np.power(np.sum(np.power(np.abs(X1-X2),self.__p),axis=1),1/self.__p)

	def __normalizeX(self,X):
		return (X-self.__means)/self.__std

	def fit(self,X,y):
		"""
		Fit X using y

		Parameters
		----------
		X : 2D numpy array, independent variables

		y : 1D numpy array, dependent variable

		"""
		self.__y, self.__n_classes = y, len(np.unique(y))
		if self.__normalize:
			self.__means, self.__std = X.mean(axis=0), X.std(axis=0)
			self.__X = self.__normalizeX(X)
		else:
			self.__X = X

	def predict_proba(self,X):
		"""
		Predict probability of all classes

		Parameters
		----------
		X : numpy array, independent variables

		Returns
		-------

		predicted probabilities

		"""
		if self.__normalize: X = self.__normalizeX(X)
		probs = []
		for sample in X:
			x = np.expand_dims(sample,axis=0)
			distances = self.__metric(self.__X, x)
			top_k_index = distances.argsort()[:self.__n_neighbors]
			prob = np.zeros(self.__n_classes)
			cls,cnts = np.unique(self.__y[top_k_index], return_counts=True)
			for cl,cn in zip(cls,cnts): prob[cl] = cn/sum(cnts)
			probs.append(prob)
		return np.array(probs)

	def predict(self,X):
		"""
		Predict dependent variable

		Parameters
		---------
		X : numpy array, independent variables

		Returns
		-------
		Predicted classes

		"""
		return np.argmax( self.predict_proba(X), axis=1 )

	def score(self,X,y):
		"""
		Calculate accuracy from independent variables

		Parameters
		----------
		X : numpy array, independent variables

		y : numpy array, dependent variable

		Returns
		-------
		accuracy score

		"""
		return (y==self.predict(X)).sum()/len(y)


import numpy as np
from distances.distances import *

##### Point and Distance
p1 = Point(0, 1)
p2 = Point(1, 0.5)
dist = Distance(p1, p2)

def test_compute_euclidian():
    assert dist.euclidian == np.sqrt(5) / 2

def test_compute_manhattan():
    assert dist.manhattan == 1.5

test_compute_euclidian()
test_compute_manhattan()

##### min
mat = np.array([[1, 2, 3], [2, 2, 0]])

def test_min_mask():
    expected = np.array([[ True, False, False], [False, False, True]])
    result = min_mask(mat)
    assert (result == expected).all()

def test_min_indexes():
    expected = {'row_idx': np.array([0, 1]), 'col_idx': np.array([0, 2])}
    result = min_indexes(mat)
    for key in result.keys():
        assert (expected[key] == result[key]).all

test_min_mask()
test_min_indexes()


import numpy as np
from sigmoid import *

def cost_function(theta, X, y): # 返回代价值，代价函数对应的斜率（导数）
    m = y.size

    # You need to return the following values correctly
    cost = 0
    grad = np.zeros(theta.shape)

    # ===================== Your Code Here =====================
    # Instructions : Compute the cost of a particular choice of theta
    #                You should set cost and grad correctly.
    #

    hypothesis = sigmoid(X @ theta.T)
    first = np.multiply(-y, np.log(hypothesis))
    second = np.multiply(1 - y, np.log(1-hypothesis))
    cost = np.sum(first - second) / m #代价

    grad = np.dot((hypothesis - y), X) / m    #代价函数对应点的斜率（导数）
    # ===========================================================

    return cost, grad


"""
Function module
"""
from dataclasses import dataclass, field
from typing import Callable

import numpy as np

@dataclass
class SmoothFunction:
    name: str
    fun: Callable = field(repr=False)
    dfun: Callable = field(repr=False)
    d2fun: Callable = field(default=None, repr=False)

fun_list = [
    SmoothFunction(name="identity",
                   fun=lambda x: x,
                   dfun=lambda x: 1.0 if np.isscalar(x) else np.ones(len(x)),
                   d2fun=lambda x: 0.0 if np.isscalar(x) else np.zeros(len(x))),
    SmoothFunction(name="quad",
                   fun=lambda x: x**2,
                   dfun=lambda x: 2*x,
                   d2fun=lambda x: 2.0 if np.isscalar(x) else np.full(len(x), 2.0)),
    SmoothFunction(name="exp",
                   fun=np.exp,
                   dfun=np.exp,
                   d2fun=np.exp),
    SmoothFunction(name="expit",
                   fun=lambda x: 1/(1 + np.exp(-x)),
                   dfun=lambda x: np.exp(-x)/(1 + np.exp(-x))**2,
                   d2fun=lambda x: np.exp(-x)*(np.exp(-x) - 1)/(np.exp(-x) + 1)**3),
    SmoothFunction(name="log",
                   fun=np.log,
                   dfun=lambda x: 1/x,
                   d2fun=lambda x: -1/x**2),
    SmoothFunction(name="logit",
                   fun=lambda x: np.log(x/(1 - x)),
                   dfun=lambda x: 1/(x*(1 - x)),
                   d2fun=lambda x: (2*x - 1)/(x*(1 - x))**2),
]

fun_dict = {
    fun.name: fun
    for fun in fun_list
}


import tensorflow.compat.v1 as tf
import numpy as np

#generates a random square orthogonal matrix of dimension dim
def square_orthogonal_matrix(dim=3, seed=None):
     random_state = np.random
     if seed is not None: #allows to get the same matrix every time
        random_state.seed(seed)
     H = np.eye(dim)
     D = np.ones((dim,))
     for n in range(1, dim):
         x = random_state.normal(size=(dim-n+1,))
         D[n-1] = np.sign(x[0])
         x[0] -= D[n-1]*np.sqrt((x*x).sum())
         # Householder transformation
         Hx = (np.eye(dim-n+1) - 2.*np.outer(x, x)/(x*x).sum())
         mat = np.eye(dim)
         mat[n-1:, n-1:] = Hx
         H = np.dot(H, mat)
         # Fix the last sign such that the determinant is 1
     D[-1] = (-1)**(1-(dim % 2))*D.prod()
     # Equivalent to np.dot(np.diag(D), H) but faster, apparently
     H = (D*H.T).T
     return H

#generates a random (semi-)orthogonal matrix of size NxM
def semi_orthogonal_matrix(N, M, seed=None):
    if N > M: #number of rows is larger than number of columns
        square_matrix = square_orthogonal_matrix(dim=N, seed=seed)
    else: #number of columns is larger than number of rows
        square_matrix = square_orthogonal_matrix(dim=M, seed=seed)
    return square_matrix[:N,:M]

#generates a weight matrix with variance according to Glorot initialization
#based on a random (semi-)orthogonal matrix
#neural networks are expected to learn better when features are decorrelated
#(stated by eg. "Reducing overfitting in deep networks by decorrelating representations",
#"Dropout: a simple way to prevent neural networks from overfitting",
#"Exact solutions to the nonlinear dynamics of learning in deep linear neural networks")
def semi_orthogonal_glorot_weights(n_in, n_out, scale=2.0, seed=None):
    W = semi_orthogonal_matrix(n_in, n_out)
    W *= np.sqrt(scale/((n_in+n_out)*W.var()))
    return W

#given a tensor x, gives back the variance
def reduce_var(x, axis=None, keepdims=False):
    """Variance of a tensor, alongside the specified axis.

    # Arguments
        x: A tensor or variable.
        axis: An integer, the axis to compute the variance.
        keepdims: A boolean, whether to keep the dimensions or not.
            If `keepdims` is `False`, the rank of the tensor is reduced
            by 1. If `keepdims` is `True`,
            the reduced dimension is retained with length 1.

    # Returns
        A tensor with the variance of elements of `x`.
    """

    m = tf.reduce_mean(input_tensor=x, axis=axis, keepdims=True)
    devs_squared = tf.square(x - m)
    return tf.reduce_mean(input_tensor=devs_squared, axis=axis, keepdims=keepdims)


# Monte Carlo valuation of European call options with pure Python
# mcs_pure_python.py
# https://github.com/yhilpisch/py4fi

from time import time
import numpy as np

np.random.seed(1234)
t0 = time()

# Parameters
S0 = 100.  # initial value
K = 105.  # strike price
T = 1.0  # maturity
r = 0.05  # risk-less short rate
sigma = 0.2  # volatility
M = 50  # number of time steps
dt = T / M  # length of time interval
n_paths = 250000  # number of paths

# Simulating n_paths paths with M time steps
S = []
for i in range(n_paths):
    path = []
    for t in range(M + 1):
        if t == 0:
            path.append(S0)
        else:
            z = np.random.standard_normal()
            St = path[t - 1] * np.exp((r - 0.5 * sigma ** 2) * dt + sigma * np.sqrt(dt) * z)
            path.append(St)
    S.append(path)

# Calculating the Monte Carlo estimator
C0 = np.exp(-r * T) * np.sum([np.maximum(path[-1] - K, 0) for path in S]) / n_paths

# Results output
tpy = time() - t0
print("European Option Value %7.3f" % C0)
print("Duration in Seconds   %7.3f" % tpy)

03 Montecarlo valuation of European call - pure Python.py


import numpy as np
import pandas as pd
import statsmodels.api as sm
from sklearn.model_selection import train_test_split
from sklearn.linear_model import Ridge
from typing import List, Tuple

def run_regression(df:pd.DataFrame, y_label:str, X_labels:List[str]) -> Tuple[np.array, np.array, np.array, np.array]:
    y_actual = df[y_label]
    X_data = df[X_labels]

    results = sm.OLS(y_actual, X_data).fit()

    y_pred = results.predict(X_data)
    coefficients = results.params.values
    p_values = results.pvalues.values

    return y_actual, y_pred, coefficients, p_values

def run_regression_with_test_split(df:pd.DataFrame, y_label:str,
                                   X_labels:List[str], test_size:float=0.2) -> Tuple[np.array, np.array, np.array, np.array, np.array, np.array]:
    y_actual = df[y_label]
    X_data = df[X_labels]

    X_train, X_test, y_train, y_test = train_test_split(X_data, y_actual,
        test_size=test_size, random_state=0)

    results = sm.OLS(y_train, X_train).fit()

    y_test_pred = results.predict(X_test)
    y_pred = results.predict(X_data)
    coefficients = results.params.values
    p_values = results.pvalues.values

    return y_test, y_test_pred, coefficients, p_values, y_actual, y_pred

def run_ml_regression(df:pd.DataFrame, y_label:str, X_labels:List[str]) -> Tuple[np.array, np.array, np.array]:
    y_train = df[y_label]
    X_train = df[X_labels]

    results = Ridge(alpha=0.01, fit_intercept=False).fit(X_train, y_train)

    y_pred = results.predict(X_train)
    coefficients = results.coef_

    return y_train, y_pred, coefficients

def run_ml_regression_with_test_split(df:pd.DataFrame, y_label:str, X_labels:List[str], test_size:float=0.2) -> Tuple[np.array, np.array, np.array]:
    y_data = df[y_label]
    X_data = df[X_labels]

    X_train, X_test, y_train, y_test = train_test_split(X_data, y_data,
        test_size=test_size, random_state=0)

    results = Ridge(alpha=0.01, fit_intercept=False, random_state=0).fit(X_train, y_train)

    y_pred = results.predict(X_test)
    coefficients = results.coef_

    return y_test, y_pred, coefficients

def create_results_df(X_labels:List[str], coefficients:np.array, p_values:List[float]=None) -> pd.DataFrame:
    if p_values is None: # ml algo doesn't give p_values
        results_df = pd.DataFrame({'coefficient': coefficients}, index=X_labels)
    else:
        results_df = pd.DataFrame({'coefficient': coefficients, 'p_value': p_values}, index=X_labels)

    return results_df

def create_pred_df(df:pd.DataFrame, results_df:pd.DataFrame) -> pd.DataFrame:
    # calculate predictions
    X_labels = results_df.index
    pred_df = df[X_labels].copy()
    for x in X_labels:
        pred_df[x] = results_df['coefficient'].loc[x] * df[x]

    return pred_df


#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Created by igor on 18/10/2017
import numpy as np

#Activation functions
sigmoid = {
    'fn': lambda z: 1 / (1+np.exp(-z)),
    'der': lambda z: z*(1-z)
}

relu = {
    'fn': lambda z:z if z>0 else 0,
    'der': lambda z: 1 if z>0 else 0
}

#Error functions
errorMeanSq = {
    'fn': lambda out, ans: 0.5 * np.power(out-ans,2),
    'der': lambda out, ans: out - ans
}


# -*- coding: utf-8 -*-
"""
Plot the interpolation functions for a 4-node isoparametric
element.

@author: Nicolas Guarin-Zapata
"""
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

Axes3D
plt.rcParams["mathtext.fontset"] = "cm"

def make_plot(x, y, N, cont):
    x_cords = [-1, 1, 1, -1]
    y_cords = [-1, -1, 1, 1]

    ax = plt.gca()
    ax.plot([-1, 1, 1, -1, -1], [-1, -1, 1, 1, -1], "-ko", zorder=-10)
    ax.plot([x_cords[cont], x_cords[cont]],
            [y_cords[cont], y_cords[cont]], [0, 1], "--k", zorder=-10)
    ax.plot_surface(x, y, N, cstride=1, rstride=1, cmap="viridis",
                alpha=0.6, lw=0.3, zorder=3, edgecolors="black")
    ax.view_init(azim=-60, elev=30)
    ax.set_xlabel(r"$x$", fontsize=12)
    ax.set_ylabel(r"$y$", fontsize=12)
    ax.set_zlabel(r"$N_%i(x, y)$"%(cont + 1), fontsize=12)
    ax.set_xticks([-1, 0, 1])
    ax.set_yticks([-1, 0, 1])
    ax.set_zticks([0.0, 0.5, 1.0])

x, y = np.mgrid[-1:1:11j, -1:1:11j]
N1 = 0.25*(1 - x)*(1 - y)
N2 = 0.25*(1 + x)*(1 - y)
N3 = 0.25*(1 + x)*(1 + y)
N4 = 0.25*(1 - x)*(1 + y)

plt.close("all")
cont = 0
fig = plt.figure(figsize=(5, 5))
for cont, N in enumerate([N1, N2, N3, N4]):
    ax = fig.add_subplot(2, 2, cont + 1, projection='3d')
    make_plot(x, y, N, cont)

plt.savefig("interp_4-nodos.pdf", transparent=True)
plt.show()


import numpy as np

def make_2D_Gaussian(size, fwhm=3):
    """make a 2D Gaussian kernel.

    find slope of the phase plane through
    two point step size for phase correlation minimization

    Parameters
    ----------
    size : list, size=(1,2), dtype=integer
        size of the resulting numpy array
    fwhm : float, size=(2,1)
        a.k.a.: full-width-half-maximum
        can be thought of as an effective radius

    Returns
    -------
    M : np.array, size=(size,size)
        array with Gaussian peak in the center

    See Also
    --------
    phase_svd, phase_radon, phase_difference

    Notes
    -----
    .. math:: M = e^{ -4 \ln(2) \frac{x^2 + y^2}{fwhm}}
    """
    if len(size)==1:
        size = (size, size)

    x = np.linspace(-(size[0]-1)/2,+(size[0]-1)/2, size[0], float)
    y = np.linspace(-(size[1]-1)/2,+(size[1]-1)/2, size[0], float)
    y = y[:,np.newaxis]
    M = np.exp(-4*np.log(2) * (x**2 + y**2) / fwhm**2)
    return M

def make_2D_Laplacian(alpha=.5):
    alpha = max(0, min(alpha, 1))
    cross_weight = np.divide(1.-alpha, 1.+alpha)
    diag_weight = np.divide(alpha, (alpha + 1.))
    center = np.divide(-4., 1.+alpha)
    M = np.array([
        [diag_weight, cross_weight, diag_weight],
        [cross_weight, center, cross_weight],
        [diag_weight, cross_weight, diag_weight]])
    return M

def sigma_filtering(y,thres=3):
    """ 3-sigma filtering

    finds the traditional statistics and filters the 1% outliers

    Parameters
    ----------
    y : np.array, size=(_,1), dtype=float
        data of interest
    thres : float, size=1
        multiplication factor of the sigma
        1: 68%
        2: 95%
        3: 99%

    Returns
    -------
    IN : np.array, size=(_,1) , dtype=boolean
        array with classification

    See Also
    --------
    weighted_sigma_filtering, mad_filtering
    """
    mean_y = np.mean(y)
    std_y = np.std(y)

    IN = (y > (mean_y - thres*std_y)) & \
        (y < mean_y + thres*std_y)
    return IN

def weighted_sigma_filtering(y,w,thres=3):
    """ weighted 3-sigma filtering

    finds the weighted statistics and filters with these statistics

    Parameters
    ----------
    y : np.array, size=(_,1), dtype=float
        data of interest
    w : np.array, size=(_,1), dtype=float
        weights to be used for the statistics calculation
    thres : float, size=1
        multiplication factor of the sigma
        1: 68%
        2: 95%
        3: 99%

    Returns
    -------
    IN : np.array, size=(_,1) , dtype=boolean
        array with classification

    See Also
    --------
    sigma_filtering, mad_filtering
    """
    mean_y = np.average(y,weights=w)
    std_y = math.sqrt(np.average((y-mean_y)**2, weights=w))

    IN = (y > (mean_y - thres*std_y)) & \
        (y < mean_y + thres*std_y)
    return IN

def mad_filtering(y,thres=1.4826):
    """ robust 3-sigma filtering

    finds the robust statistics and filters with these statistics

    Parameters
    ----------
    y : np.array, size=(_,1), dtype=float
        data of interest
    thres : float, size=1
        multiplication factor of the median absolute difference.
        if the distribution is normal then 1.4826*thresh = sigma

    Returns
    -------
    IN : np.array, size=(_,1) , dtype=boolean
        array with classification

    See Also
    --------
    sigma_filtering, weighted_sigma_filtering,
    huber_filtering, cauchy_filtering
    """
    med_y = np.median(y)
    mad_y = np.median(np.abs(y - med_y))

    IN = (y > (med_y - thres*mad_y)) & \
        (y < med_y + thres*mad_y)
    return IN

def normalize_variance(y):
    """ normalize data through its variance

    project/scale data towards a uniform space,
    by means of classical statistics

    Parameters
    ----------
    y : np.array, size=(_,1), dtype=float
        data of interest

    Returns
    -------
    r : np.array, size=(_,1) , dtype=float
        projected data, centered around the origin

    See Also
    --------
    normalize_variance_robust
    """
    mean_y = np.mean(y)
    std_y = np.std(y)
    r = (y-mean_y)/std_y
    return r

def normalize_variance_robust(y):
    """ normalize data through its robust statistics

    project/scale data towards a uniform space,
    by means of robust statistics

    Parameters
    ----------
    y : np.array, size=(_,1), dtype=float
        data of interest

    Returns
    -------
    r : np.array, size=(_,1) , dtype=float
        projected data, centered around the origin

    See Also
    --------
    normalize_variance
    """
    med_y = np.median(y)
    mad_y = np.median(np.abs(med_y - med_y))
    r = (y-med_y)/mad_y
    return r

def huber_filtering(y,thres=1.345,preproc='normal'):
    """ filter with statitics following a Huber function

    finds the robust statistics and filters with these statistics

    Parameters
    ----------
    y : np.array, size=(_,1), dtype=float
        data of interest
    thres : float, size=1
        multiplication factor of the median absolute difference.
        if the distribution is normal then 1.345*thresh = sigma
    preproc: string, default='normal'
        'normal'
            using classical statistics to estimate the mean
        else:
            using robust statistics

    Returns
    -------
    IN : np.array, size=(_,1) , dtype=boolean
        array with classification

    See Also
    --------
    sigma_filtering, weighted_sigma_filtering,
    mad_filtering, cauchy_filtering
    """
    if preproc == 'normal':
        r = normalize_variance(y)
    else:
        r = normalize_variance_robust(y)
    w = 1 / max(1, abs(r))
    IN = w<thres
    return IN

def cauchy_filtering(y,thres=2.385,preproc='normal'):
    """ filter with statitics following a Cauchy function

    finds the robust statistics and filters with these statistics

    Parameters
    ----------
    y : np.array, size=(_,1), dtype=float
        data of interest
    thres : float, size=1
        multiplication factor of the median absolute difference.
        if the distribution is normal then 2.385*thresh = sigma
    preproc: string, default='normal'
        'normal'
            using classical statistics to estimate the mean
        else:
            using robust statistics

    Returns
    -------
    IN : np.array, size=(_,1) , dtype=boolean
        array with classification

    See Also
    --------
    sigma_filtering, weighted_sigma_filtering,
    mad_filtering, huber_filtering
    """
    if preproc == 'normal':
        r = normalize_variance(y)
    else:
        r = normalize_variance_robust(y)
    w = 1 / (1 + r**2)
    IN = w<thres
    return IN

def normalized_sampling_histogram(I):
    """ sample histogram based upon Sturges' rule

    Parameters
    ----------
    I : np.array, dim={1,n}, dtype={integer,float}

    Returns
    -------
    values : np.array, size=(m)
        occurances within an interval
    base : np.array, size=(m)
        central value of the interval

    References
    ----------
    .. [1] Sturges, "The choice of a class interval". Journal of the american
       statistical association. vol.21(153) pp.65–66.
    """
    sturge = 1.6 * (np.log2(I.size) + 1)
    values, base = np.histogram(I.flatten(),
                                bins=int(np.ceil(sturge)))
    # transform to centers
    base = base[:-1] + np.diff(base)
    return values, base


import numpy as np

def quad_function(point, p, store_x0, matrix_test):
    """
    Minimum of several Quadratic forms function.

    Parameters
    ----------
    point : 1-D array with shape (d, )
            A point used to evaluate the function.
    p : integer
        Number of local minima.
    store_x0 : 2-D array with shape (p, d).
    matrix_test : 3-D array with shape (p, d, d).

    Returns
    -------
    value_of_minimum : float
                       Function value.
    """
    d = point.shape[0]
    store_func_values = (np.transpose((point - store_x0).reshape(p, d, 1),
                                      (0, 2, 1)) @
                         matrix_test @ (point - store_x0).reshape(p, d, 1))
    value_of_minimum = np.min(store_func_values)
    return value_of_minimum

def quad_gradient(point, p, store_x0, matrix_test):
    """
    Minimum of several Quadratic forms gradient.

    Parameters
    ----------
    point : 1-D array with shape (d, )
            A point used to evaluate the gradient.
    p : integer
        Number of local minima.
    store_x0 : 2-D array with shape (p, d).
    matrix_test : 3-D array with shape (p, d, d).

    Returns
    -------
    gradient : 1-D array with shape (d, )
               Gradient at point.
    """
    d = point.shape[0]
    store_func_values = (np.transpose((point - store_x0).reshape(p, d, 1),
                                      (0, 2, 1)) @
                         matrix_test @ (point - store_x0).reshape(p, d, 1))
    position_minimum = np.argmin(store_func_values)
    gradient = 2 * (matrix_test[position_minimum] @
                    (point - store_x0[position_minimum]))
    return gradient

def calc_minimizer_quad(point, p, store_x0, matrix_test):
    """
    Finding the position of the local minimizer which point is closest
    to, using the minimum of several Quadratic forms function.

    Parameters
    ----------
    point : 1-D array with shape (d, )
            A point used to evaluate the function.
    p : integer
        Number of local minima.
    store_x0 : 2-D arrays with shape (p, d).
    matrix_test : 3-D arrays with shape (p, d, d).

    Returns
    -------
    position_minimum : integer
                       Position of the local minimizer which produces the
                       smallest distance between point and all p local
                       minimizers.
    """
    d = point.shape[0]
    store_func_values = (np.transpose((point - store_x0).reshape(p, d, 1),
                                      (0, 2, 1)) @
                         matrix_test @ (point - store_x0).reshape(p, d, 1))
    position_minimum = np.argmin(store_func_values)
    norm_with_minimizer = np.linalg.norm(point - store_x0[position_minimum])
    assert(norm_with_minimizer < 0.2)
    return position_minimum


import numpy as np
import sys

def deGroot(environment, beliefs):
    i = 0
    consensus = False
    while (consensus == False and i < 1000):
        old_beliefs = beliefs
        beliefs = environment @ beliefs
        #if (np.all(old_beliefs - beliefs == np.zeros(len(beliefs)))):
        if (np.all(old_beliefs - beliefs < np.full(len(beliefs),sys.float_info.epsilon))):
            consensus = True
        i = i + 1
    return beliefs

def deGrootSteps(environment, beliefs):
    steps = []
    i = 0
    consensus = False
    while (consensus == False and i < 1000):
        old_beliefs = beliefs
        beliefs = environment @ beliefs
        #if (np.all(old_beliefs - beliefs == np.zeros(len(beliefs)))):
        if (np.all(old_beliefs - beliefs < np.full(len(beliefs),sys.float_info.epsilon))):
            consensus = True
        i = i + 1
        steps.append(beliefs)
    return steps

#print(deGroot(T, p0))


from numpy import zeros

# Define ab2 function
def ab2(f,t0,tf,y0,n):
    h = (tf - t0)/n
    t = zeros(n+1)
    y = zeros(n+1)
    t[0] = t0
    y[0] = y0
    y[1] = y[0] + h * f(t[0],y[0])
    t[1] = t[0] + h
    for i in range(1,n):
        y[i+1] = y[i] + (3.0/2.0) * h * f(t[i],y[i])-1.0/2.0 * h * f(t[i-1],y[i-1])
        t[i+1] = t[i] + h
    return t,y

# Define functions
def f(t,y):
    return  t - y

# Set initial conditions
t0 = 0.0
tf = 1.0
y0 = 1.0
n = 5

# Execute AB2
t, yab2 = ab2(f,t0,tf,y0,n)

# Print results
print("%5s %8s" % ('t','y'))
for i in range(n+1):
    print("%8.4f %8.4f" % (t[i],yab2[i]))


 # Imports

import numpy as np

# Coordinates:
x1, y1 = 3, 4
x2, y2 = 0, 0
x3, y3 = 3, 0

# Member lengths

# Member 1 (btw nodes 2 and 3)
len1 = np.linalg.norm(np.array((x2, y2)) - np.array((x3, y3)))

# Member 2 (btw nodes 2 and 1)
len2 = np.linalg.norm(np.array((x2, y2)) - np.array((x1, y1)))

print('Length 1:', len1, '\nLength 2:', len2)

def calc_length(xy1: tuple, xy2: tuple) -> float:
    """ Given the coordinates of two points, it will calculate the
    distance between the two points.
    """
    return np.linalg.norm(np.array(xy1) - np.array(xy2))

len1 = calc_length((x2, y2), (x3, y3))
len2 = calc_length((x1, y1), (x2, y2))

print('Length 1:', len1, '\nLength 2:', len2)

def dir_cos(xy1, xy2):
    """ Returns the direction cosine for a member given point coordinates.
    """
    l = calc_length(xy1, xy2)
    return (xy2[0] - xy1[0])/l, (xy2[1] - xy1[1])/l

lx1, ly1 = dir_cos((x2, y2), (x3, y3))
lx2, ly2 = dir_cos((x2, y2), (x1, y1))

print(lx1, ly1, lx2, ly2)

def stiff_matrix(xy1, xy2):
    """ Returns the stiffness matrix for a member, given the coordinates of
    its near and far end nodes.
    """
    length = calc_length(xy1, xy2)
    lx, ly = dir_cos(xy1, xy2)
    return np.array(
        [
        [lx**2, lx*ly, -lx**2, -lx*ly],
        [lx*ly, ly**2, -lx*ly, -ly**2],
        [-lx**2, -lx*ly, lx**2, lx*ly],
        [-lx*ly, -ly**2, lx*ly, ly**2]
        ]
    ) / length

k1 = stiff_matrix((x2, y2), (x3, y3))
k2 = stiff_matrix((x2, y2), (x1, y1))

print(k1, '\n')
print(k2)

def stiff_matrix(xy1, xy2, other_dofs=None):
    """ Returns the stiffness matrix for a member, given the coordinates of
    its near and far end nodes. Can optionally provide a tuple that includes
    other degrees of freedom in order to compile a matrix corresponding
    to the entire system.
    """
    length = calc_length(xy1, xy2)
    lx, ly = dir_cos(xy1, xy2)
    k = np.array(
        [
        [lx**2, lx*ly, -lx**2, -lx*ly],
        [lx*ly, ly**2, -lx*ly, -ly**2],
        [-lx**2, -lx*ly, lx**2, lx*ly],
        [-lx*ly, -ly**2, lx*ly, ly**2]
        ]
    ) / length

    if other_dofs:
        for i in other_dofs:
            k = np.insert(k, i-1, 0, axis=0)
            k = np.insert(k, i-1, 0, axis=1)

    return k

k1 = stiff_matrix((x2, y2), (x3, y3), (5, 6, ))
k2 = stiff_matrix((x2, y2), (x1, y1), (3, 4, ))

print(k1, '\n')
print(k2)


import numpy as np
import random

def MeanSquaredError(real, predicted):
    if len(real) != len(predicted):
        raise Exception("Input size not equal")
    size = len(real)
    summ = 0.0
    for i in range(size):
        summ += (real - predicted)**2
    return summ / size

def RidgeCost(real, predicted, alpha):
    if len(real) != len(predicted):
        raise Exception("Input size not equal")
    size = len(real)
    mse = MeanSquaredError(real, predicted)
    return (alpha * 0.5 * size + 1) * mse

class LinearRegression:
    def __init__(self, alpha, gradient_type="Full", batch_size = 0,  n_iters = 1000):
        self.alpha = alpha
        self.gradient_type = gradient_type
        self.batch_size = batch_size
        self.n_iters = n_iters
        self.bias = 0.0
        self.coeff = None
    def fit(self, X, y):
        n_samples, n_features = np.shape(X)
        self.coeff = np.zeros(n_features)
        X = np.array(X)
        y = np.array(y)
        XT = np.transpose(X)
        if self.gradient_type == "Full":
            for _ in range(self.n_iters):
                y_predicted = np.dot(X, self.coeff) + self.bias

                dw = (1 / n_samples) * (2 * np.dot(XT, (y_predicted - y)))
                db = (1/n_samples) * (2 * np.sum(y_predicted - y))

                self.coeff -= self.alpha * dw
                self.bias -= self.alpha * db
        elif self.gradient_type == "Stochastic":
            for _ in range(self.n_iters):
                rand_i = random.randint(0, n_samples-1)
                XT_rand = [[XT[i][rand_i]] for i in range(n_features)]
                y_predicted = np.dot([X[rand_i]], self.coeff) + self.bias

                dw = (2 * np.dot(XT_rand, (y_predicted - y[rand_i])))
                db = (2 * np.sum(y_predicted - y[rand_i]))

                self.coeff -= self.alpha * dw
                self.bias -= self.alpha * db
        elif self.gradient_type == "Mini":
            if self.batch_size > n_samples:
                raise Exception('Batch size cannot be larger than number of samples')
            for _ in range(self.n_iters):
                XT_bat = [XT[i][:self.batch_size] for i in range(n_features)]
                y_predicted = np.dot(X[:self.batch_size], self.coeff) + self.bias

                dw = (1 / self.batch_size) * (2 * np.dot(XT_bat, (y_predicted - y[:self.batch_size])))
                db = (1 / self.batch_size) * (2 * np.sum(y_predicted - y[:self.batch_size]))

                self.coeff -= self.alpha * dw
                self.bias -= self.alpha * db

    def predict(self, X):
        return np.dot(X, self.coeff) + self.bias


from __future__ import absolute_import
import numpy as np
from pyti import catch_errors
from pyti.function_helper import fill_for_noncomputable_vals
from six.moves import range
from six.moves import zip

def relative_strength_index(data, period):
    """
    Relative Strength Index.

    Formula:
    RSI = 100 - (100 / 1 + (prevGain/prevLoss))
    """
    catch_errors.check_for_period_error(data, period)

    period = int(period)
    changes = [data_tup[1] - data_tup[0] for data_tup in zip(data[::1], data[1::1])]

    filtered_gain = [val < 0 for val in changes]
    gains = [0 if filtered_gain[idx] is True else changes[idx] for idx in range(0, len(filtered_gain))]

    filtered_loss = [val > 0 for val in changes]
    losses = [0 if filtered_loss[idx] is True else abs(changes[idx]) for idx in range(0, len(filtered_loss))]

    avg_gain = np.mean(gains[:period])
    avg_loss = np.mean(losses[:period])

    rsi = []
    if avg_loss == 0:
        rsi.append(100)
    else:
        rs = avg_gain / avg_loss
        rsi.append(100 - (100 / (1 + rs)))

    for idx in range(1, len(data) - period):
        avg_gain = ((avg_gain * (period - 1) +
                    gains[idx + (period - 1)]) / period)
        avg_loss = ((avg_loss * (period - 1) +
                    losses[idx + (period - 1)]) / period)

        if avg_loss == 0:
            rsi.append(100)
        else:
            rs = avg_gain / avg_loss
            rsi.append(100 - (100 / (1 + rs)))

    rsi = fill_for_noncomputable_vals(data, rsi)

    return rsi


import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import warnings
warnings.filterwarnings('ignore', category=DeprecationWarning)
warnings.filterwarnings('ignore', category=FutureWarning)
import sklearn
sklearn.set_config(print_changed_only=True)
%matplotlib inline

from sklearn.svm import SVC
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler

# load and split the data
cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
    cancer.data, cancer.target, random_state=0)

# compute minimum and maximum on the training data
scaler = MinMaxScaler().fit(X_train)
# rescale training data
X_train_scaled = scaler.transform(X_train)

svm = SVC()
# learn an SVM on the scaled training data
svm.fit(X_train_scaled, y_train)
# scale test data and score the scaled data
X_test_scaled = scaler.transform(X_test)
svm.score(X_test_scaled, y_test)

from sklearn.pipeline import Pipeline
pipe = Pipeline([("scaler", MinMaxScaler()), ("svm", SVC())])

pipe.fit(X_train, y_train)
pipe.score(X_test, y_test)

param_grid = {'svm__C': [0.001, 0.01, 0.1, 1, 10, 100],
              'svm__gamma': [0.001, 0.01, 0.1, 1, 10, 100]}

from sklearn.model_selection import GridSearchCV
grid = GridSearchCV(pipe, param_grid=param_grid, cv=5)
grid.fit(X_train, y_train)
print("best cross-validation accuracy:", grid.best_score_)
print("test set score: ", grid.score(X_test, y_test))
print("best parameters: ", grid.best_params_)


import numpy as np
import matplotlib.pyplot as plt

def m_splines_basis(x, M, K):
    """Return the basis matrix for order-M splines."""
    dof = K + M
    xi = np.linspace(np.min(x), np.max(x), K+2)[1:-1]
    H = np.zeros((len(x), dof))
    for j in range(M):
        H[:,j] = np.power(x, j)
    for k in range(K):
        H[:,M+k] = np.where((x - xi[k]) > 0, np.power(x - xi[k], M-1), 0)
    return H

def m_splines(x, M=4, K=8):
    H = m_splines_basis(x, M, K)
    bhat = np.linalg.inv(H.T @ H) @ (H.T @ y)
    yhat = H @ bhat
    return yhat

def plot_mean_function(x, y, yhat):
    plt.figure(figsize=(10,6))
    plt.scatter(x, y, s=20, label='Mean sample signal')
    plt.plot(x, yhat, c='red', alpha=0.7, label='Estimated mean function')
    plt.xlabel(r'$x$')
    plt.ylabel(r'$y$')
    plt.legend(fontsize=14)
    plt.show()
    return None

def tau_knot_sequence(x, K, M):
    a = np.min(x)
    b = np.max(x)+1e-8
    t_inner = np.linspace(a, b, K+2)[1:-1]
    t_left = np.array([a]*M)
    t_right = np.array([b]*M)
    tau = np.append(t_left, t_inner)
    tau = np.append(tau, t_right)
    return tau

def b_basis(x, t, m, j):
    if m == 0:
        if t[j] <= x < t[j+1]:
            return 1.0
        else:
            return 0.0
    elif t[j+m] == t[j]:
        a = 0.0
    else:
        a = (x - t[j]) / (t[j+m] - t[j]) * b_basis(x, t, m-1, j)
    if t[j+m+1] == t[j+1]:
        b = 0.0
    else:
        b = (t[j+m+1] - x) / (t[j+m+1] - t[j+1]) * b_basis(x, t, m-1, j+1)
    return a + b

def b_splines_basis(x, t, m):
    n = len(t) - m
    return [b_basis(x, t, m, j) for j in range(n-1)]

def differentiate(B):
    dB = np.zeros(np.shape(B))
    dB[1:,:] = B[1:,:] - B[:-1,:]
    dB[0,:] = dB[1,:]
    return dB

def lambda_selection(B, y, lambdas):
    B1 = differentiate(B)
    B2 = differentiate(B1)
    RSS = np.zeros(len(lambdas))
    dof = np.zeros(len(lambdas))
    for i in range(len(lambdas)):
        S = B @ np.linalg.inv(B.T @ B + lambdas[i] * (B2.T @ B2)) @ B.T
        yhat = S @ y
        RSS[i] = np.sum(np.power(yhat - y, 2))
        dof[i] = np.trace(S.dot(S))
    return RSS, dof

def generalized_cv(RSS, dof, n):
    return (RSS/n) / np.power((1 - (dof/n)), 2)

def plot_lambda_curves(B, y):
    fig = plt.figure(figsize=(16,4))
    ax = [plt.subplot(1, 3, i+1) for i in range(3)]
    n = 100
    min_lam, max_lam = 0, 1
    for i in range(len(ax)):
        lambdas = np.linspace(min_lam, max_lam, n)
        RSS, dof = lambda_selection(B, y, lambdas)
        GCV = generalized_cv(RSS, dof, n)
        lamhat = lambdas[np.argmin(GCV)]
        ax[i].ticklabel_format(style='sci', axis='y', scilimits=(0,0))
        ax[i].plot(lambdas, GCV)
        ax[i].scatter(lamhat, GCV[np.argmin(GCV)], c='r', s=20,
                      label=r'$\hat{\lambda}$')
        if i == 0:
            ax[i].set_ylabel(r'GCV($\lambda$)')
        ax[i].set_xlabel(r'$\lambda$')
        ax[i].axvline(lamhat, c='k', ls='--', lw=1, alpha=0.8)
        ax[i].text(lamhat + (0.015 * np.power(10, -i)),
                   np.max(GCV) - (np.max(GCV) - np.min(GCV)) * 0.05,
                   '$\hat{\lambda}$')
        min_lam = lamhat - (0.05 * np.power(10, -i))
        max_lam = lamhat + (0.05 * np.power(10, -i))
    return lamhat

def gaussian_kernel(u, d=1):
    return np.power(2 * np.pi, -d/2) * np.exp(-np.power(u, 2))

def loocv_gaus_kernel_regression(x, y, lambdas):
    m, n = len(lambdas), len(x)
    mse = np.zeros(m)
    for j in range(m):
        Lambda = lambdas[j]
        err = np.zeros(n)
        for i in range(n):
            x_ = np.delete(x, i)
            y_ = np.delete(y, i)
            z = gaussian_kernel((x[i] - x_) / Lambda)
            yke = np.sum(z * y_) / np.sum(z)
            err[i] = y[i] - yke
        mse[j] = np.mean(np.power(err, 2))
    return mse

# additional splines if needed


import numpy as np

def sigmoid(z: np.ndarray) -> np.ndarray:
    """The sigmoid function."""
    return 1.0 / (1.0 + np.exp(-z))

def sigmoid_prime(z: np.ndarray) -> np.ndarray:
    """Derivative of the sigmoid function."""
    y = sigmoid(z)
    return y * (1 - y)

def unitVector(i: int) -> np.ndarray:
    """
    Return a (10,1) ndarray with all elements as ``0.0``, except in the ``i``th index where the value is ``1.0``.
    """
    vector = np.zeros((10, 1))
    vector[i] = 1.0
    return vector


import numpy as np
from IPython import display
import matplotlib.pyplot as plt

def gen_data(true_k, true_b, num_of_points, noise_rate, noise_type='Gaussian'):
    """
    return the generated data

    Parameters
    ----------
    num_of_points : int
                    the number of generating points
    noise_rate : float
                    the percentage of noise points in all points
    noise_type : str
                    the type of noise -> 'Gaussian' of 'Uniform', default 'Gaussian'

    Returns
    -------
    points : ndarray
                    point array, [[x1,y1]. [x2,y2], ...]
    noise_index : ndarray
                    record the indexs of noise points
    nonnoise_index : ndarry
                    record the indexs of nonnoise points
    """
    #generate all points
    noise_points_num = int(num_of_points * noise_rate)
    x = np.random.randn(num_of_points, 1)
    y = true_k * x + true_b
    y += np.random.normal(0, 0.3, size=(num_of_points,1))

    #generate noise points
    rand_list = np.arange(num_of_points)
    np.random.shuffle(rand_list)
    noise_index = rand_list[:noise_points_num]
    nonnoise_index = rand_list[noise_points_num:]
    if noise_type == 'Gaussian':
        y[noise_index] = np.random.normal(0, 4, size=(noise_points_num,1))
    elif noise_type == 'Uniform':
        y[noise_index] = np.random.uniform(min(y), max(y), size=(noise_points_num,1))
    else:
        raise NameError

    points = np.concatenate([x.reshape(-1,1), y.reshape(-1,1)], axis=1)
    return points, noise_index, nonnoise_index

def draw(points, noise_index, nonnoise_index, k, b, draw_test_line=False, k_hat=None, b_hat=None):
    '''

    Parameter
    ---------
    points : array like
    noise_index : ndarray
                  record the indexs of noise points
    nonnoise_index : ndarry
                  record the indexs of nonnoise points
    k : float
    b : float

    '''
    def use_svg_display():
        # 用矢量图显示
        display.set_matplotlib_formats('svg')

    def set_figsize(figsize=(10, 10)):
        use_svg_display()
        # 设置图的尺寸
        plt.rcParams['figure.figsize'] = figsize

    x = points[:,0]
    y = x * k + b

    set_figsize()
    plt.scatter(points[nonnoise_index, 0], points[nonnoise_index, 1], color='c', marker='.',label='Inliers')
    plt.scatter(points[noise_index, 0], points[noise_index, 1], color='r', marker='*', label='Outliers')
    plt.plot(x, y, color='y', linewidth=2, label='Line Model')

    if draw_test_line:
        y_hat = x * k_hat + b_hat
        plt.plot(x, y_hat, color='gold', linewidth=2, label='Fitting Line Model')

    plt.legend(loc='upper left')
    plt.xlabel("input")
    plt.ylabel("response")


#! /usr/bin/env python

"""
File: sin_Taylor_series_diffeq.py
Copyright (c) 2016 Chinmai Raman
License: MIT
Course: PHYS227
Assignment: A.14
Date: Feb 25, 2016
Email: raman105@mail.chapman.edu
Name: Chinmai Raman
Description: Implements difference equations for computing a Taylor polynomial approximation to sin(x)
"""

import numpy as np

def sin_Taylor(x, N):
    n = 1
    an_prev = x
    sn_prev = 0
    while n <= N + 1:
        sn = sn_prev + an_prev
        an = - x**2 / ((2 * n + 1) * 2 * n) * an_prev
        sn_prev = sn
        an_prev = an
        n += 1
    return sn, abs(an)

def test_Taylor():
    assert(abs(sin_Taylor(np.pi / 2.0, 20)[0] - 1.0) < 1e-6), 'Failure'

def test_partc():
    assert(abs(sin_Taylor(np.pi / 2.0, 2)[0] - 1.0) < 1e-2), 'Failure'


from collections import namedtuple

from numpy import ones, zeros, eye, sqrt, tile, r_, array
from scipy.linalg import block_diag
from scipy.stats import chi2, t

from MinRelEntFP import MinRelEntFP
from Tscenarios import Tscenarios
from NormalScenarios import NormalScenarios

def PanicTDistribution(varrho2, r, c, nu, j_):
    # This function generates the joint scenarios and Flexible Probabilities of
    # a Panic t Distribution
    #  INPUTS
    #   varrho2      : [matrix] (n_ x n_) calm market correlation matrix
    #   r            : [scalar] homogeneous panic correlation
    #   c            : [scalar] prob threshold of a high-correlation crash event
    #   nu           : [scalar] degree of freedom
    #   j_           : [scalar] number of scenarios
    #  OPS
    #   X            : [matrix] (n_ x j_) joint scenarios
    #   p_           : [vector] (1 x j_) Flexible Probabilities (posterior via Entropy Pooling)
    #
    #NOTE: Moment matching of t-simulations for nu > 2

    # For details on the exercise, see here .

    ## Code
    n_ = len(varrho2)
    corr_c = varrho2
    corr_p = (1-r)*eye(n_) + r*ones((n_, n_)) # panic corr
    optionT = namedtuple('option', ['dim_red','stoc_rep'])
    optionT.dim_red = 0
    optionT.stoc_rep = 0
    if nu > 1:
        # Calm Component
        Xt_c = Tscenarios(nu, zeros((n_, 1)), corr_c, j_, optionT, 'Riccati')

        # Panic Component
        Xt_p = Tscenarios(nu, zeros((n_, 1)), corr_p, j_, optionT, 'Riccati')
    else:
        s2 = block_diag(corr_c, corr_p)
        Z = NormalScenarios(zeros((2*n_, 1)), s2, j_, 'Riccati')

        # Calm Component
        X_c = Z[:n_,:]
        Chi_2 = chi2.rvs(nu, 1, j_)
        Xt_c = X_c / tile(sqrt(Chi_2 / nu), (n_, 1))

        # Panic Component
        X_p = Z[n_:-1, :]
        Chi_2 = chi2.rvs(nu, 1, j_)
        Xt_p = X_p /tile(sqrt(Chi_2 / nu), (n_, 1))

    # Panic distribution
    B = (Xt_p < t.ppf(c, nu)) # triggers panic
    X = (1-B) * Xt_c + B * Xt_p

    # Perturb probabilities via Fully Flexible Views
    p = ones((1, j_)) / j_ # flat flexible probabilities (prior)
    aeq = r_[ones((1, j_)), X]   # constrain the first moments
    beq = r_[array([[1]]), zeros((n_, 1))]

    p_ = MinRelEntFP(p, None, None, aeq , beq)[0] # compute posterior probabilities
    return X, p_


import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

from scipy.spatial.distance import pdist, cdist, squareform

from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
from sklearn.metrics import adjusted_rand_score

# For reproducibility
np.random.seed(1000)

nb_samples = 1000
nb_clusters = 8

metric = 'minkowski'
p = 7
tolerance = 0.001

if __name__ == '__main__':
    # Create the dataset
    X, Y = make_blobs(n_samples=nb_samples, n_features=2, centers=nb_clusters,
                      cluster_std=1.2, center_box=[-5.0, 5.0], random_state=1000)

    # Perform K-Means clustering
    km = KMeans(n_clusters=nb_clusters, random_state=1000)
    C_km = km.fit_predict(X)

    print('Adjusted Rand score K-Means: {}'.format(adjusted_rand_score(Y, C_km)))

    # Perform K-Medoids clustering
    C = np.random.randint(0, nb_clusters, size=(X.shape[0],), dtype=np.int32)
    mu_idxs = np.zeros(shape=(nb_clusters, X.shape[1]))

    mu_copy = np.ones_like(mu_idxs)

    while np.linalg.norm(mu_idxs - mu_copy) > tolerance:
        for i in range(nb_clusters):
            Di = squareform(pdist(X[C == i], metric=metric, p=p))
            SDi = np.sum(Di, axis=1)

            mu_copy[i] = mu_idxs[i].copy()
            idx = np.argmin(SDi)
            mu_idxs[i] = X[C == i][idx].copy()

        C = np.argmin(cdist(X, mu_idxs, metric=metric, p=p), axis=1)

    print('Adjusted Rand score K-Medoids: {}'.format(adjusted_rand_score(Y, C)))

    # Show the final results
    sns.set()

    fig, ax = plt.subplots(1, 3, figsize=(26, 8), sharey=True)

    for i in range(nb_clusters):
        ax[0].scatter(X[Y == i, 0], X[Y == i, 1], label='Blob {}'.format(i + 1))
        ax[1].scatter(X[C_km == i, 0], X[C_km == i, 1], label='Cluster {}'.format(i + 1))
        ax[2].scatter(X[C == i, 0], X[C == i, 1], label='Cluster {}'.format(i + 1))

    ax[0].set_xlabel(r'$x_0$', fontsize=22)
    ax[1].set_xlabel(r'$x_0$', fontsize=22)
    ax[2].set_xlabel(r'$x_0$', fontsize=22)
    ax[0].set_ylabel(r'$x_1$', fontsize=22)

    ax[0].set_title('Ground truth', fontsize=18)
    ax[1].set_title('K-Means', fontsize=18)
    ax[2].set_title('K-Medoids with Minkowski metric and p=7', fontsize=18)

    ax[0].legend()
    ax[1].legend()
    ax[2].legend()

    plt.show()


import numpy as np
from PIL import Image
from copy import deepcopy
from matplotlib import pyplot as plt

path = 'lena_color.tiff'
image_tiff = Image.open(path)
rgb = np.array(image_tiff)

def RGB2YUV( rgb ): #RGB 2 YUV

    m = np.array([[ 0.299     ,  0.587     ,  0.114      ],
                  [-0.14714119, -0.28886916,  0.43601035 ],
                  [ 0.61497538, -0.51496512, -0.10001026 ]])

    yuv = np.dot(rgb, m.T)
    return yuv
yuv = RGB2YUV( rgb )

Y = yuv[:, :, 0] #Y - Channel
#%% Split Image to 8x8 Blocks

height, width = Y.shape
sliced = [] # new list for 8x8 sliced image
currY = 0 #current Y index
n = 8 #dividing 8x8 blocks
for i in range(n, height+1, n):
    currX = 0 #current X index
    for j in range(n, width+1, n):
        sliced.append(Y[currY:i,currX:j]-np.ones((8,8))*128) #Normalizing 128 from all pixels
        currX = j
    currY = i

T = [np.float32(Y) for Y in sliced]

#%% DCT algorithm

D = deepcopy(sliced)
csum = 0.0
for w in range(4096):
    for i in range(8):
        for j in range(8):
            for x in range(8):
                for y in range(8): #Main algorithm below
                    csum += T[w][x][y]*np.cos((2*x+1)*i*np.pi/(2*n))*np.cos((2*y+1)*j*np.pi/(2*n))
            if (i==0 and j==0): k = 0.5
            elif ((i==0 and j) or (i and j==0)): k = 1/np.sqrt(2)
            else: k = 1
            D[w][i][j] = 2*csum*k/n
            csum = 0

#%% Quantization Matrix

xQuanmatrix = np.array([[16,11,10,16, 24, 40, 51, 61],
                       [12,12,14,19, 26, 58, 60, 55],
                       [14,13,16,24, 40, 57, 69,56 ],
                       [14,17,22,29 ,51, 87, 80, 62],
                       [18,22,37,56, 68,109,103, 77],
                       [24,35,55,64,81, 104,113, 92],
                       [49,64,78,87,103,121,120,101],
                       [72,92,95,98,112,100,103, 99]])

#%% Quantization

C = D / xQuanmatrix
for i in range(4096):
    for j in range(8):
        for x in range(8):
            C[i][j][x] = int(round(C[i][j][x]))

#%% Inverse Quantization & IDCT algorithm

R = C * xQuanmatrix
N = deepcopy(sliced)

csum = 0;
for w in range(4096):
    for i in range(8):
        for j in range(8):
            for x in range(8):
                for y in range(8):
                    k = 0.5
                    csum += k*R[w][x][y]*np.cos((2*i+1)*x*np.pi/(2*n))*np.cos((2*j+1)*y*np.pi/(2*n))
            N[w][i][j] = csum*2/n
            csum = 0

#%% ReBuilding the Image

row = 0
rowNcol = []
for j in range(int(width/n), len(N)+1, int(width/n)):
    N[row:j] = N[row:j]+np.ones((8,8))*128
    rowNcol.append(np.hstack((N[row:j])))
    row = j
YC = np.vstack((rowNcol))

#%% Plotting

output = [Y,YC]
titles = ['Original', 'Compressed']

for i in range(2):
    plt.figure(figsize=(5,5))
    plt.axis('off')
    plt.title(titles[i])
    if i == 0:
        plt.imshow(output[i], cmap = 'gray')
    else:
        plt.imshow(output[i], cmap = 'gray')
plt.show()

#%% Computing PSNR

def PSNR(img1, img2):
    mse = np.mean((img1 - img2) ** 2)
    if mse == 0:
        return 100
    PIXEL_MAX = 255.0
    return 20 * np.log10(PIXEL_MAX / np.sqrt(mse))

print('PSNR between two images is :',PSNR(Y,YC))


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler

"""
Item #04: Análise de componentes principais [[INCOMPLETO]]
- reter o 2 maiores componentes
- plotar os scatterplots das observações projetadas
"""

# funcao helper para desenho de vetores em grafico
def draw_vector(v0, v1, ax=None):
	ax = ax or plt.gca()
	arrowprops=dict(arrowstyle='->', linewidth=2, shrinkA=0, shrinkB=0)
	ax.annotate('', v1, v0, arrowprops=arrowprops)

# setando estilo e outras configs
seaborn.set()

# paths e arquivos
dataset = "datasets/glass.dat"
pca_barplot = "figures/item4/pca_barplot.png"
figpath = "figures/item4/"

# carregando dados e limpando coluna id (dencessaria)
df = pd.read_csv(dataset)
df = df.drop(["id"], axis=1)
classes = df["class"].unique()
df = df.drop(["class"], axis=1)

# normalizacao
data = np.array(df)
scaler = StandardScaler()
scaler.fit(data)
data = scaler.transform(data)

# PCA
pca = PCA(n_components=2)
projection = pca.fit_transform(data)

# plot
plt.scatter(projection[:,0], projection[:,1])
plt.title("PCA do conjunto de dados")


#!/usr/bin/env python
# -*- coding: utf-8 -*-

import matplotlib.pyplot as plt
import numpy as np

def f(x, r):
    """
    Implement the right-hand-side of the differential equation

        x' = r * x - x / (1 + x)
    """
    return r * x - x / (1 + x**2)

def plot(x, y, r):
    """
    Plot the vector field for a given value of the parameter `r`.

    Parameters
    ----------
    x: np.array
        The x-values
    y: np.array
        The y-values obtained for a specifc value of `r`
    r: float
        The value of `r` for which the `y` values have been obtained from `x`.
    """
    plt.plot(x, np.zeros(len(y)), color='grey')
    plt.plot(x, y)
    plt.xlabel('$x$')
    plt.ylabel(r'$\dot{x}$')
    plt.title(r'$\dot{x} = $' + f'$f(x, r={r})$')
    plt.show()

if __name__ == "__main__":
    x = np.linspace(-3., 3., 99)

    # Create a plot of the vector field for different values of r
    for r in [-2, 0, 0.5, 1, 5]:
        y = f(x, r)
        plot(x, y, r)


import numpy as np
import matplotlib.pyplot as plt

## Interpolare spline liniară

# Definesc funcția
def f(x):
    return x ** 2

# def f(x):
#     return np.cos(2 * x) - 2 * np.sin(3 * x)

# Definesc domeniul pe care fac interpolarea
left = -np.pi
right = +np.pi

# Numărul de funcții folosite în interpolare
N = 4

# Iau N + 1 puncte egal depărtate
x = np.linspace(left, right, N + 1)
# Eșantionez funcția
y = f(x)

def construieste_functie_spline_liniara(i):
    a = y[i]
    b = (y[i + 1] - y[i])/(x[i + 1] - x[i])

    def spline(t):
        return a + b * (t - x[i])

    return spline

x_grafic = np.linspace(left, right, 100)

y_grafic = f(x_grafic)

y_aproximat = np.piecewise(
    x_grafic,
    [
        (x[i] <= x_grafic) & (x_grafic < x[i + 1])
        for i in range(N - 1)
    ],
    [
        construieste_functie_spline_liniara(i)
        for i in range(N)
    ]
)

plt.plot(x_grafic, y_grafic, label='funcția')
plt.plot(x_grafic, y_aproximat, label='funcția aproximată')
plt.legend()
plt.show()


#! /usr/bin/python3

import sys
import pennylane as qml
import numpy as np

def gradient_200(weights, dev):
    r"""This function must compute the gradient *and* the Hessian of the variational
    circuit using the parameter-shift rule, using exactly 51 device executions.
    The code you write for this challenge should be completely contained within
    this function between the # QHACK # comment markers.

    Args:
        weights (array): An array of floating-point numbers with size (5,).
        dev (Device): a PennyLane device for quantum circuit execution.

    Returns:
        tuple[array, array]: This function returns a tuple (gradient, hessian).

            * gradient is a real NumPy array of size (5,).

            * hessian is a real NumPy array of size (5, 5).
    """

    @qml.qnode(dev, interface=None)
    def circuit(w):
        for i in range(3):
            qml.RX(w[i], wires=i)

        qml.CNOT(wires=[0, 1])
        qml.CNOT(wires=[1, 2])
        qml.CNOT(wires=[2, 0])

        qml.RY(w[3], wires=1)

        qml.CNOT(wires=[0, 1])
        qml.CNOT(wires=[1, 2])
        qml.CNOT(wires=[2, 0])

        qml.RX(w[4], wires=2)

        return qml.expval(qml.PauliZ(0) @ qml.PauliZ(2))

    gradient = np.zeros([5], dtype=np.float64)
    hessian = np.zeros([5, 5], dtype=np.float64)

    # QHACK #
    s = np.pi/2
    default = circuit(weights)
    weight_copy = np.copy(weights)
    for i in range(len(weights)):
        weight_copy[i] += s
        plus = circuit(weight_copy)
        weight_copy[i] -= (2 * s)
        minus = circuit(weight_copy)
        gradient[i] = (plus - minus)/(2 * np.sin(s))
        hessian[i][i] = (plus - 2 * default + minus) / 2
        weight_copy[i] = weights[i]

    weight_copy = np.copy(weights)
    for i in range(len(hessian)):
        for j in range(i, len(hessian[i])):
            if i == j:
                continue
            else:
                weight_copy[i] += s
                weight_copy[j] += s
                plus = circuit(weight_copy)
                weight_copy[i] -= 2 * s
                minus_1 = circuit(weight_copy)
                weight_copy[i] += 2 * s
                weight_copy[j] -= 2 * s
                minus_2 = circuit(weight_copy)
                weight_copy[i] -= 2 * s
                minus_3 = circuit(weight_copy)
                hessian[i][j] = (plus - minus_1 - minus_2 + minus_3) / (2 * np.sin(s))**2
                weight_copy[i] = weights[i]
                weight_copy[j] = weights[j]

    for i in range(len(hessian)):
        for j in range(0, i):
            hessian[i][j] = hessian[j][i]

    # QHACK #

    return gradient, hessian, circuit.diff_options["method"]

if __name__ == "__main__":
    # DO NOT MODIFY anything in this code block
    weights = sys.stdin.read()
    weights = weights.split(",")
    weights = np.array(weights, float)

    dev = qml.device("default.qubit", wires=3)
    gradient, hessian, diff_method = gradient_200(weights, dev)

    print(
        *np.round(gradient, 10),
        *np.round(hessian.flatten(), 10),
        dev.num_executions,
        diff_method,
        sep=","
    )


import theano
import theano.tensor as T
import numpy as np

x = T.dscalar('x')
m = T.dscalar('mu')
s = T.dscalar('s')

sigma = T.exp(s)
first = 1 / (sigma * T.sqrt(2 * np.pi))
second = T.exp(-T.sqr(x-m)/(2 * T.sqr(sigma)))

f0 = first * second
f_x0 = T.grad(f0, x)
f_m0 = T.grad(f0, m)
f_s0 = T.grad(f0, s)

# compilation
f_noraml = theano.function([x,m,s], f0)
fprime_noraml_x = theano.function([x,m,s], f_x0)
fprime_normal_m = theano.function([x,m,s], f_m0)
fprime_normal_s = theano.function([x,m,s], f_s0)


from sympy import Eq, Matrix, cancel, expand, fraction, gcd_list, lcm_list, poly, solve, symbols

def sphere(P1, P2, P3):
    # return F(x, y, z) such that F(x, y, z) = 0 is the sphere's equation
    g, h, j, k, x, y, z = symbols('g, h, j, k, x, y, z')
    sphere_eq = Eq(x**2 + y**2 + z**2 + g*x + h*y + k, 0)
    sphere_eqs = []
    sphere_eqs.append(sphere_eq.subs(x, P1[0]).subs(y, P1[1]).subs(z, P1[2]))
    sphere_eqs.append(sphere_eq.subs(x, P2[0]).subs(y, P2[1]).subs(z, P2[2]))
    sphere_eqs.append(sphere_eq.subs(x, P3[0]).subs(y, P3[1]).subs(z, P3[2]))
    s = solve(sphere_eqs, (g, h, k))
    return fraction(cancel(x**2 + y**2 + z**2 + s[g]*x + s[h]*y + s[k]))[0]

def coplanar(P1, P2, P3, P4):
    mat = []
    mat.append([P1[0], P1[1], P1[2], 1])
    mat.append([P2[0], P2[1], P2[2], 1])
    mat.append([P3[0], P3[1], P3[2], 1])
    mat.append([P4[0], P4[1], P4[2], 1])
    return Eq(fraction(cancel(Matrix(mat).det()))[0], 0)

def plane(P1, P2, P3):
    x, y, z = symbols('x, y, z')
    return coplanar((x, y, z), P1, P2, P3)

def intersect(P, S, sphere_l):
    # return the intersection of PS and sphere_l(x, y, z) = 0:
    x, y, z, t = symbols('x, y, z, t')
    xt, yt, zt = P[0] + (S[0] - P[0])*t, P[1] + (S[1] - P[1])*t, P[2] + (S[2] - P[2])*t
    t0 = solve(Eq(sphere_l.subs(x, xt).subs(y, yt).subs(z, zt)/t, 0), t)[0]
    return xt.subs(t, t0), yt.subs(t, t0), zt.subs(t, t0)

def multiplied(x, y, z, w):
    x1, y1, z1, w1 = fraction(cancel(x)), fraction(cancel(y)), fraction(cancel(z)), fraction(cancel(w))
    lcd = lcm_list([x1[1], y1[1], z1[1], w1[1]])
    return x1[0]*cancel(lcd/x1[1]), y1[0]*cancel(lcd/y1[1]), z1[0]*cancel(lcd/z1[1]), w1[0]*cancel(lcd/w1[1])

def to_homogeneous(P):
    return multiplied(P[0], P[1], P[2], 1)

def reduced(x, y, z, w):
    gcd = gcd_list([x, y, z, w])
    if gcd == 0:
        return 0, 0, 0, 1
    return cancel(x/gcd), cancel(y/gcd), cancel(z/gcd), cancel(w/gcd)

def cross(P1, P2, P3):
    x10, x11, x12, x13 = P1[0], P1[1], P1[2], P1[3]
    x20, x21, x22, x23 = P2[0], P2[1], P2[2], P2[3]
    x30, x31, x32, x33 = P3[0], P3[1], P3[2], P3[3]
    # generated by cross-3d.py
    x = -x11*x22*x33 + x11*x23*x32 + x12*x21*x33 - x12*x23*x31 - x13*x21*x32 + x13*x22*x31
    y = x10*x22*x33 - x10*x23*x32 - x12*x20*x33 + x12*x23*x30 + x13*x20*x32 - x13*x22*x30
    z = -x10*x21*x33 + x10*x23*x31 + x11*x20*x33 - x11*x23*x30 - x13*x20*x31 + x13*x21*x30
    w = x10*x21*x32 - x10*x22*x31 - x11*x20*x32 + x11*x22*x30 + x12*x20*x31 - x12*x21*x30
    return reduced(x, y, z, w)

def on_sphere(sphere_h, P):
    x, y, z, w = symbols('x, y, z, w')
    return expand(sphere_h.subs(x, P[0]).subs(y, P[1]).subs(z, P[2]).subs(w, P[3])) == 0

def tangent_plane(sphere_poly, P):
    # Tangent plane to point (x0, y0, z0, w0) and quadratic curve plane
    # /x\T/a b d g\/x\        /a b d g\/x0\
    # |y| |b c e h||y| = 0 is |b c e h||y0|
    # |z| |d e f j||z|        |d e f j||z0|
    # \w/ \g h j k/\w/        \g h j k/\w0/
    # For a sphere with equator on xy:
    # a = c = f
    # b = d = e = j = 0
    x, y, z, w = symbols('x, y, z, w')
    coeff_a = sphere_poly.coeff_monomial(x**2)
    coeff_g = sphere_poly.coeff_monomial(x*w)/2
    coeff_h = sphere_poly.coeff_monomial(y*w)/2
    coeff_k = sphere_poly.coeff_monomial(w**2)
    x0 = coeff_a*P[0] + coeff_g*P[3]
    y0 = coeff_a*P[1] + coeff_h*P[3]
    z0 = coeff_a*P[2]
    w0 = coeff_g*P[0] + coeff_h*P[1] + coeff_k*P[3]
    return reduced(x0, y0, z0, w0)

def dist2(P1, P2):
    return cancel((P1[0]/P1[3] - P2[0]/P2[3])**2 + (P1[1]/P1[3] - P2[1]/P2[3])**2 + (P1[2]/P1[3] - P2[2]/P2[3])**2)

def main():
    # https://imomath.com/index.cgi?page=inversion (Problem 12)
    a, b, c, d, e, f, x, y, z, w = symbols('a, b, c, d, e, f, x, y, z, w')
    A, B, C, S = (a, 0, 0), (0, b, 0), (c, 0, 0), (d, e, f)
    sphere_l = sphere(A, B, C)
    print('Sphere Equation:', sphere_l, '= 0')
    A1, B1, C1 = intersect(A, S, sphere_l), intersect(B, S, sphere_l), intersect(C, S, sphere_l)
    sphere_poly = poly(sphere_l, (x, y, z)).homogenize(w)
    sphere_h = sphere_poly.expr
    print('Sphere Equation in Homogeneous:', sphere_h, '= 0')
    S, A, B, C = to_homogeneous(S), to_homogeneous(A), to_homogeneous(B), to_homogeneous(C)
    A1, B1, C1 = to_homogeneous(A1), to_homogeneous(B1), to_homogeneous(C1)
    print('A1:', A1)
    print('B1:', B1)
    print('C1:', C1)
    print('Is A on Sphere?', on_sphere(sphere_h, A))
    print('Is B on Sphere?', on_sphere(sphere_h, B))
    print('Is C on Sphere?', on_sphere(sphere_h, C))
    print('Is A1 on Sphere?', on_sphere(sphere_h, A1))
    print('Is B1 on Sphere?', on_sphere(sphere_h, B1))
    print('Is C1 on Sphere?', on_sphere(sphere_h, C1))
    plane_A1 = tangent_plane(sphere_poly, A1)
    plane_B1 = tangent_plane(sphere_poly, B1)
    plane_C1 = tangent_plane(sphere_poly, C1)
    print('Tangent plane to A1:', plane_A1)
    print('Tangent plane to B1:', plane_B1)
    print('Tangent plane to C1:', plane_C1)
    O = cross(plane_A1, plane_B1, plane_C1)
    print('O:', O)
    OS2 = dist2(O, S)
    print('OS**2 =', OS2)
    print('OS**2 - OA1**2 =', OS2 - dist2(O, A1))
    print('OS**2 - OB1**2 =', OS2 - dist2(O, B1))
    print('OS**2 - OC1**2 =', OS2 - dist2(O, C1))

if __name__ == '__main__':
    main()


"""
measure.py

This module is for which performs measurements

"""
import numpy as np

def calculate_distance(r_a, r_b):
    """
    Calculate the distance between two points.

    Parameters
    ----------
    r_a, r_b : np.ndarray
	The coordinates of each point.

    Return
    ------
    distance : float
        The distance between the two points.

    Example
    --------
    >>> r1 = nparray([0, 0, 0])
    >>> r2 = nparray([0, 0.1, 0])
    >>> calculate_distance(r1, r2)
    0.1
    """
    # This function calculates the distance between two points given as numpy arrays.
    if not isinstance(r_a, np.ndarray) or not isinstance(r_b, np.ndarray):
        raise TypeError("Input are np array not list")

    distance_vector = (r_a - r_b)
    distance = np.linalg.norm(distance_vector)
    return distance

def calculate_angle(r_a, r_b, r_c, degrees = False):
    # Calculate the angle between three points. Answer is given in radians by default, but can be given in degrees
    # by setting degrees=True
    ab = r_b - r_a
    bc = r_b - r_c
    theta = np.arccos(np.dot(ab, bc) / (np.linalg.norm(ab)*np.linalg.norm(bc)))

    if degrees:
        return np.degrees(theta)
    else:
        return theta


#!/usr/bin/python
# -*- coding:utf-8 -*-

"""
最小二乘法线性回归
math
"""

import numpy as np
import matplotlib.pyplot as plt

def lstsq(X,Y):
    """
    最小二乘法线性回归
    """
    n = len(X)
    sumX,sumY,sumXY,sumXX =0,0,0,0
    for i in range(0,n):
        sumX  += X[i]
        sumY  += Y[i]
        sumXX += X[i]*X[i]
        sumXY += X[i]*Y[i]
    a = (n*sumXY -sumX*sumY)/(n*sumXX -sumX*sumX)
    b = (sumXX*sumY - sumX*sumXY)/(n*sumXX-sumX*sumX)
    return a,b,

if __name__ == '__main__':
    # 数据准备
    X = [1,2,3,4,5,6,7,8,9,10]
    Y = [10,11.5,12,13,14.5,15.5,16.8,17.3,18,18.7]

    #进行拟合
    a,b=lstsq(X,Y)
    print("y = %10.5fx + %10.5f" %(a,b))

    #展示拟合结果
    X1 = np.linspace(0,10)
    Y1 = a * X1 + b
    plt.plot(X1,Y1)
    plt.scatter(X,Y)
    plt.show()


#!/usr/bin/env python3
# coding: utf8

""" IMPORTS """
import numpy as np
import matplotlib.pyplot as plt

class Perceptron(object):

	def __init__(self):

		self.l_rate = 0.01
		self.n_epoch = 5
		self.bias = 0
		self.input_data = [[0.2, 0.7], [15.25, 14.37], [0.02, 0.68], [14.55, 16.36], [0.55, 0.36], [0.45, 0.16], [0.45, 0.26], [11.54, 17.226], [12.58, 17.36], [13.95, 15.26]]
		self.expected = [0, 1, 0, 1, 0, 0, 0, 1, 1, 1]

		#~ x = [i[0] for i in self.input_data]
		#~ y = [i[1] for i in self.input_data]
		#~ plt.scatter(x, y)
		#~ plt.show()

	def predict(self, row, weights):

		# Activation threshold function
		activation = 0
		for i in range(len(row) - 1):
			activation += weights[i] * row[i]
		activation += self.bias
		# Return class
		if activation >= 0.0:
			return 1.0
		else:
			return 0.0

	# Estimate Perceptron weights using stochastic gradient descent
	def train_weights(self):

		# Let's initiate weights with small values
		weights = list(np.random.uniform(low = 0, high = 0.1, size = 2))
		global_errors = []
		for epoch in range(self.n_epoch):
			# Keep track of errors for plotting
			epoch_errors = 0.0
			for row, expected in zip(self.input_data, self.expected):
				prediction = self.predict(row, weights)
				error = expected - prediction
				# We keep a track of global errors for plotting
				global_errors.append(abs(error))
				epoch_errors += abs(error)
				# If predicted and expected are different, update weights and bias
				if expected != prediction:
					self.bias = self.bias + self.l_rate * error
					for i in range(len(row)-1):
						weights[i] = weights[i] + self.l_rate * error * row[i]
			print('epoch: {}, lrate: {}, errors: {}'.format(epoch, self.l_rate, epoch_errors))

		plt.plot(global_errors)
		plt.ylim(-1, 2)
		plt.show()

		return weights

if __name__ == '__main__':
	# Calculate weights

	neuron = Perceptron()

	weights = neuron.train_weights()

	print(neuron.predict([8.23, 9.45], weights))
	print(neuron.predict([0.23, 1.45], weights))


##========================================================================================
import numpy as np
from scipy import linalg

""" --------------------------------------------------------------------------------------
fit h0 and w based on Expectation Reflection
input: features x[l,n], target: y[l]
 output: h0, w[n]
"""
def fit(x,y,niter_max=500,regu=0.1):
    #print(niter_max)

    n = x.shape[1]

    x_av = np.mean(x,axis=0)
    dx = x - x_av
    c = np.cov(dx,rowvar=False,bias=True)
    c += regu*np.identity(n)
    c_inv = linalg.inv(c)

    # initial values
    h0 = 0.
    w = np.random.normal(0.0,1./np.sqrt(n),size=(n))

    cost = np.full(niter_max,100.)
    for iloop in range(niter_max):
        h = h0 + x.dot(w)
        y_model = np.tanh(h)

        # stopping criterion
        cost[iloop] = ((y[:]-y_model[:])**2).mean()
        if iloop>0 and cost[iloop] >= cost[iloop-1]: break

        # update local field
        t = h!=0
        h[t] *= y[t]/y_model[t]
        h[~t] = y[~t]

        # find w from h
        h_av = h.mean()
        dh = h - h_av
        dhdx = dh[:,np.newaxis]*dx[:,:]

        dhdx_av = dhdx.mean(axis=0)
        w = c_inv.dot(dhdx_av)
        h0 = h_av - x_av.dot(w)

    return h0,w

""" --------------------------------------------------------------------------------------
calculate probability p based on x,h0, and w
input: x[l,n], w[n], h0
output: p[l]
"""
def predict(x,h0,w):
    #h = h0 + x.dot(w)
    #p = 1/(1+np.exp(-2.*h))
    #return p
    return np.sign(h0 + x.dot(w))


# -*- coding: UTF-8 -*-

from matplotlib import pyplot as plt
import numpy as np

################################################################################

def logistic(x, r):
    """Logistic map, with parameter r."""
    return r * x * (1 - x)

def bif_plot(x0, rs, axes):
    """Bifurcation plot for the logistic map.
    Inputs: x0 - initial condition.
            rs - Numpy array with values for
                 parameter r.
            axes - matplotib axes object."""
    y = np.zeros([2, 50])
    for r in rs:
        x = np.arange(x0, 800)
        for i in xrange(len(x)-1):
            x[i+1] = logistic(x[i], r)

        y[0, :] = r
        y[1, :] = x[-50:]
        axes.plot(y[0, :], y[1, :], 'b.')

################################################################################

if __name__=='__main__':
    # parameter definitions
    rs = np.linspace(0.001, 4, 2000) # values for the parameter r
    x0 = .5 #initial condition for x

    fig = plt.figure()
    ax = fig.add_subplot(111)
    bif_plot(x0, rs, ax)
    plt.show(fig)


# -*- coding: utf-8 -*-
# @Time    : 7/28/2018 5:58 PM
# @Author  : DonaldY

import numpy as np

# 1. 定义数据集
# 针对原 x 数据添加截距项系数 1
x = np.matrix([[1, 56], [1, 72], [1, 69], [1, 88], [1, 102], [1, 86], [1, 76], [1, 79], [1, 94], [1, 74]])
y = np.matrix([92, 102, 86, 110, 130, 99, 96, 102, 105, 92])

# 2. 定义 求解函数
def w_matrix(x, y):
    w = (x.T * x).I * x.T * y
    return w

w_matrix(x, y.reshape(10, 1))


import math
import numpy as np
import collections
import scipy.stats as sst
import matplotlib.pyplot as plt

def plot(*args, **kwargs):
    plt.plot(*args, **kwargs)
    plt.show()

def linregshow(x, y, col: str="r"):
    linregresult = sst.linregress(list(zip(x, y)))
    plot(x, y, col, x, [(val * linregresult.slope) + linregresult.intercept for val in x])
    return linregresult

def list_or_starargs(func):
    """This is a decorator to specify that a function either takes iterable input in the form of an iterable or a list of passed arguments.
    If other arguments are needed, the function will need to use kwargs.
    This passes the list as the first argument."""
    def decorated(*args, **kwargs):
        if isinstance(args[0], collections.Iterable):
            data = args[0]
            # We make generators into lists
            data = [val for val in data]
        else:
            data = args
        return func(data, **kwargs)

    return decorated

@list_or_starargs
def spridning(data):
    """Returns the size of the range of values in the data."""
    return max(data) - min(data)

@list_or_starargs
def medel(data):
    """Returns the arithmetic mean."""
    return sum(data) / len(data)

@list_or_starargs
def median(data):
    """Returns the median."""
    # We sort the data
    data = sorted(data)
    length = len(data)
    if length % 2 == 0:
        return medel(data[length // 2], data[(length // 2) - 1])
    else:
        return data[int(length // 2)]

@list_or_starargs
def kvartiler(data):
    """Returns the three quartiles of the data in order: lower, median, higher."""
    # We sort the data
    data = sorted(data)
    # We divide the data into two lists
    length = len(data)
    if length % 2 == 1:
        low_list = data[:(length // 2)]
        high_list = data[((length // 2) + 1):]
    else:
        low_list = data[:int(length / 2)]
        high_list = data[int(length / 2):]

    # We return the three quartiles
    return median(low_list), median(data), median(high_list)

def standardav(data, stick=False):
    """Returns the standard deviation of the input data, which has to be an iterable. stick specifies if it should be treated like
    non-total set of values (divide by n-1 instead of n)."""
    div_by = len(data) if (not stick) else (len(data) - 1)
    medelv = medel(data)
    return math.sqrt(sum([(val-medelv)**2 for val in data]) / div_by)

def normal_d(x, u, o):
    """Returns the value of a normal/standard distribution at the value x. u is Mu, and o is the standard deviation."""
    return (1 / (o * math.sqrt(2*math.pi))) * (math.e ** (-(((x-u)**2) / (2 * (o**2)))))