import numpy as np
import math

def euclidiana(vetor): # norma-2 vetorial
    n, x = len(vetor), 0

    for i in range(n):
        x += math.fabs(vetor[i]) ** 2

    return x ** (1/2)

def manhattan(vetor): # norma-1 vetorial
    n, x = len(vetor), 0

    for i in range(n):
        x += math.fabs(vetor[i])

    return x

def p(vetor, p): #norma-p vetorial
    n, x = len(vetor), 0

    for i in range(n):
        x += math.fabs(math.pow(vetor[i], p))

    return x ** (1/p)

def infinita(vetor): # norma-infinita vetorial
    n, max = len(vetor), vetor[0]

    for i in range(1, n):
        if math.fabs(vetor[i]) > max:
            max = math.fabs(vetor[i])

    return max

def frobenius(matriz_a): # norma-2 matricial
    n, x = len(matriz_a), 0

    for i in range(n):
        for j in range(n):
            x += math.pow(math.fabs(matriz_a[i,j]), 2)

    return x ** (1/2)

def soma_coluna(matriz_a): # norma-1 matricial
    n, max, x = len(matriz_a), 0, 0

    for j in range(n):
        for i in range(n):
            x += math.fabs(matriz_a[i,j])

        if x > max:
            max = x

    return max

def soma_linha(matriz_a): # norma-infinita matricial
    n, max, x = len(matriz_a), 0, 0

    for i in range(n):
        for j in range(n):
            x += math.fabs(matriz_a[i,j])

        if x > max:
            max = x

    return max

def residual(matriz_a, vetor_b, delta_x): #norma-residual matricial
    n, k = len(matriz_a), np.linalg.cond(matriz_a)
    delta_b = np.matmul(matriz_a, delta_x)
    vetor_r = vetor_b - delta_b

    vetor_x = np.ones(n)
    vetor_x_menos_delta_x = vetor_x - delta_x
    residuo_r_b = euclidiana(vetor_r)/euclidiana(vetor_b)

    print("Vetor residual:\n", vetor_r)
    print("Resíduo da solução x:", residuo_r_b)

    if euclidiana(vetor_x_menos_delta_x)/euclidiana(vetor_x) <= k*residuo_r_b:
        print("A solução encontrada é precisa.")
    else:
        print("A solução encontrada não é precisa.")


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Jul 17 16:07:48 2019

@author: TempestGuerra
"""

import numpy as np
from numpy import multiply as mul
from scipy import linalg as las
import math as mt
from scipy.special import roots_hermite
from scipy.special import roots_chebyt

def hefunclb(NX):
       #'''
       # Compute off-diagonals of 7.84 in Spectral Methods, Springer
       b = range(1,NX+1)
       bd = 0.5 * np.array(b)

       # Assemble the matrix
       m1 = np.diag(np.sqrt(bd), k=+1)
       m2 = np.diag(np.sqrt(bd), k=-1)
       mm = np.add(m1,m2)

       # Compute the eigenvalues of this matrix (zeros Hermite polys)
       ew = las.eigvals(mm)
       # Sort the eigenvalues in ascending order and store nodes
       xi = np.sort(np.real(ew))

       # Compute the Hermite function weights
       hf = hefuncm(NX, xi, False)
       w = 1.0 / (NX+1) * np.power(hf, -2.0)
       #'''
       '''
       xi, w = roots_hermite(NX+1)

       # Compute the Hermite function weights
       hf = hefuncm(NX, xi, False)
       w = 1.0 / (NX+1) * np.power(hf, -2.0)
       '''
       return xi, w

def hefuncm(NX, xi, fullMat):
       # Initialize constant
       cst = 1.0 / mt.pi**4;
       ND = len(xi)

       # Initialize the output matrix if needed
       if fullMat:
              HFM = np.zeros((NX+1,ND))

       # Compute the first two modes of the recursion
       wfun = np.exp(-0.5 * np.power(xi, 2.0))
       poly0 = cst * wfun;
       poly1 = cst * mt.sqrt(2.0) * (xi * wfun);

       # Put the first two functions in the matrix or return low order functions
       if fullMat:
              HFM[0,:] = poly0
              HFM[1,:] = poly1
       elif NX == 0:
              return poly0
       elif NX == 1:
              return poly1

       for nn in range(1,NX):
              polyn = mt.sqrt(2.0 / (nn+1)) * (xi * poly1)
              polyn -= mt.sqrt(nn / (nn+1)) * poly0
              poly0 = poly1;
              poly1 = polyn;
              # Put the new function in its matrix place
              if fullMat:
                     HFM[nn+1,:] = polyn
              else:
                     HFM = polyn

       return HFM.T

def cheblb(NZ):
       # Compute Chebyshev CGL nodes and weights
       ep = NZ - 1
       xc = np.array(range(NZ))
       xi = -np.cos(mt.pi / ep * xc)

       w = mt.pi / NZ * np.ones(NZ)
       w[0] *= 0.5
       w[ep] *= 0.5

       return xi, w

def chebpolym(NM, xi):
       # Compute Chebyshev pols (first kind) into a matrix transformation
       # Functions need to be arranged bottom to top!
       NX = len(xi)
       CTM = np.zeros((NX, NM+1))

       CTM[:,0] = np.ones(NX)
       CTM[:,1] = xi

       # 3 Term recursion for functions
       for ii in range(2, NM+1):
              CTM[:,ii] = 2.0 * \
              mul(xi, CTM[:,ii-1]) - \
              CTM[:,ii-2]

       return CTM


from sympy import Matrix
import numpy as np
import random

def GenerateMatrixWithRank(row, column, rank, lowerBound=-9, upperBound=9):
    """
    Generate Matrix with Rank=rank
    Res = A(row x rank) X B(rank x column)
    lowerBound: lower bound for generated entry
    upperBound: upper bound for generated entry
    """
    A = np.array([random.randint(lowerBound, upperBound) for x in range(row*rank)]).reshape(row, rank)
    B = np.array([random.randint(lowerBound, upperBound) for x in range(column*rank)]).reshape(rank, column)

    return np.matmul(A, B)

if __name__ == "__main__":
    rank = 1
    row = 5
    column = 7
    M = GenerateMatrixWithRank(row, column, rank, lowerBound=-3, upperBound=3)
    print(M)
    RREF, cols = Matrix.rref(Matrix(M))
    C = np.array(M)[:,[x for x in cols]]
    R = np.array(RREF)[[x for x in cols],:]

    print("C:")
    print(C)
    print("R:")
    print(R)
    print("C x R:")
    print(np.matmul(C, R))


import numpy as np
import matplotlib.pyplot as plt

# 计算在某一特定t下的 B_{i,k}
def getBt(controlPoints, knots, t):
	# calculate m,n,k
	m = knots.shape[0]-1
	n = controlPoints.shape[0]-1
	k = m - n - 1
	# initialize B by zeros
	B = np.zeros((k+1, m))

	# get t region
	tStart = 0
	for x in range(m+1):
		if t==1:
			tStart = m-1
		if knots[x] > t:
			tStart = x-1
			break

	# calculate B(t)
	for _k in range(k+1):
		if _k == 0:
			B[_k, tStart] = 1
		else:
			for i in range(m-_k):
				if knots[i+_k]-knots[i]== 0:
					w1 = 0
				else:
					w1 = (t-knots[i])/(knots[i+_k]-knots[i])
				if knots[i+_k+1]-knots[i+1] == 0:
					w2 = 0
				else:
					w2 = (knots[i+_k+1]-t)/(knots[i+_k+1]-knots[i+1])
				B[_k,i] = w1*B[_k-1, i] + w2*B[_k-1, i+1]
	return B

# 绘制 B_{i,k}(t)函数
def plotBt(Bt,num, i,k):
	print(k,i)
	Bt = np.array(Bt)
	tt = np.linspace(0,1,num)
	yy = [Bt[t,k,i] for t in range(num)]
	plt.plot(tt, yy)

# 根据最后一列（最高阶次）的 B(t)，即权重，乘以控制点坐标，从而求出曲线上点坐标
def getPt(Bt, controlPoints):
	Bt = np.array(Bt)
	ptArray = Bt.reshape(-1,1) * controlPoints
	pt = ptArray.sum(axis = 0)
	return pt

# 绘制出生成的样条曲线: useReg 表示是否使用曲线有效定义域[t_k, t_{m-k}]
def main1(controlPoints ,knots, useReg = False):

	m = knots.shape[0]-1
	n = controlPoints.shape[0]-1
	k = m - n - 1
	print('n:',n)
	print('m:',m)
	print('k:',k)

	for t in np.linspace(0,1,100):
		if useReg and not(t >= knots[k] and t<= knots[n+1]):
			continue
		Bt = getBt(controlPoints, knots, t)
		Pt = getPt(Bt[k, :n+1], controlPoints)

		plt.scatter(Pt[0],Pt[1],color='b')

	plt.scatter(controlPoints[:,0], controlPoints[:,1],color = 'r')
	plt.show()

# 绘制 B_{i,k} 变化图:如果不给定{i,k}则显示所有B{i,k}(t)图像
def main2(i=-1,k=-1):
	controlPoints = np.array([[50,50], [100,300], [300,100], [380,200], [400,600]])
	knots = np.array([0,1/9,2/9,3/9,4/9,5/9,6/9,7/9,8/9,1])
	m = knots.shape[0]-1
	n = controlPoints.shape[0]-1
	k = m - n - 1
	print('n:',n)
	print('m:',m)
	print('k:',k)
	B = []
	num = 100 # 离散点数目
	for t in np.linspace(0,1,num):
		Bt = getBt(controlPoints, knots, t)
		B.append(list(Bt))

	figure1 = plt.figure('B_{i,k}')
	if i==-1:
		fig = []
		for i in range(n+1):
			for k in range(k+1):
				plotBt(B,num, i,k)
				fig.append('B_{%d,%d}'%(i,k))
	else:
		plotBt(B,num, i,k)
		fig.append('B_{%d,%d}'%(i,k))
	plt.legend(fig)
	plt.show()

if __name__ == '__main__':
    controlPoints = np.array([
                [ 0.00000000e+00 , 0.00000000e+00 ], [-1.73422712e+01 , 2.15658488e-01],
                [-2.35382699e+01 , 3.13403809e-01] ,[-3.76766971e+01,  5.46545379e-01],
                [-4.78039077e+01 , 5.62960911e-01 ],[-5.98447978e+01 ,-7.11339258e-02],
                [-7.74681854e+01, -2.17359351e+00] ,[-8.87793826e+01 ,-1.75073904e+00],
                [-9.63270000e+01, -1.81000000e+00]
                            ])
    knots = np.array([0,0,0,0,1/6,1/3,1/2,2/3,5/6,1,1,1,1])

    main1(controlPoints,knots)


import numpy as np

from compute_cost import compute_cost

def gradient_descent(x, y, size, theta, alpha, iterations):
    """
        Performs gradient descent to optimize the 'theta' parameters. Updates theta for a total of
        inputted 'iterations', with a learning rate 'alpha'.

        Parameters
        ----------
        x : array_like
            Shape (m, n+1), where m is the number of examples, and n is the number of features
            including the vector of ones for the zeroth parameter.

        y : array_like
            Shape (m,), where m is the value of the function at each point.

        size : int
            Number of total training points.

        theta : array_like
            Shape (n+1, 1). Starting parameters of the regression function.

        alpha : float
            The learning rate.

        iterations : int
            The number of iterations for gradient descent.

        Returns
        -------
        theta : array_like
            Shape (n+1, 1). The optimized linear regression parameters.

        cost_history : list
            A list of the values of the cost function after each iteration.
    """

    cost_history = []
    converge = False
    for i in range(iterations):
        temp_cost = compute_cost(x, y, size, theta)
        try:
            if cost_history[-1] - temp_cost <= 0.0001:
                converge = True
        except IndexError:
            pass
        cost_history.append(temp_cost)

        delta = (1 / size) * ((np.dot(theta.T, x)) - y) * x
        delta2 = delta.sum(axis=1, keepdims=True)
        theta = (theta - (alpha * delta2))
    if converge:
        print("The function converged, use less iterations.")
    print(f"The new optimized parameters are: \n{theta}\n")
    return theta, cost_history


# Draw 100000 samples from Normal distribution with stds of interest: samples_std1, samples_std3, samples_std10
import matplotlib.pyplot as plt
import numpy as np

samples_std1 = np.random.normal(20, 1, size=100000)
samples_std3 = np.random.normal(20, 3, size=100000)
samples_std10 = np.random.normal(20, 10, size=100000)

# Make histograms
plt.hist(samples_std1, bins=100, normed = True, histtype = 'step')
plt.hist(samples_std3,bins=100, normed = True, histtype = 'step')
plt.hist(samples_std10, bins=100,normed = True, histtype = 'step')

# Make a legend, set limits and show plot
plt.legend(('std = 1', 'std = 3', 'std = 10'))
plt.ylim(-0.01, 0.42)
plt.show()


# -*-coding:utf-8 -*-
import numpy as np
from scipy import interpolate
import pylab as pl

x=np.linspace(0,10,11)
#x=[  0.   1.   2.   3.   4.   5.   6.   7.   8.   9.  10.]
y=np.sin(x)
xnew=np.linspace(0,10,101)
pl.plot(x,y,"ro")

for kind in ["nearest","zero","slinear","quadratic","cubic"]:#插值方式
    #"nearest","zero"为阶梯插值
    #slinear 线性插值
    #"quadratic","cubic" 为2阶、3阶B样条曲线插值
    f=interpolate.interp1d(x,y,kind=kind)
    # ‘slinear’, ‘quadratic’ and ‘cubic’ refer to a spline interpolation of first, second or third order)
    ynew=f(xnew)
    pl.plot(xnew,ynew,label=str(kind))
pl.legend(loc="lower right")
pl.show()


import numpy as np

print("")
print("Ejercicio 1.1")
A = np.array([[4, -2, 1, ], [3, 6, -4], [2, 1, 8]])
A_inversa = np.linalg.inv(A)
print("")
print("Matriz A")
print(A)
print("")
print("Matriz A^-1")
print(A_inversa)
print("")
print("Verificando A * A^-1")
print(A@A_inversa)

print("")
print("Ejercicio 1.2")
A_inversa_analitica = (1/263)*np.array([[52, 17, 2],[-32, 30, 19],[-9, -8, 30]])
print("")
print("Cifras significativas en A^{-1}")
print(np.log10(np.abs(A_inversa-A_inversa_analitica)))

print("")
print("Ejercicio 2")
b = np.array([12, -25, 32])
x_sol = np.array([+1, -2, +4])
x = np.linalg.solve(A, b)
print("")
print("numerico: {} . analitico: {}".format(x, x_sol))

b = np.array([+4, -10, +22])
x_sol = np.array([+0.312, -0.038, +2.677])
x = np.linalg.solve(A, b)
print("")
print("numerico: {} . analitico: {}".format(x, x_sol))

b = np.array([+20, -30, +40])
x_sol = np.array([+2.319, -2.965, +4.790])
x = np.linalg.solve(A, b)
print("")
print("numerico: {} . analitico: {}".format(x, x_sol))

print("")
print("Ejercicio 3")
alpha = 2.0
beta = 1.0
A = np.array([[alpha, beta], [-beta, alpha]])
values, vectors = np.linalg.eig(A)
print("")
print('lambda_1 {}. eigenvec_1 {}'.format(values[0], vectors[:,0]))
print('lambda_2 {}. eigenvec_2 {}'.format(values[1], vectors[:,1]))
print('son complejos conjugados como se esperaba')

print("Ejercicio 4")
A = np.array([[-2, +2, -3], [+2, +1, -6], [-1, -2, +0]])
values, vectors = np.linalg.eig(A)
print("")
print("Obtengo autovalores: {}. Esperaba {} {} {}".format(values, 5, -3, -3))
eigen_5 = 1/np.sqrt(6)*np.array([-1, -2, +1])
eigen_3_a = 1/np.sqrt(5)*np.array([-2, +1, 0])
eigen_3_b = 1/np.sqrt(10)*np.array([3, 0, +1])

print("")
print("Eigenvector para lambda=5: {} (que es proporcional a {})".format(vectors[:,1], eigen_5))

print("")
print("Eigenvector para lambda=3: {} ".format(vectors[:,0]))
beta_a = vectors[1,0]*np.sqrt(5) # componente y
beta_b = vectors[2,0]*np.sqrt(10) # componente z
print("Combinacion lineal de dos vectores\n\t vec_a: {} y vec_b {}".format(eigen_3_a, eigen_3_b))
print("\t vec_3 = beta_a * vec_a + beta_b * vec_b: {}".format((beta_a * eigen_3_a + beta_b * eigen_3_b)))

print("")
print("Eigenvector para lambda=3: {} ".format(vectors[:,2]))
beta_a = vectors[1,2]*np.sqrt(5) # componente y
beta_b = vectors[2,2]*np.sqrt(10) # componente z
print("Combinacion lineal de dos vectores\n\t vec_a: {} y vec_b {}".format(eigen_3_a, eigen_3_b))
print("\t vec_3 = beta_a * vec_a + beta_b * vec_b: {}".format((beta_a * eigen_3_a + beta_b * eigen_3_b)))

print("")
print("Ejercicio 5")
n = 100
A = np.zeros([n,n])
b = np.ones(n)
for i in range(1,n+1):
    b[i-1] = 1/i
    for j in range(1,n+1):
        A[i-1,j-1] = 1/(i+j-1)
x = np.linalg.solve(A,b)
print("Solucion con todos los elementos igual a cero salvo el primero:\n\t {}".format(x))


import pickle

import numpy as np
from sklearn import linear_model
import sklearn.metrics as sm
import matplotlib.pyplot as plt

input_file = 'data_singlevar_regr.txt'

data = np.loadtxt(input_file, delimiter=',')
X, y = data[:, :-1], data[:, -1]

num_training = int(0.8 * len(X))
num_test = len(X) - num_training

X_train, y_train = X[:num_training], y[:num_training]

X_test, y_test = X[num_training:], y[num_training:]

regressor = linear_model.LinearRegression()

regressor.fit(X_train, y_train)

y_test_pred = regressor.predict(X_test)

plt.scatter(X_test, y_test, color='green')
plt.plot(X_test, y_test_pred, color='black', linewidth=4)
plt.xticks(())
plt.yticks(())
plt.show()

print("Linear regressor performance:")
print("Mean absolute error =", round(sm.mean_absolute_error(y_test, y_test_pred), 2))
print("Mean squared error =", round(sm.mean_squared_error(y_test, y_test_pred), 2))
print("Median absolute error =", round(sm.median_absolute_error(y_test, y_test_pred), 2))
print("Explain variance score =", round(sm.explained_variance_score(y_test, y_test_pred), 2))
print("R2 score =", round(sm.r2_score(y_test, y_test_pred), 2))

output_model_file = 'model.pkl'

with open(output_model_file, 'wb') as f:
    pickle.dump(regressor, f)

with open(output_model_file, 'rb') as f:
    regressor_model = pickle.load(f)

y_test_pred_new = regressor_model.predict(X_test)
print("\nNew mean absolute error =", round(sm.mean_absolute_error(y_test, y_test_pred_new), 2))


import numpy as np
import pandas as pd
import scipy.stats as sp

class BlackScholes:
    """
    Black-Scholes model for pricing European options.

    Notes
    -----
    Assumptions of the model:

    - the volatility of the underlying asset is constant over time;
    - the underlying asset price follows the log-normal distribution;
    - the underlying assset can be traded continuously;
    - no transaction costs or taxes;
    - all securities are perfectly divisible;
    - the risk-free rate is constant and the same for all maturities.

    Price of the call option was calculated based on below formula:

    .. math:: c = S_{0}N(d_{1}) - Ke^{-rT}N(d_{2})

    On the other hand, price of the put option was derived from the formula:

    .. math:: p = Ke^{-rT}N(-d_{2}) - S_{0}N(-d_{1}),

    where:

    .. math:: d_{1} = \\frac{ ln(S_{0}/K) + (r + \\sigma^{2}/2)T }{ \\sigma \\sqrt{T} } \\
        d_{2} = \\frac{ ln(S_{0}/K) + (r - \\sigma^{2}/2)T }{ \\sigma \\sqrt{T} } = d_{1} - \\sigma \\sqrt{T}

    """

    def __init__(self, S: float, K: float, r: float, q: float=0, T: float, sigma: float, type: str) -> None:
        """
        Class initializer.

        Parameters
        ----------
        S : float
            Price of the underlying.
        K : float
            Strike price.
        r : float
            Risk free rate.
        q : float
            Dividend rate.
        T : float
            Time to expiry (in years).
        sigma : float
            Underlying volatility.
        type : str
            Option type: "put" or "call".
        """
        self.S = S
        self.K = K
        self.r = r
        self.q = q
        self.T = T
        self.sigma = sigma
        self.type = type

    def d1(self) -> float:
        """
        Calculates d1 from the class description.

        Returns
        -------
        float
            d1 value
        """
        return (np.log(self.S/self.K) + (self.r + (self.sigma**2)/2)*self.T) / (self.sigma*np.sqrt(self.T))

    def d2(self) -> float:
        """
        Calculates d2 from the class description.

        Returns
        -------
        float
            d2 value
        """
        return self.d1() - self.sigma*np.sqrt(self.T)

    def price(self) -> float:
        """
        Runs Black-Scholes calculation.

        Returns
        -------
        float
            Option price
        """
        if self.type == 'call':
            return self.S*sp.norm.cdf(self.d1()) - self.K*np.exp(-self.r*self.T)*sp.norm.cdf(self.d2())

        elif self.type == 'put':
            return self.K*np.exp(-self.r*self.T)*sp.norm.cdf(-self.d2()) - self.S*sp.norm.cdf(-self.d1())

        else:
            raise ValueError("Option price type can only be call or put")


"""
Lagrange (Polynomial Interpolation)
"""

import numpy as np

def L(i, X):
    """
    This function returns l(x).

    Parameters
    ----------
        i : int
            Index of X.
        X : list
            List of x values.

    Returns
    -------
        function
            l(x)
    """
    temp = X.copy()
    xi = temp.pop(i)

    def l(x):
        return np.prod([(x - xj) / (xi - xj) for xj in temp])

    return l

def lagrange(X, Y):
    """
    Polynomial Interpolation using Lagrange method.
    X and Y are data from `(x, f(x))`.

    Parameters
    ----------
        X : list
            list of x values.
        Y : list
            list of y values.

    Returns
    -------
        function
            Lagrange Polynomial from `X` and `Y` values.
    """
    def f(x):
        return sum([yi * L(i, X)(x) for i, yi in enumerate(Y)])

    return f


""" Example showing how to compute a family of basis polynomials """

# -------------------------------------------------------------------------------------------------------------------- #
# Importing packages
# -------------------------------------------------------------------------------------------------------------------- #
import numpy as np
import nurbspy as nrb
import matplotlib.pyplot as plt

# -------------------------------------------------------------------------------------------------------------------- #
# Basis polynomials and derivatives example
# -------------------------------------------------------------------------------------------------------------------- #
# Maximum index of the basis polynomials (counting from zero)
n = 4

# Define the order of the basis polynomials
p = 3

# Define the knot vector (clamped spline)
# p+1 zeros, n-p equispaced points between 0 and 1, and p+1 ones. In total r+1 points where r=n+p+1
U = np.concatenate((np.zeros(p), np.linspace(0, 1, n - p + 2), np.ones(p)))

# Define a new u-parametrization suitable for finite differences
h = 1e-5
hh = h + h**2
Nu = 1000
u = np.linspace(0.00 + hh, 1.00 - hh, Nu)       # Make sure that the limits [0, 1] also work when making changes

# Compute the basis polynomials and derivatives
N_basis   = nrb.compute_basis_polynomials(n, p, U, u)
dN_basis  = nrb.compute_basis_polynomials_derivatives(n, p, U, u, derivative_order=1)
ddN_basis = nrb.compute_basis_polynomials_derivatives(n, p, U, u, derivative_order=2)

# -------------------------------------------------------------------------------------------------------------------- #
# Plot the basis polynomials
# -------------------------------------------------------------------------------------------------------------------- #
# Create the figure
fig = plt.figure(figsize=(15, 5))

# Plot the basis polynomials
ax1 = fig.add_subplot(131)
ax1.set_title('Zeroth derivative', fontsize=12, color='k', pad=12)
ax1.set_xlabel('$u$ parameter', fontsize=12, color='k', labelpad=12)
ax1.set_ylabel('Function value', fontsize=12, color='k', labelpad=12)
for i in range(n+1):
    line, = ax1.plot(u, N_basis[i, :])
    line.set_linewidth(1.25)
    line.set_linestyle("-")
    # line.set_color("k")
    line.set_marker(" ")
    line.set_markersize(3.5)
    line.set_markeredgewidth(1)
    line.set_markeredgecolor("k")
    line.set_markerfacecolor("w")
    line.set_label('index ' + str(i))

# Plot the first derivative
ax2 = fig.add_subplot(132)
ax2.set_title('First derivative', fontsize=12, color='k', pad=12)
ax2.set_xlabel('$u$ parameter', fontsize=12, color='k', labelpad=12)
ax2.set_ylabel('Function value', fontsize=12, color='k', labelpad=12)
for i in range(n+1):
    line, = ax2.plot(u, dN_basis[i, :])
    line.set_linewidth(1.25)
    line.set_linestyle("-")
    # line.set_color("k")
    line.set_marker(" ")
    line.set_markersize(3.5)
    line.set_markeredgewidth(1)
    line.set_markeredgecolor("k")
    line.set_markerfacecolor("w")
    line.set_label('index ' + str(i))

# Plot the second derivative
ax3 = fig.add_subplot(133)
ax3.set_title('Second derivative', fontsize=12, color='k', pad=12)
ax3.set_xlabel('$u$ parameter', fontsize=12, color='k', labelpad=12)
ax3.set_ylabel('Function value', fontsize=12, color='k', labelpad=12)
for i in range(n+1):
    line, = ax3.plot(u, ddN_basis[i, :])
    line.set_linewidth(1.25)
    line.set_linestyle("-")
    # line.set_color("k")
    line.set_marker(" ")
    line.set_markersize(3.5)
    line.set_markeredgewidth(1)
    line.set_markeredgecolor("k")
    line.set_markerfacecolor("w")
    line.set_label('index ' + str(i))

# Create legend
ax3.legend(ncol=1, loc='right', bbox_to_anchor=(1.60, 0.50), fontsize=10, edgecolor='k', framealpha=1.0)

# Adjust pad
plt.tight_layout(pad=5.0, w_pad=None, h_pad=None)

# Show the figure
plt.show()

# # -------------------------------------------------------------------------------------------------------------------- #
# # Check that the computations are correct
# # -------------------------------------------------------------------------------------------------------------------- #
# # Check that the sum of the basis polynomials is equal to one (partition of unity property)
# print('The two-norm of partition of unity error is     :  ', np.sum((np.sum(N_basis, axis=0) - 1.00) ** 2) ** (1 / 2))
#
# # Check the first derivative against a finite difference aproximation
# a = -1/2*compute_basis_polynomials(n, p, U, u - h)
# b = +1/2*compute_basis_polynomials(n, p, U, u + h)
# dN_fd = (a+b)/h
# print('The two-norm of the first derivative error is   :  ', np.sum((dN_basis-dN_fd)**2)**(1/2)/Nu)
#
# # Check the second derivative against a finite difference aproximation
# a = +1*compute_basis_polynomials(n, p, U, u - h)
# b = -2*compute_basis_polynomials(n, p, U, u)
# c = +1*compute_basis_polynomials(n, p, U, u + h)
# ddN_fd = (a+b+c)/h**2
# print('The two-norm of the second derivative error is  :  ', np.sum((ddN_basis-ddN_fd)**2)**(1/2)/Nu)


import numpy as np

def createSquare(size):
    """Creates an N x N magic square

    In a magic square, every row, column, and diagonal add up to the same number.

    @param size The size of the magic square
    @return A boolean representing if the square was created or not
    """

    # The size must be odd
    if size % 2 == 0:
        print('Size must be odd')
        return False

    # Initialize with zeros
    magic_square = np.zeros((size,size), dtype=int)

    n = 1
    i, j = 0, size//2

    while n <= size**2:
        magic_square[i, j] = n
        n += 1
        newi, newj = (i - 1) % size, (j + 1) % size
        if magic_square[newi, newj]:
            i += 1
        else:
            i, j = newi, newj

    print(magic_square)
    return True

def runTests():
    # Test cases
    assert createSquare(3) is True
    assert createSquare(5) is True
    assert createSquare(6) is False
    assert createSquare(4) is False

runTests()


#!/usr/bin/env python

"""
Usage:
python polyarea.py c 1 2 4 8 3 5
python polyarea.py f coord.txt
python polyarea.py help
"""

import sys
import numpy as np

def simpoly(x,y):
    """
    A function that calculates the area of a 2-D simple polygon (no matter concave or convex)
    Must name the vertices in sequence (i.e., clockwise or counterclockwise)
    Inputs must be float type
    Formula used: http://en.wikipedia.org/wiki/Polygon#Area_and_centroid
    Definition of "simply polygon": http://en.wikipedia.org/wiki/Simple_polygon

    Input x: x-axis coordinates of vertex array
          y: y-axis coordinates of vertex array
    Output: polygon area
    """

    ind_arr = np.arange(len(x))-1  # for indexing convenience
    s = 0
    for ii in ind_arr:
      s = s + (x[ii]*y[ii+1] - x[ii+1]*y[ii])

    return abs(s)*0.5

if __name__ == "__main__":
    usage_str = 'Usage:\npython polyarea.py c 1 2 4 8 3 5 \npython polyarea.py f coord.txt\npython polyarea.py help'

    if len(sys.argv) == 1:
        print "Error: argument input needed"
        print usage_str
        exit()

    if sys.argv[1].lower() == 'c':
        # Recognize the inputs as the coordinates
        if len(sys.argv) <= 7:
            print "Error: at least three 2-D points needed for a valid polygon"
            print "Exiting..."
            exit()
        elif np.mod(len(sys.argv[2:]), 2) != 0:
            print "Error: the number of input arguments should be even"
            print "Exiting..."
            exit()
        else:
            print "This polygon has", (len(sys.argv)-2)/2, "vertices"

        a = np.zeros(len(sys.argv)-2)  # the default a.dtype.name is float64

        ind = 0
        for coord in sys.argv[2:]:
            a[ind]=float(eval(coord))  # convert the input arguments to "float" type
            ind = ind+1

        b = a.reshape(-1, 2).copy()
        x = b[:,0].copy()   # get x coords
        y = b[:,1].copy()   # get y coords

        print "The area of this polygon is", simpoly(x,y)

    elif sys.argv[1].lower() == 'f':
        # Get the input from a file
        # in which the 1st column is x coordinates, and the 2nd column is y coordinates
        d = np.loadtxt(sys.argv[2])
        x = d[:,0]
        y = d[:,1]
        print "The area of this polygon is", simpoly(x,y)

    elif sys.argv[1].lower() == 'help':
        print usage_str
        exit()

    else:
        print "Error need input arg either c (command line) or f (file)"
        print "Exiting"
        exit()


import numpy
from matplotlib import pyplot

def bisection(f, interval, max_steps=100, tol=1e-10):

    x_lo, x_hi = interval
    x = (x_lo + x_hi)/2
    f_lo = f(x_lo)
    f_hi = f(x_hi)
    fx = f(x)
    steps = 0

    while steps < max_steps and abs(fx) > tol and (x_hi - x_lo) > tol:
        steps = steps + 1
        if fx*f_hi < 0: # Root lies in right-hand half
            x_lo = x
            f_lo = fx
        else: # Root lies in left-hand half
            x_hi = x
            f_hi = fx
        x = (x_lo + x_hi) / 2
        fx = f(x)
    print("Nsteps", steps)
    return x

if __name__=="__main__":
    def f(x):
        return numpy.exp(x) + x - 2
    def g(x):
        return numpy.sin(x**2) - 0.1*x

    interval = [0,1]
    s = bisection(f, interval)
    print("s = ", s, "f(s) = ", f(s))

    x = numpy.linspace(0, 10, 1000)
    pyplot.plot(x, g(x))
    pyplot.show()
    s = bisection(g, [1,10])
    print("s = ", s, "g(s) = ", g(s))
    s = bisection(g, [1,9])
    print("s = ", s, "g(s) = ", g(s))
    s = bisection(g, [1,8.5])
    print("s = ", s, "g(s) = ", g(s))
    s = bisection(g, [1,8])
    print("s = ", s, "g(s) = ", g(s))


from scipy import *
from scipy import interpolate
from scipy.interpolate import barycentric_interpolate as bi
import numpy as np
import pylab as pl #where we get graph function
from scipy.optimize import curve_fit
from polyFit import *
from scipy import polyfit

h=np.array([0.0,1.525,30.050,4.575,6.10,7.625,9.150])
p=np.array([1.0,0.8617,0.7385,0.6292,0.5328,0.4481,0.3741])

z=np.arange(0,9.3,0.1) #gives points to evaluate a polynomial fit going through p and h
a=bi(h,p,2) #evaluates a polynomial going through the  points p(h) gives p at h=2
print a

z=np.arange(0,9.3,0.1)
b=bi(h,p,4)
print b

z=np.arange(0,9.2,0.1)
c=bi(h,p,8)
print c

print 'part b'
f=interpolate.interp1d(h,p,kind='cubic') #creates a cubic function that fits the graph

d=f(2) #uses interpolation function
print 'Density at 2km using cubic spline interpolation'
print d

e=f(4) #uses interpolation function
print 'Density at 4km using cubic spline interpolation'
print e

f=f(8) #uses interpolation function
print 'Density at 8km using cubic spline interpolation'
print f

print 'part c- getting errors'
actualvalue=0.67
e1= (b-actualvalue)/actualvalue
print e1

actualvalue=0.67
e2= (e-actualvalue)/actualvalue
print e2

ExamPrep/04 Curve Fitting & Interpolation/rp2.py


import numpy as np

def rbf(x1, x2, gamma=1.):
    """
    rbf kernel function

    Parameters
    ------------
    x1 : numpy array, (..., n)
        the first input feature vector
    x2 : numpy array, (..., n)
        the second input feature vector
    gamma : positive double, default: 1
        gamma=0.5/sigma**2

    Returns
    ---------
    kernel : numpy array
        output kernel
    """
    return np.exp(-gamma*((x1-x2)**2).sum(axis=-1))

def linear(x1, x2):
    """
    linear kernel function

    Parameters
    ------------
    x1 : numpy array, (..., n)
        the first input feature vector
    x2 : numpy array, (..., n)
        the second input feature vector

    Returns
    ---------
    kernel : numpy array
        output kernel
    """
    return (x1*x2).sum(axis=-1)

def poly(x1, x2, degree=3, gamma=1., r=0.):
    """
    polynomial kernel function

    Parameters
    ------------
    x1 : numpy array, (..., n)
        the first input feature vector
    x2 : numpy array, (..., n)
        the second input feature vector
    degree : positive double, default: 3
        degree of the polynomial kernel function
    gamma : positive double, default: 1
        kernel coefficient
     r : positive double, default: 0
         independent term

    Returns
    ---------
    kernel : numpy array
        output kernel
    """
    return (gamma*(x1*x2).sum(axis=-1) + r)**degree


import numpy as np
import submission as sub
import numpy.linalg as la

# 1. Generate random camera matrix

K = np.array([[1,0,100], [0,1,100], [0,0,1]])
R, _,_ = la.svd(np.random.randn(3,3))
if la.det(R) < 0: R = -R
t = np.vstack((np.random.randn(2,1), 1))

P = K @ np.hstack((R, t))

# 2. Generate random 2D and 3D points

N = 100

X = np.random.randn(N,3)
x = P @ np.hstack((X, np.ones((N,1)))).T
x = x[:2,:].T / np.vstack((x[2,:], x[2,:])).T

# 3. Test parameter estimation with clean points

Pc = sub.estimate_pose(x, X)
Kc, Rc, tc = sub.estimate_params(Pc)

print('Intrinsic Error with clean 2D points:', la.norm((Kc/Kc[-1,-1])-(K/K[-1,-1])))
print('Rotation Error with clean 2D points:', la.norm(R-Rc))
print('Translation Error with clean 2D points:', la.norm(t-tc))

# 4. Test parameter estimation with noisy points

x = x + np.random.rand(x.shape[0], x.shape[1])
Pn = sub.estimate_pose(x, X)
Kn, Rn, tn = sub.estimate_params(Pn)

print('Intrinsic Error with noisy 2D points:', la.norm((Kn/Kn[-1,-1])-(K/K[-1,-1])))
print('Rotation Error with noisy 2D points:', la.norm(R-Rn))
print('Translation Error with noisy 2D points:', la.norm(t-tn))


import numpy as np

def MSE(y_true, y_pred):
    """
        Mean Squared Error

        parameters :
        -> y_true, y_pred (numpy arrays)

        returns :
        -> scalar value of the loss
    """
    return (np.square(y_true - y_pred)).mean()

def MAE(y_true, y_pred):
    """
        Mean Absolute Error

        parameters :
        -> y_true, y_pred (numpy arrays)

        returns :
        -> scalar value of the loss
    """
    return np.abs(y_true - y_pred).mean()

def CrossEntropyLoss(y_true, y_pred, epsilon=1e-10):
    """
        Cross Entropy Loss

        parameters :
        -> y_true, y_pred, epsilon

        returns :
        -> scalar value of the loss
    """
    predictions = np.clip(y_pred, epsilon, 1. - epsilon)
    N = y_pred.shape[0]
    ce_loss = -np.sum(np.sum(y_true * np.log(predictions + 1e-5)))/N
    return ce_loss


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

# define grid
p_grid = np.linspace(0, 1, num=20)

# define prior
prior = np.repeat(1, 20)

# Other priors
# prior[p_grid < 0.5] = 0
# prior = np.exp(-5 * np.abs(p_grid - 0.5))

# compute likelihood at each value in grid
likelihood = stats.binom.pmf(k=6, n=9, p=p_grid)

# compute product of likelihood and prior
unstd_posterior = likelihood * prior

# standardize the posterior, so it sums to 1
posterior = unstd_posterior / sum(unstd_posterior)

# Show plot
plt.plot(p_grid, posterior, '-o')
plt.xlabel("Probability of water")
plt.ylabel("Posterior probability")
plt.title("20 points")
plt.show()


"""

https://en.wikipedia.org/wiki/Companion_matrix
http://et.engr.iupui.edu/~skoskie/ECE602/LNotes/A_Companion_Matrix.pdf

"""

import numpy as np
from sympy import *
from sympy.abc import *
from sympy.solvers import solve

"""

A companion matrix is of the form
C(p) = [0 0 ... 0 -a0   ]
       [1 0 ... 0 -a1   ]
       [0 1 ... 0 -a2   ]
       [    ...         ]
       [0 0 ... 1 -a[n-1]]

where the coefficients a0 .. a[n-1] are from a monic polynomial
c0 + c1*t + c2*t^2 + ... c[n-1]*t^(n-1) + t^n

"""

def gen_companion_matrix(n):
    A = [[0 for i in range(n)] for j in range(n)]
    for i in range(n-1):
        A[i+1][i] = 1
    for i in range(n):
        A[i][n-1] = -1 * Symbol('a{}'.format(i))
    return Matrix(A)

"""

det(lambda*I - A) or det(lambda*I - transpose(A))
gives rise to the monic polynomial
c0 + c1*x + c2*x^2 ... c[n-1]*x^(n-1) + x^n
where lambda gets substituted to be x

"""

def test_monic_polynomial_property(n):
    l = Symbol('x')
    A = gen_companion_matrix(n)
    I = Matrix(np.identity(n))
    p = expand(simplify(det(l*I - A)))
    q = expand(simplify(det(l*I - A.T)))
    print("Order {}".format(n))
    pprint(p)
    pprint(q)
    print()

def test_power(n, m):
    l = Symbol('x')
    A = gen_companion_matrix(n)
    I = Matrix(np.identity(n))
    p = expand(simplify(det(l*I - A)))
    for i in range(m):
        print("Power {}x{} {}".format(n, n, i))
        pprint(A**i)

"""

The inverse of a companion matrix is in the form of
C(p)^-1 = [-a1/a0     1 0 ... 0
           -a2/a0     0 1 ... 0
           -a3/a0     0 0 ... 0
            ...
           -a[n-1]/a0 0 0 ... 1
           -1/a0]     0 0 ... 0]
"""
def test_inverse(n):
    l = Symbol('x')
    A = gen_companion_matrix(n)
    pprint(A)
    pprint(A.inv())
    pprint(A.T)
    pprint(A.T.inv())

init_printing()
print("Monic Polynomial Property")
for i in range(10):
    test_monic_polynomial_property(i)
print()

print("Power")
for i in range(10):
    test_power(i, 5)
print()

print("Inverse")
for i in range(10):
    test_inverse(i)


# normalize.py

import numpy as np
from math import sqrt
from sklearn.preprocessing import minmax_scale

def normalize_l2 (x):
    """ Rerturns a normalized copy of
    an array x. Uses L2 vector norm
    for normalization.
    """
    l2 = sqrt(sum(i**2 for i in x))
    return [i/l2 for i in x]

def de_normalize_l2 (x_norm, x):
    """ Transforms a normalized vector
    back to its un-normalized form.
    """
    l2 = sqrt(sum(i**2 for i in x))
    return [i*l2 for i in x_norm]

def max_scaling(x):
    """ Scaling the values of an array x
    with respect to the maximum value of x.
    """
    return [i/max(x) for i in x]

def normalize_minmax(x, min_r, max_r):
    """ Normalizing and scaling given data
    in an array x to the range of min_r
    to max_r.
    """
    x_s = [(i - min(x))/(max(x) - min(x)) for i in x]
    return [i * (max_r - min_r) + min_r for i in x_s]

def de_normalize_minmax(x_scale, x, min_r, max_r):
    """ Transforms a min-max normalized and
    scaled vector back to its un-normalized
    form.
    """
    x_t = [((i - min_r)/(max_r - min_r)) for i in x_scale]
    x_inv = [(i*(max(x) - min(x)) + min(x)) for i in x_t]
    return x_inv

# Test data
x = [2000, 2001, 2003]

# Exampels:
# L2 normalization
print(normalize_l2(x))
print(de_normalize_l2(normalize_l2(x), x))

# Max scaling
print(max_scaling(x))

# Min-Max scaling
print(normalize_minmax(x, 0, 10))
print(de_normalize_minmax(normalize_minmax(x, 0, 10), x, 0, 10))

# sklearn data scaling
print(minmax_scale(x, feature_range=(0, 1), axis=0, copy=False))


import numpy as np
import matplotlib.pyplot as plt
import scipy.interpolate as si
plt.style.use('seaborn-whitegrid')

def f(x) :

    s = 1/(1+25*np.power(x,2))

    return s

def Lagrance(n) :

    x_nodes=np.linspace(-1,1,n)
    y_val=f(x_nodes)
    polynomial = si.lagrange(x_nodes, y_val)

    return polynomial,x_nodes,y_val

#----------- Main Programme --------------------#

n=10
x=np.linspace(-1,1,100)
polynomial,x_nodes,y_val = Lagrance(n)

plt.plot(x,f(x),'lime')
y=polynomial(x)
plt.plot(x_nodes,y_val,'+')
plt.plot(x,y,'green')
plt.xlabel('x')
plt.ylabel('y')
plt.xlim(-1,1)
plt.legend(['f(x)','Points','Lagrance'])
plt.show()


import scipy
import scipy.stats as ss
import numpy as np
import pandas as pd

def entry_point():
    pass

def iqr_threshold_method(scores, margin):
    q1 = np.percentile(scores, 25, interpolation='midpoint')
    q3 = np.percentile(scores, 75, interpolation='midpoint')
    iqr = q3-q1
    lower_range = q1 - (1.5 * iqr)
    upper_range = q3 + (1.5 * iqr)
    lower_range = lower_range - margin
    upper_range = upper_range + margin
    return lower_range, upper_range

def ZscoreOutlier(data, margin=0, axis=0, ddof=0, nan_policy='propagate'):
    """Returns numpy array with data points labelled as outliers
    Parameters
    ----------
    data : array_like
        An array like object containing the sample data.

    margin : int, default=0
        Margin of error

    axis : int or None, optional
        Axis along which to operate. Default is 0. If None, compute over
        the whole array `a`.

    ddof : int, optional
        Degrees of freedom correction in the calculation of the
        standard deviation. Default is 0.

    nan_policy : {'propagate', 'raise', 'omit'}, optional
        Defines how to handle when input contains nan. 'propagate' returns nan,
        'raise' throws an error, 'omit' performs the calculations ignoring nan
        values. Default is 'propagate'.

    """
    scores = ss.zscore(data, axis=axis, ddof=ddof, nan_policy=nan_policy)

    lower_range, upper_range = iqr_threshold_method(scores, margin)

    anomaly_points = []
    for i in range(len(scores)):
        if scores[i] < lower_range or scores[i] > upper_range:
            anomaly_points.append(data[i])

    return anomaly_points

def ModifiedZscoreOutlier(data, margin=0, consistency_correction=1.4826):
    """Returns numpy array with data points labelled as outliers
    Parameters
    ----------
    data : array_like
        An array like object containing the sample data.

    margin : int, default=0
        Margin of error

    consistency_correction : int, default=1.4826
        The consistency_correction factor converts the MAD to the standard deviation for a given
        distribution. The default value (1.4826) is the conversion factor if the underlying data
        is normally distributed

    """

    median = np.median(data)

    deviation_from_med = np.array(data) - median

    mad = np.median(np.abs(deviation_from_med))
    scores = deviation_from_med/(consistency_correction*mad)

    lower_range, upper_range = iqr_threshold_method(scores, margin)

    anomaly_points = []
    for i in range(len(scores)):
        if scores[i] < lower_range or scores[i] > upper_range:
            anomaly_points.append(data[i])

    return anomaly_points

if __name__=='__main__':
    arr = [8,5,7,8,11,13,4,9,10,7,6]
    arr = np.array(arr)
    res = ModifiedZscoreOutlier(arr, 1)
    print(res)


import numpy as np
import  matplotlib.pyplot as plt

def factorial(n):
    if n == 0:
        return 1
    else:
        fat = 1
        for i in range(1, n+1):
            fat = fat *i

        return  fat

#print(factorial(5))

def cos(x,n):
    resul  = 0
    for i in range(0,n+1):
        resul += (-1)**i * x**(2*i)/factorial(2*i)
    return resul

"""
x = int(raw_input("The value of x:"))
n = int(raw_input("The value of n:"))
print(cos(x,n))
"""

Npoints = 100
dtheta = (2.0*np.pi -0.0)/Npoints
Nterm = 10

theta = []
ctheta = []

for i in range(0, Npoints):
    theta.append(i*dtheta)
    ctheta.append(cos(i*dtheta, Nterm ))

fig = plt.figure()
ax= plt.axes()
ax.plot(theta,ctheta, '.')
ax.plot(theta,np.cos(theta))
ax.grid()
ax.set_xlabel(r"$\theta$", fontsize=14)
plt.show()
#plt.savefig('cos.png')


# -*- coding: utf-8 -*-
"""
This program models the LEGO "Doodler" Google it, and/or see:
    https://www.us.lego.com/en-us/mindstorms/community/robot?projectid=73d4591f-e964-4533-85fe-b608d3eb6a83
Briefly, a pen is at the end of a zig-zag expanding structure,
the left and right end points of the structure are connected to
to gears so they each end point moves in a circle.

Example: shown here is strucutre with n_zigzag = 3
  (three lengths from end point to tip; the Lego project has n_zig = 7);
  the length of each section in the diagram is L_zig = 3 (three "/"s)

       tip where the pen is
       /\
      /  \
    ./    \.
     \    /
      \  /
       \/
       /\
      /  \
     /    \
     L    R
   end points
The end points are attached a distance "radius" from the centers of
their gears, and the two gears centers are separated by 2*x_center distance.
"""

# use math functions from np
import numpy as np
# and plotting from matplotlib
import matplotlib.pyplot as plt

# parameters to set and adjust (see description above)
# ============================
# The mechanical setup:
n_zigzag = 7     # Lego online version has 7
L_zig = 7.0      # Lego design has spacong of 7 holes
x_center = 5.0   # Lego design has x_center = 5
radius = 1.58    # Lego design has radius = 1.58 = sqrt(1.5^2+0.5^2)
# The number of rotations for each gear before stopping,
# and the starting location (in rotations):
rot_l = 49
phi_l = -0.05
rot_r = -25
phi_r = -0.05
# FYI, the Lego page uses (effectively, note sign change too):
#    rot_l,'r = -49 & -50  (green in movie)
#             =  49 & -25  (blue in movie)
#    and Lego phi's look to be atan of 1/3 ~ 0.05 revs.
# ============================

def xys_of_rotations(rot_l, rot_r):
    """
    Calculate the location of the pen tip based on the
    amount of rotation of the two gears.
    """
    # convert rotations to radians (angle)
    theta_l = 2.0 * np.pi * rot_r
    theta_r = 2.0 * np.pi * rot_l
    # locations of the ends of the zig-zag from the angles,
    # note that they rotate in different directions
    # *** simple sin and cos use ***
    xl = -1.0 * (x_center + radius * np.cos(theta_l))
    yl = radius * np.sin(theta_l)
    xr = x_center + radius * np.cos(theta_r)
    yr = radius * np.sin(theta_r)
    # d is the half distance between the end points
    # *** distance formula ***
    d = np.sqrt((xr - xl)**2 + (yr - yl)**2) / 2.0
    # calculate the location of the tip of the zig-zag,
    # start at the midpoint of the two endpoints
    # *** midpoint formula ***
    xtip = (xl + xr) / 2.0
    ytip = (yl + yr) / 2.0
    # h is the extension distance of the zig-zag,
    # the "height" or distance of the tip from the midpoint
    # *** Pythagorean theorem ***
    h = n_zigzag * np.sqrt(L_zig**2 - d**2)
    # this distance is tilted from the vertical
    # by a tilt angle which has trig ratios:
    # *** simple trig, or similar triangles ***
    sintilt = 0.5 * (yr - yl) / d
    costilt = 0.5 * (xr - xl) / d
    # add the x and y components of the tilted height to the midpoint;
    # the x component of h is -h*sin(tilt)
    xtip = xtip - h * sintilt
    # the y component of h is hcos(tilt)\
    ytip = ytip + h * costilt
    # return the locations of the end points and writing tip
    # return (xl, yl, xr, yr, xtip, ytip)
    # or just the writing tip
    return (xtip, ytip)

# Setup a list of points to fill
xs = []
ys = []

# setup an array of times, from 0 to 1
Tmax = 1.0
ts = np.linspace(0.0, Tmax, num=2000)

# go through the times...
for t in ts:
    # evaluate the function for raotations at time t
    (xtip, ytip) = xys_of_rotations(rot_l * t + phi_l,
                                    rot_r * t + phi_r)
    xs.append(xtip)
    ys.append(ytip)

# Close the previous plot
plt.close()

# open a plot
plt.figure(1, [12, 12], frameon=False)

plt.xlabel('x')
plt.ylabel('y')
plt.title('Doodler Output  [ rot_l = ' +
          str(rot_l) + ',  rot_r = ' + str(rot_r) + ' ]')

# set color to match Lego demo movie
if rot_r == -25 and rot_l == 49:
    plt.plot(xs, ys, '-b')
elif rot_r == -50 and rot_l == -49:
    plt.plot(xs, ys, '-g')
# or use red for other custom values
else:
    plt.plot(xs, ys, '-r')

plt.show()


#!/usr/bin/python

#Here are 3 ways to use "for loops" in python to do something to each element
#in an array.

#First, import relevant modules: numpy for arrays and matplotlib for plotting
import numpy as np
import matplotlib.pyplot as plt

########################     For Loop 1.     ################################

#I'm going to make two lists that are 50 elements long
#Then, I will populate these lists with some simple trig

points = 50 #length of lists

sinwave = np.empty(points) #np.empty creates empty arrays
coswave = np.empty(points) #the only argument I am using is the array length
x = np.empty(points)       #x will be the x-value, cos and sin will by y's

#range(points) will return the list: (0,1,2,3,4...47,48,49). It's 50 #'s long

for i in range(points):     #"For each element, i, in range(points)..."
	percent = float(i)/points #find the fraction of points we've gone through
	#since i changes every time through the loop, each value in these arrays
	#    will be used. x[i] represents the current x value.
	x[i] = 2.0*np.pi*percent  #x is scaled: it will be a uniform list from 0-2pi
	sinwave[i] = np.sin(x[i]) #the sine value of the current x is stored in the
	coswave[i] = np.cos(x[i]) #   current sinwave. same with cos and coswave.

#Lets plot what we got!
plt.plot(x, sinwave, label="sine(x)")   #x-values = x, y-values = sinwave. by
plt.plot(x, coswave, label="cosine(x)") #adding labels, we can have a legend.
plt.legend() #this line adds a standard legend.
plt.show()   #this line displays the two plots above.

########################     For Loop 2.     ################################
#In For Loop 1, we had to follow three arrays syncronously, so we had to
#iterate through the variable "i". Now we'll iterate through just one array,
#which is simpler in python.
#
#Let's say I only wanted the caps of the sine wave, and I didn't care about
#the x values.

#This time, I'll make an empty array, because I don't know its ultimate length
sinwaveCaps = []

for value in sinwave:  #"For each element, value, in the array sinwave..."
	if abs(value)>=0.5:  #if the sinwave value's amplitude is larger than 0.5...
		sinwaveCaps.append(value) #apend the value to the sinwaveCaps array.

#Let's plot just the caps!
plt.plot(sinwaveCaps) #If I only use one argument here, the x-value will be
                      #The index of the argument. (It'll be a line chart)
plt.show()

#Notice that the X-values are NOT preserved, so the caps don't have blank
#space between them! This is useful for some problems but not others.

########################     For Loop 3.     ################################
#90% of Geoscience is doing math on a grid (like a map). Thankfully, if we
#nest For Loops, we can iterate through x and y values (or P and T values, e.g.)

#I want to calculate the sum of my sine and cosine waves and store those values
sumSC = []

for s in sinwave:     #For each element, s, in sinwave..."
	for c in coswave:   #For each element, c, in coswave..."
		sumSC.append(s+c) #Append the elements together.

#WARNING! The order that the above for loop adds the elements together might
#         be non-intuitive for beginner programmers. Go through the for-loop
#         a few times in your head to conceptualize it. Here's the order the
#         computer uses:
#  1. s=1       <-------outside for-loop
#  | 1. c=1     <-------inside  for-loop
#  | | 1. s+c=2 <-------operation done inside both loops
#  | 2. c=2
#  | | 1. s+c=3
#  2. s=2
#  | 1. c=1
#  | | 1. s+c=3
#  | 2. c=2
#  | | 1. s+c=4

#Because of this loop, the values (in the example: 2,3,3,4) correspond to the
#coordinates (1,1),(1,2),(2,1),(2,2). So if we want to plot them on a map,
#the order of the values is (2,3,3,4), the x-coordinates (1,1,2,2), and the
#y-coordinates (1,2,1,2). If the x and y values are (1,2), we have to TILE
#or REPEAT these arrays. Numpy has the solution:
xsin = np.repeat(sinwave,len(coswave)) #(1,2) -> (1,1,2,2)
ycos = np.tile(coswave,len(sinwave))   #(1,2) -> (1,2,1,2)
#note I repeated the sinwave array by the length of the coswave
#    (50 of the first value, 50 of the second, ... 50 of the last value)
#Since both arrays are the same length I could have just used 50. But I'm
#playing it safe here, assuming all I know is that sumSC was calculated
#len(sinwave)xlen(coswave) times.

#Let's plot this!!
#I'm using a scatter plot since the data aren't in a perfect grid.
#x = the repeated "xsin" array
#y = the tiled "ycos" array
#color value = sumSC values
#color map = matplotlib's blue-to-white-to-red
plt.scatter(xsin,ycos,c=sumSC,cmap=plt.cm.get_cmap('bwr'))
plt.colorbar() #this line adds a color bar using the color map and c values
plt.show()     #this line shows us our last figure.

#Created by Jacob


#
# This program is distributed without any warranty and it
# can be freely redistributed for research, classes or private studies,
# since the copyright notices are not removed.
#
# This file contains a function to calculate matriz convolution
#
# Jadson Santos - jadsonjs@gmail.com
#
# http://www.scipy-lectures.org/advanced/image_processing/
#
# to run this exemple install pyhton modules:
#
# python3 -m pip install SciPy
# python3 -m pip install numpy
# python3 -m pip install matplotlib
#

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from scipy import misc
from scipy import ndimage
from scipy import signal

#7x7
A = np.array(  [
               [8, 5, 8, 1, 6, 8, 7],
               [9, 9, 2, 8, 2, 7, 8],
               [2, 9, 4, 9, 7, 3, 2],
               [9, 2, 9, 7, 1, 9, 5],
               [6, 9, 8, 7, 3, 1, 5],
               [1, 9, 9, 7, 1, 4, 6],
               [3, 5, 6, 4, 1, 4, 7] ] )
#3x3
B = np.array([ [3, 2, 2],
               [1, 1, 3],
               [3, 1, 2]
               ])

print("--------------- Full --------------------")
con1 = signal.convolve(A, B, mode='full', method='direct')
print(" ")
print(con1)

con2 = signal.convolve(B, A, mode='full', method='direct')
print(" ")
print(con2)

print("---------------Same-----------------")

con3 = signal.convolve(A, B, mode='same', method='direct')
print(" ")
print(con3)

con4 = signal.convolve(B, A, mode='same', method='direct')
print(" ")
print(con4)

print("----------------My--------------------")

# calculate the convolution of a square matriz with hte mode "same"
def myconv2D( matrix, mask ):
    matrixLen = len(matrix)
    maskLen = len(mask)
    border  = int(maskLen / 2);

    # the result matrix will be a bigger in the full model
    tempMatrix = np.zeros( (matrixLen+(border*2), matrixLen+(border*2)), dtype=int  )
    convMatrix = np.zeros( (matrixLen, matrixLen), dtype=int  )

    # copy data of original matrix to convMatrix
    for i in range( matrixLen ):
        for j in range( matrixLen ):
            tempMatrix[i+1][j+1] = matrix[i][j]

    convMatrixLen = len(convMatrix)

    # the shift of the mask over the convMatrix
    # the size of original matriz
    #maxShift = matrixLen
    shiftX = 0
    shiftY = 0

    for shiftI in range( matrixLen ):
        for shiftJ in range( matrixLen ):

            for i in range( maskLen ):
                for j in range( maskLen ):
                    convMatrix[shiftI][shiftJ] = convMatrix[shiftI][shiftJ] + ( tempMatrix[i+shiftI][j+shiftJ] * mask[i][j])

    print(" ")
    print(convMatrix)

myconv2D(A, B)
myconv2D(B, A)


import numpy as np
called = 0

def z_o_knapsack(W, wt, val, n):
    global called
    called += 1

    if n == -1 or W == 0: # base case, 0 items or 0 weight left in knapsack
        return 0

    if W < wt[n]:
        return z_o_knapsack(W, wt, val, n - 1) # if nth item too heavy, cannot be included

    else:
        return max(z_o_knapsack(W, wt, val, n - 1), # value with nth item excluded
                    val[n] + z_o_knapsack(W - wt[n], wt, val, n - 1) # value with nth item included
                )

def z_o_knapsack_memoized(W, wt, val, n, memo=None):
    global called
    called += 1

    if memo == None:
        memo = np.zeros((n+1, W+1))

    if n == -1 or W == 0: # base case, 0 items or 0 weight left in knapsack
        return 0

    if memo[n, W] != 0:
        return memo[n, W]

    elif W < wt[n]:
        mem_val = z_o_knapsack(W, wt, val, n - 1) if memo[n-1, W] == 0 else memo[n-1, W] # if nth item too heavy, cannot be included
        memo[n,W] = mem_val
        return mem_val

    else:
        mem_val = max(z_o_knapsack(W, wt, val, n - 1) if memo[n-1, W] == 0 else memo[n-1, W] == 0, # value with nth item excluded
                    val[n] + z_o_knapsack(W - wt[n], wt, val, n - 1)
                        if memo[n-1, W - wt[n]] == 0 else memo[n-1, W - wt[n]] # value with nth item included
                )
        memo[n, W] = mem_val
        return mem_val

def z_o_knapsack_btm_up(W, wt, val, n):
    global called
    memo = np.zeros((n + 1, W + 1))

    for i in range(1, n + 1):
        for w in range(1, W + 1):
            called += 1
            if i == 0 or w == 0:
                memo[i, w] = 0

            elif wt[i - 1] > w:
                memo[i, w] = memo[i - 1, w]
            else:
                memo[i, w] = max(memo[i - 1, w],
                    val[i - 1] + memo[i - 1, w - wt[i - 1]]
                    )

    print(memo)
    return memo[n, W]

if __name__ == '__main__':
    val = [1,4,5,7]
    wt = [1,3,4,5]
    W = 7

    #print(z_o_knapsack_memoized(W, wt, val, len(val) - 1))
    #print(z_o_knapsack(W, wt, val, len(val) - 1))
    print(z_o_knapsack_btm_up(W, wt, val, len(val)))
    print(called)


# Dimentionality Reduction

## PCA

### Maximum variance formulation

consider a dataset $\{x_{i}\}$ where $i=1,...,n$ and $x_{i} \in \mathbb{R}^{d}$.

our goal is to project the data onto a space having dimensionality $k < d$ while maximizing the variance of the projected data.

to begin with, consider the projection onto a one-dimensional space$(k=1)$.

we can define the direction of this space by a vector $u_{1} \in \mathbb{R}^{d}$, we can choose $u_{1}$ to be a unit vector so that $u_{1}^{T}u_{1} = 1$.

each data point $x_{i}$ is then projected onto a scalar value $u_{1}^{T}x_{i}$, then mean of the projected data:

$$\frac{1}{n}\sum_{i=1}^{n}u_{1}^{T}x_{i} = u_{1}^{T}\overline{x}$$

the variance of the projected data:

$$\frac{1}{n}\sum_{i=1}^{n}(u_{1}^{T}x_{i} - u_{1}^{T}\overline{x})^{2} = \frac{1}{n}\sum_{i=1}^{n}u_{1}^{T}(x_{i} - \overline{x})(x_{i} - \overline{x})^{T}u_{1} = u_{1}^{T}Su_{1}$$

where

$$S = \frac{1}{n}\sum_{i=1}^{n}(x_{i} - \overline{x})(x_{i} - \overline{x})^{T}$$

now we can formalize our problem as:

$$\underset{u_{1}}{min}\ -u_{1}^{T}Su_{1}$$
$$s.t\quad u_{1}^{T}u_{1} = 1$$

the lagrangian of this optimization problem:

$$L(u_{1}, \lambda_{1}) = -u_{1}^{T}Su_{1} + \lambda_{1}(u_{1}^{T}u_{1} - 1)$$

the primal:

$$\underset{u_{1}}{min}\ \underset{\lambda_{1}}{max}\ L(u_{1}, \lambda_{1})$$

primal satisfy the KKT conditions, so equivalent to dual:

$$\underset{\lambda_{1}}{max}\ \underset{u_{1}}{min}\ L(u_{1}, \lambda_{1})$$

setting the derivative with respect to $u_{1}$ equal to zero, we have:

$$Su_{1} = \lambda_{1}{u_{1}}$$

which say that $u_{1}$ must be a eigenvector of $S$, if we left-multiply by $u_{1}^{T}$ and make use of $u_{1}^{T}u_{1} = 1$, we get:

$$u_{1}^{T}Su_{1} = \lambda_{1}$$

and so the variance will be a maximum when we set $u_{1}$ equal to the eigenvector having the largest eigenvalue $\lambda_{1}$. this eigenvector is known as the first principal component.

we can define the additional principal components in an increamental fashion by choosing each new direction to be that which maximizes the projected variance amongst all possible directions orthogonal to those already considered.

second principal component:

$$\underset{u_{2}}{min}\ -u_{2}^{T}Su_{2}$$
$$s.t\quad u_{2}^{T}u_{2} = 1, u_{1}^{T}u_{2} = 0$$

like before, using lagrangian we derive:

$$Su_{2} = \lambda_{2}{u_{2}} + \phi{u_{1}}$$

left multiply by $u_{1}^{T}$:

$$u_{1}^{T}Su_{2} = \lambda_{2}u_{1}^{T}{u_{2}} + \phi{u_{1}^{T}}{u_{1}}$$

analyzing each component:

$$u_{1}^{T}Su_{2} = u_{2}^{T}Su_{1} = u_{2}^{T}\lambda_{1}u_{1} = \lambda{u_{1}^{T}u_{2}} = 0$$
$$u_{1}^{T}{u_{2}} = 0$$
$${u_{1}^{T}}{u_{1}} = 1$$

we get:

$$\phi = 0$$

back to zero derivative we have:

$$Su_{2} = \lambda_{2}{u_{2}}$$
$$u_{2}^{T}Su_{2} = \lambda_{2}$$

so $\lambda_{2}$ is the second largest eigenvalue of $S$.

by induction, we can show that $i$-th principal component is the $i$-th largest eigenvector of $S$.

### properties of non-negative definite symmetric real matrix

$$S = \frac{1}{n}\sum_{i=1}^{n}(x_{i} - \overline{x})(x_{i} - \overline{x})^{T}$$

is of that kind.

### Minimum-error formulation

a complete orthonormal basis vectors $u_{i}$ in $\mathbb{R}^{d}$:

$$u_{i}^{T}u_{j} = \delta_{ij}$$

$x_{k}$ coordinate with respect to $u_{i}$ is $x_{k}^{T}u_{i}$, so:

$$x_{k} = \sum_{i=1}^{d}(x_{k}^{T}u_{i})u_{i}$$

$x_{k}$ can be approximated by the $m$-dimensional subspace representation plus a constant:

$$\tilde{x}_{k} = \sum_{i=1}^{m}z_{ki}u_{i} + \sum_{i=m+1}^{d}b_{i}u_{i}$$

where $z_{ki}$ depend on the particular data point, whereas ${b_{i}}$ are constants that are the same for all data points.

our goal is to minimize:

$$J = \frac{1}{n}\sum_{k=1}^{d}\left \| x_{k} - \tilde{x}_{k} \right \|^{2} $$

setting the derivative with respect to $z_{ni}$ to zero, and making use of the orthonormality conditions, we obtain:

$$z_{ni} = x_{n}^{T}u_{i}$$

similarly, we obtain:

$$b_{i} = \overline{x}^{T}u_{i}$$

substitude for $z_{ni}$ and $b_{i}$, we obtain:

$$x_{k} - \tilde{x}_{k} = \sum_{i=m+1}^{d}((x_{k} - \overline{x}_{k})^{T}u_{i})u_{i}$$

finally our goal is to minimize:

$$J = \frac{1}{n}\sum_{k=1}^{n}\sum_{i=m+1}^{d}(x_{k} - \overline{x}_{k})^{2} = \sum_{i=m+1}^{d}u_{i}^{T}Su_{i}$$

this is similar to the maximum variance formulation in the opposite direction.

### manual data

"""construct dataset"""
import numpy as np

m = 100
w1, w2 = 0.1, 0.3
noise = 0.2

X = np.empty((m, 3))
X[:, :2] = np.random.multivariate_normal([0, 0], [[2, 1], [1, 5]], m)
X[:, 2] = X[:, 0] * w1 + X[:, 1] * w2 + noise * np.random.randn(m)

from sklearn.decomposition import PCA

pca = PCA(n_components=2)
X2D = pca.fit_transform(X)

X2D[: 5]

"""sklearn actually uses SVD"""
X_centered = X - X.mean(axis=0)
U, s, Vt = np.linalg.svd(X_centered)

X2D_SVD = X_centered.dot(Vt.T[:, :2])
X2D_SVD[: 5]

### mnist data

from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split

mnist = fetch_openml('mnist_784', version=1, as_frame=False)
mnist.target = mnist.target.astype(np.uint8)

X = mnist["data"]
y = mnist["target"]

X_train, X_test, y_train, y_test = train_test_split(X, y)

"""
set n_components (0.0, 1.0), indicating the ratio of variance you wish to preserve
use inverse_transform trying to inverse
"""
pca = PCA(n_components=0.95)
X_reduced = pca.fit_transform(X_train)
X_mnist = pca.inverse_transform(X_reduced)

pca.explained_variance_ratio_[: 10]

"""IncrementalPCA"""
from sklearn.decomposition import IncrementalPCA

n_batches = 100
inc_pca = IncrementalPCA(n_components=154)
for X_batch in np.array_split(X_train, n_batches):
    print(".", end="")
    inc_pca.partial_fit(X_batch)

X_reduced = inc_pca.transform(X_train)

### swiss roll

from sklearn.datasets import make_swiss_roll

X, t = make_swiss_roll(n_samples=1000, noise=0.2, random_state=42)

"""kernel pca"""
from sklearn.decomposition import KernelPCA

rbf_pca = KernelPCA(n_components=2, kernel="rbf", gamma=0.04)
X_reduced = rbf_pca.fit_transform(X)

## Locally Linear Embedding(LLE)

LLE works by first measuring how each training instance linearly relates to it's colsest neighbors (c.n)

then looking for a low-dimensional representation of the training set where these local relationships are best preserved.

LLE step one: linearly modeling local relationships:

$$
\begin{equation}
\begin{split}
\hat{W} &= \underset{W}{argmin}\sum_{i=1}^{m}\left(x^{(i)} - \sum_{j=1}^{m}w_{ij}x^{(j)}\right)^{2}\\
\mbox{s.t }\ &1.w_{ij} = 0 \mbox{ if } x^{(j)} \mbox{ is not one of c.n of } x^{(i)} \\
&2.\sum_{i=1}^{m}w_{ij} = 1 \mbox{ for all }j
\end{split}
\end{equation}
$$

LLE second step doing the reverse: keeping the weights fixed and finding the optimal position of the instances' image in low-dimensional space, suppose $x^{(i)}$'s low-dimensional image is $z^{(i)}$.

$$
\begin{equation}
\begin{split}
\hat{Z} &= \underset{Z}{argmin}\sum_{i=1}^{m}\left(z^{(i)} - \sum_{j=1}^{m}w_{ij}z^{(j)}\right)^{2}\\
\mbox{s.t }\ &1.\sum_{i=1}^{m}z^{(i)} = 0\\
&2.\sum_{i=1}^{m}(z^{(i)}z^{(i)})^{T} = mI_{d}
\end{split}
\end{equation}
$$

from sklearn.manifold import LocallyLinearEmbedding

lle = LocallyLinearEmbedding(n_components=2, n_neighbors=10)
X_reduced = lle.fit_transform(X)

## Exercise

from sklearn.ensemble import RandomForestClassifier
from sklearn.base import clone

rnd_clf = RandomForestClassifier(n_estimators=1000, max_depth=4, n_jobs=-1, random_state=42)
low_clf = clone(rnd_clf)

from datetime import datetime
from sklearn.metrics import accuracy_score

pre_time = datetime.now()
rnd_clf.fit(X_train, y_train)
print((datetime.now() - pre_time).seconds)
accuracy_score(y_test, rnd_clf.predict(X_test))

pca = PCA(n_components=0.95)
X_train_reduced = pca.fit_transform(X_train)
X_test_reduced = pca.transform(X_test)

pre_time = datetime.now()
low_clf.fit(X_train_reduced, y_train)
print((datetime.now() - pre_time).seconds)
accuracy_score(y_test, low_clf.predict(X_test_reduced))

np.random.seed(42)

m = 10000
idx = np.random.permutation(60000)[:m]

X = mnist['data'][idx]
y = mnist['target'][idx]

from sklearn.manifold import TSNE

tsne = TSNE(n_components=2, random_state=42)
X_reduced = tsne.fit_transform(X)

import matplotlib.pyplot as plt

plt.figure(figsize=(13,10))
plt.scatter(X_reduced[:, 0], X_reduced[:, 1], c=y, cmap="jet")
plt.axis('off')
plt.colorbar()
plt.show()


import numpy as np
import matplotlib.pyplot as plt

"""Rienmann Sum"""

def lowersum(f, a, b, n):
    x = symbols('x')
    area = 0
    h = (b - a) / n
    t = a
    for i in range(n):
        l = min(f.subs(x, t), f.subs(x, t + h))
        area += l * h
        t = t + h
    return area

def uppersum(f, a, b, n):
    x = symbols('x')
    area = 0
    h = (b - a) / n
    t = a
    for i in range(n):
        l = max(f.subs(x, t), f.subs(x, t + h))
        area += l * h
        t = t + h
    return area

def Rienmannsum(f, a, b):
    e = 1
    n = int(input("Initial number of divisions you want: "))
    while e > 10 ** -4:
        L = lowersum(f, a, b, n)
        U = uppersum(f, a, b, n)
        e = U - L
        n *= 10
    return (U + L) / 2

'''Simpsons Method of numerical integration'''

def simps(f,a,b,N=50):
    '''
    f : function
        Vectorized function of a single variable
    a , b : numbers
        Interval of integration [a,b]
    N : (even) integer
        Number of subintervals of [a,b]
    '''
    if N % 2 == 1:
        raise ValueError("N must be an even integer.")
    dx = (b-a)/N
    x = np.linspace(a,b,N+1)
    y = f(x)
    S = dx/3 * np.sum(y[0:-1:2] + 4*y[1::2] + y[2::2])
    return S

'''Trapezoid Rule for numerical integration'''

def trapz(f,a,b,N=50):
    '''
    f : function
        Vectorized function of a single variable
    a , b : numbers
        Interval of integration [a,b]
    N : integer
        Number of subintervals of [a,b]
    '''
    x = np.linspace(a,b,N+1)
    y = f(x)
    y_right = y[1:] # Right endpoints
    y_left = y[:-1] # Left endpoints
    dx = (b - a)/N
    T = (dx/2) * np.sum(y_right + y_left)
    return T


import numpy as np
#from matplotlib import pyplot as plt

h_0 = 5.32 # height of pivot point

x_0 = 7.744 #x position of servo 1
y_0 = 7.744 #y posiiton of servo 2

l_1 = 2 # length of servo arm
l_2 = 3.398 # length of linkage

h_1_0 = 2.26 # height of servo axis
h_2_0 = 2.26

# compute maximum tilt
h_1 = h_1_0 + l_1 + l_2
dh = h_1 - h_0
p_max = np.arctan(dh/x_0)

h_1 = h_1_0 - l_1 + l_2
dh = h_1 - h_0
p_min = np.arctan(dh/x_0)

def tilt2servo(phi, rad=True):
    if not rad:
        phi = np.deg2rad(phi)

    if phi > p_max:
        phi = p_max
    elif phi < p_min:
        phi = p_min

    k = h_0 + x_0 * np.tan(phi) - h_1_0
    t = np.arcsin((l_1**2-l_2**2+k**2)/(2*k*l_1))

    if not rad:
        t = np.rad2deg(t)
    return t

if __name__ == "__main__":
    print tilt2servo(-15.0, rad=False)

    #print np.rad2deg(p_min) # max theoretical tilt
    #print np.rad2deg(p_max) # max theoretical tilt

    #p = np.linspace(-p_min,p_max) # desired tilt angle
    #t = tilt2servo(p) # desired servo angle
    #plt.plot(p,t)
    #plt.show()


'''
    Company Name : Robinhood

    Problem Statement :
    Write a program to calculate correlation (without any libraries except for math) for two lists X and Y.
    resource : https://corporatefinanceinstitute.com/resources/knowledge/finance/covariance/
'''
def solution(X, Y=None):
    """ Calculate the covariance matrix for the dataset X """
    if Y is None:
        Y = X
    n_samples = np.shape(X)[0]
    covariance_matrix = (1 / (n_samples-1)) * (X - X.mean(axis=0)).T.dot(Y - Y.mean(axis=0))

    return np.array(covariance_matrix, dtype=float)

if __name__ == "__main__":
    import numpy as np
    arr1 = np.array([1692,1978,1884,2151,2519])
    arr2 = np.array([68,102,110,112,154])
    answer = solution(arr1,arr2)
    print(answer)
    # >>> 7284.839999999999


import scipy.stats

def get_z_critical(conf_level: float) -> float:
    """Gets z critical , which is z value corresponding to a specific
    confidence level (for a two sided test)

    Args:
        conf_level (float): confidence level

    Returns:
        float: z critical value
    """
    return scipy.stats.norm.ppf(1-(1-conf_level)/2)

def get_t_critical(conf_level: float, df: int) -> float:
    """Gets t critical , which is t value corresponding to a specific
    confidence level (for a two sided test)

    Args:
        conf_level (float): confidence level
        df (int): degrees of freedom

    Returns:
        float: t critical value
    """
    return scipy.stats.t.ppf(1-(1-conf_level)/2, df)

def get_t_pvalue(t_value: float,
                 df: int,
                 alternative: str = "two-sided") -> float:
    """Get corresponding p value for t value depending on test type

    Args:
        t_value (float): t value
        df (int): degrees of freedom
        alternative (str, optional): two-sided/larger/smaller.
                                     Defaults to "two-sided".

    Raises:
        ValueError: when the test type is invalid

    Returns:
        float: p value
    """

    if alternative == "two-sided":
        p_value = scipy.stats.t.sf(abs(t_value), df=df)*2
    elif alternative == "larger":
        p_value = scipy.stats.t.sf(t_value, df=df)
    elif alternative == "smaller":
        p_value = scipy.stats.t.cdf(t_value, df=df)
    else:
        raise ValueError("invalid alternative")
    return p_value

def get_norm_pvalue(z_value: float,
                    alternative: str = "two-sided") -> float:
    """Get corresponding p value for z value depending on test type

    Args:
        z_value (float): z value
        alternative (str, optional): two-sided/larger/smaller.
                                     Defaults to "two-sided".

    Raises:
        ValueError: when the test type is invalid

    Returns:
        float: p value
    """

    if alternative == "two-sided":
        p_value = scipy.stats.norm.sf(abs(z_value))*2
    elif alternative == "larger":
        p_value = scipy.stats.norm.sf(z_value)
    elif alternative == "smaller":
        p_value = scipy.stats.norm.cdf(z_value)
    else:
        raise ValueError("invalid alternative")
    return p_value

def get_f_pvalue(f_value: float, dfg: int, dfe: int):
    return scipy.stats.f.sf(f_value, dfg, dfe)


import numpy as np
import matplotlib.pyplot as plt
from plot_utils import plot_with_residual

# this is based on https://www.youtube.com/watch?v=sDv4f4s2SB8

# data set
Weight = np.array([0.5 , 2.3 , 2.9]) # x
Height = np.array([1.4 , 1.9 , 3.2]) # y , _observed_height

# Predicted Height = intercept + slope * Weight --> h
def predicted_height(intercept , slope):
    return intercept + slope * Weight

def plot_dataset():
    plt.plot(Weight, Height,'o')
    plt.grid()
    plt.title('data set')
    plt.xlabel("Weight")
    plt.ylabel("Height")
    plt.show()

# _predicted_height is h , _observed_height is y
def sum_of_square_residual(_predicted_height , _observed_height):
    residual = _observed_height - _predicted_height
    return np.dot(residual,residual) # sum the square

def show_ssr_graph_per_intercept(slope):
    vec_intercept = np.arange(0,2,0.1)
    vec_ssr = []
    for intercept in vec_intercept:
        _predicted_height = predicted_height(intercept,slope)
        _observed_height = Height
        ssr = sum_of_square_residual(_predicted_height,_observed_height)
        vec_ssr.append(ssr)

    index_min_ssr = np.argmin(vec_ssr)
    ssr_min = vec_ssr[index_min_ssr]
    intercept_min = vec_intercept[index_min_ssr]
    plt.plot(vec_intercept,vec_ssr,'o',intercept_min,ssr_min,'ro')
    plt.title('cost ssr vs intercept for slope = {}'.format(slope))
    plt.xlabel("intercept")
    plt.ylabel("ssr - sum of squre residual")
    plt.grid()
    plt.show()

def compute_one_ssr(slope):
    intercept = 0 # initial guess
    _predicted_height = predicted_height(intercept,slope)
    _observed_height = Height
    ssr = sum_of_square_residual(_predicted_height,_observed_height)
    print('ssr : ' , ssr)

# ssr is the sum over (y[i])-h[i]))^2
# d_ssr / d_intercept is equal by the chain rule to (d_ssr / d_h) * (d_h / d_intercept)
# d_ssr / d_h -> sum over 2(y[i])-h[i]))*(-1)
# d_h / d_intercept = d(intercept + slope * weight) / d_intercept --> 1
# so  d_ssr / d_intercept is equal to the sum over 2(y[i])-h[i]))*(-1)  but h = intercept + slope * weight so
# d_ssr / d_intercept is equal to the sum over 2 ( y[i] - (intercept + slope * weight[i]))*(-1) or equivalently
# d_ssr / d_intercept is equal to the sum over 2 ( observed_height[i] - (intercept + slope * weight[i]))(-1)
def d_ssr_to_d_intercept(slope,intercept):
    _observed_height = Height
    _predicted_height = intercept + slope * Weight
    error = _observed_height - _predicted_height
    return 2 * np.sum(error) *(-1)

# ssr is the sum over (y[i])-h[i]))^2
# d_ssr / d_slope is equal by the chain rule to (d_ssr / d_h) * (d_h / d_slope)
# d_ssr / d_h -> sum over 2(y[i])-h[i]))*(-1)
# d_h / d_slope = d(intercept + slope * weight) / d_slope --> weight
# so  d_ssr / d_intercept is equal to the sum over 2(y[i])-h[i]))*(-1)*weight[i]  but h = intercept + slope * weight so
# d_ssr / d_intercept is equal to the sum over 2 ( y[i] - (intercept + slope * weight[i]))*(-1)*weight[i] or equivalently
# d_ssr / d_intercept is equal to the sum over 2 ( observed_height[i] - (intercept + slope * weight[i]))(-1)*weight[i]
def d_ssr_to_d_slope(slope,intercept):
     _observed_height = Height
     _predicted_height = intercept + slope * Weight
     error = _observed_height - _predicted_height
     # np.dot : mutliply element by element and than sum
     return 2 * np.dot(error , Weight) *(-1)

def print_d_ssr_to_d_intercept(slope):
    # derivative become smaller
    print("d_ssr/d_intercept @ intercept = 0 : ",d_ssr_to_d_intercept(slope,0))
    print("d_ssr/d_intercept @ intercept = 0.5 : ",d_ssr_to_d_intercept(slope,0.5))
    print("d_ssr/d_intercept @ intercept = 0.8 : ",d_ssr_to_d_intercept(slope,0.8))
    print("d_ssr/d_intercept @ intercept = 0.9 : ",d_ssr_to_d_intercept(slope,0.9))
    print("d_ssr/d_intercept @ intercept = 0.95 : ",d_ssr_to_d_intercept(slope,0.95))
    print("d_ssr/d_intercept @ intercept = 1.05 : ",d_ssr_to_d_intercept(slope,1.05))

def gradient_descent_constant_slope(slope):
    intercept = 0
    learning_rate = 0.1
    step_size = 1 # just a value to enter the loop
    min_step_size = 0.001
    iteration = 0
    ssr_vec = []
    intercept_vec = []

    while abs(step_size) > min_step_size:
        # ------------ this is the gradient descent engine
        step_size = d_ssr_to_d_intercept(slope,intercept) * learning_rate
        intercept = intercept - step_size # i did not see a proof for this

        # ------------ below this is relevant to plot
        intercept_vec.append(intercept)
        _predicted_height = predicted_height(intercept,slope)
        _observed_height = Height
        iteration += 1
        ssr = sum_of_square_residual(_predicted_height , _observed_height)
        ssr_vec.append(ssr)

        plot1(intercept_vec,ssr_vec,intercept,slope,ssr , iteration,step_size)

def plot1(intercept_vec,ssr_vec,intercept,slope,ssr , iteration,step_size):
    fig, axs = plt.subplots(2)
    fig.suptitle('Part 1')
    plot_with_residual(axs[0],Weight,Height,intercept,slope)
    axs[0].grid()
    axs[0].set_title('data set vs intercpt  + slope * weight and residual\nssr : {:.2f} , intercept : {:.2f} , iteration : {} , step : {:.4f}'.format(ssr , intercept , iteration,step_size))
    axs[0].set_xlabel("Weight")
    axs[0].set_ylabel("Height")
    axs[1].plot(intercept_vec,ssr_vec,'o',intercept,ssr,'ro')
    axs[1].set_title('gradient descent convergence , learn intercept . step size become smaller')
    axs[1].set_xlabel("intercept")
    axs[1].set_ylabel("cost function - ssr")
    axs[1].grid()
    plt.tight_layout()
    plt.show()

def gradient_descent():
    intercept = 0
    slope = 1
    learning_rate = 0.01 # using 0.1 will not due
    step_size = 1 # just a value to enter the loop
    min_step_size = 0.001
    iteration = 0
    ssr_vec = []

    while step_size > min_step_size:
        # ------------ this is the gradient descent engine
        step_size_intercept = d_ssr_to_d_intercept(slope,intercept) * learning_rate
        step_size_slope = d_ssr_to_d_slope(slope,intercept) * learning_rate
        intercept = intercept - step_size_intercept # i did not see a proof for this
        slope = slope - step_size_slope
        step_size = max(abs(step_size_intercept) , abs(step_size_slope))

        # ------------ below this is relevant to plot
        _predicted_height = predicted_height(intercept,slope)
        _observed_height = Height
        iteration += 1
        ssr = sum_of_square_residual(_predicted_height , _observed_height)
        ssr_vec.append(ssr)
        print("intercept : {} , slope : {} , step_size : {} , iteration : {}".format(intercept,slope,step_size,iteration))

    plot2(intercept,slope,step_size,iteration,ssr,ssr_vec)

def plot2(intercept,slope,step_size,iteration,ssr,ssr_vec):
    fig, axs = plt.subplots(2)
    plot_with_residual(axs[0],Weight,Height,intercept,slope)
    axs[0].grid()
    fig.suptitle('Part 2')
    axs[0].set_title('data set vs intercpt  + slope * weight and residual\nssr : {:.2f} , intercept : {:.2f} ,slope : {:.2f} , iteration : {} , step : {:.4f}'.format(ssr , intercept,slope , iteration,step_size))
    axs[0].set_xlabel("Weight")
    axs[0].set_ylabel("Height")
    axs[1].plot(ssr_vec)
    axs[1].set_title('gradient descent convergence , learn intercept and slope')
    axs[1].set_xlabel('iteration')
    axs[1].set_ylabel('cost function - ssr')
    axs[1].grid()
    plt.tight_layout()
    plt.show()

# part 1 assume slope is 0.64 , compute intercept
def part1_learn_slope_is_constant():
    slope = 0.64
    compute_one_ssr(slope)
    show_ssr_graph_per_intercept(slope)
    print_d_ssr_to_d_intercept(slope)
    gradient_descent_constant_slope(0.64)

def part2_learn():
    gradient_descent()

# main
plot_dataset()
part1_learn_slope_is_constant()
part2_learn()


import numpy as np

def discount_rate(rate, periods):
    return 1.0 / np.power(1.0 + rate, periods)

def yield_rate(discount, periods):
    return np.power(1.0 / discount, 1.0 / periods) - 1.0

def interpolate_rate(**kwargs) -> float:
    first_period: int = kwargs.get('first_period')
    next_period: int = kwargs.get('next_period')
    extrapolate_period: int = kwargs.get('extrapolate_period')
    first_rate: float = kwargs.get('first_rate')
    next_rate: float = kwargs.get('next_rate')

    assert next_period > extrapolate_period > first_period

    if first_rate == next_rate:
        return first_rate

    first_discount = discount_rate(first_rate, first_period)
    next_discount = discount_rate(next_rate, next_period)
    assert 0.0 < next_discount < first_discount <= 1.0

    second_discount = next_discount / first_discount
    second_periods = next_period - first_period

    extrapolated_discount = first_discount * np.power(second_discount, (extrapolate_period - first_period) / second_periods)
    yr = yield_rate(extrapolated_discount, extrapolate_period)

    assert min(first_rate, next_rate) <= yr <= max(first_rate, next_rate)
    return yr


import numpy as np

x = list(input().split(' '))
f = list(map(int,list(input().split(' '))))

def median(l):
    n = len(l)
    if n%2 == 0:
        return (l[int(n/2)]+l[int((n/2))-1]) / 2.0
    return l[int((n-1)/2)]

def quartiles(l):
    """
    l is an array of integers
    returns a tuple of three integers Q1,Q2,Q3 respectively
    """
    q2 = median(l)
    n = len(l)
    if n%2 != 0:
        i = int((n-1)/2)
        q1,q3 = median(l[:i]), median(l[i+1:])
    else:
        i = int(n/2)
        q1,q3 = median(l[:i]), median(l[i:])
    return q1,q2,q3

s = [int(i) for i,j in zip(x,f) for _ in range(j)]
q1,q2,q3 = quartiles(sorted(s))
#print(q1,q2,q3)
print("{0:.1f}".format(q3-q1))

# Needless to say, this is correct. The above answer is incorrect due to
# https://www.hackerrank.com/challenges/s10-interquartile-range/forum/comments/173186
q1,q2,q3 = np.percentile(s,25), np.percentile(s,50), np.percentile(s,75)
#print(q1,q2,q3)
print("{0:.1f}".format(q3-q1))


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Nov  3 21:06:23 2018

@author: Thiago Almeida
"""

import numpy as np
from metodos_numericos.LU import LU
from metodos_numericos.Gauss import Gauss
from Utils import Utils

class MinimosQuadrados():

    #constroi o polinomio para interpolacao
    def executar(self, x, y, n):

        n_col = len(x)
        n_linhas = n+1
        tam2 = n+1

        #ja preenche a primeira linha com 1
        M1 = np.ones((n_linhas,n_col), dtype=np.float128)

        for k in range (1,n_linhas):
            for j in range (0,n_col):
                M1[k][j] = x[j]**k

        #print("M1", M1)

        A = np.zeros((tam2,tam2), dtype=np.float128)
        B = np.zeros((tam2,), dtype=np.float128)

        #cria matriz
        for i in range (0,tam2):
            for j in range (0,tam2):
                a = np.array(M1[i], dtype=np.float128, copy=True)
                b = np.array(M1[j], dtype=np.float128, copy=True)

                A[i][j] = np.dot(a, b)

        #cria vetor fonte
        for i in range (0,tam2):
            b = np.array(M1[i], dtype=np.float128, copy=True)
            B[i] = np.dot(y, b)

        print("A", A)
        print("B", B)

        #Utils().obtemInfoMatriz(A)

        #calcula coeficientes
        X = LU().executar(A, B)[0]
        #X = Gauss().executarComPivoteamento(A, B)[0]
        #X = Gauss().executar(A, B)[0]
        return X

    def interpolaCoeficientes(self, c, n, xk):

        soma = 0
        for i in range (0,n+1):
            soma += c[i] * (xk ** i)

        #if(np.isnan(soma)):
            #print("resultado da interpolacao do valor "+repr(xk)+" foi igual a NaN")
            #soma = 0

        return soma

    def calculaResiduo(self, y, x, n, c):

        tam = len(y)

        soma1 = 0
        soma2 = 0
        soma3 = 0
        for k in range (0, tam):
            soma1 += (y[k] - self.interpolaCoeficientes(c, n, x[k]))**2
            soma2 += y[k]**2
            soma3 += y[k]

        r2 = 1 - (soma1 / (soma2 - (1/tam)*soma3**2))

        if(r2 < 0):
            print("N="+repr(n)+", r^2 = " + repr(r2) + " e nao tem raiz real")
            return 0
        else:
            return np.sqrt(r2)


#countingWithNestedForLoops.py
import numpy as np

#Example 1
# recall how to count using a for loop:
max_count = 100
for i in range(100):
    print(i)

#Example 2a
# Counting with nested for loops offers an opportunity to think about
# 1. The structure of a number system of different bases
# 2. The structure of multidimensional arrays

# consider counting to 100 in base 10:

count_list = []
base10_count_list = []

# try changing the base to see how the count changes
# the program will count to base ** 2 - 1
# provides interpretable results work for all bases up to 10
base = 3
for i in range(base):
    for j in range(base):
        val = int(str(i) + str(j))
        count_list.append(val)
        #produce equivalent list in base10
        base10_val = i * base + j
        base10_count_list.append(base10_val)
print("\ncount in base", base)
print(count_list)
print("\ncount in base 10:")
print(base10_count_list)

#Example 2b
#imagine that you wanted to count to base ** 3 - 1
count_list = []
base10_count_list = []
# try changing the base to see how the count changes
# the program will count to base ** 3 - 1
# provides interpretable results work for all bases up to 10
for i in range(base):
    for j in range(base):
        for k in range(base):
            val = int(str(i) + str(j) + str(k))
            count_list.append(val)
            #produce equivalent list in base10
            base10_val = i * base ** 2 + j * base + k
            base10_count_list.append(base10_val)

print("\ncount in base", base)
print(count_list)
print("\ncount in base 10:")
print(base10_count_list)

#Example 3
# We can use the same logic to fill an n X n array with values:
n = base
array = np.zeros((n,n))
for i in range(n):
    for j in range(n):
        array[i][j] = i * n + j
print(array)

In Class Projects/In Class Examples Fall 2019/Section 5/countingWithNestedForLoops.py


import numpy as np

def random_graph(node_count, prob):
    """
    Create a random adjacency matrix of a graph

    Parameters
    ----------
    node_count: int
        Number of nodes in the graph
    prob: float
        Probability of presence an edge between two nodes

    Returns
    -------
    adj_mat: numpy.ndarray
        A numpy array of size (node_count, node_count) with elements in {0, 1}
    """
    return np.random.binomial(1, prob, size=(node_count, node_count)).astype(
        np.float64)

def random_choice(arr):
    """
    Based on the suggestion by Radim Rehurek in this tweet:
    https://twitter.com/RadimRehurek/status/928671225861296128

    Results of comparison between this implementation and
    numpy.random.choice:
    ```
    >>>> lst = range(100000)
    >>>> timeit lst[np.searchsorted(uniform.cumsum(), np.random.random())]
    213 µs ± 1.32 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

    >>>> timeit np.random.choice(lst)
    8.2 ms ± 70.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    ```

    Parameters
    ----------
    arr: list
        A 1-D list or array from which to select an element randomly

    Returns
    -------
    One element selected randomly from arr, with uniform probability
    """
    assert type(arr) is list or type(arr) is np.ndarray, 'List not provided!'
    uniform = np.ones((len(arr), )) / len(arr)
    return arr[np.searchsorted(uniform.cumsum(), np.random.random())]

def adj_mat_to_list(adj_mat):
    """
    Converts an adjacency matrix to an adjacency list.

    Parameters
    ----------
    adj_mat: numpy.ndarray
        Square adjacency matrix of a graph

    Returns
    -------
    adj_list: list
        The adjacency list of the given matrix
    """
    assert adj_mat.ndim == 2, 'Adjacency matrix should be of rank 2.'
    assert adj_mat.shape[0] == adj_mat.shape[1], 'Adjacency matrix' \
        ' should be square.'
    assert np.all(adj_mat >= 0), 'All elements of the adjaceny matrix ' \
        'should be nonnegative.'
    adj_list = []
    for i in range(adj_mat.shape[0]):
        adj_list.append([])
        for j in range(adj_mat.shape[0]):
            if adj_mat[i, j] > 0:
                adj_list[-1].append(j)

    return adj_list

def adj_list_to_mat(adj_list):
    """
    Converts an adjacency list to an adjacency matrix.

    Parameters
    ----------
    adj_list: list
        Adjacency list of a graph

    Returns
    -------
    adj_mat: numpy.ndarray
        Square adjacency matrix of a graph
    """
    assert type(adj_list) == list, 'Adjacency list should be provided'

    adj_mat = np.zeros((len(adj_list), len(adj_list)), dtype=np.float64)
    for i in range(len(adj_list)):
        for j in adj_list[i]:
            adj_mat[i, j] = 1.0

    return adj_mat


### 3 Link Forward Kinematics ###

import numpy as np
from numpy import array
import sympy
from sympy import *
from sympy import symbols, cos, sin, pi, simplify, sqrt, atan2, pprint
from sympy.matrices import Matrix

def fk_3link(theta1,theta2,theta3):

    # Create symbols for DH param
    q1, q2, q3 = symbols('q1:4')                               # joint angles theta
    d1, d2, d3 = symbols('d1:4')                              # link offsets
    a0, a1, a2 = symbols('a0:3')                              # link lengths
    alpha0, alpha1, alpha2 = symbols('alpha0:3') # joint twist angles

    # DH Table
    dh = {alpha0:      0, a0:      0, d1:  0.75, q1:        q1,
          alpha1: -pi/2., a1:   0.35, d2:     0, q2: -pi/2.+q2,
          alpha2:      0, a2:   1.25, d3:     0, q3:        q3,}

    # Function to return homogeneous transform matrix

    def TF_Mat(alpha, a, d, q):
        TF = Matrix([[            cos(q),           -sin(q),           0,             a],
                     [ sin(q)*cos(alpha), cos(q)*cos(alpha), -sin(alpha), -sin(alpha)*d],
                     [ sin(q)*sin(alpha), cos(q)*sin(alpha),  cos(alpha),  cos(alpha)*d],
                     [                 0,                 0,           0,             1]])
        return TF

    ## Substiute DH_Table
    T0_1 = TF_Mat(alpha0, a0, d1, q1).subs(dh)
    T1_2 = TF_Mat(alpha1, a1, d2, q2).subs(dh)
    T2_3 = TF_Mat(alpha2, a2, d3, q3).subs(dh)

    #Homogeneous Transforms

    T0_2 = (T0_1 * T1_2) ## (Base) Link_0 to Link_2
    T0_3 = (T0_2 * T2_3) ## (Base) Link_0 to Link_3

    T0_3_value = N(T0_3.evalf(subs={q1: theta1, q2: theta2, q3: theta3}),2) #two digit output
    #print(T0_3 )
    #print('T0_3= \n    ',T0_3_value)
    #print("result:",np.array([T0_3_value]))

    #print("\nT_total Matrix : \n")
    #print("\n")

    return np.array([T0_3_value])

#fk_3link(pi/3,pi/3,pi/3)

#fk_3link(0,0,0)

import numpy,from numpy,import sympy,from sympy


#!/usr/bin/env python
# coding: utf-8
# ## Monte Carlo - Euler Discretization - Part I
# *Suggested Answers follow (usually there are multiple ways to solve a problem in Python).*
# Download the data for Microsoft (‘MSFT’) from Yahoo Finance for the period ‘2000-1-1’ until today.
# In[1]:
import numpy as np
import pandas as pd
from pandas_datareader import data as web
from scipy.stats import norm
import matplotlib.pyplot as plt
get_ipython().run_line_magic('matplotlib', 'inline')
# In[2]:
ticker = 'MSFT'
data = pd.DataFrame()
data[ticker] = web.DataReader(ticker, data_source='yahoo', start='2007-1-1', end='2017-3-21')['Adj Close']
# Store the annual standard deviation of the log returns in a variable, called “stdev”.
# In[3]:
log_returns = np.log(1 + data.pct_change())
# In[4]:
log_returns.tail()
# In[5]:
data.plot(figsize=(10, 6));
# In[6]:
stdev = log_returns.std() * 250 ** 0.5
stdev
# Set the risk free rate, r, equal to 2.5% (0.025).
# In[7]:
r = 0.025
# To transform the object into an array, reassign stdev.values to stdev.
# In[8]:
type(stdev)
# In[9]:
stdev = stdev.values
stdev
# Set the time horizon, T, equal to 1 year, the number of time intervals equal to 250, the iterations equal to 10,000. Create a variable, delta_t, equal to the quotient of T divided by the number of time intervals.
# In[10]:
T = 1.0
t_intervals = 250
delta_t = T / t_intervals
iterations = 10000
# Let Z equal a random matrix with dimension (time intervals + 1) by the number of iterations.
# In[11]:
Z = np.random.standard_normal((t_intervals + 1, iterations))
# Use the .zeros_like() method to create another variable, S, with the same dimension as Z. S is the matrix to be filled with future stock price data.
# In[12]:
S = np.zeros_like(Z)
# Create a variable S0 equal to the last adjusted closing price of Microsoft. Use the “iloc” method.
# In[13]:
S0 = data.iloc[-1]
S[0] = S0
# Use the following formula to create a loop within the range (1, t_intervals + 1) that reassigns values to S in time t.
# $$
# S_t = S_{t-1} \cdot exp((r - 0.5 \cdot stdev^2) \cdot delta_t + stdev \cdot delta_t^2 \cdot Z_t)
# $$
# In[14]:
for t in range(1, t_intervals + 1):
    S[t] = S[t-1] * np.exp((r - 0.5 * stdev ** 2) * delta_t + stdev * delta_t ** 0.5 * Z[t])
# In[15]:
S
# In[16]:
S.shape
# Plot the first 10 of the 10,000 generated iterations on a graph.
# In[17]:
plt.figure(figsize=(10, 6))
plt.plot(S[:, :10]);


from statistics import mean
import numpy as np
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
from matplotlib import style
import random   # to make our data random

style.use('fivethirtyeight')

# xs = [1,2,3,4,5,6]
# ys = [5,4,6,5,6,7]

# plt.plot(xs,ys)
# plt.show()

# Since above are not np array they are just a python array, to change them which will give us
# more powerful way to iterate over then values in the array,

# xs = np.array(xs, dtype = np.float64)  # you can also specify the data-type into your array
# ys = np.array(ys, dtype = np.float64)

# Here we will add our dataset random generation for testing our model
def create_dataset(hm, variance, step = 2, correaltion = False):

    """
    Definition:
    hm          : number of data points that you want to create
    variance    : is how variables or scattered your data are
    step        : how far from the average of our data we want to be, default is (2)
    correlation : to show the data r correlated positively or negatively or none (boolean), default (False)
    this function will return a two lists one for xs and one for ys, you can set your variables in that case to the
    form like
    x1, y2 = create_dataset....etc

    """
    val =1 # this would be the first value in the ys
    ys = []
    for i in range(hm):
        y = val + random.randrange(-variance,variance) # return a value between these two numbers (-variance,variance)
        ys.append(y)  # this is the way to add value to your list above, I thought before ys[i] = y (which is wrong)
        if correaltion and correaltion == 'pos':
            val += step
        elif correaltion and correaltion == 'neg':
            val -= step
    xs = [i for i in range(len(ys))]
    return np.array(xs, dtype = np.float64), np.array(ys, dtype=np.float64)

# first we need a function to calculate the slop as

def best_fit_slop_and_intercept(xs,ys):

    m = ( ((mean(xs)*mean(ys)) - mean(xs*ys)) /
          (mean(xs)**2-mean(xs**2)))
    b = mean(ys)-m*mean(xs)

# remember the PEMDAS the order of the operations in computing
    return m,b

def squared_error(ys_orig, ys_line):
    return sum((ys_line-ys_orig)**2)

def coefficient_of_determination(ys_orig,ys_line):
    y_mean_line = [mean(ys_orig) for y in ys_orig]    # to make a vector with only one value which is mean(ys_orig)
    squared_error_regr = squared_error(ys_orig,ys_line)
    squared_error_y_mean = squared_error(ys_orig, y_mean_line)
    return 1- (squared_error_regr / squared_error_y_mean)

# create data from the random generation data that we               created
xs, ys = create_dataset(2000, 1700,2,'neg')

m,b = best_fit_slop_and_intercept(xs,ys)
print(m,b)

regression_line = [(m*x)+b for x in xs]
print(regression_line)

# Here we will add the piece of code to calculate the coefficient of determination,
r_squared = coefficient_of_determination(ys, regression_line)
print(r_squared)

# this is exact identical to the following format
# for x in xs:
#     regression_line.append((m*x)+b)

# now we will plot the data and the regression line

# what if you want to predict a specific value
predict_x = 8
predict_y = (m*predict_x)+b

plt.scatter(xs,ys)
plt.scatter(predict_x,predict_y, s = 100, color = 'red')
plt.plot(xs,regression_line)
plt.show()

Machine_Learning_Old_Files/[12] linear regression P.5.py


# https://docs.sympy.org/latest/tutorial/calculus.html

from sympy import *
from myprint import spprint

x, y, z = symbols('x y z')
init_printing(use_unicode=False)

# derivatives

spprint(diff(cos(x), x))
spprint(diff(exp(x**2), x))

# derivative 3 times

spprint(diff(x**4, x, x, x))
spprint(diff(x**4, x, 3))

# many variables?

expr = exp(x*y*z)

spprint(expr)

spprint(diff(expr, x, y, y, z, z, z, z))

spprint(diff(expr, x, y, 2, z, 4))

spprint(diff(expr, x, y, y, z, 4))

# diff method

spprint(expr.diff(x, y, y, z, 4))

# "unevaluated" derivative - interesting

deriv = Derivative(expr, x, y, y, z, 4)
spprint(deriv)

# evaluate with .doit - wonder how that works with other things

spprint(deriv.doit())

# not sure what this is - nth derivative with respect to x?

m, n, a, b = symbols('m n a b')
expr = (a*x + b)**m
spprint(expr.diff((x, n)))

#integrals

# indefinate

spprint(integrate(cos(x), x))

# definate

spprint(integrate(exp(-x), (x, 0, oo)))

# multiple

spprint(integrate(exp(-x**2 - y**2), (x, -oo, oo), (y, -oo, oo)))

# unable to compute

expr = integrate(x**x, x)
spprint(expr)
spprint(expr.doit())

# unevaluated

expr = Integral(log(x)**2, x)
spprint(expr)
spprint(expr.doit())

# more complex?

integ = Integral((x**4 + x**2*exp(x) - x**2 - 2*x*exp(x) - 2*x -
        exp(x))*exp(x)/((x - 1)**2*(x + 1)**2*(exp(x) + 1)), x)
spprint(integ)

spprint(integ.doit())

integ = Integral(sin(x**2), x)
spprint(integ)
spprint(integ.doit())

integ = Integral(x**y*exp(-x), (x, 0, oo))
spprint(integ)
spprint(integ.doit())

# limits

spprint(limit(sin(x)/x, x, 0))

# things that cannot be done by subs oo/oo = nan

expr = x**2/exp(x)
spprint(expr)
spprint(expr.subs(x, oo))
spprint(limit(expr, x, oo))

# unevaluated

expr = Limit((cos(x) - 1)/x, x, 0)
spprint(expr)
spprint(expr.doit())

# + or - side of limit
# I guess you do not know if x is
# positive or negative
# maybe can say that when defining symbol

spprint(limit(1/x, x, 0, '+'))
spprint(limit(1/x, x, 0, '-'))

# series - not sure about this
# not related to CS big O

expr = exp(sin(x))
spprint(expr.series(x, 0, 4))

spprint(x + x**3 + x**6 + O(x**4))

spprint(x*O(1))

# how do I enter formalas to print and do not get them
# immediately simplified?

spprint(expr.series(x, 0, 4).removeO())

# another thing I do not understand

f, g = symbols('f g', cls=Function)
spprint(differentiate_finite(f(x)*g(x)))

f = Function('f')
dfdx = f(x).diff(x)
spprint(dfdx.as_finite_difference())

f = Function('f')
spprint(f)
spprint(f(x))
d2fdx2 = f(x).diff(x, 2)
spprint(d2fdx2)
h = Symbol('h')
spprint(d2fdx2.as_finite_difference([-3*h,-h,2*h]))

spprint(finite_diff_weights(2, [-3, -1, 2], 0)[-1][-1])

x_list = [-3, 1, 2]
spprint(x_list)

y_list = symbols('a b c')
spprint(y_list)

spprint(apply_finite_diff(1, x_list, y_list, 0))

# way to get 2*x/x without evaluating
# there is no Div apparently

y = Mul(2*x,1/x, evaluate=False)

# unsimplified

spprint(y)

# simplified

spprint(y.doit())

# I guess there is Add, Mul, Pow