# kNN Implemenation
import numpy as np
from collections import Counter

min_val = []
max_val= []

def classifyPoint(InX , dataSet , labels , k):

        Distances = []
        for X in dataSet:
            Distances.append(distanceCal(InX , X))
        finLabelInd = np.array(Distances).argsort()
        kNN = []
        for a in range(k):
            kNN.append(labels[finLabelInd[a]])
        return Counter(kNN).most_common()[0][0]

def distanceCal(inX , currX):

    x =  (inX[0] - currX[0]) * (inX[0] - currX[0]) + (inX[1] - currX[1]) *  (inX[1] - currX[1]) + (inX[2] - currX[2]) * (inX[2] - currX[2])
    return np.sqrt(np.abs(x))

def normalizeData(Data):
    global min_val
    global max_val
    min_val = Data.min(0)
    max_val = Data.max(0)
    for a in Data:
        for b in range(len(a)):
            a[b] = (a[b] - min_val[b]) / (max_val[b] - min_val[b]);
    return Data

def Matrix(filename):
    file = open(filename, "r")
    numLines = len(file.readlines())
    label = []
    lines = []
    file.close()

    file = open(filename, "r")
    for a in range(numLines):
        temp = file.readline().strip().split("\t")
        lines.append(temp[:3])
        label.append(temp[3])
    lines = np.array(lines).astype(float)
    return normalizeData(lines), label
#

def train_test_split(X , y , test_size):
    return X[:int((1-test_size)*len(X)) , :] , y[:int((1-test_size)*len(y))] , X[int((1-test_size)*len(X)): , :] , y[int((1-test_size)*len(y)):]

def trainNtest(xtr , ytr , xts , yts):
    success = 0
    for pts, ind in zip(xts , range(len(xtr))):
        if classifyPoint(pts[:3], xtr[: , :3] , ytr , 10) == yts[ind]:
             success += 1
        if 1:
            print("Pre:", classifyPoint(pts[:3], xtr[:, :3], ytr, 10), "Ans:", yts[ind])
    print("Error: " , (100 - (success*100)/len(yts)) , "%")

#End

def normalInput(Input):
    for a , ind in zip(Input , range(len(Input))):
        Input[ind] = (a - min_val[ind])/(max_val[ind] - min_val[ind])
    return np.array(Input)
def isMyMate(Data , label):
    amt = float(input("His income per m: "))
    game = float(input("Percent of time on Gaming: "))
    ice = float(input("Ice cream consumed (in Litres): "))
    nmip =  normalInput(np.array([amt, game, ice]))
    print("----------Result----------")
    res = classifyPoint(nmip, Data, label, 5)
    print("You might" , res)
    return res


import os
from math import pi

import numpy as np

from fda.zernike_annular_polynomial import ZernikeAnnularSingle as ZernikeAnnular
from fda.zernike_circular_polynomial import ZernikeCircularSingle as ZernikeCircular

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

# extension of numpy arrays
ext = "npy"

# mfs matrices path
mfs_path = "./encoding/mfs"

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

def ComputeMfCircular(width, height, order):
    # creating mf matrix name
    mf_name = get_mf_circ_name(width, height, order)
    mf_path = "%s/%s.%s" % (mfs_path, mf_name, ext)

    # if already computed, then return it
    if exists_mf(mf_path):
        return np.load(mf_path)

    # computing size
    size = width * height

    #creating mf matrix (size x order)
    Mf = np.empty((size, order), np.float64)

    ub = order + 1
    for j in range(1, ub):
        Mv = FillRectCircular(width, height, order)
        Vv = Mv.reshape((size,))
        Mf[:, j - 1] = Vv

    # saving the computed Mf matrix
    np.save(mf_path, Mf)

    #returning the Mf matrix
    return Mf

def ComputeMfAnnular(width, height, order, eps_lb, eps_ub):
    # creating mf matrix name
    mf_name = get_mf_annu_name(width, height, order, eps_lb, eps_ub)
    mf_path = "%s/%s.%s" % (mfs_path, mf_name, ext)

    # if already computed, then return it
    if exists_mf(mf_path):
        return np.load(mf_path)

    # computing size
    size = width * height

    #creating mf matrix (size x order)
    Mf = np.empty((size, order), np.float64)

    ub = order + 1
    for j in range(1, ub):
        Mv = FillRectAnnular(width, height, j, eps_lb, eps_ub)
        Vv = Mv.reshape((size,))
        Mf[:, j - 1] = Vv

    # saving the computed Mf matrix
    np.save(mf_path, Mf)

    #returning the Mf matrix
    return Mf

def FillRectCircular(width, height, order):
    # computing iris ring radius
    i_radius = 1.0  # unitary disk

    # computing deltha of radius (amount to add to the radius)
    dr = i_radius // height

    # creating rectangle
    rect = np.empty((height, width), np.float64)

    for a in range(width):
        # computing theta
        theta = a * (2 * pi) / width

        for r in range(height):
            # computing rho
            rho = dr + r * dr

            # # saving value of zernike circular polynomial in rect
            rect[r, a] = ZernikeCircular(order, rho, theta)

    return rect

def FillRectAnnular(width, height, order, eps_lb, eps_ub):
    # computing iris ring radius
    i_radius = eps_ub - eps_lb

    # computing deltha of radius (amount to add to the radius)
    dr = i_radius // (height - 1)

    # creating rectangle
    rect = np.empty((height, width), np.float64)

    for a in range(width):
        # computing theta
        theta = a * (2 * pi) / width
        for r in range(height):
            # computing rho
            rho = eps_lb + r * dr

            # saving value of zernike annular polynomial in rect
            rect[r, a] = ZernikeAnnular(order, rho, theta, eps_lb, eps_ub)

    # returning the evaluated rectangle
    return rect

def exists_mf(mf_path):
    return os.access(mf_path, os.F_OK)

def get_mf_circ_name(width, height, order):
    return "%i_%i_%i" % (width, height, order)

def get_mf_annu_name(width, height, order, eps_lb, eps_ub):
    return "%i_%i_%i_%.2f_%.2f" % (width, height, order, eps_lb, eps_ub)


## Delevoped by Leonardo Rydin Gorjão and Pedro G. Lind.

from sympy import bell, symbols, factorial, simplify

def m_formula(power, tau = True):
    r"""
    Generate the formula for the conditional moments with second-order
    corrections based on the relation with the ordinary Bell polynomials

    .. math::

        M_n(x^{\prime},\tau) \sim (n!)\tau D_n(x^{\prime}) + \frac{(n!)\tau^2}{2}
        \sum_{m=1}^{n-1}   D_m(x^{\prime})  D_{n-m}(x^{\prime})

    Parameters
    ----------
    power: int
        Desired order of the formula.

    Returns
    -------
    term: sympy.symbols
        Expression up to given ``power``.
    """
    init_sym = symbols('D:'+str(int(power+1)))[1:]
    sym = ()
    for i in range(1,power + 1):
        sym += (factorial(i)*init_sym[i-1],)

    if tau == True:
        t = symbols('tau')

        term = t*bell(power, 1, sym) + t**2*bell(power, 2, sym)

    else:
        term = bell(power, 1, sym) + bell(power, 2, sym)

    return term

def f_formula(power):
    r"""
    Generate the formula for the conditional moments with second-order
    corrections based on the relation with the ordinary Bell polynomials

    .. math::

        D_n(x) &=  \frac{1}{\tau (n!)} \bigg[ \hat{B}_{n,1}
        \left(M_1(x,\tau),M_2(x,\tau),\ldots,M_{n}(x,\tau)\right) \\
        &\qquad  \left.-\frac{\tau}{2} \hat{B}_{n,2}
        \left(M_1(x,\tau),M_2(x,\tau),\ldots,M_{n-1}(x,\tau)\right)\right].

    Parameters
    ----------
    power: int
        Desired order of the formula.

    Returns
    -------
    term: sympy.symbols
        Expression up to given ``power``.
    """

    init_sym = symbols('D:'+str(int(power+1)))[1:]
    sym = ()
    for i in range(1,power + 1):
        sym += (factorial(i)*init_sym[i-1],)

    term = (symbols('M'+str(int(power))) - bell(power, 2, sym))/factorial(power)

    return term

def f_formula_solver(power):
    r"""
    Generate the reciprocal relation of the moments to the Kramers─Moyal
    coefficients by sequential iteration.

    .. math::

        D_n(x) &=  \frac{1}{\tau (n!)} \bigg[ \hat{B}_{n,1}
        \left(M_1(x,\tau),M_2(x,\tau),\ldots,M_{n}(x,\tau)\right) \\
        &\qquad  \left.-\frac{\tau}{2} \hat{B}_{n,2}
        \left(M_1(x,\tau),M_2(x,\tau),\ldots,M_{n-1}(x,\tau)\right)\right].

    Parameters
    ----------
    power: int
        Desired order of the formula.

    Returns
    -------
    term: sympy.symbols
        Expression up to given ``power``.
    """
    power = power + 1
    terms_to_sub = []
    for i in range(1, power):
        terms_to_sub += [f_formula(i)]
        for j in range(i):
            terms_to_sub[i-1] = terms_to_sub[i-1].subs('D'+str(j+1),terms_to_sub[j])

    # for i in range
    # term = (symbols('M'+str(int(power))) + bell(power, 2, sym))/factorial(power)

    return (terms_to_sub[power-2]*factorial(power-1)).expand(basic = True)


import numpy as np
import csv

'''
Geometric Brownian Motion
Describe as dS = uS dt + oS dW(t)

Where:
S is the stock price
u is the drift coefficient
o is the diffusion coefficient
W(t) is the Brownian Motion

"drift coefficient" represents the mean of returns over X period
"diffusion coefficient" represents the standard deviation of those returns

W(t) is the random portion of the equation.
Each Brownian Increment - W(i) - is computed as:

Standard random variable - z(i) - from a normal distribution - N(0,1) - With mean 0 and standard deviation 1
multiplied by square root of the time increment - SQR[delta t(i)]
'''

def Brownian(seed, N):
    np.random.seed(seed)
    dt = 1. / N
    b = np.random.normal(0., 1., int(N)) * np.sqrt(dt)
    W = np.cumsum(b)
    return W, b

def GBM(So, mu, sigma, W, T, N):
    t = np.linspace(0., 1., int(N) + 1)
    S = []
    S.append(So)
    for i in range(1,int(N+1)):
        drift = (mu - 0.5 * sigma**2) * t[i]
        diffusion = sigma * W[i-1]
        S_temp = So*np.exp(drift + diffusion)
        S.append(S_temp)
    return S, t

def daily_return(adj_close):
    returns = []
    for i in range(0, len(adj_close)-1):
        today = adj_close[i+1]
        yesterday = adj_close[i]
        daily_return = (today - yesterday)/yesterday
        returns.append(daily_return)
    return returns

def EM(So, mu, sigma, b, T, N, M):
    dt = M * (1/N)  # EM step size
    L = N / M
    wi = [So]
    for i in range(0,int(L)):
        Winc = np.sum(b[(M*(i-1)+M):(M*i + M)])
        w_i_new = wi[i]+mu*wi[i]*dt+sigma*wi[i]*Winc
        wi.append(w_i_new)
    return wi, dt

'''
Closed-form solution of GMB (using stocks)
S(t) = So e^(mu-[1/2]o^2) t + oW(t)

So:     initial stock price
mu:     returns (drift coefficient)
sigma:  volatility (diffusion coefficient)
W:      brownian motion
T:      time period
N:      number of increments

'''

seed = 22
N = 2.**8
T = 1.

#start = '2017-01-01'
#end = '2017-12-31'
#df = quandl.get('WIKI/AMZN', start_date = start, end_date = end)
#adj_close = df['Adj. Close']

adv_perf = []
mod_perf = []
cau_perf = []

new = True
with open('Performance.csv','r') as csvfile:
    reader = csv.reader(csvfile, delimiter=',', quotechar='|')
    for row in reader:
        if(new == True):
            new = False
        else:
            adv_perf.append(float(row[0]))
            mod_perf.append(float(row[1]))
            cau_perf.append(float(row[2]))

So_a = adv_perf[0]
So_m = mod_perf[0]
So_c = cau_perf[0]

returns_a = daily_return(adv_perf)
returns_b = daily_return(mod_perf)
returns_c = daily_return(cau_perf)

#252 trade dates in one year usually

monte = []
'''for i in range(1,2):
    seed = i
    M = 1
    L = N / M
    mu = np.mean(returns_c) * 414.            # drift coefficient
    sig = np.std(returns_c) * np.sqrt(414.)   # diffusion coefficient
    W = Brownian(seed, N)[0]                # brownian movement
    b = Brownian(seed, N)[1]                # brownian increment
    output = EM(So_c, mu, sig, b, T, N, M)[0]
    monte.append(output)
'''
# Monte carlo simulation
for i in range(1,1000):
    seed = i
    M = 1
    mu = np.mean(returns_c) * 414.            # drift coefficient
    sig = np.std(returns_c) * np.sqrt(414.)   # diffusion coefficient
    W = Brownian(seed, N)[0]                # brownian movement
    b = Brownian(seed, N)[1]                # brownian increment
    output = GBM(So_c, mu, sig, W, T, N)[0]
    monte.append(output)

'''
j = 0
printable = []
for i in range(0,len(monte[0])):
    empty = ''
    for x in monte:
        empty += str(x[j]) + ','
    printable.append(empty)
    j += 1

for x in printable:
    print(x)

'''

# Output, final figure
for i in monte:
    print(i[len(i)-1])


import numpy as np
import scipy
import scipy.sparse
import scipy.sparse.linalg
import matplotlib.pyplot as plt

def Analytical_Solution_Special(alpha, x, t):
    """
    Function that generates the analytical solution for the specialised Fischer Equation
    :param alpha: Exponent in the specialised Fischer equation
    :param x: x space
    :param t: time
    :return: Analytical solution of the specialised Fischer equation with respect to x at time t.
    """
    return (-(1/2)*np.tanh(alpha/(2*(2*alpha + 4)**(1/2))*(x - ((alpha+4)*t)/((2*alpha + 4)**(1/2)))) + 1/2)**(2/alpha)

def construct_laplace_matrix_1d(N, h):
    """
    Function generates an NxN 1D laplace matrix
    :param N: Number of iterations
    :param h: Spacial step
    :return: N x N 1D laplace matrix
    """
    e = np.ones(N)
    diagonals = [e, -2*e, e]
    offsets = [-1, 0, 1]
    L = scipy.sparse.spdiags(diagonals, offsets, N, N) / h**2
    return L

eps = 1.0
h = 0.01
alpha = 3.0
k = 0.4 * h ** 2 / eps
Tf = 50
x = np.arange(-15, 15, h)

def solve_turing():
    """
    Solves the specialised Fischer Equation given the default parameters
    :return:
    """
    eps = 1.0   # Multiplier unique to specific biological systems
    h = 0.05    # Spacial step
    alpha = 3.0 # Exponent
    k = 0.2 * h**2 / eps    # Time step
    Tf = 42.0   # Total time
    x = np.arange(-15, 15, h)   # X space

    N = len(x)
    L = construct_laplace_matrix_1d(N, h)   # Construct Laplace matrix
    bc = np.concatenate(([1], np.zeros(N-1)))/h**2  # Application of Neumann boundary conditions
    out = []    # Initialise output
    u = Analytical_Solution_Special(alpha, x, 0)    # Apply initial condition at t=0

    def getsols():
        """
        :return: Generates an array of numerical solutions to the specialised Fischer equation
        """
        for i in range(int(Tf/k)):
            u_new = u + k*(eps*(L*u + bc) + u*(1-u**alpha))
            out.append([u_new])
            u[:] = u_new
        return u

    u = getsols()
    out.append([u])
    return u, x, out

u, x, out = solve_turing()
x_anal = np.linspace(-15, 15, 10)   # Define x-space for scatter plot of analytical solution

u_analstart = Analytical_Solution_Special(alpha, x_anal, 0)     # Analytical solution at t=0
u_analhalf = Analytical_Solution_Special(alpha, x_anal, 2)      # Analytical solution at t=2
u_analend = Analytical_Solution_Special(alpha, x_anal, 4)       # Analytical solution at t=4

#plt.figure()
plt.plot(x, out[0][0], label='Numerical t=0', color='blue')
plt.plot(x, out[int(len(out)/Tf)*2][0], label='Numerical t=2', color='green')
plt.plot(x, out[int(len(out)/Tf)*4][0], label='Numerical t=4', color='red')
plt.scatter(x_anal, u_analstart, label='Analytical t=0', color='blue')
plt.scatter(x_anal, u_analhalf, label='Analytical t=2', color='green')
plt.scatter(x_anal, u_analend, label='Analytical t=4', color='red')
plt.xlabel('x')
plt.ylabel('Signal')
plt.legend()
plt.show()

# Generate analytical solutions at more values of x for error analysis
u_anal0_error = Analytical_Solution_Special(alpha, x, 0)
u_anal2_error = Analytical_Solution_Special(alpha, x, 2)
u_anal4_error = Analytical_Solution_Special(alpha, x, 4)

# initialise arrays
error0 = []
error2 = []
error4 = []

for i in range(len(x)):
    error0.append((u_anal0_error[i] - out[0][0][i])**2)
    error2.append((u_anal2_error[i] - out[int(len(out)/Tf)*2][0][i])**2)
    error4.append((u_anal4_error[i] - out[int(len(out)/Tf)*4][0][i])**2)

plt.plot(x, error0, label='Error t=0', color='blue')
plt.plot(x, error2, label='Error t=2', color='green')
plt.plot(x, error4, label='Error t=4', color='red')
plt.xlabel('x')
plt.ylabel('Error')
plt.show()


# coding: utf-8

import numpy as np

x1 = np.asarray([0, 0, 1, 1])
x2 = np.asarray([0, 1, 0, 1])
X = np.row_stack((np.ones(shape=(1, 4)), x1, x2))
print("X:\n%s" % X)
y = np.asarray([0, 1, 1, 0])
W1 = np.asarray([[-1, 2, -2],
                 [-1, -2, 2]])
W2 = np.asarray([-1, 2, 2])

def sigmoid(input):
    return 1 / (1 + np.power(np.e, -10 * (input)))

np.set_printoptions(precision=6, suppress=True)
z1 = np.matmul(W1, X)
print("W1*X = z1:\n%s" % z1)
a1 = np.row_stack((np.ones(shape=(1, 4)), sigmoid(z1)))
print("sigmoid(z1) = a1:\n%s" % a1)
z2 = np.matmul(W2, a1)
print("W2*a1 = z2:\n%s" % z2)
a2 = sigmoid(z2)
print("------------------------")
print("prediction: %s" % a2)
print("target: %s" % y)
print("------------------------")

# output:
# X:
# [[1. 1. 1. 1.]
#  [0. 0. 1. 1.]
#  [0. 1. 0. 1.]]
# W1*X = z1:
# [[-1. -3.  1. -1.]
#  [-1.  1. -3. -1.]]
# sigmoid(z1) = a1:
# [[1.       1.       1.       1.      ]
#  [0.000045 0.       0.999955 0.000045]
#  [0.000045 0.999955 0.       0.000045]]
# W2*a1 = z2:
# [-0.999818  0.999909  0.999909 -0.999818]
# ------------------------
# prediction: [0.000045 0.999955 0.999955 0.000045]
# target: [0 1 1 0]
# ------------------------


import numpy as np
import math
import random
import itertools
# https://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph07-poissondisk.pdf

def getDistanceSquare(a, b):
    return np.sum(abs(a - b)**2)

def isValid(candidate, radius, minBBox, maxBBox, grid, samples):
    # check if the candidate is outside of border

    if (candidate < minBBox).any() or (candidate > maxBBox).any():
        return False

    cellSize = radius/math.sqrt(2)
    cell = ((candidate-minBBox)/cellSize).astype(int)
    minCell = cell - 2
    maxCell = cell + 2
    searchEnd = np.array(grid.shape)
    searchStart = np.zeros_like(searchEnd)
    minIndices = np.where(minCell > 0)
    searchStart[minIndices] = minCell[minIndices]
    maxIndices = np.where(np.less_equal(maxCell, searchEnd))
    searchEnd[maxIndices] = maxCell[maxIndices]

    indices = [range(a, b) for a, b in zip(searchStart, searchEnd)]
    for index in itertools.product(*indices):
        pointIndex = grid[index]-1

        if pointIndex != -1:
            distanceSquare = getDistanceSquare(samples[int(pointIndex)], candidate)

            if distanceSquare < radius**2:
                return False

    return True

def poissionDiscSampling(radius=30, bundingBox=((0, 0, 0), (1000, 1000, 1000)), sampleRetrial=1, maxTrials=100000):

    samples = []
    activeList = []
    cellSize = radius/math.sqrt(2)
    bboxMin = np.array(bundingBox[0])
    bboxMax = np.array(bundingBox[1])
    sampleRegionSize = bboxMax-bboxMin
    grid = np.zeros(np.ceil(sampleRegionSize/cellSize).astype(int))
    trial = 0
    center = (sampleRegionSize*.5)+bboxMin
    activeList = [center]

    while len(activeList) > 0:
        activeIndex = random.randrange(len(activeList))
        spawnCentre = activeList[activeIndex]
        candidateAccepted = False

        for _ in range(sampleRetrial):
            angle = random.random() * math.pi * 2
            direction = np.array([math.sin(angle), math.cos(angle), math.tan(angle)])
            candidate = spawnCentre + direction * random.uniform(radius, 2*radius)
            trial += 1

            if isValid(candidate, radius, bboxMin, bboxMax, grid, samples):
                samples.append(candidate)
                coord = (candidate-bboxMin)/cellSize
                grid[int(coord[0])][int(coord[1])][int(coord[2])] = len(samples)
                candidateAccepted = True
                activeList.append(candidate)
                break

        if candidateAccepted is False:
            activeList.pop(activeIndex)
        if trial > maxTrials:
            print("Limit trials reached!!")
            break
    return samples


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

# Problem 20
# Factorial digit sum
import numpy as np

print(sum([int(i) for i in str(np.math.factorial(100))]))

# 648
# 0.001 s


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

# Import packages
import numpy as np
import pandas as pd

# Use Subpackages
from matplotlib import pyplot as plt
from numpy import random
from sklearn.preprocessing import scale,PolynomialFeatures
from sklearn.model_selection import train_test_split
from sklearn import datasets
from sklearn import metrics

# Dataset and choose x and y
iris=datasets.load_iris()
data=iris.data
x=data[:,0]
y=data[:,3]

# Plot data as x and y
plt.scatter(x,y)
plt.xlabel('x',fontsize=15)
plt.ylabel('y',fontsize=15)
plt.show()

# Add prolynomial features to x_train
# For Using dataset features use degree=1 in polynomialfeatures and if you want more increase degree and check result
poly=PolynomialFeatures(degree=2)
x=poly.fit_transform(x.reshape(-1,1))

# Normalize x because features will have different ranges
x=np.hstack(((x[:,0].reshape(-1,1)),scale(x[:,1:])))

# Model selection
# Because of no huge difference between variables range no scaling needed
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3,shuffle=True)

# Functions

# Function to find loss function result in each step
def calJ(x,y,teta):
    return (np.sum(((x@teta)-y)**2))/2

# Function to find new teta in each step it calculates J Derivative to teta
def newTeta(x,y,teta):
    return (np.transpose(x))@((x@teta)-y)

# Function to calculate loss(J) and update teta by gradient descent up to 2 last losses difference be less than 0.0001
def tetaResult(x,y,teta,alpha):
    losses=[calJ(x,y,teta)]
    for i in range(9999):
        teta=teta-(alpha*newTeta(x,y,teta))
        losses.append(calJ(x,y,teta))
        if abs(losses[-1]-losses[-2])<0.0001:
            break
    return teta,losses

# Function to calculate coefficents and result of loss function in linearRegression
def linearRegression(alpha,x,y):
    n=(x.shape)[1]
    teta=random.randn(n)
    teta,losses=tetaResult(x,y,teta,alpha)
    # Max iteration to find optimum teta is 10000
    if len(losses)==10000:
        plt.scatter(np.arange(len(losses)),losses)
        plt.xlabel('Iteration')
        plt.ylabel('Loss')
        return False
    else:
        return teta,losses

# Funtion to calculate mean square error of perdiction
def meanSquareError(y_test,y_pred):
    return np.sum((y_test-y_pred)**2)/len(y_test)

# Execute codes and functions for any linear regression
alpha=0.00005
result=linearRegression(alpha,x_train,y_train)
if result!=False:
    teta,losses=result
    print('teta coeffiecients value is ',teta)
    primaryXTest=(x_test[:,1]).reshape(-1,1)
    plt.figure(figsize=(14,14))
    plt.subplot(2,2,1)
    plt.scatter(np.arange(len(losses)),losses)
    plt.xlabel('Iteration')
    plt.ylabel('Loss')
    plt.subplot(2,2,2)
    plt.scatter(primaryXTest,y_test)
    plt.xlabel('x_test')
    plt.ylabel('y_test')
    plt.subplot(2,2,3)
    y_pred=x_test@teta
    plt.scatter(primaryXTest,y_pred)
    plt.xlabel('x_test')
    plt.ylabel('y_pred')
    plt.subplot(2,2,4)
    plt.scatter(primaryXTest,y_test,c='blue')
    plt.scatter(primaryXTest,y_pred,c='red')
    plt.xlabel('x_test')
    plt.ylabel('y_test,y_pred')
    plt.show()
    print('mean square error for y_predict and y_test is ',meanSquareError(y_test,y_pred))
else:
    print('Error in convergence of loss function')

# Calculate y_predict and loss with sklearn linear-model package
from sklearn.linear_model import LinearRegression
lin=LinearRegression()
lin.fit(x_train,y_train)
metrics.mean_squared_error(y_test,lin.predict(x_test))
y_predict=lin.predict(x_test)
plt.scatter(x_test[:,1],y_test)
plt.scatter(x_test[:,1],y_predict,c='red')
plt.xlabel('x_test')
plt.ylabel('y_test , y_predict')
plt.show()
print('mean square error for y_predict and y_test is',metrics.mean_squared_error(y_test,y_predict))


import numpy as np
# all inputs are numpy array

def RSE(pred:np.ndarray, true:np.ndarray):
    return np.sqrt(np.sum((true-pred)**2)) / np.sqrt(np.sum((true-true.mean())**2))

def CORR(pred:np.ndarray, true:np.ndarray):
    '''
    Calculate the corrcoeff for each column pair of pred and true, then calculate mean of all corrcoeff
    '''
    u = ((true-true.mean(0))*(pred-pred.mean(0))).sum(0)
    #d = np.sqrt(((true-true.mean(0))**2*(pred-pred.mean(0))**2).sum(0)) # this is the original implementation, seems wrong
    d = np.sqrt((((true-true.mean(0))**2).sum(0)*((pred-pred.mean(0))**2).sum(0)))
    return (u/d).mean(-1) #calculate mean for corrcoef of each pair

def MAE(pred:np.ndarray, true:np.ndarray):
    return np.mean(np.abs(pred-true))

def MSE(pred:np.ndarray, true:np.ndarray):
    return np.mean((pred-true)**2)

def RMSE(pred:np.ndarray, true:np.ndarray):
    return np.sqrt(MSE(pred, true))

def MAPE(pred:np.ndarray, true:np.ndarray):
    return np.mean(np.abs((pred - true) / true))

def MSPE(pred:np.ndarray, true:np.ndarray):
    return np.mean(np.square((pred - true) / true))

def metric(pred:np.ndarray, true:np.ndarray):
    mae = MAE(pred, true)
    mse = MSE(pred, true)
    rmse = RMSE(pred, true)
    mape = MAPE(pred, true)
    mspe = MSPE(pred, true)

    return mae,mse,rmse,mape,mspe


from sympy.functions import bspline_basis, bspline_basis_set
from sympy import Piecewise, Interval
from sympy import symbols, Rational

x, y = symbols('x,y')

def test_basic_degree_0():
    d = 0
    knots = range(5)
    splines = bspline_basis_set(d, knots, x)
    for i in range(len(splines)):
        assert splines[i] == Piecewise((1, Interval(i, i+1)), (0, True))

def test_basic_degree_1():
    d = 1
    knots = range(5)
    splines = bspline_basis_set(d, knots, x)
    assert splines[0] == Piecewise((x,Interval(0,1,False,True)),(2-x,Interval(1,2)),(0,True))
    assert splines[1] == Piecewise((-1+x,Interval(1,2,False,True)),(3-x,Interval(2,3)),(0,True))
    assert splines[2] == Piecewise((-2+x,Interval(2,3,False,True)),(4-x,Interval(3,4)),(0,True))

def test_basic_degree_2():
    d = 2
    knots = range(5)
    splines = bspline_basis_set(d, knots, x)
    b0 = Piecewise((x**2/2,Interval(0,1,False,True)),(Rational('-3/2')+3*x-x**2,Interval(1,2,False,True)),(Rational(9,2)-3*x+x**2/2,Interval(2,3)),(0,True))
    b1 = Piecewise((Rational(1,2)-x+x**2/2,Interval(1,2,False,True)),(Rational(-11,2)+5*x-x**2,Interval(2,3,False,True)),(8-4*x+x**2/2,Interval(3,4)),(0,True))
    assert splines[0] == b0
    assert splines[1] == b1

def test_basic_degree_3():
    d = 3
    knots = range(5)
    splines = bspline_basis_set(d, knots, x)
    b0 = Piecewise(
        (x**3/6, Interval(0,1,False,True)),
        (Rational(2,3) - 2*x + 2*x**2 - x**3/2, Interval(1,2,False,True)),
        (Rational(-22,3) + 10*x - 4*x**2 + x**3/2, Interval(2,3,False,True)),
        (Rational(32,3) - 8*x + 2*x**2 - x**3/6, Interval(3,4)),
        (0, True)
    )
    assert splines[0] == b0

def test_repeated_degree_1():
    d = 1
    knots = [0,0,1,2,2,3,4,4]
    splines = bspline_basis_set(d, knots, x)
    assert splines[0] == Piecewise((1 - x, Interval(0,1)), (0, True))
    assert splines[1] == Piecewise((x, Interval(0,1,False,True)), (2 - x, Interval(1,2)), (0, True))
    assert splines[2] == Piecewise((-1 + x, Interval(1,2)), (0, True))
    assert splines[3] == Piecewise((3 - x, Interval(2,3)), (0, True))
    assert splines[4] == Piecewise((-2 + x, Interval(2,3,False,True)), (4 - x, Interval(3,4)), (0, True))
    assert splines[5] == Piecewise((-3 + x, Interval(3,4)), (0, True))


import numpy as np

def customTicks(data,
                forceMin=np.nan, forceMax=np.nan,
                forceMinTick=np.nan, forceMaxTick=np.nan,
                desiredNumTicks=5,
                displayFirst=True, displayLast=True,
                multipleCandidates=[1,2,2.5,5]):

    multipleCandidates = np.array(multipleCandidates)

    if np.isnan(forceMaxTick):
        maximum = np.max(data)
    else:
        maximum = forceMaxTick

    if np.isnan(forceMinTick):
        minimum = np.min(data)
    else:
        minimum = forceMinTick

    ts_exact = (maximum-minimum)/desiredNumTicks
    if ts_exact == 0:
        ts_exact = 1
        desiredNumTicks = 1
    ts_nearest = np.round(ts_exact,-int(np.floor(np.log10(ts_exact))))
    ts_tenPower = np.floor(np.log10(ts_nearest))
    ts_nTens = ts_nearest/10**ts_tenPower
    multInd = np.argmin(np.abs(ts_nTens - multipleCandidates))
    multiple = multipleCandidates[multInd]
    tickSpacing = multiple*10**ts_tenPower

    minimum = np.floor(minimum/tickSpacing)*tickSpacing
    maximum = np.ceil(maximum/tickSpacing)*tickSpacing

    tickValues = np.arange(minimum, maximum+tickSpacing/10, tickSpacing)
    if (not displayFirst) and (len(tickValues) > 1):
        tickValues = tickValues[1:]
    if (not displayLast) and (len(tickValues) > 1):
        tickValues = tickValues[:-1]
    #numTicks = len(tickValues)

    if not np.isnan(forceMin):
        minimum = forceMin
        tickValues = [tv for tv in tickValues if tv >= forceMin]
    if not np.isnan(forceMax):
        maximum = forceMax
        tickValues = [tv for tv in tickValues if tv <= forceMax]

    return minimum, maximum, tickValues


# cosine similarity and duplicate detection implementation
import numpy
from pathlib import Path
from collections import defaultdict
from copy import deepcopy

similarityThreshold = 0.99 # customizable similarity threshold
debug = True # for debug print

def cosineSimilarity(dictX: dict, dictY: dict):
	"""
	Source code can be found on
	www.biaodianfu.com/cosine-similarity.html
	"""
	listX = convertToVector(dictX)
	listY = convertToVector(dictY)
	vectorX = numpy.array(listX)
	vectorY = numpy.array(listY)
	dotProduct = numpy.dot(vectorX, vectorY)
	normalizedX = numpy.linalg.norm(vectorX)
	normalizedY = numpy.linalg.norm(vectorY)
	if normalizedX * normalizedY == 0:
		# print(dictX,"\n",dictY)
		# print(listX,"\n",listY)
		# print(vectorX,"\n", vectorY)
		# print(normalizedX, "\n", normalizedY)
		# print("cannot divide by 0")
		return -1
	return dotProduct / (normalizedX * normalizedY)

# print(f"cos sim for [1,1,1] and [1,1,1] = {cosineSimilarity([1,1,1], [1,1,1])}\tshould be 1")
# print(f"cos sim for [1,0,1] and [0,1,0] = {cosineSimilarity([1,0,1], [0,1,0])}\tshould be 0")

def readText(file) -> list:
	with file.open() as f:
		url = f.readline()
		text = list(map(lambda x: x.rstrip(), f.readlines()))
		# if(len(text) == 0):
		# 	print(f"{url} is empty!!")
	return text

def calculateTermFreq(tokenList: list) -> dict:

	termFreqDict = defaultdict(int)
	for token in tokenList:
		termFreqDict[token] += 1
	return termFreqDict

def convertToVector(tokenDict: dict) -> list:

	rawVector = sorted(tokenDict.items())
	tokenVector = [x[1] for x in rawVector] # only preserve the frequency values
	return tokenVector

def addMissingTerms(tokenDictX: dict, tokenDictY: dict) -> (dict, dict):

	for key in tokenDictX.keys():
		if not (key in tokenDictY):
			tokenDictY[key] = 0

	for key in tokenDictY.keys():
		if not (key in tokenDictX):
			tokenDictX[key] = 0

	return (tokenDictX, tokenDictY)

def queryDocSimiliarity(query: [str], fileName: str) -> float:
	queryDict = calculateTermFreq(query)
	tokenList = readText(Path(fileName))
	tokenDict = calculateTermFreq(tokenList)
	queryDict, tokenDict = addMissingTerms(queryDict, tokenDict)
	score = cosineSimilarity(queryDict, tokenDict)
	# print(score)
	return score

def duplicateCheck(allFiles) -> list:

	global similarityThreshold
	# allFiles = iterdir(Path("op"))
	fileList = list(allFiles)
	dupeList = list()
	emptyList = list()
	count = 0

	x = 0
	while(x != len(fileList)):

		fileX = fileList[x]
		y = x + 1

		tokenListX = readText(fileX)
		if len(tokenListX) == 0:
			if debug: print(f"remove {fileX.name}, current x: {x}")
			fileList.remove(fileX)
			emptyList.append(fileX)
			continue

		while(y != len(fileList)):
			if fileList[x] != fileList[y]:
				fileY = fileList[y]
				tokenListX = readText(fileX)
				tokenListY = readText(fileY)

				if len(tokenListY) == 0:
					if debug: print(f"remove {fileY.name}, current y: {y}")
					fileList.remove(fileY)
					emptyList.append(fileY)
					continue

				tokenDictX = calculateTermFreq(tokenListX)
				tokenDictY = calculateTermFreq(tokenListY)
				tokenDictX, tokenDictY = addMissingTerms(tokenDictX, tokenDictY)
				score = cosineSimilarity(tokenDictX, tokenDictY)

				if debug:
					# print(f"{fileX.name} compare to {fileY.name}\nScore is {score}")
					if count % 1000 == 0: print(f"current count: {count}")
					# print(count)
					count+= 1

				if (score >= similarityThreshold):
					if debug: print(f"remove {fileY.name}, current y: {y}")
					fileList.remove(fileY)
					dupeList.append(fileY)
					y -= 1
			# end if !=
			y += 1
		# end inner while
		x += 1
	# end outer while
	print(dupeList)
	return fileList

if __name__ == '__main__':
	testFolder = Path("C:\\Users\\hower\\Documents\\CS 121\\project3\\testFolder")
	outputFolder = Path("C:\\Users\\hower\\Documents\\CS 121\\project3\\op")
	noDupeList = duplicateCheck(outputFolder.iterdir())
	print(noDupeList)
	with open("C:\\Users\\hower\\Documents\\CS 121\\project3\\noDupeList.txt", 'w') as f:
		for filePath in noDupeList:
			f.write(filePath.name)
	# if debug: print(fileList)

	# score = queryDocSimiliarity(["fuck"],"C:\\Users\\hower\\Documents\\CS 121\\project3\\op\\10237.txt")

	# query = ["comput"]
	# result = []
	# for file in outputFolder.iterdir():
	# 	# print(file.name)
	# 	score = queryDocSimiliarity(query, file)
	# 	if score == -1:
	# 		print(f"doc id {file.name} is empty")
	# 	result.append(score)
	# print(result)


"""
We have a graph, which represents some communication network.

We would like to find the shortest path in the network.

We could've used the Dijkstra's algorithm, but we don't have
information of the whole network, as it's quite dynamic.

So we want to implement an algorithm, which will use only the local
information about the neighbors.

Bellman-Ford algorithm has such a property, so basically a node V
can compute it's value based on the value of a node W, which is it's
neighbor/adjacent node.

So for the node V works the next expression:
OPT[v] = min(Cvw + OPT[w]) for each W neighbor of V. k

We already implemented that in the Bellman-Ford alg improvement,
so this time we will do an async variant of the same algorithm.
"""
import networkx as nx
import numpy

def async_shortest_path(G : nx.DiGraph, s, t):
    n = len(G.nodes)
    nodesLst = sorted(list(G.nodes()))
    nodesIndices = {nodesLst[i]:i for i in range(n)}

    inf = float("inf")
    opt = [inf] * n
    opt[nodesIndices[t]] = 0.0
    predecessor = [None] * (n+1)

    activeNodes = set(t)
    while activeNodes:
        w = activeNodes.pop()
        wIndex = nodesIndices[w]
        edges = G.in_edges(w, data = "weight")
        for v, _, cost in edges:
            vIndex = nodesIndices[v]
            vOpt = cost + opt[wIndex]
            if vOpt < opt[vIndex]:
                opt[vIndex] = vOpt
                predecessor[vIndex] = w
                activeNodes.add(v)

    path = [s]
    while path[-1] != t: path.append(predecessor[nodesIndices[path[-1]]])
    return path, opt[nodesIndices[s]]


# coding: utf-8

__author__ = 'Mário Antunes'
__version__ = '0.1'
__email__ = 'mariolpantunes@gmail.com'
__status__ = 'Development'

import math
import numpy as np

def weighted_avg_and_std(values: np.ndarray, weights: np.ndarray) -> tuple:
    """
    Return the weighted average and standard deviation.

    Args:
        points (np.ndarray): numpy array with values
        weights (np.ndarray): numpy array with weights

    Returns:
        tuple[float, float]: returns a tuple with the weighted average and standard deviation
    """
    average = np.average(values, weights=weights)
    # Fast and numerically precise:
    variance = np.average((values-average)**2, weights=weights)
    return average, math.sqrt(variance)

def zscore(xi: float, mean: float, std: float) -> float:
    """
    Return the z-score for a single value.

    Args:
        xi (float): the single value
        mean (float): mean value from the sequence
        std (float): standart deviation from the sequence

    Returns:
        float: the z-score for a single value
    """
    if std != 0:
        return (xi - mean)/std
    else:
        return xi - mean

def linear_delta_mapping_points(points: np.ndarray) -> tuple:
    """
    Return a linear mapping from the sequence of points.

    One way to estimate the z-score metric from a uneven sequence
    is to map the values linearly and compute the weight of each new value.
    The weight is proportional to the delta in the x axis.

    Args:
        points (np.ndarray): numpy array with the points (x, y)

    Returns:
        tuple[np.ndarray, np.ndarray]: the weight and the linear mapping
    """
    x = points[:, 0]
    y = points[:, 1]
    return linear_delta_mapping(x, y)

def linear_delta_mapping(x: np.ndarray, y: np.ndarray) -> tuple:
    """
    Return a linear mapping from the sequence of points.

    One way to estimate the z-score metric from a uneven sequence
    is to map the values linearly and compute the weight of each new value.
    The weight is proportional to the delta in the x axis.

    Args:
        x (np.ndarray): values from the x axis
        y (np.ndarray): values from the y axis

    Returns:
        tuple[np.ndarray, np.ndarray]: the weight and the linear mapping
    """
    tdelta =  x[1:] - x[:-1]
    linear_values = (y[1:] + y[:-1]) / 2.0
    return tdelta, linear_values

def zscore_linear(xi: float, points: np.ndarray) -> float:
    """
    Return the z-score for a single value, using the linear mapping
    to deal with the uneven sequence of values.

    Args:
        xi (float): the single value
        points (np.ndarray): numpy array with the points (x, y)

    Returns:
        float: the z-score for a single value

    Raises:
        ValueError: If the lenght of points is smaller than 2.
    """
    if len(points) <= 1:
        raise ValueError('The number of points is smaller than 2')

    weights, values = linear_delta_mapping_points(points)
    mean, std = weighted_avg_and_std(values, weights)
    return zscore(xi, mean, std)

def zscore_array_points(points: np.ndarray) -> np.ndarray:
    """
    Returns the z-score value for all the values in the sequence.

    It uses linear mapping to deal with the uneven sequence.

    Args:
        points (np.ndarray): numpy array with the points (x, y)

    Returns:
        np.ndarray: the z-score value for all the values in the sequence
    """
    x = points[:, 0]
    y = points[:, 1]
    return zscore_array(x, y)

def zscore_array(x: np.ndarray, y: np.ndarray) -> np.ndarray:
    """
    Returns the z-score value for all the values in the sequence.

    It uses linear mapping to deal with the uneven sequence.

    Args:
        x (np.ndarray): values from the x axis
        y (np.ndarray): values from the y axis

    Returns:
        np.ndarray: the z-score value for all the values in the sequence
    """
    weights, values = linear_delta_mapping(x, y)
    mean, std = weighted_avg_and_std(values, weights)
    if std != 0.0:
        return (y - mean)/std
    else:
        return y - mean


'''--------------------------- Core Script ---------------------------------'''
'''
    Description: This library is based on the algorithms described in
    [1] Chin-Chia Michael Yeh, Yan Zhu, Liudmila Ulanova, Nurjahan Begum,
        Yifei Ding, Hoang Anh Dau, Diego Furtado Silva, Abdullah Mueen,
        Eamonn Keogh (2016). Matrix Profile I: All Pairs Similarity Joins
        for Time Series: A Unifying View that Includes Motifs, Discords and
        Shapelets. IEEE ICDM 2016.
'''
import numpy as np
import pandas as pd
import time

import matplotlib.pyplot as plt

def slidingDotProduct(Q, T):
    n = len(T)
    m = len(Q)

    Ta = list(T) # Copy the T without modifying the original
    [Ta.append(0) for i in range(0, n)]

    Qr = Q[::-1]

    Qra = list(Qr) # Copy the T without modifying the original
    [Qra.append(0) for i in range(0, 2*n - m)]

    Qraf = np.fft.fft(Qra)
    Taf = np.fft.fft(Ta)

    QT = np.fft.ifft(np.multiply(Qraf, Taf))

    return QT[m:n]

def calculateDistanceProfile(QT, Q, T, sumT, sumT2, sumQ, sumQ2, meanT, meanT_2, sigmaT, sigmaT2):
    n = len(T)
    m = len(Q)

    # computing the distances -- O(n) time.
    a = [(sumT2[i] - 2*sumT[i]*meanT[i] + m*meanT_2[i])/sigmaT2[i] for i in range(0, n - m)]
    b = [2*(QT[i] - sumQ*meanT[i])/sigmaT[i] for i in range(0, n - m)]
    c = sumQ2

    dist = [a[i] + b[i] + c for i in range(0, n - m)]

    D = np.absolute(np.sqrt(dist))

    return D

# The code below takes O(m) for each subsequence
# you should replace it for MASS
def computeMeanStd(Q, T):
    n = len(T)
    m = len(Q)

    # Compute Q stats -- O(n)
    sumQ = np.sum(Q)
    sumQ2 = np.sum(np.power(Q, 2))

    # Compute T stats -- O(n)
    cum_sumT = np.cumsum(T, dtype=float)
    cum_sumT2 = np.cumsum(np.power(T, 2), dtype=float)
    sumT2 = [cum_sumT2[i + m] - cum_sumT2[i] for i in range(0, n - m)]
    sumT = [cum_sumT[i + m] - cum_sumT[i] for i in range(0, n - m)]
    meanT = [sumT[i]/m for i in range(0, n - m)]
    meanT2 = [sumT2[i]/m for i in range(0, n - m)]
    meanT_2 = np.power(meanT, 2)
    sigmaT2 = [meanT2[i] - meanT_2[i] for i in range(0,n - m)]
    sigmaT = np.sqrt(sigmaT2)

    return sumT, sumT2, sumQ, sumQ2, meanT, meanT_2, sigmaT, sigmaT2

# MUEEN’S ALGORITHM FOR SIMILARITY SEARCH (MASS)
def mass(Q, T):
    QT = slidingDotProduct(Q, T)
    sumT, sumT2, sumQ, sumQ2, meanT, meanT_2, sigmaT, sigmaT2 = computeMeanStd(Q, T)
    D = calculateDistanceProfile(QT, Q, T, sumT, sumT2, sumQ, sumQ2, meanT, meanT_2, sigmaT, sigmaT2)

    return D

def elementWiseMin(Pab, Iab, D, idx):
    Pab_copy = [1000000 for i in range(0, len(Pab))]
    flag = False

    for i in range(0, len(D)):
        if(Pab[i] == float('Inf')):
            Pab_copy[i] = D[i]
            Iab[i] = idx
            flag = True
        elif(D[i] < Pab[i]):
            Pab[i] = D[i]
            Iab[i] = idx

    if flag:
        return Pab_copy, Iab
    else:
        return Pab, Iab

def stamp(Ta, Tb, m):
    nb = len(Tb)
    na = len(Ta)
    Pab = [float('Inf') for i in range(0, na - m)]
    Iab = [0 for i in range(0, na - m)]
    idxes = range(0, nb - m)

    for idx in idxes:
        print(idx)
        D = mass(Tb[idx : idx + m], Ta)
        Pab, Iab = elementWiseMin(Pab, Iab, D, idx)

    return Pab, Iab

# Quick Test
def test_stamp(Ta, Tb, m):
    start_time = time.time()

    df_serie_a = pd.read_csv(Ta, header= 0)
    df_serie_b = pd.read_csv(Tb, header= 0)

    ts_a = np.ravel(df_serie_a['value']).tolist()
    ts_b = np.ravel(df_serie_b['value']).tolist()

    Pab, Iab = stamp(ts_a, ts_b, m)
    print("--- %s seconds ---" % (time.time() - start_time))

    plot_graphics(Pab)

def plot_graphics(values):
    fig_width = 16
    fig_height = 8
    fig_dpi = 100
    plt.figure(figsize=(fig_width, fig_height), dpi=fig_dpi)

    plt.plot(range(0,len(values)), values, '#ff5722')
    plt.xlabel('Index')
    plt.ylabel('Value')
    plt.show()


#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime, date

hist_file = os.path.join('hist/', '%s.csv' % 'USDCAD Curncy')
usd_cad = pd.read_csv(hist_file, header=0, parse_dates=True, sep=',', index_col=0)
usd_cad = usd_cad['Price']
usd_cad.name = 'USDCAD Curncy'
plt.plot(usd_cad.index, usd_cad, '-')
plt.xlabel('Date')
plt.ylabel('USDCAD')
plt.show()

###################################################### ADF test #####################################################
import statsmodels.tsa.stattools as ts
# H0: beta==1 or random walk
adf_statistic = ts.adfuller(usd_cad, 1)           # lag = 1
print('Augmented Dickey Fuller test statistic =',adf_statistic[0])   #  -2.0188553406859833
print('Augmented Dickey Fuller p-value =',adf_statistic[1])   # 0.27836737105308673
print('Augmented Dickey Fuller # of samples =',adf_statistic[3])  # 1599
# {'1%': -3.4344462031760283, '5%': -2.8633492329988335, '10%': -2.5677331999518147}
print('Augmented Dickey Fuller 1%, 5% and 10% critical values =',adf_statistic[4])

################################################### Hurst Exponent ##################################################
def hurst(ts):
    """Returns the Hurst Exponent of the time series vector ts"""
    # Create the range of lag values
    lags = range(2, 100)

    # Calculate the array of the variances of the lagged differences
    tau = [np.sqrt(np.std(np.subtract(ts[lag:], ts[:-lag]))) for lag in lags]

    # Use a linear fit to estimate the Hurst Exponent
    poly = np.polyfit(np.log(lags), np.log(tau), 1)

    # Return the Hurst exponent from the polyfit output
    return poly[0] * 2.0

print("Hurst(USDCAD):   %s" % hurst(np.log(usd_cad)))

################################################# Variance Ratio #####################################################
def normcdf(X):
    (a1, a2, a3, a4, a5) = (0.31938153, -0.356563782, 1.781477937, -1.821255978, 1.330274429)
    L = abs(X)
    K = 1.0 / (1.0 + 0.2316419 * L)
    w = 1.0 - 1.0 / np.sqrt(2 * np.pi) * np.exp(-L * L / 2.) * (
                a1 * K + a2 * K * K + a3 * pow(K, 3) + a4 * pow(K, 4) + a5 * pow(K, 5))
    if X < 0:
        w = 1.0 - w
    return w

def vratio(a, lag=2, cor='hom'):
    t = (np.std((a[lag:]) - (a[1:-lag + 1]))) ** 2
    b = (np.std((a[2:]) - (a[1:-1]))) ** 2

    n = float(len(a))
    mu = sum(a[1:len(a)] - a[:-1]) / n
    m = (n - lag + 1) * (1 - lag / n)
    #   print mu, m, lag
    b = sum(np.square(a[1:len(a)] - a[:len(a) - 1] - mu)) / (n - 1)
    t = sum(np.square(a[lag:len(a)] - a[:len(a) - lag] - lag * mu)) / m
    vratio = t / (lag * b)

    la = float(lag)

    if cor == 'hom':
        varvrt = 2 * (2 * la - 1) * (la - 1) / (3 * la * n)

    elif cor == 'het':
        varvrt = 0
        sum2 = sum(np.square(a[1:len(a)] - a[:len(a) - 1] - mu))
        for j in range(lag - 1):
            sum1a = np.square(a[j + 1:len(a)] - a[j:len(a) - 1] - mu)
            sum1b = np.square(a[1:len(a) - j] - a[0:len(a) - j - 1] - mu)
            sum1 = np.dot(sum1a, sum1b)
            delta = sum1 / (sum2 ** 2)
            varvrt = varvrt + ((2 * (la - j) / la) ** 2) * delta

    zscore = (vratio - 1) / np.sqrt(float(varvrt))
    pval = normcdf(zscore)

    return vratio, zscore, pval

#  (1.043812391881447, 0.23398177899239425, 0.5925003942830439)
vratio(np.log(usd_cad.values), cor='het', lag=20)

###################################################### Half-Life #####################################################
from sklearn import linear_model
df_close = usd_cad.to_frame()
df_lag = df_close.shift(1)
df_delta = df_close - df_lag
lin_reg_model = linear_model.LinearRegression()
df_delta = df_delta.values.reshape(len(df_delta),1)                    # sklearn needs (row, 1) instead of (row,)
df_lag = df_lag.values.reshape(len(df_lag),1)
lin_reg_model.fit(df_lag[1:], df_delta[1:])                           # skip first line nan
half_life = -np.log(2) / lin_reg_model.coef_.item()
print ('Half life:       %s' % half_life)           #  260.65118856658813

################################################## Linear Scaling-in #################################################
# in source/straetgy/mystrategy folder


# Psychofun/Tensorflow-Como-Calcular-Derivadas
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

### Crea una sesion
sess = tf.Session()

x = tf.placeholder('float32')

f = 3*x

derivada = tf.gradients(f, x)[0]

x_array = np.linspace(-3,3)
#print(x_array)
f_, f_derivada = sess.run([f,derivada],
                                 {x:x_array})

plt.plot(x_array, f_, label="f")
plt.plot(x_array, f_derivada, label="df")
plt.legend();

x = tf.placeholder('float32')

f = x**2

#la derivada de x^2
derivada = tf.gradients(f, x)[0]

x_array = np.linspace(-3,3)

f_, f_derivada = sess.run([f,derivada],
                                 {x:x_array})

plt.plot(x_array, f_,label="f")
plt.plot(x_array, f_derivada, label="df")
plt.legend();

x = tf.placeholder('float32')

f = x**4 + x**3 + 100

#la derivada de x^2
derivada = tf.gradients(f, x)[0]

x_array = np.linspace(-3,3)

f_, f_derivada = sess.run([f,derivada],
                                 {x:x_array})

plt.plot(x_array, f_,label="f")
plt.plot(x_array, f_derivada, label="df")
plt.legend();

x = tf.placeholder('float32')

f = tf.sin(x)

#la derivada de x^2
derivada = tf.gradients(f, x)[0]

x_array = np.linspace(-3,3)
f_, f_derivada = sess.run([f,derivada],
                                 {x:x_array})

plt.plot(x_array, f_, label="f")
plt.plot(x_array, f_derivada, label="df")
plt.legend();

x = tf.placeholder('float32')

f = tf.cos(x)

#la derivada de x^2
derivada = tf.gradients(f, x)[0]

x_array = np.linspace(-3,3)
f_, f_derivada = sess.run([f,derivada],
                                 {x:x_array})
plt.figure(figsize=(12,12))
plt.plot(x_array, f_, label="f = cos(x)")
plt.plot(x_array, f_derivada, label="df = -sin(x)")
plt.legend();
### Guarda la grafica como una imagen
plt.savefig("derivada.png")

x = tf.placeholder('float32')

f = tf.exp(x)

#la derivada de x^2
derivada = tf.gradients(f, x)[0]

x_array = np.linspace(-3,3)
f_, f_derivada = sess.run([f,derivada],
                                 {x:x_array})

plt.plot(x_array, f_, label="f")
plt.plot(x_array, f_derivada, label="df")
plt.legend();

x = tf.placeholder('float32')

f = tf.log(x)

#la derivada de x^2
derivada = tf.gradients(f, x)[0]

x_array = np.linspace(-3,3)
f_, f_derivada = sess.run([f,derivada],
                                 {x:x_array})

plt.plot(x_array, f_, label="f")
plt.plot(x_array, f_derivada, label="df")
plt.legend();

x = tf.placeholder('float32')

f = tf.sigmoid(x)

#la derivada de x^2
derivada = tf.gradients(f, x)[0]

x_array = np.linspace(-3,3)
f_, f_derivada = sess.run([f,derivada],
                                 {x:x_array})

plt.plot(x_array, f_, label="f")
plt.plot(x_array, f_derivada, label="df")
plt.legend();

x = tf.placeholder('float32')

f = tf.nn.softmax(x)

#la derivada de x^2
derivada = tf.gradients(f, x)[0]

x_array = np.linspace(-3,3)
f_, f_derivada = sess.run([f,derivada],
                                 {x:x_array})

plt.plot(x_array, f_, label="f")
plt.plot(x_array, f_derivada, label="df")
plt.legend();

x = tf.placeholder('float32')

f = tf.sigmoid(x**2)

#la derivada de x^2
derivada = tf.gradients(f, x)[0]

x_array = np.linspace(-3,3)
f_, f_derivada = sess.run([f,derivada],
                                 {x:x_array})

plt.plot(x_array, f_, label="f")
plt.plot(x_array, f_derivada, label="df")
plt.legend();


'''
Copyright 2019 Agnese Salutari.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License
'''

# Dependencies:
import random

class ModularArithmetics:

    def changeToPositive(self, x, m):
        '''
        Turns the negative integer x into a positive integer (mod m).
        :param x: negative integer.
        :param m: integer.
        :return: integer.
        '''
        assert isinstance(x, int)
        assert isinstance(m, int)
        while x < 0:
            x += m
        return x

    def isPrime(self, num):
        '''
        Verifies if num is prime.
        :param num: integer.
        :return: boolean.
        '''
        assert isinstance(num, int)
        assert num > 0
        if num < 2:
            return True
        else:
            for i in range(2, num):
                if (num % i) == 0:
                    return False
            return True

    def findPrimitiveRootsOfPrime(self, primeNumber): # Time consuming!!!
        '''
        Finds primitive roots of primeNumber.
        :param primeNumber: integer (a prime number).
        :return: list of integers.
        '''
        from sympy.ntheory.residue_ntheory import _primitive_root_prime_iter
        assert isinstance(primeNumber, int)
        assert self.isPrime(primeNumber)
        return list(_primitive_root_prime_iter(primeNumber))

    def randomInteger(self, infBound=1, supBound=10):
        '''
        Gives a random integer between infBount and supBound.
        :param infBound: integer.
        :param supBound: integer.
        :return: integer.
        '''
        assert isinstance(infBound, int)
        assert isinstance(supBound, int)
        return random.randint(infBound, supBound)

    def randomPrime(self, infBound=1, supBound=10):
        '''
        Gives a random prime between infBound and supBound.
        :param infBound: integer.
        :param supBound: integer.
        :return: integer.
        '''
        assert isinstance(infBound, int)
        assert isinstance(supBound, int)
        candidatePrime = random.randint(infBound, supBound)
        while not self.isPrime(candidatePrime):
            candidatePrime = random.randint(infBound, supBound)
        return candidatePrime

    def randomPrimeFromFile(self, filePath='primes50.txt'):
        '''
        https://primes.utm.edu/lists/small/millions/
        :param: filePath: string; the path of the file containing primes.
        :return: integer; a random prime.
        '''
        assert isinstance(filePath, str)
        file = open(filePath, 'r')
        fileList = file.readlines()
        primes = []
        for line in fileList:
            line = ' '.join(line.split())
            linePrimes = line.split(' ')
            for p in linePrimes:
                primes.append(p)
        return int(random.choice(primes))

    def randomPrimitiveRoot(self, primeNumber): # Uses a time consuming function to find primitive roots!!!
        '''
        Returns a random primitive root of primeNumber.
        :param primeNumber: integer (a prime number).
        :return: integer.
        '''
        assert isinstance(primeNumber, int)
        primitiveRoots = self.findPrimitiveRootsOfPrime(primeNumber)
        return random.choice(primitiveRoots)

    def listOfPrimesFromFile(self, filePath='smallPrimes.txt'):
        '''
        https://primes.utm.edu/lists/small/millions/
        :param: filePath: string; the path of the file containing primes.
        :return: list of integer.
        '''
        file = open(filePath, 'r')
        fileList = file.readlines()
        primes = []
        for line in fileList:
            line = ' '.join(line.split())
            linePrimes = line.split(' ')
            for p in linePrimes:
                if not p == '':
                    primes.append(int(p))
        return primes

    def modularMultiplication(self, x, y, m):
        '''
        Computes x * y (mod m).
        :param x: integer.
        :param y: integer.
        :param m: integer.
        :return: integer.
        '''
        assert isinstance(x, int)
        assert isinstance(y, int)
        assert isinstance(m, int)
        return x * y % m

    def modularPower(self, a, e, m):
        '''
        Computes a^(e) (mod m).
        :param a: integer.
        :param e: integer.
        :param m: integer.
        :return: integer.
        '''
        assert isinstance(a, int)
        assert isinstance(e, int)
        assert isinstance(m, int)
        res = 1
        a = a % m
        while (e > 0):
            # If e is odd, multiply x with result
            if ((e & 1) == 1):
                res = (res * a) % m
            # e must be even now
            e = e >> 1 # y = y/2
            a = (a * a) % m
        return res

    def findGCD(self, x, y):
        '''
        Finds Greatest Common Divisor of x and y.
        :param x: integer.
        :param y: integer.
        :return: integer.
        '''
        assert isinstance(x, int)
        assert isinstance(y, int)
        if x < y:
            return self.findGCD(y, x)
        elif x % y == 0:
            return y;
        else:
            z = x % y
            return self.findGCD(y, z)

    def egcd(self, a, b):
        '''
        Euclidean Extended Algorithm.
        :param a: integer.
        :param b: integer.
        :return: (g, x, y) such that a*x + b*y = g = gcd(a, b).
        '''
        assert isinstance(a, int)
        assert isinstance(b, int)
        if a == 0:
            return (b, 0, 1)
        else:
            g, y, x = self.egcd(b % a, a)
            return g, x - (b // a) * y, y

    def modularInverse(self, a, m):
        '''
        Computes a^(-1) (mod m).
        :param a: integer.
        :param m: integer.
        :return: integer.
        '''
        assert isinstance(a, int)
        assert isinstance(m, int)
        g, x, y = self.egcd(a, m)
        if g != 1:
            raise Exception('Modular inverse does not exist!')
        else:
            return x % m

##################################TEST############################

def main():
    ma = ModularArithmetics()
    print('Is 13 prime? ' + str(ma.isPrime(13)))
    print('Is 121 prime? ' + str(ma.isPrime(121)))
    print('Random prime [1, 20]: ' + str(ma.randomPrime(1, 20)))
    print('Modular power 9^2 (mod 1000): ' + str(ma.modularPower(2, 4, 1000)))
    print('GCD 12, 400: ' + str(ma.findGCD(12, 400)))
    # print('Prime from file: ' + str(ma.randomPrimeFromFile()))
    print('Modular Inverse 5 (mod 11) = ' + str(ma.modularInverse(a=5, m=11)))

if __name__ == '__main__':
    main()


import numpy as np

def ref_rbf_kernel(X, lengthscale, signal_var):
    N, _ = X.shape
    kernel = np.zeros((N, N))
    for row_index in range(N):
        for column_index in range(N):
            vecA = X[row_index, :]
            vecB = X[column_index, :]
            delta = vecA - vecB
            distance_squared = np.dot(delta.T, delta)
            kernel[row_index, column_index] = \
                signal_var * np.exp(-0.5 * distance_squared / lengthscale ** 2)
    return kernel

def ref_arccosine_kernel(X, order, weightVariances, biasVariance, signal_var):
    num_points = X.shape[0]
    kernel = np.empty((num_points, num_points))
    for row in range(num_points):
        for col in range(num_points):
            x = X[row]
            y = X[col]

            numerator = (weightVariances * x).dot(y) + biasVariance

            x_denominator = np.sqrt((weightVariances * x).dot(x) +
                                    biasVariance)
            y_denominator = np.sqrt((weightVariances * y).dot(y) +
                                    biasVariance)
            denominator = x_denominator * y_denominator

            theta = np.arccos(np.clip(numerator / denominator, -1., 1.))
            if order == 0:
                J = np.pi - theta
            elif order == 1:
                J = np.sin(theta) + (np.pi - theta) * np.cos(theta)
            elif order == 2:
                J = 3. * np.sin(theta) * np.cos(theta)
                J += (np.pi - theta) * (1. + 2. * np.cos(theta)**2)

            kernel[row, col] = signal_var * (1. / np.pi) * J * \
                x_denominator ** order * \
                y_denominator ** order
    return kernel

def ref_periodic_kernel(X, lengthscale, signal_var, period):
    # Based on the GPy implementation of standard_period kernel
    base = np.pi * (X[:, None, :] - X[None, :, :]) / period
    exp_dist = np.exp(-0.5 *
                      np.sum(np.square(np.sin(base) / lengthscale), axis=-1))
    return signal_var * exp_dist


from math import sin, pi
import random
import numpy as np
from scipy.stats import norm

def black_box_projectile(theta, v0=10, g=9.81):
    assert theta >= 0
    assert theta <= 90
    return (v0 ** 2) * sin(2 * pi * theta / 180) / g

def random_shooting(n=1, min_a=0, max_a=90):
    assert min_a <= max_a
    return [random.uniform(min_a, max_a) for i in range(n)]

def pick_elites(actions, M_elites):
    actions = np.array(actions)
    assert M_elites <= len(actions)
    assert M_elites > 0
    results = np.array([black_box_projectile(a)
                        for a in actions])
    sorted_ix = np.argsort(results)[-M_elites:][::-1]
    return actions[sorted_ix], results[sorted_ix]

def try_random_shooting(trials=10000, n=20):
    print("Trying random shooting.")
    best_results = []
    best_actions = []
    for i in range(trials):
        actions_to_try = random_shooting(n)
        best_action, best_result = pick_elites(actions_to_try, 1)
        best_results.append(best_result[0])
        best_actions.append(best_action[0])
    print(f"Out of {trials} trials:")
    print(f"- Average score is {round(np.mean(best_results), 2)}")
    print(f"- Average action is {round(np.mean(best_actions), 2)}")
    print(f"- Action SD is {round(np.std(best_actions), 2)}")

def try_cem_normal(trials=10000, N=5, M_elites=2, iterations=3):
    print("Trying CEM.")
    best_results = []
    best_actions = []
    for i in range(trials):
        print(f"================ trial {i}")
        print("--iteration: 1")
        actions_to_try = random_shooting(N)
        elite_acts, _ = pick_elites(actions_to_try, M_elites)
        print(f"actions_to_try: {np.round(actions_to_try, 2)}")
        print(f"elites: {np.round(elite_acts, 2)}")
        for r in range(iterations - 1):
            print(f"--iteration: {r + 2}")
            mu, std = norm.fit(elite_acts)
            print(f"fitted normal mu: {np.round(mu, 2)}, std: {np.round(std, 2)}")
            actions_to_try = np.clip(norm.rvs(mu, std, N), 0, 90)
            elite_acts, elite_results = pick_elites(actions_to_try,
                                                    M_elites)
            print(f"actions_to_try: {np.round(actions_to_try, 2)}")
            print(f"elites: {np.round(elite_acts, 2)}")
        mu, std = norm.fit(elite_acts)
        print(f"final action: {np.round(mu, 2)}")
        best_results.append(black_box_projectile(mu))
        best_actions.append(np.clip(mu, 0, 90))
    print(f"Out of {trials} trials:")
    print(f"- Average score is {round(np.mean(best_results), 2)}")
    print(f"- Average action is {round(np.mean(best_actions), 2)}")
    print(f"- Action SD is {round(np.std(best_actions), 2)}")


import numpy as np
import tinynn as tn

tn.seeder.random_seed(31)

def test_softmax():
    x = np.array([1.0, 2.0, 3.0, 4.0])
    a = np.exp(x - np.max(x))
    expect = a / a.sum()
    assert np.allclose(tn.math.softmax(x), expect)

    x = np.array([1e10, 1e10])
    expect = [0.5, 0.5]
    assert np.allclose(tn.math.softmax(x), expect)

def test_log_softmax():
    x = np.random.uniform(0, 1, 10)
    assert np.allclose(tn.math.log_softmax(x), np.log(tn.math.softmax(x)))

    x = np.random.uniform(1e10, 1e10, 10)
    assert np.allclose(tn.math.log_softmax(x), np.log(tn.math.softmax(x)))

def test_sigmoid():
    assert tn.math.sigmoid(1e10) == 1.0
    assert tn.math.sigmoid(-1e10) == 0.0
    assert tn.math.sigmoid(0) == 0.5


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

import numpy as np
import os
from PIL import Image
import matplotlib.pyplot as plt
import matplotlib as mpl
from pprint import pprint

def restore1(sigma, u, v, K):  # 奇异值、左特征向量、右特征向量
    m = len(u)
    n = len(v[0])
    a = np.zeros((m, n))
    for k in range(K):
        uk = u[:, k].reshape(m, 1)
        vk = v[k].reshape(1, n)
        a += sigma[k] * np.dot(uk, vk)
    a[a < 0] = 0
    a[a > 255] = 255
    # a = a.clip(0, 255)
    return np.rint(a).astype('uint8')

def restore2(sigma, u, v, K):  # 奇异值、左特征向量、右特征向量
    m = len(u)
    n = len(v[0])
    a = np.zeros((m, n))
    for k in range(K + 1):
        for i in range(m):
            a[i] += sigma[k] * u[i][k] * v[k]
    a[a < 0] = 0
    a[a > 255] = 255
    return np.rint(a).astype('uint8')

if __name__ == "__main__":
    A = Image.open("6.son.png", 'r')
    output_path = r'./pic'
    if not os.path.exists(output_path):
        os.mkdir(output_path)
    a = np.array(A)
    K = 50
    u_r, sigma_r, v_r = np.linalg.svd(a[:, :, 0])
    u_g, sigma_g, v_g = np.linalg.svd(a[:, :, 1])
    u_b, sigma_b, v_b = np.linalg.svd(a[:, :, 2])
    plt.figure(figsize=(10, 10), facecolor='w')
    mpl.rcParams['font.sans-serif'] = [u'simHei']
    mpl.rcParams['axes.unicode_minus'] = False
    for k in range(1, K + 1):
        print(k)
        R = restore1(sigma_r, u_r, v_r, k)
        G = restore1(sigma_g, u_g, v_g, k)
        B = restore1(sigma_b, u_b, v_b, k)
        I = np.stack((R, G, B), 2)
        Image.fromarray(I).save('%s/svd_%d.png' % (output_path, k))
        if k <= 12:
            plt.subplot(3, 4, k)
            plt.imshow(I)
            plt.axis('off')
            plt.title(u'奇异值个数：%d' % k)
    plt.suptitle(u'SVD与图像分解', fontsize=18)
    plt.tight_layout(2)
    plt.subplots_adjust(top=0.9)
    plt.show()


'''
This script demonstrate how to optimize the hyperparameters for a
Gaussian process based on the marginal likelihood. Optimization is
performed in two ways, first with a grid search method and then with a
downhill simplex method.
'''
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import fmin
from rbf.gauss import gpexp
np.random.seed(3)

# True signal which we want to recover. This is a exponential function
# with mean=0.0, variance=2.0, and time-scale=0.1. For graphical
# purposes, we will only estimate the variance and time-scale.
a,b,c = 0.0, 2.0, 0.1
gp  = gpexp((a, b, c))

n = 500 # number of observations
time = np.linspace(-5.0, 5.0, n)[:,None] # observation points
data = gp.sample(time) # signal which we want to describe

# find the optimal hyperparameter with a brute force grid search
b_search = 10**np.linspace(-2, 2, 30)
c_search = 10**np.linspace(-2, 1, 30)
likelihoods = np.zeros((30, 30))
for i, b_test in enumerate(b_search):
  for j, c_test in enumerate(c_search):
    gp = gpexp((0.0, b_test, c_test))
    likelihoods[i, j] = gp.likelihood(time, data)

# find the optimal hyperparameters with a positively constrained
# downhill simplex method
def fmin_pos(func, x0, *args, **kwargs):
  '''fmin with positivity constraint'''
  def pos_func(x, *blargs):
    return func(np.exp(x), *blargs)

  out = fmin(pos_func, np.log(x0), *args, **kwargs)
  out = np.exp(out)
  return out

def objective(x,t,d):
  '''objective function to be minimized'''
  gp = gpexp((0.0,x[0],x[1]))
  return -gp.likelihood(t,d)

# maximum likelihood estimate
b_mle, c_mle = fmin_pos(objective, [1.0, 1.0], args=(time, data))

# plot the results
fig, axs = plt.subplots(2, 1, figsize=(6, 6))
ax = axs[0]
ax.grid(True)
ax.plot(time[:,0], data, 'k.', label='observations')
ax.set_xlim((-5.0, 5.0))
ax.set_ylim((-5.0, 7.0))
ax.set_xlabel('time', fontsize=10)
ax.set_ylabel('observations', fontsize=10)
ax.tick_params(labelsize=10)
ax.text(0.55, 0.925, r"$\bar{u}(x) = a$", transform=ax.transAxes)
ax.text(0.55, 0.85, r"$C_u(x,x') = b\times\exp(-|x - x'|/c)$", transform=ax.transAxes)
ax.text(0.55, 0.775, r"$a = %s$, $b = %s$, $c = %s$" % (a, b, c), transform=ax.transAxes)

ax = axs[1]
ax.set_yscale('log')
ax.set_xscale('log')
ax.set_xlabel('variance ($b$)', fontsize=10)
ax.set_ylabel('time-scale ($c$)', fontsize=10)
ax.tick_params(labelsize=10)
p = ax.contourf(b_search, c_search, likelihoods.T, np.linspace(-5000.0, -200.0, 11), cmap='viridis')
cbar = plt.colorbar(p, ax=ax)
ax.plot([b], [c], 'ro', markersize=10, mec='none', label='truth')
ax.plot([b_mle], [c_mle], 'ko', markersize=10, mec='none', label='max likelihood')
ax.legend(fontsize=10, loc=2)
cbar.set_label('log likelihood', fontsize=10)
cbar.ax.tick_params(labelsize=10)
ax.grid(True)
plt.tight_layout()
plt.savefig('../figures/gauss.f.png')
plt.show()


import matplotlib.pyplot as plt
import numpy as np

def gen_data(n, start=0, end=10):
    x = np.linspace(start, end, n)
    y = np.sin(10*x) - x*x
    return y

def gen_data_osc(n):
    return np.array([1024 + (-2)**(-i/25) for i in range(n)])

def gen_data_rand(n):
    return np.random.randn(n) + 0.3*np.linspace(0, 10, n)

def calc_cov(X, Y):
    return np.sum((X - np.average(X))*(Y - np.average(Y))) / (X.shape[0] - 1)

def angular_coef(X,Y):
    return calc_cov(X,Y)/calc_cov(X,X)

def linear_coef(a, X, Y):
    return np.average(Y) - a*np.average(X)

def kg_coef(est, measurement):
    return est / (est + measurement)

def kg_iter(prev, measurement):
    return prev + kg_coef(prev, measurement) * (measurement - prev)

def calc_cov_step(X, Y, X_avg, Y_avg, conv_sum, data_size):
    return (conv_sum + ((X - X_avg)*(Y - Y_avg))) / (data_size - 1)

def angular_coef_step(X, Y, X_sum, Y_sum, XY_conv_sum, XX_conv_sum, data_size):
    X_avg = X_sum/data_size
    Y_avg = Y_sum/data_size
    return calc_cov_step(X, Y, X_avg, Y_avg, XY_conv_sum, data_size)/calc_cov_step(X, X, X_avg, X_avg, XX_conv_sum, data_size)

def linear_coef_step(a, X_sum, Y_sum, data_size):
    X_avg = X_sum/data_size
    Y_avg = Y_sum/data_size
    return Y_avg - a*X_avg

count = 100
end = 100
time = np.linspace(0, end, count)
data = gen_data(count)

delta = end / count

preds = []
kg_preds = []
preds_step = []
kg_preds_step = []

X_sum = time[0]
Y_sum = data[0]

data_size = 2
XY_conv_sum = 0
XX_conv_sum = 0

decay = 0.99

for i in range(1, count):
    #Update data sum
    X_sum += time[i-1]
    Y_sum += data[i-1]

    #Calculate AVG
    X_avg = X_sum/data_size
    Y_avg = Y_sum/data_size

    #Calculate angular and linear coeficient using iterative function
    a_step = angular_coef_step(time[i-1], data[i-1], X_sum, Y_sum, XY_conv_sum, XX_conv_sum, data_size)
    b_step = linear_coef_step(a_step, X_sum, Y_sum, data_size)

    #Update XY and XX conv sum
    XY_conv_sum = (XY_conv_sum*(1-decay)) + ((time[i-1] - X_avg)*(data[i-1] - Y_avg))
    XX_conv_sum = (XX_conv_sum*(1-decay)) + ((time[i-1] - X_avg)*(time[i-1] - X_avg))

    #Calculate angular and linear coeficient using old function
    a = angular_coef(time[:i], data[:i])
    b = linear_coef(a, time[:i], data[:i])

    #Calculating prediction using Min. Quad.
    prediction = (time[i]+delta)*a + b
    prediction_step = (time[i-1]+delta)*a_step + b_step
    #Calculating prediction using Kalman Filter
    kg_prediction = kg_iter(prediction, data[i-1])
    kg_prediction_step = kg_iter(prediction_step, data[i-1])

    #Creating arrays of data to create Graph
    preds.append(prediction)
    kg_preds.append(kg_prediction)
    preds_step.append(prediction_step)
    kg_preds_step.append(kg_prediction_step)

    #Update data size
    data_size += 1

#calculate Min. Qua. line
minQuadLine = time*a + b

#calculate Min. Qua. line
minQuadLineWithDecay = time*a_step + b_step

plt.scatter(time, data, label="Medições", color="#FF5850")
plt.scatter(time[1:], preds, label="Est. Min. Quad.", color="#62B21C")
plt.scatter(time[1:], kg_preds, label="Est. Kalman", color="#C000FF")
plt.scatter(time[1:], preds_step, label="Est. Min. Quad. Iterativo com Decaimento", color="#1CB262")
plt.scatter(time[1:], kg_preds_step, label="Est. Kalman Iterativo com Decaimento", color="#FF00C0")
plt.plot(time, minQuadLine, label="Min. Quad. Final", color="#36A1FF")
plt.plot(time, minQuadLineWithDecay, label="Min. Quad. Final Iterativo com Decaimento", color="#FFA136")
plt.xlabel("Tempo")
plt.ylabel("Temperatura")
plt.title("Aproximação Por Kalman Filter Iterativo com Decaimento de %0.2f" %decay)
# Place a legend to the right of this smaller subplot.
plt.legend()

plt.show()

Data Fusion Test/Kalman Filter Iterativo Com Decaimento.py


import numpy as np
import warnings
from collections import Counter
import pandas as pd
import random

def k_nearest_neighbors(data, predict, k=3):
    if len(data) >= k:
        warnings.warn('K is set to a value less than total voting groups!')
    distances = []
    for group in data:
        for features in data[group]:
            euclidean_distance = np.linalg.norm(np.array(features) - np.array(predict))
            distances.append([euclidean_distance, group])
        votes = [i[1] for i in sorted(distances)[:k]]
        vote_result = Counter(votes).most_common(1)[0][0]
        return vote_result

df = pd.read_csv('./etc/breast-cancer-wisconsin.data')
df.replace('?', -99999, inplace=True)
df.drop(['id'], 1, inplace=True)
full_data = df.astype(float).values.tolist()

random.shuffle(full_data)

test_size = 0.2
train_set = {2: [], 4: []}
test_set = {2: [], 4: []}
train_data = full_data[:-int(test_size * len(full_data))]
test_data = full_data[-int(test_size * len(full_data)):]

for i in train_data:
    train_set[i[-1]].append(i[:-1])

for i in test_data:
    test_set[i[-1]].append(i[:-1])

correct = 0
total = 0

for group in test_set:
    for data in test_set[group]:
        vote = k_nearest_neighbors(train_set, data, k=5)
        if group == vote:
            correct += 1
        total += 1
print('Total: ', total)
print('Correct: ', correct)
print('Accuracy: {:2f}%'.format((correct/total)*100.0))


import numpy as np

def pearson_correlation(y_pred,y_true):
    """ calculation the pearson correlation coefficient

    如果输入的是二维矩阵，那么就计算多个feature的平均相关系数。

    Parameters
    -------------

    y_pred : 1d array-like the vector of predicted y
        or 2d array-like shape(n_samples, n_features)

    y_true : 1d array-like the vector of ground true y
        or 2d array-like shape(n_samples, n_features)

    Returns
    -------------

    cor : double

    """

    # solve 1d array-like y
    if (len(y_pred.shape) == len(y_true.shape) and len(y_true.shape) ==1 ):
        result = np.corrcoef(y_pred, y_true)
        return result[0][1]
    # solve 2d array-like y

    # column : features
    # row : sample
    # 计算矩阵的转置
    pre_Y_T = y_pred.T
    validation_Y_T = y_true.T
    # 得到矩阵后计算相关系数
    # 分别计算6个情绪的相关系数
    value_d = y_pred.shape[1] # 数据有多少维度？
    corrcoef_s = np.zeros((1,value_d))
    for i in range(0,value_d):
        result = np.corrcoef(pre_Y_T[i],validation_Y_T[i])
        # print('i: pre:\n')
        # print(pre_Y_T[i])
        # print('i: validation:\n')
        # print(validation_Y_T[i])
        # print(result)
        corrcoef_s[0][i] = result[0][1]
    return np.average(corrcoef_s)


# In this program that uses sympy, I am computing the recurrence relation
# for the factorial programs with and without Karatsuba algorithm ....

from sympy import *

# A short example ....

print('Some initial example y(n)-y(n-1)+(n-2) = 0 ')

y = Function('y')
n = var('n',integer=True)
f = y(n)-y(n-1)+(n-2)
print(rsolve(f,y(n)))

# Number of digits in n! for large n, Log(n!) ~ n Log(n)
# Proof below ....

print(
    "limit(log(gamma(n+1))/(n*log(n)),n,oo,"'+'")",
    limit(log(gamma(n+1))/(n*log(n)),n,oo,"+")
    )

# Karatsuba algorithm ...

print('Karatsuba algorithm f(n) - 3*f(n-1) - k * 2**n - m == 0 ')

f = Function('f')
k, m = symbols('k m')
cr = rsolve(f(n) - 3*f(n-1) - k * 2**n - m,f(n))
print(
    simplify(
    simplify(cr.subs(n,log(n))).subs(n,n*log(n))
    ))

# Some manual solving gives Tfact(n) = O( (n log n)**1.58 )

# School book algorithm algorithm ...

print('School book algorithm f(n) - 4*f(n-1) - k * 2**n - m == 0 ')

f = Function('f')
k, m = symbols('k m')
cr = rsolve(f(n) - 4*f(n-1) - k * 2**n - m,f(n))
print(
    simplify(
    simplify(cr.subs(n,log(n))).subs(n,n*log(n))
    ))

# Some manual solving gives Tfact(n) = O( (n log n)**2 )


"""
Exercise 3
Your challenge is to write a program that's capable of finding the sum of an
arbitrary series when you supply the nth term of the series and the number of
terms in it. Here's and example of how the program would work:
Enter the nth term: a+(n-1)*d
Enter the number of terms: 3
3a + 3d
In this example, the nth term supplied is that of an arithmetic progression.
Starting with a and d as the common difference, the number of terms up to a
which the sum is to be calculated is 3. The sum turns out the be 3a + 3d, which
agrees with the known formula for the same.
"""
from sympy import expand, summation, sympify, Symbol
from sympy.core.sympify import SympifyError

expr = input("Enter the nth term: ")

try:
    expr = sympify(expr)
except SympifyError:
    print("Invalid input")

terms = input("Enter the number of terms: ")

print(expand(summation(expr, (Symbol("n"), 1, terms))))


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
import math
print("Linear Regression Project")

# Data reading and creation data frame
house_data = pd.read_csv('house_prices.csv')
#print(house_data)
size = house_data['sqft_living']
#print(size)
price = house_data['price']
#print(price)

# removing index column
x = np.array(size).reshape(-1,1)
y = np.array(price).reshape(-1,1)

# we use linear Regression + fit() method for training
model = LinearRegression()
model.fit(x, y)

# MSE and R value
regression_model_mse = mean_squared_error(x, y)
print("MSE: ", math.sqrt(regression_model_mse))
print("R square value: ",model.score(x,y))

# we can get the b values after the model fit
# this is b1
print(model.coef_[0])
# This is b0 in our model
print(model.intercept_[0])

# visualize the data-set with the fitted model
plt.scatter(x,y,color="green")
plt.plot(x,model.predict(x),color="black")
plt.title("Linear Regression")
plt.xlabel("Size")
plt.ylabel("Price")
plt.show()

# predicting the price
print("Prediction by model: ", model.predict([[2000]]))


"""
Illustrating how FFT works
from https://alphabold.com/fourier-transform-in-python-vibration-analysis/
"""

import numpy as np
import matplotlib.pyplot as plt
from scipy import pi
from scipy.fftpack import fft

#set sample rate and generate time array
sample_rate = 1024
max_time = 2
N = max_time * sample_rate
time = np.linspace(0, max_time, N)

#generate a time signal that is the sum of two sinusoids
freq1 = 100
a1 = 17
freq2 = 340
a2 = 6
waveform1 = a1 * np.sin (2 * pi * freq1 * time)
waveform2 = a2 * np.sin (2 * pi * freq2 * time)
time_signal = waveform1 + waveform2

#plot a portion of the time signal
plt.plot (time[0:100] , time_signal[0:100])
plt.title ('Time Domain Signal')
plt.xlabel ('Time')
plt.ylabel ('Amplitude')
plt.show ()

#generate the frequency array
frequency = np.linspace (0.0, sample_rate/2, int (N/2))

#take fft of the time signal and compute its magnitude
freq_data = fft(time_signal)
fft_magnitude = 2/N * np.abs (freq_data [0:np.int (N/2)])

#plot the magnitude of the fft
plt.plot(frequency, fft_magnitude)
plt.title('Frequency domain Signal')
plt.xlabel('Frequency in Hz')
plt.ylabel('Amplitude')
plt.show()


#!/usr/bin/env python3

# fit to a1*sin(w1 * x + f1) + a2*sin(w2 * x + f2)
import sys
sys.path.append('.')

import numpy as np
from matplotlib import pyplot as plt
from curve_fit import annealing

def f(x,p):
    return p[0]*np.sin(p[1]*x + p[2]) + p[3]*np.sin(p[4]*x+p[5])

xdata = np.linspace(-100,100,1000)
ydata = f(xdata, [1, 1, 0, 1, 0.9, 0])

plt.plot(xdata, ydata, label='data')
bounds=[[0,2],[0,2],[0,2*np.pi],[0,2],[0,2],[0,2*np.pi]]

result = annealing.curve_fit(f, xdata, ydata, bounds=bounds)

pres = result.x
ydata_res = f(xdata, pres)
plt.plot(xdata, ydata_res, label='fit')
plt.legend()
plt.grid()

plt.show()


import numpy as np

def equirect_proj(x_proj, y_proj, W, H, fov):
    """Return the equirectangular projection on a unit sphere,
    given cartesian coordinates of the de-warped image."""
    theta_alt = x_proj * fov / W
    phi_alt = y_proj * np.pi / H

    x = np.sin(theta_alt) * np.cos(phi_alt)
    y = np.sin(phi_alt)
    z = np.cos(theta_alt) * np.cos(phi_alt)

    return np.arctan2(y, x), np.arctan2(np.sqrt(x**2 + y**2), z)

def buildmap(Ws, Hs, Wd, Hd, fov=180.0):
    """Return a mapping from de-warped images to fisheye images."""
    fov = fov * np.pi / 180.0

    # cartesian coordinates of the de-warped rectangular image
    ys, xs = np.indices((Hs, Ws), np.float32)
    y_proj = Hs / 2.0 - ys
    x_proj = xs - Ws / 2.0

    # spherical coordinates
    theta, phi = equirect_proj(x_proj, y_proj, Ws, Hs, fov)

    # polar coordinates (of the fisheye image)
    p = Hd * phi / fov

    # cartesian coordinates of the fisheye image
    y_fish = p * np.sin(theta)
    x_fish = p * np.cos(theta)

    ymap = Hd / 2.0 - y_fish
    xmap = Wd / 2.0 + x_fish
    return xmap, ymap


import numpy as np
import logging

from src.utilities import calculate_euclidean_distance

logging.basicConfig(filename='kmeans.log',level=logging.DEBUG)

class KMeans:
    def __init__(self, dataset, clusters_no, stop_threshold=0.01):
        self.dataset = dataset
        self.k = clusters_no
        self.stop_threshold = stop_threshold
        self.clusters = {}

    def find_closest_centroid(self, point, centroids):
        """Computes the closest centroid from a list of centroids to the point."""
        min_dist = np.inf
        min_centroid_inx = -1
        for centroid_inx in range(len(centroids)):
            dist = calculate_euclidean_distance(point, centroids[centroid_inx])
            logging.info('point: {}, centroid: {}, dist: {}'.format(point, centroids[centroid_inx], dist))
            if dist < min_dist:
                min_centroid_inx = centroid_inx
                min_dist = dist
        return min_centroid_inx

    def initialize_centroids(self):
        """initialize centroids randomly"""
        idx = np.random.randint(self.dataset.shape[0], size=self.k)
        centroids = self.dataset[idx,:]
        return centroids

    def update_centroids(self, clusters_assignment):
        """Take a cluster assignment and compute the centroids"""
        new_centroids = []
        for centroid_inx, points in clusters_assignment.items():
            if points:
                new_centroid = np.mean(np.array(points),0)
            logging.info('points: {} new centroid: {}'.format(points, new_centroid))
            new_centroids.append(new_centroid)
        return new_centroids

    def is_close_enough(self, centroids, new_centroids):
        """Check if new centroids are very close to last iteration centroids"""
        # test for stopping the iteration
        for inx in range(len(centroids)):
            dist = calculate_euclidean_distance(centroids[inx], new_centroids[inx])
            logging.info('dist: {}'.format(dist))
            if dist > self.stop_threshold:
                return False
        return True

    def k_means(self, centroids):
        if len(centroids) == 0:
            # initilization step
            centroids = self.initialize_centroids()
            logging.info('initial centroids: {}'.format(centroids))
        clusters_assignment = {}
        # cluster assignment
        for point in self.dataset:
            cluster_inx = self.find_closest_centroid(point, centroids)
            logging.info('point: {}, cluster_inx: {}'.format(point, cluster_inx))
            try:
                clusters_assignment[cluster_inx].append(point)
            except:
                clusters_assignment[cluster_inx] = [point]
        logging.info('cluster assignment: {}'.format(clusters_assignment))
        # update centroids
        new_centroids = self.update_centroids(clusters_assignment)
        logging.info('centroid: {}'.format(centroids))
        logging.info('new centroid: {}'.format(new_centroids))
        # test for stopping the iterations
        if self.is_close_enough(centroids, new_centroids):
            logging.info('stop condition reached --> clusters_assignment: {}'.format(clusters_assignment))
            # centroid have not been changed so much
            return clusters_assignment
        return self.k_means(new_centroids)

    def fit(self):
        self.clusters = self.k_means([])


#!/usr/bin/python2

import csv
import numpy as np
import matplotlib.pyplot as plt
import time

from itertools import chain
from collections import defaultdict

def read(filename):
    result = defaultdict(list)
    with open(filename, "r") as c:
        reader = csv.reader(c, delimiter=";")
        for row in reader:
            month = int(row[1].split("/")[1])
            precipitation = float(row[3])
            result[month].append(precipitation)
    return result

def write(filename, data, year):
    with open(filename, "w") as c:
        writer = csv.writer(c, delimiter=";")
        for month in sorted(data.keys()):
            for day, value in enumerate(data[month]):
                writer.writerow([
                    83743, "{:02}/{:02}/{}".format(day + 1, month, year),
                    1200, value])

def remove_outliers(data, thresh=2.5):
    full_data = np.asarray(tuple(chain.from_iterable(data[i]
                                 for i in sorted(data.keys()))))
    non_zeros = full_data != 0
    median = np.median(full_data[non_zeros])
    result = {}
    for month in data:
        values = np.asarray(data[month])[:, None]
        diff = np.sum((values - median)**2, axis=-1)
        diff = np.sqrt(diff)
        med_abs_deviation = np.median(diff)

        modified_z_score = 0.6745 * diff / med_abs_deviation

        outliers = modified_z_score > thresh
        non_outliers = modified_z_score <= thresh

        new_data = np.zeros(len(values))
        new_data[non_outliers] = np.transpose(values[non_outliers])[0]
        new_data[outliers] = median

        result[month] = new_data.tolist()
    return result

def prepare(series, months, names, div=.1, colors=["b", "g", "r"]):
    fig, ax = plt.subplots()

    ax.set_ylabel("Precipitation (mm)")
    ax.set_xlabel("Month")
    ax.set_title("Precipitation by Month")
    ax.set_xticks(months + .5)
    ax.set_xticklabels(list(map(str, months)))
    ax.set_ylim([0, 400])

    half_div = div / 2.0
    width = (1.0 - div) / len(series)
    bars = []
    for i, data in enumerate(series):
        bars.append(ax.bar(months + half_div + i * width, data, width,
                           color=colors[i]))

    ax.legend(bars, names)

def create_bargraph(output, months, years, *prec):
    prepare(prec, months, years)
    plt.savefig(output)

def sum_by_month(data, months):
    time.sleep(1)
    return [sum(data[i]) for i in months]

__VERSION__ = "1.1.0"

if __name__ == "__main__":
    import sys
    filename = sys.argv[1]
    month = sys.argv[2]
    data = read(filename)
    print(";".join(map(str, data[int(month)])))


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Jul 25 21:28:47 2018

@author: juancarlosqr
"""

import numpy as np

l1 = [100,200,300]
a = np.array(l1)
a
a[0]
a[1]
a[2]
a.dtype
# dtype('int64')
a.ndim # dimensions
# 1
a.size # length
# 3
a.shape # (len(1st-dim array), ..., len(n-th-dim array))
# (3,)

l2 = [[10,100],[20,200],[30,300]]
b = np.array(l2)
b
b[0]
b.ndim
# 2
b.size
# 6
b.shape
# (3, 2)

l3 = [[[10,100],[20,200],[30,300]], [[40,400],[50,500],[60,600]]]
c = np.array(l3)
c
c[0]
c[0][1]
c.ndim
# 3
c.size
# 12
c.shape
# (2, 3, 2)
c.itemsize # size in bytes
# 8

l4 = [[10,100,1000,10000], [20,200,2000,20000], [30,300, 3000,30000]]
d = np.array(l4)
d
d[0]
d.ndim
# 2
d.size
# 12
d.shape
# (3, 4)
d.itemsize # size in bytes
# 8
d.data
# <memory at 0x11d4ff2d0>

# with tuples

t1 = ((10,100),(20,200),(30,300),(40, 400))
e = np.array(t1)
e
e.dtype
e.dtype.name
e[0]
e.ndim
# 2
e.size
# 8
e.shape
# (4, 2)

l5 = [100,200,300]
f = np.array(l1, dtype=complex)
f
# array([ 100.+0.j,  200.+0.j,  300.+0.j])
f.dtype
# dtype('complex128')