import numpy as np
from Graphs import *

def primeFactors(n):
    if n == 1:
        return 0
    factors = 0
    d = 2
    while(n > 1):
        while(n % d == 0):
            factors += 1
            n //= d
        d = d + 1
        if(d*d > n):
            if(n > 1):
                factors += 1
            break
    return factors

def HaaseDivisibility(L,title=None,H=None,sc=.4,ptsz=.05,
                  drawConnections=True):

    L = sorted(L)

    numfacts = [primeFactors(i) for i in L]
    m = max(numfacts)
    lvls = [list() for i in range(m+1)]

    for i in L:
        n = primeFactors(i)
        lvls[n].append(i)

    G = Graph(rdef=ptsz,tscaledef=5)
    fig,ax = makeCanvas([-.4,1.4],[-.1,sc*len(lvls)],[12,12])

    y = 0
    ## We'll use these to store some information about the previous level
    XYold = []
    XYnew = []
    XYout = []
    for f in lvls:
        ## The XY positions of the previous level are now old
        ## We also reset the XY positions for this level to be blank so we can
        ## start fillign them in.
        XYold = XYnew
        XYnew = []
        ## Place the text on top of a circle. If the point is a factor of the
        ## subgraph make it salmon colored. Otherwise light blue.
        ## Also take note of the current position.
        x = np.linspace(0,1,len(f))
        if len(f) == 1:
            x = [.5]
        for l in range(len(f)):

            if H != None and H % f[l] == 0:
                G.addNode([x[l],y],text=f[l],col='#FF91A4')
            else:
                G.addNode([x[l],y],text=f[l])
            XYnew.append((f[l],x[l],y))
            XYout.append((x[l],y))

        ## Check if any of the current numbers are divisible by the ones in the
        ## level before. If they are draw a connecting line.
        ## Then also check if both numbers are factors of the subgraph. If they
        ## are then make the line red, otherwise make it gray. Gray lines are
        ## drawn beneath the red lines and are slightly thinner.
        if drawConnections == True:
            for val,xpos,ypos in XYnew:
                for valOLD,xposOLD,yposOLD in XYold:
                    if val % valOLD == 0:
                        if H != None and H % val == 0 and H % valOLD == 0:
                            connect([xpos,ypos],[xposOLD,yposOLD],width=2,col='red')
                        else:
                            connect([xpos,ypos],[xposOLD,yposOLD],width=2)

        y += sc
    G.QuickDraw(fig,ax)
    G.drawText(fig,ax)
    if title != None:
        plt.savefig(title,dpi=100)
    print(lvls)
    #print(XYout)
    return XYout

HaaseDivisibility([1,2,3,4,5,6,9,10,12,15,18,20,30,60],H=18,ptsz=.1)


import numpy as np

def medstddev(data, mask=None, medi=False, axis=0):
    """Compute the stddev with respect to the median.

    This is rather than the standard method of using the mean.

    Parameters:
    -----------
    data:   ndarray
        An array from which to caculate the median standard deviation.
    mask:   1D ndarray
        Mask indicating the good values (ones) and bad values (zeros).
        Same shape as data.
    medi:   boolean, optional
        If True return a tuple with (stddev, median) of data.
    axis:   int
        The axis along wich the median std deviation is calculated.

    Notes:
    ------
    MEANSTDDEV calculates the median, subtracts it from each value of
    X, then uses this residual to calculate the standard deviation.

    The numerically-stable method for calculating the variance from
    moment.pro doesn't work for the median standard deviation.  It
    only works for the mean, because by definition the residuals from
    the mean add to zero.

    Example:
    --------
    >>> import medstdev as m
    >>> a  = np.array([1,3,4,5,6,7,7])
    >>> std, med = m.medstddev(a, medi=True)
    >>> print(median(a))
    5.0
    >>> print(med)
    5.0
    >>> print(std)
    2.2360679775

    >>> # use masks
    >>> a    = np.array([1,3,4,5,6,7,7])
    >>> mask = np.array([1,1,1,0,0,0,0])
    >>> std, med = m.medstddev(a, mask, medi=True)
    >>> print(std)
    1.58113883008
    >>> print(med)
    3.0

    >>> # automatically mask invalid values
    >>> a = np.array([np.nan, 1, 4, np.inf, 6])
    >>> std, med = m.medstddev(a, medi=True)
    >>> print(std, med)
    (2.5495097567963922, 4.0)

    >>> # critical cases:
    >>> # only one value, return std = 0.0
    >>> a    = np.array([1, 4, 6])
    >>> mask = np.array([0, 0, 1])
    >>> std, med = m.medstddev(a, mask, medi=True)
    >>> print(std, med)
    (0.0, 6.0)

    >>> # no good values, return std = nan, med = nan
    >>> mask[-1] = 0
    >>> std, med = m.medstddev(a, mask, medi=True)
    >>> print(std, med)
    (nan, nan)

    Modification history:
    ---------------------
    2005-01-18  statia
        Written by Statia Luszcz.
    2005-01-19  statia
        Updated variance calculation according to algorithm in moment.pro,
        added medi keyword.
    2005-01-20  Joe Harrington, Cornell, jh@oobleck.astro.cornell.edu
        Header update.  Removed algorithm from moment.pro because it
        doesn't work for the median.  Added /double.
    2010-11-05  patricio  pcubillos@fulbrightmail.org
        Converted to python, documented.
    2022-04-11  Taylor James Bell
        Efficiently using numpy axes
    """
    # mask invalid values:
    data = np.ma.masked_invalid(data)
    if mask is not None:
        data = np.ma.masked_where(~mask.astype(bool), data)
    # number of good values:
    ngood = np.sum(~np.ma.getmaskarray(data), axis=axis)

    # calculate median of good values:
    median = np.ma.median(data, axis=axis)
    # residuals is data - median, masked values don't count:
    residuals = data - median
    # calculate standar deviation:
    std = np.array(np.ma.sqrt(np.ma.sum(residuals**2.0) / (ngood - 1.0)))

    # Convert masked arrays to just arrays
    std = np.array(std)
    median = np.array(median)
    if std.shape == ():
        # If just a single value, make sure using a shaped array
        std = std.reshape(-1)
        median = median.reshape(-1)

    # critical case fixes:
    if np.any(ngood == 0):
        std[np.where(ngood == 0)[0]] = np.nan
        median[np.where(ngood == 0)[0]] = np.nan
    if np.any(ngood == 1):
        std[np.where(ngood == 1)[0]] = 0.

    if len(std) == 1:
        std = std[0]
        median = median[0]

    # return statement:
    if medi:
        return (std, median)
    return std


#!/usr/bin/python2
import sympy as sp
import os
import subprocess
from implementations import *
from matplotlib import pyplot as plt
from sympy import Point2D

def getFunction():
    while True:
        string = ''
        try:
            string = raw_input("Type in the f(t,y) function: ")  # get expression as string
            expr = sp.sympify(string)  # turn string expression into Sympy expression
            break
        except:
            print "Please try again, invalid input: ", string
    return expr

def getPoint(k):
    if k is None:  # in case the user doesn't want to specify which point they're getting
        k = ''
    while True:
        try:
            t = input("Type in t{0}: ".format(k))  # get k-th t as a number
            break
        except:
            print "Please try again, invalid input"

    while True:
        try:
            y = input("Type in y{0}: ".format(k))  # get k-th y as a number
            break
        except:
            print "Please try again, invalid input"

    return t, y

def getNandH():
    h = input("Type in the step h: ")  # gets h as number
    n = input("Type in the number of iterations n: ")  # gets h as number

    return h, n

"""
    Gets order of Adams-Moulton and Adams-Bashforth methods
"""
def getOrder():

        order = 1
        while True:
                try:
                    order = int(input("\nPlease input the degree of the method: "))
                    if order > 0:
                        break
                    else:
                        print "Degree must be greater than 0."
                except:
                    print "Please try again, invalid input."
        return order

def plot(mts, mys, labels, title):
    """
        mts = Array of arrays of t coordinates
        mys = Array of arrays of y coordinates
        labels = labels for each function. (i.e. points mts[0], mys[0] have the label labels[0])
        title = plot titlte
    """
    for i in range(len(mts)):
        plt.plot(mts[i], mys[i], label=labels[i])

    plt.xlabel('t')
    plt.ylabel('y(t)')
    plt.title(title)

    plt.ticklabel_format(style='plain')              # disables scientific notation
    plt.legend(loc='best')                          # puts legend in the best place
    plt.show()

def runSimpleMethod(method, name):
    f = getFunction()

    t, y = getPoint(0)

    h, n = getNandH()

    ts, ys = method(f, t, y, h, n)

    plot([ts], [ys], [''], name)

    print "\nHave a great day!"

    return ts, ys

def runAllEulers():

    f = getFunction()

    t, y = getPoint(0)

    h, n = getNandH()

    ts1, ys1 = eulers.simple_euler(f, t, y, h, n)
    ts2, ys2 = eulers.improved_euler(f, t, y, h, n)
    ts3, ys3 = eulers.inverse_euler(f, t, y, h, n)

    #plot config
    plt.plot(ts1, ys1, label='Simple Euler')
    plt.plot(ts2, ys2, label='Improved Euler')
    plt.plot(ts3, ys3, label='Inverse Euler')
    plt.xlabel('t')
    plt.ylabel('y')
    plt.title("All Euler Methods")

    plt.legend(loc='best')
    plt.ticklabel_format(style='plain')              # disables scientific notation
    plt.show()

    print "\nHave a great day!"

    return

def runAdamsBash(order):
    name = "Adams-Bashforth Method"
    f = getFunction()

    p = []
    for i in range(order):
        p.insert(0,Point2D(getPoint(i)))

    h, n = getNandH()

    points, ts, ys = adams_bashforth.method(f, p, h, n, order)

    plot([ts], [ys], [''], name)

    return ts, ys

def runAdamsMoulton(order):
    name = "Adams-Moulton Method"
    f = getFunction()
    p = []

    print '\nObs: Adams-Moulton of order k needs only k-1 points\n'

    if order == 1: order = 2                #makes sure at least one point is asked for
    for i in range(order - 1):
        p.insert(0,Point2D(getPoint(i)))

    h, n = getNandH()

    points, ts, ys = adams_moulton.method(f, p, h, n, order)

    plot([ts], [ys], [''], name)

    return ts, ys

def runAllMethods(order):
    f = getFunction()

    t, y = getPoint(0)

    h, n = getNandH()

    p = []          # array of points for adams methods

    ts1, ys1 = eulers.simple_euler(f, t, y, h, n)
    ts2, ys2 = eulers.improved_euler(f, t, y, h, n)
    ts3, ys3 = eulers.inverse_euler(f, t, y, h, n)
    ts4, ys4 = runge.method(f, t, y, h, n)

    if order == 1: order = 2                # makes sure at least one point is put into the p array
    for i in range(order):
        p.insert(0,Point2D(ts4[i], ys4[i])) # takes point generated from runge kutta method
        n = n - 1

    points, ts5, ys5 = adams_bashforth.method(f, p, h, n + 1, order)
    # p = []      #reset p
    # for i in range(order):
    #     p.insert(0,Point2D(ts4[i], ys4[i])) # takes point generated from runge kutta method
    p.pop()                                 # adams moulton takes order - 1 points to run
    points, ts6, ys6 = adams_moulton.method(f, p, h, n + 1, order)

    # 'points' is not necessary...

    #plot config
    plot(
        [ts1, ts2, ts3, ts4, ts5, ts6],
        [ys1, ys2, ys3, ys4, ys5, ys6],
        ['Simple Euler', 'Improved Euler', 'Inverse Euler', 'Runge-Kutta', 'Adams-Bashforth', 'Adams-Moulton'],
        'All Single Step methods'
        )

def allAdamsMoulton():
    mts = []
    mys = []
    pts = []
    p = []

    f = getFunction()

    t, y = getPoint(0)

    h, n = getNandH()

    ts, ys = runge.method(f, t, y, h, 7)
    p.insert(0,Point2D(ts[0], ys[0])) # takes point generated from runge kutta method
    for i in range(6):
        o = i + 1
        if i - 1 > 0: p.insert(0,Point2D(ts[i], ys[i])) # takes point generated from runge kutta method
        if i == 1:
            i = i -1
        pts, ts5, ys5 = adams_moulton.method(f, p, h, n-i, o)
        plot([ts5], [ys5], [''], 'Adams-Moulton of order {}'.format(o))
        os.system('clear')
        mts.append(ts5)
        mys.append(ys5)

    plot(
        mts,
        mys,
        ['1st Order', '2nd Order','3rd Order','4th Order','5th Order','6th Order'],
        'Adams-Moulton Methods (1-6)'
        )


#---------------------------------------------------------------------
# File Name   : HypothesisTesting2.py
# Author      : Kunal K.
# Description : Implementing hypothesis test methods
# Date:       : 9 Nov. 2020
# Version     : V1.0
# Ref No      : DS_Code_P_K07
#---------------------------------------------------------------------

import pandas as pd
# import numpy as np
import scipy
from scipy import stats
import statsmodels.stats.descriptivestats as sd
# import plotly.plotly as py
# import plotly.graph_objs as go
# from plotly.tools import FigureFactory as FF

############## 1 Sample Sign Test(Student_Scores) ################
# import statsmodels.stats.descriptivestats as sd
data=pd.read_excel("Marks-1sample sign test.xlsx")
data
#############Normality test###############
print(stats.shapiro(data.Marks))

###################1 Sample Sign Test #############
sd.sign_test(data.Marks,mu0=82)
help(sd.sign_test)

############### Mann-Whitney test(Vehicles with and without addictive) ############
data=pd.read_excel("Hyothesis Testing\Mann_whitney.xlsx")
data
data.columns="Without_additive","With_additive"
#############Normality test###############
print(stats.shapiro(data.Without_additive))
print(stats.shapiro(data.With_additive))

############## Mann-Whitney test #############
# import statsmodels.stats.descriptivestats as sd
scipy.stats.mannwhitneyu(data.Without_additive, data.With_additive)

############2 sample T Test(Marketing Strategy) ##################
#############Normality test###############
#promotion=pd.read_excel("C:\Datasets_BA\Hypothesis\Hypothesis Testing_R&Python_codes\Promotion.xlsx")

promotion=pd.read_excel("E:/Day Wise/Day 08 Hypothesis Testing/Data/Promotion.xlsx")
promotion
promotion.columns = "Credit","Promotion.Type","InterestRateWaiver","StandardPromotion"
##########Normality Test ############

print(promotion.columns)
print(scipy.stats.anderson(promotion.InterestRateWaiver,dist = 'norm'))
#15%, 10%, 5%, 2.5%, 1%
print(scipy.stats.anderson(promotion.StandardPromotion,dist = 'norm'))
help(stats.shapiro)

######## 2 Sample T test ################
scipy.stats.ttest_ind(promotion.InterestRateWaiver,promotion.StandardPromotion,nan_policy='omit')
help(scipy.stats.ttest_ind)

############# One - Way Anova###################

cof=pd.read_excel("ContractRenewal_Data(unstacked).xlsx")
cof
cof.columns="SupplierA","SupplierB","SupplierC"

scipy.stats.levene(cof.SupplierA, cof.SupplierB,cof.SupplierC)
help(scipy.stats.levene)

stats.f_oneway(cof.SupplierA , cof.SupplierB , cof.SupplierC)

################Chi-Square Test ################

Bahaman=pd.read_excel("Hypothesis Testing/Data/Bahaman.xlsx")
Bahaman

count=pd.crosstab(Bahaman["Defective"],Bahaman["Country"])
count
Chisquares_results=scipy.stats.chi2_contingency(count)
help(scipy.stats.chi2_contingency)
Chisquares_results
Chi_square=[['','Test Statistic','p-value'],['Sample Data',Chisquares_results[0],Chisquares_results[1]]]
#chisample_results=FF.create_table(Chi_square,index=True)
#chisample_results

import numpy,import scipy,from scipy,import statsmodels


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

# In[4]:

#Antono Muniz      22.119.001-0
#Atividade 3

# In[5]:

#ex 2

#Sabe-se que 60% dos indivíduos submetidos a um tratamento médico sobrevivem.
#Se 20 indivíduos foram submetidos ao tratamento, determine, aplicando a
#distribuição binomial, a probabilidade de no máximo dois sobreviverem.

# In[6]:

from scipy.stats import binom
t = binom.pmf(2, 20, 6/10) + binom.pmf(1, 20, 6/10) + binom.pmf(0, 20, 6/10)
print(t)

# In[7]:

#ex 3
#O número de mortes por afogamento em fins de semana, numa cidade praiana,
#é de 2 a cada grupo de 50000 habitantes em média.

# In[8]:

#a - Qual a probabilidade de que em um grupo de 200000 habitantes ocorram 5 afogamentos?

# In[9]:

from scipy.stats import binom
binom.pmf(5,200000,2/50000)

# In[10]:

#b - Qual a probabilidade de que em um grupo de 125000 habitantes ocorram pelo menos 3 afogamentos?

# In[11]:

from scipy.stats import binom
print(1 - (binom.pmf(2,125000,2/50000) + binom.pmf(1,125000,2/50000) + binom.pmf(0,125000,2/50000) ) )

# In[15]:

#ex 4
#Uma empresa de eletrônicos considerou que o tempo de vida de suas baterias de celular
#segue uma distribuição normal com média de 120 minutos e variância de 100 minutos.

#media = 120
#var = 100
#desvio padrão é a raiz quadrada da variância = 10

# In[16]:

#a - Qual é a probabilidade aproximada de uma bateria durar menos que 100 minutos?

# In[17]:

from scipy.stats import norm
#P(x < 100)
norm.cdf(100,120,10)

# In[18]:

#b - Qual é a probabilidade de uma bateria durar 115 e 130 minutos?

# In[19]:

#P(115 < x < 130)
norm.cdf(130,120,10) - norm.cdf(115,120,10)


import numpy as np
import scipy.stats as st
import matplotlib.pyplot as plt
from sklearn import linear_model

def corr_plot(x, y, max_num=10000, outlier=0.01, line_on=True,
              corr_on=True, size=30, dot_color=None, outlier_color="r",
              alpha=0.8, color_rate=10,linewidth=2): #"deepskyblue"
    score = st.pearsonr(x, y)
    np.random.seed(0)
    if len(x) > max_num:
        idx = np.random.permutation(len(x))[:max_num]
        x, y = x[idx], y[idx]
    outlier = int(len(x) * outlier)

    xy = np.vstack([x,y])
    z = st.gaussian_kde(xy)(xy)
    idx = z.argsort()
    idx1, idx2 = idx[outlier:], idx[:outlier]

    if dot_color is None:
        #c_score = np.log2(z[idx]+100)
        c_score = np.log2(z[idx] + color_rate*np.min(z[idx]))
    else:
        #idx2 = []
        c_score = dot_color

    plt.set_cmap("Blues")
    plt.scatter(x[idx], y[idx], c=c_score, edgecolor='', s=size, alpha=alpha)
    plt.scatter(x[idx2], y[idx2], c=outlier_color, edgecolor='', s=size/5,
                alpha=alpha/3.0)#/5
    plt.grid(alpha=0.4)

    if line_on:
        clf = linear_model.LinearRegression()
        clf.fit(x.reshape(-1,1), y)
        xx = np.linspace(x.min(), x.max(), 1000).reshape(-1,1)
        yy = clf.predict(xx)
        plt.plot(xx, yy, "k--", label="R=%.3f" %score[0],linewidth=linewidth)
        # plt.plot(xx, yy, "k--")

    if corr_on:
        plt.legend(loc="best", fancybox=True, ncol=1)
        # plt.annotate("R=%.3f\np=%.1e" %score, fontsize='x-large',
        #             xy=(0.97, 0.05), xycoords='axes fraction',
        #             textcoords='offset points', ha='right', va='bottom')

def volcano_plot(fold_change, pval, p_min=0.00001,
                 x_log10=True, p_threshold=0.05,
                 h_color="red", label=None):
    """
    Volcano plot between log_fold change and p values, which is often used
    for hypothesis test between two conditions.
    """
    pval[pval < p_min] = p_min
    idx1 = pval < p_threshold
    idx0 = pval >= p_threshold
    plt.scatter(fold_change[idx0], -np.log10(pval)[idx0],
                color="grey", alpha=0.7, label=None)
    plt.scatter(fold_change[idx1], -np.log10(pval)[idx1],
                color=h_color, alpha=0.7, label=label)
    plt.ylabel("-log10(p value)")
    plt.xlabel("Fold change")
    if x_log10:
        plt.xscale('log', basex=10)


"""Functions utilities.

Some functions for implementation.

"""
import numpy as np

# Generic #
def G(x, y, s):
    """Gaussian kernel.

    .. math::
        G(x, y) = \exp(-(x^2 + y^2) / s)

    Parameters
    ----------
    x : float or array_like
        x value.
    y : float or array_like
        y value.
    s : float
        Gaussian shape parameter.

    Returns
    -------
    float or array_like
        Gaussian function
    """
    return np.exp(-(x ** 2 + y ** 2) / s)

# PDE FUNCTIONS #
def K(u, kap, eps):
    """Compute diffusion function

    .. math::
        K(u) = \kappa \, (1 + \varepsilon u)^3 + 1

    Parameters
    ----------
    u : array_like
        Temperature variable.
    kap : float
        Diffusion parameter.
    eps : float
        Inverse of activation energy.

    Returns
    -------
    array_like
        Evaluation of K function.
    """
    return kap * (1 + eps * u) ** 3 + 1

def Ku(u, kap, eps):
    """Derivative of K with respect to u.

    .. math:
        \dfrac{\partial K}{\partial u} = K_{u} = 3\,\varepsilon \kappa\, (1 + \varepsilon\, u)^2
    Parameters
    ----------
    u : array_like
        Temperature variable.
    kap : float
        Diffusion parameter.
    eps : float
        Inverse of activation energy.

    Returns
    -------
    array_like
        Ku evaluation.
    """
    return 3 * eps * kap * (1 + eps * u) ** 2

def f(u, b, eps, alp, s):
    """Temperature-fuel reaction function.

    Parameters
    ----------
    u : array_like
        Temperature value.
    b : array_like
        Fuel value.
    eps : float
        Inverse of activation energy parameter.
    alp : float
        Natural convection parameter.
    s : function or lambda
        Step function.

    Returns
    -------
    array_like
        Reaction function.
    """
    return s(u) * b * np.exp(u / (1 + eps * u)) - alp * u

def g(u, b, eps, q, s):
    """RHS of fuel PDE.

    Parameters
    ----------
    u : array_like
        Temperature value
    b : array_like
        Fuel value.
    eps : float
        Inverse of activation energy parameter.
    q : float
        Reaction heat parameter.
    s : function or lambda
        Step function.

    Returns
    -------
    array_like
        Fuel RHS PDE.
    """
    return -s(u) * (eps / q) * b * np.exp(u / (1 + eps * u))

def H(u, upc):
    """2D heaviside funcion

    Parameters
    ----------
    u : array_like
        Temperature value
    upc : float
        Phase change threshold.

    Returns
    -------
    array_like
        Heaviside function evaluation.
    """
    S = np.zeros_like(u)
    S[u >= upc] = 1.0
    return S

def sigmoid(u, k=.5):
    """Sigmoid function.

    Parameters
    ----------
    u : array_like
        Temperature value.
    k : float, optional
        Slope constant factor, by default .5

    Returns
    -------
    array_like
        Sigmoid evaluation.
    """
    return 1 / (1 + np.exp(-k * scale(u))) #0.5 * (1 + np.tanh(k * self.scale(u)))

def scale(u, a=-10, b=10):
    """Scale function.

    Parameters
    ----------
    u : array_like
        Temperature value.
    a : int, optional
        Minimum value, by default -10
    b : int, optional
        Maximum value, by default 10

    Returns
    -------
    array_like
        Scaled value of u.
    """
    return (b - a) * (u - np.min(u)) / (np.max(u) - np.min(u)) + a


# Importing important libraries
import numpy as np

# A function which will find the line between two points.
# @4_data_exploration.ipynb
# @ Intercept And Slope
def get_line_equation(p1, p2):
    """
    Solve the system of equations:
    y1 = m*x1 + b
    y2 = m*x2 + b

    This translates to:
    m = (y2 - y1) / (x2 - x1)
    b = y1 - m*x1

    Input:
    p1: first point [x1, y1]
    p2: second point [x2, y2]

    returns: slope, intercept
    """
    m = (p2[1] - p1[1]) / (p2[0] - p1[0]) # Slope
    b = p1[1] - m * p1[0] # Intercept
    return  m, b

# Removing the outliers
def remove_outliers(data, col):
      for x in col:
        q75,q25 = np.percentile(data.loc[:,x],[75,25])
        intr_qr = q75-q25

        max = q75+(1.5*intr_qr)
        min = q25-(1.5*intr_qr)

        data.loc[data[x] < min,x] = np.nan
        data.loc[data[x] > max,x] = np.nan


# -*- coding: utf-8 -*-
# @Time    : 7/29/2018 10:08 PM
# @Author  : DonaldY

# 1. 定义数据集
x = [4, 8, 12, 25, 32, 43, 58, 63, 69, 79]
y = [20, 33, 50, 56, 42, 31, 33, 46, 65, 75]

# 2. 实现 n 次多项式拟合
import numpy as np
from scipy.optimize import leastsq
from matplotlib import pyplot as plt

# 根据公式，定义 n 次多项式函数
def fit_func(p, x):
    f = np.poly1d(p)
    return f(x)

# 残差函数（观测值与拟合值之间的差距）
def err_func(p, x, y):
    ret = fit_func(p, x) - y
    return ret

# n 次多项式拟合
def n_poly(n):
    p_init = np.random.randn(n) # 生成 n 个随机数
    parameters = leastsq(err_func, p_init, args=(np.array(x), np.array(y)))
    return parameters[0]

n_poly(3)

# 3. 绘制出 4，5，6，7, 8, 9 次多项式的拟合图像
# 绘制拟合图像时需要的临时点
x_temp = np.linspace(0, 80, 10000)

# 绘制子图
fig, axes = plt.subplots(2, 3, figsize=(15,10))

axes[0,0].plot(x_temp, fit_func(n_poly(4), x_temp), 'r')
axes[0,0].scatter(x, y)
axes[0,0].set_title("m = 4")

axes[0,1].plot(x_temp, fit_func(n_poly(5), x_temp), 'r')
axes[0,1].scatter(x, y)
axes[0,1].set_title("m = 5")

axes[0,2].plot(x_temp, fit_func(n_poly(6), x_temp), 'r')
axes[0,2].scatter(x, y)
axes[0,2].set_title("m = 6")

axes[1,0].plot(x_temp, fit_func(n_poly(7), x_temp), 'r')
axes[1,0].scatter(x, y)
axes[1,0].set_title("m = 7")

axes[1,1].plot(x_temp, fit_func(n_poly(8), x_temp), 'r')
axes[1,1].scatter(x, y)
axes[1,1].set_title("m = 8")

axes[1,2].plot(x_temp, fit_func(n_poly(9), x_temp), 'r')
axes[1,2].scatter(x, y)
axes[1,2].set_title("m = 9")


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import statsmodels.api as sm

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

# load data
# ------------
data = pd.read_csv('../data/1.01. Simple linear regression.csv')
# print(data.head())
# print(data.describe())

# define regression variables
# ------------
# -- we want to know if SAT is a good predictor for later GPA
# use as independent variable (x) the SAT score
x1 = data ['SAT']
# use as dependent variable (y) the GPA
y = data ['GPA']

# explore data before the regression
# ------------
# Plot a scatter plot (first we put the horizontal axis, then the vertical axis)
plt.scatter(x1,y)
# Name the axes
plt.xlabel('SAT', fontsize = 20)
plt.ylabel('GPA', fontsize = 20)
# Show the plot
# plt.show()

# fit the regression model
# ------------
# add a constant
x = sm.add_constant(x1)
# Fit the model, according to the OLS (ordinary least squares) method
results = sm.OLS(y,x).fit()
# print a summary of the regression
print(results.summary())
print('Parameters: ', results.params)
print('R2: ', results.rsquared)
# -- for a full list of options to extract parameters from the summary
# print(dir(results))

# see the results, given the resulting regression from above
# https://www.statsmodels.org/stable/examples/notebooks/generated/ols.html
# ------------
# re-create a scatter plot with underlying data
plt.scatter(x1,y)
# Define the regression equation, so we can plot it later
yhat = (results.params[1] * x1) + results.params[0]
# plot the regression line (with some chart attributes)
chart = plt.plot(x1, yhat, lw=4, c='orange', label ='regression line')
# Label the axes
plt.xlabel('SAT', fontsize = 20)
plt.ylabel('GPA', fontsize = 20)
plt.show()


from gurobipy import Model, GRB, GurobiError, quicksum
import numpy as np
import matplotlib.pyplot as plt

StatusDict = {getattr(GRB.Status, s): s for s in dir(GRB.Status) if s.isupper()}

class TSP_Gurobi(object):
  """docstring for PMSP_Gurobi"""
  def __init__(self):
    # setting the solver attributes;
    self.route = []
    self.route_order = []
  def solve(self, city_ids, map_points):
    # map_points: N by 2
    # city_ids: (N,)
    solved = False
    # define the model and solution matrix
    tsp_m, X = self._create_model(city_ids, map_points)
    self._set_model_parms(tsp_m)
    try:
      tsp_m.optimize()
      if tsp_m.status == GRB.Status.OPTIMAL:
        solved = True
        # print("solution", tsp_m.getAttr('x', X))
        self._formulate_route(tsp_m, X, city_ids)
      else:
        statstr = StatusDict[tsp_m.status]
        print('Optimization was stopped with status %s' %statstr)

    except GurobiError as e:
      print('Error code '+str(e.errno)+': '+str(e))

    return solved

  def _set_model_parms(self, m):
    # permittable gap
    # m.setParam('MIPGap',0.2)
    # time limit
    # m.setParam('TimeLimit',10)
    # percentage of time on heuristics
    # m.setParam('Heuristics',0.5)
    pass

  def _formulate_route(self, tsp_m, X, city_ids):
    # print("variables: ", startTime.keys)
    solution = tsp_m.getAttr('x', X)
    selected = []
    for i in city_ids:
      for j in city_ids:
        if (i!=j) and (solution[i,j] > 0.5):
          selected.append((i,j))

    self.route = selected
    print("route: ", selected)
    self.route_order.append(city_ids[0])
    prev = city_ids[0]
    for i in range(len(city_ids)):
      for c_id in city_ids[1:]:
        if (prev, c_id) in selected:
          self.route_order.append(c_id)
          prev = c_id
    print("route_order ids", self.route_order)

    return

  def calculate_distances(self, city_ids, map_points):
    distances_map = {}
    for i, c_iid in enumerate(city_ids):
      a = map_points[i,:]
      for j, c_jid in enumerate(city_ids):
        if i != j:
          b = map_points[j,:]
          distances_map[(c_iid, c_jid)] = np.linalg.norm(a-b)

    return distances_map

  def _create_model(self, city_ids, map_points):
    depot_id = city_ids[0]
    city_num = len(city_ids)
    ## prepare the index for decision variables
    # index of network flow
    cities = tuple(city_ids)
    # index of MTZ constraint
    MTZ_u = tuple(city_ids[1:])
    # connecting arcs of the cities
    cityArcs = [(i,j) for i in cities for j in cities if i != j]

    ## parameters model (dictionary)
    # 1. distance map
    distances_map = self.calculate_distances(city_ids, map_points)

    ## create model
    m = Model('TSP')
    ## create decision variables
    # 1. choice of arcs between cities
    x = m.addVars(cityArcs, vtype=GRB.BINARY, name='route')
    # 2. for expression of non-subtour: [2,N]
    u = m.addVars(MTZ_u, name='MTZ_u')

    ## create objective: minimum route distance
    m.setObjective(quicksum([x[i,j]*distances_map[(i,j)] for (i,j) in cityArcs]), GRB.MINIMIZE) # TOTRY
    ## create constraints
    # 1. MTZ formulation
    m.addConstrs((u[i]-u[j]+city_num*x[i,j] <= city_num-1 for (i,j) in cityArcs if (i>depot_id and j>depot_id)),'MTZ formulation')
    m.addConstrs((u[i]>=0 and u[i]<=city_num-1 for i in MTZ_u), 'MTZ compensation')
    # 2. Network flow
    m.addConstrs((quicksum([x[i,j] for j in cities if i!=j])==1 for i in cities), 'Network flow1')
    m.addConstrs((quicksum([x[i,j] for i in cities if i!=j])==1 for j in cities), 'Network flow2')

    return m, x

if __name__ == '__main__':
  city_num = 50
  # map points generated
  map_points = np.random.uniform(10, 100, (city_num, 2))
  city_ids = range(1, city_num+1)
  tsp_solver = TSP_Gurobi()
  solved = tsp_solver.solve(city_ids, map_points)

  if solved:
    fig, ax = plt.subplots()
    ax.scatter(map_points[:,0], map_points[:,1], color='red')
    for i in range(city_num):
      ax.annotate(str(city_ids[i]), (map_points[i,0], map_points[i,1]))

    for (i,j) in tsp_solver.route:
      line_xs = [map_points[i-1,0], map_points[j-1,0]]
      line_ys = [map_points[i-1,1], map_points[j-1,1]]
      ax.plot(line_xs, line_ys, 'b--')
    plt.show()


# Copyright (c) 2020 Max Planck Gesellschaft

'''
File in order to compute an optimal LQR controller
x[k] = [theta , thetaDot]
'''

import numpy as np
import scipy.linalg

# Discrete-time LQR
def dlqr(A, B, Q, R):
    """Solve the discrete time lqr controller.

    x[k+1] = A x[k] + B u[k]

    cost = sum x[k].T*Q*x[k] + u[k].T*R*u[k]
    """
    # ref Bertsekas, p.151

    # first, try to solve the ricatti equation
    X = np.matrix(scipy.linalg.solve_discrete_are(A, B, Q, R))

    # compute the LQR gain
    K = np.matrix(scipy.linalg.inv(B.T * X * B + R) * (B.T * X * A))

    eigVals, eigVecs = scipy.linalg.eig(A - B * K)

    return K

# Define Params:
g = 10.0
m = 1.0
l = 1.0
dt = 0.05

A = np.matrix([[1,dt],[dt*(3*g)/(2*l),1]])
B = np.matrix([[0],[dt*(3)/(m*l**2)]])

Q = np.diag([1,0.1])
R = np.diag([0.1])

# Calculate Gain Matrix:
K = dlqr(A,B,Q,R)

print ("Gain Matrix is:")
print (K)

# PREVIOUSLY USED LQR Matrix: <-> SO FAR ALREADY CONSISTENT WITH ENV (1.0,0.1,0.001)
#Q = np.diag([10,1])
#R = 0.01
#K = [[19.80210901  6.03515527]]


import numpy as np
# Teta is features vector : teta_0,teta_1,....,teta_n . Teta is column vector (n+1)x1 (n+1 is the number of features)

# X is a matrix [X0,X1,X2,....,Xn]. each X0,X1,X2,....,Xn is a column vector mX1 where m is number of data set points. thus X is m*n. Notice that X0 is always 1

# X*Teta is : teta0*X0 + teta1*X1 + ….. +teta_n*Xn .i.e. X*Teta is a column vector mX1

# for example suppose we have 3 features i.e. teta0,teta1,teta2
Teta = np.array([2,3,-0.5])
print("Teta : ",Teta)
m=10
# for example suppose we have 10 data set points
X0 = np.ones(m)
print("X0 : ",X0)

X1 = np.arange(0,m,1)
print("X1 : ",X1)

X2 = np.arange(20,m+20,1)
print("X2 : ",X2)

X = np.vstack((X0,X1,X2)).T
print("X.shape : ",X.shape)

# both solutions works
print(np.dot(X,Teta))
print(np.matmul(X,Teta))


import numpy as np

def pointless_sort(x):
    """
    This function always returns the same values to show how testing
    works, check out the `test/test_alg.py` file to see.
    """
    return np.array([1,2,3])

def insertionsort(x):
    """
    input: insertsion sort takes in a list or numpy array
    output: returns the list or array in sorted order

    notes: use insertion sort algorithm -- adapted from pseudocode in Cormen textbook
    """
    assign = 0
    cond = 0
    for j in range(1, len(x)):
        key = x[j]
        i = j-1
        assign += 2
        while i >= 0 and x[i] > key:
            cond += 2
            x[i+1] = x[i]
            i = i-1
            assign += 2
        x[i+1] = key
        assign += 1
    return [x, cond, assign]

def bubblesort(x):
    """
    input: bubble sort takes in a list or numpy array
    output: returns the list or array in sorted order

    notes: use bubble sort algorithm -- adapted from pseudocode in Cormen textbook
    """
    assign = 0
    cond = 0
    for i in range(len(x)):
        for j in range(len(x)-1, i, -1):
            if x[j] < x[j-1]:
                cond += 1
                x[j], x[j-1] = x[j-1], x[j]
                assign += 3
    return [x, cond, assign]

def quicksort(x, start=0, end=None, assign=0, cond=0):
    """
    input: quick sort takes in a list or numpy array and the first and last index of the array
    output: returns the list or array in sorted order

    notes: use quicksort algorithm -- adapted from pseudocode in Cormen textbook
    """

    if end == None:
        cond += 1
        end = len(x)-1
        assign += 1
    if start < end:
        cond += 1
        split, cond, assign  = partition(x, start, end, cond, assign)
        assign += 1
        quicksort(x, start, split - 1, assign, cond)
        quicksort(x, split + 1, end, assign, cond)
    return [x, cond, assign]

def partition(A,p,r, cond, assign):
    '''
    input: an array and the first and last index of a region of the array
    output: a pivot index

    notes: partition algorithm adapted form pseudocode in Cormen textbook
    '''
    x = A[r]
    i = p-1
    j=p
    assign += 3
    while j < r:
        cond += 1
        if A[j] <= x:
            cond += 1
            i = i+1
            A[j], A[i] = A[i], A[j]
            assign += 4
        j += 1
        assign += 1
    A[r] = A[i+1]
    A[i+1] = x
    assign += 2
    return i+1, cond, assign


# The content of this module is taken from a Datacamp courses
# Statistical Thinking in Python I and II by Justin Bois

import numpy as np

def ecdf(data):
    """Compute ECDF for a one-dimensional array of measurements."""
    # Number of data points: n
    n = len(data)

    # x-data for the ECDF: x
    x = np.sort(data)

    # y-data for the ECDF: y
    y = np.arange(1, n + 1) / n

    return x, y

def bootstrap_replicate_1d(data, func):
    """Generate bootstrap replicate of 1D data."""
    bs_sample = np.random.choice(data, len(data))
    return func(bs_sample)

def draw_bs_reps(data, func, size=1):
    """Draw bootstrap replicates."""

    # Initialize array of replicates: bs_replicates
    bs_replicates = np.empty(size)

    # Generate replicates
    for i in range(size):
        bs_replicates[i] = bootstrap_replicate_1d(data, func)

    return bs_replicates

def draw_bs_reps_ind(data, func, size=1):
    """Draw bootstrap replicates, resampling indices"""

    # Set up array of indices
    inds = np.arange(len(data))

    # Initialize replicates
    bs_reps = np.empty(size)

    # Generate replicates
    for i in range(size):
        bs_inds = np.random.choice(inds, size=len(data))
        bs_data = data[bs_inds]
        bs_reps[i] = func(bs_data)
    return bs_reps

def draw_bs_pairs_linreg(x, y, size=1):
    """Perform pairs bootstrap for linear regression."""

    # Set up array of indices to sample from: inds
    inds = np.arange(len(x))

    # Initialize replicates: bs_slope_reps, bs_intercept_reps
    bs_slope_reps = np.empty(size)
    bs_intercept_reps = np.empty(size)

    # Generate replicates
    for i in range(size):
        bs_inds = np.random.choice(inds, size=len(x))
        bs_x, bs_y = x[bs_inds], y[bs_inds]
        bs_slope_reps[i], bs_intercept_reps[i] = np.polyfit(bs_x, bs_y, 1)

    return bs_slope_reps, bs_intercept_reps

def permutation_sample(data1, data2):
    """Generate a permutation sample from two data sets."""

    # Concatenate the data sets: data
    data = np.concatenate((data1, data2))

    # Permute the concatenated array: permuted_data
    permuted_data = np.random.permutation(data)

    # Split the permuted array into two: perm_sample_1, perm_sample_2
    perm_sample_1 = permuted_data[:len(data1)]
    perm_sample_2 = permuted_data[len(data1):]

    return perm_sample_1, perm_sample_2

def draw_perm_reps(data_1, data_2, func, size=1):
    """Generate multiple permutation replicates."""

    # Initialize array of replicates: perm_replicates
    perm_replicates = np.empty(size)

    for i in range(size):
        # Generate permutation sample
        perm_sample_1, perm_sample_2 = permutation_sample(data_1, data_2)

        # Compute the test statistic
        perm_replicates[i] = func(perm_sample_1, perm_sample_2)

    return perm_replicates


# coding: utf-8

# In[1]:

#imported packages
import numpy as np
import time
from matplotlib import pyplot as plt
import seaborn as sns
get_ipython().magic(u'matplotlib inline')

# In[2]:

#created a deta set with "years" as X and "salary" as y
#there is a linear relationship between X and y

years = np.arange(0,40,0.5)
np.random.seed(0)
salary = 45000+np.sqrt(years)*16789 +np.random.normal(2000,10000,len(years))

# In[17]:

y=np.array(salary)

X_original= np.array(years)

#Created a ones vector
ones = np.ones((X_original.shape[0],1))

#converted X_original to a nX2 matrix, n is the number samples, and the first column of X_original is 1
#add ones to the first vector/column in X_original
X = np.reshape(X_original, (X_original.shape[0],1))
X = np.concatenate((ones,X),axis=1)

print(X.shape)
print(X[0:3, :])
print(X_original.shape)

# In[ ]:

#In the above cell, I gave X_original since in Vectorized_update_theta function,
#under gradient[1] multiplication------error(theta,X,y) is in order of 80*1. So, X_original has dimension of 80*1
#Whereas X has dimension of 80*2 which would result in error for the above function and the optimum never gets executed.

##This is the most important step in vectorization assignment.

# In[24]:

# error = y_i - y_hat_i
def error(theta, X, y):
    return y - (X.dot(theta))  #np.dot() multiplication

# SSE (sum squared error)
def vectorized_calculate_SSE(theta):

    return sum(error(theta, X, y)**2 )

def vectorized_update_theta(theta, gamma):
    gradient=[0,0]

    gradient=[0,0]
    gradient[0] = -2*sum(error(theta, X, y) )
    gradient[1] = -2*sum(error(theta, X, y)*X_original) #multiplication of matrices with same dimensions [80*1]

    return  [theta[0]-gamma*gradient[0], theta[1]-gamma*gradient[1]]

def vectorized_adaptive_optimum(theta, gamma, t, precision):
    #infinite loop if no "return" is executed
    while True:
        #decrease gamma in every iteration
        gamma *=t

        #store SSE
        old_SSE = vectorized_calculate_SSE(theta)

        #update theta for a small number of time
        for i in range(10):
            temp_theta =vectorized_update_theta(theta, gamma)

        #get the new SSE
        new_SSE = vectorized_calculate_SSE(temp_theta)

        # if SSE is thrinking, go to the next iteration and try a smaller gamma
        if new_SSE > old_SSE:
            continue

        # if SEE does converge
        else:
            # try a large iteration to see if gamma can be found
            for i in range(100000):

                #update theta and calculate new SSE
                theta =vectorized_update_theta(theta, gamma)
                new_SSE = vectorized_calculate_SSE(theta)

                #if the update is within the prcision
                if abs(old_SSE - new_SSE) < precision:

                    #print out the result and return to the function call
                    print("found minimum cost:", new_SSE)
                    print("the optimum theta:", theta)
                    print("the learning rate is:", gamma)
                    return theta

# In[29]:

#initiate theta
init_theta=[1,1]

#start from a large learning rate
gamma = 1

#the decrease rate of gamma
t=0.9

#the precision for stopping the search. 1 unit is a $1
precision =1

#print out the time used for computing
start_time = time.time()

#call the vectorized function

theta = vectorized_adaptive_optimum(init_theta,gamma,t,precision)
print("the calculation takes ", time.time()-start_time, " seconds.")

# In[38]:

#plot the prediction line

plt.title("Experience vs. Salary")
plt.xlabel('Years of Experience (Years)')
plt.ylabel('Salary ($)')
plt.grid(True)
plt.xlim(0,40)
plt.ylim(45000,180000)
plt.scatter(years, salary)

y_hat = X.dot(theta)  #y_hat is the linear regression line with respect to years
plt.plot(years,y_hat, color='red')

# In[ ]:

#Thus, the above cell fulfills the assignment.


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

# ### Principal component analysis (PCA)
#
# * PCA is used to decompose a multivariate dataset in a set of successive orthogonal components that explain a maximum amount of the variance. In scikit-learn, PCA is implemented as a transformer object that learns `n`  components in its fit method, and can be used on new data to project it on these components.
#
# PCA centers but does not scale the input data for each feature before applying the SVD. The optional parameter whiten=True makes it possible to project the data onto the singular space while scaling each component to unit variance. This is often useful if the models down-stream make strong assumptions on the isotropy of the signal: this is for example the case for Support Vector Machines with the RBF kernel and the K-Means clustering algorithm.
#
#     Below is an example of the iris dataset, which is comprised of 4 features, projected on the 2 dimensions that explain most variance:

# In[2]:

get_ipython().system('pip install numpy')
get_ipython().system('pip install pandas ')
get_ipython().system('pip install matplotlib ')
get_ipython().system('pip install scikit-learn')

# In[3]:

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

from sklearn import datasets
from sklearn.decomposition import PCA
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

# In[5]:

iris = datasets.load_iris()

# In[6]:

iris.keys()

# In[7]:

X = iris.data
y = iris.target

# In[8]:

target_names = iris.target_names

# In[9]:

X.shape # 150 rows and 4 columns

# In[10]:

pca = PCA(n_components=2) # 150 rows and 2 columns

# In[11]:

X_r = pca.fit_transform(X)
X_r.shape

# In[23]:

lda = LinearDiscriminantAnalysis(n_components=2)
X_r2 = lda.fit(X,y).transform(X)

# In[14]:

# Percentage of variance explained for each components
print('explained variance ratio (first two components): %s'
      % str(pca.explained_variance_ratio_))

# In[24]:

plt.figure()
colors = ['navy', 'turquoise', 'darkorange']
lw = 2

for color, i, target_name in zip(colors, [0, 1, 2], target_names):
    plt.scatter(X_r[y == i, 0], X_r[y == i, 1], color=color, alpha=.8, lw=lw,
                label=target_name)
plt.legend(loc='best', shadow=False, scatterpoints=1)
plt.title('PCA of IRIS dataset')

plt.figure()
for color, i, target_name in zip(colors, [0, 1, 2], target_names):
    plt.scatter(X_r2[y == i, 0], X_r2[y == i, 1], alpha=.8, color=color,
                label=target_name)
plt.legend(loc='best', shadow=False, scatterpoints=1)
plt.title('LDA of IRIS dataset')

plt.show()

# In[ ]:

Clustring/Dimensionality reduction/PCA for IRIS Dataset.py


from scipy.stats import t, norm
import pandas as pd
import numpy as np

def compute_ci(r=None, nx=None, ny=None, confidence=.95):
    """Compute Parametric confidence intervals around correlation coefficient.
    See : https://online.stat.psu.edu/stat505/lesson/6/6.3

    This is done by applying Fisher's r to z transform
    z = .5[ln((1+r)/(1-r))] = arctanh(r)

    The Standard error is 1/sqrt(N-3) where N is sample size

    The critical value for normal distribution for a corresponding confidence
    level is calculated from stats.norm.ppf((1 - alpha)/2) for two tailed test

    The lower and upper condidence intervals in z space are calculated with the formula
    z ± critical value*error

    The confidence interval is then converted back to r space

    :param stat : correlation coefficient
    :param nx : length of vector x
    :param ny :length of vector y
    :param confidence : Confidence level (0.95 = 95%)

    :returns : array containing confidence interval
    """

    assert r is not None and nx is not None
    assert isinstance(confidence, float)
    assert 0 < confidence < 1

    z = np.arctanh(r) # Fisher Transform  from r to z
    se = 1 / np.sqrt(nx - 3) # Standard error = 1/sqrt(N-3) where N is sample size
    crit = np.abs(norm.ppf((1 - confidence) / 2)) # Z-critical value
    ci_z = np.array([z - crit * se, z + crit * se]) # CI = point estimator ± critical value*error
    ci = np.tanh(ci_z)  # Back Transform to r-space

    return ci

def partial_corr(data=None, x=None, y=None, z=None, method="pearson"):
    """ Calculate Partial correlation which is the degree of association between
    x and y after removing effect of z. This is done by calculating correlation
    coefficient between the residuals of two linear regressions :
    x\sim z, y\sim z
    See : 1 https://en.wikipedia.org/wiki/Partial_correlation
          2 https://onlinelibrary.wiley.com/doi/pdf/10.1111/j.1467-842X.2004.00360.x?casa_token=p_D3joHC8C0AAAAA:qigIZHVfcVi8vsz1j2t7uQYOorrYaF3Tm4lpQOUzqG_J9gJgtFerOyliKBnQPVG187nJxbA-wcbXU3QcOw
          3 https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4681537/
          4 http://parker.ad.siu.edu/Olive/slch6.pdf
    :param data : pandas dataframe
    :param x : Column name in data
    :param y : Column name in data
    :param z : string or list
    :param method : string denoting the correlation type - "pearson" or "spearman"

    : returns: a python dictionary with keys as
        n: Sample size
        r: Partial correlation coefficient
        CI95: 95% parametric confidence intervals
        p-val: p-value
    """

    assert data.shape[0] > 2 # Check for atleast 3 samples
    assert x != z # x and z should be distinct
    assert y != z # y and z should be distinct
    assert x != y # x and y should be distinct
    if isinstance(z, list):
        assert x not in z # x and z should be distinct
        assert y not in z # y and z should be distinct

    combined_variables = [x,y] # Combine all variables - x, y and z
    for var in z:
        combined_variables.append(var)
    data = data[combined_variables].dropna() #Drop missing values
    n = data.shape[0] # Number of samples after dropping missing values
    k = data.shape[1] - 2 # Number of covariates
    assert n > 2

    if method == "spearman":
        V = data.rank(na_option='keep').cov() # Change data to rank for spearman correlation
    else:
        V = data.astype(float).cov() # Computing Covariance Matrix
    Vi = np.linalg.pinv(V, hermitian=True)   # Computing Inverse Covariance Matrix
    Vi_diag = Vi.diagonal()  # Storing variance
    D = np.diag(np.sqrt(1 / Vi_diag)) # Storing Standard Deviations from diagonal of inverse covariance matrix
    pcor = -1 * (D @ Vi @ D)
    r = pcor[0,1]

    if np.isnan(r):
        return {'n': n, 'r': np.nan, 'CI95%': np.nan, 'p-val': np.nan}

    # Finding p-value using student T test
    dof = n - k - 2  # Degree of freedom for multivariate analysis
    tval = r * np.sqrt(dof / (1 - r**2)) # Test statistic
    pval = 2 * t.sf(np.abs(tval), dof) # Calculate p-value corresponding to the test statistic and degree of freedom

    ci = compute_ci(r=r, nx=(n - k), ny=(n - k)) #Finding Confidence Interval
    ci=np.round(ci, 3)
    stats = {
        'n': n,
        'r': r,
        'CI95%': [ci],
        'p-val': pval.round(5),
    }
    return stats


"""
G R A D I E N T - E N H A N C E D   N E U R A L   N E T W O R K S  (G E N N)

Author: Steven H. Berguin <steven.berguin@gtri.gatech.edu>

This package is distributed under New BSD license.
"""

import numpy as np

class Activation(object):
    def __init__(self, **kwargs):
        for name, value in kwargs.items():
            setattr(self, name, value)

    def evaluate(self, z):
        """
        Evaluate activation function

        :param z: a scalar or numpy array of any size
        :return: activation value at z
        """
        pass

    def first_derivative(self, z):
        """
        Evaluate gradient of activation function

        :param z: a scalar or numpy array of any size
        :return: gradient at z
        """
        pass

    def second_derivative(self, z):
        """
        Evaluate second derivative of activation function

        :param z: a scalar or numpy array of any size
        :return: second derivative at z
        """
        pass

class Sigmoid(Activation):
    def evaluate(self, z):
        a = 1.0 / (1.0 + np.exp(-z))
        return a

    def first_derivative(self, z):
        a = self.evaluate(z)
        da = a * (1.0 - a)
        return da

    def second_derivative(self, z):
        a = self.evaluate(z)
        da = self.first_derivative(z)
        dda = da * (1 - 2 * a)
        return dda

class Tanh(Activation):
    def evaluate(self, z):
        numerator = np.exp(z) - np.exp(-z)
        denominator = np.exp(z) + np.exp(-z)
        a = np.divide(numerator, denominator)
        return a

    def first_derivative(self, z):
        a = self.evaluate(z)
        da = 1 - np.square(a)
        return da

    def second_derivative(self, z):
        a = self.evaluate(z)
        da = self.first_derivative(z)
        dda = -2 * a * da
        return dda

class Linear(Activation):
    def evaluate(self, z):
        return z

    def first_derivative(self, z):
        return np.ones(z.shape)

    def second_derivative(self, z):
        return np.zeros(z.shape)

def plot_activations():  # pragma: no cover
    import matplotlib.pyplot as plt

    x = np.linspace(-10, 10, 100)
    activations = {"tanh": Tanh(), "sigmoid": Sigmoid()}
    for name, activation in activations.items():
        plt.plot(x, activation.evaluate(x))
        plt.title(name)
        plt.show()

if __name__ == "__main__":  # pragma: no cover
    plot_activations()


import sys
import numpy as np
from timeit import default_timer as timer

def norm(v, x):
    n = v.shape[1]  # Número de colunas do vetor (k + 1).
    maximum_numerator = 0
    maximum_denominator = 0

    for i in range(n):
        # Colhendo a maior diferença modular entre os elementos dos vetores (k +1) e k.
        if abs(v[0, i] - x[0, i]) > maximum_numerator:
            maximum_numerator = abs(v[0, i] - x[0, i])

        # Colhendo o maior elemento do vetor (k + 1).
        if abs(v[0, i]) > maximum_denominator:
            maximum_denominator = abs(v[0, i])

    return maximum_numerator / maximum_denominator

def gauss_seidel_method(A, b, e, max_interactions):
    start = timer()
    print("Matrix A:")
    print(A)

    print("\nVector b:")
    print(b)

    n = b.shape[1]  # Número de colunas do vetor b.

    # Inicialmente, os vetores (k + 1) e k e a matriz C terão apenas zeros.
    v = np.zeros((1, n))
    x = np.zeros((1, n))
    C = np.zeros((n, n))

    g = b.copy()  # O vetor g assume os mesmos elementos do vetor b.

    for i in range(n):  # Gerando a matriz C e o vetor g.
        for j in range(n):
            if i != j:
                C[i, j] = ((-1) * A[i, j]) / A[i, i]

        g[0, i] = g[0, i] / A[i, i]

    k = 1

    print("\nMatrix C:")
    print(C)

    print("\nVector g:")
    print(g)

    while k <= max_interactions:
        for i in range(n):  # Atualizando o vetor (k + 1).
            partial_sum = 0

            for j in range(n):
                partial_sum += C[i, j] * v[0, j]

            v[0, i] = partial_sum + g[0, i]

        if norm(v, x) < e:  # Checando se a precisão foi atingida por meio da norma.
            print("\nSolution found:")
            print(v)

            end = timer()
            print("\nRuntime: %.6e seconds in %d interactions." % ((end - start), k))
            return v

        x = v.copy()
        k += 1

    # Corrigindo o número de interações quando a precisão não é atingida durante o while.
    if k == max_interactions + 1:
        k -= 1

    end = timer()
    print("\nRuntime: %.6e seconds in %d interactions." % ((end - start), k))
    return v

gauss_seidel_method(A = np.array(np.mat(sys.argv[1]), dtype = float),
                    b = np.array(np.mat(sys.argv[2]), dtype = float),
                    e = float(sys.argv[3]),
                    max_interactions = 50)


import numpy as np
import pandas as pd
import patsy
import warnings

def sigmoid(x):
    '''Sigmoid function of x.'''
    return 1/(1+np.exp(-x))

np.random.seed(0)

tol = 1e-8 # convergence tolerance

lam = None # l2-regularization
max_iter = 20 # maximum allowed iterations

r = 0.95 # covariance between x and z
n = 1000 # number of observations (size of dataset to generate)
sigma = 1 # variance of noise - how spread out is the data?

beta_x, beta_z, beta_v = -4, .9, 1 # true beta coefficients
var_x, var_z, var_v = 1, 1, 4 # variances of inputs

## the model specification you want to fit
formula = 'y ~ x + z + v + np.exp(x) + I(v**2 + z)'

#lets keep x and z closely related (height and weight)
x, z = np.random.multivariate_normal([0,0], [[var_x,r],[r,var_z]], n).T
#blood presure
v = np.random.normal(0,var_v,n)**3

#create a pandas dataframe (easily parseable object for manipulation)
A = pd.DataFrame({'x' : x, 'z' : z, 'v' : v})
#compute the log odds for our 3 independent variables
#using the sigmoid function
A['log_odds'] = sigmoid(A[['x','z','v']].dot([beta_x,beta_z,beta_v]) + sigma*np.random.normal(0,1,n))

A['y'] = [np.random.binomial(1,p) for p in A.log_odds]

#create a dataframe that encompasses our input data, model formula, and outputs
y, X = patsy.dmatrices(formula, A, return_type='dataframe')

#print it
print(X.head(100))

def catch_singularity(f):
    '''Silences LinAlg Errors and throws a warning instead.'''

    def silencer(*args, **kwargs):
        try:
            return f(*args, **kwargs)
        except np.linalg.LinAlgError:
            warnings.warn('Algorithm terminated - singular Hessian!')
            return args[0]

    return silencer

@catch_singularity
def newton_step(curr, X, lam=None):
    '''One naive step of Newton's Method'''

    # how to compute inverse? http://www.mathwarehouse.com/algebra/matrix/images/square-matrix/inverse-matrix.gif

    ## compute necessary objects
    # create probability matrix, miniminum 2 dimensions, tranpose (flip it)
    p = np.array(sigmoid(X.dot(curr[:, 0])), ndmin=2).T
    # create weight matrix from it
    W = np.diag((p * (1 - p))[:, 0])
    # derive the hessian
    hessian = X.T.dot(W).dot(X)
    # derive the gradient
    grad = X.T.dot(y - p)

    ## regularization step (avoiding overfitting)
    if lam:
        # Return the least-squares solution to a linear matrix equation
        step, *_ = np.linalg.lstsq(hessian + lam * np.eye(curr.shape[0]), grad)
    else:
        step, *_ = np.linalg.lstsq(hessian, grad)

    ## update our
    beta = curr + step

    return beta

@catch_singularity
def alt_newton_step(curr, X, lam=None):
    '''One naive step of Newton's Method'''

    ## compute necessary objects
    p = np.array(sigmoid(X.dot(curr[:, 0])), ndmin=2).T
    W = np.diag((p * (1 - p))[:, 0])
    hessian = X.T.dot(W).dot(X)
    grad = X.T.dot(y - p)

    ## regularization
    if lam:
        # Compute the inverse of a matrix.
        step = np.dot(np.linalg.inv(hessian + lam * np.eye(curr.shape[0])), grad)
    else:
        step = np.dot(np.linalg.inv(hessian), grad)

    ## update our weights
    beta = curr + step

    return beta

def check_coefs_convergence(beta_old, beta_new, tol, iters):
    '''Checks whether the coefficients have converged in the l-infinity norm.
    Returns True if they have converged, False otherwise.'''
    # calculate the change in the coefficients
    coef_change = np.abs(beta_old - beta_new)

    # if change hasn't reached the threshold and we have more iterations to go, keep training
    return not (np.any(coef_change > tol) & (iters < max_iter))

## initial conditions
# initial coefficients (weight values), 2 copies, we'll update one
beta_old, beta = np.ones((len(X.columns), 1)), np.zeros((len(X.columns), 1))

# num iterations we've done so far
iter_count = 0
# have we reached convergence?
coefs_converged = False

# if we haven't reached convergence... (training step)
while not coefs_converged:
    # set the old coefficients to our current
    beta_old = beta
    # perform a single step of newton's optimization on our data, set our updated beta values
    beta = newton_step(beta, X, lam=lam)
    # increment the number of iterations
    iter_count += 1

    # check for convergence between our old and new beta values
    coefs_converged = check_coefs_convergence(beta_old, beta, tol, iter_count)

print('Iterations : {}'.format(iter_count))
print('Beta : {}'.format(beta))


# %% [markdown]
# # Fitting one dimensional data
# Generate various one dimensional functions.
# Fit a neural network to them.
# Expand the domain of the x-axis, explore what happens.
# %%
import numpy as np
import matplotlib.pyplot as plt

plt.style.use("seaborn-whitegrid")

import tensorflow as tf

# %%
# Exponential case
x = np.linspace(-5, 5, num=1000)
y = np.exp(x)

plt.plot(x, y)
plt.show()

# %%
# Log case
x = np.linspace(0, 5, num=1000)
x = x[2:]
y = np.log(x)

plt.plot(x, y)
plt.show()

# %%
# Model with one input for x, one output layer for y, hidden layer of 10 nodes
# Linear activation function

# Needs non linear activation if no polynomial inputs are given

# Taylor series model? Need polynomials of x

# Sigmoid activation allows for much smoother fits - dont use
# Tanh nearly always better than sigmoid (0 mean?)
# Relu is like miniture step funcitons - most common activation
#   Higher gradients than tanh means generally can converge faster
# LeakyRelu might be slightly better in practice, but is not commonly used

mode = 3
if mode == 0:
    model = tf.keras.Sequential(
        [tf.keras.layers.Dense(4, input_shape=(1,)), tf.keras.layers.Dense(1)]
    )
if mode == 1:
    model = tf.keras.Sequential(
        [
            tf.keras.layers.Dense(
                10, input_shape=(1,), activation=tf.keras.activations.relu,
            ),
            tf.keras.layers.Dense(1),
        ]
    )
if mode == 2:
    model = tf.keras.Sequential(
        [
            tf.keras.layers.Dense(
                10, input_shape=(1,), activation=tf.keras.activations.sigmoid
            ),
            tf.keras.layers.Dense(1),
        ]
    )
if mode == 3:
    model = tf.keras.Sequential(
        [
            tf.keras.layers.Dense(
                units=4,
                input_shape=(1,),
                activation=tf.keras.activations.tanh,
                kernel_regularizer=tf.keras.regularizers.l1(l=0.1),
            ),
            tf.keras.layers.Dense(
                units=1, kernel_regularizer=tf.keras.regularizers.l1(l=0.1)
            ),
        ]
    )

model.compile(
    optimizer=tf.optimizers.Adam(learning_rate=0.1), loss=tf.keras.losses.mse
)
history = model.fit(x, y, epochs=50, verbose=False)

y_est = model.predict(x)

model.weights
# each layer = weights and bias
# each node output has a bias

plot_results(x, y, y_est, history.history["loss"])

plt.plot(model.weights[0].numpy().squeeze())
plt.plot(model.weights[2].numpy())
plt.show

# %% Plot results
def plot_results(x, y, y_est, loss):
    fig = plt.figure(figsize=(10, 6))
    plt.subplot(121)
    plt.plot(x, y, label="f(x)")
    plt.plot(x, y_est, label="NN")
    plt.xlabel("x")
    plt.ylabel("y")
    plt.legend()

    plt.subplot(122)
    plt.plot(loss)
    plt.xlabel("epoch")
    plt.ylabel("loss")
    plt.show()


from py_qt import bootstrap as bs
import matplotlib.pyplot as plt
from py_qt import npr_methods
import numpy as np

from py_qt import nonparam_regression as smooth
from py_qt import plot_fit
import tensorflow as tf
import requests

def f(x):
    return 3*np.cos(x/2) + x**2/5 + 3

xs = np.random.rand(200) * 10
ys = f(xs) + 2*np.random.randn(*xs.shape)

birthdata_url = 'https://www.umass.edu/statdata/statdata/data/lowbwt.dat'
birth_file = requests.get(birthdata_url)
birth_data = birth_file.text.split('\r\n')[5:]
birth_header = [x for x in birth_data[0].split(' ') if len(x) >= 1]
birth_data = [[float(x) for x in y.split(' ') if len(x) >= 1] for y in birth_data[1:] if len(y) >= 1]
# Pull out target variable
y_vals = np.array([x[1] for x in birth_data])
# Pull out predictor variables (not id, not target, and not birthweight)
x_vals = np.array([x[2:9] for x in birth_data])

# Split data into train/test = 80%/20%
train_indices = np.random.choice(len(x_vals), int(round(len(x_vals) * 0.8)), replace=False)
test_indices = np.array(list(set(range(len(x_vals))) - set(train_indices)))
x_vals_train = x_vals[train_indices]
x_vals_test = x_vals[test_indices]
y_vals_train = y_vals[train_indices]
y_vals_test = y_vals[test_indices]

# Normalize by column (min-max norm)
def normalize_cols(m):
    col_max = m.max(axis=0)
    col_min = m.min(axis=0)
    return (m - col_min) / (col_max - col_min)

x_vals_train = np.nan_to_num(normalize_cols(x_vals_train))
x_vals_test = np.nan_to_num(normalize_cols(x_vals_test))

# xs = x_vals_train
# ys = y_vals_train
grid = np.r_[0:10:512j]

k1 = smooth.NonParamRegression(xs, ys, method=npr_methods.LocalPolynomialKernel())
k1.fit()

plt.figure()
# plt.plot(xs, ys, 'o', alpha=0.5, label='Data')
plt.plot(k1(grid), 'k', label='quadratic', linewidth=2)
plt.show()

# grid = np.r_[0:10:512j]
#
# plt.plot(grid, f(grid), 'r--', label='Reference')
# plt.plot(xs, ys, 'o', alpha=0.5, label='Data')
# # plt.legend(loc='best')
# # plt.show()
#
# k0 = smooth.NonParamRegression(xs, ys, method=npr_methods.SpatialAverage())
# k0.fit()
# plt.plot(grid, k0(grid), label="Spatial Averaging", linewidth=2)
# plt.legend(loc='best')
#
# k1 = smooth.NonParamRegression(xs, ys, method=npr_methods.LocalPolynomialKernel(q=1))
# k2 = smooth.NonParamRegression(xs, ys, method=npr_methods.LocalPolynomialKernel(q=2))
#
# k1.fit()
# k2.fit()
#
# plt.figure()
# plt.plot(xs, ys, 'o', alpha=0.5, label='Data')
# plt.plot(grid, k2(grid), 'k', label='quadratic', linewidth=2)
# plt.plot(grid, k1(grid), 'g', label='linear', linewidth=2)
# plt.plot(grid, f(grid), 'r--', label='Target', linewidth=2)
# plt.legend(loc='best')
#
# yopts = k2(xs)
# res = ys - yopts
# plot_fit.plot_residual_tests(xs, yopts, res, 'Local Quadratic')
#
# yopts = k1(xs)
# res = ys - yopts
# plot_fit.plot_residual_tests(xs, yopts, res, 'Local Linear')
# plt.show()

# def fit(xs, ys):
#     est = smooth.NonParamRegression(xs, ys, method=npr_methods.LocalPolynomialKernel(q=2))
#     est.fit()
#     return est
#
# result = bs.bootstrap(fit, xs, ys, eval_points = grid, CI = (95,99))
#
# plt.plot(xs, ys, 'o', alpha=0.5, label='Data')
# plt.plot(grid, result.y_fit(grid), 'r', label="Fitted curve", linewidth=2)
# plt.plot(grid, result.CIs[0][0,0], 'g--', label='95% CI', linewidth=2)
# plt.plot(grid, result.CIs[0][0,1], 'g--', linewidth=2)
# plt.fill_between(grid, result.CIs[0][0,0], result.CIs[0][0,1], color='g', alpha=0.25)
# plt.legend(loc=0)
# plt.show()


# -*- coding: utf-8 -*-
"""
Created on Sat May  4 18:46:21 2019
FIR (ventana Kaiser)
Tecnológico Nacional de México
Tecnológico de Estudios Superiores de Ixtapaluca
División de Ingeniería Electrónica
@author: M. en C. Rogelio Manuel Higuera Gonzalez
"""
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
from scipy.fftpack import fft, fftshift
window1 = signal.kaiser(51, beta=0)
window2 = signal.kaiser(51, beta=5)
window3 = signal.kaiser(51, beta=6)
window4 = signal.kaiser(51, beta=8.6)
window5 = signal.kaiser(51, beta=14)
A1 = fft(window1, 2048) / (len(window1)/2.0)
A2 = fft(window2, 2048) / (len(window2)/2.0)
A3 = fft(window3, 2048) / (len(window3)/2.0)
A4 = fft(window4, 2048) / (len(window4)/2.0)
A5 = fft(window5, 2048) / (len(window5)/2.0)
response1 = 20 * np.log10(np.abs(fftshift(A1 / abs(A1).max())))
response2 = 20 * np.log10(np.abs(fftshift(A2 / abs(A2).max())))
response3 = 20 * np.log10(np.abs(fftshift(A3 / abs(A3).max())))
response4 = 20 * np.log10(np.abs(fftshift(A4 / abs(A4).max())))
response5 = 20 * np.log10(np.abs(fftshift(A5 / abs(A5).max())))
freq = np.linspace(-0.5, 0.5, len(A1))
fig,axes=plt.subplots()
axes.plot(window1,label='Beta=0')
axes.plot(window2,label='Beta=5')
axes.plot(window3,label='Beta=6')
axes.plot(window4,label='Beta=8.6')
axes.plot(window5,label='Bata=14')
axes.set_ylabel('Amplitude')
axes.set_xlabel('Sample')
plt.legend(bbox_to_anchor=(0.35,0.45),loc=2,borderaxespad=0.1)
plt.grid(True)
plt.savefig('ventanak1.eps',dpi=1000,bbox_inches='tight')
fig,axes1=plt.subplots()
axes1.plot(freq,response1,label='Beta=0')
axes1.plot(freq,response2,label='Beta=5')
axes1.plot(freq,response3,label='Beta=6')
axes1.plot(freq,response4,label='Beta=8.6')
axes1.plot(freq,response5,label='Beta=14')
axes1.set_ylabel('Normalized magnitude [dB]')
axes1.set_xlabel('Normalized frequency [cycles per sample]')
axes1.set_ylim([-220,1])
plt.legend(bbox_to_anchor=(0.38,0.31),loc=2,borderaxespad=0.1)
plt.grid(True)
plt.savefig('ventanak2.eps',dpi=1000,bbox_inches='tight')


import jax.numpy as jnp
from jax import grad, jit, vmap
from jax import random

key = random.PRNGKey(0)

grad_tanh = grad(jnp.tanh)

def sigmoid(x):
    return 0.5 * (jnp.tanh(x / 2) + 1)

# Outputs probability of a label being true.
def predict(W, b, inputs):
    return sigmoid(jnp.dot(inputs, W) + b)

# Build a toy dataset.
inputs = jnp.array([[0.52, 1.12,  0.77],
                   [0.88, -1.08, 0.15],
                   [0.52, 0.06, -1.30],
                   [0.74, -2.49, 1.39]])
targets = jnp.array([True, True, False, True])

# Initialize random model coefficients
key, W_key, b_key = random.split(key, 3)
W = random.normal(W_key, (3,))
b = random.normal(b_key, ())

# Training loss is the negative log-likelihood of the training examples.
def loss(W, b):
    preds = predict(W, b, inputs)
    label_probs = preds * targets + (1 - preds) * (1 - targets)
    return -jnp.sum(jnp.log(label_probs))

def loss2(params_dict):
    preds = predict(params_dict['W'], params_dict['b'], inputs)
    label_probs = preds * targets + (1 - preds) * (1 - targets)
    return -jnp.sum(jnp.log(label_probs))

# Including tuple values
W_grad, b_grad = grad(loss, (0, 1))(W, b)
print('W_grad', W_grad)
print('b_grad', b_grad)

# Differentiating with respect to standard Python containers just works, so use tuples, lists, and dicts (and arbitrary nesting) however you like.
print(grad(loss2)({'W': W, 'b': b}))


import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()
from scipy.stats import norm

np.random.seed(1)
NUM_TRIALS = 2000
BANDIT_MEANS = [1, 2, 3]

class Bandit:
    def __init__(self, true_mean):
        self.true_mean = true_mean

        # prior for mu is N(0,1)
        self.m = 0 # the predicted mean of the mean of X
        self.lambda_ = 1 # assumed precision (same as variance=1)

        self.tau = 1
        self.N = 0

    def pull(self):
        # draws a sample from N(mean=true_mean, precision=tau)
        return np.random.randn() / np.sqrt(self.tau) + self.true_mean

    def sample(self):
        # posterior
        return np.random.randn() / np.sqrt(self.lambda_) + self.m

    def update(self, x):
        # the number of samples N is 1 in the bernoulli case
        self.m = (self.tau * x + self.lambda_ * self.m) / ( self.tau + self.lambda_ )
        self.lambda_ += self.tau
        self.N += 1

def plot(bandits, trial):
    x = np.linspace(-3, 6, 200)
    for bandit in bandits:
        y = norm.pdf(x, bandit.m, np.sqrt(1. / bandit.lambda_))
        plt.plot(x, y, label=f"Real mean: {bandit.true_mean:.2f}, Number of plays: {bandit.N}")
    plt.title(f"Bandit distributions after {trial} trials")
    plt.legend()
    plt.show()

def run_experiment():
    bandits = [Bandit(m) for m in BANDIT_MEANS]
    sample_points = [5,10,20,50,100,200,500,1000,1500,1999]
    rewards = np.empty(NUM_TRIALS)

    for i in range(NUM_TRIALS):
        # Thompson sampling
        j = np.argmax([b.sample() for b in bandits])

        if i in sample_points:
            plot(bandits, i)

        x = bandits[j].pull()
        bandits[j].update(x)
        rewards[i] = x

    cumulative_average = np.cumsum(rewards) / (np.arange(NUM_TRIALS) + 1)

    # plot moving average ctr
    plt.plot(cumulative_average)
    for m in BANDIT_MEANS:
        plt.plot(np.ones(NUM_TRIALS)*m)
    plt.show()

    return cumulative_average

if __name__ == '__main__':
    run_experiment()


import numpy as np
import matplotlib.pyplot as plt

import numpy as np
import matplotlib.pyplot as plt

def FT(x):
    N = len(x)
    X = np.zeros(N, dtype=complex)

    for k in range(N):
        X[k] = 0.0j
        for n in range(N):
            X[k] += x[n] * np.exp(-2.0 * np.pi * 1.0j / N ) ** (k * n)

    return X

def IFT(x):
    N = len(x)
    X = np.zeros(N, dtype=complex)

    for k in range(N):
        X[k] = 0.0j
        for n in range(N):
            X[k] += x[n] * np.exp(2.0 * np.pi * 1.0j / N ) ** (k * n)

    return X/N

data = np.loadtxt("monthrg.dat")
time = data[:,0] + data[:,1]/12.0
signal = data[:,3]

signal = signal[time>1900]
time = time[time>1900]

# calculo la transformada
fft_signal = FT(signal)

# calculo la frecuencias
N=len(fft_signal)
f = np.zeros(N)
if N%2==0:
    f[:N//2] = np.arange(N//2)
    f[N//2:] = np.arange(-N//2,0)
else:
    f[:(N-1)//2+1] = np.arange((N-1)//2 + 1)
    f[(N-1)//2+1:] = np.arange(-(N-1)//2, 0)
d = (1.0/12.0) # intervalo entre medidas
f = f/(d*N)

# filtro de las frecuencias mayores que 0.2 years^{-1}
fft_signal_filter = fft_signal.copy()
fft_signal_filter[np.abs(f)>0.2] = 0.0

# calculo de la tranformada inversa
signal_filter = IFT(fft_signal_filter)

plt.figure(figsize=(8,14))

# plot de los datos
plt.subplot(4,1,1)
plt.scatter(time, signal, label='original', s=1.0)
plt.xlabel('Tiempo (yr)')
plt.ylabel('Numero manchas')
plt.grid()
plt.legend()

#plot de la transformada
plt.subplot(4,1,2)
plt.scatter(f, np.abs(fft_signal)/len(fft_signal), label='original', s=1.0)
plt.xlabel('Frecuencia (1/yr)')
plt.ylabel('Norma FFT / N')
plt.yscale('log')
plt.ylim([5E-3,1E2])
plt.grid()
plt.legend()

# plot de la transformada filtrada
plt.subplot(4,1,3)
plt.scatter(f, np.abs(fft_signal_filter)/len(fft_signal_filter), label='filtrado', s=1.0)
plt.xlabel('Frecuencia (1/yr)')
plt.ylabel('Norma FFT / N')
plt.yscale('log')
plt.grid()
plt.legend()
plt.ylim([5E-3,1E2])

# plot de la transformada inversa
plt.subplot(4,1,4)
plt.scatter(time, np.real(signal_filter), label='filtrado', s=1.0)
plt.xlabel('Tiempo (yr)')
plt.ylabel('Numero manchas')
plt.grid()
plt.legend()

plt.savefig('ejercicio18.png', bbox_inches='tight')


import matplotlib.pyplot as plt
import numpy as np
n=6 #number of array items
x=[24, 32, 40, 48, 64, 80] #example data with distance and speed of an object
y=[4, 6, 10, 12, 18, 27]
def least_square_fitting():

    xi=[]# create an empty array

    sx, sy, sxx, sxy, s, st=0, 0, 0, 0, 0, 0
    for i in range(n):
        sx +=x[i]
        sxx += x[i]*x[i]
        sy += y[i]
        sxy += x[i]*y[i]

    a = (n*sxy - sx*sy)/(n*sxx - sx*sx)# comes from y=a*x + b fit line
    b = (sxx*sy - sx*sxy)/(n*sxx - sx*sx)
    for i in range(0, n):
        s += pow((y[i] - a*x[i])-b, 2)#square sum
        st += pow(y[i] - (sx/n), 2)
    for i in range(n):
        xii=b + a*x[i]
        xi.append(xii)
    r2=(st-s)/st#r square

    print("coeff1:", a,"coeff2:", b, "square sum:",  s, "r square:", r2 )
    plt.plot(x, y, '.')
    plt.plot(x, xi, '-')
    plt.show()


from johansen_test import coint_johansen
import pandas as pd
import matplotlib.pyplot as plt
from functions import *
from numpy.matlib import repmat
import numpy as np

# Implementation of the second part of example 3.1 in Ernest Chang's
# book Algorithmic trading : winning strategies and their rationale.
#
# log (Price) Spread

if __name__ == "__main__":

    #import data from CSV file
    root_path = '/Users/Javi/Documents/MarketData/'
    # the paths
    # MAC: '/Users/Javi/Documents/MarketData/'
    # WIN: 'C:/Users/javgar119/Documents/Python/Data/'
    filename = 'GLD_USO_daily.csv'
    full_path = root_path + filename
    data = pd.read_csv(full_path, index_col='Date')
    lookback = 20
    data = data[lookback-1:]
    y_ticket = 'USO'
    x_ticket = 'GLD'

    y = data[y_ticket]
    x = data[x_ticket]

    # ratio USO/GLD
    ratio = y/x
    # lookback period for calculating the dynamically changing

    # remove some data to have the same dataset

    moving_mean = pd.rolling_mean(ratio, window=lookback)
    moving_std = pd.rolling_std(ratio, window=lookback)
    # calculate the number of units for the strategy in the form

    # the number of units of the syntetic portfolio is given by the
    # negative value of z-score
    numunits = pd.DataFrame(-(ratio - moving_mean) / moving_std)

    # compute the $ position for each asset
    AA = repmat(numunits,1,2)
    BB = repmat([-1,1],len(numunits),1)
    position = multiply(data, multiply(AA,BB))

    # compute the daily pnl in $$
    pnl = sum((multiply(position[:-1], divide(diff(data,axis = 0), data[:-1]))),1)

    # gross market value of portfolio
    mrk_val = pd.DataFrame.sum(abs(position), axis=1)
    mrk_val = mrk_val[lookback-1:-1]

    # return is P&L divided by gross market value of portfolio
    rtn = pnl / mrk_val

    # compute performance statistics
    sharpe = (np.sqrt(252)*np.mean(rtn)) / np.std(rtn)
    APR = np.prod(1+rtn)**(252/len(rtn))-1

    ##################################################
    # print the results
    ##################################################
    print('Price spread Sharpe: {:.4}'.format(sharpe))
    print('Price Spread APR: {:.4%}'.format(APR))

    #*************************************************
    # plotting the chart
    #*************************************************
    #plot of numunits
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.plot(cumsum(rtn))
    ax.set_title('{}-{} Price Ratio Acum Return'.format(x_ticket, y_ticket))
    ax.set_xlabel('Data points')
    ax.set_ylabel('acumm rtn')
    ax.text(1000, 0, 'Sharpe: {:.4}'.format(sharpe))
    ax.text(1000, -0.06, 'APR: {:.4%}'.format(APR))

    plt.show()