import numpy as np
from numpy import *
import matplotlib.pyplot as plt
import math as m
from matplotlib.pyplot import figure, show

## we arue using the cholesky method to solve Ax=b

def facto_dense(A, n):
    T = np.zeros(shape=(n,n))
    for i in range(n):
        for k in range(i+1):
            tmp_sum = sum(np.fromiter((T[i][j] * T[k][j] for j in range(k)),float))

            if (i == k):
                T[i][k] = np.sqrt(A[i][i] - tmp_sum)
            else:
                T[i][k] = (A[i][k] - tmp_sum)/(T[k][k])
    return T

## finding Y in the method

def descente(T,n,B):
    Y = np.zeros(shape=(n, 1))
    Y[0]= B[0]/T[0][0]
    for i in range(1,n):
        s = 0
        for j in range(i):
            s += T[i][j]*Y[j]
        Y[i] = (B[i] - s)/T[i][i]
    return Y

## finding X in the method

def remontee(T,n,Y):
    X = np.zeros(shape=(n, 1))
    X[n-1] = Y[n-1]/T[n-1][n-1]
    for i in range(n-2,-1,-1):
        s = 0
        for j in range(i+1,n):
            s += T[i][j] * X[j]
        X[i] = (Y[i] -s)/T[i][i]
    return X

#final resolution of Ax=b

def resolution_cholesky(A,B,n):
    T = facto_dense(-A,n**2)
    Y = descente(T,n**2,-B)
    X = remontee(T.T, n**2, Y)
    return X

# second method reolution with gradient

def conjgrad(A, b,N):
    x=np.zeros(shape=(N**2,1))
    r=b-np.dot(A,x)
    p=r
    rsold=np.dot((np.conj(r).T),r)[0][0]

    for i in range(1, 10**6):
        Ap=np.dot(A,p)
        alpha=rsold/(np.dot(np.conj(p).T,Ap)[0][0])
        x=x+np.dot(alpha,p)
        r=r-np.dot(alpha,Ap)
        rsnew=np.dot((np.conj(r).T),r)[0][0]
        if np.sqrt(rsnew) < 10**(-10):
            break
        p=r+(rsnew/rsold)*p
        rsold=rsnew
    return x

# generate the derivative operator matrix

def generermatA(N):

    Matrix = np.zeros(shape=(N**2,N**2))
    for i in range(N**2):
        Matrix[i][i] = -4
        for j in range(N**2):
            if (j == i+1 and j%N != 0):
                Matrix[i][j] = 1
            if (i == j+1 and j%N != N-1):
                Matrix[i][j] = 1
            if (j == i+N):
                Matrix[i][j] = 1
            if (i == j+N):
                Matrix[i][j] = 1

    return Matrix

#generate f(x,y) <=> B

def genererB(f,N):
    B = np.zeros(shape=(N**2, 1))
    for i in range(N):
        for j in range(N):
            B[i*N+j] = f(i,j,N)
    return B
#function for center radiator

def radiateur_centre(i,j,N):
    if (i > N/2-5 and i < N/2+5 and j > N/2-5 and j < N/2+5):
        return -25
    return 0
#function tjat generate a north wall

def mur_nord(i,j,N):
    if (i > N-2):
        return -25
    return 0
#generate solotion according to the methode chosen

def gen_x(N, fonction, methode):
    A = generermatA(N)
    B = genererB(fonction,N)
    if (methode == "numpy"):
        x = np.linalg.solve(A,B)
    if (methode == "gradient"):
        x = conjgrad(A,B,N)
    if (methode == "cholesky"):
        x = resolution_cholesky(A,B,N)
    return x

#tranform a vector into a matrix

def vect_to_mat(x,N):
    T = np.zeros(shape=(N,N))
    for i in range(N):
        for j in range(N):
            T[i][j] = x[i*N+j][0]
    return T

def Eqchaleur(fonction, N, methode):
    return vect_to_mat(gen_x(N, fonction, methode), N)

def afficher(fonction, N, p, methode):
    fig=figure()
    pc = plt.pcolormesh(Eqchaleur(fonction, N, methode), cmap='hot' , shading='bilinear')
    fig.colorbar(pc)
    plt.xticks([x for x in range(0,N-1,int(N/10))]+[N-1], [i/10 for i in range(10)]+[1.0])
    plt.yticks([x for x in range(0,N-1,int(N/10))]+[N-1], [i/10 for i in range(10)]+[1.0])

    plt.show()

#afficher(mur_nord, 80, 0, "gradient" )
#afficher(radiateur_centre,80,1, "gradient")
#afficher(radiateur_centre, 40, 1, "cholesky" )

def calculer_ec_rel(fonction, N, methode):

    norme_numpy = np.linalg.norm(Eqchaleur(fonction, N, "numpy"))
    norme_fonction = np.linalg.norm(Eqchaleur(fonction, N, methode))

    ecart = abs(norme_fonction - norme_numpy)/norme_numpy

    return ecart


import numpy as np
import copy
import scipy
import scipy.linalg
import sys

def CalcularMatrices(n = 4): #intentar con n = 2,3,4,5 y ver que onda
    A = [[(i + j)**2 for i in range (1,n+1)] for j in range (1, n+1)]
    B = [0 for _ in range (n) ]
    bi = 0
    for i in range(0,n):
        for j in range (0,n-1):
            bi += A[i][j]
            print(bi)
        B[i] = bi
        bi = 0

    return A, B

def swap(v,i,j):
    if len(v.shape) == 1:
        v[i],v[j] = v[j],v[i]
    else:
        temp = copy.deepcopy(v[i])
        v[i] = v[j]
        v[j] = temp
    return v

def gaussPivoteo(a,b, tol = 1.0e-12):
    L = [[0 for i in range(len(a))]for j in range(len(a))] #inicializar matriz de ceros para la trinagular inferior

    n = len(b)

    s = np.zeros(n)
    for i in range(n):
        s[i] = max(abs(a[i,:]))

    # permutaciones
    vp = np.array(range(n))

    for k in range(0,n-1):
        p = np.argmax(abs(a[k:n , k])/s[k:n]) + k
        if abs(a[p,k]) < tol:
            print(f"La matriz es una matrix singular :c")
            input("Presione una tecla para salir")
            sys.exit()

        if p != k:
            swap(a,k,p)
            swap(b,k,p)
            swap(s,k,p)
            swap(vp,k,p)
            print(f"Intercambie {k} y {p}")

# Eliminación
        for i in range(k+1,n): # renglones
                lam = a[i,k]/a[k,k]
                L[i][k] = lam
                a[i,k:n] = a[i,k:n] - lam*a[k,k:n]
                b[i] = b[i] - lam*b[k]

    if abs(a[n-1,n-1]) < tol:
        print(f"Matrix singular :c")
        input("Oprime un tecla para continuar")
        sys.exit()

    # Sustitución regresiva
    for i in range(n-1,-1,-1):
        b[i] = (b[i] - np.dot(a[i,i+1:n],b[i+1:n]))/a[i,i]
    return b, vp

def Imprime(M):
    for l in M:
        print(l)
    print("\n")

if __name__ == "__main__":
    a  = np.array([[3.,-13., 9., 3.],[-6., 4., 1., -18.],[6., -2., 2., 4.],[12., -8., 6, 10.]])
    b  = np.array([-19., -34., 16., 26.])[np.newaxis]
    # a = np.array([[0.143, 0.357, 2.01],[-1.31, 0.911, 1.99],[11.2, -4.30, -0.605]])
    # b = np.array([-5.17, -5.46, 4.42])[np.newaxis]
    # a = np.array([[4,1,2,-3,5], [-3,3,-1,4,-2], [-1,2,5,1,3], [5,4,3,-1,2],[1,-2,3,-4,5.]])
    a_copy = copy.deepcopy(a)

    # b = np.array ([-16, 20, -4, -10, 3.])[np.newaxis]
    b = b.T
    b_copy = copy.deepcopy(b)

    L = []

    x, a = gaussPivoteo(a,b)

    print (f"El vertor de permutaciones es: \n")
    Imprime(a)

    print ("El vector b original", "\n",b_copy)
    print(f"\n")
    print("La solucion al sistema: ","\n", x, "\n")

    print(f"Ax = b {np.dot(a_copy,x)} \n")
    print (f"la comprobacion del sistema es: \n {np.linalg.solve(a_copy,b_copy)}")


import numpy as np
from fractions import Fraction
from kerala_math.jyatable import MST

_k = [0 for i in range(24)]
_b = [0 for i in range(24)]

# First two accurate jyas
_b[0] = MST(224, 50, 22)
_b[1] = MST(448, 42, 58)

# tattajya recurrence
for i in range(2,24):
    _b[i] = ((_b[i-1])**2 - (_b[0])**2)/_b[i-2]

# Pindajyas
_k[0] = _b[0]
for i in range(1,24):
    _k[i] = _b[i] - _b[i-1]

def khandajya(k: int):
    """
    Return the kth khandajya computed by the tattajya recurrence

    Inputs:
      k (int) : index from 0 to 23
    Outputs:
      int : kth khandajya
    """
    assert ((k>=0) & (k<24)), f"Input must be between 0 and 23 inclusive, got {k}"
    return _k[k]

def pindajya(k: int):
    """
    Return the kth pindajya computed by the tattajya recurrence

    Inputs:
      k (int) : index from 0 to 23
    Outputs:
      int : kth pindajya
    """
    assert ((k>=0) & (k<24)), f"Input must be between 0 and 23 inclusive, got {k}"
    return _b[k]


import numpy as np
from distributionLib import Dist

binom = Dist.binomialDist
xBar = Dist.expt
var = Dist.var
coolPrint = Dist.coolPrint

# test-1
#A fair coin tossed 6 times. The probability of head coming is as follow
print('test-1')
n   = 6
p   = 0.5
P   = binom(n,p,plot=True)
coolPrint(P)
print('-'*80)

'''
test-2
https://www.statisticshowto.com/probability-and-statistics/binomial-theorem/binomial-distribution-formula/
Example-3
60% of people who purchase sports cars are men.  If 10 sports car owners are randomly
selected, find the probability that exactly 7 are men.
'''
print('test-2')
n = 10
p = 0.6
k = 7
prob = binom(10,0.6,7)
print('Answer = {}'.format(prob))

P = binom(10,0.6,plot=True)
coolPrint(P)

print('-'*80)


import numpy as np
import matplotlib.pyplot as plt

def get_points():
    x_start = float(input())
    x = list(map(float, input().split()))
    y = list(map(float, input().split()))

    return x_start, x, y

def find_good_range_idx(x_start, x):
    k = 0
    for i, j in zip(x, x[1:]):
        if i <= x_start <= j:
            break
        k += 1

    return k

def calc_first_deriv(x, y, x_start):
    good_idx = find_good_range_idx(x_start, x)

    num1 = (y[good_idx + 1] - y[good_idx]) / (x[good_idx + 1] - x[good_idx])
    num2 = (y[good_idx + 2] - y[good_idx + 1]) / (x[good_idx + 2] - x[good_idx + 1]) - num1
    num2 = num2 / (x[good_idx + 2] - x[good_idx])

    return num1 + num2 * (2 * x_start - x[good_idx] - x[good_idx + 1])

def calc_second_deriv(x, y, x_start):
    good_idx = find_good_range_idx(x_start, x)
    num1 = (y[good_idx + 2] - y[good_idx + 1]) / (x[good_idx + 2] - x[good_idx + 1])
    num2 = (y[good_idx + 1] - y[good_idx]) / (x[good_idx + 1] - x[good_idx])

    return 2 * (num1 - num2) / (x[good_idx + 2] - x[good_idx])

def main():
    x_start, x, y = get_points()

    first_der = calc_first_deriv(x, y, x_start)
    second_der = calc_second_deriv(x, y, x_start)

    print(f'y\'(x) = {first_der}')
    print(f'y\"(x) = {second_der}')

main()


#!/usr/bin/python

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

def main():
    args = sys.argv
    a, b = args[1], args[2]
    t = integra_mc(func, 0, 5.5)
    print(t)

def func (x) :
    return -(x**2)+ 5*x + 5

#version numpy
def integra_mc(func, a, b, num_puntos = 100):
    puntos = np.linspace(a,b,num_puntos)
    m = max(func(puntos))
    fxpuntos = func(puntos)
    ypuntos = np.random.uniform(0, m, [num_puntos])
    menores = ypuntos < fxpuntos
    por_debajo = sum(menores)
    plt.plot(puntos, func(puntos), label="function")
    plt.plot(puntos,ypuntos,ls = 'None', marker = 'x', c = 'r', label="rand generated numbers")
    plt.legend(loc='upper left')
    ax = plt.gca() # gca stands for 'get current axis'
    ax.spines['right'].set_color('none')
    ax.spines['top'].set_color('none')
    ax.xaxis.set_ticks_position('bottom')
    ax.spines['bottom'].set_position(('data',0))
    ax.yaxis.set_ticks_position('left')
    ax.spines['left'].set_position(('data',0))
    plt.show()
    return (por_debajo / num_puntos)*(b-a)*m

#-----------------------------------------funciones añadidas--------------------------------------------#

def main1():
    args = sys.argv
    a, b = args[1], args[2]
    t = integra_mc1(func, 0, 5.5)
    print(t)

def main2():
    from scipy import integrate
    x2 = lambda x: func (x)
    t = integrate.quad(x2, 0, 5.5)
    print(t)

#version iterativa
def integra_mc1(func, a, b, num_puntos = 1000000):

    punto_f = func(a)
    por_debajo = 0

    for num in range(num_puntos):
        aux = a + (b-a)*num/num_puntos
        aux_f = func(aux)

        if aux_f > punto_f:
            punto_f = aux_f

    for num in range(num_puntos):
        fx = func(random.randrange(a,int(b)))
        y = random.randrange(int(punto_f))

        if y < fx:
            por_debajo = por_debajo + 1

    return (por_debajo / num_puntos)*(b-a)*punto_f

main() # 379 µs ± 12.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

main1() # 2 s ± 4.79 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

main2() # 10.7 µs ± 22.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)


#import skfuzzy
import numpy as np
from math import pi
from scipy.special import erf
import matplotlib.pylab as plt

##______________________S-shaped transfer functions_______________________

def s1(x):

    s1=1 / (1 + np.exp(-2*x))

    return s1

def s2(x):
    s2 = 1 / (1 + np.exp(-x))
    return s2
# s2 is called logistic function and can be imported using scipy.special.expit(x) library

def s3(x):
    s3=1 / (1 + np.exp(-x/3))
    return s3

def s4(x):
    s4=1 / (1 + np.exp(-x/2))
    return s4

x = np.arange(-8, 8, 0.1)
# x is used inside this script and will be replaced by a binary individual (1-d binary vector)
#when the transfer function is called or imported in the optimizers scripts

#____________


#!/usr/bin/env python
import numpy as np

#!/usr/bin/env python
def slopes(x,y):
  """
  SLOPES calculate the slope y'(x) Given data vectors X and Y SLOPES
  calculates Y'(X), i.e the slope of a curve Y(X). The slope is
  estimated using the slope obtained from that of a parabola through
  any three consecutive points.
  This method should be superior to that described in the appendix
  of A CONSISTENTLY WELL BEHAVED METHOD OF INTERPOLATION by Russel
  W. Stineman (Creative Computing July 1980) in at least one aspect:
  Circles for interpolation demand a known aspect ratio between x-
  and y-values.  For many functions, however, the abscissa are given
  in different dimensions, so an aspect ratio is completely
  arbitrary.

  The parabola method gives very similar results to the circle
  method for most regular cases but behaves much better in special
  cases
  Norbert Nemec, Institute of Theoretical Physics, University or
  Regensburg, April 2006 Norbert.Nemec at physik.uni-regensburg.de
  (inspired by a original implementation by Halldor Bjornsson,
  Icelandic Meteorological Office, March 2006 halldor at vedur.is)
  """
  x=np.asarray(x, np.float64)
  y=np.asarray(y, np.float64)

  yp=np.zeros(y.shape, np.float64)

  dx=x[1:] - x[:-1]
  dy=y[1:] - y[:-1]
  dydx = dy/dx
  yp[1:-1] = (dydx[:-1] * dx[1:] + dydx[1:] * dx[:-1])/(dx[1:] + dx[:-1])
  yp[0] = 2.0 * dy[0]/dx[0] - yp[1]
  yp[-1] = 2.0 * dy[-1]/dx[-1] - yp[-2]
  return yp

def stineman_interp(xi,x,y,yp=None):
  """
  STINEMAN_INTERP Well behaved data interpolation.  Given data
  vectors X and Y, the slope vector YP and a new abscissa vector XI
  the function stineman_interp(xi,x,y,yp) uses Stineman
  interpolation to calculate a vector YI corresponding to XI.
  Here's an example that generates a coarse sine curve, then
  interpolates over a finer abscissa:
    x = linspace(0,2*pi,20);  y = sin(x); yp = cos(x)
    xi = linspace(0,2*pi,40);
    yi = stineman_interp(xi,x,y,yp);
    plot(x,y,'o',xi,yi)
  The interpolation method is described in the article A
  CONSISTENTLY WELL BEHAVED METHOD OF INTERPOLATION by Russell
  W. Stineman. The article appeared in the July 1980 issue of
  Creative computing with a note from the editor stating that while
  they were
    not an academic journal but once in a while something serious
    and original comes in adding that this was
    "apparently a real solution" to a well known problem.

  For yp=None, the routine automatically determines the slopes using
  the "slopes" routine.
  X is assumed to be sorted in increasing order
  For values xi[j] < x[0] or xi[j] > x[-1], the routine tries a
  extrapolation.  The relevance of the data obtained from this, of
  course, questionable...
  original implementation by Halldor Bjornsson, Icelandic
  Meteorolocial Office, March 2006 halldor at vedur.is
  completely reworked and optimized for Python by Norbert Nemec,
  Institute of Theoretical Physics, University or Regensburg, April
  2006 Norbert.Nemec at physik.uni-regensburg.de
  """
  # Cast key variables as float.
  x=np.asarray(x, np.float64)
  y=np.asarray(y, np.float64)
  assert x.shape == y.shape
  N=len(y)

  if yp is None:
      yp = slopes(x,y)
  else:
      yp=np.asarray(yp, np.float64)

  xi=np.asarray(xi, np.float64)
  yi=np.zeros(xi.shape, np.float64)

  # calculate linear slopes
  dx = x[1:] - x[:-1]
  dy = y[1:] - y[:-1]
  s = dy/dx  #note length of s is N-1 so last element is #N-2

  # find the segment each xi is in
  # this line actually is the key to the efficiency of this implementation
  idx = np.searchsorted(x[1:-1], xi)

  # now we have generally: x[idx[j]] <= xi[j] <= x[idx[j]+1]
  # except at the boundaries, where it may be that xi[j] < x[0] or xi[j] > x[-1]

  # the y-values that would come out from a linear interpolation:
  sidx = np.take(s, idx)
  xidx = np.take(x, idx)
  yidx = np.take(y, idx)
  xidxp1 = np.take(x, idx+1)
  yo = yidx + sidx * (xi - xidx)

  # the difference that comes when using the slopes given in yp
  dy1 = (np.take(yp, idx)- sidx) * (xi - xidx)       # using the yp slope of the left point
  dy2 = (np.take(yp, idx+1)-sidx) * (xi - xidxp1) # using the yp slope of the right point

  dy1dy2 = dy1*dy2
  # The following is optimized for Python. The solution actually
  # does more calculations than necessary but exploiting the power
  # of numpy, this is far more efficient than coding a loop by hand
  # in Python
  yi = yo + dy1dy2 * np.choose(np.array(np.sign(dy1dy2), np.int32)+1,
                               ((2*xi-xidx-xidxp1)/((dy1-dy2)*(xidxp1-xidx)),
                                0.0,
                                1/(dy1+dy2),))

  return yi


from math import factorial
import numpy as np

def _poch(d, n):
    """
    Returns
    -------
    d * (d - 1) * (d - 2) * ... * (d - n + 1) : float
    """
    return np.prod([d - k for k in range(n)])

def get_coefs(d, n_terms):
    """
    Compute coefficients of fracdiff operator explicitly (but inefficiently)
    and return the sequence of them as `numpy.array`.

    Parameters
    ----------
    - d : float
        Order of fracdiff.
    - n_terms : int
        Number of coefficients to compute.
    """
    return np.array([
        (-1) ** k * _poch(d, k) / factorial(k) for k in range(n_terms)
    ])


import math
import numpy as np

# DCG
def dcg(r, k=None):
    """The Burges et al. (2005) version of DCG.

    This is what everyone uses (except trec_eval)
    :param r: results
    :param k: cut-off
    :return: sum (2^ y_i - 1) / log (i +2)
    """
    result = sum([(pow(2, rel) - 1) / math.log(rank + 2, 2) for rank, rel in enumerate(r[:k])])
    return result

def dcg_trec(r, k=None):
    """The `trec_eval` version of DCG

    :param r: results
    :param k: cut-off
    :return: sum rel_i / log(i + 2)
    """
    result = sum([rel / math.log(rank + 2, 2) for rank, rel in enumerate(r[:k])])
    return result

# nDCG
def ndcg(x, k=None, dcg=dcg):
    """
    Args:
        k: cutoff
        dcg_func: set to `dcg` or `dcg_trec`
    """
    ideal = dcg(sorted(x, reverse=True), k)
    if ideal == 0:
        return 0
    result = dcg(x, k) / ideal
    return result

def err(x, k, g_max):
    res = 0
    p = 1
    norm = pow(2, g_max)
    for i, g in enumerate(x[:k], 1):
        R = float(pow(2, g) - 1) / norm
        res += p * R / i
        p *= (1 - R)
    return res

def patk(labels, k):
    """We assume an array with 0's and 1's
        If there are no relevant documents (all zeroes) will return zero
    """
    return (0. + np.sum(labels[0:k])) / k

def mean_ap(labels, k=None, n_rel=None):
    """We assume an array with 0's and 1's
        If there are no relevant documents (all zeroes) will return zero
    """
    if n_rel is None:
        n_rel = np.sum(labels[0:k])
    if n_rel == 0:
        return 0

    idx = np.nonzero(labels[0:k])[0]
    score = np.sum((np.arange(idx.size) + 1.0) / (idx + 1.0))
    return score / n_rel

def print_trec_eval(groups):
    resfile = open('run.res', 'w')
    relfile = open('run.rel', 'w')

    qid = 0
    for s, l in groups:
        qid += 1
        new_l = [x for (y, x) in sorted(zip(s, l), key=lambda pair: pair[0], reverse=True)]
        new_s = sorted(s, reverse=True)
        for j in range(len(new_s)):
            resfile.write("Q%i Q0 Q%iD%i %i %f RUN\n" % (qid, qid, j+1, j+1, new_s[j]))
            relfile.write("Q%i 0 Q%iD%i %i\n" % (qid, qid, j+1, new_l[j]))
    relfile.close()
    resfile.close()

def ndcg_one(scores, labels):
    a = [x for (y, x) in sorted(zip(scores, labels), key=lambda pair: pair[0], reverse=True)]
    return ndcg(a, len(a))

def test_ndcg(scores, labels, query_ids, average=True):
    labels = np.maximum(labels, 0)
    groups, _ = group_per_query(scores, labels, query_ids)
    ndcg_scores = []
    for s, l in groups:
        idx = np.argsort(s)
        a = l[idx[::-1]]
        ndcg_scores.append(ndcg(a, len(a)))
    if average:
        return sum(ndcg_scores) / len(ndcg_scores)
    else:
        return ndcg_scores

def test_map(scores, labels, query_ids, average=True):
    labels = np.maximum(labels, 0)
    groups, _ = group_per_query(scores, labels, query_ids)
    map_scores = []
    for s, l in groups:
        idx = np.argsort(s)
        a = l[idx[::-1]]
        binary = [int(v > 0) for v in a]
        map_scores.append(mean_ap(binary))
    if average:
        return sum(map_scores) / len(map_scores)
    else:
        return map_scores

def group_per_query(pred, y, query_groups):
    # offsets, qids = group_offsets(query_groups, return_values=True)
    # return [(pred[a:b], y[a:b]) for a, b in offsets], qids

    qid = query_groups[0]
    ly = list()
    lpred = list()
    groups = list()
    unique_ids = [qid]

    for i in range(len(query_groups)):
        if qid != query_groups[i]:  # new query
            yarray = np.array(ly)
            predarray = np.array(lpred)
            groups.append((predarray, yarray))
            qid = query_groups[i]
            unique_ids.append(qid)
            ly = list()
            lpred = list()
        lpred.append(pred[i])
        ly.append(y[i])
    #groups.append((predarray, yarray))
    groups.append((np.array(lpred), np.array(ly)))
    return groups, unique_ids

def test_all(scores, labels, query_ids, rel=0, relcount={}, average=True):
    from collections import defaultdict
    max_grade = int(np.max(labels))
    labels = np.maximum(labels, 0)
    groups, qids = group_per_query(scores, labels, query_ids)
    # metrics = {"map": 0, "ndcg@5": 0, "ndcg@10": 0, "ndcg@20": 0, "dcg@5": 0, "dcg@10": 0,
    #            "dcg@20": 0, "err": 0,
    #            "p@1": 0, "p@2": 0, "p@5": 0, "p@10": 0, "p@20": 0, "dcg": 0, "ndcg": 0}

    if average:
        metrics = defaultdict(float)
    else:
        metrics = {k: [] for k in ('p@1', 'p@2', 'p@5', 'p@10', 'p@20', 'err@5', 'err@10', 'err@20',
                                   'dcg@5', 'dcg@10', 'dcg@20', 'ndcg@5', 'ndcg@10', 'ndcg@20',
                                   'map', 'err', 'dcg', 'ndcg')}

    # for (s, l) in groups:
    #     # sorts x using y as a key
    #     # a = [x for (y, x) in sorted(zip(s, l), key=lambda pair: pair[0], reverse=True)]
    #     idx = np.argsort(s)
    #     a = l[idx[::-1]]
    #     # print("scores %s labels %s array %s" %(s,l,a))
    #     # binary = map(lambda x: 1 if x > rel  else  0, a)
    #     binary = [int(v > 0) for v in a]

        # shallow metrics
    if average:
        for (s, l), qid in zip(groups, qids):
            idx = np.argsort(s)
            a = l[idx[::-1]]
            binary = [int(v > 0) for v in a]

            metrics["p@1"] += patk(binary, 1)
            metrics["p@2"] += patk(binary, 2)
            metrics["p@5"] += patk(binary, 5)
            metrics["p@10"] += patk(binary, 10)
            metrics["p@20"] += patk(binary, 20)
            metrics["err@5"] += err(a, 5, max_grade)
            metrics["err@10"] += err(a, 10, max_grade)
            metrics["err@20"] += err(a, 20, max_grade)
            metrics["dcg@5"] += dcg(a, 5)
            metrics["dcg@10"] += dcg(a, 10)
            metrics["dcg@20"] += dcg(a, 20)
            metrics["ndcg@5"] += ndcg(a, 5)
            metrics["ndcg@10"] += ndcg(a, 10)
            metrics["ndcg@20"] += ndcg(a, 20)

            # deep metrics
            metrics["map"] += mean_ap(binary, n_rel=relcount.get(qid, None))
            metrics["err"] += err(a, None, max_grade)
            metrics["dcg"] += dcg(a)
            metrics["ndcg"] += ndcg(a)

        for k in metrics.keys():
            metrics[k] /= len(groups) + 0.
        return metrics
    else:
        for (s, l), qid in zip(groups, qids):
            idx = np.argsort(s)
            a = l[idx[::-1]]
            binary = [int(v > 0) for v in a]

            metrics["p@1"].append(patk(binary, 1))
            metrics["p@2"].append(patk(binary, 2))
            metrics["p@5"].append(patk(binary, 5))
            metrics["p@10"].append(patk(binary, 10))
            metrics["p@20"].append(patk(binary, 20))
            metrics["err@5"].append(err(a, 5, max_grade))
            metrics["err@10"].append(err(a, 10, max_grade))
            metrics["err@20"].append(err(a, 20, max_grade))
            metrics["dcg@5"].append(dcg(a, 5))
            metrics["dcg@10"].append(dcg(a, 10))
            metrics["dcg@20"].append(dcg(a, 20))
            metrics["ndcg@5"].append(ndcg(a, 5))
            metrics["ndcg@10"].append(ndcg(a, 10))
            metrics["ndcg@20"].append(ndcg(a, 20))

            # deep metrics
            metrics["map"].append(mean_ap(binary, n_rel=relcount.get(qid, None)))
            metrics["err"].append(err(a, None, max_grade))
            metrics["dcg"].append(dcg(a))
            metrics["ndcg"].append(ndcg(a))

        return metrics


import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize
from scipy.special import erf

# gelu/swish/softplus 对 relu 的光滑逼近

def psi(x):
    return 0.5 * (1 + erf(x / np.sqrt(2)))

def swish(x, a=1.1702):
    return x / (1 + np.exp(-a * x))

def relu(x):
    return np.maximum(x, 0.0)

def gelu(x):
    return 0.5 * x * (1 + erf(x / np.sqrt(2)))

def softplus(x, a=3):
    return 1 / a * np.log(1 + np.exp(a * x))

def plot_activations():
    x = np.linspace(-4, 4, 1000)
    plt.plot(x, psi(x), label="psi(x)")
    plt.plot(x, relu(x), label="relu")
    plt.plot(x, swish(x), label="swish")
    plt.plot(x, gelu(x), label="gelu")
    plt.plot(x, softplus(x), label="softplus")
    plt.legend(loc="upper right")
    plt.show()

def swish_psi_err(a):
    x = np.arange(0, 5, 0.001)
    e = np.abs(swish(x, a) - psi(x) * x)
    return np.max(e)

# 计算 swish 的参数 a
options = {"xtol": 1e-10, "ftol": 1e-10, "maxiter": 100000}
result = minimize(swish_psi_err, 0, method="Powell", options=options)
print(result.x)

if __name__ == "__main__":
    plot_activations()


import matplotlib.pyplot as plt
import numpy as np

from numpy.random import default_rng
rng = default_rng(12345)

rate = 4.0
inter_arrival_times = rng.exponential(scale=1./rate, size=50)

arrivals = np.add.accumulate(inter_arrival_times)
count = np.arange(50)

fig1, ax1 = plt.subplots()

ax1.step(arrivals, count, where="post")
ax1.set_xlabel("Time")
ax1.set_ylabel("Number of arrivals")
ax1.set_title("Arrivals over time")

from scipy.special import factorial
N = np.arange(15)
def probability(events, time=1, param=rate):
    return ((param*time)**events/factorial(events))*np.exp(-param*time)

fig2, ax2 = plt.subplots()
ax2.plot(N, probability(N), "k", label="True distribution")
ax2.set_xlabel("Number of arrivals in 1 time unit")
ax2.set_ylabel("Probability")
ax2.set_title("Probability distribution")

estimated_scale = np.mean(inter_arrival_times)
estimated_rate = 1.0/estimated_scale

ax2.plot(N, probability(N, param=estimated_rate), "k--", label="Estimated distribution")
ax2.legend()

plt.show()


import numpy as np
import matplotlib.pyplot as plt

# System Parameters
x_init = 0
xDot_init = 0

mass = 5
damp = 10
spring = 50

omega = 2
forceMagnit = 1

timeStart = 0
timeStop = 10
stepTime = 0.001
time = np.arange(timeStart, timeStop, stepTime, dtype = float)

# Initial Condition
y = np.array([[x_init], [xDot_init]], dtype = float)

# Reserve data
totalData = np.size(time)
position = np.zeros(totalData, dtype = float)
velocity = np.zeros(totalData, dtype = float)
acceleration = np.zeros(totalData, dtype = float)

positionRK = np.zeros(totalData, dtype = float)
velocityRK = np.zeros(totalData, dtype = float)
accelerationRK = np.zeros(totalData, dtype = float)

#Euler Method
systemFunction = lambda t, y: (forceMagnit*np.sin(omega*t)-damp*float(y[1])-spring*float(y[0]))/mass
#
for i in range(totalData):
    eulerMeth = systemFunction(time[i], y)
    y = y + stepTime*np.array([y[1], [eulerMeth]], dtype = float)

    position[i] = (y[0])
    velocity[i] = (y[1])
    acceleration[i] = eulerMeth

#Runge Kutta 4-5
#systemFunction = lambda t, y: (forceMagnit*np.sin(omega*t)-damp*float(y[1])-spring*float(y[0]))/mass
y = np.array([[x_init], [xDot_init]], dtype = float)

for i in range(totalData):
    t1 = time[i]
    f_1 = systemFunction(t1, y)
    k1 = np.array([y[1], [f_1]], dtype = float)

    t2 = time[i]+0.5*stepTime
    y2 = y + 0.5*k1*stepTime
    f_2 = systemFunction(t2, y2)
    k2 = np.array([y2[1], [f_2]], dtype = float)

    t3 = time[i]+0.5*stepTime
    y3 = y + 0.5*k2*stepTime
    f_3 = systemFunction(t3, y3)
    k3 = np.array([y3[1], [f_3]], dtype = float)

    t4 = time[i]+stepTime
    y4 = y + k3*stepTime
    f_4 = systemFunction(t4, y4)
    k4 = np.array([y4[1], [f_4]], dtype = float)

    RKFunct = (k1 + 2*k2 + 2*k3 + k4)/6
    y = y + stepTime*RKFunct

    positionRK[i] = (y[0])
    velocityRK[i] = (y[1])
    accelerationRK[i] = RKFunct[1]

plt.figure(1)
plt.plot(time, position)
plt.plot(time, positionRK)
title = "position plot [step time = %1.6f s]" % stepTime
plt.title(title)
plt.ylabel('displacement [m]')
plt.xlabel('time [s]')
plt.grid(True)
plt.legend(["euler", "RK"])

plt.figure(2)
plt.plot(time, velocity)
plt.plot(time, velocityRK)
title = "velocity plot [step time = %1.6f s]" % stepTime
plt.title(title)
plt.ylabel('velocity [m/s]')
plt.xlabel('time [s]')
plt.grid(True)
plt.legend(["euler", "RK"])

plt.figure(3)
plt.plot(time, acceleration)
plt.plot(time, accelerationRK)
title = "Accleration plot [step time = %1.6f s]" % stepTime
plt.title(title)
plt.ylabel('Acceleration [m/s/s]')
plt.xlabel('time [s]')
plt.grid(True)
plt.legend(["euler", "RK"])
plt.show()


# !/usr/bin/python

__author__ = 'fjanoos'

from optparse import OptionParser
from pylab import *
from numpy import linalg

# acceptable error
eps = 1e-4  #finfo(float).eps

def test_model( num_list, verb_flg):
	lhs_matrix =  matrix( [num_list[:-1], [double(1) for x in num_list[:-1]] ] ).transpose();

	rhs_matrix = matrix( num_list[1:]).transpose();

	# do a least squares solve
	coeffs = linalg.solve( lhs_matrix.transpose()*lhs_matrix, lhs_matrix.transpose()*rhs_matrix)

	if coeffs[0] > 1 and verb_flg:
		print( 'warning: This is not a well conditioned recursion (K > 1) -- might fail giving a result.' )

	# compute residuals
	r = rhs_matrix - lhs_matrix*coeffs

	sse = ( r.transpose()*r ) / len(r)

	if  verb_flg:
		print ( coeffs, sse)

	if sse < eps :
		return coeffs
	else:
		return None

if __name__ == "__main__":
	usage = \
		'''  %prog [options] [0,1] num_1 ... num_n
				   Prints K,L for a_i = K a_{i-1} + L ''';
	option_parser = OptionParser( usage )
	option_parser.add_option( "-v", "--verbose", action = "store_true", dest = "verbose", default = False );
	(options, args) = option_parser.parse_args( )

	verb_flg = options.verbose;

	if len( args ) <= 1 or (int(args[0]) !=1 and int(args[0]) !=2 ):
		option_parser.error( "incorrect arguments" )
		option_parser.print_help( )
		sys.exit( )

	type = int(args[0])
	num_list = [];
	for ii in range( 1, len( args ) ):
		num_list.append( double(args[ii]) )

	if  verb_flg:
		print 'processing '+str( num_list)

	try:
		coefs = test_model(num_list, verb_flg)
		if coefs != None:
			if type == 1:
				print '%.2f %.2f'%(coefs[0], coefs[1])
			else:
				print 'true'
		else:
			print 'false'
	except LinAlgError:
		print 'false'

# else:
# 	type = 1
# 	a0 = 4;
# 	K = 0.5;
# 	L = 2.77
# 	num_list = [a0]
# 	a_i = a0;
# 	for i in range( 1, 1000 ):
# 		a_i = a_i * K + L
# 		num_list.append( a_i )


# Code for solving du/dt = ddu/ddx on a rectangular grid
# of size L x (T*dt),
# with with L = 1, u(x,0) = g(x), u(0,t) = u(L,t) = 0
#

import numpy,math
import sys

def forward_step(alpha,u,uPrev,N):
    """
    Steps forward-euler algo one step ahead.
    Implemented in separate function for code-reuse from crank_nicolson()
    """

    for x in xrange(1,N+1): #loop from i=1 to i=N
        u[x] = alpha*uPrev[x-1] + (1.0-2*alpha)*uPrev[x] + alpha*uPrev[x+1]

def forward_euler(alpha,u,N,T):
    """
    Implements forward euler sheme, results saved to
    array u
    """

    #Skip boundary elements
    for t in xrange(1,T):
        forward_step(alpha,u[t],u[t-1],N)

def tridiag(alpha,u,N):
    """
    Tridiagonal gaus-eliminator, specialized to diagonal = 1+2*alpha,
    super- and sub- diagonal = - alpha
    """
    d = numpy.zeros(N) + (1+2*alpha)
    b = numpy.zeros(N-1) - alpha

    #Forward eliminate
    for i in xrange(1,N):
        #Normalize row i (i in u convention):
        b[i-1] /= d[i-1];
        u[i] /= d[i-1] #Note: row i in u = row i-1 in the matrix
        d[i-1] = 1.0
        #Eliminate
        u[i+1] += u[i]*alpha
        d[i] += b[i-1]*alpha
    #Normalize bottom row
    u[N] /= d[N-1]
    d[N-1] = 1.0

    #Backward substitute
    for i in xrange(N,1,-1): #loop from i=N to i=2
        u[i-1] -= u[i]*b[i-2]
        #b[i-2] = 0.0 #This is never read, why bother...

def backward_euler(alpha,u,N,T):
    """
    Implements backward euler scheme by gaus-elimination of tridiagonal matrix.
    Results are saved to u.
    """
    for t in xrange(1,T):
        u[t] = u[t-1].copy()
        tridiag(alpha,u[t],N) #Note: Passing a pointer to row t, which is modified in-place

def crank_nicolson(alpha,u,N,T):
    """
    Implents crank-nicolson scheme, reusing code from forward- and backward euler
    """
    for t in xrange(1,T):
        forward_step(alpha/2,u[t],u[t-1],N)
        tridiag(alpha/2,u[t],N)

def g(x):
    """Initial condition u(x,0) = g(x), x \in [0,1]"""
    return numpy.sin(math.pi*x)

#Initialize
if len(sys.argv) == 6:
    N       =   int(sys.argv[1])
    dt      = float(sys.argv[2])
    T       =   int(sys.argv[3])
    method  =   int(sys.argv[4])
    outfile =   str(sys.argv[5])
else:
    print "Usage:", sys.argv[0], "N dt T method"
    print "\t N:       Number of inner meshpoints"
    print "\t dt:      Length of timestep"
    print "\t T:       Number of timesteps"
    print "\t method:  Method selector:"
    print "\t          1 => Forward Euler"
    print "\t          2 => Backward Euler"
    print "\t          3 => Crank-Nicolson"
    print "\t outfile: Name of file to write to"
    sys.exit(0)

ofile = open(outfile,'w')

#dx = 1/float(N+1)
u = numpy.zeros((T,N+2),numpy.double)
(x,dx) = numpy.linspace (0,1,N+2, retstep=True)
alpha = dt/(dx**2)

#Initial codition
u[0,:] = g(x)
u[0,0] = u[0,N+1] = 0.0 #Implement boundaries rigidly

if   method == 1:
    forward_euler(alpha,u,N,T)
elif method == 2:
    backward_euler(alpha,u,N,T)
elif method == 3:
    crank_nicolson(alpha,u,N,T)
else:
    print "Please select method 1,2, or 3!"
    import sys
    sys.exit(0)

#Output
ostring = "%16.8E "*(N+2) + "\n";
for t in xrange(T):
    ofile.write(ostring % tuple(u[t,:]))
ofile.close()


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

# # normal method
# position = 0
# walk = [position]
# steps = 1000
# for i in range(steps):
#     step = 1 if random.randint(0, 1) else -1
#     position += step
#     walk.append(position)
# x = np.linspace(0, 1000, 1001)
# plt.figure()
# plt.ylim((-15, 15))
# plt.xlim((0, 100))
# plt.title('Random walk with +1/-1 steps')
# plt.plot(x, walk)
# plt.show()

# Use NumPy
nsteps = 1000
draws = np.random.randint(0, 2, size=nsteps)
steps = np.where(draws > 0, 1, -1)
walk = steps.cumsum() # cumulative sum of the steps

print('the minium of steps : ', walk.min())
print('the maxinum of steps : ', walk.max())

x = np.linspace(0, nsteps, nsteps)
plt.xlim((0, 100))
plt.ylim((-15, 15))
plt.title('Random walk with +1/-1 steps')
plt.plot(x, walk)
plt.show()


import pytest
import numpy as np
import torch

from experiments.online_fa import generate_and_sample_fa_model
from experiments.utils.metrics import (
    compute_gaussian_log_likelihood,
    compute_fa_covariance,
    compute_distance_between_matrices,
    matrix_sqrt,
)

def test_compute_fa_covariance():
    F = torch.Tensor([
        [1, 2],
        [-3, 4],
        [-1, 2],
    ])
    psi = torch.Tensor([
        [1, 0, 0],
        [0, 2, 0],
        [0, 0, 3],
    ])
    expected_covariance = torch.Tensor([
        [6, 5, 3],
        [5, 27, 11],
        [3, 11, 8],
    ])
    actual_covariance = compute_fa_covariance(F, psi)
    assert torch.isclose(actual_covariance, expected_covariance, atol=1e-05).all()

def test_compute_matrix_norm():
    X = torch.Tensor([
        [1, 2],
        [-3, 4],
    ])
    expected_norm = np.sqrt(30)
    actual_norm = compute_distance_between_matrices(X, torch.zeros_like(X))
    assert np.isclose(actual_norm, expected_norm, atol=1e-5)

def test_compute_distance_between_matrices():
    A = torch.Tensor([
        [1, 6],
        [6, 5],
    ])
    B = torch.Tensor([
        [0, 4],
        [9, 1],
    ])
    expected_distance = np.sqrt(30)
    actual_distance = compute_distance_between_matrices(A, B)
    assert np.isclose(actual_distance, expected_distance, atol=1e-5)

@pytest.mark.parametrize("observation_dim", [10, 20])
@pytest.mark.parametrize("latent_dim", [5, 8])
@pytest.mark.parametrize("spectrum_range", [[0, 1], [0, 10]])
@pytest.mark.parametrize('n_samples', [10, 100])
def test_gaussian_log_likelihood(observation_dim, latent_dim, spectrum_range, n_samples):
    mean, F, psi, covar, observations = generate_and_sample_fa_model(
        observation_dim, latent_dim, spectrum_range, n_samples, random_seed=0,
    )
    inv_cov = torch.linalg.inv(covar)
    log_det_cov = torch.logdet(covar)
    expected_ll_observations = torch.zeros(n_samples)
    for i, x in enumerate(observations):
        centred_x = (x - mean).reshape(-1, 1)
        expected_ll_observations[i] = (
            -0.5 * centred_x.t().mm(inv_cov).mm(centred_x)
            -0.5 * log_det_cov
            -0.5 * observation_dim * np.log(2 * np.pi)
        )
    expected_ll = expected_ll_observations.mean().item()
    actual_ll = compute_gaussian_log_likelihood(mean, covar, observations)
    assert np.isclose(actual_ll, expected_ll, atol=1e-5)

@pytest.mark.parametrize("dim", [2, 5, 10, 20, 50, 100])
def test_matrix_sqrt(dim):
    torch.manual_seed(0)
    B = torch.randn(dim, dim)
    A = B.mm(B.t())
    sqrt_A = matrix_sqrt(A)
    A_rebuilt = sqrt_A.mm(sqrt_A)
    assert torch.isclose(A_rebuilt, A, atol=1e-4 * dim).all()


# Copyright 2017 Battelle Energy Alliance, LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#***************************************
#* Simple analytic test ExternalModule *
#***************************************
# This test is used to compute the global sensitivities:
# The analytic solution for 5 input variables is:
# mean = 1.0, variance = 0.728
# S1 = S2 = S3 = 0.2747
# S12 = S23 = S31 = 0.0549
# S123 = 0.0110
#
# input variables are distributed as y ~ [0,1]
# from: Bruno Sudret, Global Sensitivity Analysis using Polynomial Chaos Expansion, Reliability Engineering and System Safety, 2008

import numpy as np

def evaluate(inp):
  return 1.0/(2.0**len(inp))*np.prod(list(1.+3.0*n**2 for n in inp))

def run(self,Input):
  self.ans  = evaluate(Input.values())

#
#  This model has analytic mean and variance and is documented in raven/docs/tests
#


from my_mathematics.linear_algebra import MyVector
import pytest
import numpy as np

@pytest.mark.parametrize('lhs, rhs', [(MyVector(3, 2, 3, 4), MyVector(3, 0, 6, 4)),
                                      (MyVector(2, 3, 4), MyVector(2, 1, 0)),
                                      (MyVector(2, 3, 4), MyVector(2, 1, 0)),
                                      (MyVector(1, 9), MyVector(1, 2)),
                                      (MyVector(5, 2, 1, 3, 4, 5), MyVector(5, 4, 10, 6, 3, 4))
                                      ]
                         )
def test_vector_sum(lhs, rhs):
    np_lhs = lhs.args_as_np
    np_rhs = rhs.args_as_np

    assert (lhs + rhs).args_as_np.all() == (np_lhs + np_rhs).all()

@pytest.mark.parametrize('lhs, rhs', [(MyVector(3, 2, 3, 4), MyVector(3, 0, 6, 4)),
                                      (MyVector(2, 3, 4), MyVector(2, 1, 0)),
                                      (MyVector(2, 3, 4), MyVector(2, 1, 0)),
                                      (MyVector(1, 9), MyVector(1, 2)),
                                      (MyVector(5, 2, 1, 3, 4, 5), MyVector(5, 4, 10, 6, 3, 4))
                                      ]
                         )
def test_vector_sub(lhs, rhs):
    np_lhs = lhs.args_as_np
    np_rhs = rhs.args_as_np

    assert (lhs - rhs).args_as_np.all() == (np_lhs - np_rhs).all()

@pytest.mark.parametrize('lhs, rhs', [(MyVector(3, 2, 3, 4), MyVector(3, 0, 6, 4)),
                                      (MyVector(2, 3, 4), MyVector(2, 1, 0)),
                                      (MyVector(2, 3, 4), MyVector(2, 1, 0)),
                                      (MyVector(1, 9), MyVector(1, 2)),
                                      (MyVector(5, 2, 1, 3, 4, 5), MyVector(5, 4, 10, 6, 3, 4))
                                      ]
                         )
def test_vector_dot_product(lhs, rhs):
    np_lhs = lhs.args_as_np
    np_rhs = rhs.args_as_np
    np_dot = np_lhs.dot(np_rhs)

    assert lhs * rhs == np_dot

@pytest.mark.parametrize('vector', [MyVector(1, 0), MyVector(2, 3, 1), MyVector(3, 4, 5, 9),
                                    MyVector(4, 1, 3, 6, 4), MyVector(5, 9, 8, 5, 3, 9), MyVector(6, 5, 6, 8, 9, 0, 8)
                                    ]
                         )
def test_vector_norm(vector):
    np_vector = vector.args_as_np

    assert np.linalg.norm(np_vector) == vector.vector_norm()


import numpy as np

def spherical_coords(theta, phi):
    """
    given theta and phi, returns the corresponding Cartesian vector """
    theta *= 2*np.pi/360
    phi *= 2*np.pi/360
    r=1
    x=r*np.sin(theta)*np.cos(phi)
    y=r*np.sin(theta)*np.sin(phi)
    z=r*np.cos(theta)
    r = np.array([x,y,z])
    return r

def find_orthog(u1, u2):
    """
    Given two Cartesian vectors, find the vector that is orthogonal to both
    Arguments:
        u1: vector 1 [x,y,z]
        u2: vector 2 [x,y,z]
    Returns:
        theta, phi (oxford magnet basis)"""
    u3 = np.cross(u1, u2)
    theta = np.arccos(u3[2])/np.linalg.norm(u3)
    phi = np.arctan(u3[1]/u3[0])
    return theta, phi


## 1. The Range ##

import pandas as pd
houses = pd.read_table('AmesHousing_1.txt')

def range(distribution):
    range = max(distribution) - min(distribution)

    return range

range_by_year = {}
for year in houses['Yr Sold'].unique():
    data_by_year = houses[houses['Yr Sold'] == year]
    range_by_year[year] = range(data_by_year['SalePrice'])

print(range_by_year)

one = False
two = True

## 2. The Average Distance ##

C = [1,1,1,1,1,1,1,1,1,21]

def average_distance(array):
    reference_point = sum(array) / len(array)
    distances = []

    for value in array:
        distance = value - reference_point
        distances.append(distance)

    return sum(distances) / len(distances)

avg_distance = average_distance(C)
print(avg_distance)

## 3. Mean Absolute Deviation ##

C = [1,1,1,1,1,1,1,1,1,21]

def mean_absolute_deviation(array):
    reference_point =  sum(array) / len(array)

    distances = []

    for value in array:
        absolute_distance = abs(value - reference_point)
        distances.append(absolute_distance)

    return sum(distances)/len(distances)

mad = mean_absolute_deviation(C)
print(mad)

## 4. Variance ##

C = [1,1,1,1,1,1,1,1,1,21]

def variance(array):
    reference_point = sum(array) / len(array)

    distances = []

    for value in array:
        squared_distance =  (value - reference_point) ** 2
        distances.append(squared_distance)

    return sum(distances) / len(distances)

variance_C =  variance(C)
print(variance_C)

## 5. Standard Deviation ##

from math import sqrt
C = [1,1,1,1,1,1,1,1,1,21]

def standard_deviation(array):
    reference_point = sum(array) / len(array)

    distances = []

    for value in array:
        squared_distance = (value -  reference_point) ** 2
        distances.append(squared_distance)

    return sqrt(sum(distances)/len(distances))

standard_deviation_C = standard_deviation(C)
print(standard_deviation_C)

## 6. Average Variability Around the Mean ##

def standard_deviation(array):
    reference_point = sum(array) / len(array)

    distances = []
    for value in array:
        squared_distance = (value - reference_point)**2
        distances.append(squared_distance)

    variance = sum(distances) / len(distances)

    return sqrt(variance)

# Measure first the variability for each year
years = {}

for year in houses['Yr Sold'].unique():
    year_segment = houses[houses['Yr Sold']==year]
    st_dev = standard_deviation(year_segment['SalePrice'])
    years[year] =st_dev

# Get years of max and min variability
greatest_variability = max(years, key = years.get)
lowest_variability = min(years, key = years.get)
print(years)
print(greatest_variability)
print(lowest_variability)

## 7. A Measure of Spread ##

sample1 = houses['Year Built'].sample(50, random_state = 1)
sample2 = houses['Year Built'].sample(50, random_state = 2)

def standard_deviation(array):
    reference_point = sum(array) / len(array)

    distances = []
    for value in array:
        squared_distance = (value - reference_point)**2
        distances.append(squared_distance)

    variance = sum(distances) / len(distances)

    return sqrt(variance)

bigger_spread = 'sample 2'

st_dev1 = standard_deviation(sample1)
st_dev2 = standard_deviation(sample2)
print(st_dev1)
print(st_dev2)

## 8. The Sample Standard Deviation ##

def standard_deviation(array):
    reference_point = sum(array) / len(array)

    distances = []
    for value in array:
        squared_distance = (value - reference_point)**2
        distances.append(squared_distance)

    variance = sum(distances) / len(distances)

    return sqrt(variance)

import matplotlib.pyplot as plt
st_devs = []

for i in range(5000):
    sample = houses['SalePrice'].sample(10, random_state = i)
    st_dev = standard_deviation(sample)
    st_devs.append(st_dev)

plt.hist(st_devs)
plt.axvline(standard_deviation(houses['SalePrice']))

## 9. Bessel's Correction ##

from math import sqrt
def standard_deviation(array):
    reference_point = sum(array) / len(array)

    distances = []
    for value in array:
        squared_distance = (value - reference_point)**2
        distances.append(squared_distance)

    variance = sum(distances) / (len(distances)-1)

    return sqrt(variance)

import matplotlib.pyplot as plt
st_devs = []

for i in range(5000):
    sample = houses['SalePrice'].sample(10, random_state = i)
    st_dev = standard_deviation(sample)
    st_devs.append(st_dev)

plt.hist(st_devs)
plt.axvline(pop_stdev)  # pop_stdev is pre-saved from the last screen

## 10. Standard Notation ##

sample = houses.sample(100, random_state = 1)
from numpy import std, var

pandas_stdev = sample['SalePrice'].std(ddof = 1)
print(pandas_stdev)
numpy_stdev = std(sample['SalePrice'],ddof=1)
print(numpy_stdev)
equal_stdevs = pandas_stdev == numpy_stdev
print(equal_stdevs)

pandas_var = sample['SalePrice'].var(ddof = 1) # default ddof = 1
numpy_var = var(sample['SalePrice'], ddof = 1) #default ddof = 0
equal_vars = pandas_var == numpy_var

## 11. Sample Variance — Unbiased Estimator ##

population = [0, 3, 6]

samples = [[0,3], [0,6],
           [3,0], [3,6],
           [6,0], [6,3]
          ]

from numpy import var, std

pop_var = var(population, ddof = 0)
pop_std = std(population, ddof = 0)

st_devs = []
variances = []

for sample in samples:
    st_devs.append(std(sample, ddof = 1))
    variances.append(var(sample, ddof = 1))

mean_std = sum(st_devs) / len(st_devs)
mean_var = sum(variances) / len(variances)

equal_stdev = pop_std == mean_std
equal_var = pop_var == mean_var

5. Probability and Statistics/statistics-intermediate/Measures of Variability-308.py


import numpy as np
import math
from typing import Tuple, Set

def conj_grad(A: np.matrix, b: np.ndarray, x_0: np.ndarray):
    k = 0
    r = {}; r[0] = b - A @ x_0
    x = {}; x[0] = x_0
    p = {}
    tau = {}
    mu = {}

    while not math.isclose(np.linalg.norm(r[k], ord=2), 0):
        k += 1
        if k == 1:
            p[k] = r[0]
        else:
            tau[k-1] = (r[k-1].transpose() @ r[k-1]) / (r[k-2].transpose() @ r[k-2])
            p[k] = r[k-1] + tau[k-1] * p[k-1]
        mu[k] = (r[k-1].transpose() @ r[k-1]) / (p[k].transpose() @ A @ p[k])
        x[k] = x[k-1] + mu[k] * p[k]
        r[k] = r[k-1] - mu[k] * (A @ p[k])

    x_star = x[k]
    return x_star, k

def lu_solve(L: np.matrix, R: np.matrix, b: np.array) -> np.array:
    y = np.zeros(b.size)
    for m in range(0, b.size):
        y[m] = b[m] - sum(
            L[m][i] * y[i] for i in range(0, m)
        )
        y[m] /= L[m][m]

    x = np.zeros(b.size)
    for k in reversed(range(0, b.size)):
        x[k] = y[k] - sum(
                R[k][i] * x[i] for i in range(k + 1, b.size)
        )
        x[k] /= R[k][k]

    return x

def conj_grad_precond(A: np.matrix, b: np.ndarray, x_0: np.ndarray, precond_func):
    k = 0
    r = {}; r[0] = b - A @ x_0
    x = {}; x[0] = x_0
    z = {}
    p = {}

    L, U = precond_func(A)
    z[0] = lu_solve(L, U, r[0])

    while not math.isclose(np.linalg.norm(r[k], ord=2), 0):
        k += 1
        if k == 1:
            p[k] = z[0]
        else:
            tau = (r[k-1].transpose() @ z[k-1]) / (r[k-2].transpose() @ z[k-2])
            p[k] = z[k-1] + tau * p[k-1]
        mu = (r[k-1].transpose() @ z[k-1]) / (p[k].transpose() @ A @ p[k])
        x[k] = x[k-1] + mu * p[k]
        r[k] = r[k-1] - mu * (A @ p[k])
        z[k] = lu_solve(L, U, r[k])

    x_star = x[k]
    return x_star, k

def matrix_portrait(A: np.matrix, e: float = None) -> Set[Tuple[int, int]]:
    if e is None:
        Omega = set()
        n = A.shape[0]
        for i in range(0, n):
            for j in range(0, n):
                if not math.isclose(A[i, j], 0):
                    Omega.add((i, j))

        return Omega
    else:
        Omega = set()
        n = A.shape[0]
        for i in range(0, n):
            for j in range(0, n):
                if abs(A[i, j]) > e or i==j:
                    Omega.add((i, j))

        return Omega

def incomplete_lu(A: np.matrix, Omega: Set[Tuple[int, int]], modified: bool = False) -> Tuple[np.matrix, np.matrix]:
    A = A.copy()
    n = A.shape[0]
    L = np.eye(n, dtype=float)
    R = np.zeros(A.shape, dtype=float)

    for k in range(0, n):
        for i in range(k, n):
            if (k, i) in Omega:
                R[k, i] = A[k, i]
            elif modified:
                R[k, k] -= A[k, i]
                R[k, i] = 0
        for j in range(k + 1, n):
            L[j, k] = A[j, k] / A[k, k] if (j, k) in Omega else 0
        for p in range(k + 1, n):
            for q in range(k + 1, n):
                    A[p, q] -= L[p, k]*R[k, q]

    return L, R

def ilu_k(A: np.matrix, k: int, modified: bool = False, e: float = None) -> Tuple[np.matrix, np.matrix]:
    Omega = matrix_portrait(A, e)
    for i in range(0, k+1):
        L, R = incomplete_lu(A, Omega, modified)
        T = L @ R - A
        Omega |= matrix_portrait(T, e) # | is set union

    return L, R


# Import required libraries:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn import linear_model

# Read the CSV file :
data = pd.read_csv("https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/ML0101ENv3/labs/FuelConsumptionCo2.csv")
data.head()

# Let's select some features to explore more :
data = data[["ENGINESIZE","CO2EMISSIONS"]]

# ENGINESIZE vs CO2EMISSIONS:
plt.scatter(data["ENGINESIZE"] , data["CO2EMISSIONS"] , color="blue")
plt.xlabel("ENGINESIZE")
plt.ylabel("CO2EMISSIONS")
plt.show()

# Generating training and testing data from our data:
# We are using 80% data for training.
train = data[:(int((len(data)*0.8)))]
test = data[(int((len(data)*0.8))):]

# Modeling:

# Using sklearn package to model data :
regr = linear_model.LinearRegression()
train_x = np.array(train[["ENGINESIZE"]])
train_y = np.array(train[["CO2EMISSIONS"]])
regr.fit(train_x,train_y)

# The coefficients:
print ("coefficients : ",regr.coef_)       #Slope
print ("Intercept : ",regr.intercept_)     #Intercept

# Plotting the regression line:
plt.scatter(train["ENGINESIZE"], train["CO2EMISSIONS"], color='blue')
plt.plot(train_x, regr.coef_*train_x + regr.intercept_, '-r')
plt.xlabel("Engine size")
plt.ylabel("Emission")

# Predicting values:

# Function for predicting future values :
def get_regression_predictions(input_features,intercept,slope):
 predicted_values = input_features*slope + intercept
 return predicted_values

# Predicting emission for future car:
my_engine_size = 3.5
estimatd_emission = get_regression_predictions(my_engine_size,regr.intercept_[0],regr.coef_[0][0])
print ("Estimated Emission :",estimatd_emission)

# Checking various accuracy:
from sklearn.metrics import r2_score
test_x = np.array(test[['ENGINESIZE']])
test_y = np.array(test[['CO2EMISSIONS']])
test_y_ = regr.predict(test_x)
print("Mean absolute error: %.2f" % np.mean(np.absolute(test_y_ - test_y)))
print("Mean sum of squares (MSE): %.2f" % np.mean((test_y_ - test_y) ** 2))
print("R2-score: %.2f" % r2_score(test_y_ , test_y) )


import numpy as np
# For plotting
import matplotlib.pyplot as plt
fontsize = 16
import pandas as pd
import scipy.integrate as integrate

def PI_Approx(N):
    np.random.seed(seed=42)
    inside = 0
    PI_approx = []
    rand = []
    rand_2 = []
    for i in range(1,N):
        r = np.random.uniform(low=-1,high=1)
        rand.append(r)
        r2 = np.random.uniform(low=-1,high=1)
        rand_2.append(r2)
        if (r*r + r2*r2 < 1):
            inside = inside + 1
        PI_approx.append(4*inside/i)

        if i == 100 or i == 1000 or i == 10000:
            circle_1 = plt.Circle((0,0),1, color = 'black', fill = False, linewidth = 2, alpha = 0.5)
            fig, ax = plt.subplots(figsize = (7,7))
            color = np.array(rand)*np.array(rand) + np.array(rand_2)*np.array(rand_2) < 1
            plt.scatter(rand, rand_2, c=color, cmap= 'bwr', alpha=0.5)
            ax.add_patch(circle_1)
            plt.title(r'$ N = %s , n = %s \rightarrow \pi \approx \frac{4n}{N} \approx %.2f$' %(i, inside, 4*inside/i), fontsize=fontsize)
            plt.xlim(-1,1)
            plt.ylim(-1,1)
            plt.xlabel('x', fontsize=fontsize)
            plt.ylabel('y', fontsize=fontsize)
            plt.savefig('monte_carlo/MC_Circle_N=%s.jpg' %i, bbox_inches='tight', dpi=300)
    PI_approx = pd.DataFrame(PI_approx, columns=['Estimated PI'])
    PI_approx['Real PI'] = np.pi
    PI_approx['Error'] = np.pi - PI_approx['Estimated PI']

    return PI_approx

df_PI = PI_Approx(N=100000)

plt.figure()
df_PI[['Estimated PI', 'Real PI']].plot(logx=True)
plt.xlabel('N iterations', fontsize=fontsize)
plt.ylabel(r'$ \pi_{est} $', fontsize=fontsize)
plt.savefig('monte_carlo/Real_vs_Estimated_PI.jpg', bbox_inches='tight', dpi=300)

plt.figure()
df_PI['N_scaling']=1/np.sqrt(df_PI.index.values)
df_PI['Error'].abs().plot(logy=True, logx=True)
df_PI['N_scaling'].plot(logy=True, logx=True, c='r')
plt.text(1000, 0.2, r'$ \propto \frac{1}{\sqrt{N}}$', fontsize=fontsize)
plt.ylabel('Error', fontsize=fontsize)
plt.xlabel('N iterations', fontsize=fontsize)
plt.savefig('monte_carlo/Real_vs_Estimated_PI_Scaling.jpg', bbox_inches='tight', dpi=300)


# !pip install tf-nightly tfp-nightly seaborn
import matplotlib
from matplotlib import pyplot as plt

import seaborn

import numpy as np
from scipy.stats import itemfreq

import tensorflow as tf
import tensorflow_probability as tfp
tfd = tfp.distributions
tf.enable_eager_execution()

# ===========================================================================
# How do we specify the distribution in tensorflow probability
# ===========================================================================
boxes = tfd.Categorical(probs=[0.2, # p(r)
                               0.2, # p(b)
                               0.6], # p(g)
                        name="DistributionOfBoxes")
fruits = tfd.Mixture(
    cat=boxes,
    components=[
        # in order, the probabilities of: apple, orange, lime
        tfd.Categorical(probs=[0.3, 0.4, 0.3], name="RedBox"),
        tfd.Categorical(probs=[0.5, 0.5, 0.0], name="BlueBox"),
        tfd.Categorical(probs=[0.3, 0.3, 0.4], name="GreenBox"),
    ],
    name="DistributionOfFruits")

print("p(apple)  =", tf.exp(fruits.log_prob(0)))
print("p(orange) =", tf.exp(fruits.log_prob(1)))
print("p(lime)   =", tf.exp(fruits.log_prob(2)))

# ===========================================================================
# Draw sample and plot histogram
# ===========================================================================
n_samples = 10000
samples = fruits.sample(n_samples)
distribution = itemfreq(samples)
plt.bar(distribution[:, 0], distribution[:, 1])
plt.title("Distribution of fruits after picking %d times" % n_samples)
plt.xticks(np.arange(0, 3), fontsize=12)

# ===========================================================================
# Calculate the log-likelihood
# ===========================================================================
samples1 = fruits.sample(10)
samples2 = [0, 1, 2, 2, 2, 2, 2, 2, 2, 2]

llk1 = tf.reduce_sum(fruits.log_prob(samples1))
print("log[p(sample1|model)] =", llk1)

llk2 = tf.reduce_sum(fruits.log_prob(samples2))
print("log[p(sample2|model)] =", llk2)

if llk1 > llk2:
  print('Samples-1 are more likely to be generated from our model')
elif llk1 == llk2:
  print('Both samples are equal likely to be generated from our model')
else:
  print('Samples-2 are more likely to be generated from our model')

# ===========================================================================
# Could we replicate the same results in numpy using sampling
# ===========================================================================
# ====== configuration ====== #
n_samples = 100
np.random.seed(5218)

# ====== Sampling process ====== #
boxes = ['red', 'blue', 'green']
# this might be slow but it is intuitive
chose_boxes = [np.random.choice(boxes, size=None, p=[0.2, 0.2, 0.6])
               for i in range(n_samples)]


import numpy as np

def cgsolve(A, b, tau):
    """
    Given A nd b, it solves the linear system Ax=b using the CF-method.
    The matrix A must be symmetric and postive definite.

    The CG-steps get smaller after every iteration.
    For an nxn matrix the algorithm performs at most n iterations before terminating.
    """

    if A.shape[0] != A.shape[1]:
        raise ValueError("Matrix A is not symmetric.")
    for eig in np.linalg.eigvals(A):
        if eig <= 0.:
            raise ValueError("Matrix A is not positive definite")

    x = np.ones(A.shape[0])    # arbitrary initial guess
    r = b - np.matmul(A, x)
    d = r

    while True:
        r_prev = r
        alpha = r.dot(r)/d.dot(np.matmul(A, d))
        x = x + alpha*d
        r = r - alpha*np.matmul(A, d)
        if np.linalg.norm(r) <= tau:
            break
        d = r + (r.dot(r)/r_prev.dot(r_prev))*d

    return x

def main():
    # 2x2 matrx
    A = np.array([[1, 0],[0, 1]])
    b = np.array([23, 34])
    tau = 10e-8

    x = cgsolve(A, b, tau)
    print("### Test 2x2")
    print("x:", x)
    print("Approx.:", np.matmul(A, x))
    print("Actual:", b)

    # 6x6 matrix
    A = np.array([[7, -2, -3, 0, -1, 0],
                  [-2, 8, 0, 0, -1, 0],
                  [-3, 0, 4, -1, 0, 0],
                  [0, 0, -1, 5, 0, -2],
                  [-1, -1, 0, 0, 4, 0],
                  [0, 0, 0, -2, 0, 6]])
    b = np.array([1, 2, 3, 4, 5, 6])
    tau = 10e-8

    x = cgsolve(A, b, tau)
    print("\n### Test 6x6")
    print("x:", x)
    print("Approx.:", np.matmul(A, x))
    print("Actual:", b)

if __name__ == "__main__":
    main()


# Ploynomial Regression

# Importing the libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

# Importing the dataset
dataset = pd.read_csv('Position_Salaries.csv')
X = dataset.iloc[:, 1:2].values
y = dataset.iloc[:, 2].values

'''
# Splitting the dataset into the Training set and Test set
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)'''

# Feature Scaling
"""from sklearn.preprocessing import StandardScaler
sc_X = StandardScaler()
X_train = sc_X.fit_transform(X_train)
X_test = sc_X.transform(X_test)
sc_y = StandardScaler()
y_train = sc_y.fit_transform(y_train)"""

# Fitting Linear Regression to the dataset
from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(X, y)

# Fitting Polynomial Regression to the Dataset
from sklearn.preprocessing import PolynomialFeatures
poly_reg = PolynomialFeatures(degree = 6)
X_poly = poly_reg.fit_transform(X)
#print(X_poly)

lin_reg_2 = LinearRegression()
lin_reg_2.fit(X_poly, y)

# Visualizing linear Regression Results
plt.scatter(X, y, color = "red")
plt.plot(X, lin_reg.predict(X), color = "blue")
plt.title('Truth or Bluff (Linear Regression)')
plt.xlabel("Position Level")
plt.ylabel('Salary')
#plt.show()

# Visualizing Polynomial Regression Results
x_grid = np.arange(min(X), max(X), 0.1)
x_grid = x_grid.reshape(len(x_grid), 1)
plt.scatter(X, y, color = "red")
plt.plot(x_grid, lin_reg_2.predict(poly_reg.fit_transform(x_grid)), color = "blue")
plt.title('Truth or Bluff (Polynomial Regression)')
plt.xlabel("Position Level")
plt.ylabel('Salary')
#plt.show()

# Predicting new Result with Linear Regression
#print(lin_reg.predict(6.5))

# Predicitng a new result with Polynomial Regression
print(lin_reg_2.predict(poly_reg.fit_transform(6.5)))

Machine Learning A-Z Template Folder/Part two - Regression/Section 6 - Polynomial Regression/poly_reg.py


import os
import numpy as np
path = os.path.dirname(os.path.realpath(__file__))

def consumption(lines:list):
    data = [[int(i) for i in list(line.strip())] for line in lines]
    arr = np.array(data, dtype='int32')
    l = len(arr)
    w = len(arr[0])

    gamma_rate = []
    epsilon_rate = []
    for i in range(w):
        t = 1 if sum(arr[:,i]) >=l/2 else 0
        gamma_rate.append(t)
        epsilon_rate.append(1-t)

    gamma_val = int(''.join(map(lambda x: str(int(x)), gamma_rate)), 2)
    epsilon_val = int(''.join(map(lambda x: str(int(x)), epsilon_rate)), 2)

    return gamma_val * epsilon_val

def life_support_ratig(lines:list):

    def count(l,i,c):
        # Counts occurrence of value 'c' in index 'i' of elements in the list 'l' (expected to be strings of same length)
        res = 0
        for k in range(len(l)):
            if l[k][i] == c:
                res += 1
        return res

    def clean(l,i,c):
        # Cleans elements in the list 'l' (expected to be strings of same length)  where value in index 'i' is equal to 'c'
        k = 0
        while k < len(l):
            if l[k][i] != c:
                l.pop(k)
                continue
            k += 1
        return l

    oxygen = lines.copy()
    co2 = lines.copy()

    i = 0
    while len(oxygen)>1 or len(co2)>1:
        if len(oxygen)>1:
            c = count(oxygen,i,'1')
            t = '1' if c >= len(oxygen)/2 else '0'
            oxygen = clean(oxygen,i,t)

        if len(co2)>1:
            c = count(co2,i,'1')
            t = '0' if c >= len(co2)/2 else '1'
            co2 = clean(co2,i,t)

        i += 1

    return int(oxygen[0], 2) * int(co2[0], 2)

test_lines = [
    '00100',
    '11110',
    '10110',
    '10111',
    '10101',
    '01111',
    '00111',
    '11100',
    '10000',
    '11001',
    '00010',
    '01010',
]

lines = []
with open(path+"/input.txt") as file:
    lines = file.readlines()
    lines = [line.strip() for line in lines]

assert consumption(test_lines) == 198, "Function is wrong"

print("Part A:", consumption(lines))

assert life_support_ratig(test_lines) == 230, "Function is wrong"

print("Part B:", life_support_ratig(lines))


"""
  Name     : c15_07_equal_vol_2periods.py
  Book     : Python for Finance (2nd ed.)
  Publisher: Packt Publishing Ltd.
  Author   : Yuxing Yan
  Date     : 6/6/2017
  email    : yany@canisius.edu
             paulyxy@hotmail.com
"""

import numpy as np
import scipy as sp
import pandas as pd
from matplotlib.finance import quotes_historical_yahoo_ochl as getData
#
# input area
ticker='F'            # stock
begdate1=(1982,9,1)   # starting date for period 1
enddate1=(1987,9,1)   # ending date for period   1
begdate2=(1987,12,1)  # starting date for period 2
enddate2=(1992,12,1)  # ending   date for period 2
#
# define a function
def ret_f(ticker,begdate,enddate):
    p =getData(ticker, begdate, enddate,asobject=True, adjusted=True)
    ret = p.aclose[1:]/p.aclose[:-1]-1
    date_=p.date
    return pd.DataFrame(data=ret,index=date_[1:],columns=['ret'])
#
# call the above function twice
ret1=ret_f(ticker,begdate1,enddate1)
ret2=ret_f(ticker,begdate2,enddate2)
#
# output
print('Std period #1	vs. std period #2')
print(round(sp.std(ret1.ret),6),round(sp.std(ret2.ret),6))
print('T value ,	p-value ')
print(sp.stats.bartlett(ret1.ret,ret2.ret))


import numpy as np

def softmax_(predictions):
    '''
    Computes probabilities from scores

    Arguments:
      predictions, np array, shape is either (N) or (batch_size, N) -
        classifier output

    Returns:
      probs, np array of the same shape as predictions -
        probability for every class, 0..1
    '''
    s_pred =predictions-np.max(predictions)
    probs = np.exp(s_pred)/np.sum(np.exp(s_pred))
    # pp('soft max =', probs)
    return probs
    # TODO implement softmax_
    # Your final implementation shouldn't have any loops

def cross_entropy_loss_(probs, target_index):
    '''
    Computes cross-entropy loss

    Arguments:
      probs, np array, shape is either (N) or (batch_size, N) -
        probabilities for every class
      target_index: np array of int, shape is (1) or (batch_size) -
        index of the true class for given sample(s)

    Returns:
      loss: single value
    '''

    log =   np.sum(- np.log(probs[np.arange(probs.shape[0]),target_index.flatten()]))
    return log
    # TODO implement cross-entropy
    # Your final implementation shouldn't have any loops

def l2_regularization_(W, reg_strength):
    """
      Computes L2 regularization loss on weights and its gradient

      Arguments:
        W, np array - weights
        reg_strength - float value

      Returns:
        loss, single value - l2 regularization loss
        gradient, np.array same shape as W - gradient of weight by l2 loss
    """
    n_classes = W.value.shape[1]

    loss = reg_strength * np.sum(W.value**2)
    loss/=n_classes
    grad = reg_strength*W.value
    # pp('L2 loss, grad = ',loss,grad)
    return loss, grad

    # TODO: Copy from the previous assignment

def softmax__with_cross_entropy_(predictions, target_index):
    """
      Computes softmax_ and cross-entropy loss for model predictions,
      including the gradient

      Arguments:
        predictions, np array, shape is either (N) or (batch_size, N) -
          classifier output
        target_index: np array of int, shape is (1) or (batch_size) -
          index of the true class for given sample(s)

      Returns:
        loss, single value - cross-entropy loss
        dprediction, np array same shape as predictions - gradient of predictions by loss value
    """
    n_samples = predictions.shape[0]
    n_featerus = predictions.shape[1] if len(predictions.shape)>1 else 0
    # pp('enter of the function = ',predictions, target_index)

    softmax__ = softmax_(predictions)

    loss = cross_entropy_loss_(softmax__,target_index)
    loss = loss/n_samples
    prediction = softmax__.copy()
    prediction[np.arange(n_samples),target_index.ravel()] -= 1/n_samples

    # pp('=N_SUMPLES=',n_samples)
    # prediction/=n_samples
    # pp('loss , grand (prediction) = ',loss, prediction)
    return loss, prediction

    # TODO: Copy from the previous assignment


"""
An implementation on spherical harmonics in python becasue scipy.special.sph_harm in scipy<=0.13 is very slow

Originally written by Jozef Vesely
https://github.com/scipy/scipy/issues/1280
"""

import numpy as np

def xfact(m):
    # computes (2m-1)!!/sqrt((2m)!)
    res = 1.
    for i in xrange(1, 2*m+1):
        if i % 2: res *= i # (2m-1)!!
        res /= np.sqrt(i) # sqrt((2m)!)
    return res

def lplm_n(l, m, x):
    # associated legendre polynomials normalized as in Ylm, from Numerical Recipes 6.7
    l,m = int(l),int(m)
    assert 0<=m<=l and np.all(np.abs(x)<=1.)

    norm = np.sqrt(2. * l + 1.) / np.sqrt(4. * np.pi)
    if m == 0:
        pmm = norm * np.ones_like(x)
    else:
        pmm = (-1.)**m * norm * xfact(m) * (1.-x**2.)**(m/2.)
    if l == m:
        return pmm
    pmmp1 = x * pmm * np.sqrt(2.*m+1.)
    if l == m+1:
        return pmmp1
    for ll in xrange(m+2, l+1):
        pll = (x*(2.*ll-1.)*pmmp1 - np.sqrt( (ll-1.)**2. - m**2.)*pmm)/np.sqrt(ll**2.-m**2.)
        pmm = pmmp1
        pmmp1 = pll
    return pll

def Ylm(l, m, phi, theta):
    # spherical harmonics
    # theta is from 0 to pi with pi/2 on equator
    l,m = int(l),int(m)
    assert 0 <= np.abs(m) <=l
    if m > 0:
        return lplm_n(l, m, np.cos(theta)) * np.exp(1J * m * phi)
    elif m < 0:
        return (-1.)**m * lplm_n(l, -m, np.cos(theta)) * np.exp(1J * m * phi)
    return lplm_n(l, m, np.cos(theta)) * np.ones_like(phi)

def Ylmr(l, m, phi, theta):
    # real spherical harmonics
    # theta is from 0 to pi with pi/2 on equator
    l,m = int(l),int(m)
    assert 0 <= np.abs(m) <=l
    if m > 0:
        return lplm_n(l, m, np.cos(theta)) * np.cos(m * phi) * np.sqrt(2.)
    elif m < 0:
        return (-1.)**m * lplm_n(l, -m, np.cos(theta)) * np.sin(-m * phi) * np.sqrt(2.)
    return lplm_n(l, m, np.cos(theta)) * np.ones_like(phi)

if __name__ == "__main__":
    from scipy.special import sph_harm
    from scipy.misc import factorial2, factorial
    from timeit import Timer

    def ref_xfact(m):
        return factorial2(2*m-1)/np.sqrt(factorial(2*m))

    print "Time: xfact(10)", Timer("xfact(10)",
        "from __main__ import xfact, ref_xfact").timeit(100)
    print "Time: ref_xfact(10)", Timer("ref_xfact(10)",
        "from __main__ import xfact, ref_xfact").timeit(100)
    print "Time: xfact(80)", Timer("xfact(80)",
        "from __main__ import xfact, ref_xfact").timeit(100)
    print "Time: ref_xfact(80)", Timer("ref_xfact(80)",
        "from __main__ import xfact, ref_xfact").timeit(100)

    print "m", "xfact", "ref_xfact"
    for m in range(10) + range(80,90):
        a = xfact(m)
        b = ref_xfact(m)
        print m, a, b

    phi, theta = np.ogrid[0:2*np.pi:10j,-np.pi/2:np.pi/2:10j]

    print "Time: Ylm(1,1,phi,theta)", Timer("Ylm(1,1,phi,theta)",
        "from __main__ import Ylm, sph_harm, phi, theta").timeit(10)
    print "Time: sph_harm(1,1,phi,theta)", Timer("sph_harm(1,1,phi,theta)",
        "from __main__ import Ylm, sph_harm, phi, theta").timeit(10)

    print "l", "m", "max|Ylm-sph_harm|"
    for l in xrange(0,10):
        for m in xrange(-l,l+1):
            a = Ylm(l,m,phi,theta)
            b = sph_harm(m,l,phi,theta)
            print l,m, np.amax(np.abs(a-b))


'''
The Normal CDF
100xp
Now that you have a feel for how the Normal PDF looks, let's consider its CDF. Using the
samples you generated in the last exercise (in your namespace as samples_std1, samples_std3,
and samples_std10), generate and plot the CDFs.

Instructions
-Use your ecdf() function to generate x and y values for CDFs: x_std1, y_std1, x_std3, y_std3
and x_std10, y_std10, respectively.
-Plot all three CDFs as dots (do not forget the marker and linestyle keyword arguments!).
-Make a 2% margin in your plot.
-Hit submit to make a legend, showing which standard deviations you used, and to show your plot.
There is no need to label the axes because we have not defined what is being described by the Normal distribution; we are just looking at shapes of CDFs.
'''
import numpy as np
import matplotlib.pyplot as plt

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

# Seed random number generator
np.random.seed(42)

# Draw 100000 samples from Normal distribution with stds of interest: samples_std1, samples_std3,
#   samples_std10
samples_std1 = np.random.normal(20, 1, size=100000)
samples_std3 = np.random.normal(20, 3, size=100000)
samples_std10 = np.random.normal(20, 10, size=100000)

# Generate CDFs
x_std1, y_std1 = ecdf(samples_std1)
x_std3, y_std3 = ecdf(samples_std3)
x_std10, y_std10 = ecdf(samples_std10)

# Plot CDFs
_ = plt.plot(x_std1, y_std1, marker='.', linestyle='none')
_ = plt.plot(x_std3, y_std3, marker='.', linestyle='none')
_ = plt.plot(x_std10, y_std10, marker='.', linestyle='none')

# Make 2% margin
plt.margins(0.02)

# Make a legend and show the plot
_ = plt.legend(('std = 1', 'std = 3', 'std = 10'), loc='lower right')
plt.show()


# -*- coding: utf-8 -*-
"""
Created on Thu Jun  8 13:36:50 2017

@author: picku
"""
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import style
style.use('ggplot')

def generatePolyPoints(start, stop, num_points, coeff, noiseLevel = 1, plot = 1):
    """
    Generate evenly spaced x and y coordinates in Euclidean space from a polynomial
    with gaussian noise

    Parameters
    ------------
    start : float,
          Minimum value for the generated x-coordinates

    stop  : float
          Maximum value for the generated x-coordinates

    num_points : int
               Number of coordinates to generate

    coeff : 1-d array,

    noiseLevel : float, optional
              Indicates amount of gaussian noise to add to the y-coordinates
              generated from the polynomial characterized by coeff array.
              Zero indicates no noise, while each integer increment results in
              ten-fold noise increase

    plot : int, values = 1|~1 , optional
        plot == 1 returns a matplotlib plot of the generated coordinates

    Returns
    -----------
    x_pts : 1-d array, shape = [num_points,]
    y_pts : 1-d array, shape = [num_points,]

    """
    x_pts = np.arange(start, stop, (stop - start)/num_points)
    line = coeff[0]

    for i in np.arange(1, len(coeff)):
        line += coeff[i] * x_pts ** i

    if noiseLevel > 0:
        y_pts = np.random.normal(-(10 ** noiseLevel), 10 ** noiseLevel, len(x_pts)) + line
    else:
        y_pts = line

    if plot == 1: #Plot option
        plt.figure()
        plt.scatter(x_pts, y_pts)
        plt.xlabel('x')
        plt.ylabel('y')

    return x_pts, y_pts


#!/usr/bin/env python

import numpy as np
import random

from q1_softmax import softmax
from q2_sigmoid import sigmoid, sigmoid_grad
from q2_gradcheck import gradcheck_naive

def cross_entropy(labels, y_hat):
    assert labels.shape == y_hat.shape, "Predictions must match labels shape."
    log_y_hat = np.log(y_hat)
    x_ent = np.sum(labels * log_y_hat, axis=-1)
    return x_ent

def forward_backward_prop(data, labels, params, dimensions):
    """
    Forward and backward propagation for a two-layer sigmoidal network

    Compute the forward propagation and for the cross entropy cost,
    and backward propagation for the gradients for all parameters.

    Arguments:
    data -- M x Dx matrix, where each row is a training example.
    labels -- M x Dy matrix, where each row is a one-hot vector.
    params -- Model parameters, these are unpacked for you.
    dimensions -- A tuple of input dimension, number of hidden units
                  and output dimension
    """

    ### Unpack network parameters (do not modify)
    ofs = 0
    Dx, H, Dy = (dimensions[0], dimensions[1], dimensions[2])

    W1 = np.reshape(params[ofs:ofs+ Dx * H], (Dx, H))
    ofs += Dx * H
    b1 = np.reshape(params[ofs:ofs + H], (1, H))
    ofs += H
    W2 = np.reshape(params[ofs:ofs + H * Dy], (H, Dy))
    ofs += H * Dy
    b2 = np.reshape(params[ofs:ofs + Dy], (1, Dy))

    z1 = np.matmul(data, W1) + b1
    h = sigmoid(z1)
    z2 = np.matmul(h, W2) + b2
    y_hat = softmax(z2)
    cost = cross_entropy(labels, y_hat)

    dJ_dz2 = y_hat - labels  # (1x10)
    gradW2 = np.matmul(h.T, dJ_dz2)  # (5x10)
    dz2_dh = W2.T  # (10x5)
    dh_dz1 = np.diag(h * (1-h))  # (5x5)
    dJ_dz1 = np.matmul(np.matmul(dJ_dz2, dz2_dh), dh_dz1)  # (1x5)
    gradW1 = np.matmul(data.T, dJ_dz1)  # (10x5)
    gradb2 = dJ_dz2
    gradb1 = dJ_dz1

    ### Stack gradients (do not modify)
    grad = np.concatenate((gradW1.flatten(), gradb1.flatten(),
        gradW2.flatten(), gradb2.flatten()))

    return cost, grad

def sanity_check():
    """
    Set up fake data and parameters for the neural network, and test using
    gradcheck.
    """
    print "Running sanity check..."

    N = 20
    dimensions = [10, 5, 10]
    data = np.random.randn(N, dimensions[0])   # each row will be a datum
    labels = np.zeros((N, dimensions[2]))
    for i in xrange(N):
        labels[i, random.randint(0,dimensions[2]-1)] = 1

    params = np.random.randn((dimensions[0] + 1) * dimensions[1] + (
        dimensions[1] + 1) * dimensions[2], )

    gradcheck_naive(lambda params:
        forward_backward_prop(data, labels, params, dimensions), params)

def your_sanity_checks():
    """
    Use this space add any additional sanity checks by running:
        python q2_neural.py
    This function will not be called by the autograder, nor will
    your additional tests be graded.
    """
    print "Running your sanity checks..."

if __name__ == "__main__":
    sanity_check()
    your_sanity_checks()


# Visualization with hierarchical clustering and t-SNE
# In this chapter, you'll learn about two unsupervised learning techniques for data visualization, hierarchical clustering and t-SNE. Hierarchical clustering merges the data samples into ever-coarser clusters, yielding a tree visualization of the resulting cluster hierarchy. t-SNE maps the data samples into 2d space so that the proximity of the samples to one another can be visualized.

# Hierarchical clustering of the grain data
# In the video, you learned that the SciPy linkage() function performs hierarchical clustering on an array of samples. Use the linkage() function to obtain a hierarchical clustering of the grain samples, and use dendrogram() to visualize the result. A sample of the grain measurements is provided in the array samples, while the variety of each grain sample is given by the list varieties.

# Perform the necessary imports
from scipy.cluster.hierarchy import linkage, dendrogram
import matplotlib.pyplot as plt

# Calculate the linkage: mergings
mergings = linkage(samples, method ='complete')

# Plot the dendrogram, using varieties as labels
dendrogram(mergings,
           labels=varieties,
           leaf_rotation=90,
           leaf_font_size=6,
)
plt.show()

# Hierarchies of stocks
# In chapter 1, you used k-means clustering to cluster companies according to their stock price movements. Now, you'll perform hierarchical clustering of the companies. You are given a NumPy array of price movements movements, where the rows correspond to companies, and a list of the company names companies. SciPy hierarchical clustering doesn't fit into a sklearn pipeline, so you'll need to use the normalize() function from sklearn.preprocessing instead of Normalizer.

# linkage and dendrogram have already been imported from scipy.cluster.hierarchy, and PyPlot has been imported as plt.

# Import normalize
from sklearn.preprocessing import normalize

# Normalize the movements: normalized_movements
normalized_movements = normalize(movements)

# Calculate the linkage: mergings
mergings = linkage(normalized_movements, method ='complete')

# Plot the dendrogram
dendrogram(mergings, labels = companies, leaf_rotation= 90, leaf_font_size=6)
plt.show()

# Different linkage, different hierarchical clustering!
# In the video, you saw a hierarchical clustering of the voting countries at the Eurovision song contest using 'complete' linkage. Now, perform a hierarchical clustering of the voting countries with 'single' linkage, and compare the resulting dendrogram with the one in the video. Different linkage, different hierarchical clustering!

# You are given an array samples. Each row corresponds to a voting country, and each column corresponds to a performance that was voted for. The list country_names gives the name of each voting country. This dataset was obtained from Eurovision.

# Perform the necessary imports
import matplotlib.pyplot as plt
from scipy.cluster.hierarchy import linkage, dendrogram

# Calculate the linkage: mergings
mergings = linkage(samples, method ='single')

# Plot the dendrogram
dendrogram(mergings, labels = country_names, leaf_rotation =90, leaf_font_size =6)
plt.show()

# Extracting the cluster labels
# In the previous exercise, you saw that the intermediate clustering of the grain samples at height 6 has 3 clusters. Now, use the fcluster() function to extract the cluster labels for this intermediate clustering, and compare the labels with the grain varieties using a cross-tabulation.

# The hierarchical clustering has already been performed and mergings is the result of the linkage() function. The list varieties gives the variety of each grain sample.

# Perform the necessary imports
import pandas as pd
from scipy.cluster.hierarchy import fcluster

# Use fcluster to extract labels: labels
labels = fcluster(mergings, 6, criterion ='distance')

# Create a DataFrame with labels and varieties as columns: df
df = pd.DataFrame({'labels': labels, 'varieties': varieties})

# Create crosstab: ct
ct = pd.crosstab(df['labels'], df['varieties'])

# Display ct
print(ct)

# t-SNE visualization of grain dataset
# In the video, you saw t-SNE applied to the iris dataset. In this exercise, you'll apply t-SNE to the grain samples data and inspect the resulting t-SNE features using a scatter plot. You are given an array samples of grain samples and a list variety_numbers giving the variety number of each grain sample

# Import TSNE
from sklearn.manifold import TSNE

# Create a TSNE instance: model
model = TSNE(learning_rate =200)

# Apply fit_transform to samples: tsne_features
tsne_features = model.fit_transform(samples)

# Select the 0th feature: xs
xs = tsne_features[:,0]

# Select the 1st feature: ys
ys = tsne_features[:,1]

# Scatter plot, coloring by variety_numbers
plt.scatter(xs, ys, c=variety_numbers)
plt.show()

# A t-SNE map of the stock market
# t-SNE provides great visualizations when the individual samples can be labeled. In this exercise, you'll apply t-SNE to the company stock price data. A scatter plot of the resulting t-SNE features, labeled by the company names, gives you a map of the stock market! The stock price movements for each company are available as the array normalized_movements (these have already been normalized for you). The list companies gives the name of each company. PyPlot (plt) has been imported for you.

# Import TSNE
from sklearn.manifold import TSNE

# Create a TSNE instance: model
model = TSNE(learning_rate =50)

# Apply fit_transform to normalized_movements: tsne_features
tsne_features = model.fit_transform(normalized_movements)

# Select the 0th feature: xs
xs = tsne_features[:, 0]

# Select the 1th feature: ys
ys = tsne_features[:,1]

# Scatter plot
plt.scatter(xs, ys, alpha = 0.5)

# Annotate the points
for x, y, company in zip(xs, ys, companies):
    plt.annotate(company, (x, y), fontsize=5, alpha=0.75)
plt.show()

Unsupervised Learning in Python/Visualization_with_hierarchical_clustering_and_t-SNE.py


import numpy as np
import matplotlib.pyplot as plt
import os.path

#Reading the output
flag = 0
if os.path.exists('../../build/output/simpson_integration/simpson_approximation_errors_v1.txt'):
    flag = 1
    N, deviation = np.loadtxt('../../build/output/simpson_integration/simpson_approximation_errors_v1.txt', skiprows = 1, unpack = True)
elif os.path.exists('output/simpson_integration/simpson_approximation_errors_v1.txt'):
    flag = 2
    N, deviation = np.loadtxt('output/simpson_integration/simpson_approximation_errors_v1.txt', skiprows = 1, unpack = True)
elif os.path.exists('../../build/output/simpson_integration/simpson_approximation_errors.txt'):
    flag = 3
    N, deviation = np.loadtxt('../../build/output/simpson_integration/simpson_approximation_errors.txt', skiprows = 1, unpack = True)
elif os.path.exists('output/simpson_integration/simpson_approximation_errors.txt'):
    flag = 4
    N, deviation = np.loadtxt('output/simpson_integration/simpson_approximation_errors.txt', skiprows = 1, unpack = True)
else:
    print("No output file found")
    exit()

#Fixed quantities
a = 0
b = 2
third_derivative_a = 0
third_derivative_b = 48

#Error computed as I_simpson - I_exact
log_deviation = np.log10(abs(deviation))

#Error from theory
log_theoretical_error = np.log10(1/90*(third_derivative_b-third_derivative_a)*((b-a)/(2**N))**4)

#Error computed trhough the difference between I(N) and I(2N)
log_approximated_error= [None] * (deviation.size-1)
for i in range(0,deviation.size-1):
    log_approximated_error[i] = np.log10(1/15*(abs(deviation[i+1]-deviation[i])))

#Definition of useful quantities
N = 2**N
logN = np.log10(N)

#Plots
fig = plt.figure(figsize=(4.5*np.sqrt(2),4.5))
plt.plot(logN,log_deviation,'o',markersize=5, label = r'$\left| \widetilde{I} - I \right|$')
plt.plot(logN,log_theoretical_error,'o', markersize=5, color = 'red', label = 'Theoretical Error')
plt.plot(logN[1:],log_approximated_error,'o', markersize=5, label = 'Numerical error' )
plt.title("Error analysis for Simpson integration method", fontsize = 14)
plt.xlabel('Log(N)' , fontsize = 12)
plt.ylabel('Log(value)', fontsize = 12)
plt.legend( fontsize = 12)

fit_deviation = np.polyfit(logN[0:10], log_deviation[0:10], 1)
fit_theoretical_error = np.polyfit(logN[0:10], log_theoretical_error[0:10], 1)
fit_approximated_error = np.polyfit(logN[0:10], log_approximated_error[0:10], 1)

print('**********************')
print('PYTHON SCRIPT RESULTS:')
print(f'Deviation slope = {fit_deviation[0]}')
print(f'Theoretical slope = {fit_theoretical_error[0]}')
print(f'Approximated slope = {fit_approximated_error[0]}')
print('**********************')

if(flag == 1 or flag == 3):
    plt.savefig('simpson_approximation_errors.pdf')
else:
    plt.savefig('../pyplots/simpson_integration/simpson_approximation_errors.pdf')

print("\nOutput saved in pyplots/simpson_approximation_errors.pdf")


import numpy as np
import scipy.linalg as la

def qr_algorithm(A, eps=0.01, max_steps=1000):
    for i in range(max_steps):
        Q, R = la.qr(A)
        new_A = Q.T @ A @ Q
        diag_delta = la.norm(np.diag(A) - np.diag(new_A))
        if diag_delta < eps:
            return np.diag(A)
        A = new_A
    raise ValueError("failed to converge" + str(diag_delta))

A = np.array([[0,2,-1],[2,-1,1],[2,-1,3]])

print("eigenvalues of:\n", A)
print("scipy:", sorted(la.eigvals(A).real))
print("own qr algorithm:", sorted(qr_algorithm(A).real))


# -*- coding: utf-8 -*-
"""
Created on Sat Sep 11 13:50:12 2021

@author: Mahfuz_Shazol
"""

import numpy as np

X = np.array([[50, 15, 89, 23, 64],
              [45, 98, 25, 17, 55],
              [35, 37, 9, 100, 61]])

sum_result=X.sum()
print(sum_result)

#sum all rows
row_sum_result=X.sum(axis=0)
print(row_sum_result)

#sum all cols
col_sum_result=X.sum(axis=1)
print(col_sum_result)

#max
max_result=X.max();
print(max_result)
#max in rows
max_row_result=np.max(X,axis=0)
print('max_row_result',max_row_result)
#max in cols
max_col_result=np.max(X,axis=1)
print('max_row_result',max_col_result)

#min
min_result=X.min();
print(min_result)
#min  in rows
min_row_result=np.min(X,axis=0);
print('min_row_result',min_row_result)
min_col_result=np.min(X,axis=1);
print('min_row_result',min_col_result)

#mean
mean_result=X.mean();
print('mean_result',mean_result)
#mean in rows
mean_row_result=np.mean(X,axis=0)
print('mean_row_result',mean_row_result)
#mean in cols
mean_col_result=np.mean(X,axis=1)
print('mean_col_result',mean_col_result)

#product
product_result=X.prod();
print('product_result',product_result)
#mean in rows
product_row_result=np.prod(X,axis=0)
print('product_row_result',product_row_result)
#mean in cols
product_col_result=np.prod(X,axis=1)
print('product_col_result',product_col_result)


import numpy as np
import matplotlib.pyplot as plt

#############
# Equations #
#############

def dS_dt(beta, I, S, N):
    return (-beta * I * S) / N

def dI_dt(beta, I, S, N, gamma):
    return (beta * I * S) / N - gamma * I

def dR_dt(gamma, I):
    return gamma * I

###############
# Runge-Kutta #
###############

def runge_kutta(h, n, beta, I, S, N, gamma, R):
    '''
    Classical 4th Order Runge-Kutta Method

    y' = f(x, y) with initial conditions y(x0) = y0 and step size h

    k1 = h * f(x, y)
    k2 = h * f(x + h / 2, y + k1 / 2)
    k3 = h * f(x + h / 2, y + k2 / 2)
    k4 = h * f(x + h, y + k3)

    x = x + h
    y = y + (k1 + 2 * k2 + 2 * k3 + k4) / 6
    '''

    j = 0
    s, i, r = np.zeros(n + 1), np.zeros(n + 1), np.zeros(n + 1)
    s[0], i[0], r[0] = S, I, R
    while j < n:
        S_k1 = h * dS_dt(beta, i[j], s[j], N)
        I_k1 = h * dI_dt(beta, i[j], s[j], N, gamma)
        R_k1 = h * dR_dt(gamma, i[j])

        S_k2 = h * dS_dt(beta, i[j] + h / 2, s[j] + S_k1 / 2, N)
        I_k2 = h * dI_dt(beta, i[j] + I_k1 / 2, s[j] + h / 2, N, gamma)
        R_k2 = h * dR_dt(gamma, i[j] + h / 2)

        S_k3 = h * dS_dt(beta, i[j] + h / 2, s[j] + S_k2 / 2, N)
        I_k3 = h * dI_dt(beta, i[j] + I_k2 / 2, s[j] + h / 2, N, gamma)
        R_k3 = h * dR_dt(gamma, i[j] + h / 2)

        S_k4 = h * dS_dt(beta, i[j] + h, s[j] + S_k3, N)
        I_k4 = h * dI_dt(beta, i[j] + I_k3, s[j] + h, N, gamma)
        R_k4 = h * dR_dt(gamma, i[j] + h)

        s[j+1] = s[j] + (S_k1 + 2 * S_k2 + 2 * S_k3 + S_k4) / 6
        i[j+1] = i[j] + (I_k1 + 2 * I_k2 + 2 * I_k3 + I_k4) / 6
        r[j+1] = r[j] + (R_k1 + 2 * R_k2 + 2 * R_k3 + R_k4) / 6

        j += 1

    return s, i, r

h = 0.05
n = 5000
# Step-size of 0.05, 5000 iterations, 0.2 contact rate, 1 infected,
# 9999 susceptible, 10000 population, 0.042 transition rate, 0 recovered
s, i, r = runge_kutta(h, n, 1 / 5, 1, 9999, 10000, 1 / 24, 0)

# Plot values
t = np.linspace(0, h * n, len(s))
plt.plot(t, s, 'g-')
plt.plot(t, i, 'r-')
plt.plot(t, r, 'b-')
plt.legend(['Susceptible', 'Infected', 'Recovered'])
plt.xlabel('Time (Days)')
plt.ylabel('Number of People')
plt.title(r'SIR Model: $\beta=0.2, \gamma=0.042$')
plt.show()


from sympy import *
from sympy.matrices import *

class Transform:
    def __init__(self, phi, alpha, a, d):
        self.phi = phi
        self.alpha = alpha
        self.a = a
        self.d = d
        self.DHMatrix()

    def DHMatrix(self):
        # phi = rad(self.phi)
        phi = self.phi
        alpha = rad(self.alpha)
        a = self.a
        d = self.d

        dh = Matrix([[cos(phi), -sin(phi)*cos(alpha)  ,sin(phi)*sin(alpha), a*cos(phi)],
                     [sin(phi),  cos(phi)*cos(alpha), -cos(phi)*sin(alpha), a*sin(phi)],
                     [       0,           sin(alpha),           cos(alpha),          d],
                     [       0,                    0,                    0,          1]])
        self.A = dh

        self.R = dh[:3, :3]
        self.vecA = dh[:3, 3]

# Let's do an analysis with the SSRMS with the shoulder roll joint locked at an angle beta
beta, theta1, theta2, theta3, theta4, theta5, theta6, theta7 = symbols("beta theta1 theta2 theta3 theta4 theta5 theta6 theta7")
d1, d2, d3, d6, d7, a3, a4 = symbols('d1 d2 d3 d6 d7 a3 a4')

# SSRMS
configs = [[theta1, 90,  0, d1],
           [theta2, 90,  0, d2],
           [theta3,  0, a3, d3],
           [theta4,  0, a4,  0],
           [theta5, 90,  0,  0],
           [theta6, 90,  0, d6],
           [theta7, 90,  0, d7]]

# Stanford Arm Example from Class
# configs = [[theta1, -90, 0, d1],
#            [theta2,  90, 0, d2],
#            [   -90,   0, 0, d3],
#            [theta4, -90, 0,  0],
#            [theta5,  90, 0,  0],
#            [theta6,   0, 0,  0]]

# Build our robot
T = []
for config in configs:
    T.append(Transform(*config))

def KJ():
  # Kinematic Jacobian
  # The z_i's need to be WRT the base coordinate system
  z = Matrix([[0], [0], [1]])

  # Calculate all our z vectors
  for i, _ in enumerate(T):
      rot = Identity(3)
      for j in range(i):
          rot *= T[j].R
      T[i].z = rot * z

  # Loop through backwards to calculate the r vectors
  for i, _ in enumerate(T):
      i = len(T) - (i+1)
      rot = Identity(3)
      for j in range(i):
          rot *= T[j].R
      rot *= T[i].vecA
      if (i+1) < len(T):
          rot += T[i+1].r
      T[i].r = rot

  # Calculate the z skew matrices and compute cross products
  for i, _ in enumerate(T):
      T[i].z_skew = Matrix([[         0, -T[i].z[2],  T[i].z[1]],
                            [ T[i].z[2],          0, -T[i].z[0]],
                            [-T[i].z[1],  T[i].z[0],         0]])
      T[i].crossed = T[i].z_skew * T[i].r

  # Combine elements to form Jacobian
  top, bottom = Matrix(), Matrix()
  for i, _ in enumerate(T):
      top = top.row_join(T[i].crossed)
      bottom = bottom.row_join(T[i].z)
  J = top.col_join(bottom)

  return J

def GJ():
  # Geometric Jacobian
  Q_rev = Matrix([[0, -1, 0, 0],
                  [1,  0, 0, 0],
                  [0,  0, 0, 0],
                  [0,  0, 0, 0]])

  for i, _ in enumerate(T):
    print('i ', i)
    if i > 0:
      T[i].Ti = T[i-1].Ti * T[i-1].A
    if i == 0:
      T[i].Ti = Matrix(Identity(4))
    T[i].Ti.simplify()

    T[i].D = simplify(T[i].Ti * Q_rev) * simplify(T[i].Ti.inv())

  Jg = Matrix([[T[0].D[0, 3], T[1].D[0, 3], T[2].D[0, 3], T[3].D[0, 3], T[4].D[0, 3], T[5].D[0, 3], T[6].D[0, 3]],
               [T[0].D[1, 3], T[1].D[1, 3], T[2].D[1, 3], T[3].D[1, 3], T[4].D[1, 3], T[5].D[1, 3], T[6].D[1, 3]],
               [T[0].D[2, 3], T[1].D[2, 3], T[2].D[2, 3], T[3].D[2, 3], T[4].D[2, 3], T[5].D[2, 3], T[6].D[2, 3]],
               [T[0].D[2, 1], T[1].D[2, 1], T[2].D[2, 1], T[3].D[2, 1], T[4].D[2, 1], T[5].D[2, 1], T[6].D[2, 1]],
               [T[0].D[0, 2], T[1].D[0, 2], T[2].D[0, 2], T[3].D[0, 2], T[4].D[0, 2], T[5].D[0, 2], T[6].D[0, 2]],
               [T[0].D[1, 0], T[1].D[1, 0], T[2].D[1, 0], T[3].D[1, 0], T[4].D[1, 0], T[5].D[1, 0], T[6].D[1, 0]]])
  return Jg

# Inverse Kinematic Solution
# T07 = T[0].A * T[1].A * T[2].A * T[3].A * T[4].A * T[5].A * T[6].A

# We know that
# u_x, u_y, u_z, v_x, v_y, v_z, w_x, w_y, w_z, p_x, p_y, p_z = symbols('u_x u_y u_z v_x v_y v_z w_x w_y w_z p_x p_y p_z')
# T07 = Matrix([[u_x, v_x, w_x, p_x],
#               [u_y, v_y, w_y, p_y],
#               [u_z, v_z, w_z, p_z],
#               [  0,   0,   0,   1]])

# And setting T01^-1 * T07 = T12 T23 T34 T45 T56 T67
# print(latex(T[0].A.inv() * T07))
# print(latex(T[1].A * T[2].A * T[3].A * T[4].A * T[5].A * T[6].A))

def IK(SHOULDER=1, WRIST=1, ELBOW=1,
       a3=2.3, a4=2.3, d1=0.65, d2=0.3,
       d3=0.9, d6=0.3, d7=0.65,
       beta=rad(60),
       u_x=0.8021, u_y=-0.5859, u_z=-0.1154,
       v_x=0.1217, v_y= 0.3495, v_z=-0.9290,
       w_x=0.5846, w_y= 0.7311, w_z=0.3517,
       p_x=2.4790, p_y=-2.4734, p_z=-0.4927):
  '''
  Return the IK for a given pose, initial locked angle, and arm characteristics.
  '''

  theta1 = beta

  h1 = -v_z * d7 - d1 + p_z
  q1 = (v_x * d7 - p_x)*cos(beta) + (v_y * d7 - p_y)*sin(beta)

  theta2 = SHOULDER * acos(d3/(sqrt(h1**2 + q1**2))) + atan2(q1, h1) - pi

  theta6 = WRIST * acos(v_z*cos(theta2)-(v_x*cos(theta1) + v_y*sin(theta1))*sin(theta2))

  theta7 = -atan2(((u_x*cos(theta1) + u_y*sin(theta1))*sin(theta2) - u_z*cos(theta2))/sin(theta6),
                  ((w_x*cos(theta1) + w_y*sin(theta1))*sin(theta2) - w_z*cos(theta2))/sin(theta6)) + pi/2

  X = d6 * ((w_z * sin(theta2) + cos(theta2) * (w_x * cos(theta1) + w_y * sin(theta1))) * cos(theta7) - (u_z * sin(theta2) + cos(theta2) * (u_x * cos(theta1) + u_y * sin(theta1))) * sin(theta7)) - d7 * (v_z * sin(theta2) + cos(theta2) * (v_x * cos(theta1) + v_y * sin(theta1))) + (-d1 + p_z) * sin(theta2) + cos(theta2) * (p_x * cos(theta1) + p_y * sin(theta1))
  Y = -d2 + d6 * ((w_x * sin(theta1) - w_y * cos(theta1)) * cos(theta7) - (u_x * sin(theta1) - u_y * cos(theta1)) * sin(theta7)) - d7 * (v_x * sin(theta1) - v_y * cos(theta1)) + p_x * sin(theta1) - p_y*cos(theta1)

  theta4 = ELBOW * acos((X**2 + Y**2 - a3**2 - a4**2)/(2*a3*a4))

  theta3 = atan2(Y*(a3 + a4*cos(theta4)) - X*a4*sin(theta4),
                 X*(a3 + a4*cos(theta4)) + Y*a4*sin(theta4))

  theta5 = atan2((v_x*sin(theta1)-v_y*cos(theta1))/(sin(theta6)),
                 (w_x*sin(theta1)-w_y*cos(theta1))*cos(theta7)-(u_x*sin(theta1)-u_y*cos(theta1))*sin(theta7)) - (theta3 + theta4)

  thetas = []
  for theta in [theta1, theta2, theta3, theta4, theta5, theta6, theta7]:
    thetas.append(deg(theta).evalf())

  thetas = Matrix(thetas)
  return thetas

def IK_sols():
  '''
  Enumerate through the eight possible solutions for a given pose.
  '''

  c = [[ 1,  1,  1],
       [ 1,  1, -1],
       [ 1, -1,  1],
       [-1,  1,  1],
       [ 1, -1, -1],
       [-1,  1, -1],
       [-1, -1,  1],
       [-1, -1, -1]]

  res = []
  for S, E, W in c:
      print(S, E, W)
      t = IK(SHOULDER=S, ELBOW=E, WRIST=W)
      res.append(t)

  stacked = np.zeros((7, 1))
  for row in res:
      stacked = np.hstack((stacked, np.array(row)))

  return stacked[:, 1:].T