#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Nov 10 13:18:53 2020

Copyright 2020 by Hadrien Montanelli.
"""
# Standard library imports:
import numpy as np

def mtcarlo(f, domain, N=1000):
    """Monte Carlo integrtion of a function on a rectangular domain.

    Input
    -----
    f : function
        The function to integrate.

    domain : numpy array
        A rectangluar domain as a (2*d)x1 array in dimenion d.

    N : int
        The number of sample points.

    Output
    ------
    output ; float
        The approximate value of the integral.

    Example
    -------
    This is an example in 2d.

        import numpy as np
        from learnpy.misc import montecarlo

        f = lambda x: x[0]**2*np.cos(x[1])
        dom = np.array([0, 2, -1, 1])
        I = montecarlo(f, dom)

    See also the 'example_montecarlo' file.

    """
    # Get the dimension:
    d = int(len(domain)/2)

    # Compute the volume of the domain:
    V = 1
    for j in range(d):
        V *= domain[2*j+1] - domain[2*j]

    # Sample the domain uniformly:
    points = np.zeros([N, d])
    for i in range(N):
        for j in range(d):
            a = domain[2*j]
            b = domain[2*j+1]
            points[i, j] = a + (b - a)*np.random.uniform()

    # Compute the integral:
    S = 0
    for point in points:
        S += f(point)
    I = V/N*S

    return I


import numpy as np

a = np.arange(5)
b = np.arange(5, 10)
print(a, b)

# 1.
print(np.add(a, b))

# 2.
print(np.sum([a, b]))

print(np.sum([a, b], axis=1))

print(np.sum([a, b], axis=0))

# 3.
print(np.cumsum(a))
print(np.cumsum(b))


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Mar 18 18:59:42 2021

@author: jonathan
"""

import numpy as np
from numpy.random import default_rng
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator

# compute the RODFT00 as defined in the FFTW reference manual
def rodft00(arr):
    n = len(arr)
    out = np.zeros([n])
    for k in range(n):
        for j in range(n):
            out[k] += 2.0 * arr[j] * np.sin(np.pi*(j+1)*(k+1)/(n+1))
    return out

# compute the RODFT10 as defined in the FFTW reference manual
def rodft10(arr):
    n = len(arr)
    out = np.zeros([n])
    for k in range(n):
        for j in range(n):
            out[k] += 2.0 * arr[j] * np.sin(np.pi*(j+0.5)*(k+1)/n)
    return out

# compute the RODFT01 as defined in the FFTW reference manual
def rodft01(arr):
    n = len(arr)
    out = np.zeros([n])
    for k in range(n):
        out[k] += (-1)**k * arr[-1]
        for j in range(n-1):
            out[k] += 2.0 * arr[j] * np.sin(np.pi*(j+1)*(k+0.5)/n)
    return out

# compute the RODFT11 as defined in the FFTW reference manual
def rodft11(arr):
    n = len(arr)
    out = np.zeros([n])
    for k in range(n):
        for j in range(n):
            out[k] += 2.0 * arr[j] * np.sin(np.pi*(j+0.5)*(k+0.5)/n)
    return out

# evaluate the RODFT00 at all points given in x
def eval_rodft00(arr, x):
    n = len(arr)
    y = np.zeros_like(x)
    for j in range(n):
        y += 2.0*arr[j]*np.sin(np.pi*(j+1)*(x+1/(n+1)))
    return y

# evaluate the RODFT10 at all points given in x
def eval_rodft10(arr, x):
    n = len(arr)
    y = np.zeros_like(x)
    for j in range(n):
        y += 2.0*arr[j]*np.sin(np.pi*(j+0.5)*(x+1/n))
    return y

# evaluate the RODFT01 at all points given in x
def eval_rodft01(arr, x):
    n = len(arr)
    y = np.zeros_like(x)
    for j in range(n-1):
        y += 2.0*arr[j]* np.sin(np.pi*(j+1)*(x+0.5/n))
    y += arr[-1]* np.sin(np.pi*n*(x+0.5/n))
    return y

# evaluate the RODFT11 at all points given in x
def eval_rodft11(arr, x):
    n = len(arr)
    y = np.zeros_like(x)
    for j in range(n):
        y += 2.0*arr[j]*np.sin(np.pi*(j+0.5)*(x+0.5/n))
    return y

#%% RODFT00

# input size for RODFT00
n = 3

# logical size of equivalent DFT (for RODFT00)
N = 2*(n+1)

# random Fourier coefficients
rng = default_rng(seed=42)
r2r_out = rng.uniform(size=n)

# compute input of RODFT00 by RODFT00 (the inverse of RODFT00)
r2r_in = rodft00(r2r_out)/n

# extend to left for highlighting symmetry at start of array
left_in_x = np.arange(-N+n, 0)
left_in_y = np.zeros([N-n])
for i in range(n):
    # odd symmetry around -1
    left_in_y[-i-2] = -r2r_in[i]

# extend to equivalent DFT size to highlight symmetry at end of array
full_in_x = np.arange(n, N)
full_in_y = np.zeros([N-n])
for i in range(n):
    # even symmetry around n-1
    full_in_y[i+1] = -r2r_in[-i-1]

# sample at finer intervals
nFine = 1024
x = np.linspace(-N/2, N, nFine)
y = eval_rodft00(r2r_out, x/(n+1))/n

plt.figure(figsize=(5,3))

plt.plot(x, y, '-', color='gray', linewidth=0.5)
plt.axhline(0, ls='-', color='k')
plt.axvline(0, ls='-', color='k')

# symmetry lines
plt.axvline(-1, ls='--', color='b')
plt.axvline(n, ls='--', color='b')

# highlight array contents
plt.axvspan(0-0.25, (n-1)+0.25, alpha=0.3, color='gray')

# plot actual RODFT00 input
plt.plot(r2r_in, 'bo')

# label individual points
for i in range(n):
    plt.text(i+0.2, r2r_in[i]-0.13, chr(ord("a")+i))
plt.text(-1+0.2, 0.0+0.05, "0")

plt.plot(left_in_x, left_in_y, 'bo')

# plot data extending REDFT00 to full DFT
plt.plot(full_in_x, full_in_y, 'bo')

plt.text(full_in_x[0]+0.2, full_in_y[0]+0.05, "0")
for i in range(1,n+1):
    plt.text(full_in_x[i]+0.2, full_in_y[i]+0.07, "-"+chr(ord("a")+(n-i)))
plt.text(full_in_x[-1]+0.2, full_in_y[-1]+0.05, "0")

# only integer xaxis ticks at intervals of 1
plt.gca().xaxis.set_major_locator(MaxNLocator(steps=(1,10), integer=True))
plt.xlim((-4.5, 8.5))

plt.grid(True)
plt.xlabel("j")
plt.title("RODFT00 N=%d n=%d"%(N, n))
plt.tight_layout()
plt.savefig("rodft00.png")

#%% RODFT10
n = 4

# logical size of equivalent DFT (for RODFT10)
N = 2*n

# random Fourier coefficients
rng = default_rng(seed=41)
r2r_out = rng.uniform(size=n)

# compute input of RODFT10 by using RODFT01 (the inverse of RODFT10)
r2r_in = rodft01(r2r_out)/n

# extend to left for highlighting symmetry at start of array
left_in_x = np.arange(-n, 0)
left_in_y = np.zeros([n])
for i in range(n):
    # odd symmetry around -0.5
    left_in_y[i] = -r2r_in[-i-1]

# extend to equivalent DFT size for highlighting symmetry at end of array
full_in_x = np.arange(n, N)
full_in_y = np.zeros([N-n])
for i in range(N-n):
    # odd symmetry around n-0.5
    full_in_y[i] = -r2r_in[-i-1]

# sample "inputs" at finer intervals
nFine = 1024
x = np.linspace(-n, N, nFine)
y = eval_rodft01(r2r_out, x/n)/n

plt.figure(figsize=(5,3))

plt.plot(x, y, '-', color='gray', linewidth=0.5)

plt.axhline(0, ls='-', color='k')
plt.axvline(0, ls='-', color='k')

# symmetry lines
plt.axvline(-0.5, ls='--', color='b')
plt.axvline(n-0.5, ls='--', color='b')

# highlight array contents
plt.axvspan(0-0.25, (n-1)+0.25, alpha=0.3, color='gray')

plt.plot(r2r_in, 'bo')

# label individual points
for i in range(n-1):
    plt.text(i+0.2, r2r_in[i]-0.03, chr(ord("a")+i))
plt.text(n-1-0.6, r2r_in[n-1]-0.03, chr(ord("a")+n-1))

plt.plot(left_in_x, left_in_y, 'bo')

plt.plot(full_in_x, full_in_y, 'bo')

for i in range(n):
    plt.text(full_in_x[i]+0.2, full_in_y[i]-0.03, "-"+chr(ord("a")+(n-1-i)))

# only integer xaxis ticks
plt.gca().xaxis.set_major_locator(MaxNLocator(steps=(1,10), integer=True))
plt.xlim((-4.5, 8.5))

plt.grid(True)
plt.xlabel("j")
plt.title("RODFT10 N=%d n=%d"%(N, n))
plt.tight_layout()
plt.savefig("rodft10.png")

#%% RODFT01
n = 4

# logical size of equivalent DFT (for RODFT01)
N = 2*n

# random Fourier coefficients
rng = default_rng(seed=42)
r2r_out = rng.uniform(size=n)

# compute input of RODFT01 by using RODFT10 (the inverse of RODFT01)
r2r_in = rodft10(r2r_out)/n

# extend to left for highlighting symmetry at start of array
left_in_x = np.arange(-n, 0)
left_in_y = np.zeros([n])
for i in range(n-1):
    # odd symmetry around -1
    left_in_y[-i-2] = -r2r_in[i]

# extend to equivalent DFT size for highlighting symmetry at end of array
full_in_x = np.arange(n, N)
full_in_y = np.zeros([N-n])
for i in range(N-n-1):
    # even symmetry around n-1
    full_in_y[i] = r2r_in[-i+2]

# sample "inputs" at finer intervals
nFine = 1024
x = np.linspace(-n, N, nFine)
y = eval_rodft10(r2r_out, x/n)/n

plt.figure(figsize=(5,3))

plt.plot(x, y, '-', color='gray', linewidth=0.5)

plt.axhline(0, ls='-', color='k')
plt.axvline(0, ls='-', color='k')

# symmetry lines
plt.axvline(-1, ls='--', color='b')
plt.axvline(n-1, ls='--', color='r')

# highlight array contents
plt.axvspan(0-0.25, (n-1)+0.25, alpha=0.3, color='gray')

plt.plot(r2r_in, 'bo')

# label individual points
i=0
plt.text(i+0.2, r2r_in[i]-0.03, chr(ord("a")+i))
for i in range(1,n):
    plt.text(i-0.5, r2r_in[i]-0.03, chr(ord("a")+i))

plt.plot(left_in_x, left_in_y, 'bo')

plt.plot(full_in_x, full_in_y, 'bo')

for i in range(n-1):
    plt.text(full_in_x[i]+0.2, full_in_y[i]-0.03, chr(ord("a")+(n-2-i)))
plt.text(full_in_x[-1]+0.2, full_in_y[-1]+0.03, "0")

# only integer xaxis ticks
plt.gca().xaxis.set_major_locator(MaxNLocator(steps=(1,10), integer=True))
plt.xlim((-4.5, 8.5))

plt.grid(True)
plt.xlabel("j")
plt.title("RODFT01 N=%d n=%d"%(N, n))
plt.tight_layout()
plt.savefig("rodft01.png")

#%% RODFT11

# input size for RODFT11
n = 4

# logical size of equivalent DFT (for RODFT11)
N = 2*n

# random Fourier coefficients
rng = default_rng(seed=40)
r2r_out = rng.uniform(size=n)

# compute input of RODFT11 by RODFT11 (the inverse of RODFT11)
r2r_in = rodft11(r2r_out)/n

# extend to left for highlighting symmetry at start of array
left_in_x = np.arange(-n, 0)
left_in_y = np.zeros([n])
for i in range(n):
    # odd symmetry around -0.5
    left_in_y[i] = -r2r_in[-i-1]

# extend to equivalent DFT size to highlight symmetry at end of array
full_in_x = np.arange(n, N)
full_in_y = np.zeros([N-n])
for i in range(N-n):
    # even symmetry around n-0.5
    full_in_y[i] = r2r_in[-i-1]

# sample at finer intervals
nFine = 1024
x = np.linspace(-n, N, nFine)
y = eval_rodft11(r2r_out, x/n)/n

plt.figure(figsize=(5,3))

plt.plot(x, y, '-', color='gray', linewidth=0.5)
plt.axhline(0, ls='-', color='k')
plt.axvline(0, ls='-', color='k')

# symmetry lines
plt.axvline(-0.5, ls='--', color='b')
plt.axvline(n-0.5, ls='--', color='r')

# highlight array contents
plt.axvspan(0-0.25, (n-1)+0.25, alpha=0.3, color='gray')

# plot actual RODFT11 input
plt.plot(r2r_in, 'bo')

# label individual points
for i in range(n-1):
    plt.text(i+0.2, r2r_in[i]-0.05, chr(ord("a")+i))
i=n-1
plt.text(i-0.5, r2r_in[i]-0.03, chr(ord("a")+i))

plt.plot(left_in_x, left_in_y, 'bo')

# plot data extending REDFT11 to full DFT
plt.plot(full_in_x, full_in_y, 'bo')

for i in range(N-n):
    plt.text(full_in_x[i]+0.2, full_in_y[i]-0.05, chr(ord("a")+(n-1-i)))

# only integer xaxis ticks at intervals of 1
plt.gca().xaxis.set_major_locator(MaxNLocator(steps=(1,10), integer=True))
plt.xlim((-4.5, 8.5))

plt.grid(True)
plt.xlabel("j")
plt.title("RODFT11 N=%d n=%d"%(N, n))
plt.tight_layout()
plt.savefig("rodft11.png")


# NUMPY MANIPULATIONS OF ARRAYS
# Santiago Garcia Arango
# -------------------------------------------------------------------------
import numpy as np

my_array = np.arange(1, 11)  # [1,2,..,8,9,10]
print("my_array=\n", my_array, "\n")

# -----------------CHECKING CONDITIONS IN ARRAY ITEMS----------------------
# FIRST WAY...
# This is how we show boolean result of a desired condition of an array
boolean_array = my_array > 5
print("my_array > 5 --> ", boolean_array, "\n")
# We can take advantage of the boolean_array, by calling the main array...
# ..."evaluated" in the True statements of the boolean_array.
# This will give us only the original array where the conditions are True
print("my_array[boolean_array] = ", my_array[boolean_array], "\n")

# SECOND WAY...
# This previous two step process is usually done in one step!!!
# Remark: This is the most common way to to this!!!
print("my_array[my_array>5] = ", my_array[my_array > 5], "\n")

# -----------------------CREATE MATRICES EASIER----------------------------
# Example: create this matrix:
# 1 1 1 1 1
# 1 0 0 0 1
# 1 0 9 0 1
# 1 0 0 0 1
# 1 1 1 1 1

cool_matrix = np.ones((5, 5))
cool_matrix[1:4, 1:4] = 0
cool_matrix[2, 2] = 9
print("cool_matrix:\n", cool_matrix, "\n")


# 勾配: すべての変数の偏微分をベクトルとしてまとめたもの
# 勾配降下法: 勾配法で最小値を探す
import numpy as np
import copy

# 勾配の対象とする数式
def function_2(x):
#    print("x -> " + str(x))
    return x[0]**2 + x[1]**2

# 勾配の計算
def numerical_gradient(f, x):
    h = 1e-4
    grad = np.zeros_like(x) # xと同じ形状の配列を生成

    # 変数ごとに数値微分の計算
    for idx in range(x.size):
        tmp_val = x[idx]

        # f(x+h)の計算
        x[idx] = tmp_val + h
        fxh1 = f(x)
#        print("fxh1 -> " + str(fxh1))

        # f(x-h)の計算
        x[idx] = tmp_val - h
        fxh2 = f(x)
#        print("fxh2 -> " + str(fxh2))

        grad[idx] = (fxh1 - fxh2) / (2*h)
#        print("fxh1 - fxh2 -> " + str(fxh1 - fxh2))
#        print("2*h -> " + str(2*h))
        x[idx] = tmp_val # 値を元に戻す

#        print("------------")
    return grad

# 勾配のテスト計算
print("----- 勾配のテスト計算 -----")
print(numerical_gradient(function_2, np.array([3.0, 4.0]))) # array([6., 8.])

# 勾配降下法
# - f : 最適化したい関数
# - init_x : 初期値
# - lr : Learning rate 学習率
# - step_num : 勾配法による繰り返しの数
def gradient_descent(f, init_x, lr=0.01, step_num=100):
    x = copy.deepcopy(init_x)
    for i in range(step_num):
        grad = numerical_gradient(f, x)
        x -= lr * grad

    print("init_x -> " + str(init_x) + ", lr -> " + str(lr) + ", step_num -> " + str(step_num))
    print("  result : " + str(x))
    return x

print("----- 勾配降下法のテスト計算 -----")
init_x = np.array([-3.0, 4.0])
gradient_descent(function_2, init_x=init_x, lr=0.1, step_num=100)

print("----- 学習率が大きすぎる例 -----")
init_x = np.array([-3.0, 4.0])
gradient_descent(function_2, init_x=init_x, lr=10.0, step_num=100)

print("----- 学習率が小さすぎる例 -----")
init_x = np.array([-3.0, 4.0])
gradient_descent(function_2, init_x=init_x, lr=1e-10, step_num=100)


from numpy import linalg
import numpy as np
import matplotlib.pyplot as plt

img = plt.imread('horse.jpg')

img_rescaled = img / 255

img_gray = img_rescaled @ [0.2126, 0.7152, 0.0722]

U, s, Vt = linalg.svd(img_gray)

Sigma = np.zeros((U.shape[1], Vt.shape[0]))
np.fill_diagonal(Sigma, s)

if __name__ == '__main__':
    # Print shape of the diagonal matrix:
    print(Sigma.shape)
    # Print the norm of the difference between img_gray and the reconstructed SVD product:
    print(linalg.norm(img_gray - U @ Sigma @ Vt))
    # Check if the reconstructed product is close to the original matrix
    print(np.allclose(img_gray, U @ Sigma @ Vt))


import numpy as np
import math
import random
import matplotlib.pyplot as plt
#%matplotlib inline
square_size = 1
points_inside_circle = 0
points_inside_square = 0
sample_size = 1000
arc = np.linspace(0, np.pi/2, 100)

def generate_points(size):
    x = random.random() * size
    y = random.random() * size
    return x, y

def is_inside_circle(point, size):
    return math.sqrt(point[0]**2 + point[1]**2) <= size

def compute_pi(points_inside_circle, points_inside_square):
    return 4 * (points_inside_circle / points_inside_square)

plt.axes().set_aspect('equal')
plt.plot(1*np.cos(arc), 1*np.sin(arc))

for i in range(sample_size):
    point = generate_points(square_size)
    plt.plot(point[0],point[1],'c.')
    points_inside_square+=1
    if is_inside_circle(point, square_size):
        points_inside_circle += 1

print(compute_pi(points_inside_circle,points_inside_square))
plt.show()


#!usr/bin/env python
#-*- coding:utf-8 _*-
"""
@author:yaoli
@file: 03_lin_reg_tensorflow_way.py
@time: 2019/01/01
"""

import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
from sklearn import datasets
from tensorflow.python.framework import ops
ops.reset_default_graph()

sess = tf.Session()

# Load the data 导入鸢尾花数据集
# iris data = [(Sepal Length, Sepal Width, Petal Length, Petal Width)]
iris = datasets.load_iris()
x_vals = np.array([x[3] for x in iris.data])
y_vals = np.array([y[0] for y in iris.data])

# Declare batch size
batch_size = 25

# Initialize placeholders
x_data = tf.placeholder(shape=[None,1], dtype=tf.float32)
y_target = tf.placeholder(shape=[None,1], dtype=tf.float32)

# Create variables for linear regression
A = tf.Variable(tf.random_normal(shape=[1,1]))
b = tf.Variable(tf.random_normal(shape=[1,1]))

# Declare model operations 声明模型操作
model_output = tf.add(tf.matmul(x_data, A), b)

# Declare loss function (L2 loss)
loss = tf.reduce_mean(tf.square(y_target - model_output))

# We have to tell TensorFlow how to optimize and back propagate the gradients. We do this with the standard Gradient Descent operator (tf.train.GradientDescentOptimizer), with the learning rate argument of  0.05
# Then we initialize all the model variables.

# Declare optimizer
my_opt = tf.train.GradientDescentOptimizer(0.05)
train_step = my_opt.minimize(loss)

# Initlialize variables
init = tf.global_variables_initializer()
sess.run(init)

# We start our training loop and run the optimizer for 100 iterations
# Training loop
loss_vec = []
for i in range(100):
    rand_index = np.random.choice(len(x_vals), size=batch_size)
    rand_x = np.transpose([x_vals[rand_index]])
    rand_y = np.transpose([y_vals[rand_index]])
    sess.run(train_step, feed_dict={x_data:rand_x, y_target:rand_y})
    temp_loss = sess.run(loss, feed_dict={x_data: rand_x, y_target: rand_y})
    loss_vec.append(temp_loss)
    if (i+1)%25==0:
        print('Step #' + str(i+1) + ' A = ' + str(sess.run(A)) + ', b = ' + str(sess.run(b)))
        print('Loss = ' + str(temp_loss))

# Get the optimal coefficients
[slope] = sess.run(A)
[y_intercept] = sess.run(b)

# Get the best fit line
best_fit = []
for i in x_vals:
    best_fit.append(slope*i + y_intercept)

# Plot the result
plt.plot(x_vals, y_vals, 'o', label='Data Points')
plt.plot(x_vals, best_fit, 'r-', label='Best fit line', linewidth=3)
plt.legend(loc='upper left')
plt.title('Sepal Length vs Petal Width')
plt.xlabel('Petal Width')
plt.ylabel('Sepal Length')
plt.show()

# Plot loss over time
plt.plot(loss_vec, 'k-')
plt.title('L2 Loss per Generation')
plt.xlabel('Generation')
plt.ylabel('L2 Loss')
plt.show()


from scipy import optimize as opt
import numpy as np

def rosen(x):
    #return (1-x)^2 + 100(y-x^2)^2
	return sum(100.0*(x[1:]-x[:-1]**2.0)**2.0 + (1-x[:-1])**2.0)

def rast(x):
    return 10*2 + sum(x[:-1]**2.0 - 10*np.cos(2*np.pi*x[:-1])+x[:1]**2.0 - 10*np.cos(2*np.pi*x[:1]))

##x= np.array([21,15])
x = [1.3,.7,.8,1.9,1.2]
##x = [-1.2, 3, 12]
f = opt.rosen
fprime = opt.rosen_der

##print opt.fmin(f, x)
##print opt.fmin_powell(rosen,x)
##print opt.fmin_cg(rosen,x)
##print opt.fmin_bfgs(rosen,x)
##print opt.fmin_ncg(rosen,x, fprime, fhess=opt.rosen_hess)

def g(x):
    return x**2 + 10*np.sin(x)
grid = (-1,2,.01)
print opt.brute(g,(grid,))
##
##
##x = [.5]
##print opt.fmin_l_bfgs_b(g,x)
##print opt.fmin_bfgs(g,x)


# By
# ████████╗██╗   ██╗ █████╗ ███╗   ██╗    ██╗  ██╗ ██████╗
# ╚══██╔══╝██║   ██║██╔══██╗████╗  ██║    ██║  ██║██╔═══██╗
#    ██║   ██║   ██║███████║██╔██╗ ██║    ███████║██║   ██║
#    ██║   ██║   ██║██╔══██║██║╚██╗██║    ██╔══██║██║   ██║
#    ██║   ╚██████╔╝██║  ██║██║ ╚████║    ██║  ██║╚██████╔╝
#    ╚═╝    ╚═════╝ ╚═╝  ╚═╝╚═╝  ╚═══╝    ╚═╝  ╚═╝ ╚═════╝

# Email: ttuan.ho@outlook.com

from scipy.stats import norm, binom, poisson, expon, uniform
import numpy as np

"""
Ex4
"""

# % matlab version:
# binomcdf(1,6,0.5)
binom.cdf(1,6,0.5)

# % matlab version:
# poisscdf(1,6,0.5)
poisson.cdf(1,3)

"""
Ex5
"""
# % matlab version:
# 1 - normcdf(0.29)
# 1 - normcdf(100,96,14)
1 - norm.cdf(0.29)
1 - norm.cdf(100,96,14)

# % matlab version:
# normcdf(80,96,14)-normcdf(50,96,14)
norm.cdf(80,96,14)-norm.cdf(50,96,14)

# % matlab version:
# norminv(0.95)
norm.ppf(0.95)

# Interval that gives 90% = [mean +- sd * tinv(prob+(1-prob)/2)]
96 + 14 * norm.ppf(0.95) * np.array([-1, 1])


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# =======================================
# File Name: utils.py
# Purpose  : implementation for generating
#            parameters
# =======================================

import math
import numpy as np
import csv
import sys
import os

np.random.seed(42) # fixed random seed

def l2_cost(x, y):
    """L2 cost
    """
    m, n = x.shape[0], y.shape[0]
    ind = np.indices((m, n))
    cost = ((x[ind[0]] - y[ind[1]]) ** 2).sum(axis=2)
    return cost

def random_cost(num):
    """random cost
    """
    x = np.random.rand(num * 2).reshape((num, 2))
    y = np.random.rand(num * 2).reshape((num, 2))
    return l2_cost(x, y)

def gen_ellipse_2d(num, x1_center=0, x2_center=0, r_x1=1.3, r_x2=0.9, eps=0.1):
    """generate ellipse 2d datapoint
    """
    r = np.random.uniform(0, 2. * math.pi, num)
    dx1 = np.cos(r) + eps / math.sqrt(2.) * np.random.randn(num)
    dx2 = np.sin(r) + eps / math.sqrt(2.) * np.random.randn(num)
    x1 = r_x1 * dx1 + x1_center
    x2 = r_x2 * dx2 + x2_center
    x = np.concatenate((x1.reshape(num, 1), x2.reshape(num, 1)), axis=1)
    return x

def ellipse_cost(num, x1_center=0, x2_center=0, sr_x1=1.3, sr_x2=0.9, tr_x1=0.9, tr_x2=1.1, eps=0.1):
    """ellipse cost
    """
    x = gen_ellipse_2d(num, x1_center, x2_center, sr_x1, sr_x2, eps)
    y = gen_ellipse_2d(num, x1_center, x2_center, tr_x1, tr_x2, eps)
    return l2_cost(x, y)

def gen_caffarelli_2d(num, x1_center=0, x2_center=0, r=1, shift=2):
    """generate caffarelli 2d datapoint
    """
    l = 0
    while l <= num:
        ox1 = np.random.uniform(-r, r, num)
        ox2 = np.random.uniform(-r, r, num)
        mask = ox1 ** 2 + ox2 ** 2 < r ** 2
        dx1, dx2 = ox1[mask], ox2[mask]
        dx1[dx1 < 0.] -= shift
        dx2[dx2 >= 0.] += shift
        n = dx1.size
        x1 = dx1 + x1_center
        x2 = dx2 + x2_center
        x = np.concatenate((x1.reshape(n, 1), x2.reshape(n, 1)), axis=1)
        if l == 0:
            pos = x
        else:
            pos = np.concatenate((pos, x), axis=0)
        l = len(pos)
    return pos[0:num, ]

def caffarelli_cost(num, x1_center=0, x2_center=0, r=1, shift=2):
    """caffarelli cost
    """
    x = gen_caffarelli_2d(num, x1_center, x2_center, r, 0)
    y = gen_caffarelli_2d(num, x1_center, x2_center, r, shift)
    return l2_cost(x, y)

def DOTmark_weight(num, ImageClass):
    """DOTmark dataset weight for mu and nu
    Schuhmacher, Dominic; Schrieber, Jörn; Gottschlich, Carsten (2016):
    DOTmark v1.0. figshare. Dataset.
    https://doi.org/10.6084/m9.figshare.4288466.v1
    """
    path = os.getcwd()
    index = np.random.choice(range(1, 10), 2, replace=None)
    w = []
    for i in index:
        with open(path + '/DOT/' + ImageClass + '/data' + str(int(math.sqrt(num)))
                  + '_100' + str(i) + '.csv') as csvfile:
            csv_reader = csv.reader(csvfile)
            for row in csv_reader:
                w.append(row)
        csvfile.close()
    w = np.array(w, np.float32).reshape((2, num))
    mu = w[0, :] / sum(w[0, :])
    nu = w[1, :] / sum(w[1, :])
    return mu, nu

def gen_DOTmark(start_x1, end_x1, start_x2, end_x2, size):
    """generate DOTmark 2d datapoint
    """
    step_x1 = (end_x1 - start_x1) / size
    x1 = np.linspace(start_x1 + step_x1 / 2.0, end_x1 - step_x1 / 2.0, size)
    step_x2 = (end_x2 - start_x2) / size
    x2 = np.linspace(start_x2 + step_x2 / 2.0, end_x2 - step_x2 / 2.0, size)
    x1p, x2p = np.meshgrid(x1, x2)
    x = np.concatenate((x1p.reshape((int(size * size), 1)), x2p.reshape((int(size * size), 1))), axis=1)
    return x

def DOTmark_cost(size, start_x1=0, end_x1=1, start_x2=0, end_x2=1):
    """DOTmark cost
    """
    x = gen_DOTmark(start_x1, end_x1, start_x2, end_x2, int(math.sqrt(size)))
    y = gen_DOTmark(start_x1, end_x1, start_x2, end_x2, int(math.sqrt(size)))
    return l2_cost(x, y)

def min_row(A, eps):
    """min row
    """
    return - eps * np.log(np.sum(np.exp(-A / eps), axis=1))

def min_col(A, eps):
    """min col
    """
    return - eps * np.log(np.sum(np.exp(-A / eps), axis=0))

def get_params(n, dataset, imageclass="WhiteNoise"):
    """ get mu, nu, c for Optimal Transport problem from given dataset
    """
    if dataset == 'random':
        mu = np.random.random(n)
        mu = mu / sum(mu)
        nu = np.random.random(n)
        nu = nu / sum(nu)
        c = random_cost(n)
    elif dataset == 'caffarelli':
        mu = np.ones(n) / n
        nu = np.ones(n) / n
        c = caffarelli_cost(n)
    elif dataset == 'ellipse':
        mu = np.ones(n) / n
        nu = np.ones(n) / n
        c = ellipse_cost(n, 0, 0, 1.3, 0.9, 0.9, 1.1, 0.1)
    elif dataset == 'DOTmark':
        if n != 1024 and n != 4096:
            print("Unsupported datasize, exit")
            sys.exit(1)
        mu, nu = DOTmark_weight(n, imageclass)
        c = DOTmark_cost(n)
    return mu, nu, c


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

import openrtdynamics2.lang as dy
from openrtdynamics2.ORTDtoNumpy import ORTDtoNumpy

from .vehicle_lib import make_time

@ORTDtoNumpy()
def generate_one_dimensional_motion_trajectory(acceleration_input, Ts):

    # Delta_l_dotdot; the motion jerk is limited to +-1.0 m/s^3
    acceleration     = dy.rate_limit(acceleration_input, Ts, lower_limit = -1.0, upper_limit = 1.0)

    # Delta_l_dot
    velocity         = dy.euler_integrator(acceleration, Ts, 0)

    # Delta_l
    lateral_distance = dy.euler_integrator(velocity,     Ts, 0)

    return lateral_distance, velocity, acceleration

def generate_lateral_profile_1(Ts, T_phase1=1, T_phase2=3, T_phase3=1, T_phase4=3, T_phase5=1):
    """
        Generate a one-dimensional motion trajectory for a jerk-limited sidewards movement.

    """

    def ones_by_time(T):
        return np.ones( int(math.floor( T / Ts )) )

    lateral_distance, velocity, acceleration = generate_one_dimensional_motion_trajectory(
        np.concatenate((

            # phase 1: no movement
            +0.0 * ones_by_time(T_phase1),

            # phase 2: movement into the positive direction
            #          divided into an accelerating phase,
            #          a phase of constant velocity, and finally
            #          a braking phase. The velocity is then zero.
            +1.0 * ones_by_time(T_phase2/3),
            +0.0 * ones_by_time(T_phase2/3),
            -1.0 * ones_by_time(T_phase2/3),

            # phase 3: no movement
            +0.0 * ones_by_time(T_phase3),

            # phase 4: like phase 2, however, in the opposite direction
            -1.0 * ones_by_time(T_phase4/3),
            +0.0 * ones_by_time(T_phase4/3),
            +1.0 * ones_by_time(T_phase4/3),

            # phase 5: no movement
            +0.0 * ones_by_time(T_phase5)

        )),
        0.01
    )

    lateral_profile = {}

    lateral_profile['Ts'] = Ts

    lateral_profile['Delta_l_r_dotdot'] = acceleration
    lateral_profile['Delta_l_r_dot'] = velocity
    lateral_profile['Delta_l_r'] = lateral_distance

    # velocity of the vehicle
    lateral_profile['v'] = 5 * np.ones( len( lateral_profile['Delta_l_r'] ) )

    return lateral_profile

def plot_lateral_profile( lateral_profile ):
    """
        Show a profile for the lateral distance to the original path
    """

    time = make_time(lateral_profile['Ts'], lateral_profile['Delta_l_r'])
    plt.figure(figsize=(12,3), dpi=100)
    plt.plot(time, lateral_profile['Delta_l_r'] )
    plt.plot(time, lateral_profile['Delta_l_r_dot'] )
    plt.plot(time, lateral_profile['Delta_l_r_dotdot'] )
    plt.legend(['intended lateral distance [$m$]', '1st derivative [$m/s$]', '2nd derivative [$m/s^s$]'])
    plt.xlabel('time [s]')
    plt.ylabel('lateral distance, velocity, acceleration')
    plt.show()


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import math
import numpy as np

def inner_product(x, y):
    """Inner product."""
    return x.dot(y)

def inner_product_d(x_d, y_d):
    """Inner product for sparse vectors."""
    inner_prod = 0.0
    for k, v in x_d.items():
        if k in y_d:
            inner_prod += v * y_d[k]
    return inner_prod

def correlation_coeff(x, y):
    """Correlation coefficient.

    Note: To speed up computation, we drop normalized term (n - 1)**(-1),
    since this term is redundant after division with sqrt.
    """
    x_ = x - x.mean()
    y_ = y - y.mean()
    cov = inner_product(x_, y_)
    var_x = inner_product(x_, x_)
    var_y = inner_product(y_, y_)
    return cov / math.sqrt(var_x * var_y)

def cosine_similarity(x, y):
    """Cosine similarity."""
    inner_prod = inner_product(x, y)
    norm2_x = inner_product(x, x)
    norm2_y = inner_product(y, y)
    return inner_prod / math.sqrt(norm2_x * norm2_y)

def cosine_similarity_d(x_d, y_d):
    """Cosine similarity for sparse vectors."""
    inner_prod = inner_product_d(x_d, y_d)
    x = np.array(list(x_d.values()))
    y = np.array(list(y_d.values()))
    norm2_x = inner_product(x, x)
    norm2_y = inner_product(y, y)
    return inner_prod / math.sqrt(norm2_x * norm2_y)

def accuracy(y_pred, y_true):
    """Accuracy."""
    return (y_pred == y_true.reshape(y_pred.shape)).mean()

def mean_squared_error(y_pred, y_true):
    """Mean squared error."""
    return ((y_pred - y_true.reshape(y_pred.shape)) ** 2).mean()


import datetime
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
# import pandas_datareader as web
import pymc3 as pm
from pymc3.distributions.timeseries import GaussianRandomWalk
import seaborn as sns

import pickle
import warnings
warnings.filterwarnings('ignore')

def obtain_plot_amz_dataset(start_date, end_date):
    amzn = pd.read_csv('data/amzn.csv')
    print("Loading and plotting AMZN log returns...")
    amzn['returns'] = amzn['Adj Close']/amzn['Adj Close'].shift(1)
    amzn.dropna(inplace=True)
    amzn['log_returns'] = np.log(amzn['returns'])
    amzn['log_returns'].plot(linewidth=0.5)
    plt.ylabel('AMZN daily percentage returns')
    plt.show()
    return amzn
# Model Specification in PyMC3 ------------------------

def configure_sample_stoch_vol_model(log_returns, samples):
    print("Configuring stochastic volatility with PyMC3...")
    model = pm.Model()

    with model:
        sigma = pm.Exponential('sigma', 50.0, testval=0.1)
        nu = pm.Exponential('nu', 0.1)
        s = GaussianRandomWalk('s', sigma=(sigma**-2), shape=len(log_returns))
        logrets = pm.StudentT(
            'logrets', nu, lam=pm.math.exp(-2.0*s), observed=log_returns)

    # Fitting the Model with NUTS
    print('Fitting the stochastic volatility model')
    with model:
        trace = pm.sample(samples)

        with open('data\\trace.pickle', 'wb') as f:
            pickle.dump(trace, f, protocol=pickle.HIGHEST_PROTOCOL)

        # with open('trace.pickle', 'rb') as f:
        #     trace = pickle.load(f)

        # with open('trace2.pickle', 'rb') as f:
        #     trace = pickle.load(f)
    '''
    # print(model.vars[:-1])
    # error when call traceplot
    pm.traceplot(trace, model.vars)
    plt.show()
    '''

    print("Plotting the log volatility...")
    k = 10      # step-size
    opacity = 0.03

    plt.plot(trace[s][::k].T, 'b', alpha=opacity)       # 'b' mean blue
    plt.xlabel('Time')
    plt.ylabel('Log Volatility')
    plt.show()

    print("Plotting the absolute returns overlaid with vol...")
    plt.plot(np.abs(np.exp(log_returns))-1.0, linewidth=0.5)
    plt.plot(np.exp(trace[s][::k].T), 'r', alpha=opacity)

    plt.xlabel("Trading Days")
    plt.ylabel("Absolute Returns/Volatility")
    plt.show()

if __name__ == "__main__":
    start_date = datetime.datetime(2006, 1, 1)
    end_date = datetime.datetime(2015, 12, 31)

    # Obtain and plot the logarithmic returns of amz prices
    df = obtain_plot_amz_dataset(start_date, end_date)
    log_returns = np.array(df['log_returns'])

    samples = 500   # 2000
    configure_sample_stoch_vol_model(log_returns, samples)
    pass


import numpy as np

A=np.array([[10,2,1],[0,4,2],[1,2,2]])
b=np.array([3,2,1])

def my_back_solve(A,b) :
    n=len(A)
    x=np.zeros(n)
    x[n-1] = b[n-1] / A[n-1, n-1]
    for k in range(n-2, -1, -1):
        sums = b[k]
        for j in range(k+1, n):
            sums = sums - (A[k,j] * x[j])
        x[k] = sums / A[k,k]
    return x

x=my_back_solve(A,b)
print('x=',x)
print('A x=', np.dot(A,x))


"""
Python code for fractional differencing of pandas time series
illustrating the concepts of the article "Preserving Memory in Stationary Time Series"
by Simon Kuttruf

While this code is dedicated to the public domain for use without permission, the author disclaims any liability in connection with the use of this code.
"""

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

def getWeights(d,lags):
    # return the weights from the series expansion of the differencing operator
    # for real orders d and up to lags coefficients
    w=[1]
    for k in range(1,lags):
        w.append(-w[-1]*((d-k+1))/k)
    w=np.array(w).reshape(-1,1)
    return w

def plotWeights(dRange, lags, numberPlots):
    weights=pd.DataFrame(np.zeros((lags, numberPlots)))
    interval=np.linspace(dRange[0],dRange[1],numberPlots)
    for i, diff_order in enumerate(interval):
        weights[i]=getWeights(diff_order,lags)
    weights.columns = [round(x,2) for x in interval]
    fig=weights.plot()
    plt.legend(title='Order of differencing')
    plt.title('Lag coefficients for various orders of differencing')
    plt.xlabel('lag coefficients')
    #plt.grid(False)
    plt.show()

plotWeights([0,1],7,6)

def ts_differencing(series, order, lag_cutoff):
    # return the time series resulting from (fractional) differencing
    # for real orders order up to lag_cutoff coefficients

    weights=getWeights(order, lag_cutoff)
    res=0
    for k in range(lag_cutoff):
        res += weights[k]*series.shift(k).fillna(0)
    return res[lag_cutoff:]

def plotMemoryVsCorr(result, seriesName):
    fig, ax = plt.subplots()
    ax2 = ax.twinx()
    color1='xkcd:deep red'; color2='xkcd:cornflower blue'
    ax.plot(result.order,result['adf'],color=color1)
    ax.plot(result.order, result['5%'], color='xkcd:slate')
    ax2.plot(result.order,result['corr'], color=color2)
    ax.set_xlabel('order of differencing')
    ax.set_ylabel('adf', color=color1);ax.tick_params(axis='y', labelcolor=color1)
    ax2.set_ylabel('corr', color=color2); ax2.tick_params(axis='y', labelcolor=color2)
    plt.title('ADF test statistics and correlation for %s' % (seriesName))
    plt.show()

from statsmodels.tsa.stattools import adfuller
def MemoryVsCorr(series, dRange, numberPlots, lag_cutoff, seriesName):
    # return a data frame and plot comparing adf statistics and linear correlation
    # for numberPlots orders of differencing in the interval dRange up to a lag_cutoff coefficients

    interval=np.linspace(dRange[0], dRange[1],numberPlots)
    result=pd.DataFrame(np.zeros((len(interval),4)))
    result.columns = ['order','adf','corr', '5%']
    result['order']=interval
    for counter,order in enumerate(interval):
        seq_traf=ts_differencing(series,order,lag_cutoff)
        res=adfuller(seq_traf, maxlag=1, regression='c') #autolag='AIC'
        result.loc[counter,'adf']=res[0]
        result.loc[counter,'5%']=res[4]['5%']
        result.loc[counter,'corr']= np.corrcoef(series[lag_cutoff:].fillna(0),seq_traf)[0,1]
    plotMemoryVsCorr(result, seriesName)
    return result


import numpy as np
from scipy.misc import factorial

def loggamma_vec(x_vec, a, b):
    """
    sum_i log Gamma(x_vec[i], a[i], b[i])

    Parameters
    ----------
    x_vec : np.array
    a : np.array or float
    b : np.array or float

    Returns
    -------
    float
    """
    p_x = a * np.log(b) - np.log(factorial(a - 1.0)) + (a - 1.0) * np.log(x_vec) - b * x_vec
    return np.sum(p_x)

def logpoisson_vec(lam_vec, x_vec):
    """
    sum_i logPoisson(lam_vec[i], x_vec[i])

    Parameters
    ----------
    lam_vec : np.array
        1 dimensional (D,) size numpy array for the Poisson mean
    x_vec : np.array
        1 dimensional (D,) size numpy array

    Returns
    -------
    float

    """
    lam_vec = np.array(lam_vec)
    if np.prod(lam_vec) == 0:
        for i, l in enumerate(lam_vec):
            if l == 0:
                lam_vec[i] = 1e-7
    x_vec = np.array(x_vec)
    return np.sum(-lam_vec + x_vec * np.log(lam_vec) - np.log(factorial(x_vec)))

def logpoisson_vec_all(lam_vec, x_mat, gam_prior=False, a=1.0, b=1.0):
    """
    Get an array of log likelihood for each x_mat[i], using lam_vec
    loglik[i] = logpoisson_vec(lam_vec, x_mat[i])

    Parameters
    ----------
    lam_vec : np.array
        1 dimensional (D,) size numpy array for the Poisson mean
    x_mat : np.array
        2 dimensional (N, D) size numpy array

    Returns
    -------
    np.array
        (N,) size log probabilities
    """
    logprob= np.zeros(x_mat.shape[0])
    if gam_prior:
        for i in range(x_mat.shape[0]):
            xi = x_mat[i]
            const = np.log(factorial(a + xi - 1)) - np.log(factorial(a - 1)) \
                    - np \
                    .log ( factorial(xi)) + a* np.log(b) - (a + xi)* np.log(b+1)
            logprob[i] = loggamma_vec( lam_vec, a+xi, b+1) + np.sum(const)
    else:
        for i in range(x_mat.shape[0]):
            logprob[i] = logpoisson_vec(lam_vec, x_mat[i])
    return logprob


### The following code implements the traveling salesman probblem with a greedy heuristic approach.

from tqdm import tqdm
import numpy as np

def read_file(name):
    """Given the path/name of the file, return the graph (dictionary).
    """
    file = open(name,'r')
    data = file.readlines()

    # initialize the graph
    g = {}
    #num = int(data[0][0])
    for line in data[1:]:
        item = line.split()
        g[int(item[0])] = (float(item[1]), float(item[2]))

    return g

g = read_file('tsp_large.txt')

def euclidean_sq(a,b):
    """Return the square euclidean distance of a(x1,y1) and b(x2,y2)
    """
    dis = (a[0] - b[0])**2 + (a[1]- b[1])**2
    return dis

def tsp(g):
    """Given the graph, return the heuristic traveling salesman problem value.
    """
    # number of cities
    num = len(g)

    # Initialize visited and unvisited set
    visited = []
    visited.append(1)

    unvisited = list(range(2, len(g)+1))

    final_dis = 0
    # Main loop: stop when all the cities are visited.
    for i in tqdm(range(num-1)):

        current_city = visited[-1]
        next_city = unvisited[0]

        min_dis = euclidean_sq(g[current_city], g[next_city])

        if len(unvisited)>1:
            for j in unvisited[1:]:
                dis = euclidean_sq(g[current_city], g[j])
                if dis < min_dis:
                    min_dis = dis
                    next_city = j
                # break the tie
                elif dis == min_dis:
                    next_city = min(next_city, j)

        visited.append(next_city)
        unvisited.remove(next_city)
        final_dis += np.sqrt(min_dis)

    final_dis += np.sqrt(euclidean_sq(g[visited[-1]], g[1]))

    return final_dis

def main():
    g = read_file('tsp_large.txt')
    best_dis = tsp(g)

    return best_dis

if __name__ == '__main__':
    main()

C4: Shortest Path Revisited, NP-Complete/tsp_heuristic.py


import numpy as np
import matplotlib.pyplot as plt

class Brownian:
    """
    A Brownian motion class constructor
    """

    def __init__(self, x0=0):
        """
        Init class
        """
        assert (
            type(x0) == float or type(x0) == int or x0 is None
        ), "Expect a float or None for the initial value"

        self.x0 = float(x0)

    def gen_random_walk(self, n_step=100):
        """
        Generate motion by random walk

        Arguments:
            n_step: Number of steps

        Returns:
            A NumPy array with `n_steps` points
        """
        # Warning about the small number of steps
        if n_step < 30:
            print(
                "WARNING! The number of steps is small. It may not generate a good stochastic process sequence!"
            )

        w = np.ones(n_step) * self.x0

        for i in range(1, n_step):
            # Sampling from the Normal distribution with probability 1/2
            yi = np.random.choice([1, -1])
            # Weiner process
            w[i] = w[i - 1] + (yi / np.sqrt(n_step))

        return w

    def gen_normal(self, n_step=100):
        """
        Generate motion by drawing from the Normal distribution

        Arguments:
            n_step: Number of steps

        Returns:
            A NumPy array with `n_steps` points
        """
        if n_step < 30:
            print(
                "WARNING! The number of steps is small. It may not generate a good stochastic process sequence!"
            )

        w = np.ones(n_step) * self.x0

        for i in range(1, n_step):
            # Sampling from the Normal distribution
            yi = np.random.normal()
            # Weiner process
            w[i] = w[i - 1] + (yi / np.sqrt(n_step))

        return w

    def stock_price(self, s0=100, mu=0.2, sigma=0.68, deltaT=52, dt=0.1):
        """
        Models a stock price S(t) using the Weiner process W(t) as
        `S(t) = S(0).exp{(mu-(sigma^2/2).t)+sigma.W(t)}`

        Arguments:
            s0: Iniital stock price, default 100
            mu: 'Drift' of the stock (upwards or downwards), default 1
            sigma: 'Volatility' of the stock, default 1
            deltaT: The time period for which the future prices are computed, default 52 (as in 52 weeks)
            dt (optional): The granularity of the time-period, default 0.1

        Returns:
            s: A NumPy array with the simulated stock prices over the time-period deltaT
        """
        n_step = int(deltaT / dt)
        time_vector = np.linspace(0, deltaT, num=n_step)
        # Stock variation
        stock_var = (mu - (sigma**2 / 2)) * time_vector
        # Forcefully set the initial value to zero for the stock price simulation
        self.x0 = 0
        # Weiner process (calls the `gen_normal` method)
        weiner_process = sigma * self.gen_normal(n_step)
        # Add two time series, take exponent, and multiply by the initial stock price
        s = s0 * (np.exp(stock_var + weiner_process))

        return s

b = Brownian()
# brown = b.gen_random_walk(100)
plt.plot(brown, label="Price")
plt.axvline(x=100, color="black", ls="--", label="Now")
plt.axvline(x=80, color="red", ls="--", label="Horizon 20: sell!")
plt.axvline(x=60, color="green", ls="--", label="Horizon 40: buy!")
plt.axhline(y=brown[79], color="red", linestyle=":")
plt.axhline(y=brown[59], color="green", linestyle=":")
plt.axhline(y=brown[99], color="black", linestyle=":")
plt.title("A random stock price")
plt.xlabel("Time")
plt.ylabel("Stock price (Brownian Motion)")
plt.legend()
plt.savefig("etf.png", format="png", dpi=300)
plt.show()


"""
Filename: simplex_grid.py

Author: Daisuke Oyama

Thie module provides a function that constructs a grid for a simplex as
well as one that determines the index of a point in the simplex.

"""
import numpy as np
import scipy.misc
from numba import jit

@jit
def simplex_grid(m, n):
    r"""
    Construct an array consisting of the integer points in the
    (m-1)-dimensional simplex :math:`\{x \mid x_0 + \cdots + x_{m-1} = n
    \}`, or equivalently, the m-part compositions of n, which are listed
    in lexicographic order. The total number of the points (hence the
    length of the output array) is L = (n+m-1)!/(n!*(m-1)!) (i.e.,
    (n+m-1) choose (m-1)).

    Parameters
    ----------
    m : scalar(int)
        Dimension of each point. Must be a positive integer.

    n : scalar(int)
        Number which the coordinates of each point sum to. Must be a
        nonnegative integer.

    Returns
    -------
    out : ndarray(int, ndim=2)
        Array of shape (L, m) containing the integer points in the
        simplex, aligned in lexicographic order.

    Notes
    -----
    A grid of the (m-1)-dimensional *unit* simplex with n subdivisions
    along each dimension can be obtained by `simplex_grid(m, n) / n`.

    Examples
    --------
    >>> simplex_grid(3, 4)
    array([[0, 0, 4],
           [0, 1, 3],
           [0, 2, 2],
           [0, 3, 1],
           [0, 4, 0],
           [1, 0, 3],
           [1, 1, 2],
           [1, 2, 1],
           [1, 3, 0],
           [2, 0, 2],
           [2, 1, 1],
           [2, 2, 0],
           [3, 0, 1],
           [3, 1, 0],
           [4, 0, 0]])

    >>> simplex_grid(3, 4) / 4
    array([[ 0.  ,  0.  ,  1.  ],
           [ 0.  ,  0.25,  0.75],
           [ 0.  ,  0.5 ,  0.5 ],
           [ 0.  ,  0.75,  0.25],
           [ 0.  ,  1.  ,  0.  ],
           [ 0.25,  0.  ,  0.75],
           [ 0.25,  0.25,  0.5 ],
           [ 0.25,  0.5 ,  0.25],
           [ 0.25,  0.75,  0.  ],
           [ 0.5 ,  0.  ,  0.5 ],
           [ 0.5 ,  0.25,  0.25],
           [ 0.5 ,  0.5 ,  0.  ],
           [ 0.75,  0.  ,  0.25],
           [ 0.75,  0.25,  0.  ],
           [ 1.  ,  0.  ,  0.  ]])

    References
    ----------
    A. Nijenhuis and H. S. Wilf, Combinatorial Algorithms, Chapter 5,
    Academic Press, 1978.

    """
    L = num_compositions(m, n)
    out = np.empty((L, m), dtype=int)

    x = np.zeros(m, dtype=int)
    x[m-1] = n

    for j in range(m):
        out[0, j] = x[j]

    h = m

    for i in range(1, L):
        h -= 1

        val = x[h]
        x[h] = 0
        x[m-1] = val - 1
        x[h-1] += 1

        for j in range(m):
            out[i, j] = x[j]

        if val != 1:
            h = m

    return out

def simplex_index(x, m, n):
    r"""
    Return the index of the point x in the lexicographic order of the
    integer points of the (m-1)-dimensional simplex :math:`\{x \mid x_0
    + \cdots + x_{m-1} = n\}`.

    Parameters
    ----------
    x : array_like(int, ndim=1)
        Integer point in the simplex, i.e., an array of m nonnegative
        itegers that sum to n.

    m : scalar(int)
        Dimension of each point. Must be a positive integer.

    n : scalar(int)
        Number which the coordinates of each point sum to. Must be a
        nonnegative integer.

    Returns
    -------
    idx : scalar(int)
        Index of x.

    """
    if m == 1:
        return 0

    decumsum = np.cumsum(x[-1:0:-1])[::-1]
    idx = num_compositions(m, n) - 1
    for i in range(m-1):
        if decumsum[i] == 0:
            break
        idx -= num_compositions(m-i, decumsum[i]-1)
    return idx

def simplex_index_rec(x, m, n):
    """
    Recursive version of `simplex_index`.

    """
    if m == 1:
        return 0

    # idx0: index of the first point whose 0th coordinate = x[0]
    if x[0] == 0:
        n_next = n
        idx0 = 0
    else:
        n_next = n - x[0]
        idx0 = num_compositions(m, n) - num_compositions(m, n_next)

    return idx0 + simplex_index_rec(x[1:], m-1, n_next)

def num_compositions(m, n):
    """
    The total number of m-part compositions of n, which is equal to
    (n+m-1) choose (m-1).

    Parameters
    ----------
    m : scalar(int)
        Number of parts of composition.

    n : scalar(int)
        Integer to decompose.

    Returns
    -------
    scalar(int)
        Total number of m-part compositions of n.

    """
    # docs.scipy.org/doc/scipy/reference/generated/scipy.misc.comb.html
    return scipy.misc.comb(n+m-1, m-1, exact=True)


# Lab exercise 1:

# Ajad Chhatkuli
# Uses python 2.7 -> just change the print for 3
# Note: You might need additional library to plot
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# Generate 3D data -> 3x50 is preferable over 50x3
N=50
p = np.random.uniform(0,1,(3,N))

# add [1,1,4]
# move 3D object away from the camera with some random vector
offset = np.repeat([[1],[1],[4]], N, axis=1)
p = p + offset

# bonus visualize 3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(p[0,:], p[1,:], p[2,:], zdir='z', s=20, c=None, depthshade=True)
plt.interactive(False)
plt.show()

# Add one to the point vectors
v_ones = np.ones((1,N))
p = np.vstack((p,v_ones))
print p.shape

# Generate cameras of 3X4
v_zeros = np.zeros((3,1))
# First camera at origin
M1 = np.hstack((np.eye(3),v_zeros))

# Second camera at R, t
# R is pi/6 rotation x, y
R = np.array([[0.8660, 0.2500, 0.4330],
     [0, 0.8660, -0.5000],
      [-0.5000, 0.4330, 0.7500]])

t = np.array([[-0.4, 0.3, 0.6]])
t = t.T
print R.shape
print t.shape
M2 = np.hstack((R,t))

# Now project all points at once:

# Image points in camera 1
q1 = np.dot(M1,p)
q2 = np.dot(M2,p)

# output is w*[u, v, 1] => ok for epipolar equation, not ok for actual camera projections

# to visualize image projections you need [u,v,1], therefore divide by last homogeneous element
u1 = q1[0,:]/q1[2,:]
v1 = q1[1,:]/q1[2,:]

u2 = q2[0,:]/q2[2,:]
v2 = q2[1,:]/q2[2,:]

# form the epipolar equations

# equation Matrix:
A = np.vstack((u2 * u1,  u2 * v1 , u2 , v2 * u1 , v2 * v1 , v2 , u1 , v1 , np.ones((1,N))))
A = A.T
print A.shape

# To solve A* f = 0, ||f||=1

u_svd,s_svd,vh_svd = np.linalg.svd(A,full_matrices=False)

# Note python gives vh_svd.T instead of vh_svd
# A = u*s*vh in python instead of u*s*vh.T

# optional :# Check svd decomposition
s_svd = np.diag(s_svd)
Ah = np.dot(np.dot(u_svd,s_svd),vh_svd)
print np.linalg.norm((A-Ah))

# get solution: last row of vh

f = vh_svd[-1,:]

# get the essential matrix:
E = f.reshape((3,3))

print E
# The actual Essential Matrix from the is:
tx = np.array([[0, -t[2], t[1]], [t[2], 0, -t[0]], [-t[1], t[0], 0]])
E_actual = np.dot(tx,R)

# scale is not relevant since if E satisfies epipolar eqn w*E also does.
E_actual = E_actual/np.linalg.norm(E_actual)
print E_actual


"""
Here: f(x) = x^2 - A
We've got to minimize f(x) to find the square root of A, which is x.

Newton-Raphson's method -

Primer:
    For a curve, tangent at point x_k is:
        a) y = f'(x)*(x - x_k) + f(x_k)  (slope is f'(x), f(x_k) is "c")

The method now says, let's start from an initial condition: x_k
The next best estimate of the root: x_k+1 is the x-intercept of tangent at x_k; which means y=0.
Plugging this at a),
    0 = f'(x_k)*(x_k+1 - x_k) + f(x_k)
    x_k+1 = x_k - f(x_k) / f'(x_k)

Now x_k+1 = x_k for the next iteration.

side note: it is mesmerizing to see how newton thought algorithmically. Math is pretty much algorithms with constraints.
This also made me read about quasi-newton methods, like BFGS, which I had used in camera calibration. The appreciation for mathematics isn't enough.

"""

import numpy as np

def square_root(number, accuracy_tolerance=1e-4, num_iterations=1000):
    """Estimate the square root of a natural `number`.

    Args:
        number:
        accuracy_tolerance:
        num_iterations:

    Returns:
        the estimated square root

    Raises:
        ValueError: If number isn't a natural number.

    """
    if number < 0:
        raise ValueError("Cannot estimate the square root of a negative number.")

    estimated_root = number

    for _ in range(num_iterations):
        new_estimated_root = 0.5 * (estimated_root + (float(number) / estimated_root))
        if np.abs(new_estimated_root - estimated_root) < accuracy_tolerance:
            break
        estimated_root = new_estimated_root

    return estimated_root

if __name__ == "__main__":
    print(f"Square root for 3 is: {square_root(3)}")
    print(f"Square root for 100 is: {square_root(100)}")
    print(f"Square root for 17 is: {square_root(17)}")
    print(f"Square root for -1 is: {square_root(-1)}")


#! /usr/bin/env python

import numpy

##DEFINING FUNCTIONS##
def dist(x1,y1,z1,x2,y2,z2):
    d_a = (((x2-x1)**2) + ((y2-y1)**2) + ((z2-z1)**2))**0.5
    return d_a

def short_distance(a):
    n = a.shape[0]

    for i in range(n-1):
        x1 = a[i][0]
        y1 = a[i][1]
        z1 = a[i][2]

        for j in range(i+1,n):
            x2 = a[j][0]
            y2 = a[j][1]
            z2 = a[j][2]
            d_b = dist(x1,y1,z1,x2,y2,z2)
            if j == 1:
                short_a = d_b
                h_a = [a[0],a[1]]
            elif d_b < short_a:
                short_a = d_b
                h_a = []
                h_a = [a[i],a[j]]
            elif (d_b == short_a) and (j!=1):
                short_a = d_b
                h_a.append(a[i])
                h_a.append(a[j])
            else:
                pass

    return h_a,short_a

##DRIVER CODE##
if __name__ == "__main__":
    s = 'Y'
    while s != 'n':
        R = 0
        while R == 0:
            R = int(input("Enter the number of points : "))

        entries = []
        while len(entries) != (R*3):
            print("Enter the coordinates in x y z format separated by space : ")
            entries = list(map(float,input().split( )))

        a = numpy.array(entries).reshape(R,3)
        x,d = short_distance(a)
        y = len(x)

        print(f'Shortest distance is {d}')
        print("The coordinates with the shortest distance are : ")

        for i in range(0,y,2):
            print(f'{x[i]}' ,end=' ')
            print(f'{x[i+1]}')

        print('\n')
        while True:
            s = input('Again ?? (Y/n) : ')
            if (s=='Y') or (s=='n'):
                break

    print("\nEnd")


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

# # ML Regularized Logistic Regression - Using One-vs-All
#
# We will use an One-vs-all logistic regression to recognize hand-written digits.
#
# The data set contains the images pixels row-wise (20x20) plus its label.
# The digits are labeled from 0 through 9.

# In[1]:

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import random

# ## =========== Part 1: Loading and Visualizing Data =============

# In[2]:

data = pd.read_csv('ex3data1.txt', names=[str(i) for i in range(1, 402)])
print('Profiling Data')
print(data.info())
print(data.head())

# In[3]:

x = np.array(data[[str(i) for i in range(1, 401)]]) # training set
y = np.array(data['401']) # labels (0-9)
[m, n] = np.shape(x)

# In[4]:

digitMatrix = np.column_stack([np.reshape(x[0], [20, 20]), np.zeros([20, 1]),                                np.reshape(x[2500], [20, 20]), np.zeros([20, 1]),                                np.reshape(x[3500], [20, 20]), np.zeros([20, 1]),                                np.reshape(x[4500], [20, 20]), np.zeros([20, 1])])
plt.imshow(digitMatrix, cmap='Greys', interpolation='nearest')
plt.title("Digits examples: %s, %s, %s, %s" % (y[0], y[2500], y[3500], y[4500]))
# plt.show()

# ## ============ Part 2: Hypothesis Model ============

# ### Activation Function
# We will use the sigmoid function as our activation function.
#
# $g(z) = \frac{1}{1 + e^{-z}}$
#
# When:
#
# $z = 0$ then $g = 0.5$
#
# $z \rightarrow +\infty$ then $g \rightarrow +1$
#
# $z \rightarrow -\infty$ then $g \rightarrow 0$

# In[5]:

"""
Sigmoid activation function
"""
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

# ### Hypothesis
# Function that defines our logistic model.
#
# Definition:
#
# $h_\theta(x) = g(\theta_0 + \theta_1 * x_1 + \theta_2 * x_2)$
#
# Vectorial form:
#
# $h_\theta(x) = g(\theta^{T} * x)$
#
# where:
#
# $g$ is the sigmoid function; $x = [x_0, x_1, x_2]$; $x_0 = 1$ and $\theta = [\theta_0, \theta_1, \theta_2]$

# In[6]:

def hypothesis(X, theta):
    return sigmoid(X.dot(theta))

# ## ============ Part 3: Cost Function and Gradient Descent ============

# ### Regularized Logistic Cost Function
#
# Computes the logistic cost of our model using theta as the parameter for logistic regression to fit the data points in X and y, considering the cost of a particular choice of theta.
#
# For parameter $\theta_0$ we aren't computing its cost because it is the bias - doesn't have a feature.
#
# Function cost:
#
# $ J(\theta) = \frac{1}{m} \sum_{i=1}^{m} [ -y^{(i)} log(h_\theta(x^{(i)}) - (1 - y^{(i)}) log(1 - h_\theta(x^{(i)})) ] + \frac{\lambda}{2m} \sum_{j=1}^{n} \theta_j^{2}$
#
# Vectorial form:
#
# $ J(\theta) = [\frac{1}{m} * (-\vec{y}^{T} \cdot log(h_\theta(\vec{x})) - (1 - \vec{y})^{T} \cdot log(1 - h_\theta(\vec{x})))] + \frac{\lambda}{2m} \sum_{j=1}^{n} \theta_j^{2} $
#
# If any time we got a $log(h_\theta(x^{(i)})) = 0$ that means we need to normalize the features.

# In[7]:

def regularizedLogisticCostFunction(X, y, theta, lambd):
    m = len(X)
    # calculate the cost
    h = hypothesis(X, theta)
    loss = -(1 / m) * (y.T.dot(np.log(h)) + (1 - y).T.dot(np.log(1 - h)))
    # apply regularization
    regLoss = loss + (lambd / (2 * m) * theta[1:].T.dot(theta[1:]))
    return regLoss

# In[8]:

print('Testing regularized cost function')
X_ = np.array([
    [1, 8, 1, 6],
    [1, 3, 5, 7],
    [1, 4, 9, 2]
]);
y_ = np.array([1, 0, 1]);
theta_ = np.array([-2, -1, 1, 2]);

print('J ~= 4.6832 ->', regularizedLogisticCostFunction(X_, y_, theta_, 0))
print('J ~= 8.6832 ->', regularizedLogisticCostFunction(X_, y_, theta_, 4))

# ### Regularized Gradient Descent
# Performs gradient descent to learn $\theta$ parameters.
# It return an array with $\theta$ containing the values found by taking num_iters gradient steps with learning rate $\alpha$.
# Also it return an array with the history of $J(\theta)$ to be plotted.
#
# Step to update each parameter:
#
# $\theta_j := \theta_j - \alpha * \dfrac{\partial J}{\partial \theta_j} $
#
# $\dfrac{\partial J}{\partial \theta_j} = \frac{1}{m} \sum_{i=1}^{m} [( h_\theta(x^{(i)}) - y^{(i)}) * x^{(i)}] + \frac{\lambda}{m} \theta_j$
#
# Vectorial form:
#
# $\theta := \theta - \alpha * \dfrac{\partial J}{\partial \theta} $
#
# $\dfrac{\partial J}{\partial \theta} = \frac{1}{m} X^{T} ( h_\theta(x^{(i)}) - y^{(i)}) + \frac{\lambda}{m} \theta$

# In[9]:

def regularizedGradientDescent(X, y, theta, alpha, lambd, num_iters):
    m = len(X)
    J_history = np.zeros(num_iters)

    for i in range(num_iters):
        # gradient
        h = hypothesis(X, theta)
        nabla = (1 / m) * X.T.dot(h - y)
        # apply regularization
        nabla_theta_0 = nabla[0]
        reg_nabla = nabla + (lambd / m * theta)
        reg_nabla[0] = nabla_theta_0

        # print(reg_nabla)
        # update each parameter
        theta = theta - alpha * reg_nabla
        # Save the cost J in every iteration
        J_history[i] = regularizedLogisticCostFunction(X, y, theta, lambd)
    return theta, J_history

# In[10]:

# gradient w/o reg: [ 0.31722, 0.87232, 1.64812, 2.23787 ]
print(regularizedGradientDescent(X_, y_, theta_, 0, 0, 1)) # ~= [-2, -1, 1, 2], [4.6831]

# gradient w/ reg: [ 0.31722, -0.46102, 2.98146, 4.90454 ]
print(regularizedGradientDescent(X_, y_, theta_, 0, 4, 1)) # ~= [-2, -1, 1, 2], [8.6832]

# ## ============ Part 4: One-vs-All Training ============

# In[11]:

def train_one_vs_all(x, y, num_labels, alpha, lambd, num_iters):
    """
    Train a logistic model for each label/digit.
    As we are recognizing digits, we will have 10 models.

    It returns a matrix with dimension (num_labels)x(n + 1)
    """
    [m, n] = np.shape(x)
    all_theta = np.zeros([num_labels, n + 1]) # n parameters + 1 for bias (theta_0)
    J_history = np.zeros([num_labels, num_iters])

    X = np.column_stack([np.ones(m), x])

    for k in range(num_labels):
        theta = np.zeros([n + 1])

        # pass only the class related to current k (we are training to recognize this digit)
        k_y = np.zeros([m])
        k_y[y == k] = 1
        theta, J_history[k] = regularizedGradientDescent(X, k_y, theta, alpha, lambd, num_iters)

        all_theta[k] = theta
    return all_theta, J_history

# In[12]:

# regularization parameter
lambd = 0.1 # higher than 1 will decrease the accuracy
num_digits = 10
gc_num_iters = 50

# alpha = 1 # won't cause overshoot (and input 2500 will predict as 3) - accuracy is 88.466%
# alpha = 1.1 # won't cause overshoot (and input 2500 will predict as 3) - accuracy is 88.539%
# alpha = 1.3 # starting to cause overshoot in classifer for digit 8 - accuracy is 88.98%
# alpha = 3 # will cause some overshoot in many classes - accuracy is 88.26%
alpha = 2 # will cause less overshoot - accuracy is 89.62%

# Note: on Octave, using fmincg instead of Gradient Descent it had accurary of 95%

print('Training One-vs-All Logistic Regression...')
all_theta, J_history = train_one_vs_all(x, y, num_digits, alpha, lambd, gc_num_iters)
print('Trained')

# In[13]:

print('Plotting cost function through iterations')

# To plot the J(theta)
fig, ax = plt.subplots()
iterations = range(gc_num_iters)

for k in range(num_digits):
    plt.plot(iterations, J_history[k], label='Digit %d' % k)
plt.legend(loc='best', ncol=2)

# ## ================ Part 5: Predict for One-Vs-All ================

# In[14]:

def predict_one_vs_all(all_theta, x):
    m = len(x)
    num_labels = len(all_theta)

    X = np.column_stack([np.ones(m), x])

    pk = np.zeros([m, num_labels])
    for k in range(num_labels):
        pk[:, k] = hypothesis(X, all_theta[k])
    return np.argmax(pk, axis=1)

# In[15]:

pred = predict_one_vs_all(all_theta, x);
print('Predictions:', pred[0], pred[2500], pred[3500], pred[4500])
print('Training Set Accuracy:', np.mean(pred == y) * 100);

# In[16]:

def predict_and_display(x, y, all_theta, index):
    xp = x[index]
    yp = y[index]
    digitMatrix = np.column_stack([np.reshape(xp, [20, 20]), np.zeros([20, 1])])
    plt.imshow(digitMatrix, cmap='Greys', interpolation='nearest')
    pred = predict_one_vs_all(all_theta, np.array([xp]))
    plt.title("Digit %s, Predicted %s" % (yp, pred[0]))

# In[17]:

predict_and_display(x, y, all_theta, random.randint(0, m))

# In[ ]:

Machine Learning - Andrew Ng/assignments/machine-learning-ex3/ex3_python/ML - Regularized Logistic Regression - One-vs-All.py


import numpy as np
np.random.seed(0)

def array_info(array: np.ndarray) -> None:
    print(f"ndim: {array.ndim}")
    print(f"shape: {array.shape}")
    print(f"size: {array.size}")
    print(f"dtype: {array.dtype}")
    print(f"values:\n{array}\n")

print("=1=")
M = np.zeros(shape=[3, 3])
print(M)

print("=2=")
idxsDiag = np.diag_indices(3)
# print(idxs)
M[idxsDiag] = np.pi
print(M)

print("=3=")
idxsU = np.triu_indices(3, 1)
# print(idxsU)
M[idxsU] = 1
print(M)

print("=4=")
idxsL = np.tril_indices(3, -1)
# print(idxsL)
M[idxsL] = -1
print(M)

print("=5=")
print(np.where(M >= 1))


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

#Gaussian kernal function
def gaussian_kernal(u):
    return (1/(math.sqrt(2*math.pi)))*math.e**(-0.5*(u[0,0]**2+u[0,1]**2+u[0,2]**2+u[0,3]**2))

#calculate conditional probability
def cal_pcb(cv,train,cal_pcb_h):
    sum=0
    for i in range(len(train)):
        sum+=(1/h**4)*gaussian_kernal((cv-train[i])/cal_pcb_h)
    p_cp=(1/len(train))*sum
    #print(p_cp)
    return p_cp

def def_h(data1,data2,def_h_h):
    #separate the training dataset into 3 groups by their labels
    data_train_1 = []
    data_train_2 = []
    data_train_3 = []
    for x in range(len(data1)):
        if data1[x, 4] == 0:
            data_train_1.append(data1[x])
        elif data1[x, 4] == 1:
            data_train_2.append(data1[x])
        else:
            data_train_3.append(data1[x])
    #print(data_train_1,data_train_2,data_train_3)
    # calculate prior class probability
    pw1 = len(data_train_1) / len(data1)#P(wk)1
    pw2 = len(data_train_2) / len(data1)#P(wk)2
    pw3 = len(data_train_3) / len(data1)#P(wk)3
    #print(pw1,pw2,pw3)
    right = 0
    for j in range(len(data2)):
        p_list = []
        pcp_label1 = cal_pcb(data2[j], data_train_1, def_h_h)#P(x|wk)1
        pcp_label2 = cal_pcb(data2[j], data_train_2, def_h_h)#P(x|wk)2
        pcp_label3 = cal_pcb(data2[j], data_train_3, def_h_h)#P(x|wk)3
        p_list.append(pw1 * pcp_label1)#P(wk|x)1
        p_list.append(pw2 * pcp_label2)#P(wk|x)2
        p_list.append(pw3 * pcp_label3)#P(wk|x)3
        #record the times of right prediction
        if p_list.index(max(p_list)) == data2[j, 4]:
            right = right + 1
        #print(p_list)
    #print(right)
    return right

if __name__=='__main__':
	#read data
    iris_data = pd.read_csv("iris.data", header=None)
    labels_codes = pd.Categorical(iris_data[4]).codes
    #print(iris_data)
    for i in range(150):
        iris_data.loc[i, 4] = labels_codes[i]
    datalist = iris_data.values.tolist()
    #print(datalist)
    #shuffle data
    random.seed(17)
    random.shuffle(datalist)
    #print(datalist)
    date_set = np.mat(datalist)
    # print(dateset)

    #split data
    data_set = np.vsplit(date_set, 5)
    #print("number of subset:",len(data_set))
    #print(data_set)
    sub_set1 = data_set[0].copy()
    sub_set2 = data_set[1].copy()
    sub_set3 = data_set[2].copy()
    sub_set4 = data_set[3].copy()
    sub_set5 = data_set[4].copy()

    h = 1
    step=0.05
    average_acc=[]
    h_list_cv=[]
    while(h>0):
        cv_acc = []
        for i in range(5):
            data_cv = data_set[4 - i].copy()
            if i == 0:
                data_train = np.vstack((sub_set1, sub_set2, sub_set3, sub_set4))
            elif i == 1:
                data_train = np.vstack((sub_set1, sub_set2, sub_set3, sub_set5))
            elif i == 2:
                data_train = np.vstack((sub_set1, sub_set2, sub_set4, sub_set5))
            elif i == 3:
                data_train = np.vstack((sub_set1, sub_set3, sub_set4, sub_set5))
            else:
                data_train = np.vstack((sub_set2, sub_set3, sub_set4, sub_set5))
            cv_acc.append(def_h(data_train,data_cv,h) / len(data_cv))
        cv_acc=np.mat(cv_acc)
        average_acc.append(np.mean(cv_acc))
        h_list_cv.append(h)
        h=h-step
    #print(average_acc)
    #print(h_list_cv)
    plt.plot(h_list_cv,average_acc)
    plt.xlabel("hyperparameter h")
    plt.ylabel("average accuracy")
    plt.title("Parzen window")
    plt.show()
    h_list=[]
    for x in range(len(average_acc)):
        if average_acc[x]==max(average_acc):
            h_list.append(h_list_cv[x])
    print("highest average accuracy:",round(max(average_acc),3))
    for z in range(len(h_list)):
        h_list[z]=round(h_list[z],2)
    print("corresponding h:",h_list)


from math import degrees
from numpy import angle, arange
from pandas import read_csv
from scipy.optimize import curve_fit
from matplotlib import pyplot
from Fits import *
# define the true objective function
PI = 3.141592653
def objectiveOne(x, a, b):
    return a * x + b

def objectiveTwo(x,a,b,c):
    return a * x + b * x**2 + c

class CurveFit():

    def getParabolicPoints(self,a,b,c):
        x = []
        y = []
        for i in range(600):
            x.append(i+20)
            temp = (int(a * (i-300) + b * (i-300)**2 + c)-240)*-1
            y.append(temp)
            #y.append(int(((a * (i-300) + b * (i-300)**2 + c)-240)*-1))
        #print("x2="+str(x))
        #print("y2="+str(y))
        return x,y

    def getLimits(self,a,b,c=0):
        x_init = 20
        x_end = 620

        if(self.degree==1):
            self.startpoint = (x_init,int(((a*(-300)+b)-240)*-1))
            self.endpoint = (x_end,int(((a*(300)+b)-240)*-1))
        if(self.degree==2):
            #left = 20
            #top = ((a * (-300) + b * (-300)**2 + c)-240)*-1
            #print(top)
            #widht = 600
            #higher = -a/(2*b)
            #height = abs(((a * (higher) + b * (higher)**2 + c)-240)*-1)
            self.x_parabolic,self.y_parabolic = self.getParabolicPoints(a,b,c)

    def FitOne(self):
        # curve fit
        popt, _ = curve_fit(objectiveOne, self.x, self.y)
        # summarize the parameter values
        a, b = popt
        #print('y = %.5f * x + %.5f' % (a, b))
        self.function = str('y = %.5f * x + %.5f' % (a, b))

        self.getLimits(a,b)
        # plot input vs output
        #pyplot.scatter(self.x, self.y)
        # define a sequence of inputs between the smallest and largest known inputs
        self.x_line = arange(min(self.x), max(self.x), 1)
        # calculate the output for the range
        self.y_line = objectiveOne(self.x_line, a, b)

    def FitTwo(self):
        # curve fit
        popt, _ = curve_fit(objectiveTwo, self.x, self.y)
        # summarize the parameter values
        a, b, c = popt
        self.function = str('y = %.5f * x^2 + %.5f * x + %.3f' % (b, a, c))
        self.getLimits(a,b,c)
        #print('y = %.5f * x + %.5f * x^2 + %.5f' % (a, b, c))
        #print(resp)
        # plot input vs output
        #pyplot.scatter(self.x, self.y)
        # define a sequence of inputs between the smallest and largest known inputs
        self.x_line = arange(min(self.x), max(self.x), 1)
        # calculate the output for the range
        self.y_line = objectiveTwo(self.x_line, a, b,c)

    def __init__(self,x,y,degree = 1):
        self.x = x
        self.y = y
        #print("x="+str(x))
        #print("y="+str(y))
        self.degree = degree
        if degree== 1:
            self.FitOne()
        if degree== 2:
            self.FitTwo()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Mar 30 13:05:45 2020

@author: paul
"""
# A SIR model for the spread of Covid-19 virus

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
from pylab import *

N=10000      # Initial population
I=1         # Initially infected people
R=0         # 0 Recovered
S=N-I-R     # Susceptible (N=S+I+R)

beta=4.5         # Rate of infection
gamma=.5           # Rate of recovery

T=14       # Time-play

def SIR(vals,t,b,g):
    S,I,R=vals

    dS=-b*S*I/N     # dS/dt
    dI=b*S*I/N - g*I
    dR=g*I

    return [dS,dI,dR]

t=np.linspace(0,T,1000)
x=[S,I,R]           # Initial params
rates=(beta,gamma)
sol=odeint(SIR,x,t,args=rates)

# Plot ODE solutions
plt.plot(t,sol[:,0])
plt.plot(t,sol[:,1])
plt.plot(t,sol[:,2])

plt.xlabel('Time')
plt.ylabel('Population')
plt.legend(['S','I','R'],shadow=True)
plt.title('COVID')
plt.draw()
savefig("/home/paul/Documents/COVID/"+"diff_b"+str(beta)+"_g"+str(gamma)+".png",dpi=400)


import numpy as np
np.random.seed(1000)

def target_line():
    ''' generate two points, construct two equations , solve for W of the target line'''
    w0 = 1
    point_1 , point_2 = np.random.uniform(-1., 1., size=(2,2))
    # A*W = b
    A = [point_1 , point_2]
    b= [-w0,-w0]
    w1, w2 = np.linalg.solve(A, b)

    return np.array([w0, w1, w2])

def generate_data(N):
    ''' generate data , x0 = 1, x1 & x2 random '''
    data = np.random.uniform(-1., 1., size=(N,2))
    data_set =  np.column_stack((np.ones(N), data))

    return data_set

def prediction(data, W):
    '''classify points '''
    labels = np.sign(data.dot(W))
    return labels

def logistic_regression(D, y_labels):

    d_E = lambda W, x_n, y_n: (-y_n * x_n)/(1+np.exp(y_n * W.dot(x_n)))

    W = np.array([0., 0., 0.])
    old_W = np.copy(W)
    eta = 0.01
    epocs = 0

    while True:
        for i in np.random.permutation(len(y_labels)):
            x_n = D[i]
            y_n = y_labels[i]
            W -= eta*d_E(W,x_n,y_n)

        epocs += 1
        if np.linalg.norm(W - old_W) < 0.01:
            break

        old_W = np.copy(W)

    return W,epocs

# Testing The Algorithm
def cross_entropy(D_test,y_labels,W):
    e = 0
    N = len(y_labels)
    for i in range(N):
        y_n = y_labels[i]
        x_n = D_test[i]

        e += np.log(1+np.exp(-y_n * W.dot(x_n)))

    E_out = e / N
    return E_out

def logistic_test(n):
    E = []
    epocs = []
    for i in range(100):
        target = target_line()
        D = generate_data(100)
        y_labels = prediction(D,target)
        W,epoc = logistic_regression(D,y_labels)

        D_test = generate_data(n)
        test_labels = prediction(D_test,target)

        E_out = cross_entropy(D_test,test_labels,W)

        E.append(E_out)
        epocs.append(epoc)

    average_error = np.mean(E)
    average_epocs = np.mean(epocs)
    return average_error,average_epocs

average_error,average_epocs = logistic_test(100)
print('Error:', average_error)
print('Epochs: ', average_epocs)


#Calculation of the Posterior Distribution of the Bias of a Coin from a Polynomial Prior.
#Brendan Cordy, 2014

from matplotlib import pyplot
from numpy.linalg import solve

#An object to represent the history of priors/posteriors before/after each flip.
class Dist_Sequence(object):
	def __init__(self, bins):
		self.bins = bins
		self.heads = 0
		self.tails = 0
		self.probs = [x / (float(bins) - 1) for x in range(0,bins)]
		self.dist_list = []

	def add_prior(self, p_dist):
		self.dist_list = []
		self.dist_list.append(p_dist)

	def add_heads_posterior(self, p_dist):
		self.dist_list.append(p_dist)
		self.heads += 1

	def add_tails_posterior(self, p_dist):
		self.dist_list.append(p_dist)
		self.tails += 1

	def get_dist(self, n):
		return self.dist_list[n]

	def get_last_dist(self):
		return self.dist_list[-1]

#Define a polynomial, to be used as a prior, from a list of points.
def define_prior(point_list, dist_seq):
	#Determine the unique polynomial of degree len(point_list) through the points in point_list.
	a = [[p[0]**n for n in range(0, len(point_list))] for p in point_list]
	b = [p[1] for p in point_list]
	poly_coeff = solve(a,b)

	#Initialize the distribution of p to the polynomial computed above.
	prior_poly = [sum([c * x**j for j, c in enumerate(poly_coeff)]) for x in dist_seq.probs]

	#Check the prior can be scaled to a density curve (never lies below the axis), and normalize it.
	neg = 0
	for x in prior_poly:
		if x < 0:
			neg = 1
	if neg == 1:
		p_dist = [1 for x in range(0,dist_seq.bins)]
		print "Invalid Prior: Interpolated distribution isn't non-negative."
	else:
		dist_seq.add_prior(normalize(prior_poly,dist_seq.bins))

#Normalize p_dist to a pmf while preserving proportions.
def normalize(p_dist, bins):
	#Sum the probabilties and divide each entry by the result.
	totalweight = 0
	for r in range(0, bins):
		totalweight += p_dist[r]
	for r in range(0, bins):
		p_dist[r] = p_dist[r] / float(totalweight)

	#Return the normalized prior.
	return p_dist

#Update after observing a head.
def flip_heads(dist_seq):
	prior = dist_seq.get_last_dist()
	p_dist = []

	#Calculate the total probability of flipping a head.
	prob_h = 0
	for i in range(0, dist_seq.bins):
		prob_h += (1 / float(dist_seq.bins)) * i * prior[i]

	#Update the probability of each value of p using Bayes' rule.
	for i in range(0, dist_seq.bins):
		p_dist.append(((1 / float(dist_seq.bins)) * i * prior[i]) / prob_h)

	dist_seq.add_heads_posterior(p_dist)

#Update after observing a tail.
def flip_tails(dist_seq):
	prior = dist_seq.get_last_dist()
	p_dist = []

	#Calculate the total probability of flipping a tail.
	prob_t = 0
	for i in range(0, dist_seq.bins):
		prob_t += (1 / float(dist_seq.bins)) * (dist_seq.bins - i - 1) * prior[i]

	#Update the probability of each value of p using Bayes' rule.
	for i in range(0, dist_seq.bins):
		p_dist.append(((1 / float(dist_seq.bins)) * (dist_seq.bins - i - 1) * prior[i]) / prob_t)

	dist_seq.add_tails_posterior(p_dist)

#Draw the current distribution of the probability of heads.
def draw(dist_seq):
	#Draw prior in dashed black.
	pyplot.plot(dist_seq.probs, dist_seq.get_dist(0), '--', color='black')

	#Draw intermediates in shades of grey.
	n = len(dist_seq.dist_list) - 1
	for i in range(1, n):
			pyplot.plot(dist_seq.probs, dist_seq.get_dist(i), '-', color = 'grey', alpha = (i + 1) / float(n + 1))

	#Draw posterior in red.
	pyplot.plot(dist_seq.probs, dist_seq.get_last_dist(), '-', color='red')

	frame = pyplot.gca()
	frame.set_title('Distribution of the Probability of Heads after ' + str(dist_seq.heads) + ' Heads and ' + str(dist_seq.tails) + ' Tails')
	frame.axes.get_yaxis().set_ticks([])
	pyplot.show()

def main():
	dist_history = Dist_Sequence(1001)

	#Have the user define a prior.
	point_list = input('Enter a list of points in [0,1] x R+ to define a prior: ')
	define_prior(point_list, dist_history)

	#Have the user flip the coin.
	flip_result = raw_input('Flip the coin (H for heads, T for tails, D for done): ')

	while(flip_result != 'D'):
		if(flip_result == 'H'):
				flip_heads(dist_history)
		if(flip_result == 'T'):
				flip_tails(dist_history)
		flip_result = raw_input('Flip the coin (H for heads, T for tails, D for done): ')

	#Show the resulting sequence of distributions
	draw(dist_history)

if __name__ == '__main__':
    main()


import numpy as np
import math
import cv2
import copy
from PIL import Image
import matplotlib.pyplot as plt

from scipy.ndimage import gaussian_filter
from scipy.ndimage import sobel

class EdgeDetection:
    def __init__(self):
        self.threshold_1 = 60
        self.threshold_2 = 30

    def calc_offset(self, angle):

        epsilon = 0.0001

        if abs(math.cos(angle)) < epsilon:
            dk = 0
        else:
            dk = math.cos(angle) / abs(math.cos(angle))

        if abs(math.sin(angle)) < epsilon:
            dl = 0
        else:
            dl = math.sin(angle) / abs(math.sin(angle))

        return [int(round(dl)), int(round(dk))]

    def round_angles(self, angles):
        ret_angles = np.zeros((len(angles), len(angles[0])))
        comp = math.pi / 8

        for i in range(0, len(angles)):
            for j in range (0, len(angles[0])):
                for k in range(-4, 5):
                    ret_angles[i][j] = k * math.pi / 4 if abs(angles[i][j] - k * math.pi / 4) <= comp else ret_angles[i][j]

        return ret_angles

    def operator(self, operande):
        filtered_image = gaussian_filter(operande, 2)

        sobel_x = cv2.Sobel(filtered_image, cv2.CV_64F, 1, 0, ksize=5)
        sobel_y = cv2.Sobel(filtered_image, cv2.CV_64F, 0, 1, ksize=5)

        grad_mags = np.sqrt(np.square(np.array(sobel_x)) + np.square(np.array(sobel_y)))

        grad_angles = self.round_angles(np.arctan2(np.array(sobel_y), np.array(sobel_x)))

        return [grad_mags, grad_angles]

    def non_maxima_supp(self, grad_image):
        grad_mags = grad_image[0].tolist()
        grad_angles = grad_image[1].tolist()

        for i in range(0, len(grad_mags)):
            for j in range(0, len(grad_mags[i])):
                if i == 0 or j == 0 or i == len(grad_mags) - 1 or j == len(grad_mags[i]) - 1:
                    grad_mags[i][j] = 0

        grad_mags_ret = np.zeros((len(grad_mags), len(grad_mags[0]))).tolist()

        for i in range(0, len(grad_mags)):
            for j in range(0, len(grad_mags[i])):
                if grad_mags[i][j] > 0:

                    offset = self.calc_offset(grad_angles[i][j])

                    di = offset[0]
                    dj = offset[1]

                    if grad_mags[i][j] >= grad_mags[i + di][j + dj] and grad_mags[i][j] >= grad_mags[i - di][j - dj]:
                        grad_mags_ret[i][j] = grad_mags[i][j]

        grad_mags_ret = ((grad_mags_ret - np.amin(np.amin(grad_mags_ret, 1), 0)) / (np.amax(np.amax(grad_mags_ret, 1), 0)
                          - np.amin(np.amin(grad_mags_ret, 1), 0))) * 255
        grad_mags_ret = grad_mags_ret.astype(int)

        return grad_mags_ret

    #calculate the mask in function of the tresholds.
    #2 indicates a strong edge. 1 indicates a weak edge. 0 indicates a edge to cut
    def class_thresholding(self, image_maxima):
        mask = np.zeros((len(image_maxima), len(image_maxima[0]))).astype('uint8')
        for i in range(0, len(image_maxima)):
            for j in range(0, len(image_maxima[i])):
                if image_maxima[i][j] > self.threshold_1:
                    mask[i][j] = 2
                elif image_maxima[i][j] < self.threshold_1 and image_maxima[i][j] > self.threshold_2:
                    mask[i][j] = 1
        return mask

    def hysterisis_rec(self, mask, l, k, old_l, old_k):
        if (mask[l][k] == 2):
            return True

        no_more_edge = True
        for m in range(-1, 1):
            for n in range(-1, 1):
                if not(m == 0 and n == 0) and not(old_l == l + m and old_k == k + n):
                    no_more_edge = False if mask[l + m][k + n] != 0 else no_more_edge

        if no_more_edge:
            return False

        res = False
        for m in range(-1, 1):
            for n in range(-1, 1):
                if not(m == 0 and n == 0) and not(old_l == l + m and old_k == k + n) and (mask[l + m][k + n] != 0):
                    res = res or self.hysterisis_rec(mask, l + m, k + n, l, k)

        return res

    def hysterisis(self, mask, maxima):
        for i in range(0, len(maxima)):
            for j in range(0, len(maxima[i])):
                if mask[i][j] == 1:
                    is_strong = self.hysterisis_rec(mask, i, j, i, j)
                    if is_strong:
                        mask[i][j] = 2
                    else:
                        mask[i][j] = 0

        return mask

    def apply_mask(self, mask, maxima):
        mask = (mask / 2)

        return (np.multiply(mask, np.array(maxima))).tolist()

    def detect_edges(self, image):

        grad_image = self.operator(image)

        image_maxima = self.non_maxima_supp(grad_image)

        mask = self.class_thresholding(image_maxima)

        updated_mask = self.hysterisis(mask, image_maxima)

        return self.apply_mask(updated_mask, image_maxima)


# --------------
# Code starts here

import numpy as np

# Code starts here

# Adjacency matrix
adj_mat = np.array([[0,0,0,0,0,0,1/3,0],
                   [1/2,0,1/2,1/3,0,0,0,0],
                   [1/2,0,0,0,0,0,0,0],
                   [0,1,0,0,0,0,0,0],
                  [0,0,1/2,1/3,0,0,1/3,0],
                   [0,0,0,1/3,1/3,0,0,1/2],
                   [0,0,0,0,1/3,0,0,1/2],
                   [0,0,0,0,1/3,1,1/3,0]])

# Compute eigenvalues and eigencevectrs
values,vectors=np.linalg.eig(adj_mat)
print('eigenvalues',values, 'eigenvectors',vectors)

# Eigen vector corresponding to 1
eigen_1=abs(vectors[:,0])/np.linalg.norm(vectors[:,0],1)
print('eigen_1',eigen_1)

# most important page
page=np.where(np.max(eigen_1) == eigen_1)[0][0] + 1

print('page', page)

# Code ends here

# --------------
# Code starts here
import numpy as np
# Initialize stationary vector I
adj_mat = np.array([[0,0,0,0,0,0,1/3,0],
                   [1/2,0,1/2,1/3,0,0,0,0],
                   [1/2,0,0,0,0,0,0,0],
                   [0,1,0,0,0,0,0,0],
                  [0,0,1/2,1/3,0,0,1/3,0],
                   [0,0,0,1/3,1/3,0,0,1/2],
                   [0,0,0,0,1/3,0,0,1/2],
                   [0,0,0,0,1/3,1,1/3,0]])
print('adj_mat',adj_mat)

init_I=np.array([1,0,0,0,0,0,0,0])
print('init_I', init_I)
# Perform iterations for power method
for i in range(10):
    init_I = np.dot(adj_mat, init_I)
    init_I /= np.linalg.norm(init_I, 1)

print(init_I)
power_page = np.where(np.max(init_I) == init_I)[0][0] + 1
print(power_page)

# Code ends here

# --------------
# Code starts here

# New Adjancency matrix
# New Adjancency matrix
new_adj_mat = np.array([[0,0,0,0,0,0,0,0],
                   [1/2,0,1/2,1/3,0,0,0,0],
                  [1/2,0,0,0,0,0,0,0],
                   [0,1,0,0,0,0,0,0],
                   [0,0,1/2,1/3,0,0,1/2,0],
                   [0,0,0,1/3,1/3,0,0,1/2],
                   [0,0,0,0,1/3,0,0,1/2],
                   [0,0,0,0,1/3,1,1/2,0]])

# Initialize stationary vector I
new_init_I= np.array([1,0,0,0,0,0,0,0])
# Perform iterations for power method
for i in range(10):
    new_init_I=np.dot(new_adj_mat,new_init_I)
    new_init_I/=np.linalg.norm(new_init_I,1)
    print(new_init_I)

# Code ends here

# --------------
# Alpha value
alpha = 0.85

# Code starts here
import numpy as np
# Modified adjancency matrix
n=len(new_adj_mat)
I=np.ones(new_adj_mat.shape)
G=alpha*new_adj_mat+(I-alpha)*1/n*I
print('G',G)

# Initialize stationary vector I
final_init_I = np.array([1,0,0,0,0,0,0,0])
print('final_init_I',final_init_I)
# Perform iterations for power method
for i in range (1000):
    final_init_I=np.dot(G,final_init_I)
    final_init_I/=np.linalg.norm(final_init_I,1)
print(final_init_I)
# Code ends here


import keras
print(keras.__version__)  # 2.2.4

# 6.2 RNN introduction

# RNN pseudo code
input_sequence = []

def f(_input, state):
    new_state = _input + state  # made up for def below
    return new_state

def rnn_pseudo_code():
    state_t = 0
    for input_t in input_sequence:
        output_t = f(input_t, state_t)
        state_t = output_t

# detailed RNN pseudo code
# W, U, b = 1, 2, 3

def dot(y, z):
    pass

def activation(x):
    return x

def rnn_pseudo_code_detailed():
    state_t = 0
    for input_t in input_sequence:
        output_t = activation(dot(W, input_t) + dot(U, state_t) + b)
        state_t = output_t

# RNN Numpy
import numpy as np

timesteps = 100
input_features = 32
output_features = 64

inputs = np.random.random((timesteps, input_features))
state_t = np.zeros((output_features, ))

W = np.random.random((output_features, input_features))
U = np.random.random((output_features, output_features))
b = np.random.random((output_features, ))

successive_outputs = []
for input_t in inputs:  # input_t.shape: (input_features, ) and it loops in inputs' timesteps(timesteps, input_features)
    output_t = np.tanh(np.dot(W, input_t) + np.dot(U, state_t) + b)  # tanh: tan    dot: no matter dimensions of params
    successive_outputs.append(output_t)
    state_t = output_t

final_output_sequence = np.stack(successive_outputs, axis=0)  # refer to cloud note's math concept: dimension

print('6.2 RNN introduction done')
print('---------------------------------------------------------------------------------------------------------------')

# 6.2.1 RNN in Keras introduction

from keras.models import Sequential
from keras.layers import Embedding, SimpleRNN

# RNN layer shows the final output of each sequence only
model = Sequential()
model.add(Embedding(10000, 32))
model.add(SimpleRNN(32))
print(model.summary())
'''
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
embedding_1 (Embedding)      (None, None, 32)          320000
_________________________________________________________________
simple_rnn_1 (SimpleRNN)     (None, 32)                2080      # rnn layer output: (batch, output_features)
=================================================================
Total params: 322,080
Trainable params: 322,080
Non-trainable params: 0
_________________________________________________________________
'''

# RNN layer shows all output at each time step of each sequence including the final output
model = Sequential()
model.add(Embedding(10000, 32))
model.add(SimpleRNN(32, return_sequences=True))  # not only the final output, the rnn layer will show the whole sequence
print(model.summary())
"""
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
embedding_2 (Embedding)      (None, None, 32)          320000
_________________________________________________________________
simple_rnn_2 (SimpleRNN)     (None, None, 32)          2080      # rnn layer output: (batch, timesteps, output_features)
=================================================================
Total params: 322,080
Trainable params: 322,080
Non-trainable params: 0
_________________________________________________________________
"""

# multi-RNN layers stack: need to show the whole output of each sequence in each layer, not necessary for the last RNN.
model = Sequential()
model.add(Embedding(10000, 32))
model.add(SimpleRNN(32, return_sequences=True))
model.add(SimpleRNN(32, return_sequences=True))
model.add(SimpleRNN(32, return_sequences=True))
model.add(SimpleRNN(32))  # This last layer only returns the last outputs.
print(model.summary())
'''
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
embedding_3 (Embedding)      (None, None, 32)          320000
_________________________________________________________________
simple_rnn_3 (SimpleRNN)     (None, None, 32)          2080
_________________________________________________________________
simple_rnn_4 (SimpleRNN)     (None, None, 32)          2080
_________________________________________________________________
simple_rnn_5 (SimpleRNN)     (None, None, 32)          2080
_________________________________________________________________
simple_rnn_6 (SimpleRNN)     (None, 32)                2080      # the last RNN may show the whole sequence or not.
=================================================================
Total params: 328,320
Trainable params: 328,320
Non-trainable params: 0
_________________________________________________________________
'''

print('6.2.1 RNN in Keras introduction done')
print('---------------------------------------------------------------------------------------------------------------')

# IMDB reviews classification by RNN in Keras

# data pre-processing
from keras.datasets import imdb
from keras.preprocessing import sequence

max_features = 10000  # number of words to consider as features
maxlen = 500  # cut texts after this number of words (among top max_features most common words)
batch_size = 32

print('Loading data...')
(input_train, y_train), (input_test, y_test) = imdb.load_data(num_words=max_features)
print(len(input_train), 'train sequences')
print(len(input_test), 'test sequences')

print('Pad sequences (samples x time)')
input_train = sequence.pad_sequences(input_train, maxlen=maxlen)  # refer to pad_sequence's definition
input_test = sequence.pad_sequences(input_test, maxlen=maxlen)
print('input_train shape:', input_train.shape)
print('input_test shape:', input_test.shape)

# build network model
from keras.layers import Dense

model = Sequential()
model.add(Embedding(max_features, 32))
model.add(SimpleRNN(32))  # only show the final output
model.add(Dense(1, activation='sigmoid'))

model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc'])
history = model.fit(input_train, y_train,
                    epochs=10,
                    batch_size=128,
                    validation_split=0.2)
# loss: 0.0186 - acc: 0.9947 - val_loss: 0.6927 - val_acc: 0.8062 not good because review is cut for 500 words.

# plot
import matplotlib.pyplot as plt

acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(len(acc))

plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()

plt.figure()

plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()

plt.show()

print('IMDB reviews classification by RNN in Keras done')
print('---------------------------------------------------------------------------------------------------------------')


#!/usr/bin/env python3
#-*- coding: utf-8 -*-
"""
Filename: categorical
Date: 2019-05-09 11:28
Project: mymldev
AUTHOR: Suneel Dondapati
"""

import numpy as np
import pandas as pd
import scipy.stats as ss

__all__ = [
    'cramers_corrected_stat',
]

def cramers_corrected_stat(confusion_matrix: pd.DataFrame):
    """Calculate bias corrected cramer's V

    Arguments:
    ----------
    confusion_matrix: pd.DataFrame
        Contingency table of two nominal variables

    Returns:
    --------
    cramers_v: float
        Cramer's V value for the input nominal variables

    Examples:
    --------
    >>> cramers_corrected_stat(pd.crosstab(df['More customer service calls'], df['Churn_Flag']))
    0.3136

    References:
    -----------
    Cramer's V is the measure of association between two
    nominal variables, giving a value between 0 and +1
    '0' corresponds to no association
    '1' corresponds to complete association, value can reach 1
    only when two variables are equal to each other.

    [1] https://en.wikipedia.org/wiki/Cram%C3%A9r%27s_V
    """
    chi2 = ss.chi2_contingency(confusion_matrix)[0]
    n = confusion_matrix.sum().sum()
    phi2 = chi2 / n
    r, k = confusion_matrix.shape
    phi2corr = max(0, phi2 - ((k - 1) * (r - 1) / (n - 1)))
    rcorr = r - ((r - 1) ** 2) / (n - 1)
    kcorr = k - ((k - 1) ** 2) / (n - 1)
    cramers_v = np.sqrt(phi2corr / min((kcorr - 1), (rcorr - 1)))
    return cramers_v


import math
import numpy as np

def norm(x):
    return np.sqrt(np.sum(np.square(x)))

def convert_column(x):
    new_x = np.array(x)[np.newaxis]
    transposed = new_x.T
    return transposed

def calculateR(q, v):
    transposed_column_v = convert_column(v)
    r = np.dot(q, transposed_column_v)[0]
    return r

def qr(matrix):
    a = []
    q = []
    transpost_matrix = np.transpose(matrix)
    r_matrix = np.array(list(transpost_matrix))
    r_matrix.fill(0)

    for vectorId in range(len(transpost_matrix)):
        vector = transpost_matrix[vectorId]

        value = vector
        for qId in range(len(q)):
            r = calculateR(q[qId], vector)
            r_matrix[qId][vectorId] = r
            value -= r * q[qId]

        a.append(value)
        norm_a = norm(a[vectorId])
        q.append(a[vectorId] / norm_a)
        r_matrix[vectorId][vectorId] = calculateR(q[vectorId], vector)

    return np.transpose(q), r_matrix

def qr_method(a, k):
    for i in range(k):
        print('K = {}'.format(i))

        q, r = qr(a)
        a = np.dot(r, q)

        print('Q = ')
        pp(q)
        print('R = ')
        pp(r)
        print('A = ')
        pp(a)


import numpy as np
import matplotlib.pyplot as plt

def ljPotential(r, sigma, epsilon):
    u = 4. * epsilon * ( ((sigma/r)**12) - ((sigma/r)**6) )
    return u

def ljForce(r, sigma, epsilon):
    f = 24. * epsilon * ( (2*((sigma**12)/(r**13))) - ((sigma**6)/(r**7)) )
    return f

def compEps(pe):
    epsB = 10.
    eps = ((4. * pe) / 24.) + epsB
    return eps

def compSig(pe):
    m = -0.095771
    b = 0.307
    sig = (pe**m) * np.exp(b)
    return sig

# Get input values for my functions
rs = np.arange(0., 2., 0.0001)
pes = np.arange(50., 550., 50.)
rSoft = 2**(1./6.)

fig, ax = plt.subplots(1, 2, figsize=(10, 5))

# Plot the soft data
softPots = ljPotential(rs, 1.0, 1.0)
softForce = ljForce(rs, 1.0, 1.0)
ax[0].plot(rs, softPots, c='k')
ax[1].plot(rs, softForce, c='k')

for i in pes:
    # Grab epsilon and sigma
    inSig = compSig(i)
    inEps = compEps(i)
    # Compute the potentials and forces for each system
    hardPots = ljPotential(rs, inSig, inEps)
    hardForce = ljForce(rs, inSig, inEps)
    ax[0].plot(rs, hardPots, c=plt.cm.jet(i / 500.))
    ax[1].plot(rs, hardForce, c=plt.cm.jet(i / 500.), label=str(i))

potMax = ljPotential(0.7, compSig(500.), compEps(500.))
forMax = ljForce(0.7, compSig(500.), compEps(500.))

ax[0].set_xlim(0.7, 2.0)
ax[0].set_ylim(-inEps * 1.1, potMax)
ax[1].set_xlim(0.7, rSoft)
ax[1].set_ylim(0., forMax)

# Is there any significance to the crossing point?
#ax[0].axvline(x=(compSig(100) * (2.**(1./6.)) ))
#ax[1].axvline(x=(compSig(100) * (2.**(1./6.)) ))
#ax[0].axvline(x=(compSig(100) ))
#ax[1].axvline(x=(compSig(100) ))

ax[0].set_ylabel(r'$U_{LJ}$')
ax[1].set_ylabel(r'$F_{LJ}$')
ax[0].set_xlabel(r'$r(i,j)$')
ax[1].set_xlabel(r'$r(i,j)$')
cbar = ax[1].legend()
cbar.set_title('Activity')
plt.tight_layout()
plt.savefig('smallHS.png', dpi=1000)


'''
In order to visualize two-dimensional arrays of data, it is necessary to understand how to generate and manipulate 2-D arrays. Many Matplotlib plots support arrays as input and in particular, they support NumPy arrays. The NumPy library is the most widely-supported means for supporting numeric arrays in Python.

In this exercise, you will use the meshgrid function in NumPy to generate 2-D arrays which you will then visualize using plt.imshow(). The simplest way to generate a meshgrid is as follows:

import numpy as np
Y,X = np.meshgrid(range(10),range(20))

This will create two arrays with a shape of (20,10), which corresponds to 20 rows along the Y-axis and 10 columns along the X-axis. In this exercise, you will use np.meshgrid() to generate a regular 2-D sampling of a mathematical function.
'''
# Import numpy and matplotlib.pyplot
import numpy as np
import matplotlib.pyplot as plt

# Generate two 1-D arrays: u, v
u = np.linspace(-2, 2, 41)
v = np.linspace(-1, 1, 21)

# Generate 2-D arrays from u and v: X, Y
X,Y = np.meshgrid(u, v)

# Compute Z based on X and Y
Z = np.sin(3*np.sqrt(X**2 + Y**2))

# Display the resulting image with pcolor()
plt.pcolor(Z)
plt.show()

# Save the figure to 'sine_mesh.png'
plt.savefig('sine_mesh.png')

7 - introduction to data visualization with python/pyplot/generating meshes.py