# -*- coding: utf-8 -*-
"""
Created on Wed Apr  1 21:24:02 2020

@author: Leonardo Saccotelli
"""

import numpy as np
import matplotlib.pyplot as plt
import InterpolazionePolinomiale_Algoritmi as IP

def createMyFunction(x):
    y = np.sqrt(x)
    return y

#----------------  DEFINIZIONI DATI DI INTERPOLAZIONE
#Estremo inferiore dell'intervallo da cui estrapolo i nodi
a = 0
#Estremo superiore dell'intervallo da cui estrapolo i nodi
b = 1

#Numero di nodi da estrapolare dall'intervallo [a,b]
n = 50
#Estrapolo n+1 nodi equidistanti dall'intervallo [a,b]
xNodes = np.linspace(a, b, n + 1)
#Calcolo la funzione f(x) = sin(x) negli n+1 nodi
yNodes = createMyFunction(xNodes)

#-------------- COSTRUZIONE POLINOMIO DI INTERPOLAZIONE
#Estrapolo i punti in cui calcolare il polinomio
xPoints = np.linspace(a, b, 20 * len(xNodes) + 1)

#Creo e calcolo il polinomio con il metodo dei coefficienti indeterminati
pol_coeff_indet = IP.indeterminateCoefficientFormula(xNodes, yNodes, xPoints)

#Creo e calcolo il polinomio con la prima formula baricentrica di Lagrange in ogni punto xPoint
pol_1_Lagrange = IP.lagrangeFirstBarycentricFormula(xNodes, yNodes, xPoints)

#Creo e calcolo il polinomio con la seconda formula baricentrica di Lagrange in ogni punto xPoint
pol_2_Lagrange = IP.lagrangeSecondBarycentricFormula(xNodes, yNodes, xPoints)

#Creo e calcolo il polinomio con la formula di Newton in ogni punto xPoint
pol_Newton = IP.NewtonPolynomialInterpolation(xNodes, yNodes, xPoints)

#Calcolo la funzione in ogni punto xPoints
f_xPoints = createMyFunction(xPoints)

#------------- Grafico del polinomio di interpolazione
plt.figure(1, figsize=(12, 12))
plt.plot(xPoints, f_xPoints, label='F(x) = Sqrt(x)')

p_lab = 'Coeff Indet: %d nodi' % n
plt.plot(xPoints, pol_coeff_indet, label=p_lab)

p_lab = 'Lagrange_1: %d nodi' % n
plt.plot(xPoints, pol_1_Lagrange, label=p_lab)

p_lab = 'Lagrange_2: %d nodi' % n
plt.plot(xPoints, pol_2_Lagrange, label=p_lab)

p_lab = 'Newton: %d nodi' % n
plt.plot(xPoints, pol_Newton, label=p_lab)

plt.plot(xNodes, yNodes, 'ro')
plt.xlabel('x')
plt.legend(prop={'size': 20}, loc ='best')

#----------------Grafico del resto del polinomio di interpolazione
plt.figure(2, figsize=(12, 12))

r_lab = 'Coeff Indet: %d nodi' % n
plt.semilogy(xPoints, abs(f_xPoints - pol_coeff_indet), label=r_lab)

r_lab = 'Lagrange_1: %d nodi' % n
plt.semilogy(xPoints, abs(f_xPoints - pol_1_Lagrange), label=r_lab)

r_lab = 'Lagrange_2: %d nodi' % n
plt.semilogy(xPoints, abs(f_xPoints - pol_2_Lagrange), label=r_lab)

r_lab = 'Newton: %d nodi' % n
plt.semilogy(xPoints, abs(f_xPoints - pol_Newton), label=r_lab)

plt.xlabel('x')

plt.legend(prop={'size': 20}, loc ='best')

plt.show()


import pandas as pd
from numpy import *
import matplotlib.pyplot as plt
import statsmodels.tsa.stattools as ts
from functions import *

""" This is an implementation of the examples 2.1 to 2.5 from Ernest chan's
book ALGORITHMIC TRADING - Winning Strategies and Their Rationale
"""

if __name__ == "__main__":

    #import data from CSV file
    root_path = '/Users/Javi/Documents/MarketData/'
    # the paths
    # MAC: '/Users/Javi/Documents/MarketData/'
    # WIN: 'C:/Users/javgar119/Documents/Python/Data/'
    filename = 'USDCAD_daily.csv'
    full_path = root_path + filename
    full_dataframe = pd.read_csv(full_path, index_col='Date')

    # create a series with the data range asked
    start_date = '23/07/2007'
    end_date = '28/03/2012'
    data =  subset_dataframe(full_dataframe, start_date, end_date)

    # COMPUTE STATISTICS

    # compute the ADF test with the statsmodels pack
    adf = ts.adfuller(data['Rate'], maxlag=1, regression="c")
    print('****** ADF TEST RESULTS *****')
    print('ADF t-stat: {}'.format(round(adf[0],4)))
    print('p-value: {}'.format(round(adf[1],4)))
    print('usedlag: {}'.format(round(adf[2],4)))
    print('nobs: {}'.format(adf[3]))
    print('critical values: {}'.format(adf[4]))
    # computes the hurst exponent
    print('****** HURST EXPONENT ******')
    print('Hurst: {}'.format(round(hurst(data['Rate']),4)))
    # compute the variance ratio test
    a = log(array(data['Rate']))
    vrtest = vratio(a, cor = 'het', lag = 20)
    print('****** VARIANCE RATIO TEST ******')
    print ('stat: {}, zscore: {}, p-value: {}'.format(round(vrtest[0],4), round(vrtest[1],4), round(vrtest[2],4)))
    # compute half life of the time serie
    print('****** HALF LIFE ******')
    hl = int(half_life(data['Rate']))
    print('half life: {}'.format(hl))

    # LINEAR STRATEGY
    # A linear trading strategy means that the number of units or shares of a
    # unit portfolio we own is proportional to the negative z-score of the
    # price series of that portfolio.

    lookback = int(hl)
    moving_mean = pd.rolling_mean(data, window=lookback)
    moving_std = pd.rolling_std(data,window=lookback)

    z_score = divide(subtract(data['Rate'] , moving_mean['Rate']), moving_std['Rate'])
    numunits = multiply(z_score, -1)
    pnl = divide(multiply(numunits[:-1], diff(data['Rate'])),-numunits[:-1])

    # plot accumulative % PnL

    # some especifications for the charts
    font = {'family' : 'serif',
        'color'  : 'black',
        'weight' : 'normal',
        'size'   : 16,
        }

    plt.plot(cumsum(pnl))
    plt.title('Acumulative result z-score strategy', fontdict=font)
    plt.show()


"""
several loss functions:
CrossEntropy
L1 distance
L2 distance
"""
import numpy as np

class CrossEntropy:
    def __init__(self):
        self.middle = None

    def __call__(self, pred, label):
        return self.forward(pred, label)

    def forward(self, pred, label):
        # default : rows represent the different samples
        #           cols represent the scores
        assert pred.shape == label.shape
        result = (-1 / pred.shape[0]) * np.sum(label * np.log(pred))
        self.middle = pred, label
        return result

    def backward(self):
        pred, label = self.middle
        grad = (-1 / pred.shape[0]) * (label / pred)
        return grad

    def __repr__(self):
        return "Loss Function : CrossEntropy"

class L1:
    def __init__(self):
        self.middle = None

    def __call__(self, pred, label):
        return self.forward(pred, label)

    def forward(self, pred, label):
        assert pred.shape == label.shape
        result = np.mean(np.abs(pred - label))
        self.middle = pred, label
        return result

    def backward(self):
        pred, label = self.middle
        mask = (pred - label) >= 0
        grad = (1 / np.product(pred.shape)) * (2 * mask - 1)
        return grad

    def __repr__(self):
        return "Loss Function : L1"

class L2:
    def __init__(self):
        self.middle = None

    def __call__(self, pred, label):
        return self.forward(pred, label)

    def forward(self, pred, label):
        assert pred.shape == label.shape
        result = np.mean(np.square(pred - label))
        self.middle = pred, label
        return result

    def backward(self):
        pred, label = self.middle
        grad = (2 / np.product(pred.shape)) * (pred - label)
        return grad

    def __repr__(self):
        return "Loss Function : L2"


import matplotlib.pyplot as plt
import numpy as np

import tensor as ts

def plot_signals(s1, s2, signal, t):
    plt.ylabel("Amplitude")
    plt.xlabel("Time [s]")

    ax: plt.Axes = plt.subplot(3, 1, 1)
    ax.plot(t, s1)
    ax.set_title(r"$s_1 = \sin(33Hz * 2\pi t)$")

    ax: plt.Axes = plt.subplot(3, 1, 2)
    ax.plot(t, s2)
    ax.set_title(r"$s_2 = \sin(70Hz * 2\pi t)$")

    ax: plt.Axes = plt.subplot(3, 1, 3)
    ax.plot(t, signal)
    ax.set_title(r"$s = s_1 + s_2$")

    figure: plt.Figure = ax.get_figure()
    # figure.set_size_inches((10, 10))
    figure.tight_layout(h_pad=2)
    figure.show()

def plot_spectrum(amplitudes: np.array, t: np.array, N: int):
    K = len(amplitudes)
    T = t[1] - t[0]  # sampling interval
    # The frequency resolution is determined by: df = sampling frequency / number of samples
    f = np.linspace(0, 1 / T, N)  # (0, 1000), 500 samples

    # we don't care about negative frequencies
    amplitudes = amplitudes[:K // 2]
    f = f[:K // 2]

    figure, ax = plt.subplots()
    ax.bar(f, amplitudes, width=1.5)
    ax.set_ylabel("Amplitude")
    ax.set_xlabel("Frequency [Hz]")
    figure.show()

def main():
    t = np.linspace(0, 0.5, 500)  # 1/1000 -> sampling with 1kH frequency

    # signal = sin(f * 2PIt), where f is signal frequency
    s1 = np.sin(40 * 2 * np.pi * t)
    s2 = 0.5 * np.sin(90 * 2 * np.pi * t)
    signal = s1 + s2
    plot_signals(s1, s2, signal, t)

    N = len(signal)
    K = 200

    frequencies = np.arange(0, K)
    y = ts.fft.dft_naive(signal, frequencies)
    amplitudes = np.abs(y) * 1 / N

    plot_spectrum(amplitudes, t, N)

if __name__ == '__main__':
    main()


#!/usr/bin/python

########################################################
# K-means clustering #
# Sk. Mashfiqur Rahman (CWID: A20102717) #
# collect data from: http://yann.lecun.com/exdb/mnist/#
#######################################################

import numpy as np
import matplotlib.pyplot as plt

def k_means(k, data, _mean):
    N = data.shape[0]
    min_d = np.zeros((N,1),dtype="double")
    min_k = np.zeros((N,1),dtype=int)
    z = np.zeros(shape=(N, k),dtype=int)
    mean_init = np.zeros(np.shape(_mean))
    count = 0
    allowance = 1e-7
    change = np.linalg.norm(_mean - mean_init)
    while change > allowance:
        mean_init = _mean.copy()
        mean_update = np.zeros((k,data.shape[1]),dtype=np.float)
        for i in range(N):
            dist = np.zeros((k,1),dtype="double")
            for j in range(k):
                dist[j] = np.linalg.norm(data[i] - _mean[j])
            min_k[i] = np.argmin(dist) # return the indices of minimum value
            min_d[i] = np.amin(dist)

        for i,j in enumerate(min_k):
                z[i][j] = 1.

        for l in range(k):
            clusters = []
            for i in range(len(min_k)):
                if min_k[i] == l:
                    clusters.append(i)
            center = np.mean(data[clusters],axis=0)
            mean_update[l,:] = center

        _mean = mean_update
        count = count + 1
        change = np.linalg.norm(_mean - mean_init)
        cost = np.sum(min_d)
        print('iteration:',count,'Change:',change,'Cost:',cost)

    return z,_mean

# Test images
test_images_file = open('t10k-images.idx3-ubyte','rb')
test_images = test_images_file.read()
test_images = bytearray(test_images)
test_images = test_images[16:]
test_images_file.close()

test_images = np.array(test_images,"float64")
d = 28 * 28
n = test_images.shape[0] / d
test_images = test_images.reshape(int(n), d)

# Test labels
test_labels_file = open('t10k-labels.idx1-ubyte','rb')
test_labels = test_labels_file.read()
test_labels = bytearray(test_labels)
test_labels = test_labels[8:]
test_labels_file.close()

test_labels = np.array(test_labels)
test_labels_1 = test_labels.reshape(test_labels.shape[0], 1)

N = test_images.shape[0]
flag = 0  # 0: random data points, 1: k-means++ assignment, 2: data point drawn from each label class, 3:final

if flag == 0:
    k = 10
    mean = test_images[np.random.randint(low=0, high=N, size=k)]
    figure, axes = plt.subplots(nrows=5, ncols=2)
    ind = 1
    for axis in axes.flat:
        axis.imshow(mean[ind-1, :].reshape(28, 28), cmap='bone')
        axis.set_axis_off()
        ind += 1
    plt.suptitle("centroid for random datapoints")
    plt.savefig("kmeans1.png", format='png')
    plt.show()

    Z, m = k_means(k, test_images, mean)

    figure, axes = plt.subplots(nrows=5, ncols=2)
    ind = 1
    for axis in axes.flat:
        axis.imshow(m[ind-1].reshape(28, 28), cmap='bone')
        axis.set_axis_off()
        ind += 1
    plt.suptitle("K-means centroid for random datapoints")
    plt.savefig("kmeans2.png", format='png')
    plt.show()

if flag == 1:
    k = 10
    mean = np.zeros(shape=(k, test_images.shape[1]))
    mean[0] = test_images[np.random.randint(N)]
    for j in range(1,k):
        dist = np.array([np.min([np.linalg.norm(x-c)**2 for c in mean]) for x in test_images])
        p = np.true_divide(dist,np.sum(dist))
        cp = p.cumsum()
        r = np.random.random()
        ix = np.where(cp >= r)[0][0]
        mean[j] = np.copy(test_images[ix])

    figure, axes = plt.subplots(nrows=5, ncols=2)
    ind = 1
    for axis in axes.flat:
        axis.imshow(mean[ind-1, :].reshape(28, 28), cmap='bone')
        axis.set_axis_off()
        ind += 1
    plt.suptitle("centroid by K-means++")
    plt.savefig("kmeans3.png", format='png')
    plt.show()

    Z, m = k_means(k, test_images, mean)

    figure, axes = plt.subplots(nrows=5, ncols=2)
    ind = 1
    for axis in axes.flat:
        axis.imshow(m[ind-1].reshape(28, 28), cmap='bone')
        axis.set_axis_off()
        ind += 1
    plt.suptitle("K-means centroid for K-means++")
    plt.savefig("kmeans4.png", format='png')
    plt.show()

if flag == 2:
    k = 10
    mean = np.zeros(shape=(k, test_images.shape[1]))

    for i in range(k):
        label_images = np.copy(test_images[test_labels == i])
        np.random.shuffle(label_images)
        mean[i] = label_images[0]

    figure, axes = plt.subplots(nrows=5, ncols=2)
    ind = 1
    for axis in axes.flat:
        axis.imshow(mean[ind-1, :].reshape(28, 28), cmap='bone')
        axis.set_axis_off()
        ind += 1
    plt.suptitle("centroid by known label")
    plt.savefig("kmeans5.png", format='png')
    plt.show()

    Z, m = k_means(k, test_images, mean)

    figure, axes = plt.subplots(nrows=5, ncols=2)
    ind = 1
    for axis in axes.flat:
        axis.imshow(m[ind-1].reshape(28, 28), cmap='bone')
        axis.set_axis_off()
        ind += 1
    plt.suptitle("K-means centroid for known label")
    plt.savefig("kmeans6.png", format='png')
    plt.show()

if flag == 3:
    k = 3
    mean = np.zeros(shape=(k, test_images.shape[1]))
    mean[0] = test_images[np.random.randint(N)]
    for j in range(1,k):
        dist = np.array([np.min([np.linalg.norm(x-c)**2 for c in mean]) for x in test_images])
        p = np.true_divide(dist,np.sum(dist))
        cp = p.cumsum()
        r = np.random.random()
        ix = np.where(cp >= r)[0][0]
        mean[j] = np.copy(test_images[ix])

    figure, axes = plt.subplots(nrows=1, ncols=3)
    ind = 1
    for axis in axes.flat:
        axis.imshow(mean[ind-1, :].reshape(28, 28), cmap='bone')
        axis.set_axis_off()
        ind += 1
    plt.suptitle("centroid for K-means++ using k=3")
    plt.savefig("kmeans7.png", format='png')
    plt.show()

    Z, m = k_means(k, test_images, mean)

    figure, axes = plt.subplots(nrows=1, ncols=3)
    ind = 1
    for axis in axes.flat:
        axis.imshow(m[ind-1].reshape(28, 28), cmap='bone')
        axis.set_axis_off()
        ind += 1
    plt.suptitle("K-means centroid for K-means++ using k=3")
    plt.savefig("kmeans8.png", format='png')
    plt.show()


from __future__ import division
import numpy as np

# -------------------------------- ProNel ------------------------------------------------------------------
def ProNel(Mix):
    """
    Input parameters
    ----------
    Mix : numpy.ndarray data type (mixing matrix.)

    Returns
    ----------
    ProNel_ret : float (ProNel score for the mixing matrix.)
    """
    Mix = Mix/np.sum(Mix[:,:])

    Mix_MargR = Mix.sum(axis=0)
    Mix_MargR = Mix_MargR[ np.nonzero(Mix_MargR)[0] ]
    Mix_MargC = Mix.sum(axis=1)
    Mix_MargC = Mix_MargC[ np.nonzero(Mix_MargC)[0] ]

    Num_T1 = Mix_MargR * np.log(Mix_MargR)
    Num_T1 = np.sum(Num_T1)

    Num_T2 = Mix_MargC * np.log(Mix_MargC)
    Num_T2 = np.sum(Num_T2)

    MixNz = Mix[np.nonzero(Mix)[0],np.nonzero(Mix)[1]]
    Num_T3 = np.multiply( MixNz, np.log(MixNz) )
    Num_T3 = np.sum(Num_T3)

    Num = Num_T1 + Num_T2 - Num_T3

    Den_T1 = 0.5*Num_T1
    Den_T2 = 0.5*Num_T2
    Den = Den_T1 + Den_T2

    ProNel_ret = Num / Den
    return ProNel_ret

# -------------------------------- ProNe2 ------------------------------------------------------------------
def ProNe2(Mix):
    """
    Input parameters
    ----------
    Mix : numpy.ndarray data type (mixing matrix.)

    Returns
    ----------
    ProNe2_ret : float (ProNe2 score for the mixing matrix.)
    """
    Mix = Mix/np.sum(Mix[:,:])

    Mix_MargR = Mix.sum(axis=0)
    Mix_MargR = Mix_MargR[ np.nonzero(Mix_MargR)[0] ]
    Mix_MargC = Mix.sum(axis=1)
    Mix_MargC = Mix_MargC[ np.nonzero(Mix_MargC)[0] ]

    Num_T1 = np.multiply( Mix, Mix )
    Num_T1 = np.sum(Num_T1)

    Num_T2 = np.sum(Mix_MargC*Mix_MargC) * np.sum(Mix_MargR*Mix_MargR)

    Num = Num_T1 - Num_T2

    Den_T1 = 0.5 * (np.sum(Mix_MargC*Mix_MargC) + np.sum(Mix_MargR*Mix_MargR))
    Den_T2 = Num_T2
    Den = Den_T1 - Den_T2

    ProNe2_ret = Num / Den
    return ProNe2_ret

# -------------------------------- Choice of ProNe ---------------------------------------------------------
def choice(Mix, Type):
    """
    Input parameters
    ----------
    Mix : numpy.ndarray data type (mixing matrix.)
    Type : string data type ('ProNel' or 'ProNe2')
    """
    if Type == 'ProNel':
        return ProNel(Mix=Mix)
    if Type == 'ProNe2':
        return ProNe2(Mix=Mix)


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

def func(x,k):
    #k = 0.707 阻尼比系数
    b = math.acos(k) #阻尼角
    wn = 1 #无阻尼振荡角频率
    c1 = math.sqrt(1-k**2)
    wd = wn*c1 #阻尼振荡角频率
    ans = 1-math.exp(-k*wn*x)*math.sin(wd*x+b)/c1
    return ans

def realTime(k):
    t = np.linspace(0,30,num=30000) # delta t = 0.001
    seqk = [k]*30000
    y = list(map(func,t,seqk))
    realtime = 0
    ttt = []
    for i in range(1,30000+1):
        if  y[-i]<= 1-0.05 or y[-i] >= 1+0.05:
            realtime=t[-i]
            break
    return realtime

def envelopeTime(k):
    return -(math.log(0.05)+math.log(math.sqrt(1-k**2)))/k
def estimateTime(k):
    return 3/k

def solve():
    k = np.linspace(0.1,0.999,num=1000)
    realtime = list(map(realTime,k))
    envelopetime = list(map(envelopeTime,k))
    estimatetime = list(map(estimateTime,k))
    plt.figure()
    plt.plot(k,realtime,label='Real Time')
    plt.plot(k,envelopetime,label ='Envelope Time')
    plt.plot(k,estimatetime,label = 'Estimate Time')
    plt.legend()
    plt.xlabel(r'$\zeta$')
    plt.ylabel(r'$\omega_nt$')
    plt.show()

solve()


import math
import numpy as np
from scipy import optimize

def fit_gauss_1d_zero_c(x, y):
    """
    Fits a*gaussian(0, sig) + sky of mu=0

    Returns
    -------
    model, a, sig, c, rmse
    """
    x, y = np.asarray(x), np.asarray(y)
    gauss0 = lambda x, a, c, sig2: c + a * np.exp(-x ** 2 / (2 * sig2))

    opt, cov = optimize.curve_fit(gauss0, x, y, p0=[1.0, 0.0, 1.0])
    res = gauss0(x, *opt) - y
    rmse = math.sqrt((res * res).sum() / len(res))
    try:
        sig = math.sqrt(opt[2])
    except ValueError:
        sig = 0
    return gauss0, opt[0], sig, opt[1], rmse

def fit_gauss_2d_c(xy ,values, initial_mu = None, mu_radius=(np.inf, np.inf)):
    """
    Fits a*gaussian(mu_x, mu_y, sig) + sky

    Parameters
    ----------
    xy:
        List of coordinates, shape: Nx2

    Returns
    -------
    model, a, mu_x, mu_y, sig, c, rmse
    """
    if initial_mu is None: # initial guess
        initial_mu = xy[0]

    xy = np.asarray(xy).T  # transpose xy[0]=x  xy[1] = y

    def gauss(xy, a, c, mu_x, mu_y, sig2):
        val = c + a * np.exp(-((mu_x - xy[0])** 2 + (mu_y - xy[1])** 2) / (2 * sig2))
        return val

    # gauss = lambda xy, a, c, mu_x, mu_y, sig2: c + a * np.exp(-((mu_x - xy[0])** 2 + (mu_y - xy[1])** 2) / (2 * sig2))

    minimal = np.nanmin(values)
    maximal = np.nanmax(values)
    opt, cov = optimize.curve_fit(gauss, xy, values,
                                  p0=[maximal - minimal, minimal, initial_mu[0], initial_mu[1], 1.0],
                                  bounds=(
                                      [0.0, -np.inf, initial_mu[0]-mu_radius[0], initial_mu[1]-mu_radius[1], -np.inf],
                                      [ np.inf,  np.inf, initial_mu[0]+mu_radius[0], initial_mu[1]+mu_radius[1],  np.inf])
                                  )
    res = (gauss(xy, *opt) - values)
    rmse = math.sqrt((res * res).sum() / len(values)),
    try:
        sig = math.sqrt(opt[4])
    except ValueError:
        sig = 0
    return gauss, opt[0], opt[2], opt[3], sig, opt[1], rmse


# The code to print out the mean height is already included. Complete the code for the median height.
# Replace None with the correct code.
# Use np.std() on the first column of np_baseball to calculate stddev. Replace None with the correct code.
# Do big players tend to be heavier ? Use np.corrcoef() to store the correlation between the first and second column off np_baseball in corr.
# Replace None with the correct code.
# np_baseball is available

# Import numpy
import numpy as np

# Print mean height (first column)
avg = np.mean(np_baseball[:,0])
print("Average: " + str(avg))

# Print median height. Replace 'None'
med = np.median(np_baseball[:,0])
print("Median: " + str(med))

# Print out the standard deviation on height. Replace 'None'
stddev = np.std(np_baseball[:,0])
print("Standard Deviation: " + str(stddev))

# Print out correlation between first and second column. Replace 'None'
corr = np.corrcoef(np_baseball[:,0], np_baseball[:,1])
print("Correlation: " + str(corr))

01-introduction to python for data science/04-numpy/explore-the-baseball-data.py


from scipy.optimize import linprog
import numpy as np

def __linprog_solver_col(value_matrix):
    m, n = value_matrix.shape

    # solve col
    # objectif vector c is 0*x1+0*x2+...+0*xn+v
    C = []
    for i in range(n):
        C.append(0)
    C.append(-1)
    A = []
    for i_col in range(n):
        col = value_matrix[:, i_col]
        constraint_row = []
        for item in col:
            constraint_row.append(-item)
        constraint_row.append(1)
        A.append(constraint_row)
    B = []
    for i in range(m):
        B.append(0)

    A_eq = []
    A_eq_row = []
    for i in range(n):
        A_eq_row.append(1)
    A_eq_row.append(0)
    A_eq.append(A_eq_row)
    B_eq = [1]

    bounds = []
    for i in range(n):
        bounds.append((0, 1))
    bounds.append((None, None))

    res = linprog(C, A_ub=A, b_ub=B, A_eq=A_eq, b_eq=B_eq, bounds=bounds)
    return res['x'][:-1], -res['fun']

def __linprog_solver_row(value_matrix):
    policy, value = __linprog_solver_col(-value_matrix.T)
    return policy, -value

def linprog_solve(value_matrix):
    # rps = nash.Game(np.array(value_matrix))
    # eqs = rps.support_enumeration()
    px, value = __linprog_solver_row(value_matrix)
    py, v2 = __linprog_solver_col(value_matrix)
    # policy_x, policy_y = list(eqs)[0]
    return value, py, px

def run():
    v = [
        [4, 3, 7],
        [1, 2, 3],
        [2, 4, 6]
    ]
    v = np.array(v)
    policy_x, value_x = __linprog_solver_row(v)
    policy_y, value_y = __linprog_solver_col(v)
    linv, linx, liny = linprog_solve(v)
    print('done')


'''
Provides the exact solutions to some SDOF problems, in order
to run tests and estimate the efficiency of the method

All functions return displacement, speed and acceleration in
this order
'''

import numpy as np

# arbitrary parameters and initial conditions, 0 excitation function

def hom_sol(t: float, c: float, k: float, x0: float, dx0: float):

	w_n = np.sqrt(k)

	xi  = c/(2 * w_n)

	w_d = w_n * np.sqrt(1 - xi **2)

	exact_disp = np.exp(- xi * w_n * t)*(x0 * np.cos(w_d *t) +
						(dx0 + xi * w_n * x0)/w_d * np.sin(w_d *t))

	aux_term = - w_d *x0 * np.sin(w_d *t) + (dx0 + xi * w_n * x0) * np.cos(w_d *t)
	d_aux_term = - w_d **2 *x0 * np.cos(w_d *t) - (dx0 + xi * w_n * x0) * w_d * np.sin(w_d *t)

	exact_speed = - xi * w_n * exact_disp + np.exp(- xi * w_n * t)* aux_term

	exact_acc =  - xi * w_n * exact_speed - xi * w_n * np.exp(- xi * w_n * t)* aux_term + np.exp(- xi * w_n * t)* d_aux_term

	return exact_disp, exact_speed, exact_acc

# m = k = 1, c = 0, sin(t) excitation function, 0 initial conditions

def sin_exc_fun(t: float):
	return (np.sin(t) - t* np.cos(t))/2, t * np.sin(t)/2, (np.sin(t)+ t* np.cos(t))/2

# m = k = 1, c = 0, sin(2t) excitation function, 0 initial conditions

def sin2_exc_fun(t: float):
	return -2*np.sin(t) *(np.cos(t)-1)/3, 2*(np.cos(t) - np.cos(2*t))/3, -2*(np.sin(t) - 2* np.sin(2*t))/3


import numpy as np
import matplotlib.pyplot as mpl
from scipy.stats import chisquare
from scipy.optimize import fmin_powell as fmin

t = np.asfarray([ 300 , 350 , 400 , 450 , 500 , 550 , 600 , 650 , 700 , 750 ])
N = np.asfarray([ 803000 , 581083 , 429666 , 320016 , 242783 , 188487 , 150737 , 124103 , 105397 , 92748])

def getN(parameters,t_values):
	A, L, B = parameters
	delta_t	= 10.0
	return (2.0*A/L)*np.exp(-L*t_values)*np.sinh(L*delta_t/2.0)+B*delta_t

p = fmin(lambda x: np.sum(np.power(N-getN(x,t),2.0)), np.asfarray([5*N[0],0.1,0.0]), disp=False)

bestdata = getN(p,t)
bestA, bestL, bestB = p

chi2	= chisquare(N, bestdata)[0]

bestA_err = np.abs(bestA-fmin(lambda x: np.power(chi2 - chisquare(N, getN([x, bestL, bestB],t))[0]-1,2.0), bestA, disp=False))
bestL_err = np.abs(bestL-fmin(lambda x: np.power(chi2 - chisquare(N, getN([bestA, x, bestB],t))[0]-1,2.0), bestL, disp=False))
bestB_err = np.abs(bestB-fmin(lambda x: np.power(chi2 - chisquare(N, getN([bestA, bestL, x],t))[0]-1,2.0), bestL, disp=False))

bestT		= np.log(2.0)/bestL
bestT_err	= bestT/bestL*bestL_err

print 'Best A: ', bestA, ' Error:', bestA_err
print 'Best L: ', bestL, ' Error:', bestL_err
print 'Best B: ', bestB, ' Error:', bestB_err
print 'Best Tau: ', bestT, ' Error:', bestT_err

mpl.figure(facecolor='white')
mpl.plot(t, N, 'b^', label='Measured N')
mpl.plot(t, bestdata, 'g-', label='Curve fit')
mpl.legend()
mpl.savefig('p06_fit.pdf')
#mpl.show()

Statistical Methods 2014 - Home exam/Code/exam_p06.py


import numpy as np
from scipy.special import factorial
import scipy as sp
import matplotlib.pyplot as plt
import scipy.io as sio
"""Calculate the intensities of electric fields.
"""
def calculate_e_field_intensity(l, p, w0, x, y, petaledbeam):
    """
    calculates intensity field of LG beam on a grid with size set by x and y

    Args:
        l (int): OAM azimuthal mode number
        p (int): OAM radial mode number
        w0 (float): beam waist
        x (int): grid size in x direction
        y (int): grid size in y direction
        petaledbeam (bool): calculates interference fringes of conjugate (+/-l) beams if true, calculates intensity field of single beam if false

    Returns:
        intensity_normalized (np array): intensity field calculated on x,y grid normalized by maximum intensity
        intensity_shape (tuple of ints): shape of intensity_normalized

    """
    x = np.arange(-np.floor(x/2.), np.floor(x/2.))
    y = np.arange(-np.floor(y/2.), np.floor(y/2.))

    x_, y_ = np.meshgrid(x, y)
    r = np.sqrt(x_**2+y_**2)
    phi = np.arctan2(y_, x_)
    gaussian = np.sqrt(2) / (np.sqrt(np.pi)*w0) * np.exp(-r**2/(w0**2))

    # LG beam for arbitrary l & p
    LG = sp.special.genlaguerre(p, abs(l))

    LGlp = np.sqrt(factorial(p)) / np.sqrt(factorial(p+np.absolute(l)))\
           * (np.sqrt(2)*r/w0)**(np.absolute(l)) * np.exp(1j*l*phi) * gaussian\
           * LG(2*r**2/w0**2)

    if petaledbeam:
        fieldout = (LGlp+np.conj(LGlp))/2
        intensity = np.abs(fieldout*np.conj(fieldout))
    else:
        intensity = np.abs(LGlp*np.conj(LGlp))

    intensity_normalized = np.double(intensity/np.max(intensity))
    intensity_shape = intensity_normalized.shape
    return intensity_normalized, intensity_shape

def calculate_e_field_intensity_linear(w0, x, y, alpha, fringes=True):
    """
    calculates intensity field of Gaussian beam on a grid with size set by x and y

    Args:
        w0 (float): beam waist
        x (int): grid size in x direction
        y (int): grid size in y direction
        alpha (float): angle between beams
        fringes (bool): calculates interference fringes if True

    Returns:
        intensity_normalized (np array): intensity field calculated on x,y grid normalized by maximum intensity
        intensity_shape (tuple of ints): shape of intensity_normalized

    """
    x = np.arange(-np.floor(x/2.),np.floor(x/2.))
    y = np.arange(-np.floor(y/2.),np.floor(y/2.))

    x_, y_ = np.meshgrid(x,y)
    r = np.sqrt(x_**2+y_**2)
    phi = np.arctan2(y_, x_)
    gaussian = np.sqrt(2) / (np.sqrt(np.pi)*w0) * np.exp(-r**2/(w0**2)) * np.exp(-alpha*1j*x_)
    if fringes:
        fieldout = (gaussian+np.conj(gaussian))/2
        intensity = np.abs(fieldout*np.conj(fieldout))
    else:
        intensity = np.abs(gaussian*np.conj(gaussian))

    intensity_normalized = np.double(intensity/np.max(intensity))
    intensity_shape = intensity_normalized.shape
    return intensity_normalized, intensity_shape


import math
import numpy

global result_matrix, result
result_matrix = [[0]*5]*4
result = []*4

def gauss_method(matrix, size):
    if size == 0:
        return
    global result_matrix
    a_max = -1000
    i_max = 0
    j_max = 0

    for i in range(len(matrix)):
        for j in range(len(matrix[i])-1):
            if abs(matrix[i][j]) > a_max:
                a_max = abs(matrix[i][j])
                i_max = i
                j_max = j
    m = [0]*len(matrix)

    for i in range(len(m)):
        m[i] = -1 * matrix[i][j_max]/matrix[i_max][j_max]

    for i in range(len(matrix)):
        if i != i_max:
            for j in range(len(matrix[i])):
                matrix[i][j] = round(matrix[i][j] + matrix[i_max][j] * m[i], 2)

    result_matrix[i_max] = matrix[i_max]
    matrix[i_max] = [0]*len(matrix[i_max])
    gauss_method(matrix, size-1)

def solve_matrix(matrix):
    size = len(matrix)
    m1 = [[0]*size]*size
    v1 = [0]*size

    for i in range(size):
        v1[i] = matrix[i][size]
        m1[i] = matrix[i][:size]

    nm1 = numpy.array(m1)
    nv1 = numpy.array(v1)

    return numpy.linalg.solve(nm1, nv1)

def yakobi(A, b, eps=0.001):
    def check_conv():
        for i in range(0, A.shape[0]):
            sum = 0
            for j in range(0, A.shape[1]):
                if i != j:
                    sum += abs(A[i][j])
            if sum > abs(A[i][i]):
                return False
        return True

    if not check_conv():
        raise ValueError("Method does not converge")

    def calc_iter_process():
        iter_process = numpy.empty([4, 5])
        for i in range(0, A.shape[0]):
            arr = numpy.array(-A[i] / A[i][i])
            arr[i] = 0
            arr = numpy.append(arr, b[i] / A[i][i])
            iter_process[i] = arr
        return iter_process

    def calc_x_k(matrix, x_prev):
        return matrix @ x_prev

    iter = calc_iter_process()
    x_cur = numpy.array([0, 0, 0, 0])
    x_prev = numpy.array([100, 100, 100, 100])
    while numpy.abs(numpy.amax(x_cur - x_prev)) > eps:
        x1 = calc_x_k(iter, numpy.append(x_cur, 1))
        x_prev = x_cur
        x_cur = x1
    return x_cur

my_matrix = [[3, 1, -1, -1, 10],  [1, 10, -1, 1, 3],  [1, -1, 10, 1, -8],  [-1, 1, -1, 10, 10]]
gauss_method(my_matrix, 4)
result = solve_matrix(result_matrix)
print("Gauss result:")
print(result)

xA = numpy.array([[3, 1, -1, -1],  [1, 10, -1, 1],  [1, -1, 10, 1],  [-1, 1, -1, 10]])
xb = numpy.array([10, 3, -8, 10])
print("Yakobi result:")
print(yakobi(xA, xb).astype(numpy.float32))

xA_inv = numpy.linalg.inv(xA)
print("Number of conditionality is ", numpy.linalg.norm(xA, numpy.inf) * numpy.linalg.norm(xA_inv, numpy.inf))


import numpy as np
import pandas as pd
from collections import Counter
import math
import scipy.stats as ss

# These functions are adapted from the SweetViz package, which took them over
# from dython. SweetViz can be found at https://github.com/fbdesignpro/sweetviz

def convert(data, to):
    converted = None
    if to == 'array':
        if isinstance(data, np.ndarray):
            converted = data
        elif isinstance(data, pd.Series):
            converted = data.values
        elif isinstance(data, list):
            converted = np.array(data)
        elif isinstance(data, pd.DataFrame):
            converted = data.as_matrix()
    elif to == 'list':
        if isinstance(data, list):
            converted = data
        elif isinstance(data, pd.Series):
            converted = data.values.tolist()
        elif isinstance(data, np.ndarray):
            converted = data.tolist()
    elif to == 'dataframe':
        if isinstance(data, pd.DataFrame):
            converted = data
        elif isinstance(data, np.ndarray):
            converted = pd.DataFrame(data)
    else:
        raise ValueError("Unknown data conversion: {}".format(to))
    if converted is None:
        raise TypeError(
            'cannot handle data conversion of type: {} to {}'.format(
                type(data), to))
    else:
        return converted

def conditional_entropy(x, y):
    """
    Calculates the conditional entropy of x given y: S(x|y)
    Wikipedia: https://en.wikipedia.org/wiki/Conditional_entropy
    **Returns:** float
    Parameters
    ----------
    x : list / NumPy ndarray / Pandas Series
        A sequence of measurements
    y : list / NumPy ndarray / Pandas Series
        A sequence of measurements
    """
    y_counter = Counter(y)
    xy_counter = Counter(list(zip(x, y)))
    total_occurrences = sum(y_counter.values())
    entropy = 0.0
    for xy in xy_counter.keys():
        p_xy = xy_counter[xy] / total_occurrences
        p_y = y_counter[xy[1]] / total_occurrences
        entropy += p_xy * math.log(p_y / p_xy)
    return entropy

# IMPORTANT: look at the order of arguments y and x
def theils_u(y, x):
    """
    IMPORTANT: look at the order of arguments y and x
    Calculates Theil's U statistic (Uncertainty coefficient) for categorical-
    categorical association. This is the uncertainty of x given y: value is
    on the range of [0,1] - where 0 means y provides no information about
    x, and 1 means y provides full information about x.
    This is an asymmetric coefficient: U(x,y) != U(y,x)
    Wikipedia: https://en.wikipedia.org/wiki/Uncertainty_coefficient
    **Returns:** float in the range of [0,1]
    Parameters
    ----------
    x : list / NumPy ndarray / Pandas Series
        A sequence of categorical measurements
    y : list / NumPy ndarray / Pandas Series
        A sequence of categorical measurements
    """
    s_xy = conditional_entropy(x, y)
    x_counter = Counter(x)
    total_occurrences = sum(x_counter.values())
    p_x = list(map(lambda n: n / total_occurrences, x_counter.values()))
    s_x = ss.entropy(p_x)
    if s_x == 0:
        return 1
    else:
        return (s_x - s_xy) / s_x

def theils_sym_u(y, x):
    """
    Calculates the symmetric version of the Uncertainty coefficient.
    Wikipedia: https://en.wikipedia.org/wiki/Uncertainty_coefficient
    **Returns:** float in the range of [0,1]
    Parameters
    ----------
    x : list / NumPy ndarray / Pandas Series
        A sequence of categorical measurements
    y : list / NumPy ndarray / Pandas Series
        A sequence of categorical measurements
    """
    s_xy = conditional_entropy(x, y)
    s_yx = conditional_entropy(y, x)

    x_counter = Counter(x)
    x_total_occurrences = sum(x_counter.values())

    y_counter = Counter(y)
    y_total_occurrences = sum(y_counter.values())

    p_x = list(map(lambda n: n / x_total_occurrences, x_counter.values()))
    p_y = list(map(lambda n: n / y_total_occurrences, y_counter.values()))

    s_x = ss.entropy(p_x)
    s_y = ss.entropy(p_y)

    if s_x == 0:
        u_xy = 1
    else:
        u_xy = (s_x - s_xy) / s_x

    if s_y == 0:
        u_yx = 1
    else:
        u_yx = (s_y - s_yx) / s_y

    return (s_x * u_xy + s_y * u_yx) / (s_x + s_y)

def correlation_ratio(categories, measurements):
    """
    Calculates the Correlation Ratio (sometimes marked by the greek letter Eta)
    for categorical-continuous association.
    Answers the question - given a continuous value of a measurement, is it
    possible to know which category is it associated with?
    Value is in the range [0,1], where 0 means a category cannot be determined
    by a continuous measurement, and 1 means a category can be determined with
    absolute certainty.
    Wikipedia: https://en.wikipedia.org/wiki/Correlation_ratio
    **Returns:** float in the range of [0,1]
    Parameters
    ----------
    categories : list / NumPy ndarray / Pandas Series
        A sequence of categorical measurements
    measurements : list / NumPy ndarray / Pandas Series
        A sequence of continuous measurements
    """
    categories = convert(categories, 'array')
    measurements = convert(measurements, 'array')
    fcat, _ = pd.factorize(categories)
    cat_num = np.max(fcat) + 1
    y_avg_array = np.zeros(cat_num)
    n_array = np.zeros(cat_num)
    for i in range(0, cat_num):
        cat_measures = measurements[np.argwhere(fcat == i).flatten()]
        n_array[i] = len(cat_measures)
        y_avg_array[i] = np.average(cat_measures)
    y_total_avg = np.sum(np.multiply(y_avg_array, n_array)) / np.sum(n_array)
    numerator = np.sum(
        np.multiply(n_array, np.power(np.subtract(y_avg_array, y_total_avg),
                                      2)))
    denominator = np.sum(np.power(np.subtract(measurements, y_total_avg), 2))
    if numerator == 0:
        eta = 0.0
    else:
        eta = np.sqrt(numerator / denominator)
    return eta


# -*- coding: utf-8 -*-
"""
Created on Tue Aug 31 09:59:05 2021

@author: Julien

https://en.wikipedia.org/wiki/L%C3%A9vy_C_curve
"""

#  _____                            _
# |_   _|                          | |
#   | |  _ __ ___  _ __   ___  _ __| |_ ___
#   | | | '_ ` _ \| '_ \ / _ \| '__| __/ __|
#  _| |_| | | | | | |_) | (_) | |  | |_\__ \
# |_____|_| |_| |_| .__/ \___/|_|   \__|___/
#                 | |
#                 |_|

import cmath
import numpy as np

#   _____                _              _
#  / ____|              | |            | |
# | |     ___  _ __  ___| |_ __ _ _ __ | |_ ___
# | |    / _ \| '_ \/ __| __/ _` | '_ \| __/ __|
# | |___| (_) | | | \__ \ || (_| | | | | |_\__ \
#  \_____\___/|_| |_|___/\__\__,_|_| |_|\__|___/

X_LIMITS = (-0.6, 1.6)
Y_LIMITS = (-0.4, 1.1)

#  ______                _   _
# |  ____|              | | (_)
# | |__ _   _ _ __   ___| |_ _  ___  _ __  ___
# |  __| | | | '_ \ / __| __| |/ _ \| '_ \/ __|
# | |  | |_| | | | | (__| |_| | (_) | | | \__ \
# |_|   \__,_|_| |_|\___|\__|_|\___/|_| |_|___/

def compute_new(z1, z2, up):
    '''
    uses complex numbers to compute the next points to add for each edge.

    Parameters
    ----------
    z1 : complex
        first vertice.
    z2 : complex
        second vertice.
    up : boolean
        wether or not add the point in a clockwise or counterclockwise fashion.

    Returns
    -------
    complex
        the new point(s) generated from the given edge.
    '''

    v = (z2-z1) /2
    v_mod, v_phas = cmath.polar(v)
    v_mod *= np.sqrt(2)

    return cmath.rect(v_mod, v_phas)*1j**0.5

def partial_Levi_curve(T):
    '''
    Generates the next generation of the fractal curve algorithm. For each pair of consecutive points of T
    that make a vertice, we add between those two points the new point(s) generated by the "compute_new"
    method.

    Parameters
    ----------
    T : list[complex]
        the current state of the algorithm.

    Returns
    -------
    res : list[complex]
        The next step of the algorithm.
    '''

    res = []
    for i in range(len(T)-1):
        res.append(T[i])
        res.append(T[i]+compute_new(T[i], T[i+1], i%2==0))
    res.append(T[-1])
    return res

def Levi_curve(n):
    '''
    Recursive method to build the final fractal curve of degree n.

    Parameters
    ----------
    n : int
        The degree of the fractal curve to build.

    Returns
    -------
    list[complex]
        The list of complex numbers that represent the n-th degree fractal curve.
    '''

    if n==0 :
        return [complex(0,0), complex(1,0)]
    else :
        return partial_Levi_curve(Levi_curve(n-1))

def pts_num(n):
    '''
    Optional function that returns the amount of points in the n-th generation of the algorithm.

    Parameters
    ----------
    n : int
        The degree of the fractal curve.

    Returns
    -------
    int
        The number of vertices needed to build the n-th degree fractal curve.
    '''

    n0 = 2
    return (2**n)*(n0-1)+1

#  _            _
# | |          | |
# | |_ ___  ___| |_ ___
# | __/ _ \/ __| __/ __|
# | ||  __/\__ \ |_\__ \
#  \__\___||___/\__|___/

if __name__ == '__main__' :
    import matplotlib.pyplot as plt

    N = 20
    L = Levi_curve(N)

    def plot(C_List):
        Lr = [el.real for el in C_List]
        Li = [el.imag for el in C_List]
        plt.plot(Lr, Li, lw=np.exp(-N/7))

    plot(L)

    plt.axis('equal')
    plt.show()


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore")
import yfinance as yf
yf.pdr_override()
import datetime as dt

# input
symbol = 'AAPL'
start = dt.date.today() - dt.timedelta(days = 365*2)
end = dt.date.today()

# Read data
df = yf.download(symbol,start,end)

def linear_weight_moving_average(close, n):
    lwma = [np.nan] * n
    for i in range(n, len(close)):
        lwma.append((close[i - n : i] * (np.arange(n) + 1)).sum()/(np.arange(n + 1).sum()))
    return lwma

df['LWMA'] = linear_weight_moving_average(df['Adj Close'], 5)

fig = plt.figure(figsize=(14,7))
ax1 = plt.subplot(2, 1, 1)
ax1.plot(df['Adj Close'])
ax1.set_title('Stock '+ symbol +' Closing Price')
ax1.set_ylabel('Price')

ax2 = plt.subplot(2, 1, 2)
ax2.plot(df['LWMA'], label='Linearly Weighted Moving Average', color='red')
#ax2.axhline(y=0, color='blue', linestyle='--')
#ax2.axhline(y=0.5, color='darkblue')
#ax2.axhline(y=-0.5, color='darkblue')
ax2.grid()
ax2.set_ylabel('Linearly Weighted Moving Average')
ax2.set_xlabel('Date')
ax2.legend(loc='best')
plt.show()

# ## Candlestick with Linearly Weighted Moving Average
from matplotlib import dates as mdates

dfc = df.copy()
dfc['VolumePositive'] = dfc['Open'] < dfc['Adj Close']
#dfc = dfc.dropna()
dfc = dfc.reset_index()
dfc['Date'] = pd.to_datetime(dfc['Date'])
dfc['Date'] = dfc['Date'].apply(mdates.date2num)
from mplfinance.original_flavor import candlestick_ohlc
fig = plt.figure(figsize=(14,7))
ax1 = plt.subplot(2, 1, 1)
candlestick_ohlc(ax1,dfc.values, width=0.5, colorup='g', colordown='r', alpha=1.0)
ax1.xaxis_date()
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%d-%m-%Y'))
ax1.grid(True, which='both')
ax1.minorticks_on()
ax1v = ax1.twinx()
colors = dfc.VolumePositive.map({True: 'g', False: 'r'})
ax1v.bar(dfc.Date, dfc['Volume'], color=colors, alpha=0.4)
ax1v.axes.yaxis.set_ticklabels([])
ax1v.set_ylim(0, 3*df.Volume.max())
ax1.set_title('Stock '+ symbol +' Closing Price')
ax1.set_ylabel('Price')

ax2 = plt.subplot(2, 1, 2)
ax2.plot(df['LWMA'], label='Linearly Weighted Moving Average', color='red')
ax2.grid()
ax2.set_ylabel('Linearly Weighted Moving Average')
ax2.set_xlabel('Date')
ax2.legend(loc='best')
plt.show()


import numpy as np
import numpy.linalg as linalg

def compute_Z(X, centering=True, scaling=False):
    if centering == True:
        col_averages = np.mean(X, axis=0)
        for i in range(X.shape[1]):
            X[:,i] = X[:,i] - col_averages[i]

    if scaling == True:
        col_std = np.std(X, axis=0)

        for i in range(X.shape[1]):
            X[:,i] = X[:,i] / col_std[i]

    return X

def compute_covariance_matrix(Z):
    cov = np.matmul(Z.T,Z)
    return cov

def find_pcs(COV):
    eigenValues, eigenVectors = linalg.eig(COV)
    idx = eigenValues.argsort()[::-1]
    eigenValues = eigenValues[idx]
    eigenVectors = eigenVectors[:,idx]

    return eigenValues, eigenVectors

def project_data(Z, PCS, L, k, var):

    return 1

# Test Data
X = np.array([[-1,-1],[-1,1],[1,-1],[1,1]])

# Test Script
Z = compute_Z(X)
COV = compute_covariance_matrix(Z)
L, PCS = find_pcs(COV)
Z_star = project_data(Z, PCS, L, 1, 0)


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

import numpy as np

def euclidean_distant(vector1, vector2):
    """欧式距离"""
    vector1 = np.mat(vector1)
    vector2 = np.mat(vector2)
    return np.sqrt((vector1 - vector2) * (vector1 - vector2).T).item()

def manhattan_distant(vector1, vector2):
    """曼哈顿距离"""
    vector1 = np.mat(vector1)
    vector2 = np.mat(vector2)
    return np.sum(np.abs(vector1 - vector2))

def cosine_distant(vector1, vector2):
    """余弦距离"""
    vector1 = np.mat(vector1)
    vector2 = np.mat(vector2)
    vector1_norm = np.linalg.norm(vector1)
    vector2_norm = np.linalg.norm(vector2)
    dot_norm = vector1_norm * vector2_norm
    dot_vs = np.dot(vector1, vector2)
    return np.divide(dot_vs, dot_norm).item()

def pearson_similar(vector1, vector2):
    """皮尔逊相关系数"""
    if len(vector1) < 3:
        return 1.0
    return 0.5 + 0.5 * np.corrcoef(vector1, vector2, rowvar=0)[0][1]


"""
Example app demonstrating how to use the HoloViews API to generate
a bokeh app with complex interactivity. Uses a RangeXY stream to allow
interactive exploration of the mandelbrot set.
"""

import numpy as np
import holoviews as hv

from holoviews import opts
from holoviews.streams import RangeXY
from numba import jit

renderer = hv.renderer('bokeh')

@jit
def mandel(x, y, max_iters):
    """
    Given the real and imaginary parts of a complex number,
    determine if it is a candidate for membership in the Mandelbrot
    set given a fixed number of iterations.
    """
    i = 0
    c = complex(x,y)
    z = 0.0j
    for i in range(max_iters):
        z = z*z + c
        if (z.real*z.real + z.imag*z.imag) >= 4:
            return i

    return 255

@jit
def create_fractal(min_x, max_x, min_y, max_y, image, iters):
    height = image.shape[0]
    width = image.shape[1]

    pixel_size_x = (max_x - min_x) / width
    pixel_size_y = (max_y - min_y) / height
    for x in range(width):
        real = min_x + x * pixel_size_x
        for y in range(height):
            imag = min_y + y * pixel_size_y
            color = mandel(real, imag, iters)
            image[y, x] = color

    return image

def get_fractal(x_range, y_range):
    (x0, x1), (y0, y1) = x_range, y_range
    image = np.zeros((600, 600), dtype=np.uint8)
    return hv.Image(create_fractal(x0, x1, -y1, -y0, image, 200),
                    bounds=(x0, y0, x1, y1))

# Define stream linked to axis XY-range
range_stream = RangeXY(x_range=(-1., 1.), y_range=(-1., 1.))

# Create DynamicMap to compute fractal per zoom range and
# adjoin a logarithmic histogram
dmap = hv.DynamicMap(get_fractal, label='Manderbrot Explorer',
                     streams=[range_stream]).hist(log=True)

# Apply options
dmap.opts(
    opts.Histogram(framewise=True, logy=True, width=200, xlim=(1, None)),
    opts.Image(cmap='fire', logz=True, height=600, width=600,
               xaxis=None, yaxis=None))

doc = renderer.server_doc(dmap)
doc.title = 'Mandelbrot Explorer'


import random
from math import exp,fabs,cos,pi
from numpy import zeros,multiply,add,ndarray
from typing import Callable

RealFunc = Callable[[ndarray], float]  # type alias for a real -> real function

def ConstrainX(x:ndarray,lowerbound:ndarray, upperbound:ndarray)-> ndarray:
    for i in range(len(x)):
        x[i]=min(max(x[i],lowerbound[i]),upperbound[i])

    return x.copy()

def ConstrainV(tempV:ndarray,Vmax:float)->ndarray:
    for i in range(len(tempV)):
        tempV[i]=min(max(tempV[i],-Vmax),Vmax)

    return tempV.copy()

def GenerateR(u0:float,y0:float,length:int)->(float,float,ndarray):
    result=zeros((length,1))
    for i in range(length):
       y0 = cos(2 * pi * u0) + y0 * exp(-3)
       u0 = (u0 + 400 + 12 * y0) % 1.0
       result[i] = min(max(u0, 0), 1)
    return (u0,y0,result)

def swaplocalbest(function:RealFunc,oldx:ndarray, newx:ndarray)->ndarray:
     olderror=function(oldx)
     newerror=function(newx)
     if newerror<olderror:
         return newx.copy()
     if newerror>=olderror:
         return oldx.copy()

def chaoticPSOOptimize(function: RealFunc,lowerbound:ndarray,upperbound:ndarray,
     maximumiteration:int,initialgusssize:int,initialguess:ndarray,numofswarms:int,
     tolerance:float
) -> float:
   inertiaweightmax=1.2
   inertiaweightmin=0.1
   chi=0.73
   c1=2.0
   c2=2.0
   Vmax=4.0
   detalweight = (inertiaweightmax - inertiaweightmin) / maximumiteration
   minerror =9999999999999.999
   localswarm ={}
   localbest ={}
   Velocity = {}
   # Initialize
   temp=zeros((len(lowerbound),1))
   tempV=zeros((len(lowerbound),1))
   globalbest=initialguess.copy()
   minerror = function(globalbest)
   u0=1.0
   y0=1.0
   for i in range(initialgusssize):
     for j in range(len(lowerbound)):
        y0 = cos(2 * pi * u0) + y0 * exp(-3)
        u0 = (u0 + 400 + 12 * y0) % 1.0
        temp[j]=(upperbound[j] - lowerbound[j]) * min(max(u0, 0), 1) + lowerbound[j]
        y0 = cos(2 * pi * u0) + y0 * exp(-3)
        u0 = (u0 + 400 + 12 * y0) % 1.0
        tempV[j] = 2 * Vmax * min(max(u0, 0), 1) - Vmax
     localswarm[i]=ConstrainX(temp,lowerbound,upperbound)
     localbest[i]=initialguess.copy()
     Velocity[i]=ConstrainV(tempV,Vmax)
     error = function(temp)
     if error<minerror:
        minerror=error
        globalbest=temp.copy()
   oldglobalerror=minerror
   u0 = 1.00
   y0 = 1.00
   for i in range(maximumiteration):
       tempweight = (inertiaweightmin+(inertiaweightmax-inertiaweightmin) / maximumiteration* i)
       for j in range(numofswarms):
            (u0,y0,R1)=GenerateR(u0,y0,len(lowerbound))
            (u0,y0,R2)=GenerateR(u0,y0,len(lowerbound))
            item2 = multiply((localbest[j].copy()-localswarm[j].copy()),R1*c1)
            item3 = multiply((globalbest-localswarm[j].copy()), R2*c2)
            item1 = add( Velocity[j].copy()*tempweight, item2)
            item1 = add(item1, item3)
            localswarm[j] = ConstrainX(add(localswarm[j].copy(), ConstrainV(item1*chi, Vmax)),lowerbound,upperbound)
            Velocity[j] = ConstrainV(item1*chi, Vmax)
            newlocalbest = swaplocalbest(function,localswarm[j].copy(), localswarm[j])
            localbest[j] = newlocalbest
            localerror = function(localbest[j])
            if localerror < minerror:
               globalbest = localbest[j].copy()
               minerror = localerror

       if fabs(oldglobalerror - minerror) < tolerance and i>5:
          print("Objective function value: = %f" %minerror)
          break
       else:
         oldglobalerror = minerror
         print("Objective function value: = %f" %minerror)
   return globalbest


import numpy as np

VERBOSE = False

class LinearRegressionGD:
    """Linear Regression Using Gradient Descent.
    Parameters
    ----------
    alpha : float
        Learning rate
    n_iterations : int
        No of passes over the training set
    Attributes
    ----------
    w_ : weights/ after fitting the model
    cost_ : total error of the model after each iteration
    """
    def __init__(self, alpha=0.1e-20, n_iterations=10000):
        self.alpha = alpha
        self.n_iterations = n_iterations

    def fit(self, x, y):
        """Fit the training data
        Parameters
        ----------
        x : array-like, shape = [n_samples, n_features]
            Training samples
        y : array-like, shape = [n_samples, n_target_values]
            Target values
        Returns
        -------
        self : object
        """

        self.cost_ = []
        self.w_ = np.zeros((x.shape[1], 1))
        m = x.shape[0]
        for _ in range(self.n_iterations):
            y_pred = np.dot(x, self.w_)
            residuals = y_pred - y
            gradient_vector = np.dot(x.T, residuals)
            self.w_ -= (self.alpha / m) * gradient_vector
            cost = np.sum((residuals**2)) / (2 * m)
            self.cost_.append(cost)

            if VERBOSE:
                print(self.w_)
        return self

    def predict(self, x):
        """ Predicts the value after the model has been trained.
        Parameters
        ----------
        x : array-like, shape = [n_samples, n_features]
            Test samples
        Returns
        -------
        Predicted value
        """
        return np.dot(x, self.w_)


import numpy
import matplotlib.pyplot as plot

from base.elementspace_1D import NodeSpace1D, ElementSpace1D
from base.polynomial import Polynomial
from base.matrix import Matrix

class FiniteDifferenceMethod:

    mesh = []               # ElementSpace

    material_matrix = []    # Matrix(Square)
    force_vector = []       # Matrix(Vector)
    material_function = []  # Polynomial

    solution_space = []     # Matrix(Vector)

    def __init__(self, element_space, material_property, bc_type1, bc_type2):
        self.mesh = element_space
        self.material_matrix = Matrix(numpy.zeros((element_space.n_nodes, element_space.n_nodes)))

        # Define the linear material function for constant material properties
        self.material_function = Polynomial([material_property, 0])

        # Define the solution space to accomodate the initial type1 boundary conditions
        if isinstance(bc_type1, NodeSpace1D):
            self.solution_space = Matrix(bc_type1.nodes)
        elif isinstance(bc_type1, numpy.ndarray):
            self.solution_space = Matrix(bc_type1)
        elif isinstance(bc_type1, Matrix):
            self.solution_space = bc_type1
        else:
            raise TypeError("bc_type1: Unknown Type")

        # Define the force vector to include the initial type2 boundary conditions
        if isinstance(bc_type2, NodeSpace1D):
            self.force_vector = Matrix(bc_type2.nodes)
        elif isinstance(bc_type2, numpy.ndarray):
            self.force_vector = Matrix(bc_type2)
        elif isinstance(bc_type2, Matrix):
            self.force_vector = bc_type2
        else:
            raise TypeError("bc_type2: Unknown Type")

    # The partial differential equations (PDEs) are solved using a Centred-Space,
    # finite difference scheme:
    #       f'(x) = f(x + 1/2*h)/h - f(x-1/2*h)/h
    #
    # When this method is applied to the following differential equation:
    #   -d/dx(K(x) * dU(x)/dx) = F(X)               (Diffusion equation)
    # this results in:
    #
    #   -1/DX * ( K(x_i + DX/2) * ( U(x_i+1) - U(x_i) )/DX
    #           + K(x_i - DX/2) * ( U(x_i) - U(x_i-1) )/DX ) = F(x_i)
    #
    # Rewriting the above equation in terms of U(x) results in the creation
    # of the matrices required to solve the problem:
    def setup(self):
        self.material_matrix[0,0] = 1.0
        for i in range(1, self.mesh.n_nodes - 1):
            x_i = self.mesh.nodes[i]
            DX = x_i - self.mesh.nodes[i - 1]
            DXdiv2 = DX/2
            DXDX = DX*DX
            #print("{}:, DX:{}, DXdiv2:{}, DXDX:{}", i, DX, DXdiv2, DXDX)
            self.material_matrix[i, i - 1] += -self.material_function.evaluate(x_i - DXdiv2)/DXDX
            self.material_matrix[i, i] += self.material_function.evaluate(x_i - DXdiv2)/DXDX
            self.material_matrix[i, i] += self.material_function.evaluate(x_i + DXdiv2)/DXDX
            self.material_matrix[i, i + 1] += -self.material_function.evaluate(x_i + DXdiv2)/DXDX

        self.material_matrix[self.mesh.n_nodes - 1, self.mesh.n_nodes - 1] = 1.0
        #print(self.material_matrix)

    # Solve the matrix equations to generate the solution_space:
    def solve(self):
        self.solution_space = self.material_matrix.get_inverse() * self.force_vector
        #print("Inverse:", self.material_matrix.get_inverse())
        #print("Force_Vector:", self.force_vector)
        #print("Solution_space:", self.solution_space)

    # Plot the nodes at their respective coordinates vs their respective solution values.
    def plot(self):
        plot.plot(self.mesh.nodes, self.solution_space.matrix)
        plot.xlabel("X coordinates")
        plot.ylabel("Degree-of-Freedom Value")
        plot.show()

# Test Methods and Classes
def main():
    # Heat transfer test method
    # Create mesh using parameters:
    x_dimension = 12        # Distance specification (meters)
    n_elements = 8          # Number of finite elements in mesh
    start_pos = 0           # First Node position
    nodes_per_element = 2   # Number of Nodes per element

    # Create mesh of discrete elements that consist of nodes_per_element
    fdm_espace = ElementSpace1D(n_elements, x_dimension, start_pos, nodes_per_element)

    # Analysis Conditions:
    #   - Material properties:
    K = 20      # Constant Stiffness coefficient

    #   - Type 1 (Dirichlet) Boundary Conditions(BCs):
    Type1_BC = 24       # Temperature specification
    Type1_Nodes = [0]   # Node indices subject to Type 1 BC
    BC_Type1 = NodeSpace1D( numpy.zeros( fdm_espace.n_nodes ) )
    BC_Type1.assign_values(Type1_BC, Type1_Nodes)
    #print("BC_Type1:", BC_Type1)

    #   - Type 2 (Neumann) Boundary Conditions(BCs):
    Type2_BC = 16                   # Heat Flux specification
    Type2_Nodes = [n_elements]  # Node indices subject to Type 2 BC
    BC_Type2 = NodeSpace1D( numpy.zeros( fdm_espace.n_nodes ) )
    BC_Type2.assign_values(Type2_BC, Type2_Nodes)
    #print("BC_Type2P:", BC_Type2)

    FDM = FiniteDifferenceMethod(fdm_espace, K, BC_Type1, BC_Type2)
    FDM.setup()
    FDM.solve()
    FDM.plot()

if __name__ == "__main__":
    main()


"""
Author: Abraham Lemus Ruiz
Last change: 7pm 8/12/2020
linkedin: https://www.linkedin.com/in/abraham-lemus-ruiz/
"""

import numpy as np

class LinearRegressionByHand():
    def __init__(self, learning_rate = 0.001, iterations = 100000):
        self.learning_rate = learning_rate
        self.iterations = iterations

    def compute_loss(self, y, y_true):
        loss = np.sum( (y - y_true)**2  )
        return loss / ( 2 * self.n )

    def predict(self, X):  #returns y = b + p1x1 + p2x2 + ... + pnxn
        y = self.b + X @ self.W
        return y

    def gd(self, X, y_true, y_hat):   #Compute the derivatives from the loss function
        db = np.sum(y_hat - y_true) / self.m
        dW = np.sum(  (y_hat - y_true).T @ X, axis=0)/ self.m
        return dW, db

    def update_params(self, dW, db):
        self.W = self.W - self.learning_rate * np.reshape(dW, (self.n, 1))
        self.b = self.b - self.learning_rate * db

    def fit(self, X, y):
        y = y.values.reshape(-1,1)
        self.m, self.n = X.shape # m is # of rows. n is # of features
        self.W = np.random.randn(self.n, 1) # init random params
        self.b = np.random.randn() # bias
        self.losses = []
        for _ in range(self.iterations):
            y_hat = self.predict(X)
            loss = self.compute_loss(y_hat, y)
            self.losses.append(loss)
            dW, db = self.gd(X, y, y_hat)
            self.update_params(dW, db)
        return self.losses


import numpy as np
from astropy import constants as const

h   = const.h.cgs.value
c   = const.c.cgs.value
k_B = const.k_B.cgs.value
sigma = const.sigma_sb.cgs.value

def B_nu(nu, T):
	"""
	Specific brightness

	Parameters
	----------
	nu : float
		frequency [Hz]
	T : float
		Temperature [K]

	Returns
	-------
	B_nu : float
		Specific brightness [ergs s**-1 cm**-2 steradian**-1 Hz**-1]
	"""
	return (2*h*nu**3 / c**2) / (np.exp(h*nu/(k_B*T))-1)

def B(T):
	"""
	Total brightness as a function of temperature (analytic)

	Parameters
	----------
	T : float
		Temperature [K]

	Returns
	-------
	B : float
		Brightness [ergs s**-1 cm**-2 steradian**-1]
	"""
	return sigma * T**4 / np.pi

def d_B_nu_d_nu_dimensionless(x):
	"""
	Calculates d(B_nu) / d (nu),
	as a function of dimensionless units, x = (h nu / k_B T)

	Parameters
	----------
	x : float

	Returns
	-------
	d_B_nu_d_nu_dimensionless : float
		Not normalized to anything meaningful

	"""
	return (3*x**2 / (np.exp(x)-1)) - (x**3 * np.exp(x) / (np.exp(x)-1)**2)

def d_B_lambda_d_lambda_dimensionless(y):
	"""
	Calculates d(B_lambda) / d (lambda),
	as a function of dimensionless units, y = (h c / lambda k_B T)

	Parameters
	----------
	y: float

	Returns
	-------
	d_B_lambda_d_lambda_dimensionless : float
		Not normalized to anything meaningful

	"""
	return (5*y**4 / (np.exp(y)-1)) - (y**5 * np.exp(y) / (np.exp(y)-1)**2)

def d_B_nu_d_T_dimensionless(x):
	"""
	Calculates d(B_nu) / d (T),
	as a function of dimensionless units, x = (h nu / k_B T)

	Parameters
	----------
	x : float

	Returns
	-------
	d_B_nu_d_T_dimensionless : float
		Not normalized to anything meaningful

	"""
	return x**4 * np.exp(x) / (np.exp(x)-1)**2

def d_B_nu_d_T_dimensionless(x):
	"""
	Calculates d(B_nu) / d (T),
	as a function of dimensionless units, x = (h nu / k_B T)

	Parameters
	----------
	x : float

	Returns
	-------
	d_B_nu_d_T_dimensionless : float
		Not normalized to anything meaningful

	"""
	return x**4 * np.exp(x) / (np.exp(x)-1)**2

def d_B_nu_d_T_d_nu_dimensionless(x):
	"""
	Calculates d^2(B_nu) / d (T) / d (nu),
	as a function of dimensionless units, x = (h nu / k_B T)

	Parameters
	----------
	x : float

	Returns
	-------
	d_B_nu_d_T_d_nu_dimensionless : float
		Not normalized to anything meaningful

	"""
	return - np.exp(x)*x**3 * (np.exp(x)*(x-4)+x+4) / (np.exp(x)-1)**3


import unittest
import numpy as np
from nptest import nptest

class MathematicalFunctionsTests(unittest.TestCase):

    #region Trigonometric Functions

    def test_sin_1(self):

        a = np.arange(0, 10, dtype = np.float64)
        a = a[::2]
        b = np.sin(a)
        print(b)

        a = np.arange(0, 10, dtype = np.float32)
        a = a[::2]
        b = np.sin(a)
        print(b)

        a = np.arange(0, 10, dtype = np.int16)
        a = a[::2]
        b = np.sin(a)
        print(b)

        print("********")

        a = np.arange(0, 10, dtype = np.float64).reshape((1,2,5))
        a = a[::2]
        b = np.sin(a)
        print(b)

        print("********")

        a = np.array([[0,1,2,3,4],[5,6,7,8,9]])
        a = a[::2]

        x = a>2

        out = np.zeros_like(a, dtype=np.float64)

        b = np.sin(a, where= x, out = out )
        print(b)

    def test_sin_3(self):

        a = np.arange(0, 5, dtype = np.float64)
        b = np.sin(a)
        c = np.sin(a[::-1])

        print(b)
        print(c)

    def test_cos_1(self):

        a = np.arange(0, 10, dtype = np.float64)
        a = a[::2]
        b = np.cos(a)
        print(b)

        a = np.arange(0, 10, dtype = np.float32)
        a = a[::2]
        b = np.cos(a)
        print(b)

        a = np.arange(0, 10, dtype = np.int16)
        a = a[::2]
        b = np.cos(a)
        print(b)

        print("********")

        a = np.arange(0, 10, dtype = np.float64).reshape((1,2,5))
        a = a[::2]
        b = np.cos(a)
        print(b)

        print("********")

        a = np.array([[0,1,2,3,4],[5,6,7,8,9]])
        a = a[::2]

        x = a>2

        out = np.zeros_like(a, dtype=np.float64)

        b = np.cos(a, where= x, out = out )
        print(b)

    def test_tan_1(self):

        a = np.arange(0, 10, dtype = np.float64)
        a = a[::2]
        b = np.tan(a)
        print(b)

        a = np.arange(0, 10, dtype = np.float32)
        a = a[::2]
        b = np.tan(a)
        print(b)

        a = np.arange(0, 10, dtype = np.int16)
        a = a[::2]
        b = np.tan(a)
        print(b)

        print("********")

        a = np.arange(0, 10, dtype = np.float64).reshape((1,2,5))
        a = a[::2]
        b = np.tan(a)
        print(b)

        print("********")

        a = np.array([[0,1,2,3,4],[5,6,7,8,9]])
        a = a[::2]

        x = a>2

        out = np.zeros_like(a, dtype=np.float64)

        b = np.tan(a, where= x, out = out )
        print(b)

    def test_arcsin_1(self):

        a = np.linspace(-1.0, 1.0, 12)
        print(a)
        b = np.arcsin(a)
        print(b)

        print("********")

        a = np.linspace(-1.0, 1.0, 12).reshape((2,2,3))
        a = a[::2]
        b = np.arcsin(a)
        print(b)

        print("********")

        a = np.linspace(-1.0, 1.0, 12)
        a = a[::2]

        x = a > -0.5
        print(x)

        out = np.zeros_like(a, dtype=np.float64)

        b = np.arcsin(a, where= x, out = out )
        print(b)

    def test_arccos_1(self):

        a = np.linspace(-1.0, 1.0, 12)
        print(a)
        b = np.arccos(a)
        print(b)

        print("********")

        a = np.linspace(-1.0, 1.0, 12).reshape((2,2,3))
        a = a[::2]
        b = np.arccos(a)
        print(b)

        print("********")

        a = np.linspace(-1.0, 1.0, 12)
        a = a[::2]

        x = a > -0.5
        print(x)

        out = np.zeros_like(a, dtype=np.float64)

        b = np.arccos(a, where= x, out = out )
        print(b)

    def test_arctan_1(self):

        a = np.linspace(-1.0, 1.0, 12)
        print(a)
        b = np.arctan(a)
        print(b)

        print("********")

        a = np.linspace(-1.0, 1.0, 12).reshape((2,2,3))
        a = a[::2]
        b = np.arctan(a)
        print(b)

        print("********")

        a = np.linspace(-1.0, 1.0, 12)
        a = a[::2]

        x = a > -0.5
        print(x)

        out = np.zeros_like(a, dtype=np.float64)

        b = np.arctan(a, where= x, out = out )
        print(b)

    def test_hypot_1(self):

        a = np.hypot(np.ones((3, 3)) * 3, np.ones((3, 3)) * 4)
        print(a)

        b = np.hypot(np.ones((3, 3)) * 3, [4])
        print(b)

    def test_arctan2_1(self):

        x = np.array([-1, +1, +1, -1])
        y = np.array([-1, -1, +1, +1])
        z = np.arctan2(y, x) * 180 / np.pi
        print(z)

        a = np.arctan2([1., -1.], [0., 0.])
        print(a)

        b = np.arctan2([0., 0., np.inf], [+0., -0., np.inf])
        print(b)

    def test_degrees_1(self):

        rad = np.arange(12.)*np.pi/6
        a = np.degrees(rad)
        print(a)

        out = np.zeros((rad.shape))
        r = np.degrees(rad, out)
        print(np.all(r == out))

    def test_radians_1(self):

        deg = np.arange(12.0, dtype=np.float64) * 30.0;
        a = np.radians(deg)
        print(a)

        out = np.zeros((deg.shape))
        r = np.radians(deg, out)
        print(np.all(r == out))

    def test_rad2deg_1(self):

        rad = np.arange(12.)*np.pi/6
        a = np.rad2deg(rad)
        print(a)

        out = np.zeros((rad.shape))
        r = np.rad2deg(rad, out)
        print(np.all(r == out))

    def test_deg2rad_1(self):

        deg = np.arange(12.0, dtype=np.float64) * 30.0;
        a = np.deg2rad(deg)
        print(a)

        out = np.zeros((deg.shape))
        r = np.deg2rad(deg, out)
        print(np.all(r == out))

    #endregion

    #region Hyperbolic functions

    def test_sinh_1(self):

        a = np.arange(0, 10, dtype = np.float64)
        a = a[::2]
        b = np.sinh(a)
        print(b)

        a = np.arange(0, 10, dtype = np.float32)
        a = a[::2]
        b = np.sinh(a)
        print(b)

        a = np.arange(0, 10, dtype = np.int16)
        a = a[::2]
        b = np.sinh(a)
        print(b)

        print("********")

        a = np.arange(0, 10, dtype = np.float64).reshape((1,2,5))
        a = a[::2]
        b = np.sinh(a)
        print(b)

        print("********")

        a = np.array([[0,1,2,3,4],[5,6,7,8,9]])
        a = a[::2]

        x = a>2

        out = np.zeros_like(a, dtype=np.float64)

        b = np.sinh(a, where= x, out = out )
        print(b)

    def test_cosh_1(self):

        a = np.arange(0, 10, dtype = np.float64)
        a = a[::2]
        b = np.cosh(a)
        print(b)

        a = np.arange(0, 10, dtype = np.float32)
        a = a[::2]
        b = np.cosh(a)
        print(b)

        a = np.arange(0, 10, dtype = np.int16)
        a = a[::2]
        b = np.cosh(a)
        print(b)

        print("********")

        a = np.arange(0, 10, dtype = np.float64).reshape((1,2,5))
        a = a[::2]
        b = np.cosh(a)
        print(b)

        print("********")

        a = np.array([[0,1,2,3,4],[5,6,7,8,9]])
        a = a[::2]

        x = a>2

        out = np.zeros_like(a, dtype=np.float64)

        b = np.cosh(a, where= x, out = out )
        print(b)

    def test_tanh_1(self):

        a = np.arange(0, 10, dtype = np.float64)
        a = a[::2]
        b = np.tanh(a)
        print(b)

        a = np.arange(0, 10, dtype = np.float32)
        a = a[::2]
        b = np.tanh(a)
        print(b)

        a = np.arange(0, 10, dtype = np.int16)
        a = a[::2]
        b = np.tanh(a)
        print(b)

        print("********")

        a = np.arange(0, 10, dtype = np.float64).reshape((1,2,5))
        a = a[::2]
        b = np.tanh(a)
        print(b)

        print("********")

        a = np.array([[0,1,2,3,4],[5,6,7,8,9]])
        a = a[::2]

        x = a>2

        out = np.zeros_like(a, dtype=np.float64)

        b = np.tanh(a, where= x, out = out )
        print(b)

    def test_arcsinh_1(self):

        a = np.linspace(-1.0, 1.0, 12)
        b = np.arcsinh(a)
        print(b)

        print("********")

        a = np.linspace(-1.0, 1.0, 12).reshape((2,2,3))
        a = a[::2]
        b = np.arcsinh(a)
        print(b)

        print("********")

        a = np.linspace(-1.0, 1.0, 12)
        a = a[::2]

        x = a > -0.5
        print(x)

        out = np.zeros_like(a, dtype=np.float64)

        b = np.arcsinh(a, where= x, out = out )
        print(b)

    def test_arccosh_1(self):

        a = np.linspace(1.0, 2.0, 12)
        b = np.arccosh(a)
        print(b)

        print("********")

        a = np.linspace(1.0, 2.0, 12).reshape((2,2,3))
        a = a[::2]
        b = np.arccosh(a)
        print(b)

        print("********")

        a = np.linspace(1.0, 2.0, 12)
        a = a[::2]

        x = a > 1.5
        print(x)

        out = np.zeros_like(a, dtype=np.float64)

        b = np.arccosh(a, where= x, out = out )
        print(b)

    def test_arctanh_1(self):

        a = np.linspace(-1.0, 1.0, 12)
        b = np.arctanh(a)
        print(b)

        print("********")

        a = np.linspace(-1.0, 1.0, 12).reshape((2,2,3))
        a = a[::2]
        b = np.arctanh(a)
        print(b)

        print("********")

        a = np.linspace(-1.0, 1.0, 12)
        a = a[::2]

        x = a > -0.5
        print(x)

        out = np.zeros_like(a, dtype=np.float64)

        b = np.arctanh(a, where= x, out = out )
        print(b)

        #endregion

    #region Rounding Functions

    def test_around_1(self):

        a = np.around([0.37, 1.64])
        print(a)

        b = np.around([0.37, 1.64], decimals=1)
        print(b)

        c = np.around([.5, 1.5, 2.5, 3.5, 4.5]) # rounds to nearest even value
        print(c)

        d = np.around([1,2,3,11], decimals=1) # ndarray of ints is returned
        print(d)

        e = np.around([1,2,3,11], decimals=-1)
        print(e)

    def test_round_1(self):

        a = np.linspace(-1.0, 1.0, 12).reshape((2,2,3))
        print(a)

        print("********")
        b = np.round_(a, 2)
        print(b)

        print("********")

        c = np.round(a,2)
        print(c)

        print("********")
        b = np.round_(a, 4)
        print(b)

        print("********")

        c = np.round(a,4)
        print(c)

    def test_rint_1(self):

        a = np.array([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0, -4.2])
        b = np.rint(a)
        print(b)

        b = np.rint(a.reshape(2,4))
        print(b)

        x = a > 0.0
        print(x)

        b = np.rint(a, where = x)
        print(b)

    def test_fix_1(self):

        a = np.fix(3.14)
        print(a)

        b = np.fix(3)
        print(b)

        c = np.fix([2.1, 2.9, -2.1, -2.9])
        print(c)

        d = np.fix([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0])
        print(d)

    def test_floor_1(self):

        x = np.array([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0])
        y = np.floor(x);

        print(x)
        print(y)

        return

    def test_ceil_1(self):

        a = np.array([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0])
        b = np.ceil(a)
        print(b)

    def test_trunc_1(self):

        a = np.trunc(3.14)
        print(a)

        b = np.trunc(3)
        print(b)

        c = np.trunc([2.1, 2.9, -2.1, -2.9])
        print(c)

        d = np.trunc([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0])
        print(d)

    #endregion

    #region  Sums, products, differences
    def test_prod_1(self):

        #x = np.array([10,15,25,45,78,90,10,15,25,45,78,90], dtype= np.uint32).reshape(3, 2, -1)
        x = np.array([10,15,25,45,78,90, 10, 15, 25, 45, 78, 90 ], dtype= np.uint64)

        y = np.prod(x);

        print(x)
        print(y)

        return

    def test_prod_2(self):

        a = np.prod([1.,2.])
        print(a)
        print("*****")

        b = np.prod([[1.,2.],[3.,4.]])
        print(b)
        print("*****")

        c = np.prod([[1.,2.],[3.,4.]], axis=1)
        print(c)
        print("*****")

        d = np.array([1, 2, 3], dtype=np.uint8)
        e = np.prod(d).dtype == np.uint
        print(e)
        print("*****")

        f = np.array([1, 2, 3], dtype=np.int8)
        g = np.prod(f).dtype == int
        print(g)
        print("*****")

    def test_prod_3(self):

        a = np.array([1,2,3])
        b = np.prod(a)   # intermediate results 1, 1*2
                            # total product 1*2*3 = 6
        print(b)
        print("*****")

        a = np.array([[1, 2, 3], [4, 5, 6]])
        c = np.prod(a, dtype=float)  # specify type of output
        print(c)
        print("*****")

        d = np.prod(a, axis=0)
        print(d)
        print("*****")

        e = np.prod(a,axis=1)
        print(e)
        print("*****")

    def test_sum_1(self):

        x = np.array([10,15,25,45,78,90,10,15,25,45,78,90], dtype= np.uint32).reshape(3, 2, -1)
        x = x * 3
        y = np.sum(x);

        print(x)
        print(y)

        return

    def test_sum_2(self):

        x = np.array([10,15,25,45,78,90,10,15,25,45,78,90], dtype= np.uint32).reshape(3, 2, -1)
        x = x * 3

        y = np.sum(x, axis=0);
        print(y)
        print("*****")

        y = np.sum(x, axis=1);
        print(y)
        print("*****")

        y = np.sum(x, axis=2);
        print(y)
        print("*****")

        return

    def test_sum_3(self):

        x = np.array([10,15,25,45,78,90,10,15,25,45,78,90], dtype= np.float64).reshape(3, 2, -1)
        x = x * 3.456

        y = np.sum(x, axis=0);
        print(y)
        print("*****")

        y = np.sum(x, axis=1);
        print(y)
        print("*****")

        y = np.sum(x, axis=2);
        print(y)
        print("*****")

        return

    def test_sum_keepdims(self):

        x = np.array([10,15,25,45,78,90], dtype= np.float64)

        y = np.sum(x);
        print(y)
        print(y.shape)
        print("*****")

        print("keepdims")
        y = np.sum(x, keepdims = True);
        print(y)
        print(y.shape)
        print("*****")

        x = np.array([10,15,25,45,78,90], dtype= np.float64).reshape(3, 2, -1)
        y = np.sum(x, axis=1);
        print(y)
        print(y.shape)
        print("*****")

        print("keepdims")
        y = np.sum(x, axis=1, keepdims = True);
        print(y)
        print(y.shape)
        print("*****")

        x = np.array([10,15,25,45,78,90], dtype= np.float64).reshape(-1, 3, 2)
        y = np.sum(x, axis=2);
        print(y)
        print(y.shape)
        print("*****")

        print("keepdims")
        y = np.sum(x, axis=2, keepdims = True);
        print(y)
        print(y.shape)
        print("*****")

        return

    def test_cumprod_1(self):

        x = np.array([10,15,25,45,78,90,10,15,25,45,78,90], dtype= np.uint32).reshape(3, 2, -1)
        x = x * 3
        y = np.cumprod(x);
        print(y)

        x = np.array([10,15,25,45,78,90,10,15,25,45,78,90], dtype= np.int32).reshape(3, 2, -1)
        x = x * 3
        y = np.cumprod(x);
        print(y)

        return

    def test_cumprod_1a(self):

        x = np.array([10,15,25,45,78,90,10,15,25,45,78,90], dtype= np.uint64).reshape(3, 2, -1)
        x = x * 1
        y = np.cumprod(x);
        print(y)

        x = np.array([10,15,25,45,78,90,10,15,25,45,78,90], dtype= np.int64).reshape(3, 2, -1)
        x = x * 1
        y = np.cumprod(x);
        print(y)

        return

    def test_cumprod_2(self):

        a = np.array([1,2,3])
        b = np.cumprod(a)   # intermediate results 1, 1*2
                            # total product 1*2*3 = 6
        print(b)
        print("*****")

        a = np.array([[1, 2, 3], [4, 5, 6]])
        c = np.cumprod(a, dtype=float)  # specify type of output
        print(c)
        print("*****")

        d = np.cumprod(a, axis=0)
        print(d)
        print("*****")

        e = np.cumprod(a,axis=1)
        print(e)
        print("*****")

    def test_cumsum_1(self):

        x = np.array([10,15,25,45,78,90,10,15,25,45,78,90], dtype= np.uint32).reshape(3, 2, -1)
        x = x * 3
        y = np.cumsum(x);

        print(x)
        print(y)

        return

    def test_cumsum_2(self):

        a = np.array([[1,2,3], [4,5,6]])
        print(a)
        print("*****")

        b = np.cumsum(a)
        print(b)
        print("*****")

        c = np.cumsum(a, dtype=float)     # specifies type of output value(s)
        print(c)
        print("*****")

        d = np.cumsum(a,axis=0)      # sum over rows for each of the 3 columns
        print(d)
        print("*****")

        e = np.cumsum(a,axis=1)      # sum over columns for each of the 2 rows
        print(e)

        return

    def test_cumsum_3(self):

        a = np.array([[1,2,3], [4,5,6], [7,8,9], [10,11,12]]).reshape(2,3,-1)
        print(a)
        print("*****")

        b = np.cumsum(a)
        print(b)
        print("*****")

        c = np.cumsum(a, dtype=float)     # specifies type of output value(s)
        print(c)
        print("*****")

        d = np.cumsum(a,axis=0)      # sum over rows for each of the 3 columns
        print(d)
        print("*****")

        e = np.cumsum(a,axis=1)      # sum over columns for each of the 2 rows
        print(e)
        print("*****")

        f = np.cumsum(a,axis=2)      # sum over columns for each of the 2 rows
        print(f)
        print("*****")

        #g = np.cumsum(a,axis=3)      # sum over columns for each of the 2 rows
        #print(g)

    def test_cumsum_4(self):

        a = np.array([[1,2,3], [4,5,6], [7,8,9], [10,11,12]]).reshape(3,2,-1)
        print(a)
        print("*****")

        b = np.cumsum(a)
        print(b)
        print("*****")

        c = np.cumsum(a, dtype=float)     # specifies type of output value(s)
        print(c)
        print("*****")

        d = np.cumsum(a,axis=0)      # sum over rows for each of the 3 columns
        print(d)
        print("*****")

        e = np.cumsum(a,axis=1)      # sum over columns for each of the 2 rows
        print(e)

        f = np.cumsum(a,axis=2)      # sum over columns for each of the 2 rows
        print(f)

        #g = np.cumsum(a,axis=3)      # sum over columns for each of the 2 rows
        #print(g)

    def test_diff_1(self):

        x = np.array([10,15,25,45,78,90], dtype= np.uint32)
        x = x * 3
        y = np.diff(x[1:]);

        print(x)
        print(y)

        return

    def test_diff_2(self):

        x = np.array([10,15,25,45,78,90], dtype= np.uint32).reshape(2, -1)
        x = x * 3
        y = np.diff(x, axis=0);

        print(x)
        print(y)

        return

    def test_diff_3(self):

        x = np.array([10,15,25,45,78,90,10,15,25,45,78,90], dtype= np.uint32).reshape(3, 2, -1)
        x = x * 3
        y = np.diff(x,axis=2);

        print(x)
        print(y)

        return

    def test_ediff1d_1(self):
        x = np.array([1, 2, 4, 7, 0])
        y = np.ediff1d(x)
        print(y)

        print(np.ediff1d(x, to_begin=-99, to_end=np.array([88, 99])))

        y = [[1, 2, 4], [1, 6, 24]]
        print(np.ediff1d(y))

    def test_gradient_1(self):
        f = np.array([1, 2, 4, 7, 11, 16], dtype=float)
        a = nptest.gradient(f)
        print(a)
        print("***********")

        b = nptest.gradient(f, 2)
        print(b)
        print("***********")

        #Spacing can be also specified with an array that represents the coordinates
        #of the values F along the dimensions.
        #For instance a uniform spacing:

        x = np.arange(f.size)
        c = nptest.gradient(f, x)
        print(c)
        print("***********")

        #Or a non uniform one:

        x = np.array([0., 1., 1.5, 3.5, 4., 6.], dtype=float)
        d = nptest.gradient(f, x)
        print(d)

    def test_gradient_2(self):

        #For two dimensional arrays, the return will be two arrays ordered by
        #axis. In this example the first array stands for the gradient in
        #rows and the second one in columns direction:

        a = nptest.gradient(np.array([[1, 2, 6], [3, 4, 5]], dtype=float))
        print(a)
        print("***********")

        #In this example the spacing is also specified:
        #uniform for axis=0 and non uniform for axis=1

        dx = 2.
        y = [1., 1.5, 3.5]
        b = nptest.gradient(np.array([[1, 2, 6], [3, 4, 5]], dtype=float), dx, y)
        print(b)
        print("***********")

        #It is possible to specify how boundaries are treated using `edge_order`

        x = np.array([0, 1, 2, 3, 4])
        f = x**2
        c = nptest.gradient(f, edge_order=1)
        print(c)
        print("***********")

        d = nptest.gradient(f, edge_order=2)
        print(d)
        print("***********")

        #The `axis` keyword can be used to specify a subset of axes of which the
        #gradient is calculated

        e = nptest.gradient(np.array([[1, 2, 6], [3, 4, 5]], dtype=float), axis=0)
        print(e)

    def test_trapz_1(self):

        a = np.trapz([1,2,3])
        print(a)

        b = np.trapz([1,2,3], x=[4,6,8])
        print(b)

        c = np.trapz([1,2,3], dx=2)
        print(c)

        a = np.arange(6).reshape(2, 3)
        b = np.trapz(a, axis=0)
        print(b)

        c = np.trapz(a, axis=1)
        print(c)

    #endregion
    #region Exponents and logarithms

    def test_exp_1(self):

        x = np.array([1e-10, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0, -4.2])
        a = np.exp(x)
        print(a)

        a = np.exp(x.reshape(2,-1))
        print(a)

        b = x > 0
        a = np.exp(x, where= b)
        print(a)
        return

    def test_expm1_1(self):

        x = np.array([1e-10, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0, -4.2])
        a = np.expm1(x)
        print(a)

        a = np.expm1(x.reshape(2,-1))
        print(a)

        b = x > 0
        a = np.expm1(x, where= b)
        print(a)
        return

    def test_exp2_1(self):

        x = np.array([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0, -4.2])
        a = np.exp2(x)
        print(a)

        a = np.exp2(x.reshape(2,-1))
        print(a)

        b = x > 0
        a = np.exp2(x, where= b)
        print(a)
        return

    def test_log_1(self):

        x = np.array([1, np.e, np.e**2, 0])
        a = np.log(x)
        print(a)

        a = np.log(x.reshape(2,-1))
        print(a)

        b = x > 0
        a = np.log(x, where= b)
        print(a)
        return

    def test_log10_1(self):

        x = np.array([1, np.e, np.e**2, 0])
        a = np.log10(x)
        print(a)

        a = np.log10(x.reshape(2,-1))
        print(a)

        b = x > 0
        a = np.log10(x, where= b)
        print(a)
        return

    def test_log2_1(self):

        x = np.array([1, np.e, np.e**2, 0])
        a = np.log2(x)
        print(a)

        a = np.log2(x.reshape(2,-1))
        print(a)

        b = x > 0
        a = np.log2(x, where= b)
        print(a)
        return

    def test_log1p_1(self):

        x = np.array([1, np.e, np.e**2, 0])
        a = np.log1p(x)
        print(a)

        a = np.log1p(x.reshape(2,-1))
        print(a)

        b = x > 0
        a = np.log1p(x, where= b)
        print(a)
        return

    def test_logaddexp_1(self):

        prob1 = np.log(1e-50)
        prob2 = np.log(2.5e-50)
        a = np.logaddexp(prob1, prob2)
        print(a)
        b = np.exp(a)
        print(b)

    def test_logaddexp2_1(self):

        prob1 = np.log2(1e-50)
        prob2 = np.log2(2.5e-50)
        a = np.logaddexp2(prob1, prob2)
        print(a)
        b = 2 ** a
        print(b)

    #endregion

    #region Other special Functions

    def test_i0_1(self):

        a = np.i0(5)
        print(a)

        a = np.i0(5.0)
        print(a)

        a = np.i0([5.0, 6.0])
        print(a)

        a = np.i0([[5.0, 6.0],[7.9, 8.0]])
        print(a)

        return;

    def test_sinc_1(self):

        x = np.linspace(-4, 4, 10)
        a = np.sinc(x)
        print(a)

        print("********")

        xx = np.outer(x, x)
        b = np.sinc(xx)
        print(b)

    #endregion

    #region Floating point routines

    def test_signbit_1(self):

        a =np.signbit(-1.2)
        print(a)

        b = np.signbit(np.array([1, -2.3, 2.1]))
        print(b)

        c = np.signbit(np.array([+0.0, -0.0]))
        print(c)

        d = np.signbit(np.array([-np.inf, np.inf]))
        print(d)

        e = np.signbit(np.array([-np.nan, np.nan]))
        print(e)

        f = np.signbit(np.array([-1, 0, 1]))
        print(f)

    def test_copysign_1(self):

        a = np.copysign(1.3, -1)
        print(a)

        b = 1/np.copysign(0, 1)
        print(b)

        c = 1/np.copysign(0, -1)
        print(c)

        d = np.copysign([-1, 0, 1], -1.1)
        print(d)

        e  = np.copysign([-1, 0, 1], np.arange(3)-1)
        print(e)

    def test_frexp_1(self):

        x = np.arange(9)
        y1, y2 = np.frexp(x)
        print(y1)
        print(y2)

        print("***************")

        x = np.arange(9, dtype = np.float32).reshape(3,3)
        y1, y2 = np.frexp(x)
        print(y1)
        print(y2)

        print("***************")

        x = np.arange(9, dtype = np.float64).reshape(3,3)
        y1, y2 = np.frexp(x, where = x < 5)
        print(y1)
        print(y2)

    def test_ldexp_1(self):

        a = np.ldexp(5, np.arange(4))
        print(a)

        b = np.ldexp(np.arange(4), 5);
        print(b)

    def test_nextafter_1(self):

        a = np.nextafter(1, 2)
        print(a)

        b = np.nextafter([1, 2], [2, 1])
        d1 = b[0]
        d2 = b[1]
        print(d1)
        print(d2)

        c1 = np.array([1, 2], dtype=np.float32)
        c2 = np.array([2, 1], dtype=np.float32)

        c = np.nextafter(c1,c2)
        f1 = c[0]
        f2 = c[1]
        print(f1)
        print(f2)

    #endregion

    #region Rational routines

    def test_lcm_1(self):

        a = np.lcm(12, 20)
        print(a)

        b = np.lcm.reduce([3, 12, 20])
        print(b)

        c = np.lcm.reduce([40, 12, 20])
        print(c)

        d = np.lcm(np.arange(6), [20])
        print(d)

        e = np.lcm([20, 21], np.arange(6).reshape(3, 2))
        print(e)

        #f = np.lcm(np.arange(8).reshape(2,4), np.arange(16).reshape(4, 4))
        #print(f)

    def test_gcd_1(self):

        a = np.gcd(12, 20)
        print(a)

        b = np.gcd.reduce([3, 12, 20])
        print(b)

        c = np.gcd.reduce([40, 12, 20])
        print(c)

        d = np.gcd(np.arange(6), [20])
        print(d)

        e = np.gcd([20, 20], np.arange(6).reshape(3, 2))
        print(e)

        #f = np.lcm(np.arange(8).reshape(2,4), np.arange(16).reshape(4, 4))
        #print(f)

    #endregion

    #region Arithmetic operations

    def test_add_1(self):

        a = np.add(1.0, 4.0)
        print(a)

        b = np.arange(9.0).reshape((3, 3))
        c = np.arange(3.0)
        d = np.add(b, c)
        print(d)

    def test_reciprocal_operations(self):

        a =  np.arange(1, 32, 1, dtype = np.float32)
        print(a)

        b = np.reciprocal(a)
        print(b)

        a = np.arange(2048, 2048+32, 1, dtype = np.float64)
        print(a)

        b = np.reciprocal(a)
        print(b)

    def test_positive_1(self):

        d = np.positive([-1, -0, 1])
        print(d)

        e  = np.positive([[1, 0, -1], [-2, 3, -4]])
        print(e)

    def test_negative_1(self):

        d = np.negative([-1, -0, 1])
        print(d)

        e  = np.negative([[1, 0, -1], [-2, 3, -4]])
        print(e)

    def test_multiply_1(self):

        a = np.multiply(1.0, 4.0)
        print(a)

        b = np.arange(9.0).reshape((3, 3))
        c = np.arange(3.0)
        d = np.multiply(b, c)
        print(d)

    def test_divide(self):

        a = np.divide(7,3)
        print(a)

        b = np.divide([1., 2., 3., 4.], 2.5)
        print(b)

        c = np.divide([1., 2., 3., 4.], [0.5, 2.5, 2.5, 3.5 ])
        print(c)

        return

    def test_power_operations(self):
        a =  np.arange(0, 32, 1, dtype = np.int16)
        print(a)

        b = np.power(a, 3.23)
        print(b)

        a = np.arange(2048, 2048+32, 1, dtype = np.int64)
        print(a)

        b = np.power(a, 4)
        print(b)

        b = np.power(a, 0)
        print(b)

        b = np.power(a, 0.5)
        print(b)

    def test_subtract_1(self):

        a = np.subtract(2.0, 4.0)
        print(a)

        b = np.arange(9.0).reshape((3, 3))
        c = np.arange(3.0)
        d = np.subtract(b, c)
        print(d)

    def test_true_divide(self):

        a = np.true_divide(7,3)
        print(a)

        b = np.true_divide([1., 2., 3., 4.], 2.5)
        print(b)

        c = np.true_divide([1., 2., 3., 4.], [0.5, 2.5, 2.5, 3.5 ])
        print(c)

        return

    def test_floor_divide(self):

        a = np.floor_divide(7,3)
        print(a)

        b = np.floor_divide([1., 2., 3., 4.], 2.5)
        print(b)

        c = np.floor_divide([1., 2., 3., 4.], [0.5, 2.5, 2.5, 3.5 ])
        print(c)

        return

    def test_float_power(self):

        x1 = range(6)

        a = np.float_power(x1, 3)
        print(a)

        x2 = [1.0, 2.0, 3.0, 3.0, 2.0, 1.0]
        b = np.float_power(x1, x2)
        print(b)

        x3 = np.array([[1, 2, 3, 3, 2, 1], [1, 2, 3, 3, 2, 1]])

        c = np.float_power(x1, x3)
        print(c)

        return

    def test_fmod_1(self):

        x = np.fmod([4, 7], [2, 3])
        print(x)

        y = np.fmod(np.arange(7), 5)
        print(y)

        return

    def test_fmod_2(self):

        x = np.fmod([-4, -7], [2, 3])
        print(x)

        y = np.fmod(np.arange(7), -5)
        print(y)

        return

    def test_mod_1(self):

        x = np.mod([4, 7], [2, 3])
        print(x)

        y = np.mod(np.arange(7), 5)
        print(y)

        return

    def test_modf_1(self):

        x = np.modf([0, 3.5])
        print(x)

        y = np.modf(np.arange(7))
        print(y)

        return

    def test_remainder_1(self):

        x = np.remainder([4, 7], [2, 3])
        print(x)

        y = np.remainder(np.arange(7), 5)
        print(y)

        return

    def test_remainder_2(self):

        x = np.remainder([-4, -7], [2, 3])
        print(x)

        y = np.remainder(np.arange(7), -5)
        print(y)

        return

    def test_divmod_1(self):

        a = np.divmod(7,3)
        print(a)

        b = np.divmod([1., 2., 3., 4.], 2.5)
        print(b)

        c = np.divmod([1., 2., 3., 4.], [0.5, 2.5, 2.5, 3.5 ])
        print(c)

        return

    #endregion

    #region Miscellaneous

    def test_convolve_1(self):

        a = np.convolve([1, 2, 3], [0, 1, 0.5])
        print(a)

        # Only return the middle values of the convolution. Contains boundary effects, where zeros are taken into account:

        b = np.convolve([1,2,3],[0,1,0.5], 'same')
        print(b)

        # The two arrays are of the same length, so there is only one position where they completely overlap:

        c = np.convolve([1,2,3],[0,1,0.5], 'valid')
        print(c)

        return

    def test_clip_1(self):

        a = np.arange(10)
        print(a)
        print("*****")

        b = np.clip(a, 1, 8)
        print(b)
        print("*****")

        c = np.clip(a, 3, 6, out=a)
        print(c)
        print(a)
        print("*****")

        a = np.arange(10)
        print(a)
        b = np.clip(a, [3, 4, 1, 1, 1, 4, 4, 4, 4, 4], 8)
        print(b)
        print("*****")

    def test_clip_2(self):

        a = np.arange(16).reshape(4,4)
        print(a)
        print("*****")

        b = np.clip(a, 1, 8)
        print(b)
        print("*****")

        c = np.clip(a, 3, 6, out=a)
        print(c)
        print(a)
        print("*****")

        a = np.arange(16).reshape(4,4)
        print(a)
        b = np.clip(a, [3, 4, 1, 1], 8)
        print(b)
        print("*****")

    def test_sqrt_operations(self):
        a =  np.arange(0, 32, 1, dtype = np.int16)
        print(a)

        b = np.sqrt(a)
        print(b)

        a = np.arange(2048, 2048+32, 1, dtype = np.int64)
        print(a)

        b = np.sqrt(a)
        print(b)

    def test_cbrt_operations(self):
        a =  np.arange(0, 32, 1, dtype = np.int16)
        print(a)

        b = np.cbrt(a)
        print(b)

        a = np.arange(2048, 2048+32, 1, dtype = np.int64)
        print(a)

        b = np.cbrt(a)
        print(b)

    def test_square_operations(self):
        a =  np.arange(0, 32, 1, dtype = np.int16)
        print(a)

        b = np.square(a)
        print(b)

        a = np.arange(2048, 2048+32, 1, dtype = np.int64)
        print(a)

        b = np.square(a)
        print(b)

    def test_absolute_operations(self):
        a =  np.arange(-32, 32, 1, dtype = np.int16)
        print(a)

        b = np.absolute(a)
        print(b)

    def test_fabs_1(self):
        a =  np.arange(-32, 32, 1, dtype = np.int16)
        print(a)

        b = np.fabs(a)
        print(b)

    def test_sign_1(self):

        a =np.sign(-1.2)
        print(a)

        b = np.sign(np.array([1, -2.3, 2.1]))
        print(b)

        c = np.sign(np.array([+0.0, -0.0]))
        print(c)

        d = np.sign(np.array([-np.inf, np.inf]))
        print(d)

        e = np.sign(np.array([-np.nan, np.nan]))
        print(e)

        f = np.sign(np.array([-1, 0, 1]))
        print(f)

    def test_heaviside_1(self):

        a = np.heaviside([-1.5, 0, 2.0], 0.5)
        print(a)

        b = np.heaviside([-1.5, 0, 2.0], 1)
        print(b)

        c = np.heaviside([-1, 0, 2], 1)
        print(c)

    def test_maximum_1(self):

        a = np.maximum([2, 3, 4], [1, 5, 2])
        print(a)

        b = np.maximum(np.eye(2), [0.5, 2]) # broadcasting
        print(b)

        c = np.maximum([np.nan, 0, np.nan], [0, np.nan, np.nan])
        print(c)

        d = np.maximum(np.Inf, 1)
        print(d)

    def test_minimum_1(self):

        a = np.minimum([2, 3, 4], [1, 5, 2])
        print(a)

        b = np.minimum(np.eye(2), [0.5, 2]) # broadcasting
        print(b)

        c = np.minimum([np.nan, 0, np.nan], [0, np.nan, np.nan])
        print(c)

        d = np.minimum(np.Inf, 1)
        print(d)

    def test_fmax_1(self):

        a = np.fmax([2, 3, 4], [1, 5, 2])
        print(a)

        b = np.fmax(np.eye(2), [0.5, 2]) # broadcasting
        print(b)

        c = np.fmax([np.nan, 0, np.nan], [0, np.nan, np.nan])
        print(c)

        d = np.fmax(np.Inf, 1)
        print(d)

    def test_fmin_1(self):

        a = np.fmin([2, 3, 4], [1, 5, 2])
        print(a)

        b = np.fmin(np.eye(2), [0.5, 2]) # broadcasting
        print(b)

        c = np.fmin([np.nan, 0, np.nan], [0, np.nan, np.nan])
        print(c)

        d = np.fmin(np.Inf, 1)
        print(d)

    def test_nan_to_num_1(self):

        a = np.nan_to_num(np.inf)
        print(a)

        b = np.nan_to_num(-np.inf)
        print(b)

        c = np.nan_to_num(np.nan)
        print(c)

        x = np.array([np.inf, -np.inf, np.nan, -128, 128])
        d = np.nan_to_num(x)
        print(d)

        #e = np.nan_to_num(x, nan=-9999, posinf=33333333, neginf=33333333)
        #print(e)

        y = np.array([complex(np.inf, np.nan), np.nan, complex(np.nan, np.inf)])
        print(y)

        f = np.nan_to_num(y)
        print(f)

        #g = np.nan_to_num(y, nan=111111, posinf=222222)
        #print(g)

    def test_interp_1(self):

        xp = xp = [1, 2, 3]
        fp = [3, 2, 0]
        a = np.interp(2.5, xp, fp)
        print(a)

        b = np.interp([0, 1, 1.5, 2.72, 3.14], xp, fp)
        print(b)

        UNDEF = -99.0
        c = np.interp(3.14, xp, fp, right=UNDEF)
        print(c)

    #endregion

if __name__ == '__main__':
    unittest.main()


# -----------------------------------------------------------------------------
# Copyright (C) 2018  Nicolas P. Rougier
# Distributed under the terms of the BSD License.
# -----------------------------------------------------------------------------
import random
import numpy as np
from tools import timeit

def random_walk_slow(n):
    position = 0
    walk = [position]
    for i in range(n):
        position += 2*random.randint(0, 1)-1
        walk.append(position)
    return walk

def random_walk_faster(n=1000):
    from itertools import accumulate
    # Only available from Python 3.6
    steps = random.choices([-1,+1], k=n)
    return [0]+list(accumulate(steps))

def random_walk_fastest(n=1000):
    steps = np.random.choice([-1,+1], n)
    return np.cumsum(steps)

if __name__ == '__main__':

    timeit("random_walk_slow(1000)", globals())
    timeit("random_walk_faster(1000)", globals())
    timeit("random_walk_fastest(1000)", globals())