import json

import numpy as np
import plotly
import plotly.graph_objects as go
import scipy.misc as sc
import sympy as sp
from sympy.parsing.sympy_parser import parse_expr

def result(func):
    def wrapper(params):
        f_str, var_str = params["function"].split(",")
        var = sp.symbols(var_str)

        f_parse = parse_expr(f_str)
        f = sp.lambdify(var, f_parse, "numpy")

        fig, result = func(f, var, f_parse, params)
        fig.update_layout(width=1000, height=1000)
        graphJSON = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)
        return graphJSON, result

    return wrapper

def f_(f, x):
    return sc.derivative(f, x, dx=1e-8)

def f_k(f, x0, x):
    k = sc.derivative(f, x0, dx=1e-8)
    text = sp.latex(parse_expr(f"{round(k, 2)}*(x - {x0}) + {round(f(x0), 2)}"))
    return k * (x - x0) + f(x0), text

def f2_k(f, x0, y0, x, y):
    k_x = sc.derivative(lambda xn: f(xn, y0), x0, dx=1e-8)
    k_y = sc.derivative(lambda yn: f(x0, yn), y0, dx=1e-8)
    text = sp.latex(
        parse_expr(
            f"{round(k_x, 3)}*(x - {x0}) + {round(k_y, 3)}*(y - {y0}) + {round(f(x0, y0), 3)}"
        )
    )
    return k_x * (x - x0) + k_y * (y - y0) + f(x0, y0), text

@result
def derivative(f, var, f_parse, params):
    ranges = [[float(d) for d in r.split()] for r in params["ranges"].split(",")]
    n = int(params["n"])
    d0 = None
    if params["d0"] and params["d0"] != "":
        d0 = [float(x) for x in params["d0"].split()]

    fig = go.Figure()
    res = str()

    x = np.linspace(ranges[0][0], ranges[0][1], n)
    if isinstance(var, tuple):
        y = np.linspace(ranges[1][0], ranges[1][1], n)
        X, Y = np.meshgrid(x, y)
        fig.add_trace(
            go.Surface(x=X, y=Y, z=f(X, Y), colorscale="Viridis", name=f"f({var})")
        )
        if d0:
            f2k, text = f2_k(f, d0[0], d0[1], X, Y)
            fig.add_trace(go.Surface(x=x, y=y, z=f2k, colorscale="Viridis", name=text))
            res += "Уравнение касательной плоскости: $$z = " + text + "$$"
    else:
        fig.add_trace(go.Scatter(x=x, y=f(x), name=f"f({var})"))
        fig.add_trace(go.Scatter(x=x, y=f_(f, x), name=f"f'({var})"))
        res = f"$$ f'({var}) = " + sp.latex(sp.diff(f_parse, var))
        if d0:
            fk, text = f_k(f, d0[0], x)
            fig.add_trace(go.Scatter(x=x, y=fk, name=text))
            res += (
                f", f'({d0[0]}) = {round(f_(f, d0[0]), 3)}, $$Уравнение касательной: $$y = "
                + text
            )
        res += "$$"
    return fig, res + "График:"

import numpy,import scipy,import sympy,from sympy


# calculate the curverture
import numpy as np
import matplotlib.pyplot as plt

from predusion.tools import curvature

radius = 2
n_point = 10

circle_curve = [[radius * np.sin(t), radius * np.cos(t)] for t in np.linspace(0, 2 * np.pi, n_point, endpoint=False)]

circle_curve = np.array(circle_curve)

#plt.figure()
#plt.scatter(circle_curve[:, 0], circle_curve[:, 1])
#plt.show()

ct, ct_mean = curvature(circle_curve)
print(ct, ct_mean)


import numpy as np
import itertools

# import problem
problem = np.loadtxt("problem.txt", dtype=int)
print("problem to solve: \n",  problem)

# find empty slots to fill in the numbers

# backtrack functions
def check_safe(problem, i, j, num):
    # index for the sqaure
    square_i = i // 3 * 3
    square_j = j // 3 * 3

    # check if row is okay
    if any(problem[i,:] == num):
        return False

    # check if column is okay
    elif any(problem[:,j] == num):
        return False

    # check if square is okay
    elif (problem[square_i:square_i+3, square_j:square_j+3] == num).any():
        return False

    # return true if passing all checks
    else:
        return True

def solve(problem, blanks, location):
    # problem is the numpy 2D array holding the sudoku to solve
    # blanks is a list of (row, column) tuple with blank cells to fill
    # location is the current starting point to solve the problem. The starting location should be 0
    p = problem.copy()

    # try each of the 9 numbers
    for num in range(1,10):

        # if the number doesn't work, either try the next one or dead end the branch
        if check_safe(p, blanks[location][0], blanks[location][1], num) == False:
            if num == 9:
                return "dead end", p
            else:
                continue

        # if the number works, go to the next slot to evaluate
        else:
            # fill in the number if it works
            pp = p.copy()
            pp[blanks[location]] = num

            # if the number works and we are at the end, we have solved it!
            if location == len(blanks)-1:
                return "solved", pp
                break
            # if the number works and we are not at the end, recursively work one level deeper
            else:
                status, solution = solve(pp, blanks, location+1)
                # if the level below solved it, pass the results back
                if status == "solved":
                    return "solved", solution
                    break
                # if the level below is an dead end, skip to the next number
                elif status == "dead end":
                    if num == 9:
                        # if everything failed, return not solvable
                        if location == 0:
                            return "not solvable", p
                        # if this level failed, send dead end on the level up
                        else:
                            return "dead end", p
                    else:
                        # move onto the next number if the current number leads to failure
                        continue

def solve_sudoku(problem):
    # create a list of slots to fill in numbers
    blanks = list()
    for i, j in itertools.product(range(9), range(9)):
        if problem[i,j] == 0:
            blanks.append((i, j))

    # run solver
    status, solution = solve(problem, blanks, 0)

    # print answer
    print(status)
    if status == "solved":
        print(solution)

# solution
solve_sudoku(problem)


import numpy as np
import pandas as pd
from scipy.stats import rankdata
import matplotlib.pyplot as plt

def logloss(prediction, label):
    prediction = np.nan_to_num(prediction, copy=False)
    prediction = prediction.astype('float64', copy=False)
    eps = 1e-15
    prediction = np.fmax(np.fmin(prediction, 1.0 - eps), eps)
    logloss = -np.mean(
        label * np.log(prediction) + (1.0 - label) * np.log(1.0 - prediction)
    )
    return logloss

def normalized_cross_entropy(prediction, label):
    nce = logloss(prediction, label) / logloss(label.mean(), label)
    return nce

def auc(prediction, label):
    prediction_rank = rankdata(prediction, method='average')
    n_pos = np.sum(label == 1.0)
    n_neg = np.sum(label == 0.0)
    auc = (
        np.sum(prediction_rank[label == 1.0]) - n_pos * (n_pos + 1) / 2
    ) / (n_pos * n_neg)
    return auc

def copc_plot(prediction, label, num_bins, title='Click on Predicted Click'):
    # Compute
    df_bin = (pd.DataFrame({'prediction': prediction, 'label': label})
                .assign(bin=lambda df: pd.qcut(
                    df['prediction'], q=num_bins, duplicates='drop'))
                .groupby(by='bin')
                .mean())
    # Scatter Plot
    plt.scatter(x='prediction', y='label', data=df_bin)
    # Diagonal Line
    plt.plot([0, 1], [0, 1], '-')
    # Limits
    value_max = df_bin.values.max()
    plt.xlim(0, value_max*1.07)
    plt.ylim(0, value_max*1.07)
    # Label
    plt.title(title)
    plt.xlabel('prediction')
    plt.ylabel('label')
    # Show
    plt.show()


import dolfin as df
import numpy as np
import matplotlib.pyplot as plt

import pySDC.helpers.plot_helper as plt_helper

import pylustrator
# pylustrator.start()

N = 128  # Number of elements
k = 7  # Wave frequency
d = 4  # FE order

# Get mesh and function space (CG or DG)
mesh = df.UnitIntervalMesh(N)
V = df.FunctionSpace(mesh, "CG", d)
# V = df.FunctionSpace(mesh, "DG", d)

# Build mass matrix
u = df.TrialFunction(V)
v = df.TestFunction(V)
a_M = u * v * df.dx
M = df.assemble(a_M)

# Create vector with sine function
u0 = df.Expression('sin(k*pi*x[0])', pi=np.pi, k=k, degree=d)
w = df.interpolate(u0, V)

# Apply mass matrix to this vector
Mw = df.Function(V)
M.mult(w.vector(), Mw.vector())

# Do FFT to get the frequencies
fw = np.fft.fft(w.vector()[:])
fMw = np.fft.fft(Mw.vector()[:])
# Shift to have zero frequency in the middle of the plot
fw2 = np.fft.fftshift(fw)
fMw2 = np.fft.fftshift(fMw)

fw2 /= np.amax(abs(fw2))
fMw2 /= np.amax(abs(fMw2))

ndofs = fw.shape[0]

# Plot
plt_helper.setup_mpl()

plt_helper.newfig(240, 1, ratio=0.8)
plt_helper.plt.plot(abs(fw2), lw=2, label=f'N = {N} \n degree = {d} \n wave number = {k}')
plt_helper.plt.xticks([0, ndofs / 4 - 1, ndofs / 2 - 1, 3 * ndofs / 4 - 1, ndofs - 1],
                      (r'-$\pi$', r'-$\pi/2$', r'$0$', r'+$\pi$/2', r'+$\pi$'))
plt_helper.plt.xlabel('spectrum')
plt_helper.plt.ylabel('normed amplitude')
# plt_helper.plt.legend()
plt_helper.plt.grid()
plt_helper.savefig('spectrum_noM_CG')
# plt_helper.savefig('spectrum_noM_DG')
# plt_helper.savefig('spectrum_noM_DG_8')

plt_helper.newfig(240, 1, ratio=0.8)
plt_helper.plt.plot(abs(fMw2), lw=2, label=f'N = {N} \n degree = {d} \n wave number = {k}')
plt_helper.plt.xticks([0, ndofs / 4 - 1, ndofs / 2 - 1, 3 * ndofs / 4 - 1, ndofs - 1],
                      (r'-$\pi$', r'-$\pi/2$', r'$0$', r'+$\pi$/2', r'+$\pi$'))
plt_helper.plt.xlabel('spectrum')
plt_helper.plt.ylabel('normed amplitude')
# plt_helper.plt.legend()
plt_helper.plt.grid()
plt_helper.savefig('spectrum_M_CG')
# plt_helper.savefig('spectrum_M_DG')
# plt_helper.savefig('spectrum_M_DG_8')

# plt.show()


import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages

def gradientDescentEveryStep(derivative, startPoint, stepLength):
    return startPoint - stepLength * derivative(startPoint)

if  __name__  ==  "__main__":
    # g(w) = |x|
    with PdfPages('Chapter3Practice6.pdf') as pdf:
        costFunc = lambda x : abs(x)
        derivative = lambda x: 1 if (x >= 0) else -1

        # fixed steplength
        startPoint = 1.75
        fig = plt.figure()
        plt.title("Exercise 3.6: fixed steplength is 0.5")
        xList = [0]
        yList = [costFunc(startPoint)]
        for i in range(20):
            startPoint = gradientDescentEveryStep(derivative, startPoint, 0.5)
            xList.append(i+1)
            yList.append(costFunc(startPoint))
        plt.plot(xList, yList)
        plt.show()
        pdf.savefig(fig)
        plt.close()

        # diminishing step length
        startPoint = 1.75
        fig = plt.figure()
        plt.title("Exercise 3.6: diminishing steplength")
        xList = [0]
        yList = [costFunc(startPoint)]
        for i in range(20):
            startPoint = gradientDescentEveryStep(derivative, startPoint, 1/(i+1))
            xList.append(i + 1)
            yList.append(costFunc(startPoint))
        plt.plot(xList, yList)
        plt.show()
        pdf.savefig(fig)
        plt.close()


import numpy as np

def add_m(m1, m2):
    print("The addition of two matrix is: ")
    print(np.add(m1, m2))

def sub_m(m1, m2):
    print("The subtraction of two matrix is: ")
    print(np.subtract(m1, m2))

def multi_m(m1, m2):
    print("The multiplication of two matrix is: ")
    print(np.dot(m1, m2))

def transpose(m1, m2):
    print("The transpose of a matrix1 is: ")
    print(m1.T)
    print("The transpose of a matrix2 is: ")
    print(m2.T)

ch = "y"
while (ch == "y"):
    print("*******MENU*******")
    print("1.Addition of a matrix")
    print("2.Subtraction of a matrix")
    print("3.Multiplication of a matrix")
    print("4.Transpose of a matrix")
    choice = int(input("Enter the choice number you want to perform: "))
    r1 = int(input("Enter the number of rows of first matrix: "))
    c1 = int(input("Enter the number of columns of first matrix: "))

    print("Enter the number in a single line seperated by space: ")

    enteries = list(map(int, input().split()))
    matrix1 = np.array(enteries).reshape(r1, c1)
    print(matrix1)

    r2 = int(input("Enter the number of rows of second matrix: "))
    c2 = int(input("Enter the number of columns of second matrix: "))
    print("Enter the number in a single line seperated by space: ")
    enteries = list(map(int, input().split()))
    matrix2 = np.array(enteries).reshape(r2, c2)
    print(matrix2)

    if (choice == 1):
        add_m(matrix1, matrix2)
    elif (choice == 2):
        sub_m(matrix1, matrix2)
    elif (choice == 3):
        multi_m(matrix1, matrix2)
    elif (choice == 4):
        transpose(matrix1, matrix2)

    ch = input("Want to continue (y/n)?: ")


import numpy as np
import pandas as pd
import plotly.graph_objects as go
import scipy.stats as st

def build_confidence_interval_traces(
        data, x_column, y_column, ci=0.95, **kwargs):
    """ Build confidence interval area traces.

    Confidence interval is calculated among same timestep but different
    categories.

    References:
    https://stackoverflow.com/questions/15033511/compute-a-confidence-interval-from-sample-data
    https://kite.com/python/examples/702/scipy-compute-a-confidence-interval-from-a-dataset

    Arguments:
        data (pandas.DataFrame) Data.
        x_column (str): X series column.
        y_column (str): Y series column.
        ci (float): Confidence interval.
        kwargs: Arguments passed to "fig.add_trace" function.

    Returns:
        [trace_lo, trace_hi, trace_mean]:
            trace_lo: Trace of lower bounds.
            trace_hi: Trace of higher bounds.
            trace_mean: Trace of mean values.
    """
    # Check the type of data
    if not isinstance(data, pd.DataFrame):
        raise ValueError('"data" must be a pandas.DataFrame')

    # Group the data by X column
    grouped_by_x = data.groupby(x_column)

    # Get the number of groups
    num_groups = len(grouped_by_x)

    # Initialize the X series
    xs = np.zeros(num_groups)

    # Initialize the Y series of lower bounds, upper bounds and mean values
    y_lo, y_hi, y_mean = np.zeros(num_groups), np.zeros(
        num_groups), np.zeros(num_groups)

    # Add confidence interval at each X
    for idx, (x, group) in enumerate(grouped_by_x):
        # Get the Y series
        y = group[y_column]

        # Get number of Y values
        num = len(y)

        # Calculate mean Y value
        mean_s = np.mean(y)

        # Only calculate bounds of confidence interval when the number of Ys
        # are more than 1
        if num > 1:
            std_err = st.sem(y)
            h = std_err * st.t.ppf((1 + ci) / 2, num - 1)
            lo, hi = mean_s - h, mean_s + h
        else:
            lo, hi = mean_s, mean_s

        # Add X to the list
        xs[idx] = x

        # Add bounds to the lists
        y_lo[idx] = lo
        y_hi[idx] = hi

        # Add mean values to the list
        y_mean[idx] = mean_s

    # Set common attributes for building traces for confidence interval
    ci_attrs = dict(hoverinfo='skip', line_width=0,
                    mode='lines', showlegend=False)

    # Build the lower bounds line
    trace_lo = go.Scatter(x=xs, y=y_lo, fill=None, **ci_attrs, **kwargs)

    # Build the upper bounds line which fills the area between this one and
    # lower bounds line
    trace_hi = go.Scatter(x=xs, y=y_hi, fill='tonexty', **ci_attrs, **kwargs)

    # Build the mean values line
    trace_mean = go.Scatter(x=xs, y=y_mean, mode='lines', **kwargs)

    # Return the lower bound, upper bounds and mean values traces
    return [trace_lo, trace_hi, trace_mean]


import numpy as np
import matplotlib.pyplot as plt

x_data = np.array([35., 38., 31., 20., 22., 25., 17., 60., 8., 60.])
y_data = 2 * x_data + 50 + 5 * np.random.random(10)

bb = np.arange(0, 100, 1)
ww = np.arange(-5, 5, 0.1)
Z = np.zeros((len(bb), len(ww)))

# Create landscape
for i in range(len(bb)):
  for j in range(len(ww)):
    b = bb[i]
    w = ww[j]
    Z[j][i] = 0
    for n in range(len(x_data)):
      Z[j][i] += (1/2) * (w * x_data[n] + b - y_data[n]) ** 2

# Initial values for Gradient Descent
b = 0
w = 0
lr = 0.00015 # 0.00015741
iterations = 15000 # 8500
b_history = [b]
w_history = [w]

# Run Gradient Descent process
for i in range(iterations):
  b_grad = 0.0
  w_grad = 0.0
  for n in range(len(x_data)):
    loss = w * x_data[n] + b - y_data[n]
    b_grad += loss
    w_grad += loss * x_data[n]
  b -= lr * b_grad
  w -= lr * w_grad
  b_history.append(b)
  w_history.append(w)

# Get final values used for testing
b_final = b_history[len(b_history) - 1]
w_final = w_history[len(w_history) - 1]

# Plot figure
plt.figure(figsize = (8, 7))

# Gradient Descent process
plt.subplot(211)
plt.title('Gradient Descent', fontweight = 'bold')
plt.xlim(0, 99)
plt.xlabel('b', fontstyle = 'italic')
plt.ylim(-5, 4.9)
plt.ylabel('w', fontstyle = 'italic', rotation = 'horizontal')
plt.contourf(bb, ww, Z, 50, alpha = 0.5, cmap = plt.get_cmap('jet'))
plt.plot(b_history, w_history, 'o-', ms = 3, lw = 1.5, color = 'black')
plt.plot([b_final], [w_final], 'o-', ms=3, color='orange')
plt.annotate("b = " + str(round(b_final, 2)) + ", w = " + str(round(w_final, 2)), xy = (b_final, w_final), xytext = (b_final + 1, w_final + 0.2))

# Prediction testing
plt.subplot(212)
plt.title('Prediction vs Actual', fontweight = 'bold')
plt.xlim(0, 80)
plt.xlabel('x', fontstyle = 'italic')
plt.ylim(0, 250)
plt.ylabel('y', fontstyle = 'italic', rotation = 'horizontal')
plt.plot(x_data, y_data, 'o', ms = 3, color = 'black', label = 'Actual')
plt.plot(x_data, w * x_data + b, '+', lw = 0.5, ms = 3, color = 'red', label = 'Prediction')
plt.legend()

# Fit data to figure and display
plt.tight_layout()
plt.show()


from abc import ABCMeta, abstractmethod
from random import random

from scipy import integrate

from config import Config
from math_utils import generate_random_variables, get_function_max

class AbstractIntegration(metaclass=ABCMeta):

    @staticmethod
    @abstractmethod
    def count(N):
        pass

class Analytical(AbstractIntegration):

    @staticmethod
    def count(N: int = 100):
        return integrate.quad(Config.our_function, Config.MIN, Config.MAX)[0]

class Trapezium(AbstractIntegration):

    @staticmethod
    def count(N: int = 100):
        a, b, func = Config.MIN, Config.MAX, Config.our_function
        h = (b - a) / N
        s = 0
        while round(a, 8) < b:
            s += 0.5 * h * (func(a) + func(a + h))
            a += h
        return s

    def __str__(self):
        return 'Trapezium method'

class MonteCarloFirst(AbstractIntegration):

    @staticmethod
    def count(N: int = 100):
        a, b, func = Config.MIN, Config.MAX, Config.our_function
        SUM = 0
        random_values = generate_random_variables(N)
        for i in range(N):
            U = random_values[i] * (b - a) + a
            SUM += func(U)

        return (b - a) / N * SUM

    def __str__(self):
        return 'Monte-Carlo 1st method'

class MonteCarloSecond(AbstractIntegration):

    @staticmethod
    def count(N: int = 128):
        a, b, func = Config.MIN, Config.MAX, Config.our_function
        k = 0
        difference, min_value = get_function_max(N)
        for i in range(N):
            X = a + (b - a) * random()
            Y = min_value + difference * random()
            if 0 < Y < func(X):
                k += 1

        return difference * (b - a) * k / N

    def __str__(self):
        return 'Monte-Carlo 2nd method'


import matplotlib.pyplot as plt
import numpy as np
# import pandas as pd
from mpl_toolkits.mplot3d import Axes3D

# 创建一个Axes3d对象
fig = plt.figure()
ax = Axes3D(fig)

# x，y的取值返回是从-5到+5，每隔0.25取一个点
x = np.arange(-5, 5, 0.25)
y = np.arange(-5, 5, 0.25)

# [X,Y] = meshgrid(x,y) 将向量x和y定义的区域转换成矩阵X和Y，
# 这两个矩阵可以用来表示mesh和surf的三维空间点以及两个变量的赋值。
# 其中矩阵X的行向量是向量x的简单复制，而矩阵Y的列向量是向量y的简单复制。
x, y = np.meshgrid(x, y)
print(x)
# r=np.sqrt(x**2+y**2)
# z=np.sin(r)
z = x ** 2 + y ** 2

# plot_surface 是绘制一个平面 ax.scatter 是绘制点
surf = ax.plot_surface(x, y, z)

plt.show()


import numpy as np
from scipy.spatial import distance
import os, sys
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))
from part_1.k_means import KMeans

class DaviesBouldinIndex:
    '''
        Use KMeans to cluster unknown data
    '''

    def __init__(self, data, max_iterations=10):
        '''
            Inputs:
            - data: the data we want to find clusters for
            - max_iterations: the maximum amount of clusters we want to test k=[2, max_iterations+2)
        '''
        self.data = data
        self.max_iterations = max_iterations
        self.n_clusters = None
        self.db_index = None
        self.labels = None
        self.indices = []

    def compute_DB_index(self, labels, centroids, n_cluster):
        '''
            Compute the db index of a given partition
            Inputs:
            - labels: the current label assignments
            - centroids: the current centroids
            - n_clusters: the number of clusters we ran k-means for
        '''
        clusters = [self.data[labels == k] for k in range(n_cluster)]

        # calculate within cluster distance
        D = [np.mean([distance.euclidean(p, centroids[i]) for p in k]) for i, k in enumerate(clusters)]

        # within-to-between cluster ratios
        ratios = []

        for i in range(n_cluster):
            D_ij_list = []

            # between cluster distances
            for j in range(n_cluster):
                # don't calculate between a cluster and itself
                if i != j:
                    D_ij = (D[i] + D[j]) / distance.euclidean(centroids[i], centroids[j])
                    D_ij_list.append(D_ij)

            # keep track of the worst case within-to-between cluster ratio for cluster i
            ratios.append(max(D_ij_list))

        # get mean of all ratio values
        return np.mean(ratios)

    def model_selection(self):
        '''
            Run k_means using a variety of cluster numbers and choose the one with the lowest db_index
        '''
        for i in range(2, self.max_iterations+2):
            # run k-means for i clusters
            kmeans_euclidean = KMeans(n_clusters=i, distance="euclidean")
            kmeans_euclidean.fit(self.data)

            # calcualte the db index
            index = self.compute_DB_index(kmeans_euclidean.labels,  kmeans_euclidean.centroids, i)
            self.indices.append(index)

            # if the index is lower, replace our current index, number of clusters, and labels
            if self.db_index is None or index < self.db_index:
                self.db_index = index
                self.n_clusters = i
                self.labels = kmeans_euclidean.labels


#%% [markdown]
# # Scattered data interpolation.
# http://shihchinw.github.io/2018/10/data-interpolation-with-radial-basis-functions-rbfs.html
#%%
import numpy as np
import matplotlib.pyplot as plt
from scipy import linalg

# plt.rcParams['axes.prop_cycle']
num_samples = 5
fig_save_options = {'bbox_inches': 'tight', 'pad_inches': 0.1}

def generate_samples(sample_count, func, seed=None):
    np.random.seed(seed)
    xdata = np.random.random(sample_count)
    ydata = np.array([func(x) for x in xdata])
    return xdata, ydata

poly_funcs = [lambda x: 0.6, lambda x: 0.7 - 0.6 * x, lambda x: (x - 0.5) ** 2 + 0.5]
xdata, ydata = generate_samples(num_samples, poly_funcs[2], seed=7)
plt.ylim(0.0, 1.0)
plt.plot(xdata, ydata, 'o')
plt.show()

#%%
# Shepard's method
xsamples = np.linspace(0.0, 1.0, 256, endpoint=True)
xdiff = np.abs(xdata - xsamples[:, np.newaxis])  # Broadcast

plt.figure(figsize=(12, 3), dpi=70)
for i, p in enumerate([1, 2, 4]):
    weights = 1 / np.power(xdiff, p)
    sum_weights = np.sum(weights, axis=1, keepdims=True)
    weights /= sum_weights
    ysamples = weights.dot(ydata)

    plt.subplot(1, 3, i + 1)
    plt.title('p={}'.format(p))
    plt.plot(xsamples, ysamples, color='#9ac1bc')
    plt.plot(xdata, ydata, 'o', color='#539798')

# plt.savefig('images/shepard_interpolation.png', **fig_save_options)
plt.show()

#%%
class RBF(object):
    """1D RBF interpolant.
    """

    def __init__(self, centers, values, kernel, poly_deg=None, reg=0.0):
        """
        Args:
            centers: The spatial coordinates of data points.
            values: The values of data points.
            kernel: The radial basis function F: R -> R
            poly_deg: Max degrees of polynomial terms. 'None' means no polynomial terms.
            reg: The weight of regularizer.
        """

        sample_count = len(centers)
        Phi = np.empty((sample_count, sample_count))
        for i in range(sample_count):
            for j in range(i, sample_count):
                dist = linalg.norm(centers[i] - centers[j])
                Phi[i, j] = Phi[j, i] = kernel(dist)

        if poly_deg is None:
            if reg > 0.0:
                A = Phi.T.dot(Phi) + np.eye(sample_count) * reg
                b = Phi.T.dot(values)
            else:
                A = Phi
                b = values
        else:
            num_poly_terms = poly_deg + 1
            P = np.ones((sample_count, num_poly_terms))
            for d in range(1, poly_deg + 1):
                P[:, d] = np.power(centers, d)

            A = np.block([[Phi, P], [P.T, np.zeros((num_poly_terms, num_poly_terms))]])
            b = np.append(values, np.zeros(num_poly_terms))

            if reg > 0.0:
                b = A.T.dot(b)
                A = A.T.dot(A) + np.eye(sample_count + num_poly_terms) * reg

        self.centers = centers
        self.values = values
        self.kernel = kernel
        self.poly_deg = poly_deg
        self.coeffs = linalg.solve(A, b)

    def evaluate(self, centers, basis_idx=None):
        """Evaluate interpolated values of given sample centers.

        Args:
            centers: Array of sample locations in shape (N, 1).
            basis_idx: The index for specific basis function. Set 'None' to evaluate all basis functions.

        Results:
            An array in (N, 1) whose element is the evaluated value at the location.
        """
        dists = np.abs(centers[:, np.newaxis] - self.centers)
        Phi = self.kernel(dists)

        if basis_idx is None:
            coeffs = self.coeffs
        else:
            Phi = Phi[:, basis_idx]
            coeffs = self.coeffs[basis_idx]

        if self.poly_deg is None:
            return Phi.dot(coeffs)

        P = np.ones((len(centers), self.poly_deg + 1))
        for i in range(self.poly_deg):
            P[:, i + 1] = np.power(centers, i + 1)
        M = np.block([Phi, P])

        return M.dot(coeffs)

    def plot(self, segment_num=50, hide_ticks=False):
        """Plot interpolation result as 1D curve.
        """
        xdata = np.linspace(0.0, 1.0, segment_num, endpoint=True)
        ydata = self.evaluate(xdata)
        plt.ylim(0.0, 1.0)
        if hide_ticks:
            plt.xticks([])
            plt.yticks([])
        plt.plot(xdata, ydata, color='#9ac1bc')
        plt.plot(self.centers, self.values, 'o', color='#539798')

    def plot_basis(self, segment_num=50):
        """Plot all basis functions and the composed result.
        """
        # prop_cycle = plt.rcParams['axes.prop_cycle']
        # colors = prop_cycle.by_key()['color']
        colors = plt.cm.Paired(np.arange(len(self.centers) + 1))

        xdata = np.linspace(0.0, 1.0, segment_num, endpoint=True)
        for i, x in enumerate(self.centers):
            ydata = self.evaluate(xdata, i)
            plt.plot(xdata, ydata, color=colors[i])

            # Draw projection line to show the corresponding
            y = self.kernel(0.0) * self.coeffs[i]
            plt.plot([x, x], [y, self.values[i]], color='#CCCCCC', linestyle='--')
            plt.plot([x], [y], 'o', color=colors[i])

        # Draw composed curve
        ydata = self.evaluate(xdata)
        plt.plot(xdata, ydata, color=colors[-1])
        plt.plot(self.centers, self.values, 'o', color=colors[-1])  # Draw the data points of each center

#%%
# # Plot basis sumation with Gaussian basis
def gaussian(x, sigma=0.1):
    return np.exp(-x * x / np.power(sigma, 2.0))

np.random.seed(3)
x_data = np.linspace(0.2, 0.8, num_samples)
y_data = 10 ** np.random.random(num_samples)

plt.figure(figsize=(12, 3), dpi=70)
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')

colors = plt.cm.Paired(np.arange(num_samples + 1))
xdiff = np.abs(xsamples - x_data[:, np.newaxis])
values = gaussian(xdiff, 0.09)
for i in range(num_samples):
    x = x_data[i]
    y = y_data[i]
    plt.plot(x, y, 'o', color=colors[i])
    plt.plot(xsamples, values[i] * y, color=colors[i])

values_sum = np.sum(values * y_data[:, np.newaxis], axis=0)
plt.plot(xsamples, values_sum, color=colors[-1])
# plt.savefig('images/sum_of_gaussian_basis.png', **fig_save_options)

#%%
# Interpolate with various kernel functions.
def thinplate(r):
    return r * r * np.log(np.maximum(1e-8, r))

def triharmonic(r):
    return r * r * r

def filmc_curve(x):
    """The fitted ACES tone mapping curve by Krzysztof Narkowicz.
    https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
    """
    return (x * (2.51 * x + 0.03)) / (x * (2.43 * x + 0.59) + 0.14)

plt.figure(figsize=(12, 6), dpi=70)
kernels = [lambda x: gaussian(x, 1.0), thinplate, triharmonic]
kernel_names = [r'Gaussian: $e^{-r^2/2c^2}$', 'thin-plate: $r^2 ln(r)$', 'tri-harmonic: $r^3$']

x_data, y_data = generate_samples(5, filmc_curve, seed=7)
xsamples = np.linspace(-2.0, 2.0, 256, endpoint=True)
for i, kernel in enumerate(kernels):
    ax = plt.subplot(2, 3, i + 1)
    ax.spines['right'].set_color('none')
    ax.spines['top'].set_color('none')
    ax.spines['bottom'].set_position((('data', 0)))
    ax.spines['left'].set_position((('data', 0)))
    plt.ylim(-0.2, 2.5)

    y_values = kernels[i](np.abs(xsamples))
    plt.plot(xsamples, y_values, color='#539798')

    plt.subplot(2, 3, i + 4)
    plt.title(kernel_names[i])
    rbf = RBF(x_data, y_data, kernel, poly_deg=None)
    rbf.plot(256)

# plt.savefig('images/rbf_with_various_kernels.png', **fig_save_options)

#%%
# Basis summation
plt.figure(figsize=(12, 3), dpi=70)
np.random.seed(11)
x_data = np.linspace(0.2, 0.8, num_samples)
y_data = np.random.random(num_samples)
kernels = [lambda x: gaussian(x, 0.2), thinplate, triharmonic]

for i, kernel in enumerate(kernels):
    ax = plt.subplot(1, 3, i + 1)
    ax.spines['right'].set_color('none')
    ax.spines['top'].set_color('none')
    ax.spines['bottom'].set_position((('data', 0)))
    ax.spines['left'].set_position((('data', 0)))
    ax.set_ylim(-0.7, 1.3)
    plt.title(kernel_names[i])
    rbf = RBF(x_data, y_data, kernel)
    rbf.plot_basis(512)

# plt.savefig('images/rbf_composition_with_various_kernels.png', **fig_save_options)

#%%
# Thin-plate interpolation with regularization.
plt.figure(figsize=(12, 3), dpi=70)
for i in range(3):
    plt.subplot(1, 3, i + 1)
    reg = pow(10.0, -6 + i * 2)
    plt.title(r'$\lambda$={}'.format(reg))
    rbf = RBF(x_data, y_data, thinplate, poly_deg=None, reg=reg)
    rbf.plot(256)

#plt.savefig('images/rbf_thinplate_and_regularization.png', **fig_save_options)

#%%
# Generate samples from constant, linear and quadratic functions.
sample_values = []
for f in poly_funcs:
    sample_values.append(generate_samples(num_samples, f, 12))

# Thin-plate interpoolation without polynomial terms.
plt.figure(figsize=(12, 3), dpi=70)
for i, (xs, ys) in enumerate(sample_values):
    plt.subplot(1, 3, i + 1)
    rbf = RBF(xs, ys, thinplate)
    rbf.plot()

# plt.savefig('images/thinplate_rbf.png', **fig_save_options)

#%%
# RBF with constant polynomial
plt.figure(figsize=(12, 15), dpi=70)
text_arrays = [r'$g(x)=a_0$', r'$g(x)=a_0+a_1 x$', r'$g(x)=a_0+a_1 x+a_2 x^2$']

for i, (xs, ys) in enumerate(sample_values):
    plt.subplot(5, 3, i + 1)
    plt.ylim(0.0, 1.0)
    # plt.xticks([])
    # plt.yticks([])
    xc = np.linspace(0.0, 1.0, 64, endpoint=True)
    yc = [poly_funcs[i](x) for x in xc]
    plt.plot(xc, yc, '--', color='#9ac1bc')
    plt.plot(xs, ys, 'o', color='#539798')

    plt.subplot(5, 3, i + 4)
    rbf = RBF(xs, ys, thinplate)
    if i == 0:
        plt.text(0, 0.07, r'$g(x)=0$')
    rbf.plot(256)

    for d in range(3):
        plt.subplot(5, 3, i + 7 + d * 3)
        if i == 0:
            plt.text(0, 0.07, text_arrays[d])
        rbf = RBF(xs, ys, thinplate, poly_deg=d)
        rbf.plot(256)

# plt.savefig('images/rbf_polynomial_extensions.png', **fig_save_options)


import numpy as np
import scipy
from   sklearn import preprocessing

def cgm(A,b,x):
    """
    input:
            A: Coeficient matrix
            b: solution vector
            x: vector to be optimize
        output:
            x: optimiza vector
    """
    r = np.dot(A,x)-b
    p = -r
    k = 0

    while True:
        r_s = np.dot(np.transpose(r),r)
        alpha_k = r_s/np.dot(np.transpose(p),np.dot(A,p))

        x = x + np.dot(alpha_k,p)

        r = r + np.dot(alpha_k, np.dot(A,p))

        beta = np.dot(np.transpose(r),r)/r_s

        p = -r + beta*p

        k = k+1
        if np.linalg.norm(r) < 1e-10:
            break
        if k > 10:
            break
    return x

# Definición de matriz simétrica
def its_simetric_o(matrix, order):
    """
    inputs:
        matrix: a cuadratic matix
        order: the number of raws in the matix
    outputs:
        True ir our matrix is simetric, false otherwise
    """
    simetrica = True
    for i in range(orden):
        for j in range(orden):
            if (matriz[i][j] != matriz[j][i]):
                simetric = False
    return simetric

def its_simetric(matrix):
    """
    inputs:
        matrix: a cuadratic matix
    outputs:
        True ir our matrix is simetric, false otherwise
    """
    matrix_t = np.transpose(matrix)
    return matrix.all() == matrix_t.all()

def symmetrize(n):
    """
    input:
        n: size of the symmetric matrix required
    optput:
        symetric matix
    """

    a = np.random.randint(10, size=(n,n))

    return a + a.T - np.diag(a.diagonal())

def symmetrize_posdef(n):
    """
    input:
        n: size of the symmetric matrix required
    optput:
        symetric define positive matix
    """
    while True:

        a = np.random.randint(10, size=(n,n))
        if np.all(np.linalg.eigvals(a) > 0):
            break
        else:
            a = np.random.randint(10, size=(n,n))

    return a

def is_pos_def(x):
    """
    input:
        param x: matrix to check if it  is define positive
        return: True if the matix is define positive and False otherwise
        Checks if a matix is define positive to know the problem is being solve
        is convex and can be treated by the cojugate gradiant method.
    """
    return np.all(np.linalg.eigvals(x) > 0)


import numpy as np
from numpy.random import uniform

def generate_1d_regression(
        n_points=2000,
        domain=(-2.0, 2.0),
        noise_std=0.1,
        seed=None):
    """
    Generate data points from periodic function
    Parameters
    ----------
    n_points : Number of data points to generate
    domain : range for data points
    noise_std : noise introduced to the data points
    seed : random seed

    Returns
    -------
    xs, ys : generated  data points
    """

    def f(x):
        x = np.atleast_1d(x)
        y = np.sin(6 * x) + 0.4 * x ** 2 - 0.1 * x ** 3 - x * np.cos(9 * np.sqrt(np.exp(x)))
        return y
    rng = np.random.RandomState(seed)
    xs = rng.uniform(*domain, size=n_points).astype(np.float32).reshape(-1, 1)
    ys = (f(xs) + rng.normal(0.0, noise_std, size=(n_points, 1))).astype(np.float32)
    return xs, ys


"""Optimizer for weights of portfolio."""

from datetime import datetime
from typing import Optional

import numpy as np
import pandas as pd
from scipy.optimize import minimize

from mypo.common import covariance, safe_cast
from mypo.market import Market
from mypo.optimizer.base_optimizer import BaseOptimizer

class MeanVarianceOptimizer(BaseOptimizer):
    """Mean variance optimizer."""

    _span: int
    _risk_tolerance: Optional[float]
    _cost_tolerance: Optional[float]

    def __init__(
        self, span: int = 260, risk_tolerance: float = 0, cost_tolerance: float = 0, do_re_optimize: bool = False
    ):
        """Construct this object.

        Args:
            span: Span for evaluation.
            risk_tolerance: Risk tolerance.
            cost_tolerance: Cost tolerance.
            do_re_optimize: Do re-optimize.
        """
        self._span = span
        self._risk_tolerance = risk_tolerance
        self._cost_tolerance = cost_tolerance
        super().__init__([1], do_re_optimize)

    def optimize(self, market: Market, at: datetime) -> np.float64:
        """Optimize weights.

        Args:
            market: Past market stock prices.
            at: Current date.

        Returns:
            Optimized weights
        """
        historical_data = market.extract(market.get_index() <= pd.to_datetime(at)).get_rate_of_change()
        prices = historical_data.tail(n=self._span).to_numpy()
        Q = covariance(prices)
        R = prices.mean(axis=0)
        n = len(historical_data.columns)
        x = np.ones(n) / n

        def fn(x: np.ndarray) -> np.float64:
            ret: np.float64 = np.dot(np.dot(x, Q), x.T) - self._risk_tolerance * np.dot(R, x)
            return ret

        cons = [{"type": "eq", "fun": lambda x: np.sum(x) - 1}]
        bounds = [[0.0, 1.0] for i in range(n)]

        minout = minimize(fn, x, method="SLSQP", bounds=bounds, constraints=cons, tol=1e-6 * np.max(np.abs(Q)))

        if self._cost_tolerance != 0:
            # Cn = CEo - CEn + TC`|wn - wc| + d(wn - wo)`(wn - wo)
            previous_weights = safe_cast(self._weights)
            optimized_weights = safe_cast(minout.x)
            optimized_value = np.float64(minout.fun)

            def cn(
                x: np.ndarray,
            ) -> np.float64:
                wo_diff = x - optimized_weights
                wp_diff = x - previous_weights
                ret: np.float64 = (
                    optimized_value
                    - fn(x)
                    + self._cost_tolerance * np.dot(wp_diff, wp_diff.T)
                    + np.dot(wo_diff, wo_diff.T)
                )
                return ret

            minout = minimize(
                cn,
                previous_weights,
                method="SLSQP",
                bounds=bounds,
                constraints=cons,
                tol=1e-6 * np.max(np.abs(Q)),
            )

        self._weights = safe_cast(minout.x)
        return np.float64(minout.fun)


import numpy as np
from numba import njit, int64, float64, prange

@njit(float64[:,:](int64, int64, float64, int64, float64[:]))
def dbfuns(i, n, u, p, U):
    """Evaluates derivatives up to :math:`n` th order of all non-zero
    bspline basis functions :math:`\\frac{\partial^n}{\partial u^n} B_{j,p}(u)`
    at the coordinate :math:`u`, :math:`j=i-p\ldots i`,
    :math:`(n+1) \\times (p+1)` values.

    Parameters:
        i (int) : knot span in which :math:`u` lies
        n (in) : highest derivative order
        u (float) : evaluation point
        p (int)  : basis function degree
        U (np.array(float)) : knot vector

    Returns:
        np.array(float) : scalar values of
        :math:`\\frac{\partial^k}{\partial u^k} B_{j,p}(u)`,
        where dB[k,j] = :math:`\\frac{\partial^k}{\partial u^k} B_{j,p}(u)`.
        :math:`k=0\ldots n`
    """
    m = U.size - 1

    ndu = np.zeros((p+1, p+1))
    a = np.zeros((2,p+1))
    ders = np.zeros((n+1,p+1))
    left = np.zeros(p+1)
    right = np.zeros(p+1)

    ndu[0][0] = 1.
    for j in range(1, p+1):
        left[j] = u - U[i+1-j]
        right[j] = U[i+j] - u
        saved = 0.

        for r in range(0, j):
            ndu[j][r] = right[r+1] + left[j-r]
            temp = ndu[r][j-1] / ndu[j][r]
            ndu[r][j] = saved + right[r+1] * temp
            saved  = left[j-r] * temp

        ndu[j][j] = saved;

    for j in range(0, p+1):
        ders[0][j] = ndu[j][p]

    for r in range(0, p+1):
        s1 = 0
        s2 = 1
        a[0][0] = 1
        for k in range(1, n+1):
            d = 0;
            rk = r - k;
            pk = p - k;
            if r >= k:
                a[s2][0] = a[s1][0] / ndu[pk+1][rk]
                #d += a[s2][0] * ndu[rk][pk] # diff in C# code
                d = a[s2][0] * ndu[rk][pk]

            if rk >= -1:
                j1 = 1
            else:
                j1 = -rk

            if (r-1) <= pk:
                j2 = k - 1
            else:
                j2 = p - r

            for j in range(j1, j2+1):
                a[s2][j] = (a[s1][j] - a[s1][j-1]) / ndu[pk+1][rk+j]
                d += a[s2][j] * ndu[rk+j][pk]

            if r <= pk:
                a[s2][k] = -a[s1][k-1] / ndu[pk+1][r]
                d += a[s2][k] * ndu[r][pk];

            ders[k][r] = d;
            j = s1;
            s1 = s2;
            s2 = j;

    r = float(p);
    for k in range(1, n+1):
        for j in range(0, p+1):
            ders[k][j] *= r
        r *= (p - k)

    return ders

if __name__ == '__main__':
    from tensiga.iga.fspan import fspan
    from tensiga.iga.dbfun import *

    n = 3
    u = 5./2
    p = 2
    U = np.array([0,0,0,1,2,3,4,4,5,5,5], dtype=np.float64)
    i = fspan(u, p, U)

    print('Single call:')
    print(dbfuns(i, n, u, p, U))

    print('  ')
    print('One by one computation:')
    dB22 = dbfun(i-p+0, n, u, p, U)
    dB32 = dbfun(i-p+1, n, u, p, U)
    dB42 = dbfun(i-p+2, n, u, p, U)
    print(np.stack([dB22, dB32, dB42], axis=-1))


import sys
import sympy

def func_1_expr():
    """
    x*sin(x) - 1 = 0
    """
    x = sympy.symbols('x')
    return x*sympy.sin(x)-1.0

def func_2_expr():
    """
    x^2 - 5 = 0
    """
    x = sympy.symbols('x')
    return x**2.0 - 5.0

def func_3_expr():
    """
    x^3 -3x + 2 = 0
    """
    x = sympy.symbols('x')
    return x**3.0 - 3.0*x +2

class _func():
    """
    计算一元函数值及导数值
    """
    def __init__(self, expr, eff=15):
        """
        初始化计算表达式
        expr@表达式
        eff@有效数字位数
        """
        self._expr = expr()
        self._eff = eff
        self._x = list(self._expr.free_symbols)[0]
        self._diff_expr = sympy.diff(self._expr, self._x)

    def value(self, x):
        """
        计算 func 值
        """
        expr = self._expr
        return expr.subs('x', x).evalf(self._eff)

    def diff_value(self, x):
        """
        计算导数值
        """
        expr = self._diff_expr
        return expr.subs('x', x).evalf(self._eff)

def TrailValue(expr, a, b, e):
    """
    试值法
    f@函数
    a@区间下限
    b@区间上限
    e@容忍误差限
    """
    f = _func(expr)
    fa_0 = f.value(a)
    fb_0 = f.value(b)
    res = 0
    count = 0
    if abs(fa_0) < e:
        res = a
    elif abs(fb_0) < e:
        res = b
    elif sympy.sign(fa_0) == sympy.sign(fb_0):
        print('f(a) and f(b) 同号')
        sys.exit()
    else:
        while True:
            count = count + 1
            fa = f.value(a)
            fb = f.value(b)
            c = b - ((b-a)/(fb - fa))*fb
            fc = f.value(c)

            # 更新有根区间
            if sympy.sign(fa) == sympy.sign(fc):
                a = c
            else:
                b = c

            # 判断计算结束
            if abs(f.value(c)) < e:
                res = c
                break

    return res, count

def Newton(expr, a, b, e):
    """
    牛顿法与二分法结合
    f@函数
    a@区间下限
    b@区间上限
    e@容忍误差限
    """
    f = _func(expr)
    fa_0 = f.value(a)
    fb_0 = f.value(b)
    res = 0
    count = 0
    if abs(fa_0) < e:
        res = a
    elif abs(fb_0) < e:
        res = b
    elif sympy.sign(fa_0) == sympy.sign(fb_0):
        print('f(a) and f(b) 同号')
        sys.exit()
    else:
        x = a
        while True:
            count = count + 1
            c = x - f.value(x)/f.diff_value(x)

            # Newton与二分法结合，找下一个点
            if (c > a) and (c < b):
                x = c
            else:
                x = a+(b-a)/2

            # 更新有根区间
            if sympy.sign(f.value(a)) == sympy.sign(f.value(x)):
                a = x
            else:
                b = x

            # 判断计算结束
            if abs(f.value(x)) < e:
                res = x
                break

    return res, count

def main():
    """
    main
    """
    res_t, count_t = TrailValue(func_1_expr, 1, 2, 1.0/sympy.Pow(10, 5))
    print('试值法 func 1 根: %.5f, 迭代次数: %d' % (res_t, count_t))

    res_n, count_n = Newton(func_1_expr, 1, 2, 1.0/sympy.Pow(10, 5))
    print('牛顿法 func 1 根: %.5f, 迭代次数: %d' % (res_n, count_n))

    res_t, count_t = TrailValue(func_2_expr, 2, 3, 1.0/sympy.Pow(10, 5))
    print('试值法 func 2 根: %.5f, 迭代次数: %d' % (res_t, count_t))

    res_n, count_n = Newton(func_2_expr, 2, 3, 1.0/sympy.Pow(10, 5))
    print('牛顿法 func 2 根: %.5f, 迭代次数: %d' % (res_n, count_n))

    res_t, count_t = TrailValue(func_3_expr, -2.5, -1.5, 1.0/sympy.Pow(10, 5))
    print('试值法 func 3 根: %.5f, 迭代次数: %d' % (res_t, count_t))

    res_n, count_n = Newton(func_3_expr, -2.5, -1.5, 1.0/sympy.Pow(10, 5))
    print('牛顿法 func 3 根: %.5f, 迭代次数: %d' % (res_n, count_n))

if __name__ == "__main__":
    main()


"""
  Name     : c11_15_VaR_500shares_VMT_sort_daily.py
  Book     : Python for Finance (2nd ed.)
  Publisher: Packt Publishing Ltd.
  Author   : Yuxing Yan
  Date     : 6/6/2017
  email    : yany@canisius.edu
             paulyxy@hotmail.com
"""
import numpy as np
import pandas as pd
from scipy.stats import norm
from matplotlib.finance import quotes_historical_yahoo_ochl as getData
#
ticker='WMT'            # input 1
n_shares=500            # input 2
confidence_level=0.99   # input 3
begdate=(2012,1,1)      # input 4
enddate=(2016,12,31)    # input 5
#
z=norm.ppf(1-confidence_level)
x=getData(ticker,begdate,enddate,asobject=True,adjusted=True)
ret = np.array(x.aclose[1:]/x.aclose[:-1]-1)
ret2=np.sort(ret)
#
position=n_shares*x.close[0]
n=np.size(ret2)
m=int(n*(1-confidence_level))
print("m=",m)
#
sum=0.0
for i in np.arange(m):
    sum+=ret2[i]
ret3=sum/m
ES=position*ret3
print("Holding=",position, "Expected Shortfall=", round(ES,4), "tomorrow")


import numpy as np
from numpy import linalg as lg
from numpy.linalg import solve
from numpy.linalg import eig
from scipy.integrate import quad

# MAT 350 - Linear Algebra
# Homework 1

# Question 1
'''
x^1 + 2x^2 = 8
x^1 - x^2 = 2

[1 2 | 8]
[1 -1 | 2]

x1 = 4
x2 = 2
'''

# Question 2
'''
x^2 + 3x^3 = 3
x^1 + 2x^2 + 2x^3 = -5
5x^1 + 9x^2 + 7x^3 = 2

Matrix:
[0 1 3 | 3]
[1 2 2 | -5]
[5 9 7 | 2]

Interchange rows 1 & 2:
[1 2 2 | -5]
[0 1 3 | 3]
[5 9 7 | 2]

Row operation to change entry in 3rd row, column 1 to a 0:
(subtract 5 * row 1)
[1 2 2 | -5]
[0 1 3 | 3]
[0 -1 -3 | -23]

Add row 2 to row 3 to zero out the left side of row 3:
[1 2 2 | -5]
[0 1 3 | 3]
[0 0 0 | -20]

This problem has no solution because the 3rd row is the inequality:
0 = 20
'''

# Question 3
'''
[1 h 4]
[5 10 16]

Subtract 5 * row 1 from row 2:
[1 h 4]
[0 10 - 5h | -4]

Rewrite as a system of linear equations:
x^1 + hx^2 = 4
(10 - 5h)x^2 = -4

If h = 2, the equation is undefined, so h != 2
'''

# Question 4
# Multiple Choice

# Question 5
# Multiple Choice

# Question 6
# Multiple Choice

# Question 8
'''
Find the general solution of this system:
[1 0 -7 0 -3 | 4]
[0 1 5 -1 0  | 6]
[0 0 0 0 1   | 0]
[0 0 0 0 0   | 0]

First, add 3*r3 to r1, resulting in reduced row echelon form:
[1 0 -7 0 0 | 4]
[0 1 5 -1 0 | 6]
[0 0 0 0 0  | 1]
[0 0 0 0 0  | 0]

# Write the system of equations:
x1 - 7x3  = 4
  x2 + 5x3 -x4 = 6
x5 = 0
0 = 0


import numpy as np

def affine_forward(x, theta, theta0):
  """
  Computes the forward pass for an affine (fully-connected) layer.

  The input x has shape (m, d_1, ..., d_k) and contains a minibatch of m
  examples, where each example x[i] has shape (d_1, ..., d_k). We will
  reshape each input into a vector of dimension d = d_1 * ... * d_k, and
  then transform it to an output vector of dimension h.

  Inputs:
  - x: A numpy array containing input data, of shape (m, d_1, ..., d_k)
  - theta: A numpy array of weights, of shape (d, h)
  - theta0: A numpy array of biases, of shape (h,)

  Returns a tuple of:
  - out: output, of shape (m, h)
  - cache: (x, theta, theta0)
  """
  out = None
  #############################################################################
  # TODO: Implement the affine forward pass. Store the result in out. You     #
  # will need to reshape the input into rows.                                 #
  #############################################################################
  # 2 lines of code expected
  xmd = x.reshape((x.shape[0], theta.shape[0]))
  out = xmd @ theta + theta0
  #############################################################################
  #                             END OF YOUR CODE                              #
  #############################################################################
  cache = (x, theta, theta0)
  return out, cache

def affine_backward(dout, cache):
  """
  Computes the backward pass for an affine layer.

  Inputs:
  - dout: Upstream derivative, of shape (m, h)
  - cache: Tuple of:
    - x: Input data, of shape (m, d_1, ... d_k)
    - theta: Weights, of shape (d,h)
    - theta0: biases, of shape (h,)

  Returns a tuple of:
  - dx: Gradient with respect to x, of shape (m, d1, ..., d_k)
  - dtheta: Gradient with respect to theta, of shape (d, h)
  - dtheta0: Gradient with respect to theta0, of shape (h,)
  """
  x, theta, theta0 = cache
  dx, dtheta, dtheta0 = None, None, None
  #############################################################################
  # TODO: Implement the affine backward pass.                                 #
  #############################################################################
  # Hint: do not forget to reshape x into (m,d) form
  # 4-5 lines of code expected
  xmd = x.reshape((x.shape[0], theta.shape[0]))
  dx = (dout @ theta.T).reshape(x.shape)
  dtheta = xmd.T @ dout
  dtheta0 = np.sum(dout, axis=0)
  #############################################################################
  #                             END OF YOUR CODE                              #
  #############################################################################
  return dx, dtheta, dtheta0

def relu_forward(x):
  """
  Computes the forward pass for a layer of rectified linear units (ReLUs).

  Input:
  - x: Inputs, of any shape

  Returns a tuple of:
  - out: Output, of the same shape as x
  - cache: x
  """
  out = None
  #############################################################################
  # TODO: Implement the ReLU forward pass.                                    #
  #############################################################################
  # 1 line of code expected
  out = np.where(x > 0, x, 0)
  #############################################################################
  #                             END OF YOUR CODE                              #
  #############################################################################
  cache = x
  return out, cache

def relu_backward(dout, cache):
  """
  Computes the backward pass for a layer of rectified linear units (ReLUs).

  Input:
  - dout: Upstream derivatives, of any shape
  - cache: Input x, of same shape as dout

  Returns:
  - dx: Gradient with respect to x
  """
  dx, x = None, cache
  #############################################################################
  # TODO: Implement the ReLU backward pass.                                   #
  #############################################################################
  # 1 line of code expected. Hint: use np.where
  dx = np.where(x > 0, dout, 0)
  #############################################################################
  #                             END OF YOUR CODE                              #
  #############################################################################
  return dx

def dropout_forward(x, dropout_param):
  """
  Performs the forward pass for (inverted) dropout.

  Inputs:
  - x: Input data, of any shape
  - dropout_param: A dictionary with the following keys:
    - p: Dropout parameter. We drop each neuron output with probability p.
    - mode: 'test' or 'train'. If the mode is train, then perform dropout;
      if the mode is test, then just return the input.
    - seed: Seed for the random number generator. Passing seed makes this
      function deterministic, which is needed for gradient checking but not in
      real networks.

  Outputs:
  - out: Array of the same shape as x.
  - cache: A tuple (dropout_param, mask). In training mode, mask is the dropout
    mask that was used to multiply the input; in test mode, mask is None.
  """
  p, mode = dropout_param['p'], dropout_param['mode']
  if 'seed' in dropout_param:
    np.random.seed(dropout_param['seed'])

  mask = None
  out = None

  if mode == 'train':
    ###########################################################################
    # TODO: Implement the training phase forward pass for inverted dropout.   #
    # Store the dropout mask in the mask variable.                            #
    ###########################################################################
    # 2 lines of code expected
    mask = (np.random.rand(*x.shape) < (1 - p)) / (1 - p)
    out = x * mask
    ###########################################################################
    #                            END OF YOUR CODE                             #
    ###########################################################################
  elif mode == 'test':
    ###########################################################################
    # TODO: Implement the test phase forward pass for inverted dropout.       #
    ###########################################################################
    # 1 line of code expected
    out = x
    ###########################################################################
    #                            END OF YOUR CODE                             #
    ###########################################################################

  cache = (dropout_param, mask)
  out = out.astype(x.dtype, copy=False)

  return out, cache

def dropout_backward(dout, cache):
  """
  Perform the backward pass for (inverted) dropout.

  Inputs:
  - dout: Upstream derivatives, of any shape
  - cache: (dropout_param, mask) from dropout_forward.
  """
  dropout_param, mask = cache
  mode = dropout_param['mode']

  dx = None
  if mode == 'train':
    ###########################################################################
    # TODO: Implement the training phase backward pass for inverted dropout.  #
    ###########################################################################
    # 1 line of code expected
    dx = dout * mask
    ###########################################################################
    #                            END OF YOUR CODE                             #
    ###########################################################################
  elif mode == 'test':
    dx = dout
  return dx

def conv_forward_naive(x, theta, theta0, conv_param):
  """
  A naive implementation of the forward pass for a convolutional layer.

  The input consists of m data points, each with C channels, height H and width
  W. We convolve each input with F different filters, where each filter spans
  all C channels and has height HH and width HH.

  Input:
  - x: Input data of shape (m, C, H, W)
  - theta: Filter weights of shape (F, C, HH, WW)
  - theta0: Biases, of shape (F,)
  - conv_param: A dictionary with the following keys:
    - 'stride': The number of pixels between adjacent receptive fields in the
      horizontal and vertical directions.
    - 'pad': The number of pixels that will be used to zero-pad the input.

  Returns a tuple of:
  - out: Output data, of shape (m, F, H', W') where H' and W' are given by
    H' = 1 + (H + 2 * pad - HH) / stride
    W' = 1 + (W + 2 * pad - WW) / stride
  - cache: (x, theta, theta0, conv_param)
  """
  out = None
  #############################################################################
  # TODO: Implement the convolutional forward pass.                           #
  # Hint: you can use the function np.pad for padding.                        #
  #############################################################################
  m, C, H, W = x.shape
  F, C, HH, WW = theta.shape
  stride, pad = conv_param['stride'], conv_param['pad']
  H1 = int(1 + (H + 2 * pad - HH) / stride)
  W1 = int(1 + (W + 2 * pad - WW) / stride)
  out = np.zeros((m, F, H1, W1))
  xp = np.pad(x, [(0, 0), (0, 0), (pad, pad), (pad, pad)], mode='constant')
  for i in range(m):
    for j in range(F):
      for k in range(H1):
        for l in range(W1):
          conv = xp[i, :, (k * stride):(k * stride + HH), (l * stride):(l * stride + WW)]
          out[i, j, k, l] = np.sum(conv * theta[j]) + theta0[j]
  #############################################################################
  #                             END OF YOUR CODE                              #
  #############################################################################
  cache = (x, theta, theta0, conv_param)
  return out, cache

def conv_backward_naive(dout, cache):
  """
  A naive implementation of the backward pass for a convolutional layer.

  Inputs:
  - dout: Upstream derivatives.
  - cache: A tuple of (x, theta, theta0, conv_param) as in conv_forward_naive

  Returns a tuple of:
  - dx: Gradient with respect to x
  - dtheta: Gradient with respect to theta
  - dtheta0: Gradient with respect to theta0
  """
  dx, dtheta, dtheta0 = None, None, None
  #############################################################################
  # TODO: Implement the convolutional backward pass.                          #
  #############################################################################
  x, theta, theta0, conv_param = cache
  m, C, H, W = x.shape
  F, C, HH, WW = theta.shape
  stride, pad = conv_param['stride'], conv_param['pad']
  H1 = int(1 + (H + 2 * pad - HH) / stride)
  W1 = int(1 + (W + 2 * pad - WW) / stride)
  dx = np.zeros_like(x)
  dtheta = np.zeros_like(theta)
  xp = np.pad(x, [(0, 0), (0, 0), (pad, pad), (pad, pad)], mode='constant')
  dxp = np.pad(dx, [(0, 0), (0, 0), (pad, pad), (pad, pad)], mode='constant')
  for i in range(m):
    for j in range(F):
      for k in range(H1):
        for l in range(W1):
          dxp[i, :, (k * stride):(k * stride + HH), (l * stride):(l * stride + WW)] += dout[i, j, k, l] * theta[j, :, :, :]
          dtheta[j, :, :, :] += dout[i, j, k, l] * xp[i, :, (k * stride):(k * stride + HH),(l * stride):(l * stride + WW)]
  dtheta0 = np.sum(dout, axis=(0, 2, 3))
  dx = dxp[:, :, pad:(pad + H), pad:(pad + W)]
  #############################################################################
  #                             END OF YOUR CODE                              #
  #############################################################################
  return dx, dtheta, dtheta0

def max_pool_forward_naive(x, pool_param):
  """
  A naive implementation of the forward pass for a max pooling layer.

  Inputs:
  - x: Input data, of shape (m, C, H, W)
  - pool_param: dictionary with the following keys:
    - 'pool_height': The height of each pooling region
    - 'pool_width': The width of each pooling region
    - 'stride': The distance between adjacent pooling regions

  Returns a tuple of:
  - out: Output data
  - cache: (x, pool_param)
  """
  out = None
  #############################################################################
  # TODO: Implement the max pooling forward pass                              #
  #############################################################################
  m, C, H, W = x.shape
  pool_height, pool_width, stride = pool_param['pool_height'], pool_param['pool_width'], pool_param['stride']
  H2 = int(1 + (H - pool_height) / stride)
  W2 = int(1 + (W - pool_width) / stride)
  out = np.zeros((m, C, H2, W2))
  for i in range(m):
    for j in range(C):
      for k in range(H2):
        for l in range(W2):
          out[i, j, k, l] = np.max(x[i, j,  (k * stride):(k * stride + pool_height), (l * stride):(l * stride + pool_width)])
  #############################################################################
  #                             END OF YOUR CODE                              #
  #############################################################################
  cache = (x, pool_param)
  return out, cache

def max_pool_backward_naive(dout, cache):
  """
  A naive implementation of the backward pass for a max pooling layer.

  Inputs:
  - dout: Upstream derivatives
  - cache: A tuple of (x, pool_param) as in the forward pass.

  Returns:
  - dx: Gradient with respect to x
  """
  dx = None
  #############################################################################
  # TODO: Implement the max pooling backward pass                             #
  #############################################################################
  x, pool_param = cache
  m, C, H, W = x.shape
  pool_height, pool_width, stride = pool_param['pool_height'], pool_param['pool_width'], pool_param['stride']
  H2 = int(1 + (H - pool_height) / stride)
  W2 = int(1 + (W - pool_width) / stride)
  dx = np.zeros_like(x)
  for i in range(m):
    for j in range(C):
      for k in range(H2):
        for l in range(W2):
          pool = x[i, j,  (k * stride):(k * stride + pool_height), (l * stride):(l * stride + pool_width)]
          maxPool = (np.max(pool) == pool)
          dx[i, j, (k * stride):(k * stride + pool_height), (l * stride):(l * stride + pool_width)] += dout[i, j, k, l] * maxPool
  #############################################################################
  #                             END OF YOUR CODE                              #
  #############################################################################
  return dx

def svm_loss(x, y):
  """
  Computes the loss and gradient using for multiclass SVM classification.

  Inputs:
  - x: Input data, of shape (m, C) where x[i, j] is the score for the jth class
    for the ith input.
  - y: Vector of labels, of shape (m,) where y[i] is the label for x[i] and
    0 <= y[i] < C

  Returns a tuple of:
  - loss: Scalar giving the loss
  - dx: Gradient of the loss with respect to x
  """
  m = x.shape[0]
  correct_class_scores = x[np.arange(m), y]
  margins = np.maximum(0, x - correct_class_scores[:, np.newaxis] + 1.0)
  margins[np.arange(m), y] = 0
  loss = np.sum(margins) / m
  num_pos = np.sum(margins > 0, axis=1)
  dx = np.zeros_like(x)
  dx[margins > 0] = 1
  dx[np.arange(m), y] -= num_pos
  dx /= m
  return loss, dx

def softmax_loss(x, y):
  """
  Computes the loss and gradient for softmax classification.

  Inputs:
  - x: Input data, of shape (m, C) where x[i, j] is the score for the jth class
    for the ith input.
  - y: Vector of labels, of shape (m,) where y[i] is the label for x[i] and
    0 <= y[i] < C

  Returns a tuple of:
  - loss: Scalar giving the loss
  - dx: Gradient of the loss with respect to x
  """
  probs = np.exp(x - np.max(x, axis=1, keepdims=True))
  probs /= np.sum(probs, axis=1, keepdims=True)
  m = x.shape[0]
  loss = -np.sum(np.log(probs[np.arange(m), y])) / m
  dx = probs.copy()
  dx[np.arange(m), y] -= 1
  dx /= m
  return loss, dx


# Copyright (c) 2020 Chris Richardson
# FEniCS Project
# SPDX-License-Identifier: MIT

import basix
import pytest
import numpy as np
import sympy

@pytest.mark.parametrize("celltype", [(basix.CellType.quadrilateral, 1.0),
                                      (basix.CellType.hexahedron, 1.0),
                                      (basix.CellType.prism, 0.5),
                                      (basix.CellType.interval, 1.0),
                                      (basix.CellType.triangle, 0.5),
                                      (basix.CellType.tetrahedron, 1.0/6.0)])
@pytest.mark.parametrize("order", [1, 2, 3, 4, 5, 6, 7, 8])
def test_cell_quadrature(celltype, order):
    Qpts, Qwts = basix.make_quadrature("default", celltype[0], order)
    print(sum(Qwts))
    assert(np.isclose(sum(Qwts), celltype[1]))

@pytest.mark.parametrize("m", [0, 1, 2, 3, 4, 5, 6])
@pytest.mark.parametrize("scheme", ['default', 'GLL'])
def test_qorder_line(m, scheme):
    Qpts, Qwts = basix.make_quadrature(scheme, basix.CellType.interval, m)
    x = sympy.Symbol('x')
    f = x**m
    print(f)
    q = sympy.integrate(f, (x, 0, (1)))
    s = 0.0
    for (pt, wt) in zip(Qpts, Qwts):
        s += wt * f.subs([(x, pt[0])])
    print(len(Qwts))
    assert(np.isclose(float(q), float(s)))

@pytest.mark.parametrize("m", [0, 1, 2, 3, 4, 5, 6])
@pytest.mark.parametrize("scheme", ['default', 'Gauss-Jacobi'])
def test_qorder_tri(m, scheme):
    Qpts, Qwts = basix.make_quadrature(scheme, basix.CellType.triangle, m)
    x = sympy.Symbol('x')
    y = sympy.Symbol('y')
    f = x**m + y**m
    q = sympy.integrate(sympy.integrate(f, (x, 0, (1 - y))), (y, 0, 1))
    s = 0.0
    for (pt, wt) in zip(Qpts, Qwts):
        s += wt * f.subs([(x, pt[0]), (y, pt[1])])
    print(len(Qwts))
    assert(np.isclose(float(q), float(s)))

@pytest.mark.parametrize("m", [0, 1, 2, 3, 4, 5, 6])
@pytest.mark.parametrize("scheme", ['default', 'Gauss-Jacobi'])
def test_qorder_tet(m, scheme):
    Qpts, Qwts = basix.make_quadrature(scheme, basix.CellType.tetrahedron, m)
    x = sympy.Symbol('x')
    y = sympy.Symbol('y')
    z = sympy.Symbol('z')
    f = x**m + y**m + z**m
    q = sympy.integrate(sympy.integrate(sympy.integrate(f, (x, 0, (1 - y - z))), (y, 0, 1 - z)), (z, 0, 1))
    s = 0.0
    for (pt, wt) in zip(Qpts, Qwts):
        s += wt * f.subs([(x, pt[0]), (y, pt[1]), (z, pt[2])])
    print(len(Qwts))
    assert(np.isclose(float(q), float(s)))

def test_quadrature_function():
    Qpts, Qwts = basix.make_quadrature("default", basix.CellType.interval, 3)
    # Scale to interval [0.0, 2.0]
    Qpts *= 2.0
    Qwts *= 2.0

    def f(x):
        return x * x

    b = sum([w * f(pt[0]) for pt, w in zip(Qpts, Qwts)])

    assert np.isclose(b, 8.0 / 3.0)

def test_jacobi():
    pts = np.arange(0, 1, 0.1)
    f = basix.compute_jacobi_deriv(1.0, 4, 5, pts)
    print(f)

def test_gll():
    m = 6
    pts, wts = basix.gauss_lobatto_legendre_line_rule(m)
    ref_pts = np.array([-1., -0.76505532,
                        -0.28523152, 0.28523152,
                        0.76505532, 1.])
    assert (np.allclose(pts, ref_pts))
    ref_wts = np.array([0.06666667, 0.37847496,
                        0.55485838, 0.55485838,
                        0.37847496, 0.06666667])
    assert (np.allclose(wts, ref_wts))
    print(pts, wts)
    assert np.isclose(sum(pts * wts), 0)
    assert np.isclose(sum(wts), 2)


import numpy as np
import math

W = np.array([[ -8, 8, -6, 14, 14, -9, -4],
	[ 2, -11, -2, -11, 14, -2, 14],
	[-13, -2, -5, 3, -8, -4, 13],
	[ 2, 13, -14, -15, -14, -15, 13],
	[ 2, -1, 12, 3, -7, -3, -6]])
Z = np.array([
[ -6, -1, -8, 7, -8],
 [ 7, 4, 0, -10, -10],
 [ 7, -13, 2, 2, -11],
 [ 3, 14, 7, 7, -4],
 [ -1, -3, -8, -4, -14],
 [ 9, -14, 9, 12, -7],
 [ -9, -4, -10, -3, 6]])
X = np.array([0, 15, -9, 7, 12, 3, -21])
Y = np.array([2, 14, -13, 5, 12, 4, -19])
# X = np.array([0, 15, -9, 7, 12, 3, -21]).reshape((7,1))
# Y = np.array([2, 14, -13, 5, 12, 4, -19]).reshape((7,1))
def sum__(x, f):
	acc = 0.
	for item in x:
		acc += f(item)
	return acc
def mean(x):
	n = x.shape[0]
	acc = 0.
	for item in x:
		acc += item
	return acc/n

def	variance(x):
	u = mean(x)
	return sum__(x,lambda x: (x - u)**2) / x.shape[0]

def std(x):
	return math.sqrt(variance(x))

def dot(x, y):
	if (x is None or y is None
	or x.shape[0] != y.shape[0]):
		return None
	return sum__(x * y, lambda x:x)

def mat_vec_prod(x, y):
	if (x.shape[1], 1) != y.shape:
		return None
	res = np.zeros((x.shape[0],1))
	f = 0
	for row in x:
		row = row.reshape((row.shape[0],1))
		res[f] = dot(row, y)
		f += 1
	return res

# print(mat_vec_prod(W, X))
# print(W.dot(X))
# print(mean(X**2))

def mat_mat_prod(x, y):
	if (x.shape[0] != y.shape[1]):
		return None
	res = np.zeros((x.shape[0],y.shape[1]))
	print(x.shape," ",y.shape)
	for i in range(x.shape[0]):
		for j in range(y.shape[1]):
			res[i][j] = dot(x[i],y[:,j])
	return res

def mse(y, y_hat):
	if y.shape != y_hat.shape:
		return None
	acc = 0.
	for elem1,elem2 in zip(y,y_hat):
		acc += (elem1 - elem2)**2
	return acc / y.shape[0]

def vec_mse(y, y_hat):
	y = y.reshape((y.shape[0],1))
	y_hat = y_hat.reshape((y_hat.shape[0],1))
	# print(y.shape)
	return float(dot(y_hat - y,y_hat - y) / y_hat.shape[0])

def linear_mse(x, y, theta):
	return mse(dot(theta, x), y)
# print(X.shape)
# print(X)
# print(X.reshape((1,X.shape[0])))
# print(X)

# print(linear_mse(X, Y))


"""SIR model simulations."""
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

from tqdm import tqdm
from typing import Union, Dict, List

class SIR:
    """Vanilla SIR model."""

    def __init__(
            self,
            param: Dict = {}):
        """Only initialize the model parameters."""
        self.beta = param.get('beta', 0.1)
        self.gamma = param.get('gamma', 0.05)
        self.eta = param.get('eta', 0.01)
        self.X_init = None
        self.X = None
        self.num_steps = 0

    def run(
            self,
            X_init: Union[List, np.ndarray],
            num_steps: int = 365):
        """Run the simulation by solving the SIR ODE numerically."""
        self.X_init = X_init
        self.num_steps = num_steps

        # sanity check for non-negative value
        for x in self.X_init:
            if x < 0:
                print('Invalid value, needs a non-negative number.', x)
        self.X_int = [min(0, x) for x in self.X_init]
        # sanity check, for nomalization
        norm = sum(self.X_init)
        self.X_init = [x / norm for x in self.X_init]

        # we want to simulate S, I and R, plus D (death)
        m = 4
        assert(len(X_init) == m)

        # initialize the X array
        self.X = np.zeros(shape=(m, self.num_steps))
        for i in range(m):
            self.X[i][0] = self.X_init[i]

        # solving the ODE
        for t in tqdm(range(1, self.num_steps)):
            S, I, R, D = self.X[0][t - 1], self.X[1][t - 1], \
                self.X[2][t - 1], self.X[3][t - 1]
            dS = -1. * self.beta * S * I / (S + I + R)
            dI = -1. * dS - self.gamma * I
            dR = (1 - self.eta) * self.gamma * I
            dD = self.eta * self.gamma * I

            self.X[0][t] = S + dS  # update S
            self.X[1][t] = I + dI  # update I
            self.X[2][t] = R + dR  # update R
            self.X[3][t] = D + dD  # update D

    def make_plot(self):
        """Visualize the simulation results."""
        if self.X is None:
            tqdm.write('Run the simulation first.')
            return
        sns.set(font_scale=1.2)
        sns.set_style("whitegrid", {'grid.linestyle': '--'})
        # _ = plt.figure(figsize=(12, 9))

        time_steps = list(range(self.num_steps))

        sns.lineplot(x=time_steps, y=100 * self.X[0, :], label='Susceptible')
        sns.lineplot(x=time_steps, y=100 * self.X[1, :], label='Infectious')
        sns.lineplot(x=time_steps, y=100 * self.X[2, :], label='Recovered')
        sns.lineplot(x=time_steps, y=100 * self.X[3, :], label='Death')

        plt.xlabel('Day')
        plt.ylabel('Proportion of population (%)')
        plt.legend()
        plt.show()


from pennylane import numpy as np
from scipy.linalg import sqrtm
import matplotlib.pyplot as plt

def fidelity(rho, sigma):
    """Computes the fidelity between two density matrices.

    Fidelity has a maximum value of 1 when the two input states are
    the same, and a minimum value of 0 when the two states are
    totally orthogonal. When comparing the output of, e.g.,
    a state obtained through a noisy process to the ideal state,
    higher fidelity is better.

    Args:
        rho (array[complex]): A density matrix.
        sigma (array[complex]): A second density matrix.

    Returns:
        float: The fidelity between rho and sigma.
    """
    sqrt_rho = sqrtm(rho)
    inner_thing = np.linalg.multi_dot([sqrt_rho, sigma, sqrt_rho])
    return np.real(np.trace(sqrtm(inner_thing)) ** 2)

def trace_distance(rho, sigma):
    """Computes the trace distance between two density matrices.

    Trace distance has a maximum value of 1 when the two input states
    are totally orthogonal, and a minimum value of 0 when the two
    states are the same. When comparing the output of, e.g., a state
    obtained through a noisy process to the ideal state, lower
    trace distance is better.

    Args:
        rho (array[complex]): A density matrix.
        sigma (array[complex]): A second density matrix.

    Returns:
        float: The trace distance between rho and sigma.
    """
    rms = rho - sigma
    inner_thing = np.dot(rms.conj().T, rms)
    return np.real(0.5 * np.trace(sqrtm(inner_thing)))

def plot_density_matrix_city(rho):
    """A "city plot" of a density matrices real and imaginary components.

    Code taken from:
      - https://matplotlib.org/stable/gallery/mplot3d/3d_bars.html
      - https://stackoverflow.com/questions/43869751/change-bar-color-in-a-3d-bar-plot-in-matplotlib-based-on-value
    Args:
        rho (array[complex]): A density matrix.
    """

    fig = plt.figure(figsize=(15, 5))
    ax1 = fig.add_subplot(111, projection='3d')
    ax2 = fig.add_subplot(122, projection='3d')

    _x = np.arange(len(rho))
    _y = np.arange(len(rho))
    _xx, _yy = np.meshgrid(_x, _y)
    x, y = _xx.ravel(), _yy.ravel()

    real = rho.flatten().real
    imag = rho.flatten().imag

    colors_real = plt.cm.jet(real/float(real.max()))
    colors_imag = plt.cm.jet(imag/float(imag.max()))

    ax1.bar3d(x, y, np.zeros_like(x), 1, 1, real, color=colors_real, shade=False)
    ax2.bar3d(x, y, np.zeros_like(x), 1, 1, imag, color=colors_imag, shade=False)

    plt.show()


import numpy as np
import time

def hms2dec(h,m,s):
  return 15*(h + (m/60) + (s/3600))

def dms2dec(d,m,s):
  if d>=0:
    return (d + (m/60) + (s/3600))
  return (d - (m/60) - (s/3600))

def angular_dist(r1, d1, r2, d2):   # remove radians, radians mein hi ghusenge
  # r1= np.radians(r1)
  # r2= np.radians(r2)
  # d1= np.radians(d1)
  # d2= np.radians(d2)
  a = (np.sin(np.abs(d1 - d2)/2))**2
  b = np.cos(d1)*np.cos(d2)*np.sin(np.abs(r1 - r2)/2)**2
  d = np.degrees(2*np.arcsin(np.sqrt(a + b)))
  return d

def crossmatch(cat1, cat2, max_dist):
  matches = []
  no_matches = []
  start = time.perf_counter()
  cat1 = np.radians(cat1)
  cat2 = np.radians(cat2)
  id_1 = 0
  for i in cat1:
      best = (0,0,max_dist+1)
      id_2 = 0
      for j in cat2:
        dist = angular_dist(i[0], i[1], j[0], j[1])
        if dist<=best[2]:
          best = (id_1,id_2,dist)
        id_2+=1
      if best[2]<=max_dist:
         matches.append(best)
      else:
         no_matches.append(id_1)
      id_1+=1
  return (matches, no_matches, time.perf_counter() - start)


import numpy as np
from scipy.linalg import svd
from copy import deepcopy
from collections import Counter
from pdb import set_trace

def pca(X, n_components = 5):
    #  Use svd to perform PCA on X
    #  Inputs:
    #     X: input matrix
    #     n_components: number of principal components to keep
    #  Output:
    #     principal_components: the top n_components principal_components
    #     X_pca = X.dot(principal_components)

    U, s, Vh = svd(X)

    # Write your own code
    principal_components = "Write your own code"
    return principal_components

def vector_norm(x, norm="Min-Max"):
    # Calculate the normalized vector
    # Input x: 1-d np.array
    if norm == "Min-Max":
        x_norm = "Write your own code"
    elif norm == "L1":
        x_norm = "Write your own code"
    elif norm == "L2":
        x_norm = "Write your own code"
    elif norm == "Standard_Score":
        x_norm = "Write your own code"
    else:
        raise Exception("Unknown normlization.")
    return x_norm

def normalize(X, norm="Min-Max", axis = 1):
    #  Inputs:
    #     X: input matrix
    #     norm = {"L1", "L2", "Min-Max", "Standard_Score"}
    #     axis = 0: normalize rows
    #     axis = 1: normalize columns
    #  Output:
    #     X_norm: normalized matrix (numpy.array)

    X_norm = deepcopy(np.asarray(X))
    m, n = X_norm.shape
    if axis == 1:
        for col in range(n):
            X_norm[:,col] = vector_norm(X_norm[:,col], norm=norm)
    elif axis == 0:
        X_norm = np.array([vector_norm(X_norm[i], norm=norm) for i in range(m)])
    else:
        raise Exception("Unknown axis.")
    return X_norm

def stratified_sampling(y, ratio, replace = True):
    #  Inputs:
    #     y: a 1-d array of class labels
    #     0 < ratio < 1: number of samples = len(y) * ratio
    #     replace = True: sample with replacement
    #     replace = False: sample without replacement
    #  Output:
    #     sample: indices of stratified sampled points
    #             (ratio is the same across each class,
    #             samples for each class = int(np.ceil(ratio * # data in each class)) )

    if ratio<=0 or ratio>=1:
        raise Exception("ratio must be 0 < ratio < 1.")
    y_array = np.asarray(y)
    # Write your own code below

    return sample.astype(int)


# Question 06, Lab 05
# AB Satyaprakash - 180123062

# imports ----------------------------------------------------------------------------
from math import cos, log, sin, pi
from sympy.abc import t
import numpy as np
import pandas as pd
import sympy as sp
from scipy.integrate import quad

# global dictionaries ----------------------------------------------------------------
phi = {-1: 0, 0: 1}
alpha = {}
beta = {0: 0}

# functions --------------------------------------------------------------------------

def getFuncVal(x):
    # cosx log(sinx)/(1 + sin^2(x))
    return (cos(x)*log(sin(x))/(1+sin(x)**2))

def getInnerProduct(a, b):
    poly = np.poly1d(np.polyint(np.polymul(a, b)))
    return poly(1) - poly(-1)

def getPhi(n):
    # The value of ϕ(n) = (x-α(n-1))ϕ(n-1) - β(n)ϕ(n-2)
    if n in phi:
        return phi[n]

    a = getAlpha(n-1)
    b = getBeta(n-1)
    phi_n_1 = getPhi(n-1)
    phi_n_2 = getPhi(n-2)

    secondTerm = np.polymul([b], phi_n_2)
    firstTerm = np.polymul(np.polysub([1, 0], a), phi_n_1)
    phi[n] = np.polysub(firstTerm, secondTerm)
    return phi[n]

def getAlpha(n):
    # The value of α(n) = <xϕ(n), ϕ(n)>/<ϕ(n) , ϕ(n)>
    if n in alpha:
        return alpha[n]

    phi_n = getPhi(n)
    xphi_n = np.polymul([1, 0], phi_n)
    num = getInnerProduct(xphi_n, phi_n)
    denom = getInnerProduct(phi_n, phi_n)
    alpha[n] = num/denom

    return alpha[n]

def getBeta(n):
    # The value of β(n) = <ϕ(n), ϕ(n)>/<ϕ(n-1) , ϕ(n-1)>
    if n in beta:
        return beta[n]

    phi_n = getPhi(n)
    phi_n_1 = getPhi(n-1)
    num = getInnerProduct(phi_n, phi_n)
    denom = getInnerProduct(phi_n_1, phi_n_1)
    beta[n] = num/denom

    return beta[n]

def getGaussian(f, roots, W, limits):
    a, b = limits
    I = 0
    for x, w in zip(roots, W):
        I += w*f(x, a, b)
    return I

def f(x, a, b):
    c1, c2 = (b-a)/2, (b+a)/2
    x = c1*x + c2

    return c1*getFuncVal(x)

# program body
table = []
for k in range(1, 6):
    n = k+1
    poly = np.poly1d(getPhi(n))

    roots = poly.r
    roots.sort()

    temp = [[1] + [0]*(i) for i in range(n)]
    output = []
    for P in temp:
        P = (np.polyint(P))
        P = np.poly1d(P)
        I = P(1) - P(-1)
        output.append(I)

    X = []
    for i in range(n):
        temp = [x**i for x in roots]
        X.append(temp)

    X_ = np.linalg.inv(X)
    W = np.dot(X_, output)

    limits = (0, pi/2)
    result = getGaussian(f, roots, W, limits)
    table.append([k, round(result, 2)])

df = pd.DataFrame(
    table, columns=['N', 'Evaluated value using N+1 point Gaussian Quadrature'])
print(df)

ans, _ = quad(getFuncVal, 0, pi/2)
print("The actual value of the integral is", ans)

Semester 6/MA 322 (Scientific Computing Theory)/Labs/Lab 5/Code/q6.py

import numpy,from scipy,import sympy,from sympy


import unittest
import numpy as np
from  cuddlyguacamole import lennardjones
from  cuddlyguacamole import neighbourlist
import numpy.testing as npt

r_cut = 2.5
r_skin = 1.3
positions = np.array([[ 2.90956646, 2.15152179, 3.65165442],[ 3.68121774, 0.18314957, 3.73834638],[ 1.14410085, 4.85833454, 2.95269129],[ 0.78264966, 3.65091237, 1.03486635]])
neighbour_list = neighbourlist.create_verlet_list(positions, r_cut, r_skin)

class TestLennardJones(unittest.TestCase):

	def test_lennard_jones_ij(self):
		r = np.linalg.norm(positions[1] - positions[0])
		self.assertEqual(lennardjones.lennard_jones_ij(r, r_cut), -0.044065854914534311)

	def test_lennard_jones_ij2(self):
		r = np.linalg.norm(positions[0] - positions[3])
		self.assertEqual(lennardjones.lennard_jones_ij(r, r_cut), 0.0)

	def test_calculate_potential(self):
		self.assertEqual(lennardjones.calculate_potential(positions, neighbour_list), -0.071261145028207878)

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


# -*- coding: utf-8 -*-
"""
Spyder Editor

Authot: Lama Hamadeh 28/11/2016

This file is to create a 6-D parallel coordinate chart for x=[0, 2pi] and the relations with its sin, cos, tan, exp, sqrt and sqruare values.

*Still working on it!*
"""

import pandas as pd
import math
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
from pandas.tools.plotting import parallel_coordinates
matplotlib.style.use('ggplot')

x=np.arange(0,np.pi*2,np.pi/40)
#print(x)

#Constructing dataframe
data = {'x':x,
        '-x':-x,
        'Sin(x)':np.sin(x),
        'Cos(x)': np.cos(x),
        'Tan(x)': np.tan(x),
        'exp(x)': np.exp(x),
        'Square(x)': x*x,
        'Sqrt(x)': np.sqrt(x)} #python arange the columns alphabetically
df = pd.DataFrame(data, index=None) #without the index there will be an index column starting from 0
print(df)

#Playing with plots and subplots before going to parallel coordinates
plt.figure(1)
plt.subplot(311)
plt.plot(x,np.sin(x),'b', linewidth=2.0)
plt.xlabel('x')
plt.ylabel('Sin(x)')
plt.grid(False)
plt.xticks([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi],
           ['$0$', r'$\frac{\pi}{2}$', r'$\pi$', r'$\frac{3\pi}{2}$', r'$2\pi$'])

plt.subplot(312)
plt.plot(x,np.cos(x),'r', linewidth=2.0)
plt.xlabel('x')
plt.ylabel('Cos(x)')
plt.grid(False)
plt.xticks([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi],
           ['$0$', r'$\frac{\pi}{2}$', r'$\pi$', r'$\frac{3\pi}{2}$', r'$2\pi$'])

plt.subplot(313)
plt.plot(x,np.tan(x),'g', linewidth=2.0)
plt.xlabel('x')
plt.ylabel('Tan(x)')
plt.grid(False)
plt.xticks([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi],
           ['$0$', r'$\frac{\pi}{2}$', r'$\pi$', r'$\frac{3\pi}{2}$', r'$2\pi$'])

plt.show()

plt.plot(x,np.sin(x),'b',x,np.cos(x),'r', linewidth=2.0)
plt.xlabel('x')
plt.ylabel('Cos(x) (in red) and Sin(x) (in blue)')
plt.xticks([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi],
           ['$0$', r'$\frac{\pi}{2}$', r'$\pi$', r'$\frac{3\pi}{2}$', r'$2\pi$'])

plt.show()

#Here we go!
plt.figure()
parallel_coordinates(df,'x',alpha= 0.4)
plt.show()


from mpl_toolkits import mplot3d
import numpy as np
import matplotlib.pyplot as plt

def simple_3d():
    fig = plt.figure()
    ax = plt.axes(projection='3d')
    zline = np.linspace(0, 15, 1000)
    xline = np.sin(zline)
    yline = np.cos(zline)
    ax.plot3D(xline, yline, zline, 'gray')

    # Data for three-dimensional scattered points
    zdata = 15 * np.random.random(100)
    xdata = np.sin(zdata) + 0.1 * np.random.randn(100)
    ydata = np.cos(zdata) + 0.1 * np.random.randn(100)
    ax.scatter3D(xdata, ydata, zdata, c=zdata, cmap='Greens');

    plt.show()

def f(x, y):
    return np.sin(np.sqrt(x ** 2 + y ** 2))

def color_3d():
    x = np.linspace(-6, 6, 30)
    y = np.linspace(-6, 6, 30)
    X, Y = np.meshgrid(x, y)
    Z = f(X, Y)
    fig = plt.figure()

    ax = plt.axes(projection='3d')
    ax.contour3D(X, Y, Z, 50, cmap='binary')
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_zlabel('z')
    ax.view_init(60, 35)
    plt.show()

def wireframes():
    x = np.linspace(-6, 6, 30)
    y = np.linspace(-6, 6, 30)
    X, Y = np.meshgrid(x, y)
    Z = f(X, Y)
    fig = plt.figure()
    ax = plt.axes(projection='3d')
    ax.plot_wireframe(X, Y, Z, color='black')
    ax.set_title('wireframe');

    ax = plt.axes(projection='3d')
    ax.plot_surface(X, Y, Z, rstride=1, cstride=1,
                    cmap='viridis', edgecolor='none')
    ax.set_title('surface');
    r = np.linspace(0, 6, 20)
    theta = np.linspace(-0.9 * np.pi, 0.8 * np.pi, 40)
    r, theta = np.meshgrid(r, theta)

    X = r * np.sin(theta)
    Y = r * np.cos(theta)
    Z = f(X, Y)

    ax = plt.axes(projection='3d')
    ax.plot_surface(X, Y, Z, rstride=1, cstride=1,
                    cmap='viridis', edgecolor='none')
    plt.show()

def surface_triangulations():
    theta = 2 * np.pi * np.random.random(1000)
    r = 6 * np.random.random(1000)
    x = np.ravel(r * np.sin(theta))
    y = np.ravel(r * np.cos(theta))
    z = f(x, y)
    ax = plt.axes(projection='3d')
    ax.scatter(x, y, z, c=z, cmap='viridis', linewidth=0.5)
    ax = plt.axes(projection='3d')
    ax.plot_trisurf(x, y, z, cmap='viridis', edgecolor='none')
    plt.show()

def visualize_mobius_strip():
    theta = np.linspace(0, 2 * np.pi, 30)
    w = np.linspace(-0.25, 0.25, 8)
    w, theta = np.meshgrid(w, theta)
    phi = 0.5 * theta
    # radius in x-y plane
    r = 1 + w * np.cos(phi)

    x = np.ravel(r * np.cos(theta))
    y = np.ravel(r * np.sin(theta))
    z = np.ravel(w * np.sin(phi))

    # triangulate in the underlying parametrization
    from matplotlib.tri import Triangulation
    tri = Triangulation(np.ravel(w), np.ravel(theta))

    ax = plt.axes(projection='3d')
    ax.plot_trisurf(x, y, z, triangles=tri.triangles, cmap='viridis', linewidths=0.2);

    ax.set_xlim(-1, 1); ax.set_ylim(-1, 1); ax.set_zlim(-1, 1)
    plt.show()

if __name__ == '__main__':
    print('Numpy Version:', np.__version__)
    # simple_3d()
    # color_3d()
    # wireframes()
    # surface_triangulations()
    visualize_mobius_strip()


import numpy as np

def poly_to_polycr(line_fit, ploty, ym_per_pix, xm_per_pix):
    ### Calc both polynomials using ploty, left_fit and right_fit ###
    if line_fit is None:
        return None

    line_fitx = line_fit[0] * ploty ** 2 + line_fit[1] * ploty + line_fit[2]
    line_fit_cr = np.polyfit(ploty * ym_per_pix, line_fitx * xm_per_pix, 2)
    return line_fit_cr

def measure_real_world_curvature_for_line(line_fit, ploty, ym_per_pix=30 / 720, xm_per_pix=3.7 / 700):
    '''
    Calculates the curvature of polynomial functions in meters.
    '''
    # Define y-value where we want radius of curvature
    # We'll choose the maximum y-value, corresponding to the bottom of the image
    y_eval = np.max(ploty)

    line_fit_cr = poly_to_polycr(line_fit, ploty, ym_per_pix, xm_per_pix)
    if line_fit_cr is None:
        return None
    curvature = (((1 + (2 * line_fit_cr[0] * y_eval * ym_per_pix + line_fit_cr[1]) ** 2) ** 1.5)
                 / np.absolute(2 * line_fit_cr[0]))
    return curvature

def avg_curvature(left_curvature, right_curvature):
    if left_curvature is not None and right_curvature is not None:
        return np.mean([left_curvature, right_curvature])
    elif left_curvature is not None and right_curvature is None:
        return left_curvature
    elif left_curvature is None and right_curvature is not None:
        return right_curvature
    else:
        # print('no curvature found')
        return None

def measure_real_world_curvature_for_road(left_fit, right_fit, ploty, ym_per_pix=30 / 720, xm_per_pix=3.7 / 700):
    '''
    Calculates the curvature of polynomial functions in meters.
    '''
    # Calculation of R_curve (radius of curvature)
    left_curvature, right_curvature = None, None
    if left_fit is not None:
        left_curvature = measure_real_world_curvature_for_line(left_fit, ploty, ym_per_pix, xm_per_pix)
    if right_fit is not None:
        right_curvature = measure_real_world_curvature_for_line(right_fit, ploty, ym_per_pix, xm_per_pix)

    return avg_curvature(left_curvature, right_curvature)

def measure_mid_position(left_fit, right_fit, ploty, std_mid=660, imgsize_x=1200, xm_per_pix=3.7 / 700):
    y_eval = np.max(ploty)
    # find mid point
    leftx = left_fit[0] * y_eval ** 2 + left_fit[1] * y_eval + left_fit[2] if left_fit is not None else 0
    rightx = right_fit[0] * y_eval ** 2 + right_fit[1] * y_eval + right_fit[2] if right_fit is not None else imgsize_x

    current_mid_pix = (leftx + rightx) / 2
    to_mid_of_line = (std_mid - current_mid_pix) * xm_per_pix
    return to_mid_of_line


import math
from functools import partial

import numpy as np
import scipy

import jax
import jax.numpy as jnp
from jax import random
from jax import jit

from .norm import normalize_l2_cw
from .util import promote_arg_dtypes
from .array import hermitian

def gaussian_mtx(key, N, D, normalize_atoms=True):
    """A dictionary/sensing matrix where entries are drawn independently from normal distribution.

    Args:
        key: a PRNG key used as the random key.
        N (int): Number of rows of the sensing matrix
        D (int): Number of columns of the sensing matrix
        normalize_atoms (bool): Whether the columns of sensing matrix are normalized
          (default True)

    Returns:
        (jax.numpy.ndarray): A Gaussian sensing matrix of shape (N, D)

    Example:

        >>> from jax import random
        >>> import cr.nimble as cnb
        >>> m, n = 8, 16
        >>> Phi = cnb.gaussian_mtx(random.PRNGKey(0), m, n)
        >>> print(Phi.shape)
        (8, 16)
        >>> print(cnb.norms_l2_cw(Phi))
        [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
    """
    shape = (N, D)
    dict = random.normal(key, shape)
    if normalize_atoms:
        dict = normalize_l2_cw(dict)
    else:
        sigma = math.sqrt(N)
        dict = dict / sigma
    return dict

def _pascal_lower(n):
    A = jnp.empty((n, n), dtype=jnp.int32)
    A = A.at[0, :].set(0)
    A = A.at[:, 0].set(1)
    for i in range(1, n):
        for j in range(1, i+1):
            A = A.at[i, j].set(A[i-1, j] + A[i-1, j-1])
    return A

def _pascal_sym(n):
    A = jnp.empty((n, n), dtype=jnp.int32)
    A = A.at[0, :].set(1)
    A = A.at[:, 0].set(1)
    for i in range(1, n):
        for j in range(1, n):
            A = A.at[i, j].set(A[i-1, j] + A[i, j-1])
    return A

def pascal(n, symmetric=False):
    """Returns a pascal matrix of size n \times n
    """
    if symmetric:
        return _pascal_sym(n)
    else:
        return _pascal_lower(n)

pascal_jit = jax.jit(pascal, static_argnums=(0, 1))

import numpy,import scipy,import jax,from jax


import numpy as np

def pairwise_distances(p, q):
    first_term = np.einsum('ij->i', p ** 2)  # sum along dimension
    second_term = np.einsum('ij->i', q ** 2)  # sum along dimension
    third_term = np.einsum('ik,jk->ij', p, q)  # pairwise product
    squared_distances = first_term[:, None] + second_term
    squared_distances -= 2 * third_term

    # Ignore numerical error
    squared_distances[squared_distances < 1e-10] = 0

    return np.sqrt(squared_distances)


from time import time
import matplotlib
#this will prevent the figure from popping up
matplotlib.use('Agg')
from matplotlib import pyplot as plt
import numpy as np
import pycuda.autoinit
from pycuda import gpuarray
from pycuda.elementwise import ElementwiseKernel

# first string: the input, pycuda::complex<float> is a special type from pycuda
mandel_ker = ElementwiseKernel(
"pycuda::complex<float> *lattice, float *mandelbrot_graph, int max_iters, float upper_bound",
"""
mandelbrot_graph[i] = 0;

pycuda::complex<float> c = lattice[i];
pycuda::complex<float> z(0,0);

for (int j = 0; j < max_iters; j++)
    {

     z = z*z + c;

     if(abs(z) > 1000)
         {
          mandelbrot_graph[i] = j;
          break;
         }

    }

""",
"mandel_ker")

def gpu_mandelbrot(width, height, real_low, real_high, imag_low, imag_high, max_iters, upper_bound):

    # we set up our complex lattice as such, matrix not supported by pycuda
    real_vals = np.matrix(np.linspace(real_low, real_high, width), dtype=np.complex64)
    imag_vals = np.matrix(np.linspace(imag_high, imag_low, height), dtype=np.complex64) * 1j

    # put them on top of each other
    mandelbrot_lattice = np.array(real_vals + imag_vals.transpose(), dtype=np.complex64)

    # copy complex lattice to the GPU
    mandelbrot_lattice_gpu = gpuarray.to_gpu(mandelbrot_lattice)

    # allocate an empty array on the GPU
    mandelbrot_graph_gpu = gpuarray.empty(shape=mandelbrot_lattice.shape, dtype=np.float32)

    mandel_ker(mandelbrot_lattice_gpu, mandelbrot_graph_gpu, np.int32(max_iters), np.float32(upper_bound))

    mandelbrot_graph = mandelbrot_graph_gpu.get()

    return mandelbrot_graph

if __name__ == '__main__':

    t1 = time()
    mandel = gpu_mandelbrot(4096,4096,-2,2,-2,2,1024, 2)
    t2 = time()

    mandel_time = t2 - t1

    t1 = time()
    fig = plt.figure(1)
    plt.imshow(mandel, vmin=0, vmax=15)
    plt.savefig('mandelbrot.png', dpi=fig.dpi)
    t2 = time()

    dump_time = t2 - t1

    print('It took {} seconds to calculate the Mandelbrot graph.'.format(mandel_time))
    print('It took {} seconds to dump the image.'.format(dump_time))


#!/usr/bin/python
"""
File: fit_pendulum_data

Copyright (c) 2016 Michael Seaman

License: MIT

Gets data about a pendulum and fits it using the numpy
polynomial approximator
"""
import numpy as np
import matplotlib.pyplot as plt

def retrieve_pendulum_data(filename = "pendulum.dat"):
    """
    Gets pendulum data from filename and outputs a 2d list of
    output[0] = L and output[1] = T
    """
    L_list = []
    T_list = []
    with open(filename, 'r') as infile:
        for line in infile:
            data = line.split()
            try:
                L_list.append(float(data[0]))
                T_list.append(float(data[1]))
            except ValueError:
                pass

    infile.close()
    return [L_list, T_list]

def pendulum_fit(L, T, degree):
    """
    Outputs the original list of lengths and a list of period variables as given by the fitted function T(L)
    """
    coeff = np.polyfit(L, T, degree)
    p = np.poly1d(coeff)
    print "Fitted Curve of degree {0}: ".format(degree)
    print p
    return [L,p(L)]


# loss function常用的一种交叉熵函数cross_entropy_error, E = -(for k in range(len(y) np.sum(np.log(y) * t))
import numpy as np

def cross_entropy_error(y, t):
    delta = 1e-7  #定一个非常小的theta主要用于防止np.log(0)变为-inf，导致后面的数据无法正常计算
    return -(np.sum(t * np.log(y + delta)))

# 人为设定test label为2，即当前标签为digit 2
t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]

# example 1
# y1中代表softmax predict 从0～9的概率
y1 = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]
print('y1: ', cross_entropy_error(np.array(y1), np.array(t)))

# example 2
y2 = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]
print('y2: ', cross_entropy_error(np.array(y2), np.array(t)))

'''
cross entropy error
由于t中的数据除了正确标签为1， 其余标签都为0，所以cross entropy error计算的是对应的正确标签的自然对数
由于对数函数log的性质，x = 1时， 由= 0， 随着x靠近0，y逐渐变小，由于cross entropy error带上负号，所以越接近0，误差越大
'''


#  in console run py -m pip install matplotlib
import matplotlib.pyplot as plt
import numpy as np

# x = np.linspace(0, 20, 100)  # Create a list of evenly-spaced numbers over the range
# plt.plot(x, np.sin(x))       # Plot the sine of each x point
# plt.show()                   # Display the plot

print("S")

h  = [1.7, 1.8]
w = [70, 73]

print(h)

np_h  = np.array(h)
np_w = np.array(w)

bmi = np_w / np_h ** 2

print(bmi)
print(bmi[0])
print(bmi[1])

print(bmi[bmi > 23])

print(type(bmi))

print("end")

nn = np.array([0,1,2,3,4,5])
mm = nn[2:4]
print(mm)

print(type(nn))

np_all = np.array([h,w])

print(np_all)

print(np_all[0,0])
print(np_all[:,0])

print("ssssssss")
x = np.array([[1, 2, 3],
              [1, 2, 3]])
y = np.array([[1, 1, 1],
              [1, 2, 3]])

print(x)
print(y)
z = x - y

print(z)

print ("xxxx")
baseball = [[180, 78.4],
            [215, 102.7],
            [210, 98.5],
            [188, 75.2]]

np_baseball = np.array(baseball)

print(np_baseball.shape)