import unittest
import numpy as np
import matplotlib.pyplot as pl
import math
import os

# Using parts of Python for Data Analysis - Wes McKinney

arr1 = np.array([[1, 2], [3, 4], [5, 6]])
arr2 = np.array([[1, 2], [3, 2]])
arr3 = np.zeros((1, 2, 3))
arr4 = np.eye(10) # same as identity
arr5 = np.arange(4)
arr6 = np.random.randn(2, 4, 3)

class ArraysTestCase(unittest.TestCase):
  def shape_test(self):
    self.assertEquals(arr1.shape, (3, 2))
    self.assertEquals(arr1.T.shape, (2, 3))
    self.assertEquals(arr2.shape, (2, 2))
    self.assertEquals(arr3.shape, (1, 2, 3))
    self.assertEquals(arr4.shape, (10, 10))
    self.assertEquals(arr5.shape, (4,))
    self.assertEquals(arr6[1:, :2, :1].shape, (1, 2, 1))

  def dimension_test(self):
    self.assertEquals(arr1.ndim, 2)
    self.assertEquals(arr2.ndim, 2)
    self.assertEquals(arr3.ndim, 3)
    self.assertEquals(arr4.ndim, 2)
    self.assertEquals(arr5.ndim, 1)
    self.assertEquals(arr6.ndim, 3)

  def indexing_test(self):
    np.testing.assert_array_equal(arr1[0], [1, 2])
    self.assertEquals(arr1[1][0], 3)
    np.testing.assert_array_equal(arr3[0], np.zeros((2, 3)))
    self.assertEquals(len(arr4[0]), 10)

  def operations_test(self):
    self.assertEquals(type(arr2), np.ndarray)
    self.assertEquals(type(np.dot(arr2, arr2)), np.ndarray)
    np.testing.assert_array_equal(np.dot(arr2, np.eye(2)), arr2)

  def universal_functions_test(self):
    np.testing.assert_array_equal(np.sqrt(arr5), [0, 1, math.sqrt(2), math.sqrt(3)])
    np.testing.assert_array_equal(np.isinf(arr1), False)
    np.testing.assert_array_equal(np.ceil(arr1), arr1)
    np.testing.assert_array_equal(np.add(arr4, arr4), 2 * arr4)

  def mesh_test(self):
    points = np.arange(-10, 10, 0.01) # 2000 equally spaced points
    xs, ys = np.meshgrid(points, points) # 2 arrays of 2000x2000, second is transposed
    self.assertEquals(xs.shape, (2000, 2000))
    self.assertEquals(round(xs[0][1000], 2), 0.0) # Center
    self.assertEquals(round(xs[0][0], 2), -10)
    # As it is transposed, all the row is equal
    self.assertEquals(round(ys[0][1000], 2), -10)
    self.assertEquals(round(ys[0][0], 2), -10)
    z = np.sqrt(xs ** 2 + ys ** 2)
    self.assertEquals(round(z[0][0], 0), 14) # sqrt(200)
    self.assertEquals(round(z[1000][1000], 0), 0)
    # Create plot
    if os.environ['LEAVES_PYTHON_WITH_PLOTS'] == 'true':
      pl.imshow(z, cmap=pl.cm.Blues)
      pl.colorbar()
      pl.title("Image plot of $\sqrt{x^2 + y^2}$ for a grid of values")
      filepath = 'reports/languages/python/'
      if not os.path.isdir(filepath): os.makedirs(filepath)
      pl.savefig(filepath + "mesh.png")
      pl.close()


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

data=pd.read_csv(r".spyder-py3\Mall_Customers.csv")
print(data)

X=data.iloc[0:,[3,4]].values

from sklearn.cluster import KMeans
wcss=[]

for i in range(1,10):
    model=KMeans(n_clusters=i, init='k-means++', random_state=42)
    model.fit(X)
    wcss.append(model.inertia_)

plt.plot(range(1,10), wcss)
plt.title("ELBOW METHOD")
plt.xlabel("Number of Cluster")
plt.ylabel("WCSS value")
plt.show()

model=KMeans(n_clusters=5, init='k-means++', random_state=42)
pred_cluster = model.fit_predict(X)
print(pred_cluster)

d=pd.DataFrame({"cluster":pred_cluster})
data=pd.concat((data,d),axis=1)

plt.scatter(X[pred_cluster==0,0],X[pred_cluster==0,1],s=100,c='red',label='cluster0')

plt.scatter(X[pred_cluster==1,0],X[pred_cluster==1,1],s=100,c='blue',label='cluster1')

plt.scatter(X[pred_cluster==2,0],X[pred_cluster==2,1],s=100,c='yellow',label='cluster2')

plt.scatter(X[pred_cluster==3,0],X[pred_cluster==3,1],s=100,c='magenta',label='cluster3')

plt.scatter(X[pred_cluster==4,0],X[pred_cluster==4,1],s=100,c='black',label='cluster4')

plt.title("Cluster of customer")
plt.xlabel("annual income")
plt.ylabel("spending score")
plt.legend()
plt.show()

####################################################################
# customer segment on the basis of gender and spending score

data=pd.read_csv(r".spyder-py3\Mall_Customers.csv")
print(data)

data["Gender"]=data.Gender.map({"Male":1,"Female":0})
X=data.iloc[0:,[1,4]].values

from sklearn.cluster import KMeans
wcss=[]

for i in range(1,10):
    model=KMeans(n_clusters=i, init='k-means++', random_state=42)
    model.fit(X)
    wcss.append(model.inertia_)

plt.plot(range(1,10), wcss)
plt.title("ELBOW METHOD")
plt.xlabel("Number of Cluster")
plt.ylabel("WCSS value")
plt.show()

model=KMeans(n_clusters=3, init='k-means++', random_state=42)
pred_cluster = model.fit_predict(X)
print(pred_cluster)

d=pd.DataFrame({"cluster":pred_cluster})
data=pd.concat((data,d),axis=1)

plt.scatter(X[pred_cluster==0,0],X[pred_cluster==0,1],s=100,c='red',label='cluster0')

plt.scatter(X[pred_cluster==1,0],X[pred_cluster==1,1],s=100,c='blue',label='cluster1')

plt.scatter(X[pred_cluster==2,0],X[pred_cluster==2,1],s=100,c='yellow',label='cluster2')

plt.title("Cluster of customer")
plt.xlabel("Gender")
plt.ylabel("spending score")
plt.legend()
plt.show()

########################################################################
#  customer segment on the basis of age and spending score

data=pd.read_csv(r".spyder-py3\Mall_Customers.csv")
print(data)

X=data.iloc[0:,[2,4]].values

from sklearn.cluster import KMeans
wcss=[]

for i in range(1,10):
    model=KMeans(n_clusters=i, init='k-means++', random_state=42)
    model.fit(X)
    wcss.append(model.inertia_)

plt.plot(range(1,10), wcss)
plt.title("ELBOW METHOD")
plt.xlabel("Number of Cluster")
plt.ylabel("WCSS value")
plt.show()

model=KMeans(n_clusters=4, init='k-means++', random_state=42)
pred_cluster = model.fit_predict(X)
print(pred_cluster)

d=pd.DataFrame({"cluster":pred_cluster})
data=pd.concat((data,d),axis=1)

plt.scatter(X[pred_cluster==0,0],X[pred_cluster==0,1],s=100,c='red',label='cluster0')

plt.scatter(X[pred_cluster==1,0],X[pred_cluster==1,1],s=100,c='blue',label='cluster1')

plt.scatter(X[pred_cluster==2,0],X[pred_cluster==2,1],s=100,c='yellow',label='cluster2')

plt.scatter(X[pred_cluster==3,0],X[pred_cluster==3,1],s=100,c='magenta',label='cluster3')

plt.title("Cluster of customer")
plt.xlabel("age")
plt.ylabel("spending score")
plt.legend()
plt.show()

######################################################################
# dendogram curve

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

data=pd.read_csv(r".spyder-py3\Mall_Customers.csv")

x=data.iloc[0:,[3,4]].values

import scipy.cluster.hierarchy as sch

dendo = sch.dendrogram(sch.linkage(x,method='ward'))

plt.title("Dendogram curve")
plt.xlabel("datapoints")
plt.ylabel("Euclidean Distance")
plt.show()

from sklearn.cluster import AgglomerativeClustering
model = AgglomerativeClustering(n_clusters=5, affinity='euclidean', linkage='ward')

y_pred=model.fit_predict(x)
print(y_pred)


import matplotlib.pyplot as plt
import numpy as np
from sklearn import linear_model
np.random.seed(1234)
# create two gaussians
A = np.random.multivariate_normal(mean=[1, 1], cov=[[2, 1], [1, 2]], size=200)
B = np.random.multivariate_normal(mean=[-2, -2], cov=[[2, 0], [0, 2]], size=200)

# get them into proper matrix form
X = np.vstack([A, B])
Y = np.hstack([np.zeros(len(A)), np.ones(len(B))])

# train the linear regressor and save the coefficents
reg = linear_model.LinearRegression()
reg.fit(X, Y)
b_1, b_2 = reg.coef_
b_0 = reg.intercept_

# solve the function y = b_0 + b_1*X_1 + b_2 * X_2 for X2
x1s = np.linspace(-8, 8)
x2s = (0.5 - b_0 - b_1 * x1s) / b_2

plt.scatter(A[:, 0], A[:, 1], s=25, color='dodgerblue', label='True class A')
plt.scatter(B[:, 0], B[:, 1], s=25, color='limegreen', label='True class B')

plt.plot(x1s, x2s, color='gray', linestyle='--')

plt.fill_between(x1s, x2s, 10, color='dodgerblue', alpha=0.07)
plt.fill_between(x1s, x2s, -10, color='limegreen', alpha=0.07)
plt.grid()
plt.xlabel('X1')
plt.ylabel('X2')
plt.margins(x=0, y=0)
plt.xlim([-8, 8])
plt.ylim([-8, 8])
plt.legend()
None


# ------------------------------------------------------------------------------------------------------
#  Copyright (c) Leo Hanisch. All rights reserved.
#  Licensed under the BSD 3-Clause License. See LICENSE.txt in the project root for license information.
# ------------------------------------------------------------------------------------------------------

#pylint: disable=invalid-name

from functools import reduce
import numpy as np

def michalewicz(x):
    m = 10

    def func(x):
        return np.sin(x) * np.power(np.sin((0 + 1) * np.power(x, 2) / np.pi), 2 * m)

    result = reduce(lambda acc, x: acc + func(x), x, 0.)
    return -result

def ackley(x, a=20, b=0.2, c=2*np.pi):

    x = np.asarray_chkfinite(x)  # ValueError if any NaN or Inf
    n = len(x)
    s1 = np.sum(x**2, axis=0)
    s2 = np.sum(np.cos(c * x), axis=0)
    return -a*np.exp(-b*np.sqrt(s1 / n)) - np.exp(s2 / n) + a + np.exp(1)

FUNCTIONS = {
    'michalewicz': michalewicz,
    'ackley': ackley
}


import numpy as np
from scipy.stats import scoreatpercentile

data = np.loadtxt("mdrtb_2012.csv", delimiter=',', usecols=(1,), skiprows=1, unpack=True)

print "Max method", data.max()
print "Max function", np.max(data)

print "Min method", data.min()
print "Min function", np.min(data)

print "Mean method", data.mean()
print "Mean function", np.mean(data)

print "Std method", data.std()
print "Std function", np.std(data)

print "Median", np.median(data)
print "Score at percentile 50", scoreatpercentile(data, 50)


import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import hamming
from scipy.fftpack import fft, fftshift

plt.figure(1, figsize=(6, 5))
M= 64
N = 64
x = np.cos(2*np.pi*3/M*np.arange(M)) * np.hanning(M)

plt.subplot(2,1,1)
plt.title('x')
plt.plot(np.arange(-M/2.0,M/2), x, 'b', lw=1.5)
plt.axis([-M/2,M/2-1,-1,1])

powerx = sum(np.abs(x)**2)
print (powerx)

mX = np.abs(fftshift(fft(x, N)))
plt.subplot(2,1,2)
plt.title('abs(X)')
plt.plot(np.arange(-N/2.0,N/2), mX, 'r', lw=1.5)
plt.axis([-N/2,N/2-1,0,max(mX)])

powerX = sum(mX**2) / N
print (powerX)

plt.tight_layout()
plt.savefig('power.png')
plt.show()


import os
import tensorflow as tf
import numpy as np
from matplotlib.pyplot import axis
from tensorflow.contrib.factorization.examples.mnist import fill_feed_dict
tf.set_random_seed(777)

x_data = [[1,2,1,1],
          [2,1,3,2],
          [3,1,3,4],
          [4,1,5,5],
          [1,7,5,5],
          [1,2,5,6],
          [1,6,6,6],
          [1,7,7,7]]
y_data = [[0,0,1],
          [0,0,1],
          [0,0,1],
          [0,1,0],
          [0,1,0],
          [0,1,0],
          [1,0,0],
          [1,0,0]]

X = tf.placeholder('float', [None, 4])
Y = tf.placeholder('float', [None, 3])

nb_classes = 3

W = tf.Variable(tf.random_normal([4, nb_classes]), name='weight')
b = tf.Variable(tf.random_normal([nb_classes]), name='bias')

hypothesis = tf.nn.softmax(tf.matmul(X, W) + b)

cost = tf.reduce_mean(-tf.reduce_sum(Y * tf.log(hypothesis), axis=1))
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(cost)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    for step in range(2001):
        sess.run(optimizer, feed_dict={X: x_data, Y: y_data})
        if step % 200 == 0:
            print(step, sess.run(cost, feed_dict={X: x_data, Y: y_data}))

    print('--------------')

    a = sess.run(hypothesis, feed_dict={X: [[1, 11, 7, 9]] })
    print (a, sess.run(tf.arg_max(a, 1)))

    print('----------------')

    all = sess.run(hypothesis, feed_dict={ X:[[1,11, 7,9], [1,3,4,3], [1,1,0,1]] })


import numpy as np

def get_gaussian_stencil(size, sigma, ndims=3, normalize=False):

    x = np.arange(-(size//2), size//2 + 1)

    vals = 1 / (sigma * np.sqrt(2 * np.pi)) * np.exp(-x**2 / (2 * sigma**2))

    if normalize:
        vals = vals / vals.sum()

    stenc = np.empty((size,)*ndims, dtype=np.float32)

    if ndims == 3:
        for i in range(size):
            for j in range(size):
                for k in range(size):
                    stenc[i, j, k] = vals[i] * vals[j] * vals[k]
    elif ndims == 2:
        for i in range(size):
            for j in range(size):
                stenc[i, j] = vals[i] * vals[j]

        stenc = np.expand_dims(stenc, axis=0)

    return stenc


import numpy as np

def plane_rotation(ang, i, j, d):
    """
    D-dimensional transformation matrix for rotation within a given axis-aligned plane.
      ang : The angle of rotation, in radians
      i, j : The two axis indices specifying the plane of rotation
      d : the dimension of the matrix
    """
    R = np.eye(d)
    R[[i, i, j, j], [i, j, i, j]] = [np.cos(ang), -np.sin(ang), np.sin(ang), np.cos(ang)]
    return R

def smile_rotation(rotation, d=3):
    """
    Transformation matrix for rotation 3-tuples in SMILE
    can pass d=4 for homogenous coordinates
    """
    Rx = plane_rotation(rotation[0]*np.pi/180,1,2,d);
    Ry = plane_rotation(rotation[1]*np.pi/180,2,0,d);
    Rz = plane_rotation(rotation[2]*np.pi/180,0,1,d);
    R = Rz.dot(Ry).dot(Rx)
    return R

if __name__ == "__main__":

    # R = plane_rotation(np.pi/2, 0, 1, 2)
    R = smile_rotation((np.pi/2, 0, 0))
    print(R)
    print(R.dot(np.array([[1,0]]).T))


import numpy as np

def get_MSE(pred, real):
    return np.mean(np.power(real - pred, 2))

def get_RMSE(pred, real):
    return np.sqrt(np.mean(np.power(real - pred, 2)))

def get_MAE(pred, real):
    return np.mean(np.abs(real - pred))

def get_MRE(pred, real, upscale_factor=4):
    ori_real = real.copy()
    real[real == 0] = 1
    return np.mean(np.abs(ori_real - pred) / real)


## module newtonRaphson2
''' soln = newtonRaphson2(f,x,tol=1.0e-9).
    Solves the simultaneous equations f(x) = 0 by
    the Newton-Raphson method using {x} as the initial
    guess. Note that {f} and {x} are vectors.
'''
import numpy as np
from gaussPivot import *
import math
def newtonRaphson2(f,x,tol=1.0e-9):

    def jacobian(f,x):
        h = 1.0e-4
        n = len(x)
        jac = np.zeros((n,n))
        f0 = f(x)
        for i in range(n):
            temp = x[i]
            x[i] = temp + h
            f1 = f(x)
            x[i] = temp
            jac[:,i] = (f1 - f0)/h
        return jac,f0

    for i in range(30):
        jac,f0 = jacobian(f,x)
        if math.sqrt(np.dot(f0,f0)/len(x)) < tol:
            return x
        dx = gaussPivot(jac,-f0)
        x = x + dx
        if math.sqrt(np.dot(dx,dx)) < tol*max(max(abs(x)),1.0): return x
    print('Too many iterations')


import math
import numpy as np

def complexSignal(f1, f2, a1, a2, data_points = 3000, dT = 0.01,noisy = True,
                  mean = 0, std = 10,separate_signals = False):

    if noisy:
        noise = np.random.normal(mean, std, size=data_points)
    else:
        noise = np.zeros(shape=(data_points))

    tremor1 = []
    tremor2 = []

    frequencies = np.zeros(shape=(2, data_points))

    t = 0

    for i in range(data_points):
        t += dT
        tremor1.append(a1*math.sin(2 * math.pi * f1 * t))
        tremor2.append(a2* math.cos(2 * math.pi * f2 * t))
        if a1 > a2:
            frequencies[0][i] = f1
            frequencies[1][i] = f2
        else:
            frequencies[0][i] = f2
            frequencies[1][i] = f1
    if separate_signals:
        return tremor1, tremor2, noise
    else:
        return np.array(tremor1) + np.array(tremor2) + noise, frequencies


import numpy as np

def sigmoid(x):
    return 1.0/(1+ np.exp(-x))

def sigmoid_derivative(x):
    return x * (1.0 - x)

class NeuralNetwork:
    def __init__(self, x, y):
        self.input      = x
        self.weights1   = np.random.rand(self.input.shape[1], 6)
        self.weights2   = np.random.rand(6,1)
        self.y          = y
        self.output     = np.zeros(self.y.shape)

    def feedforward(self):
        self.layer1 = sigmoid(np.dot(self.input, self.weights1))
        self.output = sigmoid(np.dot(self.layer1, self.weights2))

    def backprop(self):
        # application of the chain rule to find derivative of the loss function with respect to weights2 and weights1
        d_weights2 = np.dot(self.layer1.T, (2*(self.y - self.output) * sigmoid_derivative(self.output)))
        d_weights1 = np.dot(self.input.T,  (np.dot(2*(self.y - self.output) * sigmoid_derivative(self.output), self.weights2.T) * sigmoid_derivative(self.layer1)))

        # update the weights with the derivative (slope) of the loss function
        self.weights1 += d_weights1
        self.weights2 += d_weights2
        print(self.weights1)
        print(self.weights2)

if __name__ == "__main__":
    X = np.array([[False, True, False],
                  [False, True, True],
                  [True, True, False],
                  [True, False, True],
                  [False, True, False],
                  [True, False, False]])

    y = np.array([[False],[True],[True],[False],[False],[False]])

    nn = NeuralNetwork(X,y)

    for i in range(1500):
        nn.feedforward()
        nn.backprop()

    for i in range(len(nn.output)):
        if nn.output[i] < 0.1:
            print(False)

        else:
            print(True)


import numpy as np

############# Base Functions and Matrixes #############

# Scaling

def scale_matrix(k_x: float, k_y: float, k_z: float) -> np.matrix:
    return np.matrix([
        [k_x, 0.0, 0.0],
        [0.0, k_y, 0.0],
        [0.0, 0.0, k_z]
    ])

def unscale_matrix(k_x: float, k_y: float, k_z: float) -> np.matrix:
    return np.matrix([
        [1.0/k_x, 0.0, 0.0],
        [0.0, 1.0/k_y, 0.0],
        [0.0, 0.0, 1.0/k_z]
    ])

# Projection over planes

M_xy = np.matrix([
                  [1.0, 0.0, 0.0],
                  [0.0, 1.0, 0.0],
                  [0.0, 0.0, -1.0]
                ])

M_yz = np.matrix([
                  [-1.0, 0.0, 0.0],
                  [0.0, 1.0, 0.0],
                  [0.0, 0.0, 1.0]
                ])

M_xy = np.matrix([
                  [1.0, 0.0, 0.0],
                  [0.0, 1.0, 0.0],
                  [0.0, 0.0, -1.0]
                ])

# Rotation

def R_x(deg: float) -> np.matrix:
    return np.matrix([
        [1.0, 0.0, 0.0],
        [0.0, np.cos(deg), np.sin(deg)],
        [0.0, -np.sin(deg), np.cos(deg)]
    ])

def R_y(deg: float) -> np.matrix:
    return np.matrix([
        [np.cos(deg), 0.0, -np.sin(deg)],
        [0.0, 1.0, 0.0],
        [np.sin(deg), 0.0, np.cos(deg)]
    ])

def R_z(deg: float) -> np.matrix:
    return np.matrix([
        [np.cos(deg), np.sin(deg), 0.0],
        [-np.sin(deg), np.cos(deg), 0.0],
        [0.0, 0.0, 1.0]
    ])

# Movement

def T(dx: float, dy: float, dz: float) -> np.matrix:
    return np.matrix([
        [1.0, 0.0, 0.0, -dx],
        [0.0, 1.0, 0.0, -dy],
        [0.0, 0.0, 1.0, -dz],
        [0.0, 0.0, 0.0, 1.0]
    ])

def T_1(dx: float, dy: float, dz: float) -> np.matrix:
    return np.matrix([
        [1.0, 0.0, 0.0, dx],
        [0.0, 1.0, 0.0, dy],
        [0.0, 0.0, 1.0, dz],
        [0.0, 0.0, 0.0, 1.0]
    ])

############# Example Tasks #############

# Побудувати матрицю перетворення щодо обертання навколо осі, яка
# проходить через точку A(x_A, y_A, z_A). Напрямок прямої задано
# одиничним вектором (l, m, n).

# l^2 + m^2 + n^2 = 1
# Зсув системи координат в А:

(l, m, n) = (1.0, 1.0, 1.0)
(x_A, y_A, z_A) = (10.0, 10.0, 10.0)

ex_T = T(x_A, y_A, z_A)

d = np.sqrt(m**2 + n**2)

alpha = np.arccos(n/d)

ex_R_x = np.matrix([
    [1.0, 0.0, 0.0, 0.0],
    [0.0, n/d, m/d, 0.0],
    [0.0, -m/d, n/d, 0.0],
    [0.0, 0.0, 0.0, 1.0]
])

print(f"l = {l}, m = {m}, n = {n}, d = {d}")
print(f"[l, m, n, 1][R_x] = {np.array([l, m, n, 1.0] * ex_R_x)}")

ex_R_y = np.matrix([
    [d, 0.0, l, 0.0],
    [0.0, 1.0, 0.0, 0.0],
    [-l, 0.0, d, 0.0],
    [0.0, 0.0, 0.0, 1.0]
])

print(f"[l, 0, d, 1][R_y] = {np.array([0.0, 0.0, 1.0, 1.0])}")


import numpy as np
from collections import Counter

def is_prime(x):
    prime = True
    if x==1:
        prime=False
    if x==2:
        prime=True
    elif x%2==0:
        prime=False
    else:
        for i in range(3,int(x**0.5)+1,2):
            if x%i==0:
                prime=False
                break
    return prime

def get_primes(nb):
    x=1
    primes=[]
    while x<nb:
        if is_prime(x):
            primes.append(x)
        x+=1
    return primes

def decompo_primes(nb,primes,factors):
    nbt=nb
    decomp_primes = []
    while is_prime(nbt)==False:
        for i in primes:
            if nbt%i==0:
                decomp_primes.append(i)
                nbt /= i
                break
    decomp_primes.append(int(nbt))
    factor = Counter(decomp_primes)
    for prime in factors:
        if factor[prime] and factor[prime] > factors[prime]:
            factors[prime]=factor[prime]
    return factors

def PPCM(nb):
    primes = get_primes(nb)
    factors={k:0 for k in primes}
    ppcm=1
    for i in range(2,nb+1):
        factors = decompo_primes(i,primes,factors)
        # print('decompo ',i,' done')
        print('étape ',i,': ',factors)
    for i in factors:
        ppcm *= i**factors[i]
    return ppcm

print(PPCM(50))
# 232792560


import scipy.stats
import pandas as pd

def kullback_leibler_divergence(p_df, q_df):
    """
    A thin wrapper deriving the KLD (to allow switching
    out and layer abstraction)
    :param p_df: a dataframe representing the 'true' distribution or reference distribution (discrete)
    :param q_df: a dataframe on the same probability space representing an approximation of p_df
    :return: the divergence in [0,1]
    """
    if not (isinstance(p_df, pd.DataFrame) and isinstance(q_df, pd.DataFrame)):
        raise NotImplementedError('')
    return scipy.stats.entropy(p_df, q_df)

def median_iqr(series):
    """
    The interquartile range (Q3-Q1) and median are computed on a pandas series
    :param df:
    :return:
    """
    iqr_median = [.25, .5, .75]
    series = series.quantile(iqr_median)
    iqr = series.iloc[2] - series.iloc[0]
    median = series.iloc[1]
    return median, iqr


import numpy as np
import matplotlib.pyplot as plt

"""Question-2:: Newton's Method"""

def cost_function(cf):
    cf = np.asarray(cf)
    cf_x = cf[0]
    cf_y = cf[1]
    cost = np.log(1 - cf_x - cf_y) - np.log(cf_x) - np.log(cf_y)
    return cost

def gradient_cost_function(gcf):
    gcf = np.asarray(gcf)
    gcf_x = gcf[0]
    gcf_y = gcf[1]
    gradient_x = np.divide(1, (1 - gcf_x - gcf_y)) - np.divide(1, gcf_x)
    gradient_y = np.divide(1, (1 - gcf_x - gcf_y)) - np.divide(1, gcf_y)
    new_gcf = np.asarray((gradient_x, gradient_y))
    return new_gcf

"""define fuction that calculates the hessian matrix and returns
 the pseudo inverse of the matric"""
def hessian_inverse_matrix(him):
    him = np.asarray(him)
    him_x = him[0]
    him_y = him[1]
    h_11 = np.divide(1, np.square(1 - him_x - him_y)) + np.divide(1, np.square(him_x))
    h_12 = np.divide(1, np.square(1 - him_x - him_y))
    h_21 = np.divide(1, np.square(1 - him_x - him_y))
    h_22 = np.divide(1, np.square(1 - him_x - him_y)) + np.divide(1, np.square(him_y))
    hessian_matrix = np.ndarray(shape=(2, 2))
    hessian_matrix_array = np.asarray(hessian_matrix)

    for i in range(0, 2):
        for j in range(0, 2):
            if i == 0 and j == 0:
                hessian_matrix_array[i][j] = h_11
            else:
                if i ==0 and j == 1:
                    hessian_matrix_array[i][j] = h_12
                else:
                    if i == 1 and j == 0:
                        hessian_matrix_array[i][j] = h_21
                    else:
                        if i == 1 and j == 1:
                            hessian_matrix_array[i][j] = h_22

    hessian_inverse = np.linalg.pinv(hessian_matrix_array)
    return hessian_inverse

"""weights initialization"""

w_x = np.random.uniform(0, 0.5, 1)
w_y = np.random.uniform(0, 0.4, 1)
weights = np.asarray((w_x, w_y))
print "initial weights", weights
learning_rate = 0.1
threshold = 0.0000002
iteration_number = 0
domain_miss = 0
actual_cost = [[0.0]]
actual_cost = np.asarray(actual_cost, dtype=np.float)
cost_plot = []
iteration_plot = []
w0_plot = []
w1_plot = []
w0_plot.append(weights[[0]])
w1_plot.append(weights[[0]])

while True:
    step_update = gradient_cost_function(weights)
    temp_hessian = hessian_inverse_matrix(weights)
    delta_weights_temp = np.dot(temp_hessian, step_update)
    temp_weights = weights - learning_rate * delta_weights_temp
    domain_condition_temp = np.asarray(temp_weights)
    domain_condition = domain_condition_temp[0] + domain_condition_temp[1]
    if domain_condition < 1:
        weights = temp_weights
        w0_plot.append(temp_weights[[0]])
        w1_plot.append(temp_weights[[1]])
        temp_cost = cost_function(weights)
        iteration_temp = iteration_number + 1
        iteration_plot.append(iteration_temp)
        cost_plot.append(temp_cost)

    else:
        w_x = np.random.uniform(0, 0.5, 1)
        w_y = np.random.uniform(0, 0.4, 1)
        weights = np.asarray((w_x, w_y))
        domain_miss = domain_miss +1
        print "number of domain misses:", domain_miss, "weights are:", temp_weights
        continue
    iteration_number = iteration_number + 1
    actual_cost_temp = cost_function(weights)
    actual_cost = np.append(actual_cost, actual_cost_temp)
    threshold_cal = np.subtract(actual_cost[iteration_number], actual_cost[iteration_number-1])
    print "iteration number::", iteration_number, "cost difference", threshold_cal, "cost::", actual_cost_temp
    if np.absolute(threshold_cal) < threshold:
        break

print "final weights::", weights
print "final cost::", cost_function(weights)
plt.figure(1)
plt.xlabel('iteration number')
plt.ylabel('cost')
plt.plot(iteration_plot, cost_plot, color='red')
plt.savefig('question2NM.png')
plt.figure(2)
plt.scatter(w0_plot, w1_plot, s=2)
plt.xlabel('x')
plt.ylabel('y')
plt.savefig('Q2pointPlotNM.png')


import numpy as np

"""
READ README.rst

    Neural network example

    - inputs (data) :
        - x1
        - x2
        - x3
    - synapses (way):
       - w1
       - w2
       - w3
    - neurones :
      - Σxi*wi = x1*w1+x2*w2+x3*w3
         - i number(1,2,3,4,5,...)
         - xi number of data inputs
         - wi number of neurone
    - output :
      - y : result

    - phi (Greek alphabet):
      -  phi(x) = 1/1+e^(-x) | phi'(x) = x.(1-x)
      x =Σxiwi

      - phi(x) = 1/1+e^(-Σxiwi)

      - exp^(-x) : exponential de -x

"""

def sigmoid(x):
    return 1/(1+np.exp(-x))

def sigmoid_derivation(x):
    return x*(1-x)

# input
training_inputs = np.array([
    [0,0,1],
    [1,1,1],
    [1,0,1],
    [0,1,1]
])

training_outputs = np.array([[0,1,1,0]]).T

np.random.seed(1)
synaptic_weights = 2* np.random.random((3,1))-1

print("Random starting synaptic weight : ")
print(synaptic_weights)

for iteration in range(20000): #1 after 20000 50000 100000 ...

    input_layer = training_inputs

    outputs = sigmoid(np.dot(input_layer,synaptic_weights))

    error = training_outputs - outputs

    adjustements = error*sigmoid_derivation(outputs)

    synaptic_weights+=np.dot(input_layer.T, adjustements)

print("Synaptic weights after training ")
print(synaptic_weights)
print("\n")
print("Outputs after training : ")
print(outputs)


# coding: utf-8

# ## Sorting arrays in Numpy
# Numpy, short for Numerical Python, is the fundamental package required for hight performance scientific computing and its best library to learn and apply on data science career.
#
#

# In[3]:

import numpy as np

# In[9]:

names = np.array(['F', 'C', 'A', 'G'])
weights = np.array([20.8, 93.2, 53.4, 61.8])

sort(weights)

# In[10]:

#argsort
ordered_indices = np.argsort(weights)
ordered_indices

# In[11]:

weights[ordered_indices]

# In[13]:

names[ordered_indices]

# In[15]:

data = np.array([20.8,  93.2,  53.4,  61.8])
data.argsort()

# In[16]:

# sort data
data.sort()
data

# In[17]:

# 2d array
a = np.array([
        [.2, .1, .5],
        [.4, .8, .3],
        [.9, .6, .7]
    ])
a

# In[18]:

sort(a)

# In[20]:

# sort by column
sort(a, axis = 0)

# In[22]:

# search sort
sorted_array = linspace(0,1,5)
values = array([.1,.8,.3,.12,.5,.25])

# In[24]:

np.searchsorted(sorted_array, values)


#===================================================================================
#
#   Code (đã cái tiến) cho PP tiếp tuyến - Newton-Ralphson.
#       * Input: f(x) trong pt f(x) = 0; khoảng cách li ban đầu (a, b); sai số epsilon
#       * Output: Nghiệm PT f(x) = 0;
#       * Hạn chế: Chưa có gói tìm khoảng cách ly nghiệm
#       * Cải tiến: Giảm khối lượng tính toán - tính f(a) 1 lần + thêm SymPy
#
#===================================================================================
from sympy import *
from math import *
import sys

#===================================================================================
# Phần thuật toán chính
class newton_oop:
#{
    def __init__(self, a_0, b_0, eps, expr):
    #{
        x = symbols("x");
        func = sympify(expr);

        self.a_0 = a_0;
        self.b_0 = b_0;
        self.eps = eps;

        self.sym_df = [
            func,
            diff(func, x),
            diff(func, x, 2)
        ];
        self.df = [
            lambdify(x, self.sym_df[0], "math"),
            lambdify(x, self.sym_df[1], "math"),
            lambdify(x, self.sym_df[2], "math"),
        ];

        # print(self.sym_df, file=sys.stderr);
    #}

    # Trị tuyệt đối và check dấu
    def __abs(self, x):
    #{
        return x if x >= 0 else -x;
    #}
    def __sign(self, x):
    #{
        if(x > 0): return 1;
        if(x < 0): return -1;
        return 0;
    #}

    # Tìm max/min của f
    def __findMaxMin(self, sym_f, f):
    #{
        x = symbols("x");
        a = self.a_0;
        b = self.b_0;

        val_max = val_min = f(a);
        sol_set = FiniteSet(a, b);
        sol_set = Union(sol_set, solveset(diff(sym_f, x), x, Interval(a, b)));

        if(sol_set.is_iterable):
            for args in sol_set:
            #{
                val_max = max(val_max, f(args));
                val_min = min(val_min, f(args));
            #}

        return (
            val_min,
            val_max,
            self.__sign(val_min),
            self.__sign(val_max)
        );
    #}

    # Chốt 141
    def __checkInputValidity(self):
    #{
        a = self.a_0;
        b = self.b_0;
        f = self.df[0];

        # Corner case: f(a) = 0 or f(b) = 0
        if(f(a) == 0 or f(b) == 0): return 1;

        # Check if a < b
        if(a > b or (a == b and f(a) != 0)):
        #{
            print(f"Khoảng cách ly [{a}, {b}] không hợp lệ 8==>");
            return 0;
        #}

        # Check if f(a) * f(b) < 0
        if(f(a) * sign(f(b)) >= 0):
        #{
            print(f"Khoảng cách ly [{a}, {b}] không hợp lệ 8==>");
            return 0;
        #}

        # Check if [a, b] is "safe" to converge
        d1f_maxmin = self.__findMaxMin(self.sym_df[1], self.df[1]);
        d2f_maxmin = self.__findMaxMin(self.sym_df[2], self.df[2]);

        if(d2f_maxmin[2] * d2f_maxmin[3] < 0 or d1f_maxmin[2] * d1f_maxmin[3] <= 0):
        #{
            print("PP Newton ko hội tụ được do f'(x), f''(x) vi phạm điều kiện xác định dấu không đổi");
            return 0;
        #}

        # print(d1f_maxmin, file=sys.stderr);
        # print(d2f_maxmin, file=sys.stderr);

        # Assign auxiliary variables
        self.m1 = -d1f_maxmin[1] if (d1f_maxmin[0] < 0) else d1f_maxmin[0];
        self.M2 = -d2f_maxmin[0] if (d2f_maxmin[0] < 0) else d2f_maxmin[1];
        self.sign =  d2f_maxmin[2];
        return 1;
    #}

    def __newtonMethod(self):
    #{
        eps = self.eps;
        a = self.a_0;
        b = self.b_0;
        m1 = self.m1;

        f = self.df[0];
        d1f = self.df[1];
        x0 = a if (f(a) * self.sign > 0) else b;

        if(f(a) == 0): return a;
        if(f(b) == 0): return b;

        print(x0, m1, self.sign, file=sys.stderr);

        while(self.__abs(f(x0)) > eps * m1):
        #{
            x0 = x0 - f(x0) / d1f(x0);
            # print(x0, file=sys.stderr);
        #}

        return x0;
    #}

    def Solve(self):
    #{
        if(self.__checkInputValidity() == 0):
        #{
            print("Invalid input. The program will now exit", file=sys.stderr);
            return float("NaN");
        #}
        return self.__newtonMethod();
    #}
#}

#===================================================================================
# Chương trình ví dụ
# expr = "sqrt(log(x)) - 1";
# L = 2;
# R = 3;
# eps = 1e-12;

# uu = newton_oop(L, R, eps, expr);
# print(f"Nghiệm của phương trình {expr} trên khoảng [{L}, {R}] là: {uu.Solve()}");

Topic 1 - Find solution for single-variable functions/Newton-Ralphson Method/newton_ralphson.py


import numpy as np
import math

class square_root():
    def __init__(self,A,b,limit):
        self.A=A.astype(float)
        self.b=b.astype(float)
        self.limit=limit
        self.n=b.size

    def cal(self):
        self.L=np.zeros_like(self.A,dtype=float)
        for k in range (self.n):
            sum_l_square=0.
            for m in range(k):
                sum_l_square+=self.L[k,m]**2
            s=self.A[k,k]-sum_l_square
            if s<self.limit:
                print("求解失败！")
                return None
            self.L[k,k]=math.pow(s,0.5)
            for i in range(k+1,self.n):
                sum_l=0.
                for m in range(k):
                    sum_l+=self.L[i,m]*self.L[k,m]
                self.L[i,k]=(self.A[i,k]-sum_l)/self.L[k,k]
        self.Y=np.zeros_like(self.b,dtype=float)
        self .Y[0]=self.b[0]/self.L[0,0]
        for i in range(1,self.n):
            sum_ly=0.
            for j in range(i):
                sum_ly+=self.L[i,j]*self.Y[j]
            self.Y[i]=(self.b[i]-sum_ly)/self.L[i,i]
        self.X=np.zeros_like(self.b,dtype=float)
        self.X[-1]=self.Y[-1]/self.L[-1,-1]
        for i in range(self.n-2,-1,-1):
            sum_lx=0.
            for j in range(i+1,self.n):
                sum_lx+=self.L[j,i]*self.X[j]
            self.X[i]=(self.Y[i]-sum_lx)/self.L[i,i]
        return self.X

A=np.array([[3,2,1],[2,2,0],[1,0,3]])
b=np.array([[5],[3],[4]])
s_r=square_root(A,b,1e-4)
print(s_r.cal())


import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from random import randint
import traceback
import os
from scipy.integrate import odeint
import math
import json
import sys

# https://en.wikipedia.org/wiki/Hohmann_transfer_orbit
#print 'Argument List:', str(sys.argv)
#print sys.argv[1:2]
#print sys.argv[1]
data=sys.argv[1:2]
decoded = json.loads(sys.argv[1])
#print decoded
#print decoded['x0']
central=decoded['central']
x0=decoded['x0']
y0=decoded['y0']
vx0=decoded['vx0']
vy0=decoded['vy0']
z0=0
GM=decoded['GM']
tf=decoded['tf']

#GM = 1.5

#print GM/2
#r = math.sqrt(x0 * x0 + y0 * y0 + z0 * z0)
#rcubed = r * r * r
#print rcubed
#muorc = -1.0 * GM / rcubed
#print muorc

def acceleration(r_vec, t):
    x, y, z, vx, vy, vz = r_vec
    #mu = 3000.0
    r = math.sqrt(x * x + y * y + z * z)
    rcubed = r * r * r
    #muorc = -1.0 * mu / rcubed
    muorc = -1.0 * GM / rcubed
    #print r
    drdt = [vx, vy, vz, muorc * x, muorc * y, muorc * z]
    return drdt

def npmax(l):
    max_idx = np.argmax(l)
    max_val = l[max_idx]
    #return (max_idx, max_val)
    return max_val

def npmin(l):
    min_idx = np.argmin(l)
    min_val = l[min_idx]
    #return (min_idx, min_val)
    return min_val

t = np.linspace(0, tf, 100)
y_vec0 = [x0, y0, 0, vx0, vy0, 0]
#y_vec0 = [0, 20, 0, 16, 0, 0]
print 'y_vec0 ',y_vec0,

sol = odeint(acceleration, y_vec0, t)

try:
    os.remove("writeFiles/orbitTest01.png")
except Exception:
    pass

try:
    if central=='Earth':
        circle1=plt.Circle((0,0),6378,color='#36AFBF')
        #77 182 196
        plt.gcf().gca().add_artist(circle1)
    if central=='Sun':
        circle1=plt.Circle((0,0),6963000,color='#E9F073')
        plt.gcf().gca().add_artist(circle1)
    #plt.plot(range(5))
    # plt.plot(t, s)
    plt.plot(sol[:, 0], sol[:, 1])
    #print npmax(sol[:, 0])
    #print npmax(sol[:, 1])
    #print npmin(sol[:, 1])
    ps1=npmax(sol[:, 0])
    ps2=np.absolute(npmin(sol[:, 0]))
    ps3=npmax(sol[:, 1])
    ps4=np.absolute(npmin(sol[:, 1]))
    print max(ps1,ps2,ps3,ps4)
    plotsize=1.01*max(ps1,ps2,ps3,ps4)

    plt.xlim(-plotsize, plotsize)
    plt.ylim(-plotsize, plotsize)
    plt.gca().set_aspect('equal', adjustable='box')
    plt.draw()
    plt.xlabel('x')
    plt.ylabel('y')
    plt.title('central body orbit')
    plt.grid(True)
    plt.savefig("writeFiles/orbitTest01.png", bbox_inches='tight')
except Exception:
    print(traceback.format_exc())
    print "exception"
    print "end"


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

def gaussian(x, mu, sigma):
    return ((1.0/np.sqrt(2.0*math.pi)*sigma)*np.exp(-(x - mu)**2/(2.0*sigma**2)))

print(random.random()) #prints a single random number b/t 0 and 1
print(random.uniform(1.0,6.0)) #single random b/t 1 and 6
print(random.randint(1,6)) #single integer btwn 1 and 6
print(random.gauss(0.0, 1.0)) #single guassian number

print(np.random.random(10))
print(np.random.uniform(1.0, 6.0, 10)) # 10 numbers btwn 1 and 6
print(np.random.randint(1,6,10))
print(np.random.normal(0, 1.0 , 10))

x_0 = np.linspace(-4.0,4.0,10000)
y_0 = gaussian(x_0,0.0,1.0)
x = np.random.normal(0.0, 1.0, 10000)

plt.hist(x,bins='fd',density =True)
plt.plot(x_0, y_0)
plt.show()


import math
from math import cos, sin
import numpy as np

def servo_angles_to_xyzlines(a1, a2, r=0.5):
    alpha, beta = math.radians(a1), math.radians(a2)
    x1, y1, z1 = r * cos(alpha), 0, r * sin(alpha)

    transform = np.array([[cos(alpha), 0, -sin(alpha), x1],  # DH matrix
                          [0, 1, 0, y1],
                          [sin(alpha), 0, cos(alpha), z1],
                          [0, 0, 0, 1]])
    x2, y2, z2 = r*sin(beta), r*cos(beta), 0
    xyz2 = np.matmul(transform, [x2, y2, z2, 1]).transpose()
    x2, y2, z2, _ = xyz2
    return [[0, x1, x2], [0, y1, y2], [0, z1, z2]]

def xyz_to_servo_angles(x2, y2, z2):
    r = math.sqrt(x2**2 + y2**2 + z2**2)
    if x2 == 0:
        alpha = 90
    else:
        alpha = math.degrees(math.atan(z2/x2))
    beta = math.degrees(math.acos(y2/r))
    if alpha < 0:
        alpha = 180 + alpha
    return alpha, beta

def el_az_to_servo_angles(el, az, r=0.5):
    xyz = el_az_to_xyz(el, az, r=r)
    return xyz_to_servo_angles(*xyz)

def el_az_to_xyz(el, az, r=0.5):
    el = math.radians(el)
    az = math.radians(az)
    x = r * cos(el) * cos(az)
    y = r * cos(el) * sin(az)
    z = r * sin(el)
    return x, y, z

def xyz_to_el_az(x, y, z):
    az = math.atan2(x, y)
    r = math.sqrt(x**2 + y**2)
    el = math.atan2(z, r)

    if el < 0 < z:
        print('elevation is less than 0 and z is greater than 0')
        el += math.pi
        az += math.pi
    return el, az

def rotate(x, y, z, alpha, axis=None):
    alpha = math.radians(alpha)
    if axis == 1 or axis == 'y':
        transform = np.array([[cos(alpha),  0, sin(alpha)],
                              [0,           1, 0],
                              [-sin(alpha), 0, cos(alpha)]])
    elif axis == 2 or axis == 'z':
        transform = np.array([[cos(alpha), -sin(alpha), 0],
                              [sin(alpha),  cos(alpha), 0],
                              [0,           0,          1]])
    else:
        transform = np.array([[1, 0,           0],
                              [0, cos(alpha), -sin(alpha)],
                              [0, sin(alpha),  cos(alpha)]])
    return *np.matmul([x, y, z], transform), 1

def r3(points, rotations):
    if len(rotations) != 3:
        print(f'invalid rotations: <{rotations=}>. should be of the form [rx, ry, rz]')
        return points

    rx, ry, rz = np.radians(rotations)
    rx_mat = np.array([[1, 0,        0],
                       [0, cos(rx), -sin(rx)],
                       [0, sin(rx),  cos(rx)]])
    ry_mat = np.array([[cos(ry),  0, sin(ry)],
                       [0,        1,       0],
                       [-sin(ry), 0, cos(ry)]])
    rz_mat = np.array([[cos(rz), -sin(rz), 0],
                       [sin(rz),  cos(rz), 0],
                       [0,        0,       1]])
    rotate = np.matmul(np.matmul(rz_mat, ry_mat), rx_mat)
    return np.matmul(points, rotate)

def servo_angles_to_camera_line(a1, a2, r=0.5):
    alpha, beta = math.radians(a1), math.radians(a2)
    x2 = r*sin(beta) * cos(alpha)
    y2 = r*cos(beta)
    z2 = sin(alpha) * r * sin(beta)
    return [[0, x2], [0, y2], [0, z2]]

def plot_servo(alpha, beta, ax, color1='--k', color2='--k'):
    nums = servo_angles_to_xyzlines(alpha, beta)
    l1 = [nums[x][:2] for x in range(len(nums))]
    l2 = [nums[x][1:3] for x in range(len(nums))]
    ax.plot3D(*l1, color1)
    ax.plot3D(*l2, color2)

def plot_servo_dir(alpha, beta, ax, color='--k'):
    nums = servo_angles_to_camera_line(alpha, beta)
    l1 = [nums[x][:2] for x in range(len(nums))]
    ax.plot3D(*l1, color)

def setup_plot(ax):
    ax.set_xlim3d(-1, 1)
    ax.set_ylim3d(-1, 1)
    ax.set_zlim3d(0, 2)
    ax.plot3D([-1, 1], [0, 0], [0, 0], '--k')
    ax.plot3D([0, 0], [-1, 1], [0, 0], '--k')

def plot_el_az(el, az, ax, r=0.5, color='--k'):
    x, y, z = el_az_to_xyz(el, az, r=r)
    ax.plot3D([0, x], [0, y], [0, z], color)

def plot_x_y_z(x, y, z, ax, color='--k'):
    ax.plot3D([0, x], [0, y], [0, z], color)

def get_quadrant(x, y, z):
    sign = lambda x: -1 if x < 0 else 1 if x > 0 else 0
    x = sign(x)
    y = sign(y)
    z = sign(z)
    return x, y, z

if __name__ == "__main__":
    import pigpio
    from servo import Servo
    import time
    pi = pigpio.pi('192.168.178.229')
    s1 = Servo(pi, 16, angle_range=[-20, 200], pulse_range=[550,2008])
    s2 = Servo(pi, 12, angle_range=[-20, 200], pulse_range=[550,2008])
    s1.set_angle(90)
    s2.set_angle(90)

    el, az = 43, 87
    el_dir = 10/18

    while True:
        if el_dir > 0 and el >= 80-abs(el_dir):
            el_dir = -el_dir
        if el_dir < 0 and el <= 10+abs(el_dir):
            el_dir = -el_dir
        el += el_dir

        az += 10
        if az > 180:
            az -= 360
        az += 2.5
        if el > 90:
            el = 0

        xyz = el_az_to_xyz(el, az)
        x, y = el_az_to_servo_angles(el, az)

        print()
        s1.set_angle(x)
        s2.set_angle(y)
        time.sleep(0.02)


import numpy as np

# 通用计算
arr = np.array([1, 2, 3, 4])

# 指数函数
# [ 2.71828183  7.3890561  20.08553692 54.59815003]
print(np.exp(arr))

# 正弦、余弦、正切函数
# [ 0.84147098  0.90929743  0.14112001 -0.7568025 ]
print(np.sin(arr))
# [ 0.54030231 -0.41614684 -0.9899925  -0.65364362]
print(np.cos(arr))
# [ 1.55740772 -2.18503986 -0.14254654  1.15782128]
print(np.tan(arr))

# 开方函数
# [1.         1.41421356 1.73205081 2.        ]
print(np.sqrt(arr))

# 加法，与+功能一致，参与运算的两个数组（矩阵），规格（shapes）必须一致
# [ 2  5  8 11]
print(np.add(arr, np.array([1, 3, 5, 7])))


# -*- coding: utf-8 -*-
# @Date  : 2020/5/20
# @Author: Luokun
# @Email : olooook@outlook.com

import numpy as np

class PCA:
    """
    Principal Components Analysis(主成分分析)
    """

    def __init__(self, K: int):
        """
        :param K: 保留的主成因个数
        """
        self.K = K

    def transform(self, X: np.ndarray):
        X_norm = X - X.mean(axis=0)  # 去中心化
        L, U = np.linalg.eig(X_norm.T @ X_norm)  # 对协方差矩阵进行特征值分解
        topk = np.argsort(L)[::-1][:self.K]  # 找出特征值中前K大特征对应的索引
        return X_norm @ U[:, topk]  # 将去中心化矩阵乘以前K大特征对应的特征向量


import numpy as np
import math
size = (3,3)
point = (1,1)
weight = np.zeros(size)
def gaussian_fn(x,y):
    # np.exp 返回自然常数 e
    # sigma σ 控制"钟形"的宽度 现在设为 1.5
    sigma = 1.5
    return 1 / (2 * math.pi * sigma ** 2) * np.exp(-(x ** 2 + y ** 2) / (2 * sigma ** 2))

for y in range(size[0]):
	for x in range(size[1]):
		bias_x  = x - point[0]
		bias_y = y - point[1]
		print(bias_x,bias_y)
		weight[x][y] = gaussian_fn(bias_x,bias_y)

total = np.sum(weight)
weight = weight / total


from numpy import sin

def comp_surface(self):
    """Compute the Slot total surface (by analytical computation).
    Caution, the bottom of the Slot is an Arc

    Parameters
    ----------
    self : Slot19
        A Slot19 object

    Returns
    -------
    S: float
        Slot total surface [m**2]

    """

    Rbo = self.get_Rbo()

    # Wint is the with at the top of the opening
    alpha0 = self.comp_angle_opening()
    alpha1 = self.comp_angle_bottom()

    if self.is_outwards():
        R1 = Rbo + self.H0
    else:
        R1 = Rbo - self.H0

    W0 = 2 * Rbo * sin(alpha0 / 2)
    W1 = 2 * R1 * sin(alpha1 / 2)

    Str = 1 / 2 * (W0 + W1) * self.H0
    S0 = Rbo ** 2 / 2 * (alpha0 - sin(alpha0))
    S1 = R1 ** 2 / 2 * (alpha1 - sin(alpha1))

    return Str + S1 - S0


import numpy as np

x0=np.zeros(4)
TOL=10**(-5)
NMAX=100
A=np.ones((4,4))
A[0,0]=6
A[1,1]=7
A[2,2]=8
A[3,3]=9

x_sol=np.ones((4))
b=np.dot(A,x_sol)

def Gauss_Seidel(A,b,NMAX,TOL,x0):
    m=A.shape[0]

    D=np.diag(np.diag(A))
    U=np.triu(-A,1)
    L=np.tril(-A,-1)

    y=np.dot(U,x0)+b
    x=np.linalg.solve(D-L,y)
    e=np.linalg.norm(x-x0)

    M=(D-L)
    N=(U)
    n=1
    while ( n < NMAX) and (e > TOL ):
        x0=x
        y=np.dot(N,x0)+b
        x=np.linalg.solve(M,y)
        e=np.linalg.norm(x-x0)
        n=n+1

    return x,n,e

print(Gauss_Seidel(A,b,NMAX,TOL,x0))


# Estimating pi using the monte carlo method
import numpy as np

limit = 5000000

darts = 0
insideCircle = 0

while darts < limit:
    darts +=1
    x = np.random.uniform(-1.0,1.0)
    y = np.random.uniform(-1.0,1.0)
    if x*x + y*y <= 1:
        insideCircle += 1

    #print(x,y,inside)

print(darts)
print(insideCircle)
pi = 4 * (insideCircle / darts)
print(pi)


from sympy import *

h = symbols('h',positive=true)

A = Matrix([[1 - h**2/2, -h/2*(2-h**2/2)],[h , 1-h**2/2]])

print("transition matrix")
print(A)
print("\n")

ATA = A.adjoint()*A

print("gram matrix")
print(simplify(ATA))
print("\n")

v1 = ATA.eigenvects()[0][2][0]
v2 = ATA.eigenvects()[1][2][0]

print("Eigenvector matrix ATA")
u1 = (1/v1.norm())*v1
u2 = (1/v2.norm())*v2
U = u1.row_join(u2)
print(simplify(U))
print("\n")

print("Eigenvalue matrix ATA")
print(simplify(U.T*ATA*U))

print("Eigenvector matrix A")
P,D = A.diagonalize()

print(simplify(P))

print("\n")

print("Eigenvalue matrix A")
print(simplify(D))

print("\n")

print("Eigenvector matrix A inv")
print(simplify(P.inv()))

print(simplify(P.inv() * P))

h = 1/32
v1 = Matrix([[-sqrt(h**2 - 4)/2], [1]])
v2 = Matrix([[sqrt(h**2 - 4)/2], [1]])

print(0.5*v1.norm()+0.5*v2.norm())


import math
from numba import jit

@jit(nopython=True)
def manhattan_distance(p1, p2):
    """
    Precondition: p1 and p2 are same length
    :param p1: point 1 tuple coordinate
    :param p2: point 2 tuple coordinate
    :return: manhattan distance between two points p1 and p2
    """
    distance = 0
    for dim in range(len(p1)):
        distance += abs(p1[dim] - p2[dim])
    return distance

@jit(nopython=True)
def euclidean_distance(p1, p2):
    """
    Precondition: p1 and p2 are same length
    :param p1: point 1 tuple coordinate
    :param p2: point 2 tuple coordinate
    :return: euclidean distance between two points p1 and p2
    """
    distance = 0
    for dim in range(len(p1)):
        distance += (p1[dim] - p2[dim])**2
    return math.sqrt(distance)


from sympy import *
import matplotlib.pyplot as plt
import numpy as np

# Find the area under the semicircle

x = symbols( 'x', positive = True )

S = sqrt( 1 - x**2 )
a, b, n = -1, 1, 8

def trapezoidal_rule( f, a, b, n ):
	area = 0

	steps = np.linspace( a, b, n + 1, endpoint = True )

	for i in range( 0, n + 1 ):

		v = f.subs( { x: steps[ i ] } )

		if i == 0 or i == n:
			area += .5 * v
		else:
			area += v

	return area * ( b - a ) / n

area = trapezoidal_rule( S, a, b, n )

g_xlim = [ -5, 5 ]

lam_s = lambdify( x, S, np )
x_vals = np.linspace( g_xlim[0], g_xlim[1], 1000, endpoint = True )
y_vals = lam_s( x_vals )

plt.vlines( x = a, ymin = 0, ymax = S.subs( { x: a } ), color = 'Black', zorder = 1, alpha = .4 )
plt.vlines( x = b, ymin = 0, ymax = S.subs( { x: b } ), color = 'Black', zorder = 1, alpha = .4 )

bounds = np.arange( a, b, 1/25., dtype=float)

for n in bounds:
	y = S.subs( { x: n } )
	plt.vlines( x = n, ymin = 0, ymax = y, color = 'Teal', zorder = 1, alpha = .2 )

plt.title( 'Trapezoidal Rule Area: {0}'.format( round( area, 3 ) ) )
plt.plot( x_vals, y_vals )
plt.show()


from math import log
log2= lambda x:log(x,2)
from scipy import histogram, digitize, stats, mean, std
from collections import defaultdict

def mutual_information(x,y):
    return entropy(y) - conditional_entropy(x,y)

def conditional_entropy(x, y):
    """
    x: vector de numeros reales
    y: vector de numeros enteros

    devuelve H(Y|X)
    """
    # discretizacion de X
    hx, bx= histogram(x, bins=x.size/10, density=True)

    Py= compute_distribution(y)
    Px= compute_distribution(digitize(x,bx))

    res= 0
    for ey in set(y):
        # P(X | Y)
        x1= x[y==ey]
        condPxy= compute_distribution(digitize(x1,bx))

        for k, v in condPxy.iteritems():
            res+= (v*Py[ey]*(log2(Px[k]) - log2(v*Py[ey])))
    return res

def entropy(y):
    """
    Computa la entropia de un vector discreto
    """
    # P(Y)
    Py= compute_distribution(y)
    res=0.0
    for k, v in Py.iteritems():
        res+=v*log2(v)
    return -res

def compute_distribution(v):
    """
    v: vector de valores enteros

    devuelve un diccionario con la probabilidad de cada valor
    computado como la frecuencia de ocurrencia
    """
    d= defaultdict(int)
    for e in v: d[e]+=1
    s= float(sum(d.values()))
    return dict((k, v/s) for k, v in d.items())


import numpy as np
import newton
import utils

def f(x):
    return f_2d(x[0], x[1])

def fp(x):
    y1 = np.exp(x[0]+3*x[1]-0.1) + np.exp(x[0]-3*x[1]-0.1) - np.exp(-x[0]-0.1)
    y2 = 3*np.exp(x[0]+3*x[1]-0.1) - 3*np.exp(x[0]-3*x[1]-0.1)
    return np.array([y1, y2])

def fpp(x):
    y11 = np.exp(x[0]+3*x[1]-0.1) + np.exp(x[0]-3*x[1]-0.1) + np.exp(-x[0]-0.1)
    y12 = 3*np.exp(x[0]+3*x[1]-0.1) - 3*np.exp(x[0]+3*x[1]-0.1)
    y21 = 3*np.exp(x[0]+3*x[1]-0.1) - 3*np.exp(x[0]+3*x[1]-0.1)
    y22 = 9*np.exp(x[0]+3*x[1]-0.1) + 9*np.exp(x[0]-3*x[1]-0.1)
    return np.array([[y11, y12], [y21, y22]])

def f_2d(x1, x2):
    return np.exp(x1+3*x2-0.1) + np.exp(x1 - 3*x2 - 0.1) + np.exp(-x1-0.1)

# use the value you find in HW7
f_opt = 4 * np.exp(-0.1) / np.sqrt(2)

def gap(x):
    return f(x) - f_opt

def draw_plot(x0, path):
    # Newton
    x_traces = newton.newton(fp, fpp, x0)
    f_value = f(x_traces[-1])

    print()
    print("Newton's method")
    print('  number of iterations:', len(x_traces)-1)
    print('  solution:', x_traces[-1])
    print('  value:', f_value)
    print()

    utils.plot_traces_2d(f_2d, x_traces, path+'nt_traces.png')
    utils.plot(gap, x_traces, path+'nt_gap.png')

draw_plot(np.array([-1.5, 1.0]), 'figures/1a/')
draw_plot(np.array([1.5, 1.0]), 'figures/1b/')


import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn.cluster import KMeans
from sklearn import datasets

np.random.seed(5)

iris = datasets.load_iris()
X = iris.data
y = iris.target
print(len(X))

km = KMeans(n_clusters=3,
            init='k-means++',
            n_init=10,
            max_iter=300,
            tol=1e-04,
            random_state=0)

y_km = km.fit_predict(X)

titles = ['3 clusters']
fig = plt.figure( figsize=(8, 6))
ax = Axes3D(fig, rect=[0, 0, .95, 1], elev=48, azim=134)
labels = km.labels_

for name, label in [('Setosa', 0),
                    ('Versicolour', 1),
                    ('Virginica', 2)]:
    ax.text3D(X[y == label, 3].mean(),
              X[y == label, 0].mean(),
              X[y == label, 2].mean() + 2, name,
              horizontalalignment='center',
              bbox=dict(alpha=.2, edgecolor='w', facecolor='w'))

ax.scatter(X[:, 3], X[:, 0], X[:, 2],
           c=labels.astype(np.float), edgecolor='k')
ax.scatter(km.cluster_centers_[:, 3],
            km.cluster_centers_[:, 0],
            km.cluster_centers_[:, 2],
            s=250, marker='*',
            c='red', edgecolor='black',
            label='centroids')

ax.w_xaxis.set_ticklabels([])
ax.w_yaxis.set_ticklabels([])
ax.w_zaxis.set_ticklabels([])
ax.set_xlabel('Petal width')
ax.set_ylabel('Sepal length')
ax.set_zlabel('Petal length')
ax.set_title('3 Features')
ax.dist = 12
plt.show()

plt.scatter(X[y_km == 0, 0],
            X[y_km == 0, 1],
            s=50, c='lightgreen',
            marker='s', edgecolor='black',
            label='cluster 1')
plt.scatter(X[y_km == 1, 0],
            X[y_km == 1, 1],
            s=50, c='orange',
            marker='o', edgecolor='black',
            label='cluster 2')
plt.scatter(X[y_km == 2, 0],
            X[y_km == 2, 1],
            s=50, c='lightblue',
            marker='v', edgecolor='black',
            label='cluster 3')
plt.scatter(km.cluster_centers_[:, 0],
            km.cluster_centers_[:, 1],
            s=250, marker='*',
            c='red', edgecolor='black',
            label='centroids')
plt.legend(scatterpoints=1)
plt.grid()
plt.tight_layout()
plt.title('sepal length and  sepal width')
#plt.savefig('images/11_02.png', dpi=300)
plt.show()

# 1. sepal length in cm
# 2. sepal width in cm
# 3. petal length in cm
# 4. petal width in cm

plt.scatter(X[y_km == 0, 0],
            X[y_km == 0, 2],
            s=50, c='lightgreen',
            marker='s', edgecolor='black',
            label='cluster 1')
plt.scatter(X[y_km == 1, 0],
            X[y_km == 1, 2],
            s=50, c='orange',
            marker='o', edgecolor='black',
            label='cluster 2')
plt.scatter(X[y_km == 2, 0],
            X[y_km == 2, 2],
            s=50, c='lightblue',
            marker='v', edgecolor='black',
            label='cluster 3')
plt.scatter(km.cluster_centers_[:, 0],
            km.cluster_centers_[:, 2],
            s=250, marker='*',
            c='red', edgecolor='black',
            label='centroids')
plt.legend(scatterpoints=1)
plt.grid()
plt.tight_layout()
#plt.savefig('images/11_02.png', dpi=300)
plt.title('sepal length and  petal length')
plt.show()

plt.scatter(X[y_km == 0, 1],
            X[y_km == 0, 2],
            s=50, c='lightgreen',
            marker='s', edgecolor='black',
            label='cluster 1')
plt.scatter(X[y_km == 1, 1],
            X[y_km == 1, 2],
            s=50, c='orange',
            marker='o', edgecolor='black',
            label='cluster 2')
plt.scatter(X[y_km == 2, 1],
            X[y_km == 2, 2],
            s=50, c='lightblue',
            marker='v', edgecolor='black',
            label='cluster 3')
plt.scatter(km.cluster_centers_[:, 1],
            km.cluster_centers_[:, 2],
            s=250, marker='*',
            c='red', edgecolor='black',
            label='centroids')
plt.legend(scatterpoints=1)
plt.grid()
plt.tight_layout()
#plt.savefig('images/11_02.png', dpi=300)
plt.title(' sepal width and  petal length')
plt.show()

plt.scatter(X[y_km == 0, 0],
            X[y_km == 0, 3],
            s=50, c='lightgreen',
            marker='s', edgecolor='black',
            label='cluster 1')
plt.scatter(X[y_km == 1, 0],
            X[y_km == 1, 3],
            s=50, c='orange',
            marker='o', edgecolor='black',
            label='cluster 2')
plt.scatter(X[y_km == 2, 0],
            X[y_km == 2, 3],
            s=50, c='lightblue',
            marker='v', edgecolor='black',
            label='cluster 3')
plt.scatter(km.cluster_centers_[:, 0],
            km.cluster_centers_[:, 3],
            s=250, marker='*',
            c='red', edgecolor='black',
            label='centroids')
plt.legend(scatterpoints=1)
plt.grid()
plt.tight_layout()
#plt.savefig('images/11_02.png', dpi=300)
plt.title(' sepal length and  petal width')
plt.show()

# from sklearn.decomposition import PCA
# from sklearn.cluster import KMeans
# from sklearn.datasets import load_iris
# import pylab as pl
# iris = load_iris()
# pca = PCA(n_components=2).fit(iris.data)
# pca_2d = pca.transform(iris.data)
# pl.figure('Reference Plot')
# pl.scatter(pca_2d[:, 0], pca_2d[:, 1], c=iris.target)
# kmeans = KMeans(n_clusters=3, random_state=111)
# kmeans.fit(iris.data)
# pl.figure('K-means with 3 clusters')
# pl.scatter(pca_2d[:, 0], pca_2d[:, 1], c=kmeans.labels_)
# pl.show()

print('Distortion: %.2f' % km.inertia_)
distortions = []
for i in range(1, 11):
    km = KMeans(n_clusters=i,
                init='k-means++',
                n_init=10,
                max_iter=300,
                random_state=0)
    km.fit(X)
    distortions.append(km.inertia_)
plt.plot(range(1, 11), distortions, marker='o', c='g')
plt.xlabel('Number of clusters')
plt.ylabel('Distortion')
plt.tight_layout()
#plt.savefig('images/11_03.png', dpi=300)
plt.show()

# c) Show the silhouette plots of these clusters similar to input  [9] of this  notebook.

from sklearn.metrics import silhouette_samples
from matplotlib import cm

km = KMeans(n_clusters=3,
            init='k-means++',
            n_init=10,
            max_iter=300,
            tol=1e-04,
            random_state=0)
y_km = km.fit_predict(X)

cluster_labels = np.unique(y_km)
n_clusters = cluster_labels.shape[0]
silhouette_vals = silhouette_samples(X, y_km, metric='euclidean')
y_ax_lower, y_ax_upper = 0, 0
yticks = []
for i, c in enumerate(cluster_labels):
    c_silhouette_vals = silhouette_vals[y_km == c]
    c_silhouette_vals.sort()
    y_ax_upper += len(c_silhouette_vals)
    color = cm.jet(float(i) / n_clusters)
    plt.barh(range(y_ax_lower, y_ax_upper), c_silhouette_vals, height=1.0,
             edgecolor='none', color=color)

    yticks.append((y_ax_lower + y_ax_upper) / 2.)
    y_ax_lower += len(c_silhouette_vals)

silhouette_avg = np.mean(silhouette_vals)
plt.axvline(silhouette_avg, color="red", linestyle="--")

plt.yticks(yticks, cluster_labels + 1)
plt.ylabel('Cluster')
plt.xlabel('Silhouette coefficient')

plt.tight_layout()
# plt.savefig('images/11_04.png', dpi=300)
plt.show()

# d) Show the silhouette plots of K-means with n_clusters=2, 3, and 4.
from sklearn.metrics import silhouette_samples
from matplotlib import cm

km = KMeans(n_clusters=2,
            init='k-means++',
            n_init=10,
            max_iter=300,
            tol=1e-04,
            random_state=0)
y_km = km.fit_predict(X)

cluster_labels = np.unique(y_km)
n_clusters = cluster_labels.shape[0]
silhouette_vals = silhouette_samples(X, y_km, metric='euclidean')
y_ax_lower, y_ax_upper = 0, 0
yticks = []
for i, c in enumerate(cluster_labels):
    c_silhouette_vals = silhouette_vals[y_km == c]
    c_silhouette_vals.sort()
    y_ax_upper += len(c_silhouette_vals)
    color = cm.jet(float(i) / n_clusters)
    plt.barh(range(y_ax_lower, y_ax_upper), c_silhouette_vals, height=1.0,
             edgecolor='none', color=color)

    yticks.append((y_ax_lower + y_ax_upper) / 2.)
    y_ax_lower += len(c_silhouette_vals)

silhouette_avg = np.mean(silhouette_vals)
plt.axvline(silhouette_avg, color="red", linestyle="--")

plt.yticks(yticks, cluster_labels + 1)
plt.ylabel('Cluster')
plt.xlabel('Silhouette coefficient')

plt.tight_layout()
# plt.savefig('images/11_04.png', dpi=300)
plt.show()

from sklearn.metrics import silhouette_samples
from matplotlib import cm

km = KMeans(n_clusters=3,
            init='k-means++',
            n_init=10,
            max_iter=300,
            tol=1e-04,
            random_state=0)
y_km = km.fit_predict(X)

cluster_labels = np.unique(y_km)
n_clusters = cluster_labels.shape[0]
silhouette_vals = silhouette_samples(X, y_km, metric='euclidean')
y_ax_lower, y_ax_upper = 0, 0
yticks = []
for i, c in enumerate(cluster_labels):
    c_silhouette_vals = silhouette_vals[y_km == c]
    c_silhouette_vals.sort()
    y_ax_upper += len(c_silhouette_vals)
    color = cm.jet(float(i) / n_clusters)
    plt.barh(range(y_ax_lower, y_ax_upper), c_silhouette_vals, height=1.0,
             edgecolor='none', color=color)

    yticks.append((y_ax_lower + y_ax_upper) / 2.)
    y_ax_lower += len(c_silhouette_vals)

silhouette_avg = np.mean(silhouette_vals)
plt.axvline(silhouette_avg, color="red", linestyle="--")

plt.yticks(yticks, cluster_labels + 1)
plt.ylabel('Cluster')
plt.xlabel('Silhouette coefficient')

plt.tight_layout()
# plt.savefig('images/11_04.png', dpi=300)
plt.show()

from sklearn.metrics import silhouette_samples
from matplotlib import cm

km = KMeans(n_clusters=4,
            init='k-means++',
            n_init=10,
            max_iter=300,
            tol=1e-04,
            random_state=0)
y_km = km.fit_predict(X)

cluster_labels = np.unique(y_km)
n_clusters = cluster_labels.shape[0]
silhouette_vals = silhouette_samples(X, y_km, metric='euclidean')
y_ax_lower, y_ax_upper = 0, 0
yticks = []
for i, c in enumerate(cluster_labels):
    c_silhouette_vals = silhouette_vals[y_km == c]
    c_silhouette_vals.sort()
    y_ax_upper += len(c_silhouette_vals)
    color = cm.jet(float(i) / n_clusters)
    plt.barh(range(y_ax_lower, y_ax_upper), c_silhouette_vals, height=1.0,
             edgecolor='none', color=color)

    yticks.append((y_ax_lower + y_ax_upper) / 2.)
    y_ax_lower += len(c_silhouette_vals)

silhouette_avg = np.mean(silhouette_vals)
plt.axvline(silhouette_avg, color="red", linestyle="--")

plt.yticks(yticks, cluster_labels + 1)
plt.ylabel('Cluster')
plt.xlabel('Silhouette coefficient')

plt.tight_layout()
# plt.savefig('images/11_04.png', dpi=300)
plt.show()


from numpy import array,zeros

def coeffs(x0,x1,f0,f1):
    a1= (f1-f0)/(x1-x0)
    a0 = f0
    return a0, a1

def linear_intp(x,y):
    n = len(x)
    for i in range(n-1):
        x0 = x[i]
        x1 = x[i+1]
        f0 = y[i]
        f1 = y[i+1]
        a0, a1 = coeffs(x0,x1,f0,f1)
        print("f(x) = %8.4f + %8.4f (x - %8.4f)" % (a0, a1, x0))

x = array([0, 1, 2])
y = array([1, 3, 2])
linear_intp(x,y)


import numpy as np

def genBasisVectors(phase_sectors):

    '''
    Description: Generates unit basis vectors that divide complex plane into desired number of phase sectors

    Parameters:
      phase_sectors : (int) the number of sectors you wish to divide the complex plane into

    returns: numpy array containing numpy array representations of the unit basis vectors
    '''

    if (phase_sectors == 8):

        '''

        3  2  1
         \ | /
      4 -- . -- 0
         / | \
        5  6  7

        '''

        #0 rad
        b0 = np.array([1,0], dtype = np.float64)

        #pi/4 rad
        b1 = np.array([1/np.sqrt(2),1/np.sqrt(2)], dtype = np.float64)

        #pi/2 rad
        b2 = np.array([0,1], dtype = np.float64)

        #3pi/4 rad
        b3 = np.array([-1/np.sqrt(2),1/np.sqrt(2)], dtype = np.float64)

        #pi rad
        b4 = np.array([-1,0], dtype = np.float64)

        #5pi/4 rad
        b5 = np.array([-1/np.sqrt(2),-1/np.sqrt(2)], dtype = np.float64)

        #3pi/2 rad
        b6 = np.array([0,-1], dtype = np.float64)

        #7pi/4 rad
        b7 = np.array([1/np.sqrt(2),-1/np.sqrt(2)], dtype = np.float64)

        basis_vectors = np.array([b0, b1, b2, b3, b4, b5, b6, b7])

        return basis_vectors

    else:

        print("This desired phase sector number has yet to be implemented!")
        print("You requested a phase sector number of: " + str(phase_sectors))
        return -1


import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import jaccard_similarity_score
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
from scipy import stats

plt.style.use('seaborn-poster')
x12=np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24])
x123=np.arange(1,37)
x1=np.arange(1,13)
x2=np.arange(13,25)
x3=np.arange(25,37)
x4=np.arange(37,43)

y12=np.array([25,22,24,21,19,19,21,16,22,20,22,21, 22,16,21,16,16,21,23,27,56,33,20,28])
y1=np.array([25,22,24,21,19,19,21,16,22,20,22,21])
y2=np.array([22,16,21,16,16,21,23,27,56,33,20,28])
y3=np.array([31,39,33,11,6,12,12,32,49,37,29,34])
y4=np.array([31,32,31,21,21,21])
y123=np.array([25,22,24,21,19,19,21,16,22,20,22,21, 22,16,21,16,16,21,23,27,56,33,20,28, 31,39,33,11,6,12,12,32,49,37,29,34])

z = np.polyfit(x1,y1, 1)
p = np.poly1d(z)

z2 = np.polyfit(x12,y12, 1)
p2 = np.poly1d(z2)

z3 = np.polyfit(x123,y123, 1)
p3 = np.poly1d(z3)

plt.subplot(3,2,1)
plt.plot(x1,y1,'o',label='Original Data')
plt.plot(x1,p(x1), 'k', label='Degree 3')
plt.title('Household 3',loc='center')
plt.subplot(3,2,2)
plt.plot(x2,y2,'o',label='Test Data')
plt.plot(x2,p(x2), '-ok', label='Predicted')
plt.title('Predicted Values',loc='center')
plt.legend(loc='upper right')
plt.subplot(3,2,3)
plt.plot(x12,y12,'o',label='Original Data')
plt.plot(x12,p2(x12), 'k', label='Degree 3')
plt.ylabel('kWh')
plt.subplot(3,2,4)
plt.plot(x3,y3,'o',label='Test Data')
plt.plot(x3,p2(x3), '-ok', label='Predicted')
plt.legend(loc='upper right')
plt.subplot(3,2,5)
plt.plot(x123,y123,'o',label='Original Data')
plt.plot(x123,p3(x123), 'k', label='Degree 3')
plt.xlabel('Month')
plt.subplot(3,2,6)
plt.plot(x4,y4,'o',label='Test Data')
plt.plot(x4,p3(x4), '-ok', label='Predicted')
plt.legend(loc='upper right')
plt.xlabel('Month')
plt.show()

mse =mean_squared_error(y2,p(x2))
print('MSE 1:%.16f'%mse)
mse2 =mean_squared_error(y3,p2(x3))
print('MSE 12:%.16f'%mse2)
mse3 =mean_squared_error(y4,p3(x4))
print('MSE 123:%.16f'%mse3)
avg=(mse+mse2+mse3)/3
print('Avg MSE:%.16f'%avg)

slope, intercept, r_value, p_value, std_err = stats.linregress(x1, y1)
print("r-squared1: %f" % r_value**2)
slope, intercept, r_value2, p_value, std_err = stats.linregress(x12, y12)
print("r-squared12: %f" % r_value2**2)
slope, intercept, r_value3, p_value, std_err = stats.linregress(x123, y123)
print("r-squared123: %f" % r_value3**2)


import numpy as np

class PCA:
    '''
    This class implements Principle Component Analysis.
    '''
    def __init__(self, data_points, no_components):
        '''
        This class implements Principle Component Analysis, used for
        dimensionality reduction.

        Parameters
        ----------
        data_points : numpy.array
            The dataset to perform PCA i.e. dimensionality reduction on.
        no_components : int
            Number of principle components to use.
        '''
        # Calculate covariance matrix
        covariance_matrix = (data_points.T) @ data_points;
        covariance_matrix = covariance_matrix/data_points.shape[0]

        # Perform Singular Value Decomposition on the comvariance matrix
        u, s, v = np.linalg.svd(covariance_matrix, full_matrices=True)

        # Calculate amount of variance retained
        self._retention = np.sum(s[0:no_components])/np.sum(s)

        # The transformation matrix for PCA
        self._transform = u[:, 0:no_components]

    def transform(self, data_points):
        '''
        Transforms the input dataset to lower dimensions.

        Parameters
        ----------
        data_points : numpy.array
            The input dataset.

        Returns
        -------
        transformed_data_points : numpy.array
            The transformed input.
        '''
        # Transform the datapoints using principle components
        return data_points@self._transform

    def inverse_transform(self, pca_points):
        '''
        Gets the original dataset from transformed points.

        Parameters
        ----------
        pca_points : numpy.array
            The trasformed points.

        '''
        # Transform from principle components back to approx feature
        return pca_points @ (self._transform.T)

    @property
    def retention(self):
        '''
        Returns the amount of variance retained, between 0 and 1.
        '''
        return round(self._retention, 2)


"""
 1. Black-Scholes formula for vanilla option without yield:

    c = S * N(d1) - X * exp(-rT) * N(d2)
    p = X * exp(-rT) * N(-d2) - S * N(-d1)
    where:
        d1 = (ln(S/X) + (r + vol*vol/2) * T) / (vol * sqrt(T))
        d2 = d1 - vol * sqrt(T)

    while:
        c: call option price
        P: put option price
        S: spot price (stock current price)
        X: strike price
        r: risk-free interest rate
        T: time to expiration in years
        vol: volatility of the relative price change of the underlying stock price
        N(x): the cumulative normal distribution function
        exp(x): e to the x power

    Note:
        N(x) is given by integral and has no closed-form solution, so a numerical
        approximation must be used. Here we use Hart algorithm.

********************************************************************************

 2. Black-Scholes formula for vanilla option with yield:

    c = S * exp(-qT) * N(d1) - X * exp(-rT) * N(d2)
    p = X * exp(-rT) * N(-d2) - S * exp(-qT) * N(-d1)
    where:
        d1 = (ln(S/X) + (r - q + vol*vol/2) * T) / (vol * sqrt(T))
        d2 = d1 - vol * sqrt(T)

    while:
        q: dividend yield

    Note:
        this is a more general case of formula 1, thus can be integrated easily
        with formular 1.

********************************************************************************

 3. Black-Scholes formula for option on futures:

    c = F * exp(-rT) * N(d1) - X * exp(-rT) * N(d2)
    p = X * exp(-rT) * N(-d2) - F * exp(-rT) * N(-d1)
    where:
        d1 = (ln(F/X) + (vol*vol/2) * T) / (vol * sqrt(T))
        d2 = d1 - vol * sqrt(T)

    while:
        F: future spot price

    Note:
        this is a special case of formula 2 where r == q

********************************************************************************

 4. Black-Scholes formula for FX option (currency option):

    Note:
        it is the same as formula 2 where q is risk-free rate of foreign currency rf

********************************************************************************

 5. Generalized Black-Scholes formula:

    c = S * exp(bT-rT) * N(d1) - X * exp(-rT) * N(d2)
    p = X * exp(-rT) * N(-d2) - S * exp(bT-rT) * N(-d1)

    where:
        d1 = (ln(S/X) + (b + vol*vol/2) * T) / (vol * sqrt(T))
        d2 = d1 - vol * sqrt(T)

    while:
        b: cost of carry rate
    and
        b = r           stock option model
        b = r - q       stock option model with dividend yield q
        b = 0           futures option model
        b = r = 0       margined futures option model
        b = r - rf      currency option model

********************************************************************************

 6. Put-Call Supersymmetry:

    p(S, X, T, r, b, vol) == -c(S, X, T, r, b, -vol)

    This simplifies coding. No need to code seperate formulas for put and call.
"""

from math import exp, log, sqrt

from options.functions import cdf
# from scipy.stats import norm  # much slower than cdf
from options.option import OptionType, OptionTypeError

class BlackScholesPricer:
    def get_d1_d2(self, spot, strike, expiry, vol, cost_of_carry):
        d1 = (log(spot * 1.0 / strike) + (cost_of_carry + vol ** 2 / 2) * expiry) / (vol * sqrt(expiry))
        d2 = d1 - vol * sqrt(expiry)
        return d1, d2

    def price_option(self, option, round_digit=4):
        self.product_coc_map = {'stock_option': option.rate,
                                'stock_option_with_dividend': option.rate - option.dividend,
                                'futures_option': 0,
                                'margined_futures_option': 0,
                                'currency_option': option.rate - option.dividend,
                                }
        if option.cost_of_carry is None:
            if option.product is None:
                raise Exception('Both "product" and "cost_of_carry" are None. Cannot decide "cost of carry" rate')
            elif option.product in self.product_coc_map:
                option.cost_of_carry = self.product_coc_map[option.product]
            else:
                raise Exception('Unknow product type: "{}". Cannot decide "cost of carry" rate.'.format(option.product))

        # This is the generalized Black_Scholes formula
        d1, d2 = self.get_d1_d2(option.spot, option.strike, option.expiry, option.vol, option.cost_of_carry)

        if option.type == OptionType.CALL:
            price = option.spot * exp((option.cost_of_carry - option.rate) * option.expiry) * cdf(d1) - option.strike * exp(- option.rate * option.expiry) * cdf(d2)
            # price = self.spot * exp((self.cost_of_carry - self.rate) * self.expiry) * norm.cdf(d1) - self.strike * exp(- self.rate * self.expiry) * norm.cdf(d2)
        elif option.type == OptionType.PUT:
            price = option.strike * exp(- option.rate * option.expiry) * cdf(-d2) - option.spot * exp((option.cost_of_carry - option.rate) * option.expiry) * cdf(-d1)
            # price = self.strike * exp(- self.rate * self.expiry) * norm.cdf(-d2) - self.spot * exp((self.cost_of_carry - self.rate) * self.expiry) * norm.cdf(-d1)
        else:
            raise OptionTypeError

        return round(price, round_digit)


# This script performs the mix columns stage in AES algorithm
# [[2 3 1 1],
#  [1 2 3 1],
#  [1 1 2 3],
#  [3 1 1 2]]

import numpy as np

# The algorithm for this gmul function is:
    # 0. Initialise product with 0. Prepare an eight-time loop
        # 1. If the LSB of b is set product = product XOR a
        # 2. If the MSB of a is set a = a << 1 and a = a XOR 0x11b. Otherwise, just shift a one bit to the left
        # 3. Shift b one bit to the right

def gmul(a, b):
    i = 0
    product = 0

    for i in range(8):
        if ((b & 1) == 1):
            product ^= a

        if ((a & 0x80) == 0x80):
            a = a << 1
            a = a ^ 0x11b
        else:
            a = a << 1

        b = b >> 1

    return int(product)

MixColumnMatrix = [[2, 3, 1, 1], [1, 2, 3, 1], [1, 1, 2, 3], [3, 1, 1, 2]]

R = int(input("Enter the number of rows: "))
C = int(input("Enter the number of columns: "))

print("Enter the entries in a single line (separated by space): ")

# User input of entries in a
# single line separated by space
entries = list(map(int, input().split()))
matrix = np.array(entries).reshape(R, C)

# Variables initialisation
i = 0
j = 0
k = 0
result = np.zeros((R, C))

# Iterate through rows
for i in range(len(MixColumnMatrix)):
   # Iterate through columns
   for j in range(len(matrix[0])):
       # Iterate through rows
       for k in range(len(matrix)):
           temp_a = int(gmul(MixColumnMatrix[i][k], matrix[k][j]))
           temp_b = int(result[i][j])
           temp = temp_a ^ temp_b
           result[i][j] = temp

# For printing the matrix
print(result)

# num_a = int(input("Enter number a: "))
# num_b = int(input("Enter number b: "))

# print("Product: ", gmul(num_a, num_b))


# Generates figure 6.3

from math import exp
import matplotlib.pyplot as plt
import numpy as np
from scipy.special import lambertw

XMIN = 0
XMAX = 3
YMIN = 0
YMAX = 2

def parametric_omega(gamma, other_omega):
    if gamma == 0:
        return 0
    if other_omega < gamma:
        return -gamma * lambertw(-other_omega * exp(-other_omega / gamma) / gamma, k=-1).real
    return -gamma * lambertw(-other_omega * exp(-other_omega / gamma) / gamma).real

def plot_figure1():
    # plots the left panel of figure 6.3
    plt.close()
    plt.rc('text', usetex=True)
    plt.rc('font', family='serif')
    plt.plot(xs, [(2 - x) / (2 - 1) for x in xs], color="C0")
    plt.fill_between(xs_fill_above, [(2 - x) / (2 - 1) for x in xs_fill_above], above_line, color="C0",
                     label=r"Possible $\Omega$ values", alpha=0.5)
    plt.fill_between(xs_fill_below, [(2 - x) / (2 - 1) for x in xs_fill_below], below_line, color="C0",
                     alpha=0.5)
    plt.plot(xs, [parametric_omega(1.0, x) for x in xs], label=r"$\gamma=1.0$", linestyle="dashed", color="C2")
    plt.xlim([XMIN, XMAX])
    plt.ylim([YMIN, YMAX])
    plt.xlabel(r"$\omega_{in}$", fontsize=14)
    plt.ylabel(r"$\omega_{out}$", fontsize=14)
    plt.title(r"Maximum Expected $\gamma$ Estimates, $K=2$", fontsize=14)
    plt.legend()
    plt.savefig("general_max_gamma2.pdf")

def plot_figure2():
    # plots the right panel of figure 6.3
    plt.close()
    plt.rc('text', usetex=True)
    plt.rc('font', family='serif')
    plt.plot(xs, [(3 - x) / (3 - 1) for x in xs], color="C1")
    plt.fill_between(xs_fill_above, [(3 - x) / (3 - 1) for x in xs_fill_above], above_line, color="C1",
                     label=r"Possible $\Omega$ values", alpha=0.5)
    plt.fill_between(xs_fill_below, [(3 - x) / (3 - 1) for x in xs_fill_below], below_line, color="C1",
                     alpha=0.5)
    plt.plot(xs, [parametric_omega(1.0926, x) for x in xs], label=r"$\gamma=1.0926$", linestyle="dashed", color="C3")
    plt.xlim([XMIN, XMAX])
    plt.ylim([YMIN, YMAX])
    plt.xlabel(r"$\omega_{in}$", fontsize=14)
    plt.ylabel(r"$\omega_{out}$", fontsize=14)
    plt.title(r"Maximum Expected $\gamma$ Estimates, $K=3$", fontsize=14)
    plt.legend()
    plt.savefig("general_max_gamma3.pdf")

if __name__ == "__main__":
    xs = np.linspace(XMIN, XMAX, 500)
    xs_fill_above = np.linspace(XMIN, 1, len(xs))
    xs_fill_below = np.linspace(1, XMAX, len(xs))
    below_line = [YMIN] * len(xs)
    above_line = [YMAX] * len(xs)

    plot_figure1()
    plot_figure2()


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time     : 2018/12/27 09:54
# @Author   : Iydon
# @File     : course8.3.py

import Poly
import sympy as sp

def least_square_poly(x, y, a, b, n, sympy, Poly, display=False):
    A  = sympy.zeros(n+1)
    b_ = sympy.zeros(n+1,1)
    for i in range(n+1):
        for j in range(n+1):
            A[i,j] = sympy.integrate(x**(i+j), (x,a,b))
        b_[i] = sympy.integrate(x**i*y, (x,a,b))
    x = A**-1 * b_
    f = Poly.Poly(x.T.tolist()[0][::-1])
    if display:
        print(A)
        print(b_.T)
        print(x.T)
    return f

x = sp.symbols("x")
y = sp.exp(x)
result = least_square_poly(x, y, 0, 2, 1, sp, Poly, display=True)
print(result)


import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import beta

def plot(a, b, trial, ctr):
  x = np.linspace(0, 1, 200)
  y = beta.pdf(x, a, b)
  mean = float(a) / (a + b)
  plt.plot(x, y)
  plt.title("Distributions after %s trials, true rate = %.1f, mean = %.2f" % (trial, ctr, mean))
  plt.show()

true_ctr = 0.3
a, b = 1, 1 # beta parameters
show = [0, 5, 10, 25, 50, 100, 200, 300, 500, 700, 1000, 1500]
for t in range(1501):
  coin_toss_result = (np.random.random() < true_ctr)
  if coin_toss_result:
    a += 1
  else:
    b += 1

  if t in show:
    plot(a, b, t+1, true_ctr)


import matplotlib.pyplot as plt
import numpy as np

def sigmoid(z):
    return 1.0 / (1.0 + np.exp(-z))

def cost(y, z):
    return -y*np.log(sigmoid(z)) - (1-y)*np.log(1 - sigmoid(z))

def cost_1(z):
    return cost(1, z)

def cost_0(z):
    return cost(0, z)

## sigmoid ##
z = np.arange(-7, 7, 0.1)
phi_z = sigmoid(z)

plt.plot(z, phi_z)
plt.axvline(0.0, color='k')
plt.ylim(-0.1, 1.1)
plt.xlabel('z')
plt.ylabel('$\phi (z)$')

# y axis ticks and gridline
plt.yticks([0.0, 0.5, 1.0])
ax = plt.gca()
ax.yaxis.grid(True)

## cost ##

plt.tight_layout()
plt.show()

z = np.arange(-10, 10, 0.1)
phi_z = sigmoid(z)

c1 = [cost_1(x) for x in z]
plt.plot(phi_z, c1, label='J(w) if y=1')

c0 = [cost_0(x) for x in z]
plt.plot(phi_z, c0, linestyle='--', label='J(w) if y=0')

plt.ylim(0.0, 5.1)
plt.xlim([0, 1])
plt.xlabel('$\phi$(z)')
plt.ylabel('J(w)')
plt.legend(loc='best')
plt.tight_layout()
plt.show()


#!/usr/bin/env python3.6
# Includes multiple activation functions and their derivatives
import numpy as np

def sigmoid(z):
    return 1.0 / (1.0 + np.exp(-z))

def sigmoid_prime(z):
    return sigmoid(z) * (1 - sigmoid(z))

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

def softmax_prime(z):
    return softmax(z) * (1 - softmax(z))

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

def tanh_prime(z):
    return 1 - tanh(z) * tanh(z)

def relu(z):
    return np.maximum(z, 0)

def relu_prime(z):
    return float(z > 0)

def get_prime_function(function):
    if function == sigmoid:
        return sigmoid_prime
    elif function == softmax:
        return softmax_prime
    elif function == tanh:
        return tanh_prime
    elif function == relu:
        return relu_prime


#call numpy package
import numpy as np

#input data
x = [77, 50, 99, 60, 90, 82, 93, 75, 86, 99, 55, 79]

#numpy.mean(), sum() and len() methods
get_population_mean = np.sum(x) / (len(x))

print("Input : ", x)
print("Population mean of x : ", get_population_mean)


#!/usr/bin/env python3
from math import cos, pi, sin
from numpy import linspace

# several s-waves, all in normalized units for x (0,0 to 1,1)
def sinusoid(t):
	# normalized sinusoid
	x = .5 - .5*cos(pi*t)
	v = .5*pi*sin(pi*t)
	a = .5*pi**2*cos(pi*t)
	return x, v, a

def min_jerk(npoints):
	# lowest order polynomial that has an s curve with zero velocity and acceleration at start and end
	x = 10 * t**3 -  15 * t**4  +  6 * t**5
	v = 30 * t**2 -  60 * t**3  + 30 * t**4
	a = 60 * t    - 180 * t**2 + 120 * t**3
	return x, v, a

def rsinusoid(t):
	# lowest order polynomial that has an s curve with zero velocity at start and end
	# and zero acceleration at start, and -pi**2/2 acceleration at end
	x =   (40-pi**2)/4 * t**3 +    (pi**2-30)/2 * t**4 +   (24-pi**2)/4  * t**5
	v = 3*(40-pi**2)/4 * t**2 +  4*(pi**2-30)/2 * t**3 +  5*(24-pi**2)/4 * t**4
	a = 6*(40-pi**2)/4 * t    + 12*(pi**2-30)/2 * t**2 + 20*(24-pi**2)/4 * t**3
	return x, v, a

for t in linspace(0, 1, 100):
	print("{:.6f}".format(t), end="")
	print("\t{:.6f}\t{:.6f}\t{:.6f}".format(*sinusoid(t)), end="")
	print("\t{:.6f}\t{:.6f}\t{:.6f}".format(*min_jerk(t)), end="")
	print("\t{:.6f}\t{:.6f}\t{:.6f}".format(*rsinusoid(t)), end="")
	print()
	#gnuplot:
	# plot "tt.dat" u 1:2 w l lw 3 t "sinusoid" , "tt.dat" u 1:5 w l lw 3 t "minjerk", "tt.dat" u 1:8 w l lw 3 t "rsinusoid"


import numpy as np
from scipy.optimize import approx_fprime

def joint_limits(q):
    """ Joint limits objective function

    Calculate the cost of the current joint configuration from the lower
    and upper bounds of the joints

    :param q: Joint position of the robot
    type q: numpy.ndarray
    :return: Cost of the current configuration
    :type: float
    """

    q_min = np.array([-180.0, -128.9, -180.0, -147.8, -180.0, -120.3, -180.0]) * np.pi / 180.0
    q_max = np.array([180.0, 128.9, 180.0, 147.8, 180.0, 120.3, 180.0]) * np.pi / 180.0

    q_bar = (q_min + q_max) / 2

    return (-1 / (2 * q.shape[0])) * np.sum(((q - q_bar) / (q_max - q_min)) ** 2)

def joint_limits_gradient(q):
    """ Gradient of the joint limits objective function

    Calculate the first derivative of the joint limits objective
    function with respect to all joint variables

    :param q: Joint position of the robot
    :type q: numpy.ndarray
    :return: Gradient vector for the joint limits objective function
    :type: numpy.ndarray
    """

    return approx_fprime(q, joint_limits, np.sqrt(np.finfo(float).eps))


import numpy as np

#load some logits directly from the first iteration of the model
#and ensure the the IBP parameters are calibrated correctly

def test_IBP(hists,M,eps=None,weights=None,niter=100,tol=1e-6):
    """
    Calculates the barycentre of a set of histograms using
    the iterative bregman projection approach detailed in the paper
    Benamou et al.

    Parameters
    -----------
    hists : array (d x n) [n histograms of coming from the d simplex]
    M : array (d x d) [ground metric, please normalise with median of metric]
    eps : float [regularisation parameter 2/d is a natural choice]
    weights : array [if None then set as isometric by default]
    niter : int [maximum number of iterations to run IBP]
    tol : float [tolerance for convergance]
    """

    d = hists.shape[0] #dimension of hists [i.e size of space]
    n = hists.shape[1] #number of hists

    if eps is None:
        eps = 2/d

    #define the kernel
    K = np.exp(-M/eps)
    #numerical trick seen in gpeyre implementation
    K[K<1e-300]=1e-300

    counter = 0
    diff = np.inf

    if weights is None:
        weights = np.ones(n)/n

    #initialise u0 v0 as ones
    v,u = (np.ones((d,n)),np.ones((d,n)))
    uKv = u*(K@v)
    #weighted log of uKv
    wloguKv = weights*np.log(uKv)

    #prod uKv^weights = exp( sum {weights*log(uKv)})
    bary  = np.exp(wloguKv.sum(axis=1)).reshape(-1,1)
    prev_bary = np.copy(bary)

    for i in range(1,niter):
        #update v
        v = hists / (K.T@u)
        #update barycentre
        uKv = u*(K@v)
        wloguKv = weights*np.log(uKv)
        #prod uKv**weights = exp( sum weights*log(uKv))
        bary  = np.exp(wloguKv.sum(axis=1)).reshape(-1,1)
        if i%10 ==0:
            if np.sum(bary-prev_bary)<tol:
            	print(f"IBP has been terminated at iteration {i}")
            	return bary
        prev_bary =np.copy(bary)
        #update u
        u = bary / (K@v)

    return bary

hists = np.load("tests/q_aug.npy")
M  = np.load("groundmetrics/nm-cifar10.npy")

#just for the kth index
k = np.random.randint(0,len(hists))

#give loads of its
unlim = test_IBP(hists[k],M,niter=10000,tol=1e-16)
lim  = test_IBP(hists[k],M,niter=100,tol=1e-5)

print(np.sum(lim-unlim))


import numpy as np
from numpy import linalg as la
from matplotlib import pyplot as plt
import bisection as bis
class Newton():

    def descent(self, alpha = 1, X = np.array([[0.0],[0.0]]), precision = 10**-6):
        self.Xs = []       # Candidates
        self.Xs.append(X)  # First Candidate (x0)
        self.precision = precision
        H = self.modify(self.hessiana())    # Initial hessiana
        d = - np.dot(la.inv(H), self.gradF(X))  # Initial direction
        self.alpha = bis.getAlpha(self.Xs[-1], d)

        while la.norm(d) > self.precision:
            X = X + alpha*d
            self.Xs.append(X)
            X = self.Xs[-1]
            H = self.modify(self.hessiana())
            d = - np.dot(la.inv(H), self.gradF(X))

        return self.Xs[-1]

    def r(self, X):
        x1 = X[0][0]
        x2 = X[1][0]

        return np.array([[4*(x1 - 2)], [4*(x2 - 3)]])

    ''' Builds the matrix of gradient of r(x)'''
    def buildGradientR(self):   # TODO: Transform function in CONSTANT
        return np.array([[4, 0],
                         [0, 4]])

    def gradF(self, X):
        x1 = X[0][0]
        x2 = X[1][0]

        return np.array([[4*(x1 - 2)],[4*(x2 - 3)]])

    ''' Second gradient of partial derivatives of f(x)'''
    def hessiana(self):
        hess = np.array([[4, 0], [0, 4]])

        return hess

    def getEigenvalue(self, H):
        eigs = la.eigvals(H)
        return min(eigs)

    ''' ModifiedNewton '''
    def modify(self, H):
        epsilon = 0.01
        e = self.getEigenvalue(H)
        if(e > 0):
            return H
        else:
            M = H + (epsilon - e) * np.identity(2)

    def plot(self, title, xlabel, ylabel):
        x1s = []
        x2s = []

        for X in self.Xs:
            x1s.append(X[0][0])
            x2s.append(X[1][0])

        plt.plot(x1s, x2s, 'ro')
        plt.title(title)
        plt.xlabel(xlabel)
        plt.ylabel(ylabel)
        plt.show()


import matplotlib.pyplot as plt
import numpy as np
from scipy import linalg
import time

def power_iteration(A, max_iters, epsilon):
    eigvec = np.random.rand(A.shape[0])

    for _ in range(max_iters):
        new_eigvec = np.dot(A, eigvec)
        new_eigvec_norm = np.linalg.norm(new_eigvec)
        new_eigvec /= new_eigvec_norm
        if np.linalg.norm(new_eigvec - eigvec) < epsilon:
            break
        else:
            eigvec = np.transpose(new_eigvec) * A * new_eigvec

    eigval = np.max(np.abs(eigvec))
    eigvec /= np.linalg.norm(eigvec, axis=0)
    return eigvec, eigval

def calculate_and_plot_power_iterations():
    xs = []
    ys = []
    for k in range(100, 2000, 100):
        A = np.random.rand(k, k)
        A = A * np.transpose(A)
        start_time = time.time_ns()
        eigvec, eigval = power_iteration(A, 10000, 1e-9)
        end_time = time.time_ns()
        calc_time = end_time - start_time
        #m = A.shape[0]
        #lib_eigval, lib_eigvec = eigh(A, eigvals=(m-1, m-1))
        #lib_eigvec = np.transpose(lib_eigvec)[0]
        xs.append(k)
        ys.append(calc_time)
    plt.plot(xs, ys)
    plt.show()

def inverse_power_iteration(A, u, max_iters, epsilon):
    v0 = np.identity(A.shape[0])[0]
    AuI = A - u*np.identity(A.shape[0])
    lupiv = linalg.lu_factor(AuI)
    for i in range(max_iters):
        v = v0
        w = linalg.lu_solve(lupiv, v)
        v = w / np.linalg.norm(w)
        if np.linalg.norm(v-v0) < epsilon or np.linalg.norm(v+v0) < epsilon:
            print("Iterations: " + str(i))
            return u, v
        u = v.T @ A @ v
        v0 = v

A = np.random.rand(100, 100)
A = A * np.transpose(A)
eigvec, eigval = inverse_power_iteration(A, 0, 1000, 1e-5)
eigvec2, eigval2 = inverse_power_iteration(A, 10, 1000, 1e-5)
eigvec3, eigval3 = inverse_power_iteration(A, 50, 1000, 1e-5)


import numpy as np
import copy

import check_test
from frozenlake import FrozenLakeEnv
from plot_utils import plot_values
env = FrozenLakeEnv()
# print the state space and action space
print(env.observation_space)
print(env.action_space)

# print the total number of states and actions
print(env.nS)
print(env.nA)
env.P[1][0]
def policy_evaluation(env, policy, gamma=1, theta=1e-8):
    V = np.zeros(env.nS)
    while True:
        delta = 0
        for s in range(env.nS):
            Vs = 0
            for a, action_prob in enumerate(policy[s]):
                for prob, next_state, reward, done in env.P[s][a]:
                    Vs += action_prob * prob * (reward + gamma * V[next_state])
            delta = max(delta, np.abs(V[s]-Vs))
            V[s] = Vs
        if delta < theta:
            break
    return V
random_policy = np.ones([env.nS, env.nA]) / env.nA
# evaluate the policy
V = policy_evaluation(env, random_policy)

plot_values(V)
check_test.run_check('policy_evaluation_check', policy_evaluation)
def q_from_v(env, V, s, gamma=1):
    q = np.zeros(env.nA)
    for a in range(env.nA):
        for prob, next_state, reward, done in env.P[s][a]:
            q[a] += prob * (reward + gamma * V[next_state])
    return q
Q = np.zeros([env.nS, env.nA])
for s in range(env.nS):
    Q[s] = q_from_v(env, V, s)
print("Action-Value Function:")
print(Q)
check_test.run_check('q_from_v_check', q_from_v)
def policy_improvement(env, V, gamma=1):
    policy = np.zeros([env.nS, env.nA]) / env.nA
    for s in range(env.nS):
        q = q_from_v(env, V, s, gamma)

        # OPTION 1: construct a deterministic policy
        # policy[s][np.argmax(q)] = 1

        # OPTION 2: construct a stochastic policy that puts equal probability on maximizing actions
        best_a = np.argwhere(q==np.max(q)).flatten()
        policy[s] = np.sum([np.eye(env.nA)[i] for i in best_a], axis=0)/len(best_a)

    return policy
check_test.run_check('policy_improvement_check', policy_improvement)
def policy_iteration(env, gamma=1, theta=1e-8):
    policy = np.ones([env.nS, env.nA]) / env.nA
    while True:
        V = policy_evaluation(env, policy, gamma, theta)
        new_policy = policy_improvement(env, V)

        # OPTION 1: stop if the policy is unchanged after an improvement step
        if (new_policy == policy).all():
            break;

        # OPTION 2: stop if the value function estimates for successive policies has converged
        # if np.max(abs(policy_evaluation(env, policy) - policy_evaluation(env, new_policy))) < theta*1e2:
        #    break;

        policy = copy.copy(new_policy)
    return policy, V
# obtain the optimal policy and optimal state-value function
policy_pi, V_pi = policy_iteration(env)

# print the optimal policy
print("\nOptimal Policy (LEFT = 0, DOWN = 1, RIGHT = 2, UP = 3):")
print(policy_pi,"\n")

plot_values(V_pi)
check_test.run_check('policy_iteration_check', policy_iteration)
def truncated_policy_evaluation(env, policy, V, max_it=1, gamma=1):
    num_it=0
    while num_it < max_it:
        for s in range(env.nS):
            v = 0
            q = q_from_v(env, V, s, gamma)
            for a, action_prob in enumerate(policy[s]):
                v += action_prob * q[a]
            V[s] = v
        num_it += 1
    return V
def truncated_policy_iteration(env, max_it=1, gamma=1, theta=1e-8):
    V = np.zeros(env.nS)
    policy = np.zeros([env.nS, env.nA]) / env.nA
    while True:
        policy = policy_improvement(env, V)
        old_V = copy.copy(V)
        V = truncated_policy_evaluation(env, policy, V, max_it, gamma)
        if max(abs(V-old_V)) < theta:
            break;
    return policy, V
policy_tpi, V_tpi = truncated_policy_iteration(env, max_it=2)

# print the optimal policy
print("\nOptimal Policy (LEFT = 0, DOWN = 1, RIGHT = 2, UP = 3):")
print(policy_tpi,"\n")

# plot the optimal state-value function
plot_values(V_tpi)
check_test.run_check('truncated_policy_iteration_check', truncated_policy_iteration)
def value_iteration(env, gamma=1, theta=1e-8):
    V = np.zeros(env.nS)
    while True:
        delta = 0
        for s in range(env.nS):
            v = V[s]
            V[s] = max(q_from_v(env, V, s, gamma))
            delta = max(delta,abs(V[s]-v))
        if delta < theta:
            break
    policy = policy_improvement(env, V, gamma)
    return policy, V
policy_vi, V_vi = value_iteration(env)

# print the optimal policy
print("\nOptimal Policy (LEFT = 0, DOWN = 1, RIGHT = 2, UP = 3):")
print(policy_vi,"\n")

# plot the optimal state-value function
plot_values(V_vi)
check_test.run_check('value_iteration_check', value_iteration)


"""
Test suite for matrix approximation
"""
import numpy as np
from descent import algorithms
from descent.proxops import nucnorm

def generate_lowrank_matrix(n=10, m=20, k=3, eta=0.05, seed=1234):
    """
    Generate an n-by-m noisy low-rank matrix

    """
    print("Generating data for low rank matrix approximation")
    global Xtrue, Xobs

    # define the seed
    np.random.seed(seed)

    # the true low-rank matrix
    Xtrue = np.sin(np.linspace(0, 2 * np.pi, n)).reshape(-1, 1).dot(
        np.cos(np.linspace(0, 2 * np.pi, m)).reshape(1, -1))

    # the noisy, observed matrix
    Xobs = Xtrue + eta * np.random.randn(n, m)

    return Xobs, Xtrue

def test_lowrank_matrix_approx():
    """
    Test low rank matrix approximation

    """

    Xobs, Xtrue = generate_lowrank_matrix()

    # helper function to test relative error of given parameters
    def test_error(Xhat):
        test_err = np.linalg.norm(Xhat - Xtrue, 'fro')
        naive_err = np.linalg.norm(Xobs - Xtrue, 'fro')
        err_ratio = test_err / naive_err
        assert err_ratio <= 0.5

    # Proximal gradient descent and Accelerated proximal gradient descent
    for algorithm in ['sgd', 'nag']:

        # objective
        def f_df(X):
            grad = X - Xtrue
            obj = 0.5 * np.linalg.norm(grad.ravel()) ** 2
            return obj, grad

        # optimizer
        opt = getattr(algorithms, algorithm)(lr=5e-3)
        opt.operators.append(nucnorm(0.2))

        # run it
        res = opt.minimize(f_df, Xobs, maxiter=5000, display=None)

        # test
        test_error(res.x)


import numpy as np

class NMF(object):
    '''
    A Non-Negative Matrix Factorization (NMF) model using the Alternating Least
    Squares (ALS) algorithm.

    This class represents an NMF model, which is a useful unsupervised data
    mining tool; e.g. for finding latent topics in a text corpus such as NYT
    articles.
    '''

    def __init__(self, k, max_iters=50, alpha=0.5, eps=1e-6):
        '''
        Constructs an NMF object which will mine for `k` latent topics.
        The `max_iters` parameter gives the maximum number of ALS iterations
        to perform. The `alpha` parameter is the learning rate, it should range
        in (0.0, 1.0]. `alpha` near 0.0 causes the model parameters to be
        learned slowly over many many ALS iterations, while an alpha near 1.0
        causes model parameters to be fit quickly over very few ALS iterations.
        '''
        self.k = k
        self.max_iters = max_iters
        self.alpha = alpha
        self.eps = eps

    def _fit_one(self, V):
        '''
        Do one ALS iteration. This method updates self.H and self.W
        and returns None.
        '''
        # Fit H while holding W constant:
        H_new = np.linalg.lstsq(self.W, V, rcond=None)[0].clip(min=self.eps)
        self.H = self.H * (1.0 - self.alpha) + H_new * self.alpha

        # Fit W while holding H constant:
        W_new = np.linalg.lstsq(self.H.T, V.T, rcond=None)[0].T.clip(min=self.eps)
        self.W = self.W * (1.0 - self.alpha) + W_new * self.alpha

    def fit(self, V, verbose = False):
        '''
        Do many ALS iterations to factorize `V` into matrices `W` and `H`.

        Let `V` be a matrix (`n` x `m`) where each row is an observation
        and each column is a feature. `V` will be factorized into a the matrix
        `W` (`n` x `k`) and the matrix `H` (`k` x `m`) such that `WH` approximates
        `V`.

        This method returns the tuple (W, H); `W` and `H` are each ndarrays.
        '''
        n, m = V.shape
        self.W = np.random.uniform(low=0.0, high=1.0 / self.k, size=(n, self.k))
        self.H = np.random.uniform(low=0.0, high=1.0 / self.k, size=(self.k, m))
        for i in range(self.max_iters):
            if verbose:
                print('iter', i, ': reconstruction error:', self.reconstruction_error(V))
            self._fit_one(V)
        if verbose:
            print('FINAL reconstruction error:', self.reconstruction_error(V), '\n')
        return self.W, self.H

    def reconstruction_error(self, V):
        '''
        Compute and return the reconstruction error of `V` as the
        matrix L2-norm of the residual matrix.
        See: https://en.wikipedia.org/wiki/Matrix_norm
        See: https://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.norm.html
        '''
        return np.linalg.norm(V - self.W.dot(self.H))