# Question 7 Lab 03
# AB Satyaprakash (180123062)

# imports ----------------------------------------------------------------------
from math import factorial
from fractions import Fraction
import numpy as np
import sympy as sp
# ------------------------------------------------------------------------------
# For a function f , the Newton divided-difference formula gives the interpolating polynomial
# P(x) = 1 + 4x + 4x(x − 0.25) + (16/3)x(x − 0.25)(x − 0.5),
# on the nodes x0 = 0, x1 = 0.25, x2 = 0.5, and x3 = 0.75. Find f(0.75).

print('Using P(x) we find the following:')
print('f[x0,x1,x2,x3] = 16/3')
print('f[x0,x1,x2] = 4')
print('f[x0,x1] = 4')
print('f[x0] = 1')

print('\nUsing the above information and simple arithmetic, the divided differences table is obtained as follows:')
X = [[0, 1], [0.25, 2, 4], [0.5, 3.5, 6, 4], [0.75, 6, 10, 8, 16/3]]
print('x\tf\n-------------------------------------------------------------------')
for i in range(4):
    for j in range(5):
        if(j >= len(X[i])):
            print(" ", end="\t")
        else:
            print(X[i][j], end="\t")
    print('\n', end="")

print('\nClearly, from the above table, we get f(0.75) = 6')

# Question 7 ends --------------------------------------------------------------

Semester 6/MA 322 (Scientific Computing Theory)/Labs/Lab 3/Code/q7.py


# import required libraries
import numpy as np
import codecs, json

def load_json_files(file_path):
    '''
    Loads data from a json file

    Inputs:
        file_path   the path of the .json file that you want to read in

    Outputs:
        json_data    this is a numpy array if data is numeric, it's a list if it's a string

    '''

    #  load data from json file
    with codecs.open(file_path, 'r', encoding='utf-8') as handle:
        json_data = json.loads(handle.read())

    # if a string, then returns list of strings
    if not isinstance(json_data[0], str):
        # otherwise, it's assumed to be numeric and returns numpy array
        json_data = np.array(json_data)

    return json_data

def compute_distances(X):
    '''
    Constructs a distance matrix from data set, assumes Euclidean distance

    Inputs:
        X       a numpy array of size n x p holding the data set (n observations, p features)

    Outputs:
        D       a numpy array of size n x n containing the euclidean distances between points

    '''
    if (len(X.shape) != 2):
        print("please input a 2D matrix")
        return -1

    n, p = X.shape
    D = np.zeros((n, n))
    for i in range(n):
        for j in range(n):
            s = 0
            for k in range(p):
                s += (X[i,k] - X[j,k])**2 #Euclidean distance
            D[i, j] = s**0.5

    # return distance matrix
    return D

def compute_affinity_matrix(D, kernel_type, sigma=None, k=None):
    '''
    Construct an affinity matrix from a distance matrix via gaussian kernel.

    Inputs:
        D               a numpy array of size n x n containing the distances between points
        kernel_type     a string, either "gaussian" or "adaptive".
                            If kernel_type = "gaussian", then sigma must be a positive number
                            If kernel_type = "adaptive", then k must be a positive integer
        sigma           the non-adaptive gaussian kernel parameter
        k               the adaptive kernel parameter

    Outputs:
        W       a numpy array of size n x n that is the affinity matrix

    '''
    if (len(D.shape) != 2):
        print("D must be a 2D matrix")
        return -1

    W = np.zeros((D.shape[0], D.shape[1]))

    if (kernel_type == "gaussian"):
        if (sigma == None or sigma <= 0):
            print("sigma must be a positive number")
            return -1
        # Gaussian Kernel
        W = np.exp(-D**2 / sigma**2)

    elif (kernel_type == "adaptive"):
        if (k == None or k <= 0):
            print("k must be a positive integer")
            return -1

        # Calculate K nearest neighbor distance
        sigmak = np.sort(D, axis=1)[:, k]
        for i in range(W.shape[0]):
            for j in range(W.shape[1]):
                # Adaptive Kernel distance based on sigmak
                W[i, j] = 0.5 * (np.exp(-D[i,j]**2 / sigmak[i]**2) + np.exp(-D[i,j]**2 / sigmak[j]**2))

    # return the affinity matrix
    return W

def diff_map_info(W):
    '''
    Construct the information necessary to easily construct diffusion map for any t

    Inputs:
        W           a numpy array of size n x n containing the affinities between points

    Outputs:

        diff_vec    a numpy array of size n x n-1 containing the n-1 nontrivial eigenvectors of Markov matrix as columns
        diff_eig    a numpy array of size n-1 containing the n-1 nontrivial eigenvalues of Markov matrix

        We assume the convention that the coordinates in the diffusion vectors are in descending order
        according to eigenvalues.
    '''

    if (len(W.shape) != 2):
        print("W must be a 2D matrix")
        return -1

    D=np.diag(np.sum(W, axis=0))
    M=np.linalg.inv(D)@W
    Ms=D**(1/2)@M@np.linalg.inv(D)**(1/2)

    # Eigendecomposition
    diff_eig, diff_vec = np.linalg.eigh(Ms)

    #Reverse Order of eigenvectors based on eigenvalues
    diff_eig = diff_eig[::-1]
    diff_vec = diff_vec[:, ::-1]

    #actual diffusion map eigenvectors
    diff_vec = np.linalg.inv(D) @ D**(1/2) @ diff_vec
    diff_vec = diff_vec / np.linalg.norm(diff_vec, axis=1)[:, np.newaxis]

    #remove steady state (largest) eigenvector/value pair
    diff_vec = diff_vec[:, 1:]
    diff_eig = diff_eig[1:]

    # return the info for diffusion maps
    return diff_vec, diff_eig

def get_diff_map(diff_vec, diff_eig, t):
    '''
    Construct a diffusion map at t from eigenvalues and eigenvectors of Markov matrix

    Inputs:
        diff_vec    a numpy array of size n x n-1 containing the n-1 nontrivial eigenvectors of Markov matrix as columns
        diff_eig    a numpy array of size n-1 containing the n-1 nontrivial eigenvalues of Markov matrix
        t           diffusion time parameter t

    Outputs:
        diff_map    a numpy array of size n x n-1, the diffusion map defined for t
    '''

    #construct diffusion maps
    diff_map = (np.diag(diff_eig**t) @ diff_vec.T).T

    return diff_map


"""
理解矩阵连乘的含义。
"""

from numpy import *

M0 = mat([[2, 0],
          [0, 2]])
M1 = mat([[2, 0],
          [0, 2]])
M2 = mat([[2, 0],
          [1, 2]])
v = mat([1, 1])
# 矩阵乘法是有维数要求的。不能乱来。所以vc要转置。 向量没有维数要求，行向量列向量都可以乘
vc = M0 @ M1 @ M2 @ v.T
print(vc)
print(M0.I @ M1.I @ M2.I @ vc)


# -*- coding: utf-8 -*
# Time-stamp: <2019-06-04 14:50:45 jcao>
# --------------------------------------------------------------------
# File Name          : math_utils.py
# Original Author    : jiessie.cao@gmail.com
# Description        : Utils for math operaters
# --------------------------------------------------------------------

import numpy
numpy.seterr(all='ignore')

def sigmoid(x):
    return 1. / (1 + numpy.exp(-x))

def dsigmoid(x):
    return x * (1. - x)

def tanh(x):
    return numpy.tanh(x)

def dtanh(x):
    return 1. - x * x

def softmax(x):
    e = numpy.exp(x - numpy.max(x))  # prevent overflow
    return e / numpy.sum(e, axis=0)

def norm_prob(x):
    return x / numpy.sum(x, axis=0)

def ReLU(x):
    return x * (x > 0)

def dReLU(x):
    return 1. * (x > 0)

def acc_sum_len(y, arr):
    for i in range(len(arr)):
        y = y - arr[i]
        if y <= 0.0:
            return i + 1
    return len(arr)


"""
 # Copyright 2020 Adobe
 # All Rights Reserved.

 # NOTICE: Adobe permits you to use, modify, and distribute this file in
 # accordance with the terms of the Adobe license agreement accompanying
 # it.

"""

import numpy as np

def area_of_triangle(pts):

    AB = pts[1, :] - pts[0, :]
    AC = pts[2, :] - pts[0, :]

    return 0.5 * np.linalg.norm(np.cross(AB, AC))

def area_of_polygon(pts):
    l = pts.shape[0]
    s = 0
    for i in range(1, l-1):
        s += area_of_triangle(pts[(0, i, i+1), :])
    return s

def area_of_signed_triangle(pts):

    AB = pts[1, :] - pts[0, :]
    AC = pts[2, :] - pts[0, :]

    return 0.5 * np.cross(AB, AC)

def area_of_signed_polygon(pts):
    l = pts.shape[0]
    s = 0
    for i in range(1, l-1):
        s += area_of_signed_triangle(pts[(0, i, i+1), :])
    return s


import numpy as np
from typing import Callable, Optional

def euler_maruyama(x0: float, a_t: Callable, b_t: Callable, n_steps: int, dt: float, random_toss: Optional[np.array] = None):
        """
        Simulate a stochastic process according to Euler-Maruyama method.

        Parameters
        ----------
        x0: float
            Starting value for the process
        a_t: Callable f: (t, x) -> R
            First characteristic of a stochastic process,
        b_t: Callable f: (t, x) -> R
            Second characteristic of a stochastic process
        n_steps: int
            Number of time discretization steps
        dt: float
            Lenght of a time step
        random_toss: Optional[np.array]
            Array of +1/-1, which is used for Wiener Process approximation.
            If not provided, it gets generated automatically.

        Returns
        -------
        (np.array, np.array)
            Time array and simulated stochastic process values
        """
        if not random_toss:
            random_toss = np.random.rand(n_steps).round()*2 - 1
        if random_toss.shape != (n_steps, ):
            raise ValueError("Incompatible shapes")

        xt = [x0]
        t = [0.]
        for k in range(1, n_steps):
            t_k = k*dt
            x_k = xt[-1] + a_t(t[-1], xt[-1])*dt + b_t(t[-1], xt[-1])*random_toss[k-1]*np.sqrt(dt)
            xt.append(x_k)
            t.append(t_k)
        return np.array(t), np.array(xt)

if __name__ == "__main__":
    pass


from scipy.fftpack import dct, dctn
import my_dct as my
import numpy as np
import pprint

pp = pprint.PrettyPrinter(indent=4)

block = np.array([[231, 32, 233, 161, 24, 71, 140, 245],
                  [247, 40, 248, 245, 124, 204, 36, 107],
                  [234, 202, 245, 167, 9, 217, 239, 173],
                  [193, 190, 100, 167, 43, 180, 8, 70],
                  [11, 24, 210, 177, 81, 243, 8, 112],
                  [97, 195, 203, 47, 125, 114, 165, 181],
                  [193, 70, 174, 167, 41, 30, 127, 245],
                  [87, 149, 57, 192, 65, 129, 178, 228]])

# block = np.random.randint(0, 255, size=(4, 5, 6))

pp.pprint("Test matrix:")
pp.pprint(block)

original2 = dctn(block, norm="ortho")
custom2 = my.dctn(block)
are_close2 = np.allclose(original2, custom2)

pp.pprint("Official DCT2:")
pp.pprint(original2)
print()
pp.pprint("My DCT2:")
pp.pprint(custom2)
print()
pp.pprint("All values are almost equal?")
pp.pprint(are_close2)
print()
print()

############################

pp.pprint("Test vector:")
pp.pprint(block[0])

original1 = dct(block[0], axis=0, norm="ortho")
custom1 = my.dct(block[0], axis=0)
are_close1 = np.allclose(original1, custom1)

pp.pprint("Official DCT1:")
pp.pprint(original1)
print()
pp.pprint("My DCT1:")
pp.pprint(custom1)
print()
pp.pprint("All values are almost equal?")
pp.pprint(are_close1)
print()
print()

# for axis in range(block.ndim):
#   original = dct(block, axis=axis, norm="ortho")
#   custom = my.dct(block, axis=axis)
#   are_close = np.allclose(original, custom)

  # print("Official 1D DCT, axis", axis)
  # print(original)
  # print()
  # print("My 1D DCT, axis", axis)
  # print(custom)
  # print()
  # print("All values are almost equal?", are_close)
  # print()


#!/usr/local/bin/python3.9
'''
Module for examining and plotting correlations

Change Log
==========
0.0.1 (2021-04-08)
----------
Initial commit

'''

import os
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats
import seaborn as sns

ROOT = '/Datasets/'        #define base directory
df = pd.read_csv(ROOT + 'FuelConsumption.csv')

# Pearson Correlation Coefficient
np.corrcoef(df['ENGINESIZE'], df['CO2EMISSIONS'])

# Correlation matrix (Pearson or Spearmann)
df.corr(method='pearson')['CO2EMISSIONS'].abs().sort_values(ascending=False)  # can sub spearman for pearson

# Scatter plot
plt.scatter(data = df, x='ENGINESIZE', y='CO2EMISSIONS')

# Scatter plot with fitted line
x = df['ENGINESIZE']
y = df['CO2EMISSIONS']
res = stats.linregress(x, y)
plt.plot(x, y, 'o', label='Data')
plt.plot(x, res.intercept + res.slope * x, 'r', label='Fitted Line')
plt.legend()
plt.show()

# SIMPLE LINEAR REGRESSION PLOT
sns.set(rc={'figure.figsize': (8, 5)})
sns.set(font_scale=1)
sns.set_style("ticks")
X = df['ENGINESIZE']
Y = df['CO2EMISSIONS']
#plt.grid(False)
ax = sns.regplot(X, Y, ci=95, scatter_kws={"color": "black"}, line_kws={"color": "red"})
ax.set_title('Simple Linear Regression Plot', weight='bold')
sns.despine()

# Plot Correlation matrix
sns.set_context('paper')
f, ax = plt.subplots(figsize=(10, 7))
cor = df.corr()
plt.title('Feature Correlation Matrix', weight='bold', fontsize=20)
ax = sns.heatmap(cor, vmax=1, annot=True, cmap=sns.color_palette("coolwarm", 20))
ax.set_xticklabels(
    ax.get_xticklabels(),
    rotation=45,
    horizontalalignment='right')
# plt.savefig('CorrMat.png')
plt.show()

# define correlation function (spearman or pearson)
# def corrfunc(x, y, **kws):
#     r, p = stats.spearmanr(x, y)  # use stats.pearsonr for pearson
#     ax = plt.gca()
#     ax.annotate("r = {:.2f}".format(r),
#                 xy=(.1, .9), xycoords=ax.transAxes)
#     ax.annotate("p = {:.2f}".format(p),
#                 xy=(.6, .9), xycoords=ax.transAxes)

# Pairgrid plot
# NOTE: very computationally demanding; do not perform with high predictors, use correlation matrix above
mpl.rcParams['axes.labelsize']=5
g = sns.PairGrid(df, palette=["red"], height=1, aspect=1.5)
g.map_upper(plt.scatter, s=1)
g.map_diag(sns.distplot, kde=False)
g.map_lower(sns.kdeplot, cmap="gist_heat")
g.map_lower(corrfunc)
g.map_upper(corrfunc)

'''
DataFrame of correlation (r) and coef. of determination (R^2)
between predictor(s) and response variable

Loop through each column of dataframe
'''
# Create empty lists to append
slope_list = []
intercept_list = []
rvalue_list = []
r2_value_list = []
pvalue_list = []
stderr_list = []

df = df.drop(labels=['MODELYEAR', 'MAKE', 'MODEL', 'VEHICLECLASS',
                     'TRANSMISSION', 'FUELTYPE'], axis = 1)      #drop unwanted columns
y = df['CO2EMISSIONS']          #define the response variable
# Run loop for each column
for i in df.columns[0:]:
    print(i)
    x = df[i]
    res = stats.linregress(x, y)
    slope_list.append(res.slope)
    intercept_list.append(res.intercept)
    rvalue_list.append(res.rvalue)
    r2_value = res.rvalue**2
    r2_value_list.append(r2_value)
    pvalue_list.append(res.pvalue)
    stderr_list.append(res.stderr)

# Create empty dataframe
corr_df = pd.DataFrame(columns=['Variable', 'Slope', 'Intercept', 'r', 'R^2', 'p', 'SE'])
variable_list = df.columns.tolist()

# Append lists to dataframe
corr_df['Variable'] = variable_list
corr_df['Slope'] = slope_list
corr_df['Intercept'] = intercept_list
corr_df['r'] = rvalue_list
corr_df['R^2'] = r2_value_list
corr_df['p'] = pvalue_list
corr_df['SE'] = stderr_list
pd.set_option('display.max_columns', None)
print(corr_df)

# Two-sided inverse Students t-distribution
# p - probability, df - degrees of freedom
x = df['ENGINESIZE']
y = df['CO2EMISSIONS']
res = stats.linregress(x, y)
from scipy.stats import t
tinv = lambda p, df: abs(t.ppf(p/2, df))
ts = tinv(0.05, len(x)-2)
print(f"slope (95%): {res.slope:.6f} +/- {ts*res.stderr:.6f}")
print(f"intercept (95%): {res.intercept:.6f}"
f" +/- {ts*res.intercept_stderr:.6f}")


from scipy.integrate import solve_ivp
import numpy as np
import matplotlib.pyplot as plt
from collections import OrderedDict
import copy
import ode_tools.ode_lib as ode_lib

N =  5e6 # T
I0 = 1./N
S0 = 1- I0
R0 = 0
t_sim = [0, 200]
t_eval = np.arange(0, 201, 1)

compartments = OrderedDict([['S', S0], ['I', I0], ['R', R0]])

# note: copy of above but above will be updated with current values so keep this for re-running/reference
initial_conditions = OrderedDict([['S', S0],
                                  ['I', I0],
                                  ['R', R0]])

parameters = OrderedDict([['beta', 0.3],
                          ['gamma', 0.1]])

#stoichiometry_wide = [['S',['J_inf',-1]],
#                      ['I',['J_inf',1],['J_rec',-1]],
#                      ['R',['J_rec',1]]]

#stoichiometry = ode_lib.stoichiometry_wide_to_tall(stoichiometry_wide)

# now using reaction scheme form
# either
#reaction_system = ['J_inf: S -> I',
#                   'J_rec: I -> R'
# or
reaction_system = ['J_inf: S + I -> 2I',
                   'J_rec: I -> R']

# maybe need to think a bit better about passing by copy or ref but oh well
stoichiometry = OrderedDict()
stoichiometry = ode_lib.parse_reaction_system(reaction_system=reaction_system,d=stoichiometry)

# will give expected form:
# stoichiometry = OrderedDict([[('S', 'J_inf'), -1],
#                              [('I', 'J_inf'), 1],
#                              [('I', 'J_rec'), -1],
#                              [('R', 'J_rec'), 1]])

# save figure
dot = ode_lib.stoichiometry_to_dot(stoichiometry,dot_name='output/SIR_example_usage',save=True)

fluxes = OrderedDict([['J_inf', lambda c, p: p['beta'] * c['S'] * c['I']],
                      ['J_rec', lambda c, p: p['gamma'] * c['I']]])

problem_data = {'compartments':compartments,
                'parameters':parameters,
                'fluxes':fluxes,
                'stoichiometry':stoichiometry,
                'initial_conditions':initial_conditions}

S,I,R = ode_lib.simulate_and_eval(problem_data,t_sim,t_eval)

# total infections
plt.figure()
plt.plot(R*N)
plt.show()

# total infections logged
plt.figure()
plt.plot(R*N)
plt.yscale('log')
plt.show()

# empirical Reff estimates
plt.figure()
plt.plot(1+(1/parameters['gamma'])*np.gradient(np.log(np.diff(R))))
plt.show()

plt.figure()
plt.plot(1+(1/parameters['gamma'])*np.gradient(np.log(I)))
plt.show()

# all compartments
plt.figure()
plt.plot(S*N, label='S')
plt.plot(I*N, label='I')
plt.plot(R*N, label='R')
plt.legend()
plt.show()


"""
Sample script for fitting sinusoidal data.  This script
uses the data file: sample_AD_data.csv

This data was logged on: 2017-03-08 12:40 pm using an arduino
A/D pin and an associated test circuit.

Author: HMokhtarzadeh
Date: April 13, 2017
"""

import pandas as pd
import numpy as np

#
# Load Data
#
path_data = '/home/hamid/Documents/Work/ONav-Hive/talks/2017-04-13-Python-Environments/sample_AD_data.csv'
df = pd.DataFrame.from_csv(path_data)
df.index = df.index*1e-6 #conver from usec to sec
df.index.names = ["time(sec)"]
print("Data loaded from: {:s}".format(path_data))

#
# Caluculate and report data sampling rate.
#
dt_sec = np.median(np.diff(df.index))
print("Data Sampling rate: {:d} Hz".format(int(1./dt_sec)))

#
# Fit to sinusoid.
#
# This is method is quite sensative to a good initial guess.
# Alternate approach: http://exnumerus.blogspot.com/2010/04/how-to-fit-sine-wave-example-in-python.html
tmax_sec = .5
def func(x, time, data):
    bias, amp, freq_hz, phase_rad = x

    predict = amp * np.cos(2*np.pi*freq_hz*time + phase_rad)

    return predict - data
from scipy.optimize import leastsq # Other optimizers tried: fmin, minimize, least_squares
x0 = [0.7, 1, 60, 0] # good iniital guess
ind = df.index < tmax_sec
xopt = leastsq(func, x0, args=(df.index[ind], df['amplitude'][ind]))

#
# Save initial guess, fit, and print final fit.
#
bias, amp, freq_hz, phase_rad = x0
df['fit x0'] = bias + amp * np.cos(2*np.pi*freq_hz*df.index + phase_rad)

bias, amp, freq_hz, phase_rad = xopt[0]
df['fit xopt'] = bias + amp * np.cos(2*np.pi*freq_hz*df.index + phase_rad)

print("Fitted Sinusoid: {b:.3f} + {a:.3f}*cos(2 PI {f:.2f} + {p:.3f})".format(b=bias, a=amp, f=freq_hz, p=phase_rad))

#
# Visualize
#
from matplotlib import pyplot as plt
fig, [ax0, ax1] = plt.subplots(2,1)
df['amplitude'][df.index < tmax_sec].plot(ax=ax0, label='raw data', linestyle='', marker='.')
df['fit x0'][df.index < tmax_sec].plot(ax=ax0, alpha=.5, color='black', marker='', lw=2)
df['fit xopt'][df.index < tmax_sec].plot(ax=ax0, color='black', marker='', lw=2)
ax0.legend()
df['amplitude'].plot(ax=ax1)
plt.show()


import math

from pathlib import Path
from numpy import array
import numpy as np

from manim import *

ANGLE_IN_DEGREES = 90
angle = math.radians(ANGLE_IN_DEGREES)

TRANSFORMATION_MATRIX = np.array([
    [math.cos(angle), math.sin(angle)],
    [-math.sin(angle), math.cos(angle)]
])

def convert_to_3d(vect):
    return np.array([*list(vect), 0])

def get_transform_matrix_text(angle, color):
    return MathTex(
        f"\\begin{{bmatrix}}\\cos({angle}) && \\sin({angle}) \\\\ -\\sin({angle}) && \\cos({angle})\\end{{bmatrix}}").set_color(color)

class TransformationMatrix(Scene):
    def construct(self):
        VECT1 = np.array([2, 2])
        VECT1_COLOR = "#b9b28b"

        TRANS_VEC = TRANSFORMATION_MATRIX @ VECT1
        VECT2_COLOR = "#b98b99"

        VECT3_COLOR = "#8ba7b9"

        vect1 = Line(start=ORIGIN, end=convert_to_3d(VECT1), stroke_color=VECT1_COLOR).add_tip()
        # vect1_name = MathTex(r"\begin{bmatrix}2 \\ 2\end{bmatrix}").next_to(vect1.get_end(), UP + RIGHT * 2, buff=0.1).set_color(VECT1_COLOR)

        angle = math.radians(45)

        matrix_part = get_transform_matrix_text(90, color=VECT3_COLOR)

        vector_part = MathTex(f"\\begin{{bmatrix}}{VECT1[0]} \\\\ {VECT1[1]}\end{{bmatrix}}").set_color(VECT1_COLOR)
        equals_part = MathTex(" = ").set_color(VECT1_COLOR)

        transformed_vector_part = MathTex(f"\\begin{{bmatrix}}{round(TRANS_VEC[0], 1)} \\\\ {round(TRANS_VEC[1], 1)}\end{{bmatrix}}").set_color(VECT2_COLOR)

        expression = VGroup(matrix_part, vector_part, equals_part, transformed_vector_part).arrange(RIGHT)

        expression.shift(UP * 3 + LEFT * 2)

        # self.add(expression)

        self.play(GrowFromPoint(vect1, point=vect1.get_start()), FadeIn(vector_part), FadeIn(matrix_part))

        self.wait()

        self.play(FadeIn(equals_part))

        trans_vect1 = vect1.copy().set_color(VECT2_COLOR)
        trans_vect1.put_start_and_end_on(ORIGIN, np.array([2, 2.00001, 0]))

        angle = Angle(vect1, trans_vect1, other_angle=True)
        self.add(angle)

        angle.add_updater(
            lambda x: x.become(Angle(vect1, trans_vect1, color=VECT2_COLOR, other_angle=True))
        )

        self.add(trans_vect1)
        self.play(ApplyMethod(trans_vect1.put_start_and_end_on, ORIGIN, np.array([*list(TRANS_VEC), 0])), FadeIn(transformed_vector_part))

        self.wait(3)

if __name__ == '__main__':
    # Generate animated gif.
    config.background_color = WHITE

    config.pixel_width = 640
    config.pixel_height = 360

    config.output_file = Path(__file__).resolve().parent.parent.parent / Path('notes/_media/transformation-matrix-example')

    config.format = 'gif'

    scene = TransformationMatrix()
    scene.render()


import numpy as np

class LinearRegressor:
    """
    A linear regressor optimized through gradient descent
    """

    def __init__(self, dat, theta=None):
        # number of samples and features in the dataset
        self.num_samples = dat.shape[0]
        self.num_features = dat.shape[1]

        # For feature normalization
        self.mu = None
        self.sigma = None

        # row for the bias terms
        biases = np.ones(self.num_samples)
        normalized_features = self.feature_normalize(dat[:, :-1])
        self.x = np.column_stack((biases, normalized_features))
        self.y = np.reshape(dat[:, -1], (self.num_samples, 1))

        self.theta = theta if theta else np.zeros((self.num_features, 1))

    def feature_normalize(self, x):
        """
        Normalize the features in x
        After normalization the mean value of each feature is 0, and the standard deviation is 1

        Arguments:
            x {np.ndarray} -- An N x K dimensional numpy array of data samples
        Returns:
            {np.ndarray} -- An N x K dimensional numpy array of normalized data samples
        """

        # Initialize normalization params on training data set
        if self.mu is None or self.sigma is None:
            self.mu = np.mean(x, axis=0)
            self.sigma = np.std(x, axis=0)
            zero_mask = self.sigma == 0
            self.sigma += zero_mask  # ensure no division by zero (if == 0, set = 1)

        return (x - self.mu) / self.sigma

    def gradient_descent(self, alpha, num_iters, l1, l2):
        """ Perform gradient descent to fit theta to the data x, given y

        Arguments:
            alpha {float} -- the learning rate
            num_iters {int} -- the number of iterations to perform
            l1 {float} -- the l1 regularisation constant for gradient calculations
            l2 {float} -- the l2 regularisation constant for gradient calculations
        """

        scalar = alpha / len(self.x)
        for i in range(num_iters):
            gradients = self.x.transpose().dot((self.x.dot(self.theta) - self.y))
            gradients[1:, :] += l1 * np.sign(self.theta[1:, :])  # l1 regularisation
            gradients[1:, :] += 2 * l2 * self.theta[1:, :]  # l2 regularisation
            self.theta -= scalar * gradients

    def compute_cost(self, l1, l2):
        """ Compute the cost for linear regression

        Returns:
            {float} -- the mean squared error of this linear model
            l1 {float} -- the l1 regularisation constant for cost calculations
            l2 {float} -- the l2 regularisation constant for cost calculations
        """

        diffs = self.x.dot(self.theta) - self.y
        loss = 1 / (2 * len(self.y)) * sum(diffs * diffs)

        loss += l1 * np.sign(self.theta).sum()  # l1 regularisation
        loss += l2 * np.square(self.theta).sum()  # l2 regularisation

        return loss

    def predict(self, x):
        """ Predict the output of the linear model against sample data using learned parameters

        Arguments:
            x {np.ndarray} -- An N x K dimensional numpy array of data samples to predict
        Returns:
            {[float]} -- a list of the predicted outputs of the model
        """

        return x.dot(self.theta)

def example_main(dat):
    # Hyper-parameters
    alpha = 0.1
    num_iters = 1000
    l1 = 0.01
    l2 = 0.001

    regressor = LinearRegressor(dat)
    print("Starting Cost:", regressor.compute_cost(l1, l2))
    print("Training...")
    regressor.gradient_descent(alpha=alpha, num_iters=num_iters, l1=l1, l2=l2)
    print("Final Cost:", regressor.compute_cost(l1, l2))
    print("Final Theta:\n", regressor.theta)

if __name__ == "__main__":
    print("Beginning Univariate Linear Regression:\n")
    univariate_dat = np.loadtxt("../../datasets/regression/linear_univariate.txt", delimiter=",")
    example_main(univariate_dat)

    print("\nBeginning Multivariate Linear Regression:\n")
    multivariate_dat = np.loadtxt("../../datasets/regression/linear_multivariate.txt", delimiter=",")
    example_main(multivariate_dat)


from IMLearn.learners import UnivariateGaussian, MultivariateGaussian
import numpy as np
import plotly.express as pex
import plotly.io as pio
import matplotlib.pyplot as plt

pio.templates.default = "simple_white"
form = "{:.3f}"

def test_univariate_gaussian():
    # Question 1 - Draw samples and print fitted model
    un = UnivariateGaussian()
    X = np.random.normal(10.0, 1.0, 1000)
    un.fit(X)
    print(f"Expectation: {un.mu_}, Variance: {un.var_}\n")

    # Question 2 - Empirically showing sample mean is consistent
    loss = []
    un = UnivariateGaussian()
    for sample_size in range(10, 1010, 10):
        un.fit(X[:sample_size])
        loss.append(np.abs(un.mu_ - 10))

    graph = pex.line(x=range(10, 1010, 10),
                     y=np.asarray(loss),
                     labels=dict(x="Sample size", y="Loss of the expectation"),
                     title="Absolute distance between the estimated & true-value of the expectation, "
                           "as a function of the sample size")
    graph.write_html('first_figure.html', auto_open=True)

    # Question 3 - Plotting Empirical PDF of fitted model
    plt.scatter(X, un.pdf(X))
    plt.ylabel("PDF")
    plt.xlabel("SAMPLES")
    plt.title("Empirical PDF of samples")
    plt.show()

def test_multivariate_gaussian():
    # Question 4 - Draw samples and print fitted model
    multivariate_gaussian = MultivariateGaussian()
    mu = np.array([0, 0, 4, 0])
    cov = np.array([[1, 0.2, 0, 0.5],
                    [0.2, 2, 0, 0],
                    [0, 0, 1, 0],
                    [0.5, 0, 0, 1]])

    X = np.random.multivariate_normal(mu, cov, 1000)
    multivariate_gaussian.fit(X)
    print(f"Estimated expectation:\n{multivariate_gaussian.mu_}\n\n"
          f"Estimated covariance:\n{multivariate_gaussian.cov_}\n")

    # Question 5 - Likelihood evaluation
    linspace = np.linspace(-10, 10, 200)
    log_likelihood = [[(multivariate_gaussian.log_likelihood(np.asarray([f1, 0, f3, 0]).T, cov, X))
                       for f3 in linspace]
                       for f1 in linspace]

    graph = pex.imshow(log_likelihood,
                       x=linspace,
                       y=linspace,
                       labels=dict(x="f1",
                                   y="f3",
                                   color="log-likelihood"),
                       title="log-likelihood for models with expectation "
                             "μ=[f1, 0, f3, 0] and the given true covariance matrix Σ")
    graph.write_html('first_figure.html', auto_open=True)

    # Question 6 - Maximum likelihood
    max_coord = np.where(log_likelihood == np.amax(log_likelihood))
    f1_argmax = linspace[max_coord[0][0]]
    f3_argmax = linspace[max_coord[1][0]]
    print(f"max(log-likelihood): {form.format(np.amax(log_likelihood))}")
    print(f"argmax(log-likelihood): ({form.format(f1_argmax)} : {form.format(f3_argmax)})")

if __name__ == '__main__':
    np.random.seed(0)
    test_univariate_gaussian()
    test_multivariate_gaussian()


from functools import partial

import chaospy as cp
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from integration_algorithms import monte_carlo_naive_one
from integration_algorithms import quadrature_gauss_legendre_one
from integration_algorithms import quadrature_newton_trapezoid_one
from integration_problems import problem_kinked
from integration_problems import problem_smooth

def plot_gauss_legendre_weights(deg):
    xevals, weights = np.polynomial.legendre.leggauss(deg)

    fig, ax = plt.subplots()

    ax.bar(xevals, weights, width=0.02)
    ax.set_ylabel("Weight")
    ax.set_xlabel("Node")
    ax.set_xlim([-1, 1])
    plt.show()

def plot_benchmarking_exercise():
    xvals = np.linspace(-1, 1, 10000)

    fig, (ax1, ax2) = plt.subplots(2)
    ax1.plot(xvals, problem_smooth(xvals), label=r"$e^-x$")
    ax1.legend()

    ax2.plot(xvals, problem_kinked(xvals), label=r"$\sqrt{|x|}$")
    ax2.legend()

def plot_naive_monte_carlo(num_nodes):
    fig, ax = plt.subplots(figsize=(4, 4))
    x, y = np.hsplit(np.random.uniform(size=num_nodes * 2).reshape(num_nodes, 2), 2)
    ax.scatter(x, y)
    ax.get_yticklabels()[0].set_visible(False)
    ax.set_ylim(0, 1)
    ax.set_xlim(0, 1)

def plot_quasi_monte_carlo(num_points):
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4))

    distribution = cp.J(cp.Uniform(0, 1), cp.Uniform(0, 1))
    samples = distribution.sample(num_points, rule="halton")
    x, y = np.hsplit(samples.T, 2)

    ax1.get_yticklabels()[0].set_visible(False)
    ax1.scatter(x, y)
    ax1.set_ylim(0, 1)
    ax1.set_xlim(0, 1)
    ax1.set_title("Halton")

    samples = distribution.sample(num_points, rule="sobol")
    x, y = np.hsplit(samples.T, 2)
    ax2.get_yticklabels()[0].set_visible(False)
    ax2.scatter(x, y)
    ax2.set_ylim(0, 1)
    ax2.set_xlim(0, 1)

    ax2.set_title("Sobol")

def plot_naive_monte_carlo_error(max_nodes):

    index = pd.Index(np.linspace(5, max_nodes, dtype=int), name="Nodes")
    df_results = pd.DataFrame(columns=["Trapezoid", "Gauss", "Naive", "Truth"], index=index)

    p_trapezoid = partial(quadrature_newton_trapezoid_one, problem_smooth, -1, 1)
    p_gauss = partial(quadrature_gauss_legendre_one, problem_smooth, -1, 1)
    p_naive = partial(monte_carlo_naive_one, problem_smooth, -1, 1)

    df_results.loc[:, "Truth"] = np.exp(1) - np.exp(-1)
    for nodes in df_results.index.get_level_values("Nodes"):
        df_results.loc[nodes, "Trapezoid"] = np.abs(p_trapezoid(nodes))
        df_results.loc[nodes, "Gauss"] = np.abs(p_gauss(nodes))
        df_results.loc[nodes, "Naive"] = np.abs(p_naive(nodes))

    fig, ax = plt.subplots()
    for column in df_results.columns:
        ax.plot(df_results.index.get_level_values("Nodes"), df_results[column], label=column)
    ax.set_xlabel("Number of nodes")
    ax.set_ylabel("Error")
    ax.legend()

def plot_naive_monte_carlo_randomness():

    grid = range(10)
    yvals = list()
    for seed in grid:
        rslt = monte_carlo_naive_one(problem_smooth, a=-1, b=1, n=50, seed=seed)
        yvals += [np.abs(rslt - 2.3504023872876028)]

    fig, ax = plt.subplots()
    ax.scatter(grid, yvals)
    ax.set_xlabel("Seed")
    ax.set_ylabel("Error")


from typing import Tuple
import numpy as np

def stencil_weights(d: int, i_min: int, i_max: int)->Tuple[np.ndarray, int]:
    """
    Generates weights c_k for the finite difference stencil.

    Args:
        d (int): order of the derivative
        i_min (int): number of stencil points to the left of the point of the derivation
        i_max (int): number of stencil points to the right of the point of the derivation

    Returns:
        Tuple[np.ndarray, int]: returns a tuple of the stencli weight vector c_k (1d numpy array) and the largest of the two values i_min and i _max
    """
    A = []
    b = []
    di = i_max-i_min + 1
    for n in range(di):
        A.append(np.array([1 if (i == 0) & (n == 0) else i**n for i in range(i_min, i_max + 1)]))
        b.append(0 if n != d else 1)

    A = np.array(A)
    b = np.array(b)
    i0 = np.max(np.abs([i_max, i_min]))
    return np.linalg.solve(A, b)*np.math.factorial(d), i0

def stencil_matrix_pure(c: np.ndarray, i0: int, y_axes=0)-> np.ndarray:
    """
    Generates a matrix that corresponds to a FDM stencil of a derivative in only one direction. This matrix can be convolved with the target field to take the derivative.
    Args:
        c (np.ndarray): stencil vector
        i0 (int): number of points on the largest side of the stencil
        y_axes (int, optional): Transposes the stencil matrix if the derivation is i y direction. Stencil vectors for x and y axes are the same but their stencil matrices are transposedversions of each other. Defaults to 0.

    Returns:
        np.ndarray: _description_
    """
    n = c.size
    o = np.zeros(n)
    o[i0] = 1
    M = np.outer(o, c)

    if y_axes:
        return M.transpose()
    else:
        return M

def stencil_matrix_mixed(*c_s: np.ndarray):
    return np.outer(*c_s)


import csv
import argparse
import numpy as np
import scipy.stats as stats

class data_group:
    def __init__(self, group_name, data_array):
        self.group_name = group_name
        self.data_array = data_array
        self.mean       = np.mean(np.array(data_array))
        self.sd         = np.std(np.array(data_array))

def data_reader(filename):
    group_list = []
    with open(filename, 'r') as r:
        data_reader = csv.reader(r)
        for row in data_reader:
            group_name = row[0]
            data_array = []
            for data in row[1:]:
                data_array.append(float(data))

            group_list.append(data_group(group_name,data_array))

    return group_list

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--input', type=str, default='testData.csv', help='path to the input csv file (default: testData.csv)')
    parser.add_argument('--confidence', type=float, default=0.95, help='level of significance (default: 0.95)')
    args       = parser.parse_args()
    filename   = args.input
    confidence = args.confidence

    group_list = data_reader(filename)

    for group_xi in group_list:
        print(group_xi.group_name)
        # 自由度
        df = len(group_xi.data_array) - 1

        chi2_under, chi2_upper = stats.chi2.interval(alpha=confidence, df=df)
        variance = group_xi.sd*group_xi.sd
        interval_under = df*variance / chi2_upper
        interval_upper = df*variance / chi2_under
        print('mean: {}, variance: {}, SD: {}'.format(group_xi.mean, variance, group_xi.sd))
        print('{}% confidence interval: ({}, {})'.format(int(confidence*100),interval_under,interval_upper))
        print(" ")

if __name__ == '__main__':
    main()


import pytest
import numpy as np
import numba
from utils_cm_toolbox import numericals
import matplotlib.pyplot as plt

NUM_POINTS_REF = 10
T_REF = np.linspace(0., 10., NUM_POINTS_REF + 1)
Y_REF = np.array([10., 9., 11., 10., 5., 4., 7., 8., 5., 9., 11.])

# def test_b_spline_coeff():
#     coefs, h = numericals.b_spline_coeff(T_REF, Y_REF)

#     assert coefs[0] == 5.0

# def test_b_spline_eval():
#     coeffs_test = np.ones(NUM_POINTS_REF + 1)
#     coeffs_test[0::2] = -1
#     x = 4.5
#     r = numericals.b_spline_eval(T_REF, coeffs_test, x)

    # assert r == 5.0

def test_b_spline():
    coefs, h = numericals.b_spline_coeff(T_REF, Y_REF)
    x = 4.5
    r = numericals.b_spline_eval(T_REF, coefs, h, x)
    assert r < 5.0 and r > 4.0

def show_plot_b_spline():
    coefs, h = numericals.b_spline_coeff(T_REF, Y_REF)
    nt = 101
    x = np.linspace(0.0, T_REF[-1], nt)
    r = np.empty_like(x)
    for i in np.arange(0, nt):
        r[i] = numericals.b_spline_eval(T_REF, coefs, h, x[i])
    plt.figure()
    plt.plot(x, r, 'o-')
    plt.plot(T_REF, Y_REF, 'dr')
    print(coefs)
    plt.show()

def case_testing_b_spline():
    coefs, h = numericals.b_spline_coeff(T_REF, Y_REF)
    coefs = np.random.random(11) * len(coefs)
    nt = 101
    x = np.linspace(0.0, T_REF[-1], nt)
    r = np.empty_like(x)
    for i in np.arange(0, nt):
        r[i] = numericals.b_spline_eval(T_REF, coefs, h, x[i])
    plt.figure()
    plt.plot(x, r, 'o-')
    plt.plot(T_REF, Y_REF, 'dr')
    print(coefs)
    plt.show()

######
# Brents
######
@numba.njit
def f(x):
    return x**2 - 20

def test_brents():

    root, steps = numericals.brents(f, 2, 5, tolerance=10e-5)
    print("root is:", root)
    print("steps taken:", steps)
    assert(np.isclose(root, np.sqrt(20.0)))
    assert(steps < 50)

if __name__ == "__main__":
    # case_testing_b_spline()
    show_plot_b_spline()


#!/usr/bin/python3
# -*- coding: utf-8 -*-

import numpy as np

###### list

##
a = [1, 2, 3]
b = [4, 5, 6]

a, b
# Out[2]: ([1, 2, 3], [4, 5, 6])

##
a * b
# TypeError: can't multiply sequence by non-int of type 'list'

##
np.multiply(a, b)
# Out[4]: array([ 4, 10, 18])

##
np.dot(a, b)
# Out[5]: 32

###### ndarray

##
c = np.asarray(a)
d = np.asarray(b)

c, d
# Out[6]: (array([1, 2, 3]), array([4, 5, 6]))

##
c * d
# Out[7]: array([ 4, 10, 18])

##
np.multiply(c, d)
# Out[8]: array([ 4, 10, 18])

##
np.dot(c, d)
# Out[9]: 32

###### constant

##
a * 3
# Out[10]: [1, 2, 3, 1, 2, 3, 1, 2, 3]

##
c * 3
# Out[11]: array([3, 6, 9])

##
np.multiply(a, 3)
# Out[6]: array([3, 6, 9])

###### mixture

##
np.dot(c, a) # = np.dot(a, c)
# Out[14]: 14 = 1*1 + 2*2 + 3*3

##
np.multiply(c, a)
# Out[16]: array([1, 4, 9])

###### T

## 1-D
c, c.T, c.reshape((len(c), -1))
# Out[16]: (array([1, 2, 3]), array([1, 2, 3]), array([[1],
#         [2],
#         [3]]))

## 2-D
e = np.array([[1,2,3], [4,5,6]])
e, e.T, e.reshape(len(e[0]), len(e))
# Out[18]: (array([[1, 2, 3],
#         [4, 5, 6]]), array([[1, 4],
#         [2, 5],
#         [3, 6]]), array([[1, 2],
#         [3, 4],
#         [5, 6]]))

## Mul
t = 3
x = np.array([t])
y = np.array([[t]])
f = c.reshape((len(c)), -1)
x, y, f
# Out[23]: (array([3]), array([[3]]), array([[1],
#         [2],
#         [3]]))

##
f * t, f * x, f * y
# Out[25]: (array([[3],
#         [6],
#         [9]]), array([[3],
#         [6],
#         [9]]), array([[3],
#         [6],
#         [9]]))


from math import gcd
import numpy as np
from util import *

def getSafePrime(digits):
    '''
    To get the a random safe prime of the form p = 2q+1 where q is also a prime
    Implemented by Rishika Mohanta
    '''
    while True:
        p = generate_prime(digits)
        if MillerRabin_test(int((p-1)/2)):
            print("Generated Safe Prime...",end="")
            return p

def getPrimitiveRoot(p):
    '''
    To get the first primitive root mod n
    Implemented by Rishika Mohanta
    '''
    coprime_set = {num for num in range (1, p) if gcd(num, p) == 1}
    for g in range(1, p):
        generated_set = set(pow(g, powers) % p for powers in range (1, p))
        if coprime_set == generated_set:
            print(f"Generated primitive root modulo p.")
            return g

def genPublicMessage(p,g,privatekey):
    '''
    To generate DH public message
    Implemented by Ramya Narayanan
    '''
    return int(pow(g,privatekey,p))

def genSharedKey(p,publicmessage,privatekey):
    '''
    To generate DH shared key
    Implemented by Ramya Narayanan
    '''
    return int(pow(publicmessage,privatekey,p))


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

df = pd.read_csv('owid-covid-data.csv')
pd.set_option("display.max_rows", None, "display.max_columns", None)
#print(df.head())

#df.info()
countries_list= df['location'].tolist()
countries_set = set(countries_list)
#print(countries_set)
print("1. How many countries the dataset has ?")
print(len(countries_set))
print("----------------------------------------")

contry_groupby = df.groupby(['location'])
date_earliest_each = contry_groupby.agg(Earliest_Date=('date',np.min))
#date_earliest = date_earliest_each.agg(Minumum_Date=('date',))
print("2. When is the earliest date data are taken for a country? Which country is it ?")
print(date_earliest_each[date_earliest_each.eq(date_earliest_each.min()).any(1)])
print("----------------------------------------")

totalcases_each= contry_groupby.agg(q3_Total_Cases= ('total_cases',np.max))
print("3. How many cases are confirmed for each country so far? Print pairwise results of country and total cases.")
print(totalcases_each)
print("----------------------------------------")

totaldeaths_each= contry_groupby.agg(q4_Total_Deaths= ('total_deaths',np.max))
print("4. How many deaths are confirmed for each country so far? Print pairwise results of country and total deaths.")
print(totaldeaths_each)
print("----------------------------------------")

reproduction_each= contry_groupby.agg(q5_minimum=('reproduction_rate', np.min), q5_maximum=('reproduction_rate', np.max), q5_average=('reproduction_rate', np.mean), q5_variation=('reproduction_rate', np.var))
print("5. What are the average, minimum, maximum and variation values of the reproduction rates for each country ?")
print(reproduction_each)
print("----------------------------------------")

icupatients_each= contry_groupby.agg(q6_minimum=('icu_patients', np.min), q6_maximum=('icu_patients', np.max), q6_average=('icu_patients', np.mean), q6_variation=('icu_patients', np.var))
print("6. What are the average, minimum, maximum and variation values of the icu patients (intensive care unit patients) for each country?")
print(icupatients_each)
print("----------------------------------------")

hosp_patients= contry_groupby.agg(q7_minimum=('hosp_patients', np.min), q7_maximum=('hosp_patients', np.max), q7_average=('hosp_patients', np.mean), q7_variation=('hosp_patients', np.var))
print("7. What are the average, minimum, maximum and variation values of the hosp patients (hospital patients) for each country?")
print(hosp_patients)
print("----------------------------------------")

weekly_icu_admissions= contry_groupby.agg(q8_minimum=('weekly_icu_admissions', np.min), q8_maximum=('weekly_icu_admissions', np.max), q8_average=('weekly_icu_admissions', np.mean), q8_variation=('weekly_icu_admissions', np.var))
print("8. What are the average, minimum, maximum and variation values of the weekly icu (intensive care unit) admissions for each country?")
print(weekly_icu_admissions)
print("----------------------------------------")

weekly_hosp_admissions= contry_groupby.agg(q9_minimum=('weekly_hosp_admissions', np.min), q9_maximum=('weekly_hosp_admissions', np.max), q9_average=('weekly_hosp_admissions', np.mean), q9_variation=('weekly_hosp_admissions', np.var))
print("9. What are the average, minimum, maximum and variation values of the weekly hospital admissions for each country?")
print(weekly_hosp_admissions)
print("----------------------------------------")

new_tests= contry_groupby.agg(q10_minimum=('new_tests', np.min), q10_maximum=('new_tests', np.max), q10_average=('new_tests', np.mean), q10_variation=('new_tests', np.var))
print("10. What are the average, minimum, maximum and variation values of new tests per day for each country?")
print(new_tests)
print("----------------------------------------")

total_tests= contry_groupby.agg(q11_total_test=('total_tests', np.max))
print("11. How many tests are conducted in total for each country so far?")
print(total_tests)
print("----------------------------------------")

positive_rate= contry_groupby.agg(q12_minimum=('positive_rate', np.min), q12_maximum=('positive_rate', np.max), q12_average=('positive_rate', np.mean), q12_variation=('positive_rate', np.var))
print("12. What are the average, minimum, maximum and variation values of the positive rates of the tests for each country?")
print(positive_rate)
print("----------------------------------------")

tests_per_case= contry_groupby.agg(q13_minimum=('tests_per_case', np.min), q13_maximum=('tests_per_case', np.max), q13_average=('tests_per_case', np.mean), q13_variation=('tests_per_case', np.var))
print("13. What are the average, minimum, maximum and variation values of the tests per case for each country?")
print(tests_per_case)
print("----------------------------------------")

people_vaccinated= contry_groupby.agg(q14_People_Fully_Vaccianated= ('people_vaccinated',np.max))
print("14. How many people are vaccinated by at least one dose in each country?")
print(people_vaccinated)
print("----------------------------------------")

people_fully_vaccinated= contry_groupby.agg(q15_People_Fully_Vaccianated= ('people_fully_vaccinated',np.max))
print("15. How many people are vaccinated fully in each country?")
print(people_fully_vaccinated)
print("----------------------------------------")

total_vaccinations = contry_groupby.agg(q16_total_vaccinations= ('total_vaccinations',np.max))
print("16. How many vaccinations are administered in each country so far?")
print(total_vaccinations)
print("----------------------------------------")

info = contry_groupby.agg(q17_population= ('population',np.max), q17_median_age= ('median_age',np.max), q17_aged_65_older= ('aged_65_older',np.max),q17_aged_70_older= ('aged_70_older',np.max),q17_gdp_per_capita= ('gdp_per_capita',np.max),q17_cardiovasc_death_rate= ('cardiovasc_death_rate',np.max),q17_diabetes_prevalence= ('diabetes_prevalence',np.max),q17_female_smokers= ('female_smokers',np.max),q17_male_smokers= ('male_smokers',np.max),q17_handwashing_facilities= ('handwashing_facilities',np.max),q17_hospital_beds_per_thousand= ('hospital_beds_per_thousand',np.max),q17_life_expectancy= ('life_expectancy',np.max), q17_human_development_index= ('human_development_index',np.max), )
print("17. List information about population, median age, # of people aged 65 older, # of people aged 70 older, economic performance, death rates due to heart disease, diabetes prevalence,  of female smokers,  of male smokers, handwashing facilities, hospital beds per thousand people, life expectancy and human development index.")
print(info)
print("----------------------------------------")

file= open("output.txt","w")
print("18. Summarize all the results that you obtain by the first 17 questions (except question 2).")
result = pd.concat([totalcases_each, totaldeaths_each,reproduction_each ,icupatients_each ,hosp_patients ,weekly_icu_admissions ,weekly_hosp_admissions ,new_tests ,total_tests ,positive_rate ,tests_per_case ,people_vaccinated ,people_fully_vaccinated,total_vaccinations,info ], axis=1)
print(result)
file.write(result.to_string())
file.close()
print("----------------------------------------")


# -*- coding: utf8 -*-
import matplotlib.pyplot as plt
import numpy as np
import scipy.integrate
plt.style.use('labdls-dark')

def lorenz_attractor(r, t, p):
    """
    Compute the right hand side of system of ODEs for Lorenz attractor.

    Parameters
    ----------
    r : array_like, shape (3,)
        (x, y, z) position of trajectory.
    t : dummy_argument
        Dummy argument, necessary to pass function into
        scipy.integrate.odeint
    p : array_like, shape (3,)
        Parameters (s, k, b) for the attractor.

    Returns
    -------
    output : ndarray, shape (3,)
        Time derivatives of Lorenz attractor.

    Notes
    -----
    .. Returns the right hand side of the system of ODEs describing
       the Lorenz attractor.
        x' = s * (y - x)
        y' = x * (k - z) - y
        z' = x * y - b * z
    """
    # Unpack variables and parameters
    x, y, z = r
    s, p, b = p

    return np.array([s * (y - x),
                     x * (p - z) - y,
                     x * y - b * z])

# Parameters to use
p = np.array([10.0, 28.0, 8.0 / 3.0])

# Initial condition
r0 = np.array([0.1, 0.0, 0.0])

# Time points to sample
t = np.linspace(0.0, 80.0, 10000)

# Use scipy.integrate.odeint to integrate Lorentz attractor
r = scipy.integrate.odeint(lorenz_attractor, r0, t, args=(p,))

# Unpack results into x, y, z.
x, y, z = r.transpose()

# Plot the result
plt.plot(x, z, '-', linewidth=0.5)
plt.xlabel(r'$x(t)$', fontsize=18)
plt.ylabel(r'$z(t)$', fontsize=18)

#plt.savefig('lorenz.png')
plt.show()


# Plot the gamma distribution
# Based on https://github.com/probml/pmtk3/blob/master/demos/gammaPlotDemo.m

import numpy as np
import matplotlib.pyplot as plt
import pyprobml_utils as pml

from scipy.stats import gamma

x = np.linspace(0, 7, 100)
aa = [1.0, 1.5, 2.0, 1.0, 1.5, 2.0]
bb = [1.0, 1.0, 1.0, 2.0, 2.0, 2.0]
#props = ['b-', 'r:', 'k-.', 'g--', 'c-', 'o-']
props = ['b-', 'r-', 'k-', 'b:', 'r:', 'k:']

for a, b, p in zip(aa, bb, props):
    y = gamma.pdf(x, a, scale=1/b, loc=0)
    plt.plot(x, y, p, lw=3, label='a=%.1f,b=%.1f' % (a, b))
plt.title('Gamma distributions')
plt.legend(fontsize=14)
pml.savefig('gammadist.pdf')
plt.show()

x = np.linspace(0, 7, 100)
b = 1
plt.figure()
for a in [1, 1.5, 2]:
    y = gamma.pdf(x, a, scale=1/b, loc=0)
    plt.plot(x, y)
plt.legend(['a=%.1f, b=1' % a for a in [1, 1.5, 2]])
plt.title('Gamma(a,b) distributions')
pml.savefig('gammaDistb1.pdf')
plt.show()

x = np.linspace(0, 7, 100)
b = 1
a = 1
rv = gamma(a, scale=1/b, loc=0)
y = rv.pdf(x)
plt.plot(x, y)
plt.axvline(1, color='r')
plt.title('Gamma(1,1) distribution')
pml.savefig('gammaDist1.pdf')
plt.show()


'''
查找 - 顺序查找和二分查找
算法： 解决问题的方法(步骤)
评价一个算法的好坏主要有两个指标：渐进时间复杂度和渐进空间复杂度，
通常一个算法很难做到时间复杂度和空间复杂度都很低(因为时间和空间是不可调和的矛盾)
表示渐进时间复杂度通常使用大O标记
O(c): 常量时间复杂度 - 哈希存储 / 布隆过滤器
O(log_2n): 对数时间复杂度 - 折半查找
O(n):线性时间复杂度 - 顺序查找
O(n * log_2 n): - 对数线性时间复杂度 - 高级排序算法 （归并排序、快速排序）
O(n ** 2): 平方时间复杂度 - 简单排序算法(冒泡排序、选择排序、插入排序)
O(n ** 3):立方时间复杂度 - Floyd算法 / 矩阵乘法运算
也称为多项式时间复杂度
O(2 ** n):几何级数时间复杂度 - 汉诺塔
O(3 ** n):几何级数时间复杂度
也称为指数时间复杂度
O(n!):阶乘时间复杂度 - 旅行经销商问题 - NP
'''

from math import log2, factorial
from matplotlib import pyplot
import numpy

def seq_search(items:list, elem) -> int:
    '''顺寻查找'''
    for index, item in enumerate(items):
        if elem == item:
            return index
    return -1

def bin_search(items, elem):
    '''二分查找'''
    start, end = 0, len(items) - 1
    while start <= end:
        mid = (start + end) // 2
        if elem > items[mid]:
            start = mid + 1
        elif elem < items[mid]:
            end = mid - 1
        else:
            return mid
    return -1

def main():
    '''主函数(程序入口)'''
    num = 6
    styles = ['r-.', 'g-*', 'b-o', 'y-x', 'c-^', 'm-+', 'k-d']
    legends = ['对数', '线性', '线性对数', '平方', '立方', '几何级数', '阶乘']
    x_data = [x for x in range(1, num + 1)]
    y_data1 = [log2(y) for y in range(1, num + 1)]
    y_data2 = [y for y in range(1, num + 1)]
    y_data3 = [y * log2(y) for y in range(1, num + 1)]
    y_data4 = [y ** 2 for y in range(1, num + 1)]
    y_data5 = [y ** 3 for y in range(1, num + 1)]
    y_data6 = [3 ** y for y in range(1, num + 1)]
    y_data7 = [factorial(y) for y in range(1, num + 1)]
    y_datas = [y_data1, y_data2, y_data3, y_data4, y_data5, y_data6, y_data7]
    for index, y_data in enumerate(y_datas):
        pyplot.plot(x_data, y_data,styles[index])
    pyplot.legend(legends)
    pyplot.xticks(numpy.arange(1, 7, step=1))
    pyplot.yticks(numpy.arange(0, 751, step=50))
    pyplot.show()

if __name__ == '__main__':
    main()


from cvxopt import matrix as cvxmat, sparse as cvxsparse, spmatrix as cvxspmatrix
from cvxopt.solvers import qp as cvxQP, options as cvxopt
import numpy as np

def quadprog(H, f, Aeq=None, beq=None, Aineq=None, bineq=None, lb=None, ub=None,abstol=None,reltol=None,maxiters=None,returnVar='yes'):
    """
    minimize:
            (1/2)*x'*H*x + f^T*x
    subject to:
            Aeq*x = beq
	    Aineq <= bineq
            lb <= x <= ub

##########################################################################################################################
#        Matlab style quadratic programming using cvxopt with equality, inequality and lower and upper bounds.           #
#                                                                                #
#             I modified slightly the code from https://gist.github.com/garydoranjr/1878742 to fit what I wanted                  #
#                                                                                #
#                     Louis-Francois Arsenault, Columbia University la2518@columbia.edu (2013-2017)                      #
##########################################################################################################################
#                                                                                #
#       INPUTS:                                                                                #
#                                                                                #
#         H     : numpy 2d array([[h_11,h_12,...,h_1n],[h_21,h_22,...,h_2n],...,[h_n1,h_n2,...,h_nn]])                   #
#		  can also be a scalar which mean H is the scalar H time the identity matrix                             #
#															 #
#         f     : numpy 1d array([f_1,f_2,f_3,...,f_n])                                                                  #
#                                                                                #
#         Aeq   : numpy 2d array([[aeq_11,aeq_12,...,aeq_1n],[aeq_21,aeq_22,...,aeq_2n],...,[aeq_p1,aeq_p2,...,aeq_pn]]) #
#                                                                                #
#         beq   : numpy 1d array([beq_1,beq_2,beq_3,...,beq_p])                                                          #
#                                                                                #
#         Aineq : numpy 2d array([[ai_11,ai_12,...,ai_1n],[ai_21,ai_22,...,ai_2n],...,[ai_l1,ai_l2,...,ai_ln]])          #
#                                                                                #
#         bineq : numpy 1d array([bi_1,bi_2,bi_3,...,bi_l])                                                              #
#                                                                                #
#         lb    : numpy 1d array([lb_1,lb_2,...,lb_n])                                                                   #
#                                                                                #
#         ub    : numpy 1d array([ub_1,ub_2,...,ub_n])                                                                   #
#                                                                                #
#	  Optionnal:													 #
#	  abstol   : absolute tolerance											 #
#	  reltol   : relative tolerance											 #
#	  maxiters : max number of iterations										 #
#															 #
##########################################################################################################################
#	Note that as long as f,beq,bineq,lb and ub are somewhat 1d like arrays like shape =  (m,1) or (1,m),		 #
#			         they will be reshaped to have the correct (m,) shape !!                                 #
##########################################################################################################################
"""
    P, q, G, h, A, b = _convert(H, f, Aeq, beq,Aineq,bineq, lb, ub)

    cvxopt['show_progress'] = False
    #Use options given. If None, use default
    if abstol != None:
	cvxopt['abstol'] = abstol
    if reltol != None:
	cvxopt['reltol'] = reltol
    if maxiters != None:
	cvxopt['maxiters'] = maxiters

    #Only returns the values
    results = cvxQP(P, q, G, h, A, b)

    #Convert back to NumPy array
    if returnVar is 'yes':
    	return np.array(results['x'])
    else:
	return results

def _convert(H, f, Aeq=None, beq=None,Aineq=None,bineq=None, lb=None, ub=None):

    #Convert everything to
    #cvxopt-style matrices

    #P and q are always given
    if isinstance(H,np.ndarray) is False:
	#H is a scalar meaning H*I, where I identity matrix
	P=H*speye(len(f))
    else:
    	P = cvxmat(H,tc='d')
    q = cvxmat(f, tc='d')

    if Aeq is None:
        A = None
	b = None #if no Aeq, no beq
    else:
	if Aeq.ndim == 1:
		Aeq.shape = (1,Aeq.size)
	elif (Aeq.shape[1]==1):
		Aeq = Aeq.transpose()
        A = cvxmat(Aeq,tc='d')
	if beq.ndim != 1:
		beq.shape = (beq.size,)
	b = cvxmat(beq,tc='d')

    if Aineq is None:
	if lb is None:
		if ub is None:
			G = None
			h = None
		else:
			if ub.ndim != 1:
		                ub.shape = (ub.size,)
			n=ub.size
			G = cvxsparse(speye(n),tc='d')
			h = cvxmat(ub,tc='d')
	else:
		if lb.ndim != 1:
                	lb.shape = (lb.size,)
		if ub is None:
			n=lb.size
			G = cvxsparse(-speye(n),tc='d')
			h = cvxmat(-lb,tc='d')
		else:
			if ub.ndim != 1:
                                ub.shape = (ub.size,)
			n = lb.size
    			G = cvxsparse([speye(n), -speye(n)],tc='d')
    			h = cvxmat(np.hstack([ub,-lb]),tc='d')
    else:
	if bineq.ndim != 1:
        	bineq.shape = (bineq.size,)
	if lb is None:
		if ub is None:
			G = cvxmat(Aineq,tc='d')
			h = cvxmat(bineq,tc='d')
		else:
			if ub.ndim != 1:
                                ub.shape = (ub.size,)
			n = ub.size
			Gt = cvxmat(Aineq,tc='d')
			G = cvxmat([Gt,speye(n)],tc='d')
			h = cvxmat(np.hstack([bineq,ub]),tc='d')
	else:
		if lb.ndim != 1:
                	lb.shape = (lb.size,)
		if ub is None:
			n = lb.size
			Gt = cvxmat(Aineq,tc='d')
                        G = cvxmat([Gt,-speye(n)],tc='d')
                        h = cvxmat(np.hstack([bineq,-lb]),tc='d')
		else:
			if ub.ndim != 1:
                                ub.shape = (ub.size,)
			n = lb.size
			Gt = cvxmat(Aineq,tc='d')
                        G = cvxmat([Gt,speye(n),-speye(n)],tc='d')
                        h = cvxmat(np.hstack([bineq,ub,-lb]),tc='d')
    return P, q, G, h, A, b

def speye(n):

#    Create a sparse identity matrix

    r = range(n)
    return cvxspmatrix(1.0, r, r)


# Question: https://projecteuler.net/problem=29

import numpy as np

N_a = 100
N_b = 100

count = np.ones((N_a+1, N_b+1), dtype = np.uint8)
count[0] = 0
count[1] = 0
count[:,0] = 0
count[:,1] = 0
for x in range(2, 11):
    #  2^{2,4,6,...100} = 4^{1,2,3,...,50}
    # ---
    #  2^{3,6,9,...,99} = 8^{1,2,3,...,33}
    #  4^{3,6,9,...,99} = 8^{2,4,6,...,66}
    # ---
    #  2^{4,8,12,...,100} = 16^{1,2,3,...,25}
    #  4^{4,8,12,...,100} = 16^{2,4,6,...,50}
    #  8^{4,8,12,...,100} = 16^{3,6,9,...,75}
    #  ---
    #  2^{5,10,15,...,100} = 32^{1,2,3,...,20}
    #  4^{5,10,15,...,100} = 32^{2,4,6,...,40}
    #  8^{5,10,15,...,100} = 32^{3,6,9,...,60}
    # 16^{5,10,15,...,100} = 32^{4,8,12,...,80}
    n = x * x
    k = 2
    while n <= N_a:
        for i in range(1, k):
            #print(x, n, list(range(i, 100//k*i+1, i)))
            count[n][i:100//k*i+1:i] = 0
        n = n * x
        k = k + 1

print(np.sum(count))
""" Doesn't work
start_from = [2] * (N_a+1)

count = 0

for i in range(2, N_a + 1):
    n = i * i
    k = 2
    while n <= N_a:
        start_from[n] = max(start_from[n], N_b // k + 1)
        n = n * i
        k = k + 1
    count = count + N_b - start_from[i] + 1
    print(i, count)

for i, j in enumerate(start_from):
    print(i, start_from[i], end = '| ')
    if i % 20 == 19:
        print()
print(count)
"""


import numpy as np

# Problem 40 : Champernowne's constant

def dn(n):
    """
    This function returns the last digit in the decimal number 0.123456...
    (loop over digits while there is n digits after the comma)
    """
    i = 0
    champ = "0."
    while len(champ) <= n+2:
        i += 1
        champ += str(i)
    dn = champ[n+1]
    return dn

def dn_liste(liste_n):
	"""
	This function return the a list with the dn value for every n in the given list.
	"""
    liste_n = np.sort(liste_n)
    liste_dn = []
    i = 0
    j = 0
    champ = "0."
    while len(champ) <= liste_n[-1]+2:
        i += 1
        champ += str(i)
        if len(champ) >= liste_n[j]+2:
            liste_dn.append(int(champ[liste_n[j]+1]))
            j += 1
    return liste_dn

def champernowne_constant_product(liste_n):
	"""
	This function returns the champernowne constant product.
	"""
    liste_dn = dn_liste(liste_n)
    product = 1
    for elt in liste_dn:
        product *= elt
    return product

print(champernowne_constant_product(
    [1, 10, 100, 1000, 10000, 100000, 1000000]))

# Result 210


import numpy as np
import pandas as pd

def annualizedRet(r, num_periods):
    '''

    @param r: series, returns
    @param num_periods: scalar, number of periods in return series
    @return: scalar, annualized return
    '''

    comp = (1 + r).prod()
    nPer = r.shape[0]
    return comp ** (num_periods / nPer) - 1

def annualizedVol(r, num_periods, downside = False):
    '''

    @param r: series, returns
    @param num_periods: scalar, number of periods in return series
    @param downside: bool, for downside std
    @return: scalar, annualized volatility
    '''

    if downside:
        semistd = r[r < 0].std()
        return semistd * (num_periods ** 0.5)
    else:
        return r.std() * (num_periods ** 0.5)

def drawdown(r: pd.Series):
    '''

    @param r: series, returns
    @return: dictionary: 'hwm':high watermark, 'drawdowns': drawdown periods
    '''

    index = 1000 * (1 + r).cumprod()
    highwatermark = index.cummax()
    drawdowns = (index - highwatermark) / highwatermark
    return pd.DataFrame(dict(hwm = highwatermark,
                             drawdowns=drawdowns))

def skewness(r):
    '''

    @param r: series, returns
    @return: scalar, third moment
    '''
    centerMoment = r - r.mean()
    sigR = r.std(ddof=0)
    exp = (centerMoment ** 3).mean()
    return exp / sigR ** 3

def kurtosis(r):
    '''

    @param r: series, returns
    @return: scalar, fourth moment
    '''

    centerMoment = r - r.mean()
    sigR = r.std(ddof=0)
    exp = (centerMoment ** 4).mean()
    return exp / sigR ** 4

def varGaussian(r, level=5, modified=False):
    '''

    @param r: series, returns
    @param level: scalar, significance level
    @param modified: bool, taylor expansion and approximation of the VAR
    @return: scalar, percentage of portfolio Value at Risk
    '''
    from scipy.stats import norm
    z = norm.ppf(level / 100)

    if modified is True:
        s = skewness(r)
        k = kurtosis(r)
        z = (z +
             (z ** 2 - 1) * s / 6 +
             (z ** 3 - 3 * z) * (k - 3) / 24 -
             (2 * z ** 3 - 5 * z) * (s ** 2) / 36
             )
    return - (r.mean() + z * r.std(ddof=0))

def sharpeRatio(r, rf, num_periods):
    '''

    @param r: series, returns
    @param rf: scalar or series, of risk-free rate proxy
    @param num_periods: scalar, number of periods
    @return: scalar, risk-adjusted return
    '''
    # convert the annual riskfree to per period
    rf = (1 + rf) ** (1 / num_periods) - 1
    excessRets = r - rf
    annExcessRets = annualizedRet(excessRets, num_periods)
    annVol = annualizedVol(r, num_periods)
    return annExcessRets / annVol

def sortinoRatio(r,rf, num_periods):
    '''

    @param r: series, returns
    @param rf: scalar or series, of risk-free rate proxy
    @param num_periods: scalar, number of periods
    @return: scalar, risk-adjusted return
    '''

    rf = (1 + rf) ** (1 / num_periods) - 1
    excessRets = r - rf
    annExcessRets = annualizedRet(excessRets, num_periods)
    anndownsideVol = annualizedVol(r, num_periods, downside=True)
    return annExcessRets / anndownsideVol

def summary_stats(r, riskFree=0, periodsInYear=252):
    '''

    @param r: series, return
    @param riskFree: scalar or series, of risk-free rate proxy
    @param num_periods: scalar, number of periods
    @param title: string, title of the returned df
    @return: DataFrame of summary statistics
    '''

    if not isinstance(r,pd.DataFrame):
        r = pd.DataFrame(r)

    annR = r.aggregate(annualizedRet, num_periods= periodsInYear)
    annVol = r.aggregate(annualizedVol, num_periods= periodsInYear)
    dd = r.aggregate(lambda r: drawdown(r).drawdowns.min())
    skew = r.aggregate(skewness)
    kurt = r.aggregate(kurtosis)
    modVar = r.aggregate(varGaussian, level=5, modified=True)
    sharpe = r.aggregate(sharpeRatio, rf=riskFree, num_periods = periodsInYear)
    sortino = r.aggregate(sortinoRatio, rf = riskFree, num_periods = periodsInYear)

    stats = pd.DataFrame({
        'Annualized Returns': annR*100,
        'Annualized Volatility':  annVol*100,
        'Sharpe Ratio': sharpe,
        'Sortino Ratio': sortino,
        'Max Drawdown':  dd*100,
        'Skewness': skew,
        'Kurtosis': kurt,
        'Cornish Fisher adj. VAR 5%': modVar*100,
    })

    #formatting
    stats['Annualized Returns'] = stats['Annualized Returns'].map('{:,.2f}%'.format)
    stats['Annualized Volatility'] = stats['Annualized Volatility'].map('{:,.2f}%'.format)
    stats['Sharpe Ratio'] = stats['Sharpe Ratio'].map('{:,.2f}'.format)
    stats['Sortino Ratio'] = stats['Sortino Ratio'].map('{:,.2f}'.format)
    stats['Max Drawdown'] = stats['Max Drawdown'].map('{:,.2f}%'.format)
    stats['Skewness'] = stats['Skewness'].map('{:,.2f}'.format)
    stats['Kurtosis'] = stats['Kurtosis'].map('{:,.2f}'.format)
    stats['Cornish Fisher adj. VAR 5%'] = stats['Cornish Fisher adj. VAR 5%'].map('{:,.2f}%'.format)

    return stats.T


import numpy as np
import matplotlib.pyplot as plt
from scipy.sparse import spdiags
from scipy.sparse import linalg as lg

# Quadratic function
class Quad(object):
    def __init__(self, Q, p):
        self.Q = Q
        self.p = p

    def grad_func(self, x):
        df = np.dot(self.Q, x) - self.p
        return df

# Solver
class CG_Solve(object):

    def __init__(self, A, b, x_0, TOL, MAXIT):
        self.func = Quad(A, b)
        self.x = x_0
        self.TOL = TOL
        self.MAXIT = MAXIT
        self.g = self.func.grad_func(self.x)
        self.d = - self.g
        self.k = 1
        self.res = [np.linalg.norm(self.g)]

    def calc(self, ):
        while self.res[-1] > self.TOL and self.k < self.MAXIT:
            z = np.dot(self.func.Q, np.copy(self.d))
            alpha = np.linalg.norm(self.g) ** 2 / np.dot(self.d.T, z)
            self.x += alpha * self.d
            self.g += alpha * z
            res = np.linalg.norm(self.g)
            self.res.append(res)
            beta = (self.res[-1] / self.res[-2]) ** 2
            self.d = - self.g + beta * self.d
            self.k += 1
        return self.res, self.k, self.x

# Generate Matrix
class gen_mat(object):

    def __init__(self, n):
        self.n = n

    def gen_diag(self, ):
        data = np.array([- np.ones(self.n), 2 * np.ones(self.n), - np.ones(self.n)])
        diags = np.array([-1,0,1])
        M = spdiags(data, diags, self.n, self.n).toarray()
        return M

def main(n):
    mat = gen_mat(n)
    run = CG_Solve(mat.gen_diag(), -np.ones(n),np.zeros(n), 1e-5, 2000)
    sci = lg.cg(mat.gen_diag(), -np.ones(n), np.zeros(n), 1e-5, 2000)
    result = run.calc()
    print('result :', result[2])
    print('result_sci :', sci[0])
    plt.semilogy(range(0, result[1]), np.log(result[0]), label='CG')
    plt.legend()
    plt.ylabel('Residuals')
    plt.xlabel('Iterations')
    plt.show()

if __name__ == '__main__':
    main(25)


import csv
import json

import numpy as np

class NpEncoder(json.JSONEncoder):
    def default(self, x):
        if isinstance(x, np.ndarray):
            return x.tolist()
        return super().default(x)

def sigmoid(x) -> np.ndarray:
    return 1 / (1 + np.exp(-x))

def sigmoid_derivative(x) -> np.ndarray:
    return x * (1 - x)

def softmax(a) -> np.ndarray:
    exp = np.exp(a - np.max(a, axis=0))
    return exp / exp.sum(axis=1, keepdims=True)

def cross_entropy(outputs, labels, epsilon=1e-12) -> np.double:
    # avoid error
    outputs = np.clip(outputs, epsilon, 1. - epsilon)
    return -np.sum(labels * np.log(outputs))

def load_csv_np(path):
    """
    load csv as np array
    :param path: file path
    """
    with open(path) as fd:
        return np.asarray([np.asarray(row, dtype=np.double) for row in csv.reader(fd)])

def load_csv(path):
    """
    load csv as list
    :param path: file path
    """
    with open(path) as fd:
        for row in csv.reader(fd):
            yield row


# Library of Gaussian Mixture Models
# To-do: convert library into class
# Author: Gerardo Durán-Martín

import superimport

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

def plot_mixtures(X, mu, pi, Sigma, r, step=0.01, cmap="viridis", ax=None):
    ax = ax if ax is not None else plt.subplots()[1]
    colors = ["tab:red", "tab:blue"]
    x0, y0 = X.min(axis=0)
    x1, y1 = X.max(axis=0)
    xx, yy = np.mgrid[x0:x1:step, y0:y1:step]
    zdom = np.c_[xx.ravel(), yy.ravel()]

    Norms = [multivariate_normal(mean=mui, cov=Sigmai)
             for mui, Sigmai in zip(mu, Sigma)]

    for Norm, color in zip(Norms, colors):
        density = Norm.pdf(zdom).reshape(xx.shape)
        ax.contour(xx, yy, density, levels=1,
                    colors=color, linewidths=5)

    ax.scatter(*X.T, alpha=0.7, c=r, cmap=cmap, s=10)
    ax.set_xlim(x0, x1)
    ax.set_ylim(y0, y1)

def compute_responsibilities(k, pi, mu, sigma):
    Ns = [multivariate_normal(mean=mu_i, cov=Sigma_i) for mu_i, Sigma_i in zip(mu, sigma)]
    def respons(x):
        elements = [pi_i * Ni.pdf(x) for pi_i, Ni in zip(pi, Ns)]
        return elements[k] / np.sum(elements, axis=0)
    return respons

def e_step(pi, mu, Sigma):
    responsibilities = []
    for i, _ in enumerate(mu):
        resp_k = compute_responsibilities(i, pi, mu, Sigma)
        responsibilities.append(resp_k)
    return responsibilities

def m_step(X, responsibilities, S=None, eta=None):
    N, M = X.shape
    pi, mu, Sigma = [], [], []
    has_priors = eta is not None
    for resp_k in responsibilities:
        resp_k = resp_k(X)
        Nk = resp_k.sum()
        # mu_k
        mu_k = (resp_k[:, np.newaxis] * X).sum(axis=0) / Nk
        # Sigma_k
        dk = (X - mu_k)
        Sigma_k = resp_k[:, np.newaxis, np.newaxis] * np.einsum("ij, ik->ikj", dk, dk)
        Sigma_k = Sigma_k.sum(axis=0)
        if not has_priors:
            Sigma_k = Sigma_k / Nk
        else:
            Sigma_k = (S + Sigma_k) / (eta + Nk + M + 2)

        # pi_k
        pi_k = Nk / N

        pi.append(pi_k)
        mu.append(mu_k)
        Sigma.append(Sigma_k)
    return pi, mu, Sigma

def gmm_log_likelihood(X, pi, mu, Sigma):
    likelihood =  0
    for pi_k, mu_k, Sigma_k in zip(pi, mu, Sigma):
        norm_k = multivariate_normal(mean=mu_k, cov=Sigma_k)
        likelihood += pi_k * norm_k.pdf(X)
    return np.log(likelihood).sum()

def apply_em(X, pi, mu, Sigma, threshold=1e-5, S=None, eta=None):
    r = compute_responsibilities(0, pi, mu, Sigma)(X)
    log_likelihood = gmm_log_likelihood(X, pi, mu, Sigma)
    hist_log_likelihood = [log_likelihood]
    hist_coeffs = [(pi, mu, Sigma)]
    hist_responsibilities = [r]

    while True:
        responsibilities = e_step(pi, mu, Sigma)
        pi, mu, Sigma = m_step(X, responsibilities, S, eta)
        log_likelihood = gmm_log_likelihood(X, pi, mu, Sigma)

        hist_coeffs.append((pi, mu, Sigma))
        hist_responsibilities.append(responsibilities[0](X))
        hist_log_likelihood.append(log_likelihood)

        if np.abs(hist_log_likelihood[-1] / hist_log_likelihood[-2] - 1) < threshold:
            break
        results = {
            "coeffs": hist_coeffs,
            "rvals": hist_responsibilities,
            "logl": hist_log_likelihood
        }
    return results


from math import pi, cos, sin
import numpy as np
import random
from matplotlib import pyplot as plt, colors as mcol
from pymicro.view.vol_utils import compute_affine_transform

colors = 'brgmk'
my_gray = (0.8, 0.8, 0.8)
random.seed(13)
n = 5
ref_points = np.empty((n, 2))
for i in range(n):
    ref_points[i, 0] = random.randint(0, 10)
    ref_points[i, 1] = random.randint(0, 10)
    print(ref_points[i])
    plt.plot(ref_points[i, 0], ref_points[i, 1], 'o', color=colors[i], markersize=10, markeredgecolor='none',
             label='reference points' if i == 0 else '')
plt.grid()
plt.axis([0, 20, 0, 20])
plt.xlabel('X coordinate')
plt.ylabel('Y coordinate')
plt.legend(numpoints=1)
plt.savefig('pointset_registration_1.png', format='png')

# compute the affine transform by composing R, S and T
s = 1.4
angle = 22 * pi / 180.
tx, ty = 5, 3
S = np.array([[s, 0.0, 0.0],
              [0.0, s, 0.0],
              [0.0, 0.0, 1.0]])
R = np.array([[cos(angle), -sin(angle), 0.0],
              [sin(angle), cos(angle), 0.0],
              [0.0, 0.0, 1.0]])
T = np.array([[1.0, 0.0, tx],
              [0.0, 1.0, ty],
              [0.0, 0.0, 1.0]])
A = np.dot(T, np.dot(S, R))
print('full affine transform:\n{:s}'.format(A))

# transform the points
tsr_points = np.empty_like(ref_points)
for i in range(n):
    p = np.dot(A, [ref_points[i, 0], ref_points[i, 1], 1])
    tsr_points[i, 0] = p[0]
    tsr_points[i, 1] = p[1]
    # tsr_points[i] = T[:2] + np.dot(np.dot(S[:2, :2], R[:2, :2]), ref_points[i])
    print(tsr_points[i])
    plt.plot(tsr_points[i, 0], tsr_points[i, 1], 's', color=colors[i], markersize=10, markeredgecolor='none',
             label='transformed points' if i == 0 else '')
# overwrite reference points in light gray
plt.plot(ref_points[:, 0], ref_points[:, 1], 'o', color=my_gray, markersize=10, markeredgecolor='none',
         label='reference points' if i == 0 else '')
# draw dashed lines between reference and transformed points
for i in range(n):
    plt.plot([ref_points[i, 0], tsr_points[i, 0]], [ref_points[i, 1], tsr_points[i, 1]], '--', color=colors[i])
plt.legend(numpoints=1)
plt.savefig('pointset_registration_2.png', format='png')

# compute the affine transform from the point set
translation, transformation = compute_affine_transform(ref_points, tsr_points)
invt = np.linalg.inv(transformation)
offset = -np.dot(invt, translation)
ref_centroid = np.mean(ref_points, axis=0)
tsr_centroid = np.mean(tsr_points, axis=0)
new_points = np.empty_like(ref_points)
for i in range(n):
    new_points[i] = ref_centroid + np.dot(transformation, tsr_points[i] - tsr_centroid)
    print('point %d will move to (%3.1f, %3.1f) to be compared with (%3.1f, %3.1f)' % (
        i, new_points[i, 0], new_points[i, 1], ref_points[i, 0], ref_points[i, 1]))
    plt.plot(new_points[i, 0], new_points[i, 1], 'x', color=colors[i], markersize=12,
             label='new points' if i == 0 else '')
plt.legend(numpoints=1)
plt.savefig('pointset_registration_3.png', format='png')
plt.show()


import numpy as np

def weights(N,p):
    """ Compute the weights for all (uniform) N-point
        finite difference approximations to the pth derivative """

    M = np.array([[ (i**j) for i in range(1-N,N) ] \
                           for j in range(N)])
    G = np.diag(np.cumprod([1]+[j for j in range(1,N)]))
    return np.flipud([np.linalg.solve(M[:,k:(k+N)],G[p]) for k in range(N)])

def stencil_weights( N, p=1, tol=1e-13 ):
    W = weights(N,p)
    d = int(N//2)
    h = [k-d for k in range(N)]
    h,w = zip(*[ (h[k],w) for k,w in enumerate(W[d]) if abs(w)>tol ])
    return h,w

def check_derivative(fun,exact,x,v,delta,order=1):

    import numpy as np
    from numpy.linalg import norm

    d,w = stencil_weights(order+1)

    phi = lambda h : fun(x+h*v)
    df = lambda h : sum( fun(x+j*h*v)*w[k] for k,j in enumerate(d) )/h

    if isinstance(delta,np.ndarray):
        assert np.all(np.isreal(delta))
        return np.array([ norm(df(h)-exact) for h in delta ])

    elif hasattr(delta,'__getitem__') and hasattr(delta,'__len__'):
        assert np.all([np.isreal(delta[k]) for k in range(len(delta))])
        return [ norm(df(h)-exact) for h in delta ]

    elif np.isscalar(delta):
        assert np.isreal(delta)
        return norm(df(h)-exact)

    else:
        raise TypeError("Finite difference step delta must either be a real-valued scalar, an array-like container of real scalars, or an iterable that yields real scalars.")


"""
 NAME:
    LUMDIST

 PURPOSE:
    Calculate luminosity distance (in Mpc) of an object given its redshift
 EXPLANATION:
    The luminosity distance in the Friedmann-Robertson-Walker model is
    taken from  Caroll, Press, and Turner (1992, ARAA, 30, 499), p. 511
    Uses a closed form (Mattig equation) to compute the distance when the
    cosmological constant is zero.   Otherwise integrates the function using
    QSIMP.
 CALLING SEQUENCE:
    result = lumdist(z, [H0 = , k = , Omega_M =, Lambda0 = , q0 = ,/SILENT])

 INPUTS:
    z = redshift, positive scalar or vector

 OPTIONAL KEYWORD INPUTS:
    /SILENT - If set, the program will not display adopted cosmological
        parameters at the terminal.
    H0: Hubble parameter  in km/s/Mpc, default is 70

        No more than two of the following four parameters should be
        specified.   None of them need be specified -- the adopted defaults
        are given.
    k - curvature constant, normalized to the closure density.   Default is
        0, indicating a flat universe
    Omega_m -  Matter density, normalized to the closure density, default
        is 0.3.   Must be non-negative
    Lambda0 - Cosmological constant, normalized to the closure density,
        default is 0.7
    q0 - Deceleration parameter, numeric scalar = -R*(R'')/(R')^2, default
        is -0.55

 OUTPUTS:
    The result of the function is the luminosity distance (in Mpc) for each
    input value of z.

 EXAMPLE:
    (1) Plot the distance of a galaxy in Mpc as a function of redshift out
        to z = 5.0, assuming the default cosmology (Omega_m=0.3, Lambda = 0.7,
        H0 = 70 km/s/Mpc)

        IDL> z = findgen(50)/10.
        IDL> plot,z,lumdist(z),xtit='z',ytit='Distance (Mpc)'

        Now overplot the relation for zero cosmological constant and
        Omega_m=0.3
        IDL> oplot,z,lumdist(z,lambda=0,omega=0.3),linestyle=1
 COMMENTS:
    (1) Integrates using the IDL Astronomy Version procedure QSIMP.    (The
    intrinsic IDL QSIMP function is not called because of its ridiculous
    restriction that only scalar arguments can be passed to the integrating
    function.)
    (2) Can fail to converge at high redshift for closed universes with
    non-zero lambda.   This can presumably be fixed by replacing QSIMP with
    an integrator that can handle a singularity
 PROCEDURES CALLED:
    COSMO_PARAM, QSIMP
 REVISION HISTORY:
    Written   W. Landsman        Raytheon ITSS       April 2000
    Avoid integer overflow for more than 32767 redshifts  July 2001
    Use double precision J. Moustakas/W. Landsman April 2008
    Convert to python S. Koposov                        2010
"""

from numpy import array, ndarray, sqrt, sin, sinh, maximum
from cosmo_param import cosmo_param
from scipy.integrate import quad
from math import sqrt as msqrt

def ldist(z, q0=None, lambda0=None):

   term1 = (1. + z) ** 2
   term2 = 1. + 2. * (q0 + lambda0) * z
   term3 = z * (2. + z) * lambda0
   denom = (term1 * term2 - term3)
   if denom>0:
      out = 1. / msqrt(denom) # since the function is used with scalar arguments
								  # I use math.sqrt instead of numpy.sqrt for
                                  # performance reasons
   else:
      out = 0.
   return out

def lumdist(z, h0=None, k=None, lambda0=None, omega_m=None, q0=None, silent=None):
   '''Syntax: result = lumdist(z, H0 = ,k=, Lambda0 = ])
   Returns luminosity distance in Mpc'''

   scal=False
   scalret = lambda x : x[0] if scal else x

   if isinstance(z, list):
      z = numpy.array(z)
   elif isinstance(z, ndarray):
      pass
   else:
      scal = True
      z = array([z])
   n = len(z)

   omega_m, lambda0, k, q0 = cosmo_param(omega_m, lambda0, k, q0)

   # Check keywords
   c = 2.99792458e5                  #  speed of light in km/s
   if h0 is None:
      h0 = 70
   if not silent:
      print 'LUMDIST: H0:', h0, ' Omega_m:', omega_m, ' Lambda0', lambda0, ' q0: ', q0, ' k: ', k#, format='(A,I3,A,f5.2,A,f5.2,A,f5.2,A,F5.2)'

   # For the case of Lambda = 0, we use the closed form from equation 5.238 of
   # Astrophysical Formulae (Lang 1998).   This avoids terms that almost cancel
   # at small q0*z better than the more familiar Mattig formula.
   #
   if lambda0 == 0:
      denom = sqrt(1 + 2 * q0 * z) + 1 + q0 * z
      dlum = (c * z / h0) * (1 + z * (1 - q0) / denom)
      return scalret(dlum)

      # For non-zero lambda
   else:
      dlum = z * 0.0
      for i in range(n):
         if z[i] <= 0.0:
            dlum[i] = 0.0
         else:
            lz = quad(ldist, 0, z[i], args=(q0, lambda0))
            dlum[i] = lz[0]

      if k > 0:
         dlum = sinh(sqrt(k) * dlum) / sqrt(k)
      else:
         if k < 0:
            dlum = maximum(sin(sqrt(-k) * dlum) / sqrt(-k), 0)
      return scalret(c * (1 + z) * dlum / h0)


import cocos.numerics as cn
from cocos.numerics.numerical_package_selector import \
    select_num_pack_by_dtype_from_iterable

import cocos.device as cd

from cocos.symbolic import (
    LambdifiedMatrixExpression, \
    find_length_of_state_vectors
)
import numpy as np
import sympy as sym
import time

sym.init_printing()

# define symbolic arguments to the function
x1, x2, x3, t = sym.symbols('x1, x2, x3, t')
argument_symbols = (x1, x2, x3)

# define a function f: R^3 -> R^3
g = sym.Function('g')
f = sym.Matrix([[x1 + x2], [(g(t) * x1 + x3) ** 2], [sym.exp(x1 + x2 + g(t))]])
print("defining the vector valued function f(x1, x2, x3) as")
print(f)
print()

# Compute the Jacobian symbolically
jacobian_f = f.jacobian([x1, x2, x3])
print("symbolically derived Jacobian:")
print(jacobian_f)
print()

def numeric_time_function(t: float):
    return np.log(t)

def jacobian_direct(t, x1, x2, x3):
    g = numeric_time_function
    state_vectors = (x1, x2, x3)
    R = find_length_of_state_vectors(state_vectors)
    num_pack = select_num_pack_by_dtype_from_iterable(state_vectors)
    result = num_pack.zeros((R, 3, 3))

    result[:, 0, 0] = 1.0
    result[:, 0, 1] = 1.0
    result[:, 0, 2] = 0.0

    result[:, 1, 0] = 2.0 * g(t) * (g(t) * x1 + x3)
    result[:, 1, 1] = 0.0
    result[:, 1, 2] = 2.0 * (g(t) * x1 + x3)

    result[:, 2, 0] = num_pack.exp(x1 + x2 + g(t))
    result[:, 2, 1] = num_pack.exp(x1 + x2 + g(t))
    result[:, 2, 2] = 0.0

    return result

# Convert the symbolic array expression to an object that can evaluated
# numerically on the cpu or gpu.
jacobian_f_lambdified \
    = LambdifiedMatrixExpression(
        argument_symbols=argument_symbols,
        time_symbol=t,
        symbolic_matrix_expression=jacobian_f,
        symbolic_time_function_name_to_numeric_time_function_map={'g': numeric_time_function})

# Define a 3 dimensional vector X = (x1, x2, x3) = (1, 2, 3)
X_gpu = cn.array([[1], [2], [3]])

# Numerically evaluate the Jacobian at X = (1, 2, 3)
print("numerical Jacobian at X = (1, 2, 3)")
print(jacobian_f_lambdified.evaluate(X_gpu.transpose(), t=1.0))
print(jacobian_direct(t=1.0, x1=1.0, x2=2.0, x3=3.0))

# Compare the performance on cpu and gpu by numerically evaluating the Jacobian
# at n different vectors (x1, x2, x3)
n = 10000000
print(f'evaluating Jacobian at {n} vectors\n')

X_gpu = cn.random.rand(n, 3)
X_cpu = np.array(X_gpu)

# evaluate on gpu
tic = time.time()
# jacobian_f_numeric_gpu = jacobian_f_lambdified.evaluate(X_gpu, t=1.0)
# jacobian_f_numeric_gpu = \
#     (jacobian_f_lambdified
#      .evaluate_with_dictionary(
#         symbolic_to_numeric_parameter_map={x1: X_gpu[:, 0],
#                                            x2: X_gpu[:, 1],
#                                            x3: X_gpu[:, 2]},
#         t=1.0))
jacobian_f_numeric_gpu = \
    (jacobian_f_lambdified
     .evaluate_with_kwargs(x1=X_gpu[:, 0],
                           x2=X_gpu[:, 1],
                           x3=X_gpu[:, 2],
                           t=1.0))
cd.sync()
time_gpu = time.time() - tic
print(f'time on gpu: {time_gpu}')

tic = time.time()
jacobian_f_numeric_gpu_direct = \
    jacobian_direct(t=1.0,
                    x1=X_gpu[:, 0],
                    x2=X_gpu[:, 1],
                    x3=X_gpu[:, 2])
cd.sync()
time_gpu_direct = time.time() - tic
print(f'time for direct computation on gpu: {time_gpu_direct}')

print(f'numerical results from gpu match results from direct computation: '
      f'{np.allclose(jacobian_f_numeric_gpu_direct, jacobian_f_numeric_gpu)}')

# evaluate on cpu
tic = time.time()
# jacobian_f_numeric_cpu = jacobian_f_lambdified.evaluate(X_cpu, t=1.0)
# jacobian_f_numeric_cpu = \
#     (jacobian_f_lambdified
#      .evaluate_with_dictionary(
#         symbolic_to_numeric_parameter_map={x1: X_cpu[:, 0],
#                                            x2: X_cpu[:, 1],
#                                            x3: X_cpu[:, 2]},
#         t=1.0))
jacobian_f_numeric_cpu = \
    (jacobian_f_lambdified
     .evaluate_with_kwargs(x1=X_cpu[:, 0],
                           x2=X_cpu[:, 1],
                           x3=X_cpu[:, 2],
                           t=1.0))
time_cpu = time.time() - tic
print(f'time on cpu: {time_cpu}')

tic = time.time()
jacobian_f_numeric_cpu_direct = \
    jacobian_direct(t=1.0,
                    x1=X_cpu[:, 0],
                    x2=X_cpu[:, 1],
                    x3=X_cpu[:, 2])
time_cpu_direct = time.time() - tic
print(f'time for direct computation on cpu: {time_cpu_direct}')

print(f'numerical results from cpu match results from direct computation: '
      f'{np.allclose(jacobian_f_numeric_cpu_direct, jacobian_f_numeric_cpu)}')

# output performance gain on gpu
print(f'speedup on gpu vs cpu: {time_cpu / time_gpu}\n')

# Verify that the results match
print(f'numerical results from cpu and gpu match: '
      f'{np.allclose(jacobian_f_numeric_gpu, jacobian_f_numeric_cpu)}')


#! /usr/bin/env python
import argparse
from scipy.stats import binom
import matplotlib.pyplot as plt
from scipy.stats import norm
import os
import math
import numpy as np

def testScipy(N, p, outdir):
    fig, ax = plt.subplots(1, 1)
    x = list(range(0,N+1))
    ax.plot(x, binom.pmf(x, N, p), 'bo', ms=8, label='binom pmf')
    ax.plot(x, binom.cdf(x, N, p), 'ro', ms=8, label='binom cdf')
    ax.plot(x, binom.sf(x, N, p), 'go', ms=8, label='binom sf')
    ax.legend(loc='best', frameon=False)
    plt.savefig(outdir + "/distributions.png")

def main(n, p_0, alpha=1/10, outdir='out'):
    testScipy(n, p_0, outdir)
    k_cutoff = binom.ppf(alpha, n, p_0) - 1
    print('k*: {}'.format(k_cutoff))
    print('P(binom < k*): {}'.format(binom.cdf(k_cutoff, n, p_0)))

    fig, ax = plt.subplots(1, 1)
    x = list(range(0,n+1))
    ax.plot(x, binom.cdf(x, n, p_0), 'ro', ms=5)
    ax.plot([0,n], [alpha,alpha], 'g')
    ax.plot([k_cutoff,k_cutoff], [0,1], 'b')
    # TODO alpha and k*
    plt.savefig(outdir + "/{}_{}.png".format(n, p_0))

if __name__ == "__main__":
    main(20, 1/2)
    main(100, 1/7)


import numpy as np                  # NumPy library for arrays
import matplotlib.pyplot as plt     # Matplotlib library for plotting

tmax = 10.0                         # Time to perform integration to
dt = 0.01                           # Timestep
time = np.arange(0.0, tmax, dt)     # Initialise the time array; from t = 0 -> t = tmax, in steps of size dt

# Set the constants and initial conditions in the equation to solve; du/dt = -lambda * (u - sin(t))
lambd = 100.0                       # Set lambda as a constant (= 100)
u = np.zeros(len(time))             # Initialise the array; u = 0 for each timestep
u[0] = 1.0                          # Intial condition, u(0) = 1

for i in range(len(time)-1):       # Loop over i in 0,1,2,..,(total number of timesteps - 1)
    # We solve for u;
    # du/dt = -lambda * (u - sin(t))
    # So,
    # u(i+1) = u(i) + du/dt * dt

    dudt = -lambd * (u[i] - np.sin(time[i]))    # We use the numpy sine function (np.sin)
    u[i+1] = u[i]  + dt * dudt

    plt.cla()                       # Clear the axis to prevent repeatedly plotting on top of old lines
    plt.xlabel('t')                # x-label for the plot
    plt.ylabel('u')                # y-label for the plot
    plt.plot(time,u,label='numerical solution')   # Plot our numerical solution for the current timestep
    plt.plot(time,np.sin(time),ls='dashed',label=r'$\sin t$') # Plot sin(t) for the current timestep as reference
                                                              # with a dashed linestyle (ls='dashed')
    plt.title(f'time={time[i]:.2f}')# Update the title as the current time to two decimal places
    plt.legend()                    # Display the legend, where the labels are set in the two lines above
    plt.show(block = False)         # Tell matplotlib to show the plot (block=False allows the code to continue)
    plt.pause(0.02)                 # Pause for a short time for animatio


import torch
import torch.nn as nn
# import torch.autograd as Variable
import numpy as np

#Pytorch Linear regression
x = [i for i in range(11)]
y = [2*i + 1 for i in x]
x = np.array(x, dtype=np.float32).reshape((-1,1))
y = np.array(y, dtype=np.float32).reshape((-1,1))

#Build the model
class LinearRegressionModel(nn.Module):
    def __init__(self, input_dim, output_dim):
        super(LinearRegressionModel, self).__init__()
        self.linear = nn.Linear(input_dim, output_dim)

    def forward(self, x):
        out = self.linear(x)
        return out

#Model and dmensions
input_dim = 1
output_dim = 1
model = LinearRegressionModel(input_dim, output_dim)
#Loss function
criterion = nn.MSELoss()

learning_rate = 0.001
#The graadient descent function
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
#Inputs and Outputs
I = torch.from_numpy(x).requires_grad_()
Y = torch.from_numpy(y).requires_grad_()
#Training
for i in range(1000):
    optimizer.zero_grad()
    outputs = model(I)
    loss = criterion(outputs, Y)
    loss.backward()
    optimizer.step()

#Prediction
predicted = model(I).data.numpy()
print('prediction:')
print(predicted.reshape((1,-1)))
print('target:')
print(Y.data.numpy().reshape((1,-1)))
#Saving and loading the model
saveModel = False
if saveModel:
    torch.save(model.state_dict(), 'awesome.pkl')

loadModel = False
if loadModel:
    model.load_state_dict(torch.load('awesome.pkl'))


import math
import time

import numpy as np

def calc_pearson(matrix, method='default', zero_diag=True):
    """Calculate the pearson correlation between nodes

    Params:
        matrix: data of shape [N, T], N is node num, T is sample num
        method: method used, default for manually calculation,
            numpy for numpy implementation
        zero_diag:
                if zero the self correlation value (in diagonal position)
    """
    # 一行是一个数据
    if method == 'numpy':
        res = np.corrcoef(np.array(matrix))
        if zero_diag:
            for i in range(res.shape[0]):
                res[i, i] = 0.0
        res = res.tolist()
    else:
        nrows = len(matrix)
        ncols = len(matrix[0])
        n = ncols * 1.0
        res = [[0 for i in range(nrows)] for j in range(nrows)]
        for i in range(nrows):
            idx = i + 1
            for j in range(idx, nrows):
                a = b = c = f = e = 0
                for k in range(0, ncols):
                    a += matrix[i][k] * matrix[j][k]  # sigma xy
                    b += matrix[i][k]  # sigma x
                    c += matrix[j][k]  # sigma y
                    e += matrix[i][k] * matrix[i][k]  # sigma xx
                    f += matrix[j][k] * matrix[j][k]  # sigma yy

                para1 = a
                para2 = b * c / n
                para3 = e
                para4 = b * b / n
                para5 = f
                para6 = c * c / n

                r1 = para1 - para2
                r2 = (para3 - para4) * (para5 - para6)
                r2 = math.sqrt(r2)
                r = 1.0 * r1 / r2
                res[i][j] = res[j][i] = r * 1.00000
        # w = Workbook()
        # # Write to a new Sheet
        # ws = w.create_sheet("relation"+str(ela) + ".xlsx")  #Create table sheet
        # for i in range(nrows):
        #     for j in range(nrows):
        # 	    ws.cell(row = i+1, column = j+1).value = res[i][j]
        if not zero_diag:
            for i in range(nrows):
                for j in range(nrows):
                    res[i][j] = 1.0
    return res

if __name__ == "__main__":
    np.random.seed(42)
    a = np.random.rand(100, 100)
    tic = time.time()
    b_numpy = calc_pearson(a, 'numpy')
    time_numpy = time.time() - tic
    tic = time.time()
    b_default = calc_pearson(a, 'default')
    time_default = time.time() - tic
    print('{:^10}Default time:{}'.format('', time_default))
    print('{:^10}Numpy   time:{}'.format('', time_numpy))
    print('{:^10}Distance    :{}'.format(
        '', np.linalg.norm(np.array(b_numpy)-np.array(b_default))))
    print('Result numpy  :', b_numpy[0][:10])
    print('Result default:', b_default[0][:10])


#setup: import numpy as np ; np.random.seed(0); N = 500000 ; X, Y = np.random.rand(N), np.random.rand(N)
#run: lstsqr(X, Y)
#from: http://nbviewer.ipython.org/github/rasbt/One-Python-benchmark-per-day/blob/master/ipython_nbs/day10_fortran_lstsqr.ipynb

#pythran export lstsqr(float[], float[])
import numpy as np
def lstsqr(x, y):
    """ Computes the least-squares solution to a linear matrix equation. """
    x_avg = np.average(x)
    y_avg = np.average(y)
    dx = x - x_avg
    dy = y - y_avg
    var_x = np.sum(dx**2)
    cov_xy = np.sum(dx * dy)
    slope = cov_xy / var_x
    y_interc = y_avg - slope*x_avg
    return (slope, y_interc)


#runas import numpy as np ; N = 10000 ; a = np.arange(float(N)); b = 0.1; c =1.1; log_likelihood(a, b, c)
#from http://arogozhnikov.github.io/2015/09/08/SpeedBenchmarks.html
import numpy

#pythran export log_likelihood(float64[], float64, float64)
def log_likelihood(data, mean, sigma):
    s = (data - mean) ** 2 / (2 * (sigma ** 2))
    pdfs = numpy.exp(- s)
    pdfs /= numpy.sqrt(2 * numpy.pi) * sigma
    return numpy.log(pdfs).sum()


import numpy as npv
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

def fit_plane_svd(data):
    """
    Fit plane using SVD, ax + by + cz + d = 0
    :param data: 3D points
    :return: normalized direction [a, b, c]
    """
    # if don't remove center, don't changed the value (a,b,c)
    avg = data.mean(axis=0)
    centered_data = data - avg
    cal_data = np.c_[centered_data, np.ones(len(data))]
    u, s, vh = np.linalg.svd(cal_data)

    # params
    abc = vh[-1, :-1]
    abc = abc / np.linalg.norm(abc)
    d = -np.dot(abc, avg)
    return np.hstack((abc, d))

def plane_fitting_example():
    """example for 3D line fitting"""
    print(util.Section('3D Plane Fitting'))

    # generate 3D points data, ax + by + cz + d = 0
    print(util.Section('Generate 3D Points Data'))
    # generate simulated data
    params = np.array([1.0, 2.0, 3.0, 4.0])
    x, y = np.meshgrid(np.arange(-10, 10, 1), np.arange(-10, 10, 1))
    z = -(params[0] * x + params[1] * y + params[3]) / params[2]
    plane_data = np.c_[x.flatten(), y.flatten(), z.flatten()]
    print(f'abcd = {params}')
    print(f'normalized abcd = {params / np.linalg.norm(params)}')

    # plane fitting
    print(util.Section('Generate 3D Points Data'))
    params_svd = fit_plane_svd(plane_data)
    print(f'SVD, abcd = {params_svd}')
    print(f'SVD, normalized abcd = {params_svd / np.linalg.norm(params_svd)}')

    # generate plot data
    x_plot, y_plot = np.meshgrid(np.arange(-10, 10, 0.01), np.arange(-10, 10, 0.01))
    z_plot = -(params_svd[0] * x_plot + params_svd[1] * y_plot + params_svd[3]) / params_svd[2]
    # plot
    fig = plt.figure('3D Plane Fitting')
    ax = fig.add_subplot(111, projection='3d')
    ax.plot(x.flatten(), y.flatten(), z.flatten(), 'k.', label='Measurement')
    ax.plot_surface(x_plot, y_plot, z_plot, alpha=0.2, color='r', label='SVD Fitting')
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
    ax.set_title('3D Plane Fitting')
    plt.show(block=True)

if __name__ == '__main__':
    plane_fitting_example()


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

D=list(range(1,9))          #list with the dimesions of the integral

#function to be integrated
def g(x):
    g=np.e**(-x)
    return g

#analytic result of the integral as a function of dimensionality
def I_analytic(D):
    I= (1- (1/np.e))**D
    return I

N=[65536, 256**2, 40**3, 16**4, 9**5, 6**6, 5**7, 4**8]   #number of extractions = number of cells

#Compute the integral with Monte Carlo integration (hit or miss)
I_mc=[]
for d in range(0, len(D)):
    s=1
    for j in range(0,D[d]):
        I=0
        for i in range(0,N[d]):
            x=random.random()
            h=g(x)
            I+=h
        s=s*I/N[d]
    I_mc.append(s)
I_mc=np.array(I_mc)

#number of counts in mid-point summation per each dimensionality
def k(d):
    k=round((N[d])**(1./D[d]))
    return k

#Compute the integral with mid-point summation:
I_mid=[]
for d in range(0, len(D)):
    n = k(d)
    h = 1/(k(d)-1)
    x = np.linspace(0., 1., n)
    I = h * sum(g((x[:n-1] + x[1:])/2))
    I_mid.append(I**D[d])

#plot of the result for Monte Carlo vs. mid-point integration
D=np.array(D)
plt.figure()
plt.plot(D, abs(I_analytic(D)-I_mc), 'ro', label='$Monte\ Carlo$')
plt.plot(D, abs(I_analytic(D)-I_mid), 'b*', label='$Mid-point$')
plt.ylabel('$|I_{analytic}-I_{numerical}|$', fontsize=14)
plt.xlabel('$Dimensionality$', fontsize=14)
plt.xticks(fontsize=10)
plt.yticks(fontsize=10)
plt.yscale('log')
plt.legend(loc='lower right')
plt.ylim(10**(-12),10**(-2) )