import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn.linear_model import LogisticRegression
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
from sklearn.datasets import make_moons
from sklearn.datasets import make_circles
from sklearn.decomposition import KernelPCA
from scipy.spatial.distance import pdist, squareform
from scipy import exp
from scipy.linalg import eigh
from matplotlib.ticker import FormatStrFormatter

# for sklearn 0.18's alternative syntax
from distutils.version import LooseVersion as Version
from sklearn import __version__ as sklearn_version
if Version(sklearn_version) < '0.18':
    from sklearn.grid_search import train_test_split
    from sklearn.lda import LDA
else:
    from sklearn.model_selection import train_test_split
    from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA

#############################################################################
print(50 * '=')
print('Section: Unsupervised dimensionality reduction'
      ' via principal component analysis')
print(50 * '-')

df_wine = pd.read_csv('https://archive.ics.uci.edu/ml/'
                      'machine-learning-databases/wine/wine.data',
                      header=None)

df_wine.columns = ['Class label', 'Alcohol', 'Malic acid', 'Ash',
                   'Alcalinity of ash', 'Magnesium', 'Total phenols',
                   'Flavanoids', 'Nonflavanoid phenols', 'Proanthocyanins',
                   'Color intensity', 'Hue',
                   'OD280/OD315 of diluted wines', 'Proline']

print('Wine data excerpt:\n\n:', df_wine.head())

X, y = df_wine.iloc[:, 1:].values, df_wine.iloc[:, 0].values

X_train, X_test, y_train, y_test = \
    train_test_split(X, y, test_size=0.3, random_state=0)

sc = StandardScaler()
X_train_std = sc.fit_transform(X_train)
X_test_std = sc.transform(X_test)

cov_mat = np.cov(X_train_std.T)
eigen_vals, eigen_vecs = np.linalg.eig(cov_mat)

print('\nEigenvalues \n%s' % eigen_vals)

#############################################################################
print(50 * '=')
print('Section: Total and explained variance')
print(50 * '-')

tot = sum(eigen_vals)
var_exp = [(i / tot) for i in sorted(eigen_vals, reverse=True)]
cum_var_exp = np.cumsum(var_exp)

plt.bar(range(1, 14), var_exp, alpha=0.5, align='center',
        label='individual explained variance')
plt.step(range(1, 14), cum_var_exp, where='mid',
         label='cumulative explained variance')
plt.ylabel('Explained variance ratio')
plt.xlabel('Principal components')
plt.legend(loc='best')
# plt.tight_layout()
# plt.savefig('./figures/pca1.png', dpi=300)
plt.show()


import math
import numpy as np

#converts matrix entries to mod26
vector_mod26 = np.vectorize(lambda n: round(n % 26))

#change to whatever, as long as it's mod26
A = np.array([[5, 2],
              [3, 1]])
A_inv = vector_mod26(np.linalg.inv(A))
b = np.array([[6],
              [7]])

#encoding function, could be modified for more complexity
def enc(p):
    return A @ p + b

#decoding, directly related to encoding, so need a new decoding for a new encoding function
def dec(p):
    return A_inv @ p - A_inv @ b

#lettertonumber
def ltn(c):
    return ord(c)-65

#numbertoletter
def ntl(n):
    return chr((n % 26)+65)

#for polyalphabetic encoding
def messageToVectors(msg):
    vec_list = []
    while len(msg) > 1 :
        vec_list.append(np.array([[ltn(msg[0])],
                                  [ltn(msg[1])]]))
        msg = msg[2:]
    if len(msg) == 1:
        vec_list.append(np.array([[ltn(msg[0])],
                                  [0]]))
    return vec_list

#applies encoding to vector list
def appEnc(vl):
    return list(map(enc, vl))

#applies decoding to vector list
def appDec(vl):
    return list(map(dec, vl))

#in the name
def vectorsToMessage(vl):
    f = lambda v : v.tolist()
    lol = map(f, vl)
    nums = []
    for sublist in lol:
        for item in sublist:
            for realitem in item:
                nums.append(realitem)
    chars = map(ntl, nums)
    return ''.join(chars)

#actual encryption function, which takes in message
def encrypt(msg):
    print(vectorsToMessage(appEnc(messageToVectors(msg))))

#actual decryption function
def decrypt(msg):
    print(vectorsToMessage(appDec(messageToVectors(msg))))

#tests
print(A_inv)
encrypt("LISTENINGTOGOODKIDMAADCITYFORTHEFIRSTTIMERIGHTNOWITSPRETTYGOOD")


# -*- coding: utf-8 -*-
"""
interest.py

You have $1000 on day 11, and every day you earn 10\%10% of what you already get,
so that on day 22 you have $1000+10%⋅$1000=$1100, and on day 33 you have $1100+10%⋅$1100=$1210.
 On which day you will have more than $1000000 for the first time?

Created on Thu Apr 16 17:42:39 2020

@author: Tim
"""

# %matplotlib inline

import matplotlib.pyplot as plt
import numpy as np

# You can play with the range of values for n and with the base 1.02, see what changes
sample = 200
x = np.arange(sample)
# This is used to plot the graph of 1.02^n, it is blue on the picture below
y = 1.02 ** x
plt.plot(x, y)
plt.xlabel('n')
plt.ylabel('Money($)')
# This is used to plot the graph of 1 + 0.02 * n, it is green on the picture below
z = 1 + 0.02 * x
plt.plot(x, z)
plt.show()

# Computes how much money you will have on day *day*, if you start with *starting_amount* of cash
# and earn *earn_percent* percents of what you already have every day.
def HowMuchMoney(starting_amount, earn_percent, day):
    day_multiplier = 1 + (earn_percent / 100.0)
    return starting_amount * (day_multiplier ** (day - 1))

def PrintExample(starting_amount, earn_percent, day):
    print("If you start with $%d and earn %d%% each day, you will have more than $%.0f on day %d!" %
          (starting_amount, earn_percent, HowMuchMoney(starting_amount, earn_percent, day), day))

# Prints what will happen by day 74 if you start with $1000 and earn 10% every day
# Feel free to play with the parameters

# PrintExample(1000, 10, 74)


import numpy as np
from numpy import fft

# Create a Gaussian kernel of size kernlen and standard deviation sigma
def gaussian_kernel(kernlen, sigma):
    x = np.linspace(-(kernlen // 2), kernlen // 2, kernlen)
    # Unidimensional Gaussian kernel
    kern1d = np.exp(-0.5 * (x ** 2 / sigma))
    # Bidimensional Gaussian kernel
    kern2d = np.outer(kern1d, kern1d)
    # Normalization
    return kern2d / kern2d.sum()

# Compute the FFT of the kernel 'K' of size 'd' padding with the zeros necessary
# to match the size of 'shape'
def psf_fft(K, d, shape):
    # Zero padding
    K_p = np.zeros(shape)
    K_p[:d, :d] = K

    # Shift
    p = d // 2
    K_pr = np.roll(np.roll(K_p, -p, 0), -p, 1)

    # Compute FFT
    K_otf = fft.fft2(K_pr)
    return K_otf

# Multiplication by A
def A(x, K):
    x = fft.fft2(x)
    return np.real(fft.ifft2(K * x))

# Multiplication by A transpose
def AT(x, K):
    x = fft.fft2(x)
    return np.real(fft.ifft2(np.conj(K) * x))

eps = 1e-2

# Variazione totale
def totvar(x):
    # Calcola il gradiente di x
    dx, dy = np.gradient(x)
    n2 = np.square(dx) + np.square(dy)

    # Calcola la variazione totale di x
    tv = np.sqrt(n2 + eps ** 2).sum()
    return tv

# Gradiente della variazione totale
def grad_totvar(x):
    # Calcola il numeratore della frazione
    dx, dy = np.gradient(x)

    # Calcola il denominatore della frazione
    n2 = np.square(dx) + np.square(dy)
    den = np.sqrt(n2 + eps ** 2)

    # Calcola le due componenti di F dividendo il gradiente per il denominatore
    Fx = dx / den
    Fy = dy / den

    # Calcola la derivata orizzontale di Fx
    dFdx = np.gradient(Fx, axis=0)

    # Calcola la derivata verticale di Fy
    dFdy = np.gradient(Fy, axis=1)

    # Calcola la divergenza
    div = dFdx + dFdy

    # Restituisci il valore del gradiente della variazione totale
    return -div

def next_step(x, f, df):  # backtracking procedure for the choice of the steplength
    alpha = 1.1
    rho = 0.5
    c1 = 0.25
    p = -df
    j = 0
    jmax = 10
    # Armijo rule and max iterations
    while (f(x + alpha * p) > f(x) + c1 * alpha * df.T @ p) and j < jmax:
        alpha = rho * alpha
        j += 1
    # Next step not found , convergence not reached
    if j > jmax:
        return -1
    else:
        # print('alpha=',alpha)
        return alpha


import numpy as np
import pandas as pd
from scipy.sparse import csr_matrix

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib.colors import TABLEAU_COLORS

def classic_walk(n, go_left_prob, circle=True):
    """
    create transition matrix and initial state for classic random walk
    args:
    n: number of points on line, use even number to get nice animations, midpoint is adapted to be even point
    this is done in light of frame_option='even' in animation methods, see below
    circle: if True will glue end points together to obatin circle graph
    """
    go_right_prob = 1 - go_left_prob
    # prepare transition matrix
    T = np.diag(go_left_prob*np.ones(n-1),k=-1) + np.diag(go_right_prob*np.ones(n-1),k=1)
    # for circle, glue opposite border nodes by adding an edge between
    if circle:
        T = T + np.diag(go_left_prob*np.ones(1),k=(n-1)) + np.diag(go_right_prob*np.ones(1),k=-(n-1))
    #create start state with all probability in one mid point
    state_0 = np.zeros(n)
    state_0[n//2 - (n//2)%2] = 1
    return T, state_0

def anim_classic_walk(transition, projection, start_pd, n_steps=10, show_equil=False, frame_option='pairsmean'):

    """
    calculate the evolution of random walk and prepare dataframe df of the evolutionvof probability distribution
    the probability distribution at start is given as input start_pd. i
    in each loop through the n_steps frames for the animation, the transition matrix in applied

    projection: matrix would allow projection of whole graph for animation, not really useful for circle
    show_equil: equilibrium is the uniform distribution, which can be plotted so that conversion can be seen
    frame_option: three options of animation frames are possible:
    plain: notrecommended, just plots in each frame the actual probability distribution of that time step of the walk
           this gives a jumpy animation, as in every second step any fixed node has probability zero,
    therefore two variants are recommended:
    pairsmean: show in each animation frame the average of two consecutive evolution steps of probability distribtions
                (except first step, to show true start state)
    even: like a zoom out, it shows only even numbered nodes and only even time steps,
          this gives the smoothest animation, but might be losing some detail
          Note: this is only recommended for even number of nodes, otherwise even nodes become uneven nodes
          as they pass the glued border and parts of dynamic are then invisible in the animation
    """

    T = csr_matrix(transition)
    n = T.shape[0]

    if projection is None:
        P = np.diag(np.ones(n))
    else:
        P = projection
    P = csr_matrix(P)
    n_proj = P.shape[0]

    if frame_option in ['pairsmean', 'plain']:
        n_frames = n_steps-1
        pos_select_stepsize = 1
    elif  frame_option=='even':
        if (n%2)!=0:
            print("NOTE: animation with frame_option='even' and uneven number "
                  +"of nodes not recommended (part of dynamic will be hidden)")
        n_frames = n_steps//2
        pos_select_stepsize = 2
        T = T*T

    # create anim df
    T0 = csr_matrix(np.diag(np.ones(n)))
    T1 = T0
    equi_y = P.dot((1/n)*np.ones(n))*pos_select_stepsize

    df = pd.DataFrame({'x': [], 'y': []})
    for i in range(n_frames):
        T1 = T0*T
        if frame_option=='pairsmean':
            x = np.arange(n_proj)
            if i == 0:
                y = P*(T0*start_pd)
            else:
                y = 0.5*P*(T0*start_pd + T1*start_pd)
        elif  frame_option=='even':
            x = np.arange(0,n_proj+1,2)[:n_proj//2+n_proj%2]
            y = (P*(T0*start_pd))[::pos_select_stepsize]
        elif  frame_option=="plain":
            x = np.arange(n_proj)
            y = P*(T0*start_pd)
        T0 = T1

        df = df.append(pd.DataFrame({'x': x, 'y': y, 'frame': i, 'info': 'evol'}))
        if show_equil:
            df = df.append(pd.DataFrame({'x': x, 'y': equi_y[::pos_select_stepsize], 'frame': i, 'info': 'equi'}))

    return df

### adjusted function for marked state with extra coin
def run_state_evol(graph:dict, coin_mat:np.array, start_state:np.array , n_steps:int, probsum_tol=1e-5,
                  marked_state=None,mrk_state_coin=None, verbose=False):
    """
    run number of steps of quantum random walk on given graph with edge labelling,
    which related edges to dimensions in the coin space

    INPUT: graph = {'edges': (n,2) array , 'fw_edge_labels': (n,) array ,'bw_edge_labels': (n,) array}
    each edge has a label for forward and one for backward direction, the edge array defines what is fw
    edge labels refer to dimensions of the coin space and determine which coinspace
    coefficients are passed along the edge to neighbor node
    coin_mat= (d,d) array, the coin space operator applied before each step on the coin space at each node
    start_state= (n,d) array defines the start state of the coin space - graph - tensor product
    a marked state can be passed with separate coin
    OUT: stacked states for each time step
    """
    n,d = start_state.shape
    # get stacked transition operators on all dimensions of coin space
    A = np.zeros((n,n,d))
    A[graph['edges'][:,0],graph['edges'][:,1],graph['fw_edge_labels']] = 1
    A[graph['edges'][:,1],graph['edges'][:,0],graph['bw_edge_labels']] = 1
    # initialise all zero state evolution and set start state at index time 0
    state_evol = np.zeros((n,d,n_steps)).astype(np.complex64)
    state_evol[:,:,0] = start_state
    # run through all steps, update coin space and then apply transition operator
    if verbose: print('-'*(n_steps-1))
    for i in range(1,n_steps): # .. einstein sum is used for stacked matrix multiplications
        transf_state = coin_mat.dot(state_evol[:,:,i-1].T)
        if marked_state is not None:
            transf_state[:,marked_state] = mrk_state_coin.dot(state_evol[marked_state,:,i-1].T)
        state_evol[:,:,i] = np.einsum('ijk,kj->ik', A, transf_state)
        if verbose: print('-',end='')
    # check for consistent prob distribution
    assert(np.abs((1 - (np.linalg.norm(state_evol,ord=2,axis=1)**2).sum(axis=0))).max()<probsum_tol)
    if verbose: print("\nerror in amplitude sum: ",np.abs((1 - (np.linalg.norm(state_evol,ord=2,axis=1)**2).sum(axis=0))).max())
    return state_evol

def quantum_walk_circle(n):
    d = 2
    # this defines a circle graph with 2 dimensional direction space, one for each direction on the circle
    graph = {
        'edges': np.column_stack((np.arange(0,n),np.arange(1,n+1)%n)).astype(int),
        'fw_edge_labels': 0 * np.ones(n).astype(int) ,
        'bw_edge_labels': 1 * np.ones(n).astype(int)
    }
    # define the state at time 0
    start_state = np.zeros((n,d)).astype(np.complex64)
    start_state[n//2,:] = np.array([1,1])*(1/np.linalg.norm(np.array([1,1])))
    return graph, start_state

def anim_quantum_walk(probs_evol, projection, show_equil=False,show_cesaromean=True,
                       scale_projection=False, frame_option='pairsmean'):
    """
    animation for quantum random walk
    similar to anim_classic_walk above, only difference is that the probability evolution not calculated but an input
    the cesaro mean (which is just the mean of vurrent evolution at every step) is additionally calculated as y_avg
    """
    n = probs_evol.shape[0]

    if projection is None:
        P = np.diag(np.ones(n))
    elif scale_projection:
        P = projection
        P = (np.diag(1/(P.sum(axis=1)))*P)
    else:
        P = projection
    probs_evol = P.dot(probs_evol)
    n_proj = P.shape[0]

    equil_state = P.dot((1/P.shape[1])*np.ones(P.shape[1]))

    if frame_option in ['pairsmean', 'plain']:
        n_frames = probs_evol.shape[1]-1
        pos_select_stepsize = 1
    elif  frame_option=='even':
        if (n%2)!=0:
            print("NOTE: animation with frame_option='even' and uneven number "
                  +"of nodes is not recommended (part of dynamic will be hidden)")
        n_frames = probs_evol.shape[1]//2
        probs_evol = probs_evol[::2,:]
        equil_state = equil_state[::2]

    df = pd.DataFrame({'x': [], 'y': []})
    for i in range(n_frames):
        if frame_option=='pairsmean':
            x = np.arange(n_proj)
            y = 0.5*(probs_evol[:,max(i-1,0)] + probs_evol[:,i])
            y_avg = probs_evol[:,:max(1,i+1)].mean(axis=1)
        elif  frame_option=='even':
            x = np.arange(0,n_proj+1,2)[:n_proj//2+n_proj%2]
            y = probs_evol[:,2*i]
            y_avg = probs_evol[:,:max(2,2*i+1)].mean(axis=1)
        elif  frame_option=="plain":
            x = np.arange(n_proj)
            y = probs_evol[:,i]
            y_avg = y_avg = probs_evol[:,:max(2,i+1)].mean(axis=1)

        df = df.append(pd.DataFrame({'x': x, 'y': y, 'frame': i, 'info': 'Probability'}))
        if show_cesaromean:
            df = df.append(pd.DataFrame({'x': x, 'y': y_avg,
                                         'frame': i, 'info': 'Cesaro mean'}))
        if show_equil:
            df = df.append(pd.DataFrame({'x': x, 'y': equil_state,
                                         'frame': i, 'info': 'Equilibrium'}))

    return df


import math

import torch
import torch.nn as nn

class LocallyConnected(nn.Module):
    """Local linear layer, i.e. Conv1dLocal() with filter size 1.

    Args:
        num_linear: num of local linear layers, i.e.
        in_features: m1
        out_features: m2
        bias: whether to include bias or not

    Shape:
        - Input: [n, d, m1]
        - Output: [n, d, m2]

    Attributes:
        weight: [d, m1, m2]
        bias: [d, m2]
    """

    def __init__(self, num_linear, input_features, output_features, bias=True):
        super(LocallyConnected, self).__init__()
        self.num_linear = num_linear
        self.input_features = input_features
        self.output_features = output_features

        self.weight = nn.Parameter(
            torch.Tensor(num_linear, input_features, output_features)
        )
        if bias:
            self.bias = nn.Parameter(torch.Tensor(num_linear, output_features))
        else:
            # You should always register all possible parameters, but the
            # optional ones can be None if you want.
            self.register_parameter("bias", None)

        self.reset_parameters()

    @torch.no_grad()
    def reset_parameters(self):
        k = 1.0 / self.input_features
        bound = math.sqrt(k)
        nn.init.uniform_(self.weight, -bound, bound)
        if self.bias is not None:
            nn.init.uniform_(self.bias, -bound, bound)

    def forward(self, input: torch.Tensor):
        # [n, d, 1, m2] = [n, d, 1, m1] @ [1, d, m1, m2]
        out = torch.matmul(input.unsqueeze(dim=2), self.weight.unsqueeze(dim=0))
        out = out.squeeze(dim=2)
        if self.bias is not None:
            # [n, d, m2] += [d, m2]
            out += self.bias
        return out

    def extra_repr(self):
        # (Optional)Set the extra information about this module. You can test
        # it by printing an object of this class.
        return "num_linear={}, in_features={}, out_features={}, bias={}".format(
            self.num_linear, self.in_features, self.out_features, self.bias is not None
        )

def main():
    n, d, m1, m2 = 2, 3, 5, 7

    # numpy
    import numpy as np

    input_numpy = np.random.randn(n, d, m1)
    weight = np.random.randn(d, m1, m2)
    output_numpy = np.zeros([n, d, m2])
    for j in range(d):
        # [n, m2] = [n, m1] @ [m1, m2]
        output_numpy[:, j, :] = input_numpy[:, j, :] @ weight[j, :, :]

    # torch
    torch.set_default_dtype(torch.double)
    input_torch = torch.from_numpy(input_numpy)
    locally_connected = LocallyConnected(d, m1, m2, bias=False)
    locally_connected.weight.data[:] = torch.from_numpy(weight)
    output_torch = locally_connected(input_torch)

    # compare
    print(torch.allclose(output_torch, torch.from_numpy(output_numpy)))

if __name__ == "__main__":
    main()


import numpy as np
import json
from utility import *

FILE_TRAIN_DATA = 'train.csv'
FILE_TEST_DATA = 'test.csv'
ALPHA = 2e1
EPOCHS - 75000
FILE_MODEL = 'model/model.dat'

train_flag = False ;

def appendIntercept(X):
	return(np.hstack((np.ones((X.shape[0], 1)), X)))

def originalTheta(len):
	return np.zeros(len)

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

def calcGrad(h_theta, X, y):
	factor = h_theta - y
	factor = factor.values.reshape((X.shape[0], 1))
	term = factor * X
	sigma = np.sum(term, axis=0)
	return sigma / X.shape[0]

def train_model():
	model = {}

	X_df, y = loadData(FILE_TRAIN_DATA)
	X, y, model = normalizeData(X_df, y, model)

	X = appendIntercept(X)
	theta = originalTheta(X.shape[1])

	for i in range(EPOCHS):
		h_theta = sigmoid(np.dot(theta, X.T))
		grad = calcGrad(h_theta, X, y)
		theta = theta - ALPHA * grad

	model['theta'] = list(theta)
	with open(FILE_MODEL, 'w') as f:
		f.write(json.dumps(model))

def predict(X, theta):
	z = np.dot(theta, X.T)
	h_theta = sigmoid(z)
	y_predicted = np.around(h_theta + 1) - 1
	return y_predicted

def test_acc(X, y, given_theta):
	theta = np.array(given_theta)
	y_predicted = predict(X, theta)
	y_diff = np.square(y_predicted - y)
	num_error = np.sum(y_diff)
	err_rat = num_error / (1.0 * X.shape[0])
	acc_pc = (1.0 - err_rat) * 100
	print "The accuracy of the model is", acc_pc

#NOT YET READY
def test_model():
	model = {}
	with open(FILE_MODEL, 'r') as f:
		model = json.loads(f.read())
		X_df, y = loadData(FILE_TEST_DATA)
		X, y = normalizeTestData(X_df, y, model)
		X = appendIntercept(X)
		test_acc(X, y, model['theta'])
#READY
if(train_flag):
	train_model()
else:
	test_model()


import yahoo_fin.stock_info as yf
import numpy as np
import statistics as stats
import scipy.stats as st

ticker = "AAPL"

def getStockStats(ticker):
    """
    Returns stats for a single ticker
    """

    data = yf.get_data(ticker, start_date="08/31/2004",end_date="10/31/2019", interval="1mo") # DATE IS MM/DD/YYYY

    prices = data["adjclose"].tolist()

    returns = []

    for i in range(0, len(prices)-1):
        returns.append(float((prices[i+1]/prices[i])-1))

    average = np.mean(returns)
    standardDeviation = stats.pstdev(returns)
    kurtosis = st.kurtosis(returns)
    sample = len(returns)
    actualKurtosis = float((((kurtosis*(sample-2)*(sample-3)/(sample-1)-6)/(sample+1)+3)))
    skewness = st.skew(returns, bias=True)
    jarque_bera_test, jarque_bera_p_value = st.jarque_bera(returns)

    return [average, standardDeviation, kurtosis, sample, actualKurtosis, skewness, jarque_bera_test, jarque_bera_p_value]

if __name__ == "__main__": #if script runs as program not import
    stats = getStockStats(ticker)
    print("General Statistics on ticker: " + ticker + "\n")
    print("Average Returns: " + str(stats[0]))
    print("Standard Deviation: " + str(stats[1]))
    print("Kurtosis: " + str(stats[2]))
    print("Sample (N): " + str(stats[3]))
    print("Actual Kurtosis: " + str(stats[4]))
    print("Skewness: " + str(stats[5]))
    print("Jarque-Bera Test: " + str(stats[6]))
    print("Jarque-Bera p-value: " + str(stats[7]))


#%% Load libraries
from pandas.plotting import scatter_matrix
import scipy.stats as stats
import statsmodels.formula.api as smf
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.style
import matplotlib.pyplot as plt
%matplotlib inline
mpl.style.use('classic')

#%% Import dataset

#%% Association between random variables
housing = pd.DataFrame.from_csv('data/housing.csv')

display(housing.shape)

display(housing.columns.values)
# columns: array(['LSTAT', 'INDUS', 'NOX', 'RM', 'MEDV'], dtype=object)
# LSTAT - percentage of the population classified as low status
# INDUS - proportion of non-retail business across the town
# NOX - NO2 concentration
# RM - average number of rooms per dwelling
# MEDV - median value of the owner-occupied homes, in $1000s

display(housing.describe())
display(housing.head())

# Check out covariance
# Strongest association - ? todo to understand that: coefficient of correlation
display(housing.cov())

# Check out correlation
display(housing.corr())

#%% Visualize the association between two variables
# Scatter matrix is a matrix of scatter plots for each pair of random variabless.
# The histograms in diagonal positions are those of variables.
housing_scatter_matrix = pd.plotting.scatter_matrix(housing, figsize=(10, 10))
plt.show()

#%% Observe the association more closely
housing.plot(
    kind='scatter',
    x='LSTAT', y='MEDV',
    figsize=(5, 5)
)
plt.show()

housing.plot(
    kind='scatter',
    x='RM', y='MEDV',
    figsize=(5, 5)
)
plt.show()

#%% Simple linear regression model

# y_i = betha_0 + betha_1 * x_i + eps_i

# Try to estimate relations between RM (OX) and MEDV (OY)

# Step 1. estimate values of betha_0 (intercept) and betha_1 (slope)

# Guess of b0 and b1
b0 = 0.1
b1 = 1
housing['guess_response'] = b0 + b1 * housing['RM']
# Calculate error of the guess; this shows how far is our guess response from the true response
housing['guess_error'] = housing['MEDV'] - housing['guess_response']
# Plot estimated line together with real points' values
plt.figure(figsize=(8, 8))
plt.scatter(
    x=housing['RM'], y=housing['MEDV'],
    color='g', label='Observed values'
)
plt.plot(
    housing['RM'], housing['guess_response'],
    color='red', label='guessed response (b0=0.1, b1=1)'
)
plt.legend()
plt.show()
# Calculate SSE
sse_value = (housing['guess_error']**2).sum()
display('Sum of squared error is {0}'.format(sse_value))

#%% Least square estimates
formula = 'MEDV~RM'
model = smf.ols(formula=formula, data=housing).fit()

display(model.params)

b0_ols = model.params[0]
b1_ols = model.params[1]

housing['best_response'] = b0_ols + b1_ols * housing['RM']

housing['best_error'] = housing['MEDV'] - housing['best_response']

# plot estimated line
plt.figure(figsize=(8, 8))
plt.scatter(
    x=housing['RM'], y=housing['MEDV'],
    color='g', label='Observed values'
)
plt.plot(
    housing['RM'], housing['best_response'],
    color='red', label='best response (b0=0.1, b1=1)'
)
plt.legend()
plt.show()

# Calculate SSEs
guess_sse_value = (housing['guess_error']**2).sum()
best_sse_value = (housing['best_error']**2).sum()

display('Sums of squared error are {0}'.format(
    [guess_sse_value, best_sse_value]))
# 'Sums of squared error are [170373.528047, 22061.8791962118]'  # much lower in the second case!!!

#%% Print model summary
model.summary()
# R-squared:	0.484
# F-statistic:	471.8

#%% Diagnostic of linear regression model

# Assumptions of Linear Regression Model
# linearity
# independence
# normality
# equal variance

#%% linearity
# in our case, scatter plot between MEDV and RM has linear pattern - OK

#%% Independence
# Demonstrate that observed error is independent mutually
housing['error'] = housing['MEDV'] - housing['best_response']
plt.figure(figsize=(10, 5))
plt.plot(housing.index, housing['error'], color='red')
plt.axhline(y=0, color='red')
plt.show()  # there is no obvious pattern in the plot

# Durbin Watson test for serial correlation
# Durbin-Watson:	0.684  -- bad score

#%% Normality
# use quantile-quantile plot (QQ plot)
z = (housing['error'] - housing['error'].mean()) / housing['error'].std(ddof=1)
stats.probplot(z, dist='norm', plot=plt)
plt.title('Normal q-q plot')
plt.show()

#%% Equal variance
housing.plot(
    kind='scatter',
    x='RM', y='error',
    figsize=(10, 5), color='green'
)
plt.title('Residuals vs predictor')
plt.axhline(y=0, color='red')
plt.show()

housing.plot(
    kind='scatter',
    x='LSTAT', y='error',
    figsize=(10, 5), color='green'
)
plt.title('Residuals vs predictor')
plt.axhline(y=0, color='red')
plt.show()

# We can see that the regression model (MEDV~LSTAT) violates all four assumptions. Therefore, we cannot make statistical inference using this model
# However, the model can still be applied to make a prediction. The accuracy and the consistency of your model, do not rely on these four assumptions.

#%% Multiple linear regression model
# mimic the process of building trading model of SPY, using historical data of DIFFERENT stock markets.
aord = pd.DataFrame.from_csv('data/ALLOrdinary.csv')
nikkei = pd.DataFrame.from_csv('data/Nikkei225.csv')
hsi = pd.DataFrame.from_csv('data/HSI.csv')
daxi = pd.DataFrame.from_csv('data/DAXI.csv')
cac40 = pd.DataFrame.from_csv('data/CAC40.csv')
sp500 = pd.DataFrame.from_csv('data/SP500.csv')
dji = pd.DataFrame.from_csv('data/DJI.csv')
nasdaq = pd.DataFrame.from_csv('data/nasdaq_composite.csv')
spy = pd.DataFrame.from_csv('data/SPY.csv')

display(nasdaq.head())
# ['Open', 'High', 'Low', 'Close', 'Adj Close', 'Volume']
display(nasdaq.columns.values)

#%% use timezones

indicepanel = pd.DataFrame(index=spy.index)

indicepanel['spy'] = spy['Open'].shift(-1)-spy['Open']
indicepanel['spy_lag1'] = indicepanel['spy'].shift(1)
indicepanel['sp500'] = sp500["Open"]-sp500['Open'].shift(1)
indicepanel['nasdaq'] = nasdaq['Open']-nasdaq['Open'].shift(1)
indicepanel['dji'] = dji['Open']-dji['Open'].shift(1)

indicepanel['cac40'] = cac40['Open']-cac40['Open'].shift(1)
indicepanel['daxi'] = daxi['Open']-daxi['Open'].shift(1)

indicepanel['aord'] = aord['Close']-aord['Open']
indicepanel['hsi'] = hsi['Close']-hsi['Open']
indicepanel['nikkei'] = nikkei['Close']-nikkei['Open']
indicepanel['Price'] = spy['Open']

#%% fix NaN values
display(indicepanel.isnull().sum())

# fill NaNs with forward values

indicepanel = indicepanel.fillna(method='ffill')
indicepanel = indicepanel.dropna()

# check for NaNs again
display(indicepanel.isnull().sum())

# save cleaned data
path_save = 'indicepanel.csv'
indicepanel.to_csv(path_save)

display(indicepanel.shape)

#%% Split dataset & explore train and test sets of data
# because this is financial data (== high noise level), divide into equal parts
Train = indicepanel.iloc[-2000:-1000, :]
Test = indicepanel.iloc[-1000:, :]

print(Train.shape, Test.shape)

# sm = scatter_matrix(Train, figsize=(10, 10))
# plt.show()

#%% Check out correlation of each index between SPY
corr_array = Train.iloc[:, :-1].corr()['spy']
print(corr_array)

formula = 'spy~spy_lag1+sp500+nasdaq+dji+cac40+aord+daxi+nikkei+hsi'
lm = smf.ols(formula=formula, data=Train).fit()
lm.summary()

#%% Make prediction
Train['PredictedY'] = lm.predict(Train)
Test['PredictedY'] = lm.predict(Test)

plt.scatter(Train['spy'], Train['PredictedY'])
plt.show()

#%% Evaluate the model

# RMSE - Root Mean Squared Error, Adjusted R^2

def adjustedMetric(data, model, model_k, yname):
    data['yhat'] = model.predict(data)
    SST = ((data[yname] - data[yname].mean())**2).sum()
    SSR = ((data['yhat'] - data[yname].mean())**2).sum()
    SSE = ((data[yname] - data['yhat'])**2).sum()
    r2 = SSR/SST
    adjustR2 = 1 - (1-r2)*(data.shape[0] - 1)/(data.shape[0] - model_k - 1)
    RMSE = (SSE/(data.shape[0] - model_k - 1))**0.5
    return adjustR2, RMSE

def assessTable(test, train, model, model_k, yname):
    r2test, RMSEtest = adjustedMetric(test, model, model_k, yname)
    r2train, RMSEtrain = adjustedMetric(train, model, model_k, yname)
    assessment = pd.DataFrame(index=['R2', 'RMSE'], columns=['Train', 'Test'])
    assessment['Train'] = [r2train, RMSEtrain]
    assessment['Test'] = [r2test, RMSEtest]
    return assessment

# Get the assement table fo our model
assessTable(Test, Train, lm, 9, 'spy')
# Train	Test
# R2	0.059020	0.067248
# RMSE	1.226068	1.701291

#%% Strategy built from Regression model
Train = indicepanel.iloc[-2000:-1000, :]
Test = indicepanel.iloc[-1000:, :]

formula = 'spy~spy_lag1+sp500+nasdaq+dji+cac40+aord+daxi+nikkei+hsi'
lm = smf.ols(formula=formula, data=Train).fit()

Train['PredictedY'] = lm.predict(Train)
Test['PredictedY'] = lm.predict(Test)

# Train
Train['Order'] = [1 if sig>0 else -1 for sig in Train['PredictedY']]
Train['Profit'] = Train['spy'] * Train['Order']

Train['Wealth'] = Train['Profit'].cumsum()
print('Total profit made in Train: ', Train['Profit'].sum())

plt.figure(figsize=(10, 10))
plt.title('Performance of Strategy in Train')
plt.plot(Train['Wealth'].values, color='green', label='Signal based strategy')
plt.plot(Train['spy'].cumsum().values, color='red', label='Buy and Hold strategy')
plt.legend()
plt.show()

# Test
Test['Order'] = [1 if sig>0 else -1 for sig in Test['PredictedY']]
Test['Profit'] = Test['spy'] * Test['Order']

Test['Wealth'] = Test['Profit'].cumsum()
print('Total profit made in Test: ', Test['Profit'].sum())

plt.figure(figsize=(10, 10))
plt.title('Performance of Strategy in Test')
plt.plot(Test['Wealth'].values, color='green', label='Signal based strategy')
plt.plot(Test['spy'].cumsum().values, color='red', label='Buy and Hold strategy')
plt.legend()
plt.show()

#%% Evaluate strategy
Train['Wealth'] = Train['Wealth'] + Train.loc[Train.index[0], 'Price']
Test['Wealth'] = Test['Wealth'] + Test.loc[Test.index[0], 'Price']

# Sharpe Ratio on Train data
Train['Return'] = np.log(Train['Wealth']) - np.log(Train['Wealth'].shift(1))
dailyr = Train['Return'].dropna()

print('Daily Sharpe Ratio is ', dailyr.mean()/dailyr.std(ddof=1))
print('Yearly Sharpe Ratio is ', (252**0.5)*dailyr.mean()/dailyr.std(ddof=1))

# Sharpe Ratio in Test data
Test['Return'] = np.log(Test['Wealth']) - np.log(Test['Wealth'].shift(1))
dailyr = Test['Return'].dropna()

print('Daily Sharpe Ratio is ', dailyr.mean()/dailyr.std(ddof=1))
print('Yearly Sharpe Ratio is ', (252**0.5)*dailyr.mean()/dailyr.std(ddof=1))

# Maximum Drawdown in Train data
Train['Peak'] = Train['Wealth'].cummax()
Train['Drawdown'] = (Train['Peak'] - Train['Wealth'])/Train['Peak']
print('Maximum Drawdown in Train is ', Train['Drawdown'].max())

# Maximum Drawdown in Test data
Test['Peak'] = Test['Wealth'].cummax()
Test['Drawdown'] = (Test['Peak'] - Test['Wealth'])/Test['Peak']
print('Maximum Drawdown in Test is ', Test['Drawdown'].max())

import numpy,import scipy,import statsmodels


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Dec  2 15:37:10 2020

Copyright 2020 by Hadrien Montanelli.
"""
# %% Imports.

# Standard library imports:
from math import pi
import matplotlib.pyplot as plt
import numpy as np
import time

# Chebpy imports:
from chebpy.trig import coeffs2vals, multmat, trigpts, vals2coeffs

# %% Multiplication g = f*h on [-1,1].

# Functions:
f = lambda x: np.cos(pi*x)
h = lambda x: np.exp(np.sin(10*pi*x))
gex = lambda x: f(x)*h(x)

# Grid:
n = 10000
x = trigpts(n)

# Compute coeffs of f:
F = vals2coeffs(f(x))

# Multiplication by h matrix in coefficient space:
start = time.time()
M = multmat(n, h)
end = time.time()
print(f'Time   (setup): {end-start:.5f}s')
plt.figure()
plt.spy(M)

# Multiply:
start = time.time()
G = M @ F
end = time.time()
print(f'Time (product): {end-start:.5f}s')

# Convert to value space:
g = coeffs2vals(G)

# Error:
error = np.max(np.abs(g - gex(x)))/np.max(np.abs(gex(x)))
print(f'Error  (L-inf): {error:.2e}')

# %% Multiplication g = f*h on [0,2*pi].

# Functions:
f = lambda x: np.cos(x)
h = lambda x: np.exp(np.sin(10*x))
gex = lambda x: f(x)*h(x)

# Grid:
n = 10000
x = trigpts(n, [0, 2*pi])

# Compute coeffs of f:
F = vals2coeffs(f(x))

# Multiplication by h matrix in coefficient space:
start = time.time()
M = multmat(n, h, [0, 2*pi])
end = time.time()
print(f'Time   (setup): {end-start:.5f}s')
plt.figure()
plt.spy(M)

# Multiply:
start = time.time()
G = M @ F
end = time.time()
print(f'Time (product): {end-start:.5f}s')

# Convert to value space:
g = coeffs2vals(G)

# Error:
error = np.max(np.abs(g - gex(x)))/np.max(np.abs(gex(x)))
print(f'Error  (L-inf): {error:.2e}')


# AUTOGENERATED! DO NOT EDIT! File to edit: notebooks/02_hypothesis_testing.ipynb (unless otherwise specified).

__all__ = ['get_mean_test_statistic', 'get_boot_test_statistics', 'get_p_value',
           'plot_hist_with_kde_for_hypothesis_test', 'get_chi2_test_statistic', 'get_spearmanr_test_statistic']

# Cell
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
from scipy import stats
import pandas as pd

from thinkstats import basic_stats
from thinkstats import nsfg

# Cell
def get_mean_test_statistic(a:np.ndarray, b: np.ndarray) -> float: return a.mean() - b.mean()

# Cell
def get_boot_test_statistics(a:np.ndarray, b: np.ndarray, n_tests:int=100,
                             test_statistic_fun:callable=get_mean_test_statistic,
                             mode="merge+shuffle"):
    "Computes bootstrapped test statistics using shuffling"
    test_statistic_boot = np.zeros(n_tests)
    if mode == "merge+shuffle":
        samples = np.hstack((a, b))
        n = len(a)
        for i in range(n_tests):
            np.random.shuffle(samples)
            _a, _b = samples[:n], samples[n:]
            test_statistic_boot[i] = test_statistic_fun(_a, _b)
    elif mode == "shuffle":
        for i in range(n_tests):
            _a, _b = np.random.choice(a, size=len(a)), np.random.choice(b, size=len(b))
            test_statistic_boot[i] = test_statistic_fun(_a, _b)
    else:
        raise NotImplementedError("`mode` needs to be 'merge+shuffle' or 'shuffle'.")
    return test_statistic_boot

# Cell
def get_p_value(x:np.ndarray, test_statistic:float):
    "Computes the p-value using `x` as generated from `get_boot_test_statistics` and the original `test_statistic`"
    kde = stats.gaussian_kde(x)
    p_val = kde.integrate_box_1d(-np.inf, test_statistic)
    if p_val > .5:
        p_val = 1. - p_val
    return p_val

# Cell
def plot_hist_with_kde_for_hypothesis_test(test_statistic_boot:np.ndarray, p_val:float,
                                           left_ext:float=.5, right_ext:float=.5):
    ax = basic_stats.plot_hist_with_kde(test_statistic_boot,
                                   plot_params={"xlabel": "test statistic", "ylabel": "frequency",
                                                "title": f"Sampled test statistics: p-value = {p_val:.4f}"},
                                   fig_params={"figsize": (7,7)}, left_ext=left_ext, right_ext=right_ext)
    ax.plot([test_statistic, test_statistic], ax.get_ylim(), marker="o", color="red", label="actual test statistic")
    ax.legend(loc="best")
    return ax

# Cell
def get_chi2_test_statistic(a:np.ndarray, b: np.ndarray) -> float:
    "`b` is the reference"
    freq_e = pd.Series(b).value_counts(normalize=True).sort_index()
    freq_o = pd.Series(a).value_counts(normalize=True).sort_index()
    return ((freq_o - freq_e)**2/freq_e).sum()

# Cell
def get_spearmanr_test_statistic(a:np.ndarray, b:np.ndarray) -> float:
    "Computes the ranked Spearman correlation"
    assert len(a) == len(b)
    return stats.spearmanr(a, b).correlation


import os, pickle, csv, sys
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
import random

R = 1
TOTAL = 10000000
HIT = 0

for j in range(1,100):
    for i in range(TOTAL):
        x = random.uniform(-1,1)
        y = random.uniform(-1,1)
        r = np.sqrt(x*x+y*y)
        if r < 1:
            HIT = HIT + 1
    pi = float(HIT)/float(TOTAL*j)*4
    print j,HIT, TOTAL, pi


# -*- coding: utf-8 -*-

# -- Sheet --

# # Simple Linear Regression

# # Importing the Libraries

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

# # Importing the dataset

dataset=pd.read_csv("Salary_Data.csv")
X=dataset.iloc[:,:-1].values
y=dataset.iloc[:,-1].values
dataset.head()

# # Splitting the dataset into Train set and Test set

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X,y, test_size=0.2, random_state=0)

# # Training the Simple Linear Regression model on the Training set

from sklearn.linear_model import LinearRegression
regressor=LinearRegression()
regressor.fit(X_train, y_train)

# # Predicting the Test set results

y_pred=regressor.predict(X_test)

# # Visualising the Training set results
# - We will use the matplotlib library. To be exact pyplot for plotting our training set reults.

plt.scatter(X_train, y_train, color='red')
plt.plot(X_train, regressor.predict(X_train), color='blue')
plt.title('SALARY vs EXPERIENCE (Training Set)')
plt.xlabel('EXPERIENCE (Years)')
plt.ylabel('SALARY (USD)')

# # Visualising the Test set results
# - We will use the matplotlib library. To be exact pyplot for plotting our training set reults.

plt.scatter(X_test, y_test, color='green')
plt.plot(X_train, regressor.predict(X_train), color='blue')
plt.title('SALARY vs EXPERIENCE (Test Set)')
plt.xlabel('EXPERIENCE (Years)')
plt.ylabel('SALARY (USD)')

# # Making a single prediction (for example the salary of an employee with 12 years of experience)

print(regressor.predict([[12]]))

# Therefore, our model predicts that the salary of an employee with 12 years of experience is $ 138967,5.
#
# Important note: Notice that the value of the feature (12 years) was input in a double pair of square brackets. That's because the "predict" method always expects a 2D array as the format of its inputs. And putting 12 into a double pair of square brackets makes the input exactly a 2D array. Simply put:
#
# `12 ➙ Scalar`
#
# `[12] ➙ 1D Array`
#
# `[[12]] ➙ 2D Array`

# # Getting the final linear regression equationwith the values of the coefficients.

print(regressor.coef_)
print(regressor.intercept_)

# Therefore, the equation of our simple linear regression model is:
#
# **Salary=9345.94xYearsOfExperience+26816.19**
#
# **Important Note:** To get these coefficients we called the "coef_" and "intercept_" attributes from our regressor object. Attributes in Python are different than methods and usually return a simple value or an array of values.


import numpy as np

# function which transforms factorization from the form of the product WH to the sum of rank 1 matrices
def from_WH_to_rank_1_list(W, H):
    l = []
    for i in range(W.shape[1]):
        l.append(W[:, i:i+1] @ H[i:i+1, :])
    return l

# function which transforms factorization from the form of the sum of rank 1 matrices to the product WH
def from_rank_1_list_to_WH(rank_1_list):
    cols_W = []
    rows_H = []

    for V in rank_1_list:
        w, h = from_rank_1_matrix_to_wh(V)
        cols_W.append(w)
        rows_H.append(h)

    W = np.hstack(cols_W)
    H = np.vstack(rows_H)
    return W, H

def from_rank_1_matrix_to_wh(V):
    idx = np.where(V > 0)
    idx = [idx[0][0], idx[1][0]]

    v = V[idx[0], idx[1]]

    w = V[:, [idx[1]]]
    h = V[[idx[0]], :] / v

    if np.sum(np.abs(V - w @ h)) / (V.shape[0] * V.shape[1]) > 1e-9:
        raise Exception("Matrix appears to be of rank higher than 1\n{}".format(V))
    return w, h

# a function which makes sure that for i, ith column of W and ith row of H are of the same magnitude
# and that these rows / columns are sorted according to this magnitude in a decreasing order
def rescale_WH(W, H):
    s1 = np.sum(W, axis=0)
    s2 = np.sum(H, axis=1)
    s1[s1 == 0] = 1e-10
    s2[s2 == 0] = 1e-10

    srt_prod = np.sqrt(s1 * s2)
    idx = np.argsort(-1 * srt_prod)
    S1 = (srt_prod / s1).reshape((1, -1))
    S2 = (srt_prod / s2).reshape((-1, 1))
    return (W * S1)[:, idx], (H * S2)[idx, :]


import numpy as np

y_predicted = np.array([1, 1, 0, 0, 1])
y_true = np.array([0.30, 0.7, 1, 0, 0.5])

def mae(y_predicted, y_true):
    total_error = 0
    for yp, yt in zip(y_predicted, y_true):
        total_error += abs(yp - yt)
    print("Total error is:", total_error)
    mae = total_error / len(y_predicted)
    print("Mean absolute error is:", mae)
    return mae

mae(y_predicted, y_true)

# todo: Implement same thing using numpy in much easier way
print("np abs", np.abs(y_predicted - y_true))
print("np mean", np.mean(np.abs(y_predicted - y_true)))

def mae_np(y_predicted, y_true):
    return np.mean(np.abs(y_predicted - y_true))

print("np mean by", mae_np(y_predicted, y_true))

# todo: Implement Log Loss or Binary Cross Entropy
print("np log[0]", np.log([0]))
epsilon = 1e-15
print("np.log[1e-15]", np.log([1e-15]))
print("y_predicted", y_predicted)

y_predicted_new = [max(i, epsilon) for i in y_predicted]
print("y_predicted_new", y_predicted_new)

print("1 - epsilon", 1 - epsilon)
y_predicted_new = [min(i, 1 - epsilon) for i in y_predicted_new]
print("y_predicted_new", y_predicted_new)
y_predicted_new = np.array(y_predicted_new)
print("np.log(y_predicted_new)", np.log(y_predicted_new))

print("long line", -np.mean(y_true * np.log(y_predicted_new) + (1 - y_true) * np.log(1 - y_predicted_new)))

def log_loss(y_true, y_predicted):
    y_predicted_new = [max(i, epsilon) for i in y_predicted]
    y_predicted_new = [min(i, 1 - epsilon) for i in y_predicted_new]
    y_predicted_new = np.array(y_predicted_new)
    return -np.mean(y_true * np.log(y_predicted_new) + (1 - y_true) * np.log(1 - y_predicted_new))

print("last line", log_loss(y_true, y_predicted))

Python/Deep Learning/Code Basics/11 Loss or Cost Function.py


from numpy import*

import matplotlib.pyplot as plt

def rungeKutta(f, to, yo, tEnd, tau):
         def increment(f, t, y, tau):  # поиск приближённого решения методом Рунге—Кутта—Фельберга.
                  k1 = tau*f(t, y)
                  k2 = tau*f(t+(1/4)*tau, y+(1/4)*k1)
                  k3 = tau*f(t+(3/8)*tau, y+(3/32)*k1+(9/32)*k2)
                  k4 = tau*f(t+(12/13)*tau, y+(1932/2197)*k1-(7200/2197)*k2+(7296/2197)*k3)
                  k5 = tau*f(t+tau, y+(439/216)*k1-8*k2+(3680/513)*k3 -(845/4104)*k4)
                  k6 = tau*f(t+(1/2)*tau, y-(8/27)*k1+2*k2-(3544/2565)*k3 +(1859/4104)*k4-(11/40)*k5)
                  return (16/135)*k1+(6656/12825)*k3+(28561/56430)*k4-(9/50)*k5+(2/55)*k6

         t = []  # preparing an empty list t
         y = []  # preparing an empty list y
         t.append(to)  #
         y.append(yo)  # внесение в список y начального значения yo
         while to < tEnd:  # внесение результатов расчёта в массивы t,y
                  tau = min(tau, tEnd - to)  # определение минимального шага tau
                  yo = yo + increment(f, to, yo, tau)  # расчёт значения в точке t0,y0 для задачи Коши
                  to = to + tau  # приращение времени
                  t.append(to)  # заполнение массива t
                  y.append(yo)  # заполнение массива y
         return array(t), array(y)

def f(t, y):
    return (1/power(t,2))*(t*y - power(y,2))

to = 1  # начальный момент отсчёта времени
tEnd = 3  # конечный момент отсчёта времени
#yo = array([0,1,1,0])  # начальные условия
#yo = array([0,1,1,0,1])
#yo = 2
#yo = array([0.2, 1, 1, 0, 1, 1.5])
tau = 0.2
t = to  # шаг
tt = []  # preparing an empty list tt
yy = []

while(to<=tEnd):
    t, y = rungeKutta(f, to, yo, tEnd, tau)
    t = t+ tau
    tt.append(t)
    yy.append(y)
y1 = array([i[0] for i in y])
y2 = array([i[1] for i in y])
y3 = array([i[2] for i in y])
y4 = array([i[3] for i in y])
y5 = array([i[4] for i in y])
y6 = array([i[5] for i in y])

# визуализация
plt.plot(t, y1, label = 'y1')
plt.plot(t, y2, label = 'y2')
plt.plot(t, y3, label = 'y3')
plt.plot(t, y4, label = 'y4')
plt.plot(t, y5, label = 'y5')
plt.plot(t, y6, label = 'y6')

print(y1)
print(y2)
print(y3)
print(y4)
print(y5)
print(y6)

plt.title("Results of the numerical solution of the ODE \n system using the \n Runge–Kutta–Felberg method")
plt.xlabel('t')
plt.ylabel('Yn')
plt.legend(loc='best')
# plt.xlim(0, 8)
# plt.ylim(-0.1, 2)
plt.grid(True)
plt.show()


#!/usr/bin/python

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

class DiffDriveController():
    """
    Class used for controlling the robot linear and angular velocity
    """
    def __init__(self, max_speed, max_omega):
        # TODO for Student: Specify these parameters
        self.kp= 0.5 #0.3
        self.ka= 2.0 #4
        self.kb= 0.001 #0.01
        self.MAX_SPEED = max_speed
        self.MAX_OMEGA = max_omega
        self.target_rho = 1.0

    def update_target_rho(self, new_rho):
        self.target_rho = new_rho

    def compute_vel(self, state, goal):
        """
        Function that computes the desired outputs given the state and goal
        Inputs:
        state - a numpy vector of size 3 by 1 with components (x,y,theta)
        goal - a numpy vector of size 2 by 1 specifying the location of the goal
        Outputs: a tuple with 3 elements
        v - a number specifying the forward speed (in m/s) of the robot (should
            be no more than max_speed)
        omega - a number specifying the angular velocity (in rad/s) of the robot
            (should be no more than max_omega)
        done - a boolean value specifying if the robot has reached its goal (or
            is close enough
        """
        # YOUR CODE HERE
        #print "goal: ", goal
        #print "state: ", state
        dx = goal[0] - state[0]
        dy = goal[1] - state[1]
        theta = state[2]
        rho = np.sqrt(dx**2 + dy**2)
        pos_beta = atan2(dy,dx) #NOTE, I CHANGED THE DEFINITION BETA TO BE +ATAN2, SO NOW kb > 0
        alpha = pos_beta - theta
        if(alpha >= pi):
            alpha -= 2*pi
        elif(alpha < -pi):
            alpha += 2*pi

        v = self.kp * rho
        if(v < -self.MAX_SPEED):
          v = -self.MAX_SPEED
        elif(v > self.MAX_SPEED):
          v = self.MAX_SPEED

        w = self.ka*alpha + self.kb*pos_beta
        if(w < -self.MAX_OMEGA):
          w = -self.MAX_OMEGA
        elif(w > self.MAX_OMEGA):
          w = self.MAX_OMEGA

        #~ if(v < 0.15):
          #~ v = 0.15
          #~ if(abs(w) < 0.5):
            #~ v = 0.15
          #~ else:
            #~ v = 0.0
            #~ if(w < 0):
              #~ w = -1.0
            #~ else:
              #~ w = 1.0

        done = False
        if(rho < self.target_rho):
            v = 0.0
            w = 0.0
            done = True

        return v,w,done, alpha, pos_beta


import logging
from typing import List

import numpy
from sklearn.decomposition import PCA

logger = logging.Logger("PrincipalComponentAnalysis")

class PrincipalComponentAnalysis:

    def __init__(self, number_of_dimensions: int, data: numpy.array, number_of_closest_values: int):
        assert number_of_closest_values <= len(data)
        self.number_of_closest_values = number_of_closest_values
        self.number_of_dimensions = number_of_dimensions
        self.data = data
        self.__train()

    def __train(self) -> None:
        self.pca = PCA(n_components=self.number_of_dimensions)
        logger.info("Start fitting PCA")
        self.low_dim_train_data = self.pca.fit_transform(X=self.data)
        logger.info("Completed fitting PCA")

    def calculate_distance(self, feature_array: numpy.array) -> float:
        observed_record = self._transform(feature_array)

        distances = self._calculate_distances(observed_record)
        smallest_distances = self._filter_smallest_distances(distances)
        average = self._average(smallest_distances)
        return average

    def _calculate_distances(self, observed_record) -> List[float]:
        distances = []
        for td_record in self.low_dim_train_data:
            euclid_distance = numpy.linalg.norm(td_record - observed_record)
            distances.append(euclid_distance)
        return distances

    def _transform(self, feature_array: numpy.array) -> numpy.array:
        return self.pca.transform(feature_array)

    def _filter_smallest_distances(self, distances: List[float]):
        np_distances = numpy.asarray(distances)
        indexes = numpy.argpartition(np_distances, self.number_of_closest_values)
        values = np_distances[indexes[:self.number_of_closest_values]]
        return values

    def _average(self, smallest_distances: numpy.array) -> float:
        assert smallest_distances.shape == (self.number_of_closest_values,)
        return numpy.mean(smallest_distances)


import jax.numpy as jnp

import matplotlib.pyplot as plt

from jsl.gym_envs.configs.regression_kf_test import get_config, make_evenly_spaced_x_sampler, sample_fn
from jsl.gym_envs.run import main as train

from numpy.linalg import inv

def posterior_lreg(X, y, R, mu0, Sigma0):
    Sn_bayes_inv = inv(Sigma0) + X.T @ X / R
    Sn_bayes = inv(Sn_bayes_inv)
    mn_bayes = Sn_bayes @ (inv(Sigma0) @ mu0 + X.T @ y / R)

    return mn_bayes, Sn_bayes

def main():
    config = get_config()
    params_per_trial, _ = train(config)

    trial = 0

    w0_hist, w1_hist = params_per_trial[trial]["mu"].T
    w0_err, w1_err = jnp.sqrt(params_per_trial[trial]["sigma"][:, [0, 1], [0, 1]].T)

    # Offline estimation
    input_dim, num_train = 2, 21
    x_generator = make_evenly_spaced_x_sampler(input_dim)
    X, y = sample_fn(None, x_generator, num_train, None)

    R = config.agent.init_kwargs['R']
    mu0 = config.agent.init_kwargs['mu0']
    Sigma0 = config.agent.init_kwargs['Sigma0']
    (w0_post, w1_post), Sigma_post = posterior_lreg(X, y, R, mu0, Sigma0)

    w0_std, w1_std = jnp.sqrt(Sigma_post[[0, 1], [0, 1]])

    dict_figures = {}

    timesteps = jnp.arange(num_train)
    fig, ax = plt.subplots()
    ax.errorbar(timesteps, w0_hist, w0_err, fmt="-o", label="$w_0$", color="black", fillstyle="none")
    ax.errorbar(timesteps, w1_hist, w1_err, fmt="-o", label="$w_1$", color="tab:red")

    ax.axhline(y=w0_post, c="black", label="$w_0$ batch")
    ax.axhline(y=w1_post, c="tab:red", linestyle="--", label="$w_1$ batch")

    ax.fill_between(timesteps, w0_post - w0_std, w0_post + w0_std, color="black", alpha=0.4)
    ax.fill_between(timesteps, w1_post - w1_std, w1_post + w1_std, color="tab:red", alpha=0.4)
    plt.legend()
    ax.set_xlabel("time")
    ax.set_ylabel("weights")
    ax.set_ylim(-8, 4)
    ax.set_xlim(-0.5, num_train)
    dict_figures["linreg_online_kalman"] = fig

    return dict_figures

if __name__ == "__main__":
    from jsl.demos.plot_utils import savefig
    plt.rcParams["axes.spines.right"] = False
    plt.rcParams["axes.spines.top"] = False
    dict_figures = main()
    savefig(dict_figures)
    plt.show()


import numpy as np
import logging
from tqdm import tqdm

class Perceptron():

    def __init__(self, eta, epochs) -> None:
        #initialize weights randomly--> these are when NN is initialized
        # create 3 weights w1,w2 and bias w0 , and multiply by very small no. to get a small value (randomly)
        self.weights = np.random.randn(3) * 1e-4
        logging.info(f'initial weights before training {self.weights}')
        self.eta= eta
        self.epochs = epochs

    # this is a unit step function
    def activationFunction(self, inputs, weights):
        """To perform dot product and apply activation fn. z= W*X and then act(z) .

        Args:
            inputs (array): array of inputs in array form
            weights (array): array of weights

        Returns:
            array: returns 1 wherever z elements is greater than 0
        """
        z= np.dot(inputs, weights)
        # unit step act. fn.
        return np.where(z>0, 1, 0)

    def fit(self, X, y):
        ## self making variables accesible globally in class
        self.X= X
        self.y= y

        ## Concatenating using np,.c_ ... X (3x1) and bias ([-1,-1,-1]) (3x1)
        X_with_bias= np.c_[self.X, -np.ones((len(self.X),1))]
        logging.info(f'x with bias : \n{X_with_bias}')

        for epoch in tqdm(range(self.epochs), total=self.epochs, desc="Training the model"):
            logging.info("-"*20)
            logging.info(f"for epoch: {epoch}")
            logging.info("-"*20)

            #forward propagation
            y_hat= self.activationFunction(X_with_bias, self.weights)
            logging.info(f"predicted value after forward pass: \n{y_hat}")

            self.error= self.y - y_hat
            logging.info(f"Error: \n{self.error}")

            #backward propagation --> to update weights based on prediction error (using gradient of loss fn.)
            ## gradient of simple diff error y-y' wrt W is below
            self.weights= self.weights + self.eta * np.dot(X_with_bias.T, self.error)
            logging.info(f"updated weights after this epoch: \n{epoch}/{self.epochs} : {self.weights}")
            logging.info("##"*20)

    def predict(self, X):
        X_with_bias= np.c_[X, -np.ones((len(X),1))]
        return self.activationFunction(X_with_bias, self.weights)

    def total_loss(self):
        loss_total= np.sum(self.error)
        logging.info(f"total loss: \n{loss_total}")


from functools import partial

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

def my_kde_bandwidth(obj, fac=1./5):
    """We use Scott's Rule, multiplied by a constant factor."""
    return np.power(obj.n, -1./(obj.d+4)) * fac

loc1, scale1, size1 = (-2, 1, 175)
loc2, scale2, size2 = (2, 0.2, 50)
x2 = np.concatenate([np.random.normal(loc=loc1, scale=scale1, size=size1),
                     np.random.normal(loc=loc2, scale=scale2, size=size2)])

x_eval = np.linspace(x2.min() - 1, x2.max() + 1, 500)

kde = stats.gaussian_kde(x2)
kde2 = stats.gaussian_kde(x2, bw_method='silverman')
kde3 = stats.gaussian_kde(x2, bw_method=partial(my_kde_bandwidth, fac=0.2))
kde4 = stats.gaussian_kde(x2, bw_method=partial(my_kde_bandwidth, fac=0.5))

pdf = stats.norm.pdf
bimodal_pdf = pdf(x_eval, loc=loc1, scale=scale1) * float(size1) / x2.size + \
              pdf(x_eval, loc=loc2, scale=scale2) * float(size2) / x2.size

fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111)

ax.plot(x2, np.zeros(x2.shape), 'b+', ms=12)
ax.plot(x_eval, kde(x_eval), 'k-', label="Scott's Rule")
ax.plot(x_eval, kde2(x_eval), 'b-', label="Silverman's Rule")
ax.plot(x_eval, kde3(x_eval), 'g-', label="Scott * 0.2")
ax.plot(x_eval, kde4(x_eval), 'c-', label="Scott * 0.5")
ax.plot(x_eval, bimodal_pdf, 'r--', label="Actual PDF")

ax.set_xlim([x_eval.min(), x_eval.max()])
ax.legend(loc=2)
ax.set_xlabel('x')
ax.set_ylabel('Density')

plt.show()


from numpy import *
import theano
import theano.tensor as T
from scipy.misc import logsumexp
from scipy.optimize import fmin_ncg

random.seed(1)

K = 5#nClasses
N = 10 #nSamples
Dout = 4 #hidden features
Din = 2 #input features

#single precision for now
theano.config.floatH = 'float32'

#setup toy example
X = random.randn(N, Din)
Win = random.randn(Din, Dout)
Wout = random.randn(Dout,K)
#hidden activations
Hlin = dot(X, Win)
H = tanh(Hlin)
Eta = dot(H,Wout)
lNorm = logsumexp(Eta, axis=1).reshape(N,1)
lP = Eta - lNorm
#take one sample from a multinomial distribution specified by a row of lP
_,y = apply_along_axis(lambda row: random.multinomial(1, exp(row)), axis=1, arr=lP).nonzero()
y = y.astype(int32)
Wout = Wout.astype(float32)
Win = Win.astype(float32)
H = H.astype(float32)
X = X.astype(float32)
Hlin = Hlin.astype(float32)

#setup theano
tX = T.matrix('X')
tWin = T.matrix('Win')
tWout = T.matrix('Wout')
ty = T.ivector('y')
tlambda = T.scalar('lambda')

#symbolic representation
tHlin = T.dot(tX, tWin)
tH = T.tanh(tHlin)
tEta = T.dot(tH, tWout)
tP = T.nnet.softmax(tEta)
terror = T.nnet.categorical_crossentropy(tP, ty).mean()
tgrad = T.grad(terror, [tWout, tWin])

#numeric functions
f = theano.function([tWout, tWin, tX, ty], terror)
g = theano.function([tWout, tWin, tX, ty], tgrad)

"""
Main Part of experiment:
    Can we manually invoke the chain rule to let theano compute gradients deeper down in the architecture?
    The goal is to compute the gradient wrt. parameters of the output layer by hand which is more convenient and then let theano figure out the rest, i.e. the parameters of the RNN backbone automatically
"""
#Compute reference gradient
gWout, gWin = g(Wout, Win, X,y)

#compute symbolic graident wrt. to hidden
tgH = T.grad(terror, tH)

#invoking chain rule manually with partial symbolic gradient with respect to hidden unit
tgWin2 = theano.gradient.Lop(tH, tWin, tgH)
gWin2 = tgWin2.eval({tX:X,ty:y,tWin:Win,tWout:Wout})

#can we do it also with an actual partial numeric result?
gH = tgH.eval({tX:X,ty:y,tWin:Win,tWout:Wout})
tgHdummy = T.matrix("tgHdummy")
tgWin3 = theano.gradient.Lop(tH, tWin, tgHdummy)
gWin3 = tgWin3.eval({tX:X,tWin:Win,tgHdummy:gH})


import numpy as np
from scipy.stats import norm, chi2

def Hartung(p, L=None, kappa=0.2, alpha=0.10):

    '''
     This function applies the modified inverse normal method for the combination of dependent p-values.

     Arguments:
         p:         vector of p-values.
         lambda:    vector of weights. It must be of the same length of p.
         kappa:     adjustment parameter. It is a positive value (0.2 is the default value),
                    then it is computed as in Hartung, p. 853.
         alpha:     level for the 1-alpha confidence interval for rho (0.10 is the default).

    Returns:
         Value: {"statistic": the Ht test statistic
        	     "parameter": the number of combined tests (p-values)
        	     "pvalue": the combined test p-value
        	     "conf_int": the confidence interval for the estimated correlation
        	     "estimate": the estimated correlation
        	     "null_value": the specified hypothesized value under the null
        	     "alternative": string describing the alternative hypothesis
        	     "method": string indicating the type of combination test (only Z-test is implemented)}

     Reference:
     Hartung, J. (1999): "A note on combining dependent tests of significance",
                         Biometrical Journal, 41(7), 849--855.
    '''

    if L == None:
        L = np.ones(len(p), dtype=float)

    t = norm.ppf(p)
    n = float(len(p))
    avt = np.sum(t)/n
    q = np.sum((t - avt)**2)/(n-1)                          # Hartung, eqn. (2.2)
    rhohat = 1 - q
    rhostar = max(-1/(n-1), rhohat)                           # Hartung, p. 851
    if kappa=="formula": kappa = (1 + 1/(n-1) - rhostar)/10  # Hartung, p. 853
    if kappa=="formula2": kappa = (1 + 1/(n-1) - rhostar)/5  # Hartung, p. 853

    # Hartung inverse normal corrected. See eqn. (2.4)

    Ht = np.sum(L*t)/np.sqrt(np.sum(L**2)+((np.sum(L))**2-np.sum(L**2))*(rhostar+kappa*np.sqrt(2/(n-1))*(1-rhostar)))
    lower = 1 - (n-1)/chi2.ppf(alpha/2, (n-1)) * q
    upper = 1 - (n-1)/chi2.ppf((1-alpha/2), (n-1)) * q          # Hartung, eqn. (2.3)

    output = dict(statistic=Ht,
                   parameter=n,
                   pvalue=norm.cdf(Ht),
                   conf_int=(lower, upper),
                   estimate=rhohat,
                   null_value="Ht=0",
                   alternative="less",
                   method="modified inverse normal combination")

    return output


# logistic regression

# minimize (1/n)sum_t ln(1 + e(-y_t beta.x_t)) + 0.5*lambda*||beta||_2^2

import math
import numpy as np
#from cvxpy import *
from sklearn.linear_model import LogisticRegression

MAX_ERR = 1000000000

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

# Max norm of optimal hypothesis when this is the regularization param
def compute_max_norm(lamb):
  return math.sqrt(2.0*math.log(2.0) / lamb)

# Sensitivity of a query to sparse vector
def get_sv_sensitivity(max_norm, n):
  return math.log(1.0 + math.exp(max_norm)) / n

# L1-sensitivity of the optimal beta
def compute_opt_sensitivity(n, dim, lamb):
  return 2.0 * math.sqrt(dim) / (n*lamb)

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

def compute_err(X, Y, lamb, beta):
  n = len(X)
  total = 0.0
  try:
    for i in range(n):
      total += math.log(1.0 + math.exp(-Y[i] * np.dot(X[i], beta)))
  except OverflowError:
    return MAX_ERR
  avg = total / n
  twonorm = np.dot(beta, beta)
  return avg + 0.5 * lamb * twonorm

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

def logistic_regression(X, Y, lamb):
  C = 1.0 / (lamb * len(X))
  lr = LogisticRegression(penalty="l2", C=C, fit_intercept=False)
  lr.fit(X, Y)
  beta = np.array(lr.coef_[0])
  return beta, compute_err(X, Y, lamb, beta)

# Problem: this took too much memory (5+GB on a 120MB input data file)
# Input:
#   X and Y are numpy arrays,
#   X is dim by n
#   Y is 1 by n, each entry is {-1, +1}
#   lamb is regularization constant
#
# Output:
#   optimal hypothesis beta
#   value of its solution (optimal regularized error)
#def cvxpy_logistic_regression(X, Y, lamb):
#  n = len(Y)
#  d = X.shape[1]
#  beta = Variable(d)
#  # this version threw an error for me
#  #expr1 = sum([log_sum_exp(vstack(0, -Y[i] * np.dot(X[i, :], beta))) for i in range(n)])
#  expr1 = sum(logistic(X[i,:].T*beta*-Y[i]) for i in range(n))
#  expr1 = conv(1.0 / float(n), sum(expr1))
#  expr2 = square(norm(beta))
#  expr2 = conv(lamb, expr2)
#  expr_list = [expr1, expr2]
#  expr = sum(expr_list)
#  obj = Minimize(expr)
#
#  p = Problem(obj)
#  p.solve()
#
#  beta_arr = np.array([b[0,0] for b in beta])
#  return beta, p.value
#


""""
Function  : area_triangle_3d.py
Title     : Triangle area 3D
Written by: Alejandro Rios
Date      : November/2019
Last edit : August/2020
Language  : Python
Aeronautical Institute of Technology - Airbus Brazil

Description:
    - This module calculate the area triangle for applications in 3D surfaces area calculation

Future implementations:
    -

Inputs:
    - Triangle coordinates x, y, z
Outputs:
    - area
"""
########################################################################################
"""Importing Modules"""
########################################################################################
import numpy as np
########################################################################################
"""Function definition"""
########################################################################################

def area_triangle_3d(x,y,z):

    x1=x[0]
    x2=x[1]
    x3=x[2]
    #
    y1=y[0]
    y2=y[1]
    y3=y[2]
    #
    z1=z[0]
    z2=z[1]
    z3=z[2]
    #A=sqrt(s*(s-a)*(s-b)*(s-c))
    # Method  2
    # https://math.stackexchange.com/questions/128991/how-to-calculate-area-of-3d-triangle
    T1=(x2*y1 - x3*y1 - x1*y2 + x3*y2 + x1*y3 - x2*y3)**2
    T2=(x2*z1 - x3*z1 - x1*z2 + x3*z2 + x1*z3 - x2*z3)**2
    T3=(y2*z1 - y3*z1 - y1*z2 + y3*z2 + y1*z3 - y2*z3)**2
    area=(np.sqrt(T1+T2+T3)/2)
    return(area)


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

def grid_plot(data, size, title='Untitle', is_img=False):
    fig = plt.figure()
    fig.canvas.set_window_title(title)
    length = size**2
    graphs = []

    for i in range(1, length+1):
        temp_plt = fig.add_subplot(size, size, i)
        graphs.append(temp_plt)

    for i, d in enumerate(data):
        try:
            graphs[i].imshow(d, cmap=plt.cm.gray)
        except IndexError:
            break

# sigma = the standard deviation of the Gaussian function used in the Gabor filter.
# theta = the orientation of the normal to the parallel stripes of the Gabor function.
# lambda = the wavelength of the sinusoidal factor in the above equation.
# gamma = the spatial aspect ratio.
# psi = the phase offset.
# ktype = indicates the type and range of values that each pixel in the Gabor kernel can hold.

grid = []

for dx in np.arange(0.5, 5, 0.5):
    _usize = 9
    _ksize = (_usize, _usize)
    _sigma = 0 + dx
    _theta = 0
    _lambda = 4
    _gamma = 1.0
    _psi = 0
    _ktype = cv2.CV_32F

    gabor_k = cv2.getGaborKernel(
        _ksize, _sigma, _theta,
        _lambda, _gamma, _psi,
        _ktype
    )

    h, w = gabor_k.shape[:2]
    gabor_k_show = cv2.resize(gabor_k, (100*w, 100*h), interpolation=cv2.INTER_CUBIC)
    grid.append(gabor_k_show)

size = np.int(np.round(np.sqrt(len(grid))))
grid_plot(grid, size, title='Gabor Kernel', is_img=True)
plt.show()


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

from sklearn.datasets import load_iris

from sklearn.model_selection import train_test_split

from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.manifold import Isomap

iris_dataset = load_iris()

features = pd.DataFrame(iris_dataset.data)
features.columns = iris_dataset.feature_names
print(features.head())

labels = pd.DataFrame(iris_dataset.target)
print(labels.head())

print(features.info())
print(labels.info())

print("features size ", features.shape)
print("labels size ", labels.shape)

iris_data = iris_dataset.data
iris_labels = iris_dataset.target
# print(iris_dataset.data)

pca = PCA()
pca.fit(iris_data)
iris_data_transformed = pca.transform(iris_data)

print(pca.explained_variance_ratio_)

print(iris_data_transformed.mean(axis=0))

iris_attributes = iris_data_transformed[:, :2]

# print(iris_attributes)

lr_normal = LogisticRegression(C=1e5).fit(iris_data, iris_labels)
# lr_transofrmed = LogisticRegression(C=1e5).fit(iris_attributes, iris_labels)
lr_transofrmed = LogisticRegression(C=1e5).fit(
    iris_attributes[:, 0].reshape(-1, 1), iris_labels
)

print(lr_normal.score(iris_data, iris_labels))
# print(lr_transofrmed.score(iris_attributes, iris_labels))
print(lr_transofrmed.score(iris_attributes[:, 0].reshape(-1, 1), iris_labels))

isomap = Isomap(n_neighbors=10, n_components=2)
iris_data_isomap = isomap.fit_transform(iris_data)

plt.scatter(iris_data_isomap[:, 0], iris_data_isomap[:, 1], c=iris_labels)
plt.show()

plt.scatter(iris_data_transformed[:, 0], iris_data_transformed[:, 1], c=iris_labels)
plt.show()


import numpy as np

def sph2cart(lon, lat, radius):
    lon_rad = np.deg2rad(lon)
    lat_rad = np.deg2rad(lat)
    x = radius * np.cos(lat_rad) * np.cos(lon_rad)
    y = radius * np.cos(lat_rad) * np.sin(lon_rad)
    z = radius * np.sin(lat_rad)
    return x, y, z


import numpy as np
import scipy.stats as ss

def maxim(data):
	'''
	Calculates de maximum value in a list with nan values
	Inputs:
		- data: array-like.
	Outputs:
		- m: int, the maximun value in the array.
		- ind: the index of the maximum.
	'''
	m = 0
	ind = 0
	for i in range(len(data)):
		if not(np.isnan(data[i])) and data[i]>m:
			m = data[i]
			ind = i
	return m,ind

def thompson_tau(data,alpha = 0.05,threshold):
	# Information obtained from: https://www.statisticshowto.datasciencecentral.com/modified-thompson-tau-test/
	'''
	Implements the Thompson Tau method and returns a list with the outliers index.
	Inputs:
		- data: an array.
		- alpha: the significance level, default 0.05.
		- Threshold: the number of points tested.
	Outputs:
	 	- outliers: a list with the indices of the outliers.
	'''
	outliers = []
	n = len(data)
	mean = np.mean(data)
	delta = abs(data-mean)
	std = np.std(data)
	for i in range(threshold):
		d,ind = maxim(delta)
		reject = ss.t.ppf(alpha/2, n - 2)
		tau = (reject*(n - 1))/(np.sqrt(n)*np.sqrt(n - 2 + np.power(reject,2)))
		if d > tau*std:
			outliers += [ind]
		delta[ind] = None
	return outliers

# An example to test it
data = np.array([489, 490, 490, 491, 494, 499, 499, 500, 501, 505])
print(thompson_tau(data,0.05,10))


from __future__ import division
from scipy.stats import multivariate_normal
import scipy.stats as stats
import scipy.io as sio
import matplotlib.pyplot as plt
import numpy as np

def estimate_gaussian(X):
    mu = np.mean(X, axis=0)
    sigma2 = np.var(X, axis=0)
    return mu, sigma2

def select_threshold(y_val, p_val):
    best_epsilon, best_F1 = 0, 0

    step_size = (max(p_val) - min(p_val)) / 1000
    for epsilon in np.arange(p_val.min(), p_val.max(), step_size):
        predictions = (p_val < epsilon)[:, np.newaxis]
        tp = np.sum(predictions[y_val == 1] == 1)
        fp = np.sum(predictions[y_val == 0] == 1)
        fn = np.sum(predictions[y_val == 1] == 0)

        prec = tp / (tp + fp)
        rec = tp / (tp + fn)

        F1 = 2 * prec * rec / (prec + rec)

        if F1 > best_F1:
            best_epsilon = epsilon
            best_F1 = F1

    return best_epsilon, best_F1

def main():
    # 1
    file_path = 'ex8data1.mat'
    dataset = sio.loadmat(file_path)
    X = dataset["X"]
    Xval = dataset["Xval"]
    yval = dataset["yval"]

    # 2
    plt.scatter(X[:, 0], X[:, 1], marker="o", s=16)
    plt.xlim(0, 30)
    plt.ylim(0, 30)
    plt.xlabel("Latency (ms)")
    plt.ylabel("Throughput (mb/s)")
    plt.show()

    # 3
    mu, sigma2 = estimate_gaussian(X)

    # 4
    p = multivariate_normal(mu, np.diag(sigma2))
    print(mu, sigma2)

    # 5
    xs, ys = np.mgrid[0:30:0.1, 0:30:0.1]
    pos = np.empty(xs.shape + (2,))
    pos[:, :, 0] = xs
    pos[:, :, 1] = ys

    plt.figure(figsize=(8, 6))
    plt.plot(X.T[0], X.T[1], 'o', ms=4)
    plt.contour(xs, ys, p.pdf(pos), 10. ** np.arange(-21, -2, 3))
    plt.xlabel('Latency (ms)')
    plt.ylabel('Throughput (mb/s)')
    plt.xlim(0, 30)
    plt.ylim(0, 30)
    plt.show()

    # 6
    p_val = p.pdf(Xval)
    epsilon, F1 = select_threshold(yval, p_val)
    print("Best epsilon found using cross-validation:", epsilon)
    print("Best F1 on Cross Validation Set:", F1)

    # 7
    outliers = X[p.pdf(X) < epsilon]
    plt.figure(figsize=(8, 6))
    plt.plot(X.T[0], X.T[1], 'o', ms=4)
    plt.plot(outliers.T[0], outliers.T[1], 'o', ms=18, mfc='none', mec='r')
    plt.contour(xs, ys, p.pdf(pos), 10. ** np.arange(-21, -2, 3))
    plt.xlabel('Latency (ms)')
    plt.ylabel('Throughput (mb/s)')
    plt.xlim(0, 30)
    plt.ylim(0, 30)
    plt.show()

    # 8
    file_path = 'ex8data2.mat'
    dataset = sio.loadmat(file_path)
    X, Xval, yval = dataset['X'], dataset['Xval'], dataset['yval'][:, 0]

    # 9
    mu, sigma2 = estimate_gaussian(X)

    # 10
    p = multivariate_normal(mu, np.diag(sigma2))

    # 11
    p_val = p.pdf(Xval)
    epsilon, F1 = select_threshold(yval, p_val)
    print('Best epsilon found using cross-validation: %.2e' % epsilon)
    print('Best F1 on Cross Validation Set          : %f\n' % F1)
    print('  (you should see a value epsilon of about 1.38e-18)')
    print('  (you should see a Best F1 value of       0.615385)')

    # 12
    print('\n# Anomalies found: %d' % np.sum(p.pdf(X) < epsilon))

if __name__ == '__main__':
    main()


import numpy as np
from numpy.linalg import *
import time # for timing program
import sys # for printing to std out

dat = np.genfromtxt('../data/dat.txt',delimiter=' ')

y = dat[:,0]
X = dat[:,1:11]
K = X.shape[1]
n = y.shape[0]
Xt = X.transpose()
XXi = inv(np.dot(Xt,X))
b_mle = np.dot( np.dot(XXi, Xt), y )

a = 1
b = 1
B = 100000
s2 = 10

def ll(be, sig2):
    y_min_Xb = y - np.dot(X, be)
    return np.dot( y_min_Xb.transpose(), y_min_Xb) / (-2*sig2) - n/2 * np.log(sig2)

def lpb(be):
    return -np.dot( be.transpose(), np.dot(XXi, be) ) / (s2*2)

def lps(sig2):
    return (a-1) * np.log(sig2) - sig2 / b

def mvrnorm(M,S): # STOPPED HERE
    return M + np.dot( cholesky(S) , np.random.normal(0,1,M.shape[0]) )

#ll(b_mle, s2) # test
#lpb(b_mle) # test
#lps(s2) # test
mvrnorm(b_mle, np.eye(b_mle.shape[0]))

csb = 4 * XXi
css = 1
acc_b = 0
acc_s = 0

b_hat = np.zeros(shape=(B,K))
s2_hat = np.ones(B)

# Time this:
start = time.time()
for b in range(1,B):
    b_hat[b] = b_hat[b-1]
    s2_hat[b] = s2_hat[b-1]
    #
    # Update Beta:
    cand = mvrnorm(b_hat[b], csb)
    q = ( ll(cand, s2_hat[b]) + lpb(cand)
        - ll(b_hat[b], s2_hat[b]) - lpb(b_hat[b]) )
    if q > np.log( np.random.rand() ):
      b_hat[b] = cand
      acc_b += 1
    #
    # Update s2:
    cand = np.random.normal(s2_hat[b], css)
    if cand > 0:
      q = ( ll(b_hat[b], cand) + lps(cand)
          - ll(b_hat[b], s2_hat[b]) - lps(s2_hat[b]) )
      if q > np.log( np.random.rand() ):
        s2_hat[b] = cand
        acc_s += 1
    #
    if b%(B//10) == 0:
      print "\rProgress: %d%s" %(round(b*100/B),"%"),
      sys.stdout.flush()

end = time.time()

print "\n"
print "beta: ", b_hat[B*.9:B].mean(0)
print "s2:   ", s2_hat[B*.9:B].mean()

print "acc_b:", acc_b / B
print "acc_s:", acc_s / B

elapsed_time = end - start # 23 seconds
print "Time Elapsed: ", elapsed_time, "\n"


"""This module will use RANSAC to estimate the plane of a point cloud.

"""

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import time
import logging

from sklearn import linear_model

# Looks like this function needs to be compiled on first call or something similar.
# Below is a dummy calculation
# If I don't do this there is always a 23 ms overhead. Even with only 3 points!!
_, _, _, _ = np.linalg.lstsq(np.array([[0,0], [1, 0], [0, 1]]), np.array([0, 0, 0]), rcond=None)

def estimate_plane(pc:np.ndarray, stop_probability=0.95):
    """Will estimate a planes parameters using RANSAC

    Args:
        pc (np.ndarray): NX3 Point Cloud
        stop_probability (float, optional): sklearn.linear_model.See RANSACRegressor. Defaults to 0.95.

    Returns:
        tuple(ndarray, ndarray, RANSACRegressor): Returns a tuple of the centroid of the point cloud, unit normal, and the RANSAC object
    """
    x_train = pc[:, :2]
    y_train = pc[:, 2]
    ransac = linear_model.RANSACRegressor(linear_model.LinearRegression(), stop_probability=stop_probability)

    t0 = time.perf_counter()
    ransac.fit(x_train, y_train)
    t1 = time.perf_counter()
    ms  = (t1 - t0) * 1000

    logging.debug(f"Took {ms:.1f} ms to compute RANSAC for {pc.shape[0]:} points. # Trials: {ransac.n_trials_:}")

    z = lambda x,y: (ransac.estimator_.intercept_ + ransac.estimator_.coef_[0]*x + ransac.estimator_.coef_[1]*y)

    point_on_plane_0 = np.array([0, 0, z(0,0)])
    point_on_plane_1 = np.array([1, 0, z(1,0)])
    point_on_plane_2 = np.array([0, 1, z(0,1)])

    vec_a = point_on_plane_1 - point_on_plane_0
    vec_b = point_on_plane_2 - point_on_plane_0

    normal = np.cross(vec_a, vec_b)
    normal = normal / np.linalg.norm(normal, axis=0)
    centroid = np.mean(pc, axis=0)

    logging.debug("Normal: %r; Centroid: %r", normal, centroid)
    return normal, centroid, ransac

def plot_pc(pc, ax):
    normal, centroid, ransac = estimate_plane(pc)
    ax.plot3D(pc[:,0], pc[:,1], pc[:,2], 'or')
    ax.quiver(centroid[0], centroid[1], centroid[2], normal[0], normal[1], normal[2], length=2.0)

def test_wheelchair():
    pc_1 = np.load("scratch/plane_0_0.npy")
    pc_2 = np.load("scratch/plane_0_1.npy")
    pc_3 = np.load("scratch/plane_0_2.npy")

    fig = plt.figure()
    ax  = fig.add_subplot(111, projection='3d')

    plot_pc(pc_1, ax)
    plot_pc(pc_2, ax)
    plot_pc(pc_3, ax)

    ax.set_xlabel("X")
    ax.set_ylabel("Y")
    ax.set_xlim([-2, 2])
    ax.set_ylim([-2, 2])
    ax.set_zlim([-2, 2])
    ax.view_init(-7,-68)
    plt.show()

def main():
    np.random.seed(1)
    slope_x = 0.5
    slope_y = 0.5
    intercept= 1.0
    noise = 0.5

    NUM_POINTS = 10

    X, Y = np.mgrid[0:NUM_POINTS, 0:NUM_POINTS]
    PC = np.column_stack((X.ravel(), Y.ravel()))

    Z = []
    for i in range(PC.shape[0]):
        Z.append(slope_x * PC[i,0] + slope_y * PC[i, 1] + intercept)
    Z = np.array(Z) + np.random.randn(PC.shape[0]) * noise

    PC = np.column_stack((PC[:,0], PC[:, 1], Z))

    normal, centroid, ransac = estimate_plane(PC)

    # # the plane equation
    z = lambda x,y: (ransac.estimator_.intercept_ + ransac.estimator_.coef_[0]*x + ransac.estimator_.coef_[1]*y)
    x,y = np.mgrid[0:NUM_POINTS,0:NUM_POINTS]

    fig = plt.figure()
    ax  = fig.add_subplot(111, projection='3d')
    ax.plot3D(PC[:,0], PC[:,1], PC[:,2], 'or')

    ax.plot_surface(x, y, z(x,y))
    ax.quiver(centroid[0], centroid[1], centroid[2], normal[0], normal[1], normal[2], length=2.0)

    ax.set_xlabel("X")
    ax.set_ylabel("Y")
    ax.set_xlim([0, NUM_POINTS])
    ax.set_ylim([0, NUM_POINTS])
    ax.set_zlim([0, NUM_POINTS])
    ax.view_init(-7,-68)
    plt.show()

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    # test_wheelchair()
    main()


import numpy as np
import pandas as pd
from sklearn.metrics.pairwise import euclidean_distances

def assign_clusters(samples, centroids):
    distances = euclidean_distances(samples, centroids)
    return pd.DataFrame(distances).idxmin(axis="columns")

def cost(samples, clusters, centroids):
    centroids_for_samples = centroids.iloc[clusters]
    centroids_for_samples.reset_index(drop=True, inplace=True)
    norms = np.linalg.norm(samples - centroids_for_samples, axis=1) ** 2
    return 1 / len(clusters) * norms.sum()

def get_centroids(samples, k):
    return samples.sample(k)

def kmeans(samples, k):
    centroids = get_centroids(samples, k)
    while True:
        clusters = assign_clusters(samples, centroids)
        yield clusters, centroids
        new_centroids = move_centroids(samples, clusters)
        if np.equal(centroids, new_centroids).all().all():
            break
        centroids = new_centroids

def kmeans_multi(samples, k, n):
    best_cost = float("inf")
    best_results = None
    for _ in range(n):
        results = list(kmeans(samples, k))
        clusters, centroids = results[-1]
        current_cost = cost(samples, clusters, centroids)
        if current_cost < best_cost:
            best_cost = current_cost
            best_results = results
    return best_results

def mass_center(cluster):
    return cluster.mean()

def move_centroids(samples, clusters):
    k = clusters.max() + 1
    result = []
    for i in range(k):
        index = clusters[clusters == i].index
        cluster = samples.iloc[index]
        result.append(mass_center(cluster))
    return pd.DataFrame(result)


import argparse
import json
import numpy as np

def build_arg_parser():
    parser = argparse.ArgumentParser(description='Compute similarity score')
    parser.add_argument('--user1', dest='user1', required=True,
            help='First user')
    parser.add_argument('--user2', dest='user2', required=True,
            help='Second user')
    parser.add_argument("--score-type", dest="score_type", required=True,
            choices=['Euclidean', 'Pearson'], help='Similarity metric to be used')
    return parser

# Compute the Euclidean distance score between user1 and user2
def euclidean_score(dataset, user1, user2):
    if user1 not in dataset:
        raise TypeError('Cannot find ' + user1 + ' in the dataset')

    if user2 not in dataset:
        raise TypeError('Cannot find ' + user2 + ' in the dataset')

    # Movies rated by both user1 and user2
    common_movies = {}

    for item in dataset[user1]:
        if item in dataset[user2]:
            common_movies[item] = 1

    # If there are no common movies between the users,
    # then the score is 0
    if len(common_movies) == 0:
        return 0

    squared_diff = []

    for item in dataset[user1]:
        if item in dataset[user2]:
            squared_diff.append(np.square(dataset[user1][item] - dataset[user2][item]))

    return 1 / (1 + np.sqrt(np.sum(squared_diff)))

# Compute the Pearson correlation score between user1 and user2
def pearson_score(dataset, user1, user2):
    if user1 not in dataset:
        raise TypeError('Cannot find ' + user1 + ' in the dataset')

    if user2 not in dataset:
        raise TypeError('Cannot find ' + user2 + ' in the dataset')

    # Movies rated by both user1 and user2
    common_movies = {}

    for item in dataset[user1]:
        if item in dataset[user2]:
            common_movies[item] = 1

    num_ratings = len(common_movies)

    # If there are no common movies between user1 and user2, then the score is 0
    if num_ratings == 0:
        return 0

    # Calculate the sum of ratings of all the common movies
    user1_sum = np.sum([dataset[user1][item] for item in common_movies])
    user2_sum = np.sum([dataset[user2][item] for item in common_movies])

    # Calculate the sum of squares of ratings of all the common movies
    user1_squared_sum = np.sum([np.square(dataset[user1][item]) for item in common_movies])
    user2_squared_sum = np.sum([np.square(dataset[user2][item]) for item in common_movies])

    # Calculate the sum of products of the ratings of the common movies
    sum_of_products = np.sum([dataset[user1][item] * dataset[user2][item] for item in common_movies])

    # Calculate the Pearson correlation score
    Sxy = sum_of_products - (user1_sum * user2_sum / num_ratings)
    Sxx = user1_squared_sum - np.square(user1_sum) / num_ratings
    Syy = user2_squared_sum - np.square(user2_sum) / num_ratings

    if Sxx * Syy == 0:
        return 0

    return Sxy / np.sqrt(Sxx * Syy)

if __name__=='__main__':
    args = build_arg_parser().parse_args()
    user1 = args.user1
    user2 = args.user2
    score_type = args.score_type

    ratings_file = 'ratings.json'

    with open(ratings_file, 'r') as f:
        data = json.loads(f.read())

    if score_type == 'Euclidean':
        print("\nEuclidean score:")
        print(euclidean_score(data, user1, user2))
    else:
        print("\nPearson score:")
        print(pearson_score(data, user1, user2))


import numpy as np

def create_search_space(size, dim):
    _dict_ = {}
    for i in range(dim):
        _dict_[str(i)] = size

    return _dict_

def sphere_function(para, X, y):
    loss = []
    for key in para.keys():
        if key == "iteration":
            continue
        loss.append(para[key] * para[key])

    return -np.array(loss).sum()

def rastrigin_function(para, X, y):
    loss = []
    for key in para.keys():
        if key == "iteration":
            continue

        loss_1d = 1 + para[key] * para[key] - np.cos(2 * np.pi * para[key])
        loss.append(loss_1d)

    return -(np.array(loss).sum())

def ackley_function(para, X, y):
    x, y = para["x"], para["y"]

    loss = -20 * np.exp(-0.2 * np.sqrt(0.5 * (x * x + y * y))) - np.exp(
        0.5 * (np.cos(2 * np.pi * x) + np.cos(2 * np.pi * y)) + np.exp(1) + 20
    )

    return -loss

def rosenbrock_function(para, X, y):
    x = np.array([para["x1"], para["x2"], para["x3"], para["x4"]])
    y = np.array([para["x0"], para["x1"], para["x2"], para["x3"]])

    loss = sum(100.0 * (x - y ** 2.0) ** 2.0 + (1 - y) ** 2.0)

    return -loss

def himmelblau_function(para, X, y):
    loss = (para["x"] ** 2 + para["y"] - 11) ** 2 + (
        para["x"] + para["y"] ** 2 - 7
    ) ** 2

    return -loss

dim_size = np.arange(-10, 10, 0.03)

sphere_function_search_config_3 = {sphere_function: create_search_space(dim_size, 3)}

rastrigin_function_search_config_3 = {
    rastrigin_function: create_search_space(dim_size, 3)
}

sphere_function_search_config_5 = {sphere_function: create_search_space(dim_size, 5)}

rastrigin_function_search_config_5 = {
    rastrigin_function: create_search_space(dim_size, 5)
}

sphere_function_search_config_7 = {sphere_function: create_search_space(dim_size, 7)}

rastrigin_function_search_config_7 = {
    rastrigin_function: create_search_space(dim_size, 7)
}

sphere_function_search_config_9 = {sphere_function: create_search_space(dim_size, 9)}

rastrigin_function_search_config_9 = {
    rastrigin_function: create_search_space(dim_size, 9)
}

ackley_function_search_config = {ackley_function: {"x": dim_size, "y": dim_size}}

rosenbrock_function_search_config = {
    rosenbrock_function: {
        "x0": dim_size,
        "x1": dim_size,
        "x2": dim_size,
        "x3": dim_size,
        "x4": dim_size,
    }
}

himmelblau_function_search_config = {
    himmelblau_function: {"x": dim_size, "y": dim_size}
}

test_func_search_configs = [
    sphere_function_search_config_3,
    rastrigin_function_search_config_3,
    sphere_function_search_config_5,
    rastrigin_function_search_config_5,
    sphere_function_search_config_7,
    rastrigin_function_search_config_7,
    sphere_function_search_config_9,
    rastrigin_function_search_config_9,
    ackley_function_search_config,
    rosenbrock_function_search_config,
    himmelblau_function_search_config,
]


import numpy as np
#Gauss Seidel iteration method
#this program is Write By Endurance ogun and is part of the Sfip program
#CopyRight:: can be use for any of your project but one should not delete this comment or claim ownship of the program.

def G_S(A,B):
    t=float(input("the toll::"))
    L = np.tril(A)
    U = A - L
    L_inv = np.linalg.inv(L)
    x = np.zeros_like(B)
    N = 1
    M = 0
    j=0
    while True:
        for i in range(N):
            j=j+1
            print("Iteration::" + str(j))
            Ux = np.dot(U, x)
            x_new = np.dot(L_inv, B - Ux)
            M = np.allclose(x, x_new, t)
           # if np.allclose(x, x_new, t):
            #    break
            x = x_new
            print(x)

        if M:
            break
        N = N + 1

def get_matrixA(m_len,variable_type=float):
    A=[]
    for i in range(1,m_len+1):
        for j in range(1,m_len+1):
            m_col_row= float(input("enter value for \n a"+str(i)+str(j)+"::"))
            A.append(m_col_row)

    A=np.array(A).reshape(m_len,m_len)

    print(A)
    return A

def get_matrixB(m_len, variable_type=float):
    B = []
    for h in range(1, m_len + 1):
        m_col = float((input("enter value for  \n b" + str(h) + "::")))
        B.append(m_col)

    B = np.array(B).reshape(m_len, 1)
    print(B)
    return B

def get_solution():
    N=int(input("dimension of Matrix:"))
    A=get_matrixA(N)
    B=get_matrixB(N)
    G_S(A,B)

get_solution()


import numpy as np

class LogisticRegression(object):
    '''
    Logistic regression python code.
    '''
    def __init__(self,trainingData, trainingCategory, cycleMax, stepSize):
        '''
        :param trainingData: input x matrix(N*M) in list.
        :param trainingCategory: input y vector (M*1) in list.
        :param cycleMax: the num of LR iteration times.
        :param stepSize: iteraion step length <<1.
        '''
        self.trainingData = trainingData
        self.trainingCategory = trainingCategory
        self.cycleMax = cycleMax
        self.stepSize = stepSize

    def buildMatrix(self):
        catVec = np.array(self.trainingCategory).reshape(len(self.trainingCategory),1)
        trainMat = self.trainingData.copy()
        for i in range(len(trainMat)):
            trainMat[i].append(1)

        return np.array(trainMat), catVec

    def Sigmoid(self, xMat, thetaVec):
        res = np.zeros(xMat.shape[0], dtype=np.float128)
        for i in range(xMat.shape[0]):
            res[i] = np.dot(xMat[i,:],thetaVec)

        res_0 = 1/(1+np.exp(-res))
        return res_0

    def iteration(self, trainingMat, catVec):
        xMat = trainingMat.copy()
        thetaVec = np.ones(len(self.trainingData[0]))
        for c in range(self.cycleMax):
            print(np.round(100*c/self.cycleMax,2),'%',end='\r')
            E = self.Sigmoid(xMat, thetaVec)
            E = E.reshape(len(self.trainingCategory),1)
            delta = self.stepSize/xMat.shape[0] * (E-catVec)
            delta = np.dot(np.transpose(delta),xMat)
            # print('delta:',delta.shape)
            thetaVec -= delta.reshape(len(xMat[0]))
        return thetaVec

    def run(self):
        trainMat, catVec = self.buildMatrix()
        theta_solu = self.iteration(trainMat, catVec)
        return theta_solu

    def plotResult(self, theta_solu):
        return

# if __name__ == "__main__":


import numpy as np

def calculate_power(v, i):
    p = 1.5 * (v.alpha * i.alpha + v.beta * i.beta)
    q = 1.5 * (v.beta * i.alpha - v.alpha * i.beta)
    return p, q

def calculate_current(v, p, q):
    i_alpha = 2 * (p * v.alpha + q * v.beta) / (v.alpha ** 2 + v.beta ** 2) / 3
    i_beta = 2 * (p * v.beta - q * v.alpha) / (v.alpha ** 2 + v.beta ** 2) / 3
    return i_alpha, i_beta

def angle_diff(theta1, theta2, deg=False):
    delta = theta1 - theta2
    if deg:
        try:
            delta = [-360. + d if d > 180. else d for d in delta]
            delta = [360. + d if d <= -180. else d for d in delta]
        except TypeError:
            if delta > 180:
                delta = -360. + delta
            if delta <= -180:
                delta = 360. + delta
    else:
        try:
            delta = [-2*np.pi + d if d > np.pi else d for d in delta]
            delta = [2*np.pi + d if d <= np.pi else d for d in delta]
        except TypeError:
            if delta > np.pi:
                delta = -(2 * np.pi) + delta
            if delta <= -np.pi:
                delta = (2 * np.pi) + delta
    return delta

def power_flow_2_bus(v1, theta1, v2, theta2, g, b):
    """ Calculate the power flow from bus 1 to bus 2 across the line with admittance g+jb
        from the given voltages and angles.
    """
    p = 0
    q = 0

    # Build admittance matrix values
    g12, b12 = -g, -b
    g11, b11 = g, b

    p += v1 * v2 * (g12 * np.cos(theta1 - theta2) + b12 * np.sin(theta1 - theta2))
    q += v1 * v2 * (g12 * np.sin(theta1 - theta2) - b12 * np.cos(theta1 - theta2))

    p += v1 * v1 *   g11
    q += v1 * v1 * - b11
    return p, q

if __name__ == "__main__":
    from numpy import testing
    # Test power flow equations with purely reactive line
    p1, q1 = power_flow_2_bus(1, 0, 0.9458, -0.0529, 0, -10)
    p2, q2 = power_flow_2_bus(0.9458, -0.0529, 1, 0, 0, -10)
    testing.assert_allclose([p1, q1], [0.5, 0.55], atol=1e-2)
    testing.assert_allclose([p2, q2], [-0.5, -0.5], atol=1e-2)
    print("p1, q1: ", p1, q1)
    print("p2, q2: ", p2, q2)


import numpy as np
import matplotlib.pyplot as plt
import gd
from builtins import range

if __name__ == "__main__":

    def f(xx):
        x = xx[0]
        y = xx[1]
        return 5 * x ** 2 - 6 * x * y + 3 * y ** 2 + 6 * x - 6 * y

    def df(xx):
        x = xx[0]
        y = xx[1]
        return np.array([10 * x - 6 * y + 6, -6 * x + 6 * y - 6])

    xmin, xmax, ymin, ymax = -3, 3, -3, 3
    algos = []
    initial = np.array([1, 1])
    alphas = [0.1, 0.2]
    for alpha in alphas:
        algo = gd.GradiantDecent(f, df, alpha)
        algo.solve(initial)
        algos.append(algo)

    xs = np.linspace(-2, 2, 300)
    ys = np.linspace(-2, 2, 300)
    xmesh, ymesh = np.meshgrid(xs, ys)
    xx = np.r_[xmesh.reshape(1, -1), ymesh.reshape(1, -1)]
    flg, ax = plt.subplots(1, 2)
    levels = [-3, -2.9, -2.8, -2.6, -2.4, -2.2, -2, -1, 0, 1, 2, 3, 4]
    for i in range(2):
        ax[i].set_xlim((xmin, xmax))
        ax[i].set_ylim((ymin, ymax))
        ax[i].set_title("alpha={}".format(alphas[i]))
        ax[i].scatter(initial[0], initial[1], color="k", marker="o")
        ax[i].plot(algos[i].path_[:, 0], algos[i].path_[:, 1], color="k", linewidth=1.5)
        ax[i].contour(xs, ys, f(xx).reshape(xmesh.shape), levels=levels, colors="k", linestyles="dotted")
    plt.show()


"""
This module contains helper functions for transforming variables
"""

import os
import sys
import inspect
import csv
import json
from math import cos, sin, acos, asin, atan, pi, sqrt
import matplotlib.pyplot as plt
import numpy as np
from pprint import pprint

def metres_to_inches(measure_metres, measure_is_list=False):
    """converts measurements from metres to inches"""
    if measure_is_list:
        measure_inches = []
        for measurement in measure_metres:
            measure_inches.append(measurement / 0.0254)
    else:
        measure_inches = measure_metres / 0.0254
    return measure_inches

def inches_to_metres(measure_inches, measure_is_list=False):
    """converts measurements from inches to metres"""
    if measure_is_list:
        measure_metres = []
        for measurement in measure_inches:
            measure_metres.append(measurement * 0.0254)
    else:
        measure_metres = measure_inches * 0.0254
    return measure_metres

def get_quat_angles(quat):
    """gets the euler angles from the quaternions"""
    q0 = quat[0]
    q1 = quat[1]
    q2 = quat[2]
    q3 = quat[3]
    phi = atan(
        ((2*((q0*q1) + (q2*q3))) /
         (1 - 2*(q1**2 + q2**2)))
    )
    theta = asin(
        2*((q0*q2) - (q3*q1))
    )
    psi = atan(
        ((2*((q0*q3) + (q1*q2))) /
         (1 - 2*(q2**2 + q3**2)))
    )
    return phi, theta, psi

def get_dcm_angle(dcm):
    """gets the theta from the given matrix"""
    theta = 0
    cos_theta = dcm[0, 0]
    sin_theta = dcm[1, 0]
    if (cos_theta > 0) and (sin_theta > 0):
        theta = acos(cos_theta)
    elif (cos_theta < 0) and (sin_theta > 0):
        theta = acos(cos_theta)
    elif (cos_theta > 0) and (sin_theta < 0):
        theta = asin(sin_theta)
    else:
        theta = asin(sin_theta)
    return theta

def rotation_2d(theta_value):
    """gives the rotational matrix for a given angle"""
    cos_theta = np.cos(theta_value)
    sin_theta = np.sin(theta_value)
    rot_mat = np.matrix([[cos_theta, -sin_theta], [sin_theta, cos_theta]])
    return rot_mat

def odom_offset(x_values, y_values, initial_positions):
    """offsets the odometry values based on initial positions"""
    total_values = len(x_values)
    count = 0
    new_x = [None] * total_values
    new_y = [None] * total_values

    while count < total_values:
        new_x[count] = x_values[count] + initial_positions[0]
        new_y[count] = y_values[count] + initial_positions[1]
        count += 1

    return new_x, new_y

def polar_to_cartesian(polar_values, two_dim=True):
    """Converts 2d polar coordinates to 2d cartesian coordinates"""
    cartesian_values = polar_values
    if two_dim:
        cartesian_values[0] = polar_values[0] * cos(polar_values[1])
        cartesian_values[1] = polar_values[0] * sin(polar_values[1])
    return cartesian_values

def cartesian_to_polar(cartesian_values, two_dim=True):
    """Converts 2d cartesian coordinates to 2d polar coordinates"""
    polar_values = cartesian_values
    if two_dim:
        polar_values[0] = sqrt(cartesian_values[0]**2 + cartesian_values[1]**2)
        polar_values[1] = atan(cartesian_values[1]/cartesian_values[0])
    return polar_values


from scipy.integrate import odeint

import matplotlib.pyplot as plt
import numpy as np

def suscetibles_derivative(compartments, beta, gamma):
    S, I, R = compartments
    return -beta * S * I

def infected_derivative(compartments, beta, gamma):
    S, I, R = compartments
    return beta * S * I - gamma * I

def recovered_derivative(compartments, beta, gamma):
    S, I, R = compartments
    return gamma * I

def compartments_derivative(compartments, beta, gamma):
    dSdt = suscetibles_derivative(compartments, beta, gamma)
    dIdt = infected_derivative(compartments, beta, gamma)
    dRdt = recovered_derivative(compartments, beta, gamma)
    return dSdt, dIdt, dRdt

def simulate_sir_epidemics(infected_people_per_day, infection_duration, days_of_simulation, initial_state):
    beta = infected_people_per_day
    gamma = 1.0 / infection_duration

    t = np.linspace(0, days_of_simulation - 1, days_of_simulation)

    # solve ODEs
    derivative = lambda compartments, t, beta, gamma: compartments_derivative(compartments, beta, gamma)

    ret = odeint(derivative, initial_state, t, args=(beta, gamma))
    S, I, R = ret.T # arrays with compartment variation through days

    return t, S, I, R

def plot_sir(t, S, I, R, time_label='days'):
  f, ax = plt.subplots(1,1,figsize=(10,4))
  ax.plot(t, S, 'b', alpha=0.7, linewidth=2, label='Susceptible')
  ax.plot(t, I, 'y', alpha=0.7, linewidth=2, label='Infected')
  ax.plot(t, R, 'g', alpha=0.7, linewidth=2, label='Recovered')

  ax.set_xlabel(f"Time ({time_label})", labelpad=10)
  ax.set_ylabel('Population (%)', labelpad=10)

  ax.yaxis.set_tick_params(length=0)
  ax.xaxis.set_tick_params(length=0)

  ax.grid(b=True, which='major', c='w', lw=2, ls='-')

  legend = ax.legend()
  legend.get_frame().set_alpha(0.5)

  for spine in ('top', 'right', 'bottom', 'left'):
      ax.spines[spine].set_visible(False)

  plt.show()