import numpy as np

class Loss():
    pass

                            ##########Regression Cost Functions#############

class MSE(Loss):

    def compute_cost(self,AL, Y):
        """
        Implement the MSE cost function

        Arguments:
        AL --  vector corresponding to your label predictions
        Y -- true "label" vector

        Returns:
        cost -- MSE regression cost
        grad -- MSE regression cost gradient
        """

        m = Y.shape[0]

        cost=(Y-AL)**2
        cost=cost/(m*2)

        grad=-(Y-AL)/m

        cost = np.squeeze(cost)      # To make sure your cost's shape is what we expect (e.g. this turns [[17]] into 17).
        assert(cost.shape == ())

        cost[np.isnan(cost)] = 0
        grad[np.isnan(grad)] = 0

        return cost,grad

                                        ##########Classification Cost Functions#############

class BinaryCrossEntropyLoss(Loss):

    def compute_cost(self,AL, Y):
        """
        Implement the cost function

        Arguments:
        AL -- probability vector corresponding to your label predictions
        Y -- true "label" vector

        Returns:
        cost -- Binary cross-entropy cost
        grad -- Binary cross-entropy gradient
        """

        m = Y.shape[0]

        # Compute loss from aL and y.
        cost = (1./m) * (-np.dot(Y.T,np.log(AL)) - np.dot((1-Y).T, np.log(1-AL)))

        grad = - (1./m) * (np.divide(Y, AL) - np.divide(1 - Y, 1 - AL))

        cost = np.squeeze(cost)      # To make sure your cost's shape is what we expect (e.g. this turns [[17]] into 17).
        assert(cost.shape == ())

        cost[np.isnan(cost)] = 0
        grad[np.isnan(grad)] = 0

        return cost,grad

class CategoricalCrossEntropyLoss(Loss):

    def compute_cost(self,AL, Y):
        """
        Implement the cost function

        Arguments:
        AL -- probability vector corresponding to your label predictions
        Y -- true "label" vector

        Returns:
        cost -- Categorical cross-entropy cost
        grad -- Categorical cross-entropy gradient
        """

        m = Y.shape[0]

        # Compute loss from aL and y.
        cost = -(1./m) * (Y*np.log(AL))
        cost=np.array(np.sum(cost))

        grad = - (1./m) * (np.divide(Y, AL))

        cost = np.squeeze(cost)      # To make sure your cost's shape is what we expect (e.g. this turns [[17]] into 17).
        assert(cost.shape == ())

        cost[np.isnan(cost)] = 0
        grad[np.isnan(grad)] = 0

        return cost,grad


# -*- coding: utf-8 -*-
from __future__ import absolute_import

from __future__ import print_function

from __future__ import division
#---------------------------------------------------------------------------

__author__ = 'Hui'

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

import numpy as np

from scipy.special import comb

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

def bernstein_poly(i, n, t, reverse=True):
    """
     The Bernstein polynomial of n, i as a function of t
    """
    if reverse:
        return comb(n, i) * ( t**(n-i) ) * (1 - t)**i
    else:
        return comb(n, i) * ( (1 - t)**(n-i) ) * t**i

# from control_points to curve_points:
def bezier_curve(points, nTimes=500, is_poly=False, is_crv=False):
    """
       Given a set of control points, return the
       bezier curve defined by the control points.

       points should be a list of lists, or list of tuples
       such as [ [1,1],
                 [2,3],
                 [4,5], ..[Xn, Yn] ]
        nTimes is the number of time steps, defaults to 1000

        See http://processingjs.nihongoresources.com/bezierinfo/

    Hui Note: given points, the returned crv points in reverse direction:
                Q[0] == points[-1]; Q[-1] == points[0]
    """
    if is_poly:
        from geometrylab.geometry import Polyline
        return Polyline(points,closed=False)
    else:
        nPoints = len(points)
        xPoints = np.array([p[0] for p in points])
        yPoints = np.array([p[1] for p in points])
        zPoints = np.array([p[2] for p in points])

        t = np.linspace(0.0, 1.0, nTimes)

        polynomial_array = np.array([ bernstein_poly(i, nPoints-1, t) for i in range(0, nPoints)])

        xvals = np.dot(xPoints, polynomial_array)
        yvals = np.dot(yPoints, polynomial_array)
        zvals = np.dot(zPoints, polynomial_array)
        Q = np.flip(np.c_[xvals,yvals,zvals],axis=0)

        if is_crv:
            crv = Polyline(Q,closed=False)
            return crv
        else:
            return Q

def berstein_matrix(n):
 #bezierM = lambda ts: np.matrix([[bernstein_poly(i,5,t) for i in range(6)] for t in ts])
    ts = np.linspace(0.0, 1.0, n)
    m = []
    for t in ts:
        m.append([bernstein_poly(i,n-1,t) for i in range(n)])
    m.reverse()
    return np.array(m)

# from curve_points to control_points:
def bezier_controlPoints(P):
    n = len(P)
    M = berstein_matrix(n)
    Q = np.dot(np.linalg.inv(M), P)
    return Q

def bezier_degree_evaluation(P, deg_evl):
    "Qi = i/(n+1) * P_{i-1} + (1-i/(n+1)) * P_i"
    "only from current curves' control_points_P to get evaluated control_points_Q"
    "deg_evl > len(P)-1 = n"
    num = len(P) # num=4, control points, P0,P1,P2,P3
    n = num-1    # degree=3, deg_evl=5

    Q = np.zeros((deg_evl+1,3))
    Q[0,:] = P[0,:]
    Q[-1,:] = P[-1,:]

    while n < deg_evl:   # 3<5
        for j in range(n): # 0,1,2
            i = j+1        # 1,2,3
            Q[i,:] = float(i)/(n+1)*P[i-1,:] + (1-float(i)/(n+1))*P[i,:]
        n += 1 # 4
        P = np.vstack((Q[:n,:], P[-1,:]))

    return Q

# def bezier_derivative(points, nTimes=100, d=1, is_poly=False, is_crv=False): #Hui add:
#     if d==1:
#         "first derivative"
#         nPoints = len(points)-1
#         xPoints = np.array([p[0] for p in points])
#         yPoints = np.array([p[1] for p in points])
#         zPoints = np.array([p[2] for p in points])

#         dx = xPoints[1:]-xPoints[:-1]
#         dy = yPoints[1:]-yPoints[:-1]
#         dz = zPoints[1:]-zPoints[:-1]

#         t = np.linspace(0.0, 1.0, nTimes)

#         polynomial_array = np.array([ bernstein_poly(i, nPoints-1, t) for i in range(0, nPoints)])

#         xvals = np.dot(dx, polynomial_array) * len(points)
#         yvals = np.dot(dy, polynomial_array) * len(points)
#         zvals = np.dot(dz, polynomial_array) * len(points)
#         Q = np.flip(np.c_[xvals,yvals,zvals],axis=0)

#     if is_crv:
#         from geometrylab.geometry import Polyline
#         crv = Polyline(Q,closed=False)
#         return crv
#     else:
#         return Q

def bezier_tangent_atparameters(ctrl_points,ti):
    "len(ti)>=1"
    n = len(ctrl_points) #==6
    dP = ctrl_points[1:,:] - ctrl_points[:-1,:]
    arr1 = np.array([bernstein_poly(i,n-2,ti,False) for i in range(0, n-1)]) # len=n-1

    xvals = np.dot(dP[:,0], arr1)
    yvals = np.dot(dP[:,1], arr1)
    zvals = np.dot(dP[:,2], arr1)
    Q = np.flip(np.c_[xvals,yvals,zvals],axis=0)
    T = Q / np.linalg.norm(Q,axis=1)[:,None]
    return T

def bezier_curvature_ataparameter(ctrl_points,ti,surfN=None,is_absolute=True):
    "P'(ti), P''(ti), P'''(ti) ,  ti=1/5, 2/5, 3/5, 4/5"
    n = len(ctrl_points) #==6
    n1,n2,n3 = n-1, n-2, n-3

    P = ctrl_points
    dP = P[1:,:] - P[:-1,:]
    ddP = dP[1:,:] - dP[:-1,:]
    dddP = ddP[1:,:] - ddP[:-1,:]

    arr  = np.array([bernstein_poly(i,n -1,ti,False) for i in range(0, n)])  # len=n
    arr1 = np.array([bernstein_poly(i,n1-1,ti,False) for i in range(0, n1)]) # len=n-1
    arr2 = np.array([bernstein_poly(i,n2-1,ti,False) for i in range(0, n2)]) # len=n-2
    arr3 = np.array([bernstein_poly(i,n3-1,ti,False) for i in range(0, n3)]) # len=n-3

    Pi = np.sum(P*arr,axis=0)
    dP = np.sum(dP*arr1,axis=0) * comb(n-1, 1)
    ddP = np.sum(ddP*arr2,axis=0) * comb(n-1, 2)
    dddP = np.sum(dddP*arr3,axis=0) * comb(n-1, 3)

    T = dP / np.linalg.norm(dP)
    k = np.linalg.norm(np.cross(dP,ddP)) / np.linalg.norm(dP)**3
    tau = np.dot(np.cross(dP,ddP), dddP) / np.linalg.norm(np.cross(dP,ddP))**2
    kg,kn,d = None,None,None
    if surfN is not None:
        kg = np.dot(np.cross(surfN,dP),ddP) / np.linalg.norm(dP)**3
        kn = np.dot(surfN,ddP) / np.linalg.norm(dP)**2
        if is_absolute:
            k,kg,kn,tau = np.abs(k),np.abs(kg),np.abs(kn),np.abs(tau)
        S = np.cross(surfN,T)
        d = tau*T-kn*S+kg*surfN
        d = d / np.linalg.norm(d)
    return Pi, T, [k,tau,kg,kn,d]

def bezier_curvature_atequalparameters(ctrl_points,is_asy_or_geo=True,num=5):
    "DENSE: P'(ti), P''(ti), P'''(ti) ,  ti=1/5, 2/5, 3/5, 4/5"
    n = len(ctrl_points)-1#==6-1
    n1,n2,n3 = n-1, n-2, n-3
    ti = np.arange(num+1) / num  #### ti==[0, 0.2, 0.4, 0.6, 0.8, 1]
    P = ctrl_points
    dP = P[1:,:] - P[:-1,:]
    ddP = dP[1:,:] - dP[:-1,:]
    dddP = ddP[1:,:] - ddP[:-1,:]

    arr  = np.array([bernstein_poly(i,n,ti,False) for i in range(0, n+1)])  # len=6
    arr1 = np.array([bernstein_poly(i,n1,ti,False) for i in range(0, n1+1)]) # len=5
    arr2 = np.array([bernstein_poly(i,n2,ti,False) for i in range(0, n2+1)]) # len=4
    arr3 = np.array([bernstein_poly(i,n3,ti,False) for i in range(0, n3+1)]) # len=3

    xvals = np.dot(P[:,0], arr)
    yvals = np.dot(P[:,1], arr)
    zvals = np.dot(P[:,2], arr)
    #Pi = np.flip(np.c_[xvals,yvals,zvals],axis=0)
    Pi = np.c_[xvals,yvals,zvals]

    xvals = np.dot(dP[:,0], arr1)
    yvals = np.dot(dP[:,1], arr1)
    zvals = np.dot(dP[:,2], arr1)
    T = np.c_[xvals,yvals,zvals]*n
    E1 = T / np.linalg.norm(T,axis=1)[:,None]

    xvals = np.dot(ddP[:,0], arr2)
    yvals = np.dot(ddP[:,1], arr2)
    zvals = np.dot(ddP[:,2], arr2)
    dT = np.c_[xvals,yvals,zvals]*n*(n-1)
    E2 = dT / np.linalg.norm(dT,axis=1)[:,None] ##NOTE: infact, for general t, E2 is not _|_  E1, but E3//E1XE2

    xvals = np.dot(dddP[:,0], arr3)
    yvals = np.dot(dddP[:,1], arr3)
    zvals = np.dot(dddP[:,2], arr3)
    ddT = np.c_[xvals,yvals,zvals]*n*(n-1)*(n-2)

    k = np.linalg.norm(np.cross(T,dT),axis=1) / np.linalg.norm(T,axis=1)**3
    tau = np.einsum('ij,ij->i',np.cross(T,dT), ddT) / np.linalg.norm(np.cross(T,dT),axis=1)**2

    tau = np.abs(tau) ##IF NOT ABS, WILL CHANGE THE DIRECTION
    #print('tau:[min,mean,max]=','%.2g' % np.min(tau),'%.2g' % np.mean(tau),'%.2g' % np.max(tau))

    E3 = np.cross(E1,E2)
    E3 = E3 / np.linalg.norm(E3,axis=1)[:,None]
    d = E1*tau[:,None]+E3*k[:,None]
    d = d / np.linalg.norm(d,axis=1)[:,None]

    if is_asy_or_geo:
        "asymptotic: surf_normal = binormal _|_ osculating_normal"
        srfN = E3 ## len==len(ti)
    else:
        "geodesic: surf_normal = osculating_normal"
        srfN = E2

    kg = np.einsum('ij,ij->i',np.cross(srfN,T),dT) / np.linalg.norm(T,axis=1)**3
    kn = np.einsum('ij,ij->i',srfN,dT) / np.linalg.norm(T,axis=1)**2

    kg,kn = np.abs(kg), np.abs(kn)

    return Pi,[E1,E2,E3],[kg,kn,k,tau,d]


import numpy as np
import matplotlib.pyplot as plt

n = np.arange(14)
fn=(-1/2)**n
hn1=np.pad(fn, (0,2), 'constant', constant_values=(0))
hn2=np.pad(fn, (2,0), 'constant', constant_values=(0))
h = hn1+hn2

nh=len(h)
x=np.array([1.0,2.0,3.0,4.0,2.0,1.0])
nx = len(x)

y = np.zeros(nx+nh-1)

for k in range(0,nx+nh-1):
	for n in range(0,nx):
		if k-n >= 0 and k-n < nh:
			y[k]+=x[n]*h[k-n]

print(y)
#plots
plt.stem(range(0,nx+nh-1),y)
plt.title('Filter Output using Convolution')
plt.xlabel('$n$')
plt.ylabel('$y(n)$')
plt.grid()# minor

plt.savefig('ynconv.png')


import numpy as np
import scipy.spatial.distance as dis
import matplotlib.pyplot as plt

__all__ = ['k_means']

# KMeans主函数
def k_means(data_set, cluster_count):
    point_count = np.shape(data_set)[0]  # 数据集中的待分类点个数

    # 列1：数据集归类的聚类中心（0,1,2,3），列2:数据集行向量到聚类中心的距离
    point_cluster_distances = np.zeros((point_count, 2), dtype=float)
    cluster_centers = data_set[:cluster_count, :]  # 取前4个点作为初始聚类中心

    iteration_flag = True  # 迭代结束标识
    iteration_count = 0  # 迭代次数

    while iteration_flag:
        iteration_flag = False
        iteration_count += 1

        # 遍历数据集中的所有点，计算每个点与聚类中心的最小欧式距离
        for index in range(point_count):
            # 遍历当前点到所有聚类中心的距离，获取最短距离的聚类中心
            current_point_to_cluster_distances = [dis.euclidean(data_set[index, :],
                                                                cluster_centers[j, :]) for j in range(cluster_count)]
            min_distance = min(current_point_to_cluster_distances)
            min_distance_cluster_index = current_point_to_cluster_distances.index(min_distance)

            # 找到了一个新聚类中心，重置标志位为True，继续迭代，如果没有找到新的聚类中心，说明迭代已经收敛，不再迭代
            if point_cluster_distances[index, 0] != min_distance_cluster_index:
                iteration_flag = True

            # 更新当前点找到的聚类中心以及距离
            point_cluster_distances[index, :] = min_distance_cluster_index, min_distance ** 2

        # 重新计算已经得到的各个聚类的质心
        for index in range(cluster_count):
            # 当前聚类的所有距离下标
            current_cluster_distance_indexes = np.nonzero(point_cluster_distances[:, 0].T == index)[0]
            # 当前聚类的所有点
            current_cluster_points = data_set[current_cluster_distance_indexes]
            cluster_centers[index, :] = np.mean(current_cluster_points, axis=0)

    print('cluster_centers: \n', cluster_centers)
    return cluster_centers, point_cluster_distances

def train(cluster_count=4):
    data_set_path = r"../data/point-set-kmeans.txt"
    # data_set_path = r"../data/point-set-bi-kmeans.txt"  # 错误的聚类
    data_set = np.loadtxt(data_set_path, dtype=float, delimiter='\t')
    cluster_centers, point_cluster_distances = k_means(data_set, cluster_count)
    cluster_point_distance_1 = point_cluster_distances[:, :1]
    colors = ['blue', 'green', 'red', 'gray', 'pink', 'cyan']

    for index in range(len(cluster_point_distance_1)):
        plt.scatter(data_set[index, 0], data_set[index, 1], c=colors[int(cluster_point_distance_1[index])], marker='o')

    plt.scatter(cluster_centers.T[0], cluster_centers.T[1], s=60, c='black', marker='D')
    plt.show()

if __name__ == '__main__':
    train()  # 5个点时效果很差


"""Individuals."""

from typing import List, Tuple

import math
import numpy as np
import random

# Custom types
Chromosome = List[float]
SearchSpace = Tuple[float, float]

class AB:
    """Approximated Brachistochrone.

    Approximated brachistochrones are the individuals that going to be evolving
    during the main algorithm execution. Each AB is represented as a set of
    n-1 vertical coordinates representing the overall curve, where n is the
    number of evenly distributed "slots" between the starting point and the
    final point.
    """

    def __init__(
            self,
            n: int,
            y: float,
            x: float,
            std: float,
            search_space: SearchSpace,
            chromosome: Chromosome = None
    ) -> None:
        """AB initialization."""
        self.n = n
        self.y = y
        self.x = x

        self.std = std

        self.search_space = search_space
        self.chromosome = chromosome if chromosome else self.initialize()

    def initialize(self) -> Chromosome:
        """Return a real-valued random vector constrained by the search space."""
        chromosome = []
        for _ in range(self.n - 1):
            value = self.y
            while value >= self.y:
                value = random.randint(*self.search_space)
            chromosome.append(value)
        return chromosome

    @property
    def fitness(self) -> float:
        """Compute AB's fitness based on Borschbach-Dreckmann."""
        total_sum = 0.0
        points = [self.y] + self.chromosome + [0]
        bin_width = self.x / self.n
        for i in range(self.n):
            si = np.sqrt(
                ((bin_width)**2) +
                ((points[i+1] - points[i])**2)
            )
            d = np.sqrt(self.y - points[i]) + np.sqrt(self.y - points[i+1])
            total_sum += si/d
        return total_sum


'''
  Module that contains the function that calculates a Local Outlier Factor.
  https://www.dbs.ifi.lmu.de/Publikationen/Papers/LOF.pdf
'''
import numpy

def distance(vector1, vector2):
    '''
    Euclidean distance.
    '''
    array1 = numpy.array(vector1)
    array2 = numpy.array(vector2)
    return numpy.linalg.norm(array1-array2)

def reach(candidate, k_distance, cluster_member, cluster):

    '''
    k-distance of candidate object p is defined as the distance d(p,o)
    between candidate p and an object o in cluster D such that:
        i)  For at least k objects o' in D/{p} d(p,o') <= d(p,o)
        ii) For at most k-1 objects o' in D/{p} d(p,o') < d(p,o)
    '''
    distances = list()
    for member in cluster:
        d = distance(candidate, member)
        if d > 0:
            distances.append(d)
    distances.sort()
    result = max(distances[:k_distance]) if distances[:k_distance] else 0.
    return max([result, distance(candidate, cluster_member)])

def local_reachability_density(test_point, k_distance, cluster):
    '''
    Local Reachability Density
    '''
    denominator = sum([reach(test_point, k_distance, member, cluster)
                       for member in cluster])
    return len(cluster)/denominator if denominator else 0.

def local_outlier_factor(test_point, k_distance, cluster):
    '''
    Return the LocalOutlierFactor for point 'p' compared
    to collection of reference points in 'D', using k-distance 'k'.
    '''
    ratios = list()
    for member in cluster:
        numerator = local_reachability_density(member,
                                               k_distance,
                                               cluster)

        denominator = local_reachability_density(test_point,
                                                 k_distance,
                                                 cluster)
        if denominator:
            ratios.append(numerator/denominator)

    result = sum(ratios)/float(len(ratios)) if ratios else 0.
    return result


from __future__ import division

import math
import numpy as np

from time import time

import sympy as sp

import mpmath as mp

from mpmath.ctx_mp_python import mpf

from scipy.misc import factorial
from scipy.special import gamma

precision = 53
mp.prec = precision
mp.pretty = True

def calculate_factorial_ratio(n, i):
	# This function calculates (n + i - 1)! / (n - i)!

	mp.dps = 50

	k = (n - i)

	result = 1
	for j in range(k + 2*i - 1, k, -1):
		result = mp.fmul(result, j)

	return result

def n_choose_k(n, k):

	j = n - k

	numerator = 1
	for i in range(1, k + 1):
		numerator *= (j + i)

	denominator = factorial(k)

	return numerator / denominator

def dirichlet_eta(s, N):

	def calculate_d_n(n):
		total = 0.0
		for k in range(n + 1):
			if k % 2 == 0:
				alternating_factor = 1
			else:
				alternating_factor = -1

			total += alternating_factor * n_choose_k(n, k) / ( k + 1)**s
		return total

	eta = 0.0
	for n in range(N + 1):
		d_n = calculate_d_n(n)
		eta += d_n / (2**(n + 1))

	return eta

def alternating_series(s, N):
	eta = dirichlet_eta(s, N)
	denominator = 1 - 2**(1 - s)
	zeta = eta / denominator

	return zeta

def riemann_siegel_theta(t):
	first_term = np.angle( gamma( (2.j*t + 1) / 4) )
	second_term = t * np.log(np.pi) / 2

	return first_term - second_term

def zeta_function(s, N):
	z = alternating_series(s, N)

	return z

def z_function(t, N=100000):
	zeta = zeta_function(1/2 + (1.j)*t, N)

	return mp.re( np.exp( 1.j * riemann_siegel_theta(t) ) * zeta )

def calculate_z(t):	# Convenient wrapper to use for roots.py
	return z_function(t, N=25)

if __name__ == '__main__':

	# print zeta_function(s=1/2 + 25.j, N=1000)
	# print z_function(t=18, N=100)

	start = time()

	eta = dirichlet_eta(1, N=25)
	print eta
	print abs(eta - np.log(2))

	end = time()

	print "Calculated using alternating series in {:.4f} seconds.".format(float(end - start))

import numpy,from scipy,import sympy,import mpmath,from mpmath


'''
The idea here is to have functions to analyse correlations between data.
y : data to be explained
x : explicative data
eps : random error
a, b : parameters to be estimated

Hypothesis A0:
y[i] is observed and random
x[i] is observed and not random
esp[i] is not observed and random

Hypothesis A1: errors are centered
E[esp[i]] = 0 for i = 1..n
E[y[i]] = 0 for i = 1..n (equivalent)

Hypothesis A2: Homogeneity of variances
Var(eps[i]) = sigma^2 for i = 1..n
Var(y[i]) = sigma^2 for i = 1..n (equivalent)

Hypothesis A3: esp[i] not correlated
Cov[esp[i], esp[j]] = 0 for i != j
Cov[esp[i], esp[j]] = 0 for i != j (equivalent)

Hypothesis A4: esp[i] normalised
esp[i] follow N(0, sigma^2)
'''

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

def average(x):
    res = 0
    n = 0
    for el in x:
        res += el
        n += 1
    return res/n

def cov(x, y):
    n = len(x)
    if n != len(y):
        return 'error: sizes of data are not matching'
    else:
        sum_x = 0
        sum_y = 0
        prod_mixte = 0
        for i in range(n):
            prod_mixte += x[i]*y[i]
            sum_x += x[i]
            sum_y += y[i]
        return (prod_mixte - sum_x * sum_y / n) / n

def var(x):
    return cov(x, x)

def coef_correlation(x, y):
    return cov(x, y)/np.sqrt(var(x)*var(y))

def linear_regression_coef(x, y):
    a = cov(x, y) / cov(x, x)
    b = average(y) - a * average(x)
    return a, b

class Regression:
    def __init__(self, x, y, model='linear'):
        self.model = model
        self.x = x
        self.y = y
        self.n = len(x)
        '''
        linear : y = a * x + b
        power : y = a * x ** b
        x, y : real data
        X, Y : linearized data
        y_approx : regression law applied to x
        Y_approx : regression law applied to X
        '''
        if self.model == 'power':
            self.X = np.log(self.x)
            self.Y = np.log(self.y)
            self.b, a_temp = linear_regression_coef(self.X, self.Y)
            self.a = np.exp(a_temp)
            self.eps = []
            self.y_approx = []
            self.Y_approx = []
            for k in range(self.n):
                self.eps.append(self.y[k] - self.a * self.x[k] ** self.b)
                self.y_approx.append(self.a * self.x[k] ** self.b)
                self.Y_approx.append(self.b * self.X[k] + a_temp)

        if self.model == 'linear':
            self.X = self.x
            self.Y = self.y
            self.a, self.b = linear_regression_coef(self.X, self.Y)
            self.eps = []
            self.y_approx = []
            self.Y_approx = []
            for k in range(self.n):
                self.eps.append(self.y[k] - self.a * self.x[k] - self.b)
                self.y_approx.append(self.a * self.x[k] + self.b)
                self.Y_approx.append(self.a * self.X[k] + self.b)

    def get_correlation(self):
        return coef_correlation(self.X, self.Y)

    def get_law(self):
        def create_fun(_a, _b, model):
            if model == 'linear':
                def fun(_x):
                    return _a * _x + _b
                return fun
            if model == 'power':
                def fun(_x):
                    return _a * _x ** _b
                return fun
        return create_fun(self.a, self.b, self.model)

    def get_str_law(self):
        if self.model == 'linear':
            return 'y = ' + str(np.round(self.a, decimals=4)) + ' * x + ' + str(np.round(self.b, decimals=4))

        if self.model == 'power':
            return 'y = ' + str(np.round(self.a, decimals=4)) + ' * x ^ ' + str(np.round(self.b, decimals=4))

    def get_sigma2(self):
        sigma2 = 0
        for el in self.eps:
            sigma2 += el ** 2
        sigma2 /= (self.n - 2)
        return sigma2

    def get_R2(self):
        return var(self.Y_approx)/var(self.Y)

    def plot(self):
        min_x = np.min(self.x)
        max_x = np.max(self.x)
        t = np.linspace(min_x, max_x, 500)
        fun_law = self.get_law()
        law_t = fun_law(t)
        legend = self.get_str_law() + '\n'\
            + 'R2 = ' + str(self.get_R2()) + '\n'\
            + 'sigma^2 = ' + str(self.get_sigma2())

        plt.figure()
        plt.scatter(self.x, self.y, color='black', marker='+')
        plt.plot(t, law_t, label=legend)
        plt.legend()
        plt.xlabel('X')
        plt.ylabel('Y')
        plt.show()

class DataAnalysis:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.regressions = []

    def regression(self, model='linear'):
        self.regressions.append(Regression(self.x, self.y, model))
        return 0

    def plot(self):
        min_x = np.min(self.x)
        max_x = np.max(self.x)
        t = np.linspace(min_x, max_x, 500)

        plt.figure()
        plt.scatter(self.x, self.y, color='black', marker='+')

        for regression in self.regressions:
            plt.scatter(self.x, regression.y_approx)
            fun_law = regression.get_law()
            law_t = fun_law(t)
            legend = regression.get_str_law() + '\n' \
                + 'R2 = ' + str(np.round(regression.get_R2(), decimals=4)) + '\n' \
                + 'sigma = ' + str(np.round(np.sqrt(regression.get_sigma2()), decimals=4))
            plt.plot(t, law_t, label=legend)
            plt.legend()

        plt.xlabel('X')
        plt.ylabel('Y')
        plt.show()

x0 = [28, 50, 55, 110, 60, 48, 70]
y0 = [130, 280, 268, 500, 320, 250, 400]
analyse = DataAnalysis(x0, y0)
analyse.regression('linear')
analyse.regression('power')
analyse.plot()


import numpy as np
import scipy.stats as stats

twain_data_str = ".225 .262 .217 .240 .230 .229 .235 .217"
snodgrass_data_str = ".209 .205 .196 .210 .202 .207 .224 .223 .220 .201"
twain_data = np.array([float(x) for x in twain_data_str.split()])
snodgrass_data = np.array([float(x) for x in snodgrass_data_str.split()])

# Wald test
twain_mu = twain_data.mean()
snodgrass_mu = snodgrass_data.mean()
diff_hat = twain_mu - snodgrass_mu
diff_se = np.sqrt(
    twain_data.var() / twain_data.size
    + snodgrass_data.var() / snodgrass_data.size
)

alpha = 0.05
z_alpha = stats.norm.ppf(1 - alpha / 2)
ci = (diff_hat - z_alpha * diff_se, diff_hat + z_alpha * diff_se)
w = np.abs(diff_hat - 0) / diff_se
p_value = 2 * stats.norm.cdf(-w)
print(
    "A 95% CI for the difference of means is given by",
    f"[{ci[0]:.3}, {ci[1]:.3}].",
)
print(f"The p-value for the Wald test is {p_value:.5f}.")

# permutation test
"""
The combined sample size is too large to iterate over all permutations,
so we sample instead.
"""
rng = np.random.default_rng()
joined_data = np.concatenate((twain_data, snodgrass_data))
twain_size = twain_data.size
b = 200000
positive_perms = 0
for _ in range(b):
    permuted_data = np.random.permutation(joined_data)
    perm_twain_data = permuted_data[:twain_size]
    perm_snodgrass_data = permuted_data[twain_size:]
    perm_diff = perm_twain_data.mean() - perm_snodgrass_data.mean()
    if perm_diff > diff_hat:
        positive_perms += 1

perm_p_value = positive_perms / b
print(f"The p-value for the permutation test is {perm_p_value:.5}.")


import math

import pandas as pd
import numpy as np
from sklearn import preprocessing

# Import
df = pd.read_csv("./data/data.csv")

# Save these here as they go away when we scale with preprocessing
X_columns = df.columns[:-1]

# Drop Y values
X_df = df.drop(labels="Y", axis="columns")

# See docs here: https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.scale.html#sklearn.preprocessing.scale
#
# This scales such that the mean of each feature is 0.
scaled = preprocessing.scale(X_df, with_std=False) # returns a nparray
zero_mean_scaled_df = pd.DataFrame(data=scaled, columns=X_columns)

# FOR THE MARKER
#
# HA! If I set 'with_std=True' in the preprocessing.scale, the transformed
# dataset is exactly what I need.
#
# I realised this AFTER implementing all of below so I'm going to
# keep this code in here just so you know that I know what's going on.

# Let's do some manual work for this next part
sum_of_squares_scaled = []
for column_name in zero_mean_scaled_df:
    column = zero_mean_scaled_df[column_name].tolist()
    n = len(column)

    sum_of_squares = 0
    for observation in column:
        sum_of_squares += (observation * observation)

    scale_factor = math.sqrt(n / sum_of_squares)
    scaled = []
    for observation in column:
        scaled.append(observation * scale_factor)

    sum_of_squares_scaled.append(scaled)

# convert to nparray - need to transpose
np_matrix = np.array(sum_of_squares_scaled).T

# convert to dataframe
final_scaled_df = pd.DataFrame(data=np_matrix, columns=X_columns)
# Add "Y" back on
final_scaled_df["Y"] = df["Y"]
# print(final_scaled_df.head())

# save to csv for later
final_scaled_df.to_csv("./data/transformed_data.csv", index=False)

# Now for the question, print out the sum of squares
print("Sum of squares for each transformed feature:")
for column_name in final_scaled_df:
    if column_name == "Y":
        continue

    column = final_scaled_df[column_name].tolist()

    sum_of_squares = 0
    for observation in column:
        sum_of_squares += (observation * observation)

    print(f"{column_name}: {sum_of_squares}")


from numpy import random, pi
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

# Parameters
N = 10_000  # number of required points
Ntrials, Nhits = 0, 0
acc_x, acc_y, acc_z = [], [], []  # accepted x, y
rej_x, rej_y, rej_z = [], [], []  # rejected x, y

# Rejection Sampling
while Nhits < N:
    Ntrials += 1
    x, y, z = random.uniform(-1, 1, 3)

    if x**2 + y**2 + z**2 < 1:
        acc_x.append(x)
        acc_y.append(y)
        acc_z.append(z)
        Nhits += 1
    else:
        rej_x.append(x)
        rej_y.append(y)
        rej_z.append(z)

print("Total number of samples drawn %d" % Ntrials)
print("Number of samples in the disk %d" % N)

fig = plt.figure()
ax = fig.gca(projection='3d')

ax.scatter(acc_x, acc_y, acc_z, color = 'green', s = 1) # parameter s determines the size of each dot in the scatter plot
ax.scatter(rej_x, rej_y, rej_z, color = 'red', s = 1)

ax.set_xlim([-1, 1])
ax.set_ylim([-1, 1])
ax.set_zlim([-1, 1])
#ax.set_aspect('equal')  # set aspect ratio 1:1

plt.show()


"""
Content under Creative Commons Attribution license CC-BY 4.0,
code under MIT license (c)2018 Sergio Rojas (srojas@usb.ve)

http://en.wikipedia.org/wiki/MIT_License
http://creativecommons.org/licenses/by/4.0/

Created on march, 2018
Last Modified on: may 15, 2018

   This program finds the algebraic solution of the equation
   a*x + b = c*x + d
"""

from sympy import symbols, Eq, solveset
x, a, b, c, d = symbols('x, a, b, c, d')

LHS = a*x + b
RHS = c*x + d

thesol = list( solveset( Eq(LHS, RHS), x) )

#rearrange the equation to read: LHS - RHS = 0
newLHS = LHS - RHS

newLHS = newLHS.subs(x, thesol[0])

if newLHS.simplify() == 0:
   print('The solution of {0} = {1}, is x = {2}'.format(LHS,RHS,thesol[0]))


# Activation Functions(활성함수)
# This function introduces activation functions in Tensorflow

import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
import tensorflow.nn as nn
from tensorflow.python.framework import ops
ops.reset_default_graph()

# Open graph session
sess = tf.Session()                                               # 항상 그렇듯이 이렇게 tensorflow graph를 실행해야 한다.

x_vals = np.linspace(start=-10., stop=10., num=100)

# ReLU activation       - 가장 일반적이고 널리 쓰임, max(0,x)와 같음
print(sess.run(tf.nn.relu([-3., 3., 10.])))
y_relu = sess.run(tf.nn.relu(x_vals))

# ReLU-6 activation         - min(max(0,x), 6)와 같음. CNN과 RNN에서 자주 쓰이는 함수 중 하나. 출력이 [0 3 6]이 된다.
print(sess.run(tf.nn.relu6([-3., 3., 10.])))
y_relu6 = sess.run(tf.nn.relu6(x_vals))

# Sigmoid activation          - smooth activation 중에서 가장 많이 사용되며 logistic function이라고도 불린다. 하지만 경사소실이 잦다. 0~1의 치역
print(sess.run(tf.nn.sigmoid([-1., 0., 1.])))
y_sigmoid = sess.run(tf.nn.sigmoid(x_vals))

# Hyper Tangent activation  - sigmoid와 같은 성ㅅ질을 가지지만, -1~1의 치역
print(sess.run(tf.nn.tanh([-1., 0., 1.])))
y_tanh = sess.run(tf.nn.tanh(x_vals))

# Softsign activation           - sign 함수의 부드러운 버젼. x / (abs(x)+1), -1~1의 치역
print(sess.run(tf.nn.softsign([-1., 0., 1.])))
y_softsign = sess.run(tf.nn.softsign(x_vals))

# Softplus activation           - ReLU 함수의 부드러운 버젼. log( exp(x)+1 ). 0~1의 치역
print(sess.run(tf.nn.softplus([-1., 0., 1.])))
y_softplus = sess.run(tf.nn.softplus(x_vals))

# Exponential linear activation(ELU)     - softplus와 비슷하지만, -1~1의 치역을 가진다. x <0 일 때 exp(x)+1, x >0 일 때 x
print(sess.run(tf.nn.elu([-1., 0., 1.])))
y_elu = sess.run(tf.nn.elu(x_vals))

# Plot the different functions
plt.plot(x_vals, y_softplus, 'r--', label='Softplus', linewidth=2)
plt.plot(x_vals, y_relu, 'b:', label='ReLU', linewidth=2)
plt.plot(x_vals, y_relu6, 'g-.', label='ReLU6', linewidth=2)
plt.plot(x_vals, y_elu, 'k-', label='ExpLU', linewidth=0.5)
plt.ylim([-1.5,7])
plt.legend(loc='top left')
plt.show()

plt.plot(x_vals, y_sigmoid, 'r--', label='Sigmoid', linewidth=2)
plt.plot(x_vals, y_tanh, 'b:', label='Tanh', linewidth=2)
plt.plot(x_vals, y_softsign, 'g-.', label='Softsign', linewidth=2)
plt.ylim([-2,2])
plt.legend(loc='top left')
plt.show()


import numpy as np
import random

def gen(var,n,m):
        beta = np.random.randint(9,size=m+1)
        X = np.random.rand(n,m+1)
        X[:,0] = 1
        h = np.dot(X, beta)
        e = np.random.normal(0,var,n)
        Y = h #+ e
        X = np.delete(X,0,1)
        print("this is known beta")
        print(beta)
        return beta, X, Y

def costf(x,y,beta,m,n):
        h = np.dot(x, beta)
        r = h - y
        return (1/(2*n))*(np.dot(r, r))**2

def grad_desc(X,Y,beta,alpha,k,n,m):
    for i in range(k+1):
        temp = X
        temp = np.transpose(temp)
        h = np.dot(X, beta)
        #print("hey this is h-y",h-Y)
        #beta = beta - (alpha/n)*np.sum(np.dot((h - Y), temp))
        beta = beta - (alpha/n)*((np.sum(np.transpose((h-Y)*np.transpose(X)),axis=0)))
        #print(costf(X,Y,beta,n,m))
    print("this is after descending the slope")
    print(beta)

    return beta

def lin_reg(X,Y,k,alpha):
    #add x_0 = 1
    #X[:,0] = 1
    m = len(X[0,:])
    n = len(X[:,0])
    X = np.append(np.ones(len(X[:,0]))[...,None],X,1)
    beta = np.zeros(m+1)
    beta = grad_desc(X,Y,beta,alpha,k,n,m)
    return beta #, cost(X,Y,beta,m,n)

beta,X,Y = gen(0.5,6,5)

k = 100000
alpha = 0.1
lin_reg(X,Y,k,alpha)


from superdifferentiator.forward.functions import X
import numpy as np
import math

def bgfs(f, init_x, accuracy = 1e-8, alphas =[.00001,.00005,.0001,.0005,0.001,0.005,0.01,0.05,0.1,0.5,1,5],
         max_iter = 1000,verbose = False):

    x_current = [X(init_x[i],'x'+str(i)) for i in  range(len(init_x))]
    B = np.eye(len(init_x))

    for i_iter in range(max_iter):
        func = f(x_current)
        f_jac = func.jacobian()[1][0].T
        p = -np.linalg.pinv(B) @f_jac

        f_minmin = 10**13
        alpha_minmin = .00001
        for alpha in alphas:
            f_min = f([x_current[i] + alpha * p[i,0] for i in range(len(x_current))])
            if f_min.val[0] < f_minmin:
                f_minmin = f_min.val[0]
                alpha_minmin = alpha

        if math.isnan(float(p[0])):
            print("It doesn't converge using bgfs! Please use some other methods or check if a maximum/minimum exists!")
            return [x_current[i].val[0] for i in range(len(x_current))]

        s = alpha_minmin * p
        if np.linalg.norm(s) <= accuracy:
            print('Since the shifted distance is smaller than {}, we stop the loop at {}th iteration.'.format(accuracy,i_iter))
            break
        x_current = [x_current[i] + alpha_minmin * p[i,0] for i in range(len(x_current))]
        if verbose:
            print('At {}th iteration, current x value is: '.format(i_iter),[x_current[i].val[0] for i in range(len(x_current))],
                  ', the step taken is: ',s,'.\n' )
        y_current = f(x_current).jacobian()[1][0].T - f_jac

        B += y_current.dot(y_current.T)/(y_current.T.dot(s)) - B.dot(s).dot(s.T).dot(B.T)/(s.T.dot(B).dot(s))

    final_del = [x_current[i].val[0] for i in range(len(x_current))]
    if i_iter == max_iter-1:
        print("Notice that the change in distance of x is still larger than input accuracy! It probably doesn't converge using bgfs! ")
    if verbose:
        print('The final value we get is',final_del,'.')
    return final_del


"""
Lun. 12 Sep 2018

Author: Abdollah RIDA
"""

#IMPORTING LIBS

import numpy as np
import scipy.stats as si
import matplotlib.pyplot as plt

#Helper functions:

def d_m(x, v):
    d_ = np.log(x) / np.sqrt(v) - .5 * np.sqrt(v)
    return d_

#Q1-a

def C0(r, T, S0, K, sigma):

    X0 = S0 / (K * np.exp(-r*T))

    C = si.norm.cdf(- d_m(X0, sigma**2 * T))

    return np.exp(-r*T) * C

def Delta0(r, T, S0, K, sigma):

    X0 = S0 / (K * np.exp(-r*T))

    D = si.norm.pdf(- d_m(X0, sigma**2 * T))

    return - np.exp(-r*T) * D / (S0 * np.sqrt(sigma**2 * T))

#Q1-b

def Brownian(n, i, T):
	#We fist define the time step Dt
    dt = T/n

    #We then create an array of i drawings following N(0, Dt)
    z = np.random.normal(0, 1, i) * np.sqrt(dt)

    #We specify W_0 = 0
    z[0] = 0

    #We then compute the cumulative sums to obtain W
    W = np.cumsum(z)
    return list(W)

def S_(r, sigma, S0, T, n, W):
    S__ = []

    for i in range(n):
    	S__ += [S0 * np.exp((r - sigma**2 / 2) * i * T/n + sigma * W[i])]

    return S__

def MC_C(r, T, S0, K, sigma, M, n):
    Ind_ = []

    for k in range(M):
        W = Brownian(n, n, T)
        S_T = S_(r, sigma, S0, T, n, W)[-1]
        if S_T <= K:
            Ind_ += [1]
        else:
            Ind_ += [0]

    Ind_ = np.array(Ind_)
    Esp = np.cumsum(Ind_)[-1] / M

    return np.exp(-r * T) * Esp

def Diff_Delta0(r, T, S0, K, sigma, M, n, epsilon):
    return (MC_C(r, T, S0 + epsilon, K, sigma, M, n) - MC_C(r, T, S0 - epsilon, K, sigma, M, n))/ (2 * epsilon)

def MC_Delta(r, T, S0, K, sigma, M, n):
    Ind_ = []

    for k in range(M):
        W = Brownian(n, n, T)
        S_T = S_(r, sigma, S0, T, n, W)[-1]
        if S_T <= K:
            Ind_ += [W[-1] / (S0 * sigma * T)]
        else:
            Ind_ += [0]

    Ind_ = np.array(Ind_)
    Esp = np.cumsum(Ind_)[-1] / M

    return np.exp(-r * T) * Esp


import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

# create a relatively long impulse response
inputSignal = np.zeros(2048)
# make the first sample == 1
inputSignal[0] = 1
# use this container to get a copy of the b and a coefficiencts for each 4th order filter
filterSystems = []

# ---------- butterworth filter ----------
bArray = [] # for b coeffecients
aArray = [] # for a coeffecients
wArray = [] # for omega
hArray = [] # for H
orderArray = [1, 2, 4, 5] # orders to use
omega_c = 0.25 # cutoff frequency

for i in orderArray:
    b, a = signal.butter(N=i, Wn=omega_c)
    if i == 4:
        filterSystems.append([b,a])
    w, h = signal.freqz(b, a)
    bArray.append(b)
    aArray.append(a)
    wArray.append(w)
    hArray.append(h)

fig = plt.figure(figsize=(16, 9))
for index in range(len(orderArray)):
    plt.plot(wArray[index], 20 * np.log10(abs(hArray[index])), label="order = " + str(orderArray[index]))
plt.title('Butterworth Filter Frequency Response: Comparison')
plt.xlabel('Frequency [up to Nyquist]')
plt.xlim([0, np.pi])
plt.ylim([-60, 12])
plt.ylabel('Amplitude [dB]')
plt.grid(which='both', axis='both')
plt.axvline(omega_c*np.pi, color='black') # cutoff frequency
plt.legend()
plt.savefig('Butterworth.png')

# ---------- chebyshev 1 ----------
bArray = []
aArray = []
wArray = []
hArray = []
orderArray = [1, 2, 4, 5]
omega_c = 0.25
for i in orderArray:
    b, a = signal.cheby1(N=i, rp=6, Wn=omega_c)
    if i == 4:
        filterSystems.append([b,a])
    w, h = signal.freqz(b, a)
    bArray.append(b)
    aArray.append(a)
    wArray.append(w)
    hArray.append(h)

fig = plt.figure(figsize=(16, 9))
for index in range(len(orderArray)):
    plt.plot(wArray[index], 20 * np.log10(abs(hArray[index])), label="order = " + str(orderArray[index]))
plt.title('Chebyshev Type 1 Filter Frequency Response: Comparison')
plt.xlabel('Frequency [up to Nyquist]')
plt.xlim([0, np.pi])
plt.ylim([-60, 12])
plt.ylabel('Amplitude [dB]')
plt.grid(which='both', axis='both')
plt.axvline(omega_c*np.pi, color='black') # cutoff frequency
plt.legend()
plt.savefig('ChebyshevT1.png')

# ---------- chebyshev 2 ----------
bArray = []
aArray = []
wArray = []
hArray = []
orderArray = [1, 2, 4, 5]
omega_c = 0.25
for i in orderArray:
    b, a = signal.cheby2(N=i, rs=54, Wn=omega_c)
    if i == 4:
        filterSystems.append([b,a])
    w, h = signal.freqz(b, a)
    bArray.append(b)
    aArray.append(a)
    wArray.append(w)
    hArray.append(h)

fig = plt.figure(figsize=(16, 9))
for index in range(len(orderArray)):
    plt.plot(wArray[index], 20 * np.log10(abs(hArray[index])), label="order = " + str(orderArray[index]))
plt.title('Chebyshev Type 2 Filter Frequency Response: Comparison')
plt.xlabel('Frequency [up to Nyquist]')
plt.xlim([0, np.pi])
plt.ylim([-60, 12])
plt.ylabel('Amplitude [dB]')
plt.grid(which='both', axis='both')
plt.axvline(omega_c*np.pi, color='black') # cutoff frequency
plt.legend()
plt.savefig('ChebyshevT2.png')

# ---------- elliptic ----------
bArray = []
aArray = []
wArray = []
hArray = []
orderArray = [1, 2, 4, 5]
omega_c = 0.25
for i in orderArray:
    b, a = signal.ellip(N=i, rp=6, rs=54, Wn=omega_c)
    if i == 4:
        filterSystems.append([b,a])
    w, h = signal.freqz(b, a)
    bArray.append(b)
    aArray.append(a)
    wArray.append(w)
    hArray.append(h)

fig = plt.figure(figsize=(16, 9))
for index in range(len(orderArray)):
    plt.plot(wArray[index], 20 * np.log10(abs(hArray[index])), label="order = " + str(orderArray[index]))
plt.title('Elliptic Filter Frequency Response: Comparison')
plt.xlabel('Frequency [up to Nyquist]')
plt.xlim([0, np.pi])
plt.ylim([-60, 12])
plt.ylabel('Amplitude [dB]')
plt.grid(which='both', axis='both')
plt.axvline(omega_c*np.pi, color='black') # cutoff frequency
plt.legend()
plt.savefig('Elliptic.png')

# ---------- graph the impulse responses ----------
names = ["Butterworth","Chebyshev T1","Chebyshev T2","Elliptic"]
fig = plt.figure(figsize=(16, 9))
nameIndex = 0
for coef in filterSystems:
    fImpulse = signal.lfilter(coef[0], coef[1], inputSignal) # calculate impulse response
    plt.plot(fImpulse, label=names[nameIndex])
    nameIndex += 1
plt.title('Compare 4th Order Filter Impulse Response')
plt.xlabel('Time [samples]')
plt.xlim([0, 128])
plt.ylabel('Amplitude')
plt.grid(which='both', axis='both')
plt.legend()
plt.savefig('CompareFilterTime.png')


"""Unit tests for LEAP's suite of real-valued fitness functions."""
import numpy as np
from pytest import approx

from leap_ec.real_rep import problems

########################
# Tests for GriewankProblem
########################
def test_GriewankProblem_eval():
    """The value of a test point should be what we expected."""
    t = np.array((0.5, 0.5))

    # In two dimensions, the Griewank function expands like so
    expected = t[0]**2/4000 + t[1]**2/4000 - np.cos(t[0]/np.sqrt(1))*np.cos(t[1]/np.sqrt(2)) + 1

    p = problems.GriewankProblem()
    assert(approx(expected) == p.evaluate(t))

########################
# Tests for WeierstrassProblem
########################
def test_WeierstrassProblem_eval():
    """The Weierstrass function has a (0, ... ,0) in all dimensions
    and have a fitness of zero.
    """
    p = problems.WeierstrassProblem()

    assert(approx(0) == p.evaluate(np.array([0, 0])))
    assert(approx(0) == p.evaluate(np.array([0]*25)))


import numpy as np
import cvxpy as cp
from geometry import Ellipsoid

def cvx_ellipsoid(A, b):
    dim = len(A[0])
    m = len(b)
    C = cp.Variable((dim, dim), symmetric=True)
    d = cp.Variable(dim)
    objective = cp.Maximize(cp.atoms.log_det(C))
    constraints = [C >> 0.]
    constraints += [cp.atoms.norm(C @ A[i].T, 2) + A[i] @ d <= b[i] for i in range(m)]

    prob = cp.Problem(objective, constraints)
    prob.solve(verbose=True)
    # return C.value, d.value, prob.value
    return Ellipsoid(dim, C.value, d.value), prob.value

if __name__ == '__main__':
    #Vertices of a pentagon in 2D
    p = [[0., 0.], [1., 3.], [5.5, 4.5], [7., 4.], [7., 1.], [3., -2.]]
    nVerts = len(p)

    #The hyperplane representation of the same polytope
    A = [[-p[i][1] + p[i - 1][1], p[i][0] - p[i - 1][0]]
         for i in range(len(p))]
    b = [A[i][0] * p[i][0] + A[i][1] * p[i][1] for i in range(len(p))]
    A = np.array(A)
    b = np.array(b)

    # Po, co = lownerjohn_outer(p)
    ellipsoid, volume = cvx_ellipsoid(A, b)
    print(ellipsoid.C_, ellipsoid.d_, volume)

    #Visualization
    try:
        import numpy as np
        import matplotlib
        matplotlib.use('Agg')
        import matplotlib.pyplot as plt
        import matplotlib.patches as patches

        #Polygon
        fig = plt.figure()
        ax = fig.add_subplot(111)
        ax.add_patch(patches.Polygon(p, fill=False, color="red"))
        #The inner ellipse
        theta = np.linspace(0, 2 * np.pi, 100)
        Ci, di = ellipsoid.C_, ellipsoid.d_
        x = Ci[0][0] * np.cos(theta) + Ci[0][1] * np.sin(theta) + di[0]
        y = Ci[1][0] * np.cos(theta) + Ci[1][1] * np.sin(theta) + di[1]
        ax.plot(x, y)
        #The outer ellipse
        # x, y = np.meshgrid(np.arange(-1.0, 8.0, 0.025), np.arange(-3.0, 6.5, 0.025))
        # ax.contour(x, y, (Po[0][0] * x + Po[0][1] * y - co[0])**2 + (Po[1][0] * x + Po[1][1] * y - co[1])**2, [1])
        # ax.autoscale_view()
        ax.xaxis.set_visible(False)
        ax.yaxis.set_visible(False)
        fig.savefig('ellipsoid.png')
    except:
        print("Inner:")
        print("  C = ", Ci)
        print("  d = ", di)
        # print("Outer:")
        # print("  P = ", Po)
        # print("  c = ", co)


import matplotlib.pylab as pylab
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import animation
from scipy.integrate import odeint
from pylab import plot,xlabel,ylabel,title,legend,figure,subplots
from pylab import cos, pi, arange, sqrt, pi, array, array

def MassSpringDamper(state,t):

    k=2.714;            # spring constant (N/m)
    c=0.437;           #damping coefficient (Ns/m)
    m=4.871;             # mass (kg)
    # unpack the state vector
    x,xd = state # displacement,x and velocity x'
    # compute acceleration xdd = x''
    # Force F is a sinusoidal with below parameters

    A = 5.0 # amplitude
    xdd = -k*x/m -c*xd + A*cos(2*pi*t)
    return [xd, xdd]

z = input("input initial Displacement Z")
z = float(z)
print(z)
state0 = [z, 0]
ti = 0.0
tf = 4.0  # final time
step = 0.001  # step
t = arange(ti, tf, step)
state = odeint(MassSpringDamper, state0, t)
x = array(state[:,[0]])
xd = array(state[:,[1]])

# Plotting displacement and velocity
pylab.rcParams['figure.figsize'] = (15, 12)
pylab.rcParams['font.size'] = 18

fig, ax1 = pylab.subplots()
ax2 = ax1.twinx()
ax1.plot(t,x*1e3,'b',label = r'$x (mm)$', linewidth=2.0)
ax2.plot(t,xd,'g--',label = r'$\dot{x} (m/sec)$', linewidth=2.0)
ax2.legend(loc='lower right')
ax1.legend()
ax1.set_xlabel('time , sec')
ax1.set_ylabel('disp (m)',color='b')
ax2.set_ylabel('velocity (m/s)',color='g')
pylab.title('Mass-Spring System')
pylab.grid()
pylab.show()

fig = plt.figure()
fig.set_dpi(50)
fig.set_size_inches(7, 6.5)
a=np.arange(1,10,0.1)
animati=[]
ax = plt.axes(xlim=(-3, 3), ylim=(0, 1))
patch = plt.Rectangle((1, 0),0.8, 0.2, fc='g')
animati.append(patch)
l1,=ax.plot([],[],lw=2,color='k')
animati.append(l1)
l2,=ax.plot([],[],lw=2,color='b')
animati.append(l2)

def init():
    animati[0].set_xy([state0[0],0])
    ax.add_patch(animati[0])
    animati[1].set_data([],[])
    animati[2].set_data([],[])
    return animati

def animate(i):
    animati[0].set_xy([x[i],0])
    animati[1].set_data([-5,x[i]],[0.05,0.05])
    animati[2].set_data([-5,x[i]],[0.15,0.15])
    return animati

anim = animation.FuncAnimation(fig, animate,
                               init_func=init,
                               frames=10000,
                               interval=0.00001,
                               blit="True")

plt.show()

Design Study Assignment 1/sineSignalInputCart.py


from scipy import linalg
import numpy as np
import matplotlib.cm as cm
from matplotlib.mlab import bivariate_normal
import matplotlib.pyplot as plt
# %matplotlib inline

# == Set up the Gaussian prior density p == #
Σ = [[0.3**2, 0.0], [0.0, 0.3**2]]
Σ = np.matrix(Σ)
x_hat 	 = np.matrix([0.5, -0.5]).T
# == Define the matrices G and R from the equation y = G x + N(0, R) == #
G = [[1, 0], [0, 1]]
G = np.matrix(G)
R = 0.5 * Σ
# == The matrices A and Q == #
A = [[1.0, 0], [0, 1.0]]
A = np.matrix(A)
Q = 0.3 * Σ
# == The observed value of y == #
y = np.matrix([2.3, -1.9]).T

# == Set up grid for plotting == #
x_grid = np.linspace(-1.5, 2.9, 100)
y_grid = np.linspace(-3.1, 1.7, 100)
X, Y = np.meshgrid(x_grid, y_grid)

def gen_gaussian_plot_vals(μ, C):
    "Z values for plotting the bivariate Gaussian N(μ, C)"
    m_x, m_y = float(μ[0]), float(μ[1])
    s_x, s_y = np.sqrt(C[0, 0]), np.sqrt(C[1, 1])
    s_xy = C[0, 1]
    return bivariate_normal(X, Y, s_x, s_y, m_x, m_y, s_xy)

fig, ax = plt.subplots(figsize=(10, 8))
ax.grid()

# Plot the figure
# Density 1
Z = gen_gaussian_plot_vals(x_hat, Σ)
cs1 = ax.contour(X, Y, Z, 6, colors="black")
ax.clabel(cs1, inline=1, fontsize=10)

# Density 2
#Kalman Gain
K = Σ * G.T * linalg.inv(G * Σ * G.T + R)
# Update the state estimate
x_hat_F = x_hat + K*(y - G * x_hat)
#update covariance estimation
Σ_F = Σ - K * G * Σ
Z_F = gen_gaussian_plot_vals(x_hat_F, Σ_F)
cs2 = ax.contour(X, Y, Z_F, 6, colors="black")
ax.clabel(cs2, inline=1, fontsize=10)

# Density 3
# Predict next state of the feature with the last state and predicted motion
#https://stackoverflow.com/questions/14058340/adding-noise-to-a-signal-in-python
new_x_hat = A * x_hat_F
# print(new_x_hat)
#predict next covariance
new_Σ = A * Σ_F * A.T + Q
new_Z = gen_gaussian_plot_vals(new_x_hat, new_Σ)
cs3 = ax.contour(X, Y, new_Z, 6, colors="black")
ax.clabel(cs3, inline=1, fontsize=10)
ax.contourf(X, Y, new_Z, 6, alpha=0.6, cmap=cm.jet)
ax.text(float(y[0]), float(y[1]), "$y$", fontsize=20, color="black")

plt.show()
dt = 33.3e-3
#state update matrices
A = np.matrix( ((1, 0, dt, 0),(0, 1, 0, dt),(0, 0, 1, 0),(0, 0, 0, 1)) )
Q = np.matrix( (30, 68, 0, 0) ).transpose()
B = np.matrix( ((dt**2/2),(dt**2/2), dt, dt)).transpose()
C = np.matrix( ((1,0,0,0),(0,1,0,0)) ) #this is our measurement function C, that we apply to the state estimate Q to get our expect next/new measurement
Q_estimate = Q
u = .005 #define acceleration magnitude

marker_noise_mag = .1; #process noise: the variability in how fast the Hexbug is speeding up (stdv of acceleration: meters/sec^2)
tkn_x = 1;  #measurement noise in the horizontal direction (x axis).
tkn_y = 1;  #measurement noise in the horizontal direction (y axis).
Ez = np.matrix(((tkn_x,0),(0,tkn_y)))
Ex = np.matrix( ((dt**4/4,0,dt**3/2,0),(0,dt**4/4,0,dt**3/2),(dt**3/2,0,dt**2,0),(0,dt**3/2,0,dt**2)) )*marker_noise_mag**2# Ex convert the process noise (stdv) into covariance matrix
P = Ex; # estimate of initial Hexbug position variance (covariance matrix)

# Predict next state of the Hexbug with the last state and predicted motion.
Q_estimate = A*Q_estimate + B*u;
# predic_state = [predic_state; Q_estimate(1)] ;
# predict next covariance
P = A*P*A.T + Ex;
# predic_var = [predic_var; P] ;
# predicted Ninja measurement covariance
# Kalman Gain
K = P*C.T*linalg.inv(C*P*C.T + Ez);
# Update the state estimate
x_avg = 32
y_avg = 70
Q_loc_meas = np.matrix( (x_avg, y_avg) ).transpose()
Q_estimate = Q_estimate + K * (Q_loc_meas - C*Q_estimate);
print(Q_estimate)
# update covariance estimation.
P = (np.identity(4) - K*C)*P;

import csv

float_list = [1.13, 0.25, 3.28]

# with open('ANN_0.csv', "w") as file:
#     writer = csv.writer(file, delimiter=',')
#     writer.writerow(Ez)

outfile = open('./ANN_0.csv','w')
writer=csv.writer(outfile)
writer.writerow(float_list)
# writer.writerow(['SNo', 'States', 'Dist', 'Population'])
# writer.writerows(list_of_rows)
writer.writerow(float_list)
writer.writerow(float_list)
writer.writerow(float_list)
writer.writerow(float_list)


import numpy as np

class LeastSquares:

    def __init__(self,data):
        self.data = data

    def lin_matrix(self):
        one_arr = np.ones([self.data.size,1]) #array of ones concatenated to matrices
        lin = np.hstack([one_arr, self.data]) #appending array of ones to array of data matrix
        return lin

    def quad_matrix(self):
        lin = self.lin_matrix()
        quad = np.hstack([lin,self.data**2]) #appending lin to array of data squared
        return quad

    def cub_matrix(self):
        quad = self.quad_matrix()
        cub = np.hstack([quad,self.data**3]) ##appending quad to array of data cubed
        return cub

    def pow_matrix(self):
        one_arr = np.ones([self.data.size,1])
        pow_m = np.hstack([one_arr,np.log(self.data)]) #appending array of ones to array of log xvalues
        return pow_m

    #parameters data_matrix, y points, and noise covariance
    #returns y_model, x_bar (parameters for fit) and error covariance
    def ymodel(self,data_matrix,yval,noise_cov=None):
        if noise_cov == None:
            noise_cov = np.identity(data_matrix.shape[0])

        #calculating parameters
        dot_matrix = np.dot(data_matrix.T,np.linalg.inv(noise_cov)) #Step 1
        doty_matrix = np.dot(dot_matrix,yval) #Step 2
        inv_matrix = np.linalg.inv(np.dot(dot_matrix,data_matrix)) #Step 3
        x_bar = np.dot(inv_matrix, doty_matrix) #Step 4
        predict_y = np.dot(data_matrix, x_bar) #Step 5
        return predict_y, x_bar, inv_matrix

    def coef(self,data_matrix,yval,noise_cov=None):
        predict_y,x_bar,inv_matrix = self.ymodel(data_matrix,yval)
        return x_bar

    #args extended data_matrix (with extra x points added), y points, index where actual data begins in data_matrix_extend
    #returns y_model, x_bar (parameters for fit) and error covariance
    def ymodel_extend(self,data_matrix_extend,yval,index_begin_x):
        data_matrix = data_matrix_extend[index_begin_x:] #slicing array to section with only x values from data
        predict_y,x_bar,inv_matrix = self.ymodel(data_matrix,yval)
        predict_y = np.dot(data_matrix_extend, x_bar)
        return predict_y,x_bar,inv_matrix

    def error_bar(self,err_cov):
        err = np.sqrt(np.diag(err_cov)) #taking the square root of the diagonal of V
        return err


import numpy as np
import matplotlib.pyplot as plt

def f(x) :

    s = np.power(x,3) + 4*np.power(x,2) - 10

    return s

def Bisection(a,b,Tol,Nmax) :

    Fa = f(a);Fb = f(b)
    d = b - a
    c = a + d/2
    Fc = f(c)
    n = 1
    d = d/2
    while n < Nmax and Fc != 0 and d > Tol :
          if np.sign(Fa) == np.sign(Fc) :
             a = c
             Fa = Fc
          else :
             b = c
             Fb = Fc

          c = a + d/2
          Fc = f(c)
          d = d/2
          n += 1

    return c,n,d,Fc

#------------ MAIN PROGRAMME -------------#
a=1;b=2 ;Tol=10**(-8) ;Nmax=100
c,n,d,Fc = Bisection(a,b,Tol,Nmax)

print ('Number of steps is ' , n )
print ('Approximation is' , c )
print ('The value of function is' , Fc )
print ('Distance from root less than ' , d)

t=np.linspace(1,2,100)
y=f(t)

plt.plot(t,y,'orange')
plt.legend(['f(x)'])
plt.ylabel('y')
plt.xlabel('x')
plt.show()


import math, cmath
import numpy as np
from numpy import pi

def menu():         #Menu interativo para realizar varias operações com apenas uma execução
    print("""
            Temos as seguintes opções:
	    (1) = Converter de Polar para Retângular
	    (2) = Converter de Retangular para Polar
	    (0) = Para SAIR

	""")
    return int(input('Escolha uma opção: '))

def getRet():       #Função que coleta do usuário os valores reais e imaginários da forma retangular
    real = float(input("Digite a parte real: "))
    imag = float(input("Digite a parte imaginária: "))
    return real, imag

def getPolar():     #Função que coleta do usuário os valores de módulo e fase da forma polar
    mod = float(input("Digite o módulo R: "))
    fase = float(input("Digite o angulo phi: "))
    return mod, fase

def convRet2Pol(x): #Função de conversão de Retangular para Polar
    modulo = abs(x) #retira o módulo de x, tirando a raiz da soma dos quadrados da parte real e da imaginária
    fase = np.arctan2(x.imag,x.real) * 180 / pi     #Para encontrar a fase em graus, fazemos o arctg da parte imaginaria sobre a real e multiplicamos por 180/pi
    return modulo, fase

def convPol2Ret(modulo,fase):   #Função de conversão de Polar para Retangular
    x = modulo * np.cos(math.radians(fase)) #Para achar a parte real devemos multiplicar o módulo pelo cosseno da fase
    y = modulo * np.sin(math.radians(fase)) #Para achar a parte real devemos multiplicar o módulo pelo seno da fase
    retangular = complex(x,y)               #Por fim juntamos os dois valores obtidos em apenas uma variável do tipo complexa
    return retangular

while True:     #laço de repetição do meno
    escolhaMenu = menu()
    if escolhaMenu == 0:    #condição de saída do programa
        print('Até a próxima!!')
        exit()

    elif escolhaMenu == 1:      #Questão 1: Converte da forma Polar Exponencial para a forma Retangular
        modulo, fase = getPolar()   #Chamamos a função para obter o modulo e a fase
        retangular = convPol2Ret(modulo,fase)   #chamamos a função de conversão para obter o numero na forma retangular
        print('Para ',modulo,'e^j',fase,'-> Convertendo para Coordenada Retangular temos:\n ', retangular)

    elif escolhaMenu == 2:      #Questão 2: Converte de Retangular para polar na forma modulo e fase e na formula exponencial
        parteReal, parteImag = getRet() #Chamamos a função para obter as partes reais e imaginária do número
        numero = complex(parteReal,parteImag)   #une ambos números para formar um único numero do tipo complexo
        modulo,fase = convRet2Pol(numero)   #Chama a função de conversão de Retangular para polar
        print('Para',numero,'-> Convertendo para Coordenada Polar temos:\n ',modulo,'/__',fase, '=', modulo,'e^j', fase)

    else:   #Se não digitar uma opção válida, o menu irá se repetir
        print('\nEssa não é uma opção válida! Tente Novamente \n')


import numpy as np
import matplotlib.pyplot as plt
import math

class NPoints:
    ''' This class is an example code of the paper
    UNIFIED INTERPOLATION AND EXTRAPOLATION FUNCTION BY DIRECT TAYLOR EXPANSION.
    This package predicts the poitns which within the given range of give data and outside the range of same data set with presize points.
    Using very small give data set in very small range this algorthm can predict the point which is extremely far away from given range.

    '''

    def __init__(self,x_domain,y_domain):
        ''' Check len of data'''
        if (len(x_domain)%2==0 and len(y_domain)%2==0 ):
            x_domain=x_domain[:-1]
            y_domain=y_domain[:-1] #drop the last element to get odd number..
            self.x_domain = x_domain  # Store x domain
            self.y_domain = y_domain  # Store y domain
            self.n = int((len(self.y_domain) - 1) / 2) #middle point index
            self.del_x = self.x_domain[1] - self.x_domain[0]
            self.taylor_coef=NPoints.taylor_coef_matrix(self)
            self.taylor_coefficent_matrix = np.matmul(np.linalg.inv(NPoints.taylor_coef_matrix(self)), self.y_domain)
        else:
            self.x_domain=x_domain # Store x domain
            self.y_domain=y_domain # Store y domain
            self.n = int((len(self.y_domain) - 1) / 2)  # middle point index
            self.del_x=self.x_domain[1]-self.x_domain[0]
            self.taylor_coef = NPoints.taylor_coef_matrix(self)
            self.taylor_coefficent_matrix=np.matmul(np.linalg.inv(NPoints.taylor_coef_matrix(self)),self.y_domain)

    @staticmethod
    def fact(num):
        ''' Static function which caluclates the factorial of feeded number'''
        factorial = 1
        if num == 0:
            return factorial
        else:
            for i in range(1, num + 1):
                factorial = factorial * i
            return factorial

    def taylor_coefficients(self,n, delta_x, m):
        coef_array = []
        for i in range(m):
            coef_array.append((n * delta_x) ** (i) / (NPoints.fact(i)))
        return coef_array

    def taylor_coef_matrix(self):
        n = int((len(self.y_domain) - 1) / 2)
        taylor_coef_matr = np.zeros((len(self.y_domain), len(self.y_domain)), dtype=float)
        mirror_array = []
        for i in range(-n, n + 1):
            mirror_array.append(i)

        for i in range(len(taylor_coef_matr)):
            taylor_coef_matr[i] =self.taylor_coefficients(mirror_array[i], self.del_x, len(mirror_array))
        return taylor_coef_matr

    def UIE_function(self,betta):
        alfa = betta - self.x_domain[self.n]
        #f_x = self.y_domain[n]
        f_x=0
        for i in range( len(self.taylor_coefficent_matrix)):
            #f_x += (((alfa ** (i)) / (NPoints.fact(i))) * (self.taylor_coefficent_matrix[i]))
            #f_x += (((alfa ** (i)) / math.factorial(i)) * (self.taylor_coefficent_matrix[i]))
            f_x += (alfa ** (i))* ((self.taylor_coefficent_matrix[i])/ math.factorial(i))
        return f_x

    def analytical_function(self):
        string ="f(x)="
        x_0=self.x_domain[self.n]
        string=string+str(self.y_domain[self.n])
        for i in range(1,len(self.taylor_coefficent_matrix)):
            string+="+(x-"+str(x_0)+")^("+str(i)+")*"+str((float(self.taylor_coefficent_matrix[i]))/(NPoints.fact(i)))

        return string


import unittest
from math import sqrt
from random import randint

import numpy as np
import scipy.stats

from pydes.core.metrics.accumulator import WelfordAccumulator

SAMPLE_SIZE = 1000000
PRECISION = 10
ERROR = 0.000015
CONFIDENCE = 0.95

class AccumulatorTest(unittest.TestCase):
    def setUp(self):
        self.accumulator = WelfordAccumulator()
        self.values = []
        for _ in range(SAMPLE_SIZE):
            value = randint(1, 1000)
            self.values.append(value)
            self.accumulator.add_value(value)

    def test_mean(self):
        expected_mean = np.mean(self.values)
        actual_mean = self.accumulator.mean()
        print("expected_mean:", expected_mean)
        print("actual_mean:", actual_mean)
        self.assertEqual(round(expected_mean, PRECISION), round(actual_mean, PRECISION))

    def test_var(self):
        expected_var = np.var(self.values)
        actual_var = self.accumulator.var()
        print("expected_var:", expected_var)
        print("actual_var:", actual_var)
        self.assertLessEqual(abs(expected_var - actual_var) / expected_var, ERROR)

    def test_sdev(self):
        expected_sdev = sqrt(np.var(self.values))
        actual_sdev = self.accumulator.sdev()
        print("expected_sdev:", expected_sdev)
        print("actual_sdev:", actual_sdev)
        self.assertLessEqual(abs(expected_sdev - actual_sdev) / expected_sdev, ERROR)

    def test_cint(self):
        expected_cint = scipy.stats.sem(self.values) * scipy.stats.t.ppf((1 + CONFIDENCE) / 2.0, len(self.values) - 1)
        actual_cint = self.accumulator.cint(1 - CONFIDENCE)
        print("expected_cint:", expected_cint)
        print("actual_cint:", actual_cint)
        self.assertLessEqual(abs(expected_cint - actual_cint) / expected_cint, ERROR)


import numpy as np
from pylab import *

style.use('postgkyl.mplstyle')

def buneman_k2w_cold(k, m):
    """
    Dispersion relation of two-fluid Bunenman instability in
    a cold plasma.

    Compute complex frequency w as roots of DR=0. DR is
    the dispersion relation equation rearranged as a
    polynommial equation where w is the unknown.
    The roots are ordered by imagninary parts (growth rate)
    first and then by real parts, both from large to small.

    Set se and si to zero for a cold plasma.

    Args:
        k: k*v0/wpe
        m: mi/me

    Returns:
        ws: Complex frequency for the given k.
    """
    ws = np.roots((m, -2 * k * m, k**2 * m - (m + 1), 2 * k,  -k**2))
    return ws[np.argsort(ws.imag + 1j * ws.real)[::-1]]

nk = 500
ks = np.linspace(0.01, 1.75, nk)

ws25 = np.zeros((nk, 4), dtype=np.complex128)
for i, k in enumerate(ks):
    ws25[i,:] = buneman_k2w_cold(k, 25.0)

ws200 = np.zeros((nk, 4), dtype=np.complex128)
for i, k in enumerate(ks):
    ws200[i,:] = buneman_k2w_cold(k, 200.0)

ws1836 = np.zeros((nk, 4), dtype=np.complex128)
for i, k in enumerate(ks):
    ws1836[i,:] = buneman_k2w_cold(k, 1836.2)

# plot imag part of dispersion relation
figure(1)
plot(ks, imag(ws25[:,0]), 'r.', markersize=2)
plot(ks, imag(ws25[:,1]), 'r.', markersize=2)
plot(ks, imag(ws25[:,2]), 'r.', markersize=2)
plot(ks, imag(ws25[:,3]), 'r.', markersize=2)

plot(ks, imag(ws200[:,0]), 'k.', markersize=2)
plot(ks, imag(ws200[:,1]), 'k.', markersize=2)
plot(ks, imag(ws200[:,2]), 'k.', markersize=2)
plot(ks, imag(ws200[:,3]), 'k.', markersize=2)

plot(ks, imag(ws1836[:,0]), 'm.', markersize=2)
plot(ks, imag(ws1836[:,1]), 'm.', markersize=2)
plot(ks, imag(ws1836[:,2]), 'm.', markersize=2)
plot(ks, imag(ws1836[:,3]), 'm.', markersize=2)

xlabel(r'$k V_0/\omega_{pe}$')
ylabel(r'$\gamma/\omega_{pe}$')
grid()
savefig('gamma-vs-k-cold.png', dpi=150)

figure(2)
plot(real(ws25[:,0]), imag(ws25[:,0]), 'r.', markersize=2)
plot(real(ws25[:,1]), imag(ws25[:,1]), 'r.', markersize=2)
plot(real(ws25[:,2]), imag(ws25[:,2]), 'r.', markersize=2)
plot(real(ws25[:,3]), imag(ws25[:,3]), 'r.', markersize=2)

plot(real(ws200[:,0]), imag(ws200[:,0]), 'k.', markersize=2)
plot(real(ws200[:,1]), imag(ws200[:,1]), 'k.', markersize=2)
plot(real(ws200[:,2]), imag(ws200[:,2]), 'k.', markersize=2)
plot(real(ws200[:,3]), imag(ws200[:,3]), 'k.', markersize=2)

plot(real(ws1836[:,0]), imag(ws1836[:,0]), 'm.', markersize=2)
plot(real(ws1836[:,1]), imag(ws1836[:,1]), 'm.', markersize=2)
plot(real(ws1836[:,2]), imag(ws1836[:,2]), 'm.', markersize=2)
plot(real(ws1836[:,3]), imag(ws1836[:,3]), 'm.', markersize=2)

axis('image')
gca().set_xlim([0.0, 0.5])
grid()
xlabel(r'$\omega/\omega_{pe}$')
ylabel(r'$\gamma/\omega_{pe}$')

savefig('omega-vs-gamma-cold.png', dpi=150)

show()


# 切片索引
import numpy as np
arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8])
print(arr[1:6]) # output: [1 2 3 4 5]

# 对于二维数组,切片方式稍显不同
arr2 = np.array([[1, 2, 3],
					[4, 5, 6],
					[7, 8, 9]])
print(arr2[:2])
'''
output:
[[1 2 3]
 [4 5 6]]
'''
print(arr2[:, 1:])
'''
output:
[[2 3]
 [5 6]
 [8 9]]
'''
arr2[1:, 1:] = 0
print(arr2)

# 数组转置和轴对换
arr = np.arange(15).reshape((3, 5))
print(arr)
print(arr.T)
'''
output:
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]

[[ 0  5 10]
 [ 1  6 11]
 [ 2  7 12]
 [ 3  8 13]
 [ 4  9 14]]
'''
# 在进行矩阵计算时,经常需要用到转置操作,例如利用np.dot计算矩阵內积
arr = np.random.randn(6, 3)
print(arr)
print(np.dot(arr.T, arr))
'''
output:
[[-1.27395567  0.00955796 -1.28750516]
 [-0.08475422  0.52563736 -2.05030602]
 [ 1.17591993 -0.015422    0.88881672]
 [ 2.15608896  0.27987763 -0.92061775]
 [-0.11040883 -0.82964402 -0.06859076]
 [-1.66814933  0.36754     0.32394515]]

[[  1.04565659e+01   7.06805306e-03   3.41424263e-01]
 [  7.06805306e-03   1.17835017e+00  -1.18542228e+00]
 [  3.41424263e-01  -1.18542228e+00   7.60860167e+00]]
'''
# 对于高维数组, transpose需要得到一个由轴编号组成的元组才能对这些轴进行转置
arr = np.arange(16).reshape((2, 2, 4))
print(arr)
'''
output:
[[[ 0  1  2  3]
  [ 4  5  6  7]]

 [[ 8  9 10 11]
  [12 13 14 15]]]
'''
print(arr.transpose((1, 0, 2))) # 0轴变成了1轴, 1轴换成了0轴, 2轴不变
'''
output:
[[[ 0  1  2  3]
  [ 8  9 10 11]]

 [[ 4  5  6  7]
  [12 13 14 15]]]
'''

print(arr.transpose((1, 2, 0)))
'''
[[[ 0  8]
  [ 1  9]
  [ 2 10]
  [ 3 11]]

 [[ 4 12]
  [ 5 13]
  [ 6 14]
  [ 7 15]]]
'''
# 简单的转置可以使用.T,就是进行轴对换.
# ndarray还有一个swapaxes方法, 它需要接受一个轴编号
print(arr)
'''
output:
[[[ 0  1  2  3]
  [ 4  5  6  7]]

 [[ 8  9 10 11]
  [12 13 14 15]]]
'''
print(arr.swapaxes(1, 2))
'''
output:
[[[ 0  4]
  [ 1  5]
  [ 2  6]
  [ 3  7]]

 [[ 8 12]
  [ 9 13]
  [10 14]
  [11 15]]]
'''
print(arr.transpose(0, 2, 1))
'''
output:
[[[ 0  4]
  [ 1  5]
  [ 2  6]
  [ 3  7]]

 [[ 8 12]
  [ 9 13]
  [10 14]
  [11 15]]]
'''

# 用于数组的文件输入输出
'''
Numpy能够读写次爬上的文本数据或二进制数据.
np.save和np.load是读写磁盘数组数据的两个主要函数.
默认情况下, 数组是以未亚索的原始二进制格式保存在扩展名为.npy文件中的
'''
arr = np.arange(10)
np.save('some_array', arr)
# 如果文件路径末尾没有扩展名.npy,则该扩展名会被自动添加
#　然后就可以通过np.load读取磁盘上的数组
print(np.load('some_array.npy'))# output: [0 1 2 3 4 5 6 7 8 9]
# 通过np.savez可以将多个数组保存到一个未压缩的文件中, 将数组以关键字参数的形式传入即可
np.savez('array_achive.npz', a=arr, b=arr)
# 加载.npz文件时,会得到一个类似字典的对象,该对象会对各个数组进行延迟加载
arch = np.load('array_achive.npz')
print(dir(arch))
print(arch.items(), '\n', arch['b'])
'''
output:
[('a', array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])), ('b', array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))]
 [0 1 2 3 4 5 6 7 8 9]
'''
# 如果数据压缩的很好,就可以使用numpy.savez_compressed:
np.savez_compressed('arrays_compressed.npz', a=arr, b=arr.T)
arch = np.load('arrays_compressed.npz')
print(arch['a'])
print('\n')
print(arch['b'])
print(arch['a'] * arch['b'])


import io, sys
import numpy as np
from heapq import *

def load_vectors(filename):
    fin = io.open(filename, 'r', encoding='utf-8', newline='\n')
    n, d = map(int, fin.readline().split())
    data = {}
    for line in fin:
        tokens = line.rstrip().split(' ')
        data[tokens[0]] = np.asarray([float(x) for x in tokens[1:]])
    return data

## This function computes the cosine similarity between vectors u and v

def cosine(u, v):
    return np.dot(u,v)/(np.linalg.norm(u)*np.linalg.norm(v))

## This function returns the word corresponding to
## nearest neighbor vector of x
## The list exclude_words can be used to exclude some
## words from the nearest neighbors search

def nearest_neighbor(x, word_vectors, exclude_words=[]):
    best_score = -1.0
    best_word = ''

    for k in word_vectors.keys():
        score = cosine(x,np.array(word_vectors[k]))

        if score > best_score and k not in exclude_words :
            best_score = score
            best_word = k

    return best_word

## This function return the words corresponding to the
## K nearest neighbors of vector x.
## You can use the functions heappush and heappop.

def knn(x, vectors, k):
    heap = []

    exclude_words=[]
    for i  in range(k+1):
        best_word = nearest_neighbor(x, word_vectors,exclude_words)
        exclude_words.append(best_word)
        heap.append((cosine(x,word_vectors[best_word]),best_word))

    return heap[1:]

## This function return the word d, such that a:b and c:d
## verifies the same relation

def analogy(a, b, c, word_vectors):
    result_word = None
    result_score = float('-Inf')

    x_a = word_vectors[a]/np.linalg.norm(word_vectors[a])
    x_b = word_vectors[b]/np.linalg.norm(word_vectors[b])
    x_c = word_vectors[c]/np.linalg.norm(word_vectors[c])
    for key in word_vectors:
        if True in [i in key for i in [a,b,c]] :
            continue
        normalized = word_vectors[key]/np.linalg.norm(word_vectors[key])
        result = np.dot((x_c+x_b-x_a),normalized)

        if result > result_score:
            result_score = result
            result_word = key

    return result_word

## Compute the association strength between:
##   - a word w
##   - two sets of attributes A and B

def association_strength(w, A, B, vectors):
    strength_a = 0.0
    strength_b = 0.0
    ## FILL CODE
    for a in A:
        strength_a += ((1/len(A))*cosine(vectors[w],vectors[a]))
    for b in B:
        strength_b += ((1/len(B))*cosine(vectors[w],vectors[b]))

    return strength_a - strength_b

## Perform the word embedding association test between:
##   - two sets of words X and Y
##   - two sets of attributes A and B

def weat(X, Y, A, B, vectors):
    score_x = 0.0
    score_y = 0.0
    ## FILL CODE
    for i in X:
        score_x += association_strength(i,A,B,vectors)
    for i in Y:
        score_y += association_strength(i,A,B,vectors)

    return score_x - score_y

######## MAIN ########

print('')
print(' ** Word vectors ** ')
print('')

word_vectors = load_vectors(sys.argv[1])

print('similarity(apple, apples) = %.3f' %
      cosine(word_vectors['apple'], word_vectors['apples']))
print('similarity(apple, banana) = %.3f' %
      cosine(word_vectors['apple'], word_vectors['banana']))
print('similarity(apple, tiger) = %.3f' %
      cosine(word_vectors['apple'], word_vectors['tiger']))

print('')
print('The nearest neighbor of cat is: ' +
      nearest_neighbor(word_vectors['cat'], word_vectors))

knn_cat = knn(word_vectors['cat'], word_vectors, 5)
print('')
print('cat')
print('--------------')
for score, word in knn(word_vectors['cat'], word_vectors, 5):
    print( word + '\t%.3f' % score)

print('')
print('france - paris + rome = ' + analogy('paris', 'france', 'rome', word_vectors))

## A word about biases in word vectors:

print('')
print('similarity(genius, man) = %.3f' %
      cosine(word_vectors['man'], word_vectors['genius']))
print('similarity(genius, woman) = %.3f' %
      cosine(word_vectors['woman'], word_vectors['genius']))

## Replicate one of the experiments from:
##
## Semantics derived automatically from language corpora contain human-like biases
## Caliskan, Bryson, Narayanan (2017)

career = ['executive', 'management', 'professional', 'corporation',
          'salary', 'office', 'business', 'career']
family = ['home', 'parents', 'children', 'family',
          'cousins', 'marriage', 'wedding', 'relatives']
male = ['john', 'paul', 'mike', 'kevin', 'steve', 'greg', 'jeff', 'bill']
female = ['amy', 'joan', 'lisa', 'sarah', 'diana', 'kate', 'ann', 'donna']

print('')
print('Word embedding association test: %.3f' %
      weat(career, family, male, female, word_vectors))


"""State purity."""
import numpy as np

from toqito.matrix_props import is_density

def purity(rho: np.ndarray) -> float:
    r"""
    Compute the purity of a quantum state [WikPurity]_.

    The negativity of a subsystem can be defined in terms of a density matrix :math:`\rho`: The
    purity of a quantum state :math:`\rho` is defined as

    .. math::
        \text{Tr}(\rho^2),

    where :math:`\text{Tr}` is the trace function.

    Examples
    ==========

    Consider the following scaled state defined as the scaled identity matrix

    .. math::
        \rho = \frac{1}{4} \begin{pmatrix}
                         1 & 0 & 0 & 0 \\
                         0 & 1 & 0 & 0 \\
                         0 & 0 & 1 & 0 \\
                         0 & 0 & 0 & 1
                       \end{pmatrix} \in \text{D}(\mathcal{X}).

    Calculating the purity of :math:`\rho` yields :math:`\frac{1}{4}`. This can be observed using
    :code:`toqito` as follows.

    >>> from toqito.state_props import purity
    >>> import numpy as np
    >>> purity(np.identity(4) / 4)
    0.25

    Calculate the purity of the Werner state.
    >>> from toqito.states import werner
    >>> rho = werner(2, 1 / 4)
    >>> purity(rho)
    0.2653

    References
    ==========
    .. [WikPurity] Wikipedia page for purity (quantum mechanics):
        https://en.wikipedia.org/wiki/Purity_(quantum_mechanics)

    :param rho: A density matrix of a pure state vector.
    :return: A value between 0 and 1 that corresponds to the purity of
            :math:`\rho`.
    """
    if not is_density(rho):
        raise ValueError("Purity is only defined for density operators.")
    # "np.real" get rid of the close-to-0 imaginary part.
    return np.real(np.trace(np.linalg.matrix_power(rho, 2)))


# -------------------------------------------------------------------------------------- #
# -------------------------------------------------------------------------------------- #
# Vignette #1
# APPM 4720/5720 Randomized Algorithms, Spring 2019
# Stephen Becker (original MATLAB) & Jake Knigge (Python)
# This is not a practical algorithm, since it only works if the matrix is *exactly* low
# rank.
# -------------------------------------------------------------------------------------- #
import numpy as np                      # import NumPy package
import time as time                     # import time package
# -------------------------------------------------------------------------------------- #
np.set_printoptions(precision = 4)      # display only four digits
np.random.seed(seed = 2)                # set seed for reproducibility
n = np.int(4e3); m = n                  # dimension of problem
r = np.int(100)                         # rank of matrix
mu, sigma = 0, 1                        # mean and standard deviation
zz = np.random.normal(mu, sigma, n*r)   # generate (normal) random numbers
Z = zz.reshape(n,r)                     # reshape to matrix
A = np.matmul(Z, Z.T)                   # compute outerproduct matrix
# -------------------------------------------------------------------------------------- #
# Find its SVD with conventional methods
t = time.time()                         # time SVD calculation
U, S, Vh = np.linalg.svd(A); V = Vh.T   # compute SVD of A and transpose V
elapsed = time.time() - t
print('The full SVD took', round(elapsed, 4), 'seconds.')
# -------------------------------------------------------------------------------------- #
# Find its SVD with a randomized method
tt = time.time()
t = time.time(); Omega = np.random.normal(mu, sigma, (n, r)); print(round(time.time() - t, 4), 'seconds')
t = time.time(); Y     = np.matmul(A, Omega);                 print(round(time.time() - t, 4), 'seconds')
t = time.time(); Q, R  = np.linalg.qr(Y, mode='reduced');     print(round(time.time() - t, 4), 'seconds')
t = time.time(); QtA   = np.matmul(Q.T, A);                   print(round(time.time() - t, 4), 'seconds')
tm  = time.time() - tt
print('The approximate SVD took', round(tm, 4), 'seconds.')
# -------------------------------------------------------------------------------------- #
A_estimate = np.matmul(Q, QtA)
err = np.linalg.norm( np.ravel(A) - np.ravel(A_estimate) ) / np.linalg.norm( np.ravel(A) )
print('The error ||A-A_estimate||_F/||A||_F is ', '{:0.4e}'.format(err), '.', sep = '')
# -------------------------------------------------------------------------------------- #
# -------------------------------------------------------------------------------------- #


"""
@Author: 	yshhuang@foxmail.com
@Date: 2020-06-10 14:42:16
@LastEditors: 	yshhuang@foxmail.com
@LastEditTime: 2020-06-10 17:43:14
@FilePath: /d2l-zh/optimization-algorithm/gradient-descent.py
"""
import d2lzh as d2l
import math
from mxnet import nd
import numpy as np

def gd(eta):
    x = 10
    results = [x]
    for i in range(10):
        x -= eta*2*x
        results.append(x)
    print('epoch 10,x:', x)
    return results

def show_trace(res):
    n = max(abs(min(res)), abs(max(res)), 10)
    f_line = np.arange(-n, n, 0.1)
    d2l.set_figsize()
    d2l.plt.plot(f_line, [x * x for x in f_line])
    d2l.plt.plot(res, [x * x for x in res], '-o')
    d2l.plt.xlabel('x')
    d2l.plt.ylabel('f(x)')
    d2l.plt.show()

if __name__ == "__main__":
    res = gd(0.2)
    show_trace(res)


from typing import Callable

import numpy as np

def trapezoid(
    func: Callable[..., float], a: float, b: float, eps: float = 0.0001, *args, **kwargs
) -> float:

    """
    Metode integrasi trapesium mengganti bentuk segiempat
    yang sebelumnya digunakan untuk mengintegrasi menjadi
    bentuk trapesium. Maka dari itu, pada trapesium, nilai
    f(x) dievaluasi pada masing2 sisi trapesium.

    Parameter:
    f   = fungsi input
    a   = batas bawah integrasi
    b   = batas atas integrasi
    eps = error relatif maksimal

    >>> trapezoid(lambda x: x**5, 0, 1)
    0.16670751153457503
    >>> trapezoid(lambda x: x**2, 0, 2)
    2.6667973728065877
    """
    try:
        # Iterasi pertama
        n = 100
        h = (b - a) / n
        fx = [func(a + i * h, *args, **kwargs) for i in range(n + 1)]
        L0 = h / 2 * (fx[0] + fx[-1]) + h * sum(fx[1:-1])

        # Optimasi
        err = 1
        while err > eps:
            n += 1
            h = (b - a) / n
            fx = [func(a + i * h, *args, **kwargs) for i in range(n + 1)]
            L1 = h / 2 * (fx[0] + fx[-1]) + h * sum(fx[1:-1])
            err = np.abs(L1 - L0) / np.abs(L1)
            L0 = L1
    except Exception:
        raise RuntimeError("Integrasi gagal, pastikan fungsi anda benar!")
    return L1

if __name__ == "__main__":

    def f(x: float) -> float:
        """
        Test Function
        """
        return x ** 4

    import doctest

    doctest.testmod()


"""
How much accuracy is lost using Strassen? On N(0,1) iid matrices.
"""

import numpy as np
import numpy.random as npr

d0 = 2048

def strassen(depth, A, B):
  """
  return AB, using strassen to recursion level `depth'
  """
  if depth == 0:
    return np.dot(A, B)
  else:
    d = A.shape[0]
    A11 = A[0:d/2, 0:d/2]
    A12 = A[0:d/2, d/2::]
    A21 = A[d/2::, 0:d/2]
    A22 = A[d/2::, d/2::]

    B11 = B[0:d/2, 0:d/2]
    B12 = B[0:d/2, d/2::]
    B21 = B[d/2::, 0:d/2]
    B22 = B[d/2::, d/2::]

    M1 = strassen(depth-1, A11 + A22, B11 + B22)
    M2 = strassen(depth-1, A21 + A22, B11)
    M3 = strassen(depth-1, A11, B12 - B22)
    M4 = strassen(depth-1, A22, B21 - B11)
    M5 = strassen(depth-1, A11 + A12, B22)
    M6 = strassen(depth-1, A21 - A11, B11 + B12)
    M7 = strassen(depth-1, A12 - A22, B21 + B22)

    C = np.zeros((d, d), dtype = A.dtype)
    C[0:d/2, 0:d/2] = M1 + M4 - M5 + M7
    C[0:d/2, d/2::] = M3 + M5
    C[d/2::, 0:d/2] = M2 + M4
    C[d/2::, d/2::] = M1 - M2 + M3 + M6

    return C

Ad = -0.2 + npr.randn(d0,d0)
Bd = 0.1 + npr.randn(d0,d0)

Af = np.array(Ad, dtype = np.float32)
Bf = np.array(Bd, dtype = np.float32)

C0d = strassen(0, Ad, Bd)
C0d2 = np.dot(Ad, Bd)

C0f = strassen(0, Af, Bf)
err0 = np.abs(C0d - np.array(C0f, dtype = np.float64))
mu0 = err0.mean()
ma0 = err0.max()

print "log2(mean absolute difference) : ", np.log2(mu0)
print "log2(max  absolute difference) : ", np.log2(ma0)
print "Depth \t\tmean/mean0 \tmax/max0"

for depth in [0,1,2,3,4,5]:
  Cxf = strassen(depth, Af, Bf)
  err1 = np.abs(C0d - np.array(Cxf, dtype = np.float64))
  print depth, "   :    ", err1.mean()/mu0, '\t', err1.max()/ma0


"""Module computes the mean and the mean square of independent variable y and dependent variable x."""

import numpy as np

def mean_meansqr(data):
    """Get the mean and mean square errors for each column (x and y data)"""
    mean_squares = np.array([])

    mean = np.mean(data,dtype=np.float64,axis=0) # an array containing the mean per each column
    for l in range(mean.shape[0]):
        # compute mean squared error for each column
        diff_squares = (data[:,l] - mean[l])**2 # differences of squares
        elements = np.mean(diff_squares)
        mean_squares = np.concatenate((mean_squares,np.array([elements])))

    return (mean, mean_squares)


# Importing the libraries
import random
import numpy as np

"""
Generate some random numbers.
"""

mylist = []
totalNumbers = 100
minNumber = 0
maxNumber = 10

for i in range(0, totalNumbers):   # [start, end) =>  [0, totalNumbers)
    x = random.randint(minNumber,maxNumber)  # [minNumber, maxNumber]
    mylist.append(x)

print(mylist)

"""
Generate a 10 x 4 data matrix X, initially polulated with zeros.
"""

rowCount = 10
colCount = 4
X = np.zeros((rowCount, colCount), dtype = int)
#X = np.zeros((rowCount, colCount), dtype = float)

print (X)

"""

Populate the First column with indentpendly identically distributed (i.i.d.)
random variables N(125, 16) (simulating height),
and the second column with i.i.d. randomN(125 variables , 64) (simulating weight).

"""
height = X[:, 0]
weight = X[:, 1]

print (height)
print (weight)

whRatioList = [0.0] * (rowCount) # Generating a list of size rowCount
whRatioArray = np.asarray(whRatioList) # Converting the list into array
print (whRatioArray.size)

for i in range(whRatioArray.size):
    height[i] = np.random.normal(loc=125, scale= 4, size=1)
    weight[i] = np.random.normal(loc=125, scale= 8, size=1)
    whRatioArray[i] = weight[i]/height[i]

print (weight)
print (height)

for i in range(whRatioArray.size):
    print("Weight[%d] = %d " % (i, weight[i]))
    print("Height[%d] = %d " % (i, height[i]))
#    print("Weight[%d] / Height[%d] = %d / %d = %.2f" % (i, i, weight[i], height[i], (weight[i]/height[i])))
    print("Weight[%d] / Height[%d] = %d / %d = %f" % (i, i, weight[i], height[i], whRatioArray[i]))

Matrix and Vector Operations/MatrixOperations_WithRandomlyGeneratedData.py


#!/usr/bin/env python

import numpy as np

def _sigmoid(x):
    if x > 0:
        s = 1.0 / (1.0 + np.exp(-x))
    else:
        s = np.exp(x) / (1.0 + np.exp(x))
    return s

sigmoid = np.vectorize(_sigmoid)

def sigmoid_grad(s):
    ds = s * (1 - s)
    return ds

def test_sigmoid_basic():
    print "Running basic tests..."
    x = np.array([[1, 2], [-1, -2]])
    f = sigmoid(x)
    g = sigmoid_grad(f)
    print f
    f_ans = np.array([
        [0.73105858, 0.88079708],
        [0.26894142, 0.11920292]])
    assert np.allclose(f, f_ans, rtol=1e-05, atol=1e-06)
    print g
    g_ans = np.array([
        [0.19661193, 0.10499359],
        [0.19661193, 0.10499359]])
    assert np.allclose(g, g_ans, rtol=1e-05, atol=1e-06)
    print "You should verify these results by hand!\n"

def test_sigmoid():
    print "Running your tests..."

if __name__ == "__main__":
    test_sigmoid_basic();
    test_sigmoid()


import scipy.integrate as spi
import autograd.numpy as anp   # Thinly-wrapped version of Numpy
import autograd as ag

print('Compute length of an arc of planar parametric curve by SciPy quad')
print('Example 1-04 quad arclength')
print('Length of arc of parametric curve x(t)=cos^3(t) and y(t)=sin^3(t) from t=0 to t=2pi')

x = lambda t : anp.cos(t) ** 3
y = lambda t : anp.sin(t) ** 3
dx_dt = ag.grad(x)
dy_dt = ag.grad(y)

integrand = lambda t : anp.sqrt(dx_dt(t) ** 2 + dy_dt(t) ** 2)
a = 0.
b = 2 * anp.pi

result, error = spi.quad(integrand, a, b)
print('Result is ', result, 'with error ', error)


import matplotlib.pyplot as plt
import numpy as np
import time
from FTCS_Pythran import loop_ftcs_pythran
from FTCS_Cython import loop_ftcs_cython
from FTCS_Cython_OMP import loop_ftcs_cython_omp

nx = 128
ny = 128

#Cell sizes
dx = 2.0*np.pi/float(nx)
dy = 2.0*np.pi/float(ny)

#Indices
index_range = np.arange(0,nx+2)
x, y = np.meshgrid(dx*index_range-dx,dy*index_range-dy)

#diffusion parameter
alpha = 0.8
#Stable timestep
dt = 0.8*dx*dx/(4.0*alpha)

#Initialize
u = np.sin(x+y)

#length of solution
ft = 1.0

def plot_field(x,y,u,title):
	#levels = np.linspace(-1, 1, 20)
	fig, ax = plt.subplots(nrows=1,ncols=1)
	ax.set_title(title)
	p1 = ax.contourf(x,y,u)
	plt.colorbar(p1,ax=ax)#,format="%.2f"
	plt.show()

def loop_ftcs(u):

	nt = int(ft/dt)
	const_mult = alpha*dt/(dx*dx)

	t = 0
	while t<nt:
		t = t+1
		utemp = np.copy(u)

		#FTCS timestep
		for i in range(1,nx+1):
			for j in range(1,ny+1):
				u[i,j] = utemp[i,j] + const_mult*(-4.0*utemp[i,j]+(utemp[i-1,j]+utemp[i+1,j]+utemp[i,j-1]+utemp[i,j+1]))

		#Periodic boundary condition update
		for j in range(1,ny+1):
			u[0,j] = u[nx,j]
			u[nx+1,j] = u[1,j]

		for i in range(0,nx+2):
			u[i,0] = u[i,ny]
			u[i,ny+1] = u[i,1]

		del(utemp)

	return u

def vectorized_ftcs(u):

	global dx,dy,dt,alpha,ft
	nt = int(ft/dt)
	const_mult = alpha*dt/(dx*dx)

	t = 0
	while t<nt:
		t = t+1
		utemp = np.copy(u)
		u[1:nx+1,1:ny+1] = utemp[1:nx+1,1:ny+1] + const_mult*(-4.0*utemp[1:nx+1,1:ny+1]+(utemp[0:nx,1:ny+1]+
							utemp[2:nx+2,1:ny+1]+utemp[1:nx+1,0:ny]+utemp[1:nx+1,2:ny+2]))

		#Update BCS
		#Need to update BCs - x direction
		u[0:1,1:ny+1] = u[nx:nx+1,1:ny+1]
		u[nx+1:nx+2,1:ny+1] = u[1:2,1:ny+1]

		#Need to update BCs - y direction
		u[0:nx+2,0:1] = u[0:nx+2,ny:ny+1]
		u[0:nx+2,ny+1:ny+2] = u[0:nx+2,1:2]

		del(utemp)

	return u

if __name__ == '__main__':

	compile_option = int(input('Enter 0 for native, 1 for vectorized, 2 for Cython build, 3 for Pythran build, 4 for Cython_OMP: '))

	if compile_option == 0:
		print('This will take some time for large values of nx. Be warned.')
		plot_field(x,y,u,'Initial Condition')
		t1 = time.time()
		u = loop_ftcs(u)
		print('CPU time taken for for loop based FTCS: ',time.time()-t1)
		plot_field(x,y,u,'Final solution')
	elif compile_option == 1:
		plot_field(x,y,u,'Initial Condition')
		t1 = time.time()
		u = vectorized_ftcs(u)
		print('CPU time taken for vectorized FTCS: ',time.time()-t1)
		plot_field(x,y,u,'Final solution')
	elif compile_option == 2:
		plot_field(x,y,u,'Initial Condition')
		t1 = time.time()
		u = loop_ftcs_cython(nx,ny,dx,dy,dt,ft,alpha,u)
		print('CPU time taken for Cython build: ',time.time()-t1)
		plot_field(x,y,u,'Final solution')
	elif compile_option == 3:
		plot_field(x,y,u,'Initial Condition')
		t1 = time.time()
		u = loop_ftcs_pythran(nx,ny,dx,dy,dt,ft,alpha,u)
		print('CPU time taken for for Pythran build: ',time.time()-t1)
		plot_field(x,y,u,'Final solution')
	elif compile_option == 4:
		plot_field(x,y,u,'Initial Condition')
		t1 = time.time()
		u = loop_ftcs_cython_omp(nx,ny,dx,dy,dt,ft,alpha,u)
		print('CPU time taken for Cython OMP build: ',time.time()-t1)
		plot_field(x,y,u,'Final solution')


#!/usr/bin/env python3

import numpy as np
from sklearn.metrics import confusion_matrix

def confusion_matrix_(y_true, y_pred, labels=None):
    """
    Compute confusion matrix to evaluate the accuracy of a classification.
    Args:
        y_true: a scalar or a numpy ndarray for the correct labels
        y_pred: a scalar or a numpy ndarray for the predicted labels
        labels: optional, a list of labels to index the matrix. This may be used to reorder or select a subset of labels. (default=None)
    Returns:
        The confusion matrix as a numpy ndarray.
        None on any error.
    Raises:
        This function should not raise any Exception.
    """
    tp = 0
    tn = 0
    fp = 0
    fn = 0
    if labels == None:
        values = list(set(y_true))
    else:
        values = labels
    if (len(values)) != 2:
        return None
    for i, elem in enumerate(y_true):
        if y_pred[i] == values[1] and y_true[i] == y_pred[i]:
            tp += 1
        elif y_pred[i] == values[1] and y_true[i] != y_pred[i]:
            fp += 1
        elif y_pred[i] == values[0] and y_true[i] == y_pred[i]:
            tn += 1
        elif y_pred[i] == values[0] and y_true[i] != y_pred[i]:
            fn += 1
    matrix = np.array([[tp, fp], [fn, tn]])
    return matrix

if __name__ == "__main__":

    y_pred = np.array(['norminet', 'dog', 'norminet', 'norminet', 'dog', 'bird'])
    y_true = np.array(['dog', 'dog', 'norminet', 'norminet', 'dog', 'norminet'])

    print(confusion_matrix_(y_true, y_pred))
    print(confusion_matrix_(y_true, y_pred, labels=['dog','norminet']))


from abc import ABC, abstractmethod
import numpy as np
import re

class ActivationBase(ABC):

    def __init__(self, **kwargs):
        super().__init__()

    def __call__(self, z):
        if z.ndim == 1:
            z = z.reshape(1, -1)
        return self.forward(z)

    @abstractmethod
    def forward(self, z):
        raise NotImplementedError

    @abstractmethod
    def grad(self, x, **kwargs):
        raise NotImplementedError

class Sigmoid(ActivationBase):
    """
    Sigmoid(x) = 1 / (1 + e^(-x))
    """

    def __init__(self):
        super().__init__()

    def __str__(self):
        return "Sigmoid"

    def forward(self, z):
        return 1 / (1 + np.exp(-z))

    def grad(self, x):
        return self.forward(x) * (1 - self.forward(x))

class Tanh(ActivationBase):
    """
    Tanh(x) = (e^x - e^(-x)) / (e^x + e^(-x))
    """

    def __init__(self):
        super().__init__()

    def __str__(self):
        return "Tanh"

    def forward(self, z):
        return np.tanh(z)

    def grad(self, x):
        return 1 - np.tanh(x) ** 2

class ReLU(ActivationBase):
    """
    ReLU(x) =
            x   if x > 0
            0   otherwise
    """

    def __init__(self):
        super().__init__()

    def __str__(self):
        return "ReLU"

    def forward(self, z):
        return np.clip(z, 0, np.inf)

    def grad(self, x):
        return (x > 0).astype(int)

class LeakyReLU(ActivationBase):
    """
    LeakyReLU(x) =
            alpha * x   if x < 0
            x           otherwise
    """

    def __init__(self, alpha=0.3):
        self.alpha = alpha
        super().__init__()

    def __str__(self):
        return "Leaky ReLU(alpha={})".format(self.alpha)

    def forward(self, z):
        _z = z.copy()
        _z[z < 0] = _z[z < 0] * self.alpha
        return _z

    def grad(self, x):
        out = np.ones_like(x)
        out[x < 0] *= self.alpha
        return out

class Affine(ActivationBase):
    """
    Affine(x) = slope * x + intercept
    """

    def __init__(self, slope=1, intercept=0):
        self.slope = slope
        self.intercept = intercept
        super().__init__()

    def __str__(self):
        return "Affine(slope={}, intercept={})".format(self.slope, self.intercept)

    def forward(self, z):
        return self.slope * z + self.intercept

    def grad(self, x):
        return self.slope * np.ones_like(x)

class SoftPlus(ActivationBase):
    """
    SoftPlus(x) = log(1 + e^x)
    """

    def __init__(self):
        super().__init__()

    def __str__(self):
        return "SoftPlus"

    def forward(self, z):
        return np.log(np.exp(z) + 1)

    def grad(self, x):
        return np.exp(x) / (np.exp(x) + 1)

class ELU(ActivationBase):
    """
    ELU(x) =
            x                   if x >= 0
            alpha * (e^x - 1)   otherwise
    """

    def __init__(self, alpha=1.0):
        self.alpha = alpha
        super().__init__()

    def __str__(self):
        return "ELU(alpha={})".format(self.alpha)

    def forward(self, z):
        return np.where(z > 0, z, self.alpha * (np.exp(z) - 1))

    def grad(self, x):
        return np.where(x >= 0, np.ones_like(x), self.alpha * np.exp(x))

class Exponential(ActivationBase):
    """
    Exponential(x) = e^x
    """

    def __init__(self):
        super().__init__()

    def __str__(self):
        return "Exponential"

    def forward(self, z):
        return np.exp(z)

    def grad(self, x):
        return np.exp(x)

class SELU(ActivationBase):
    """
    SELU(x) = scale * ELU(x, alpha)
            = scale * x                     if x >= 0
              scale * [alpha * (e^x - 1)]   otherwise
    """

    def __init__(self):
        self.alpha = 1.6732632423543772848170429916717
        self.scale = 1.0507009873554804934193349852946
        self.elu = ELU(alpha=self.alpha)
        super().__init__()

    def __str__(self):
        return "SELU"

    def forward(self, z):
        return self.scale * self.elu.forward(z)

    def grad(self, x):
        return np.where(
            x >= 0, np.ones_like(x) * self.scale, np.exp(x) * self.alpha * self.scale
        )

class HardSigmoid(ActivationBase):
    """
    HardSigmoid(x) =
            0               if x < -2.5
            0.2 * x + 0.5   if -2.5 <= x <= 2.5.
            1               if x > 2.5
    """

    def __init__(self):
        super().__init__()

    def __str__(self):
        return "Hard Sigmoid"

    def forward(self, z):
        return np.clip((0.2 * z) + 0.5, 0.0, 1.0)

    def grad(self, x):
        return np.where((x >= -2.5) & (x <= 2.5), 0.2, 0)

class ActivationInitializer(object):

    def __init__(self, acti_name="affine(slope=1, intercept=0)"):
        self.acti_name = acti_name

    def __call__(self):
        acti_str = self.acti_name.lower()
        if acti_str == "relu":
            acti_fn = ReLU()
        elif acti_str == "tanh":
            acti_fn = Tanh()
        elif acti_str == "sigmoid":
            acti_fn = Sigmoid()
        elif "affine" in acti_str:
            r = r"affine\(slope=(.*), intercept=(.*)\)"
            slope, intercept = re.match(r, acti_str).groups()
            acti_fn = Affine(float(slope), float(intercept))
        elif "leaky relu" in acti_str:
            r = r"leaky relu\(alpha=(.*)\)"
            alpha = re.match(r, acti_str).groups()[0]
            acti_fn = LeakyReLU(float(alpha))
        else:
            raise ValueError("Unknown activation: {}".format(acti_str))
        return acti_fn


import numpy as np
import time

class Newton(object):
    def __init__(self, f=None, fp=None, **extras):
        """
        f : a function f(x) that returns 'y', a float
        fp : the first derivative of function f(x), returning a float
        """
        self.f = f
        self.fp = fp

    def solve(self, init_a=None, tol=None, max_it=50, **extras):
        """fast implementation of Newton's method
        init_a : initial estimate
        tol : maximum absolute error after which the method should stop. (e.g. 1e-15)
        max_it : maximum number of iterations after which the method should stop
        """
        x = init_a
        i = 0
        while i < max_it:
            xn = x - ( self.f(x) / self.fp(x) )
            if abs(xn - x) < tol:
                break
            x = xn
            i+=1
        return x

    def vsolve(self, init_a=None, tol=None, max_it=50, **extras):
        """verbose implementation of Newton's method
        init_a : initial estimate
        tol : maximum absolute error after which the method should stop. (e.g. 1e-15)
        max_it : maximum number of iterations after which the method should stop
        """

        x = init_a
        xo = 0
        iteration_list = []
        dist_list = []
        estimate_list = []

        i = 0
        while i < max_it:
            dist = abs(x-xo)
            iteration_list.append(i)
            dist_list.append(dist)
            estimate_list.append(x)
            xo = x
            xn = x - ( self.f(x) / self.fp(x) )
            if abs(xn - x) < tol:
                break
            x = xn
            i+=1

        return iteration_list, estimate_list, dist_list

    def __repr__(self):
        # return "Newton "
        raise NotImplementedError

    def __str__(self):
        return "Newton method"