#!/usr/bin/python

'''
mjtsai1974@20180606, v1.1, scipy.norm for Gaussian normal distribution illustration

http://www.astroml.org/book_figures/chapter3/fig_gaussian_distribution.html

dist = scipy.stats.norm(...)

Where ... should be filled in with the desired distribution parameters Once we have defined the distribution parameters in this way, these distribution objects have many useful methods; for example:

    dist.pmf(x) computes the Probability Mass Function at values x in the case of discrete distributions
    dist.pdf(x) computes the Probability Density Function at values x in the case of continuous distributions
    dist.rvs(N) computes N random variables distributed according to the given distribution
'''

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

#----------------------------------------------------------------------
# This function adjusts matplotlib settings for a uniform feel in the textbook.
# Note that with usetex=True, fonts are rendered with LaTeX.  This may
# result in an error if LaTeX is not installed on your system.  In that case,
# you can set usetex to False.
from astroML.plotting import setup_text_plots
setup_text_plots(fontsize=8, usetex=False)

# Define the distributions to be plotted
sigma_values = [0.5, 1.0, 2.0]
linestyles = ['-', '--', ':']
mu = 0
x = np.linspace(-10, 10, 1000)

# plot the distributions
fig, ax = plt.subplots(figsize=(5, 3.75))

for sigma, ls in zip(sigma_values, linestyles):
    # create a gaussian / normal distribution
    dist = norm(mu, sigma)

    plt.plot(x, dist.pdf(x), ls=ls, c='black',
             label=r'$\mu=%i,\ \sigma=%.1f$' % (mu, sigma))

plt.xlim(-5, 5)
plt.ylim(0, 0.85)

plt.xlabel('$x$')
plt.ylabel(r'$p(x|\mu,\sigma)$')
plt.title('Gaussian Distribution')

plt.legend()
plt.show()


import numpy as np

def intersect_lines(p0, q0, p1, q1):
    """
    Intersect two lines in 3d: (p0, q0) and (p1, q1). Each should be a 3D
    point.

    See also:
        https://math.stackexchange.com/a/271366/640314
    """
    e = p0 - q0  # direction of line 0
    f = p1 - q1  # direction of line 1

    # Check for special case where we're given the intersection
    # Note that we must check for these, because if p0 == p1 then
    # g would be zero length and we can't continue
    if np.all(p0 == p1) or np.all(p0 == q1):
        return p0
    if np.all(q0 == p1) or np.all(p0 == q1):
        return q0

    g = p0 - p1  # line between to complete a triangle
    h = np.cross(f, g)
    k = np.cross(f, e)
    h_ = np.linalg.norm(h)
    k_ = np.linalg.norm(k)
    if h_ == 0 or k_ == 0:
        # There is no intesection; either parallel (k=0) or collinear (both=0) lines.
        return None

    # Check for the special case of lines in parallel planes.
    # https://math.stackexchange.com/a/697278/640314
    if np.dot(g, k) != 0:
        return None

    l = h_ / k_ * e  # noqa: E741
    sign = -1 if np.all(h / h_ == k / k_) else +1
    return p0 + sign * l

def intersect_2d_lines(p0, q0, p1, q1):
    """
    Intersect two lines: (p0, q0) and (p1, q1). Each should be a 2D
    point.
    """
    # Adapted from http://stackoverflow.com/a/26416320/893113
    dy = q0[1] - p0[1]
    dx = q0[0] - p0[0]
    lhs0 = [-dy, dx]
    rhs0 = p0[1] * dx - dy * p0[0]

    dy = q1[1] - p1[1]
    dx = q1[0] - p1[0]
    lhs1 = [-dy, dx]
    rhs1 = p1[1] * dx - dy * p1[0]

    a = np.array([lhs0, lhs1])
    b = np.array([rhs0, rhs1])

    try:
        return np.linalg.solve(a, b)
    except np.linalg.LinAlgError:
        return None


import matplotlib.pyplot as plt
from skimage import io
import numpy as np
import numpy.matlib

file_name='./data/sample/v2.jfif'
img=io.imread(file_name)

row, col, channel = img.shape

img = img * 1.0

center_x = (col-1)/2.0
center_y = (row-1)/2.0

xx = np.arange (col)
yy = np.arange (row)

e = col*1.0/row

x_mask = numpy.matlib.repmat (xx, row, 1)
y_mask = numpy.matlib.repmat (yy, col, 1)
y_mask = np.transpose(y_mask)

xx_dif = x_mask - center_x
yy_dif = center_y - y_mask

theta = np.arctan2(yy_dif*e, xx_dif+0.0001)

mask_1 = yy_dif < 0

theta = theta * (1 - mask_1) + (theta + 3.1415 * 2) * mask_1

r1 = yy_dif / np.sin(theta)
y1_mask = r1 * 2.0
x1_mask = theta * col / (2 * 3.1415)

# mask = (x1_mask > 0) * (x1_mask < 1)
# x1_mask = x1_mask * (1 - mask ) + ( x1_mask * mask + 1 ) * mask

mask = x1_mask < 0
x1_mask = x1_mask * (1 - mask)
mask = x1_mask > (col - 1)
x1_mask = x1_mask * (1 - mask) + (x1_mask * 0 + col -2) * mask

mask = y1_mask < 0
y1_mask = y1_mask * (1 - mask)
mask = y1_mask > (row -1)
y1_mask = y1_mask * (1 - mask) + (y1_mask * 0 + row -2) * mask

int_x = np.floor (x1_mask)
int_x = int_x.astype(int)
int_y = np.floor (y1_mask)
int_y = int_y.astype(int)

p_mask = x1_mask - int_x
q_mask = y1_mask - int_y

img_out = img * 1.0

for ii in range(row):
    for jj in range (col):
        new_xx = int_x [ii, jj]
        new_yy = int_y [ii, jj]
        p = p_mask[ii, jj]
        q = q_mask[ii, jj]

        img_out[ii, jj, :] = img[new_yy, new_xx, :]

'''
        img_out[ii, jj, :] = (1-p)*(1-q)*img[new_yy, new_xx, :]
        + p*(1-q)*img[new_yy, new_xx+1, :]
        + q*(1-p)*img[new_yy+1, new_xx, :]
        + p*q*img[new_yy+1, new_xx+1, :]
'''

img_out = img_out / 255.0

plt.figure (1)
plt.imshow (img/255.0)
plt.axis('off')

plt.figure (2)
plt.imshow (img_out)
plt.axis('off')

plt.show()

quantification of visual perception changes based on spatial data of streets in the driverless city/deprecated/cartesian2polar.py


"""
Numerical integration of the SIR disease model
"""

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

# right hand side of the equation
def compute_SIR_rhs(y, t, N, beta, gamma):
    S, I, R = y
    dSdt = - beta * I * S / N # number of uninfected people
    dIdt = beta * I * S / N - gamma * I # number of infected people
    dRdt = gamma * I # number of recovert people
    return dSdt, dIdt, dRdt

# parameters
beta = 1 / 1.0 # = 1 / time between contacts between people
N = 100 # = number of people
gamma = 1 / 14.0 # = 1 / time until recovery
args = (N, beta, gamma)
initial_infected_ratio = 1e-4
num_infected = initial_infected_ratio * N
y0 = (N - num_infected, num_infected, 0)

if __name__ == "__main__":
    # integrate the system
    t_s = np.linspace(0, 8 / gamma, 400)
    S, I, R = odeint(compute_SIR_rhs, y0, t_s, args).T

    # plot the result
    plt.plot(t_s, S, label="S")
    plt.plot(t_s, I, label="I")
    plt.plot(t_s, R, label="R")
    plt.xlabel("t")
    plt.ylabel("number of people")
    plt.title(r"SIR disease model with $N = %i, \beta = %.2f, \gamma = %.2f$" % args)
    plt.text(t_s[len(t_s) // 2], N / 2,
            r"$\frac{\mathrm{d} S}{\mathrm{d} t} = - \beta I S / N$" + "\n" +
            r"$\frac{\mathrm{d}I}{\mathrm{d}t} = \beta I S / N - \gamma I$" + "\n" +
            r"$\frac{\mathrm{d}R}{\mathrm{d}t} = \gamma I$")
    plt.legend()
    plt.show()


# the functions used in the application are here
import numpy as np
import matplotlib.pyplot as plt
import h5py

def sigmoid(Z):
    A = 1/(1+np.exp(-Z))
    cache = Z
    return A, cache

def relu(Z):
    A = np.maximum(0,Z)
    assert(A.shape == Z.shape)
    cache = Z
    return A, cache

def relu_backward(dA, cache):
    Z = cache
    dZ = np.array(dA, copy=True)
    dZ[Z <= 0] = 0
    assert (dZ.shape == Z.shape)
    return dZ

def sigmoid_backward(dA, cache):
    Z = cache
    s = 1/(1+np.exp(-Z))
    dZ = dA * s * (1-s)
    return dZ

def load_data():

    train_dataset = h5py.File('datasets/<your .h5 file>', "r")
    train_set_x_orig = np.array(train_dataset["train_set_x"][:])
    train_set_y_orig = np.array(train_dataset["train_set_y"][:])

    test_dataset = h5py.File('datasets/<your .h5 file>', "r")
    test_set_x_orig = np.array(test_dataset["test_set_x"][:])
    test_set_y_orig = np.array(test_dataset["test_set_y"][:])

    classes = np.array(test_dataset["list_classes"][:])
    train_set_y_orig = train_set_y_orig.reshape((1, train_set_y_orig.shape[0]))
    test_set_y_orig = test_set_y_orig.reshape((1, test_set_y_orig.shape[0]))

    return train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes

def initialize_parameters_deep(layer_dims):

    np.random.seed(1)
    parameters = {}
    L = len(layer_dims)

    for l in range(1, L):
        parameters['W' + str(l)] = np.random.randn(layer_dims[l], layer_dims[l-1]) / np.sqrt(layer_dims[l-1])
        parameters['b' + str(l)] = np.zeros((layer_dims[l], 1))

        assert(parameters['W' + str(l)].shape == (layer_dims[l], layer_dims[l-1]))
        assert(parameters['b' + str(l)].shape == (layer_dims[l], 1))

    return parameters

#Forward Propagation
def linear_forward(A, W, b):

    Z = W.dot(A) + b

    assert(Z.shape == (W.shape[0], A.shape[1]))
    cache = (A, W, b)

    return Z, cache

def linear_activation_forward(A_prev, W, b, activation):

    if activation == "sigmoid":

        Z, linear_cache = linear_forward(A_prev, W, b)
        A, activation_cache = sigmoid(Z)

    elif activation == "relu":

        Z, linear_cache = linear_forward(A_prev, W, b)
        A, activation_cache = relu(Z)

    assert (A.shape == (W.shape[0], A_prev.shape[1]))
    cache = (linear_cache, activation_cache)

    return A, cache

def L_model_forward(X, parameters):

    caches = []
    A = X
    L = len(parameters) // 2
    for l in range(1, L):
        A_prev = A
        A, cache = linear_activation_forward(A_prev, parameters['W' + str(l)], parameters['b' + str(l)], activation = "relu")
        caches.append(cache)

    AL, cache = linear_activation_forward(A, parameters['W' + str(L)], parameters['b' + str(L)], activation = "sigmoid")
    caches.append(cache)

    assert(AL.shape == (1,X.shape[1]))

    return AL, caches

#Computing Cost
def compute_cost(AL, Y):
    m = Y.shape[1]
    cost = (1./m) * (-np.dot(Y,np.log(AL).T) - np.dot(1-Y, np.log(1-AL).T))

    cost = np.squeeze(cost)
    assert(cost.shape == ())

    return cost

#Backward Propagation
def linear_backward(dZ, cache):

    A_prev, W, b = cache
    m = A_prev.shape[1]

    dW = 1./m * np.dot(dZ,A_prev.T)
    db = 1./m * np.sum(dZ, axis = 1, keepdims = True)
    dA_prev = np.dot(W.T,dZ)

    assert (dA_prev.shape == A_prev.shape)
    assert (dW.shape == W.shape)
    assert (db.shape == b.shape)

    return dA_prev, dW, db

def linear_activation_backward(dA, cache, activation):

    linear_cache, activation_cache = cache

    if activation == "relu":
        dZ = relu_backward(dA, activation_cache)
        dA_prev, dW, db = linear_backward(dZ, linear_cache)

    elif activation == "sigmoid":
        dZ = sigmoid_backward(dA, activation_cache)
        dA_prev, dW, db = linear_backward(dZ, linear_cache)

    return dA_prev, dW, db

def L_model_backward(AL, Y, caches):

    grads = {}
    L = len(caches)
    m = AL.shape[1]
    Y = Y.reshape(AL.shape)

    dAL = - (np.divide(Y, AL) - np.divide(1 - Y, 1 - AL))

    current_cache = caches[L-1]
    grads["dA" + str(L-1)], grads["dW" + str(L)], grads["db" + str(L)] = linear_activation_backward(dAL, current_cache, activation = "sigmoid")

    for l in reversed(range(L-1)):

        current_cache = caches[l]
        dA_prev_temp, dW_temp, db_temp = linear_activation_backward(grads["dA" + str(l + 1)], current_cache, activation = "relu")
        grads["dA" + str(l)] = dA_prev_temp
        grads["dW" + str(l + 1)] = dW_temp
        grads["db" + str(l + 1)] = db_temp

    return grads

#Updating and predicting
def update_parameters(parameters, grads, learning_rate):

    L = len(parameters) //2

    for l in range(L):
        parameters["W" + str(l+1)] = parameters["W" + str(l+1)] - learning_rate * grads["dW" + str(l+1)]
        parameters["b" + str(l+1)] = parameters["b" + str(l+1)] - learning_rate * grads["db" + str(l+1)]

    return parameters

def predict(X, y, parameters):

    m = X.shape[1]
    n = len(parameters)
    p = np.zeros((1,m))

    probas, caches = L_model_forward(X, parameters)

    for i in range(0, probas.shape[1]):
        if probas[0,i] > 0.5:
            p[0,i] = 1
        else:
            p[0,i] = 0

    print("Accuracy: "  + str( np.sum( (p == y) / m )*100 ) )

    return p

train_x_orig, train_y, test_x_orig, test_y, classes = load_data()

train_x_flatten = train_x_orig.reshape(train_x_orig.shape[0], -1).T
test_x_flatten = test_x_orig.reshape(test_x_orig.shape[0], -1).T

train_x = train_x_flatten/255.
test_x = test_x_flatten/255.

#Integrating all the functions to a model
def L_layer_model(X, Y, layers_dims, learning_rate=0.0075, num_iterations=3000, print_cost=False):

    np.random.seed(1)
    costs = []

    parameters = initialize_parameters_deep(layers_dims)

    for i in range(0, num_iterations):

        AL, caches = L_model_forward(X, parameters)

        cost = compute_cost(AL, Y)

        grads = L_model_backward(AL, Y, caches)

        parameters = update_parameters(parameters, grads, learning_rate)

        if print_cost and i % 100 == 0:
            print ("Cost after iteration %i: %f" % (i, cost))
        if print_cost and i % 100 == 0:
            costs.append(cost)

    plt.plot(np.squeeze(costs))
    plt.ylabel('cost')
    plt.xlabel('iterations (per tens)')
    plt.title("Learning rate =" + str(learning_rate))
    plt.show()

    return parameters

layers_dims = #These values are custom example:[12288, 20, 7, 5, 1]
parameters = L_layer_model(train_x, train_y, layers_dims, num_iterations=2500, print_cost=True)

print("Train Accuracy:")
pred_train = predict(train_x, train_y, parameters)

print("Test Accuracy:")
pred_test = predict(test_x, test_y, parameters)

#Running on unseen image
import cv2
image = cv2.imread("/content/test.jpeg")

image=cv2.resize(image, (64,64))
image=np.reshape(image,(12288,1))
image=image/255

my_label_y = [0]

my_predicted_image = predict(image, my_label_y, parameters)

print ("y = " + str(np.squeeze(my_predicted_image)) + ", your L-layer model predicts a \"" + classes[int(np.squeeze(my_predicted_image)),].decode("utf-8") +  "\" picture.")
from IPython.display import Image
Image(filename='/content/test.jpeg')


import os
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

# x: from 0 to 10, 100 items
x_input = np.linspace(0, 10, 100)

weight = 12
bias = 10
y_input = weight * x_input + bias

W = tf.Variable(tf.random_normal([1]), name = 'weight')
B = tf.Variable(tf.random_normal([1]), name = 'bias')

# Placeholders
with tf.name_scope('input'):
	X = tf.placeholder(tf.float32, name = 'X')
	Y = tf.placeholder(tf.float32, name = 'Y')

# Model
with tf.name_scope('model'):
	Y_pred = tf.add(tf.multiply(X, W), B)

# Loss
with tf.name_scope('loss'):
	loss = tf.reduce_mean(tf.square(Y_pred - Y))
	optimizer = tf.train.GradientDescentOptimizer(learning_rate = 0.01)
	# Training step
	train = optimizer.minimize(loss)

# Initialize
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)

tf.summary.scalar('SIMPLE-loss', loss)
merged_summary = tf.summary.merge_all()
writer = tf.summary.FileWriter(r'C:\Users\drexa\git\machine-learning\python\linear', graph = tf.get_default_graph())

# Train
epochs = 2000
for step in range(epochs):
	[_, curr_loss, curr_summary] = sess.run([train, loss, merged_summary], feed_dict = {X: x_input, Y: y_input})
	writer.add_summary(curr_summary, step)
	if step % 50 == 0:
		print(curr_loss)

writer.close()

print('\nWeight: %f' % sess.run(W))
print('Bias: %f\n' % sess.run(B))


import numpy as np
from numpy.linalg import norm
from util.merge_Tucker import merge_Tucker
from util.t2m import t2m
from util.m2t import m2t

def hosvd(X, rank, max_iter=1, err_tol=1, track_fval=False):
    ''' Higher Order Singular Value Decomposition.
    Takes the HOSVD of tensor input.

    Parameters:
    ---
        X: Data tensor

        rank: Aimed ranks for the resulting tensor.

        max_iter: Number of iterations. If 1, HOSVD will be applied, otherwise
            HOOI will be run.

        err_tol: Error tolerance. Not relevant for HOSVD.

    Returns:
    ---
        Y: Tensor with ranks `rank`at each mode unfolding.
        U_list: List of factor matrices of HOSVD.
    '''
    sizes = X.shape
    sizes_core = list(sizes)
    n = len(sizes)
    U_list = [np.eye(sizes[i]) for i in range(n)]
    Y = X.copy()

    iter = 0
    change = np.inf
    err_tot = []
    val_change = []
    while iter < max_iter and change > err_tol:
        Y_old = Y.copy()
        for i in range(n):
            ind = np.setdiff1d(np.arange(n), i)
            U_other = [U_list[j] for j in ind]
            C = merge_Tucker(X, U_other, ind, transpose=True)
            U, S, _ = np.linalg.svd(t2m(C, i), full_matrices=False)
            ind = np.argsort(S)[::-1]
            ind = ind[:rank[i]]
            U_list[i] = U[:, ind]
            sizes_core[i] = rank[i]

        C = m2t(U_list[-1].transpose()@t2m(C, n-1), sizes_core, n-1)
        Y = merge_Tucker(C, U_list, np.arange(n))

        change = norm(Y-Y_old)**2
        if track_fval:
            val_change.append(change)
            err_tot.append(norm(Y-X)**2)

        iter += 1

    return Y, U_list, err_tot, val_change


import matplotlib.pyplot as plt
import pandas as pd

from matplotlib import pyplot as plt
import numpy as np
from sklearn import linear_model

#wget -O FuelConsumption.csv https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/ML0101ENv3/labs/FuelConsumptionCo2.csv

df = pd.read_csv("FuelConsumption.csv")

# take a look at the dataset
print(df.head())
print(df.describe())
cdf = df[['ENGINESIZE','CYLINDERS','FUELCONSUMPTION_COMB','CO2EMISSIONS']]
cdf.head(9)

msk = np.random.rand(len(df)) < 0.8
train = cdf[msk]
test = cdf[~msk]

plt.scatter(train.ENGINESIZE, train.CO2EMISSIONS,  color='blue')
plt.xlabel("Engine size")
plt.ylabel("Emission")
plt.show()

regr = linear_model.LinearRegression()
train_x = np.asanyarray(train[['ENGINESIZE']])
train_y = np.asanyarray(train[['CO2EMISSIONS']])
regr.fit (train_x, train_y)
# The coefficients
print ('Coefficients: ', regr.coef_)
print ('Intercept: ',regr.intercept_)

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

from sklearn.metrics import r2_score

test_x = np.asanyarray(test[['ENGINESIZE']])
test_y = np.asanyarray(test[['CO2EMISSIONS']])
test_y_ = regr.predict(test_x)

print("Mean absolute error: %.2f" % np.mean(np.absolute(test_y_ - test_y)))
print("Residual sum of squares (MSE): %.2f" % np.mean((test_y_ - test_y) ** 2))
print("R2-score: %.2f" % r2_score(test_y_ , test_y) )


import sys
import os
import numpy as np # 'pip.exe install numpy' Currently using 1.18.3

def numpy_examples():
    print("Numpy Examples")
    print()

    print("We can create 2 new lists height and weight")
    height = [1.87,  1.87, 1.82, 1.91, 1.90, 1.85]
    weight = [81.65, 97.52, 95.25, 92.98, 86.18, 88.45]

    print("We can print the type of the arrays")
    print(type(height))
    print(type(weight))

    print("We can create 2 numpy arrays from height and weight arrays")
    np_height = np.array(height)
    np_weight = np.array(weight)

    print("We can print the type of the numpy arrays. Note they are 'numpy.ndarray' to signify Nth Dimensional Arrays")
    print(type(np_height))
    print(type(np_weight))

    print("We can print the contents of the numpy arrays")
    print(np_height)
    print(np_weight)

    print("Calculate the BMI of each item (weight / (height ^ 2))")
    bmi = np_weight / (np_height ** 2)
    print(bmi)

    print("Only print those items with BMI > 25")
    print(bmi[bmi > 25])

    print("Create list of weights in KG and print")
    weight_kg = [81.65, 97.52, 95.25, 92.98, 86.18, 88.45]
    print(weight_kg)

    print("Create a numpy array np_weight_kg from weight_kg and print")
    np_weight_kg = np.array(weight_kg)

    print("Create numpy array np_weight_lbs from np_weight_kg and print")
    np_weight_lbs = np_weight_kg * 2.2
    print(np_weight_lbs)

    print("Create numpy array [0 1 2 .. 25 26] with arange()")
    np_range = np.arange(27)
    print(np_range)

    print("Create 2-d numpy array")
    two_dimensional = np.ndarray((2, 10))
    print(two_dimensional)

    print("Create initialised 2-d numpy array of type int32")
    initialised_two_d_array = np.array([[1, 2, 3], [4, 5, 6]], np.int32)
    print(initialised_two_d_array)

    print("We can access individual elements with [x,y]")
    print(initialised_two_d_array[1, 2])


# Optimization Course - Lecture 1 Exercise 1 using PYOMO
# Author: Íngrid Munné-Collado
# Date: 07/01/2021
# code based on https://www.youtube.com/watch?v=hTKa7Qc38b4&t=184s

# Requirements: Install pyomo, glpk and gurobi. You should apply for an academic license in gurobi
from pyomo.environ import *
import pyomo.environ as pyo
from pyomo.opt import SolverFactory
import pandas as pd
import numpy as np

# Read import data

# Creating the model
model = AbstractModel()
""" This is useful because everything we define as a model will be the equations.
All data used to solve the model will come in a different file"""

# Defining Sets
model.plantas = Set()
model.mercados = Set()

# Defining Parameters for each set
model.produccion = Param(model.plantas)
model.demanda = Param(model.mercados)
model.costes = Param(model.plantas, model.mercados)

# Defining variables
model.unidades = Var(model.plantas, model.mercados, within = NonNegativeReals)

# Defining ObjectiveFunction in an abstract way
def CosteTotal(model):
    return sum(model.costes[n,i] * model.unidades[n,i]
               for n in model.plantas
               for i in model.mercados)

model.costefinal = Objective(rule=CosteTotal)
# here we are saying that we will save the value of the OF defined previously in
# this variable of the model.

# Defining constraints
def MinDemanda(model, mercado): #it depends on model and each of the markets
    return sum(model.unidades[i,mercado] for i in model.plantas) >= model.demanda[mercado]

model.DemandaConstraint = Constraint(model.mercados, rule=MinDemanda)

def MaxProduccion(model, planta):
        return sum(model.unidades[planta, j] for j in model.mercados) <= model.produccion[planta]
model.ProdConstraint = Constraint(model.plantas, rule=MaxProduccion)

## in order to solve the problem we have to run this command in a terminal prompt
## pyomo solve --solver=glpk Transport_problem_example_pyomo.py datos.dat


import numpy as np

class KMeans:
    def __init__(self, k: int, max_iterations=100):
        self.k = k
        self.max_iterations = max_iterations
        self.centroids = None

    def fit(self, dataset):
        x = dataset.X
        self._min = np.min(x, axis=0)
        self._max = np.max(x, axis=0)

    def init_centroids(self):
        self.centroids = np.array([np.random.uniform(low=self._min, high=self._max) for i in range(self.k)])

    def init_centroids_random_points(self, X):
        rng = np.random.default_rng()
        self.centroids = rng.choice(X, self.k)
        return self.centroids

    def distance(self, x, centroids):
        return np.sqrt(((centroids-x)**2).sum(axis=1))

    def get_closest_centroids(self, x):
        dist = self.distance(x, self.centroids)
        closest_centroid_index = np.argmin(dist, axis=0)
        return closest_centroid_index

    def transform(self, dataset):
        X = dataset.X
        changed = True
        count = 0
        old_idxs = np.zeros(X.shape[0])
        self.init_centroids_random_points(X)
        while changed and count < self.max_iterations:
            # array of indexes of nearest centroid
            idxs = np.apply_along_axis(self.get_closest_centroids, axis=1, arr=X)
            cent = [np.mean(X[idxs == i], axis=0) for i in range(self.k)]
            self.centroids = np.array(cent)
            changed = np.all(old_idxs == idxs)
            old_idxs = idxs
            count += 1
        return self.centroids, idxs

    def fit_transform(self, dataset):
        self.fit(dataset)
        return self.transform(dataset)


from ast import AST
from arboles import *
from genetic_algorithm import Individual, Population
import matplotlib.pyplot as plt
import math
import random
import numpy as np

random.seed(16)
ITERATIONS = 1000

# gene function and fitness function to evaluate and evolve a finder of the number 10
tree10 = AST([AddNode, SubNode, MultNode], [2, 3, 5])
def fitness_10(ind):
    score = ind.genes.eval()
    return math.exp(-((score - 10) ** 2) / 100)

# gene function and fitness function to evaluate and evolve a finder of the number 65346
tree65346 = AST([AddNode, SubNode, MultNode, MaxNode], [25, 7, 8, 100, 4, 2])
def fitness_65346(ind):
    score = ind.genes.eval()
    return math.exp(-((score - 65346) ** 2) / 1000000)

# gene function and fitness function to evaluate and evolve a finder of the number 65346
# that limits the number of nodes on the tree and gives better score to trees with less nodes
def fitness_65346_short(ind):
    score = ind.genes.eval()
    score_fitness = math.exp(-((score - 65346) ** 2) / 1000000)
    tree_number_of_nodes = len(ind.genes.serialize())
    number_of_nodes_fitness = (50 - tree_number_of_nodes) / 50 if tree_number_of_nodes <= 50 else 0
    return (score_fitness * 9  + number_of_nodes_fitness) / 10  if score_fitness != 1 else 1

# gene function and fitness function to evaluate and evolve a finder of the number 65346
# with no repetition on the terminal nodes
tree_no_repetition = AST([AddNode, SubNode, MultNode], [25, 7, 8, 100, 4, 2])
def fitness_no_repetition(ind):
    score = ind.genes.eval()
    nodes = ind.genes.serialize()
    # making a list with only terminal nodes
    terminal_nodes = [x.eval() for x in nodes if isinstance(x, TerminalNode)]
    # checking if there are no repeated nodes
    if len(terminal_nodes) == len(set(terminal_nodes)):
        score_fitness = math.exp(-((score - 65346) ** 2) / 100000000)
        return score_fitness
    else: return 0

# gene function and fitness function to evaluate and evolve an equation finder of
# x² + x - 6
number_list = list(range(-10, 11))
number_list.extend(['x'] * 20)
tree_symbolic = AST([AddNode, SubNode, MultNode], number_list)
def fitness_symbolic(ind):
    def func(x):
        return x ** 2 + x - 6
    fitness_func = np.zeros(201)
    fitness_eval = np.zeros(201)
    # calculates the function directly and with the evaluation function of the tree
    for i in range(-100, 101):
        fitness_func[i + 100] = func(i)
        fitness_eval[i + 100] = ind.genes.eval({'x': i})
    # calculating the mean square error and converting it to an appropiate fitness function
    fitness_error = ((fitness_func - fitness_eval) ** 2).mean()
    return 1 / (1 + fitness_error)

# gene function and fitness function to evaluate and evolve an equation finder of
# (x + 3) / 3
tree_division = AST([AddNode, SubNode, MultNode, DivNode], number_list)
def fitness_division(ind):
    def func(x):
        return (x + 3) / 3
    fitness_func = np.zeros(201)
    fitness_eval = np.zeros(201)
    # catching divisions by zero
    try:
        for i in range(-100, 101):
            fitness_func[i + 100] = func(i)
            fitness_eval[i + 100] = ind.genes.eval({'x': i})
        fitness_error = ((fitness_func - fitness_eval) ** 2).mean()
        return 1 / (1 + fitness_error)
    except ZeroDivisionError:
        return 0

# method to run each example
def run_exercise(fitness_func, gen_func, pop_size, mut_rate, title):
    pop = Population(pop_size, mut_rate, fitness_func, print)
    pop.generate_individuals(gen_func)
    y1, y2, y3 = pop.evolve(iterations=ITERATIONS, fitness_limit=1)
    plt.plot(range(pop.generation - 1), y1)
    plt.plot(range(pop.generation - 1), y2)
    plt.plot(range(pop.generation - 1), y3)
    plt.title(title)
    plt.legend(["minimum fitness", "average fitness", "maximum fitness"], loc=2)
    plt.ylabel("fitness")
    plt.xlabel("generation")
    plt.show()

if __name__ == "__main__":
    # To select which example to run
    option = input("Select example tu run:\n(1) Find number 10\n(2) Find number 65346\n(3) Find number 65346 (short trees version) \
        \n(4) Find number 65346 with no repetition in terminal nodes\n(5) Find equation x²+x-6\n(6) Find equation (x+3)/3\n")
    if option == '1':
        run_exercise(fitness_10, tree10, 10, 0.3, "Finding number 10")
    elif option == '2':
        run_exercise(fitness_65346, tree65346, 150, 0.3, "Finding number 65346")
    elif option == '3':
        run_exercise(fitness_65346_short, tree10, 150, 0.4, "Finding number 65346 (short trees)")
    elif option == '4':
        run_exercise(fitness_no_repetition, tree_no_repetition, 100, 0.5, "Finding number 65346 (no repetition)")
    elif option == '5':
        run_exercise(fitness_symbolic, tree_symbolic, 50, 0.1, "Finding x²+x-6")
    elif option == '6':
        run_exercise(fitness_division, tree_division, 50, 0.1, "Finding (x+3)/3")


import numpy as np
import ista
import utils

X = np.array([[2, 0, 0], [0, 1, 0]]).T
y = np.array([3, 2, 2])

lambd = 6

def f(w):
    return 0.5*np.sum((X@w - y)**2) + lambd * np.linalg.norm(w, ord=1)

w0 = 0.5 * np.ones(2)
stepsize = 0.1

w_traces = ista.ista(X, y, lambd, w0, stepsize=stepsize, tol=1e-9)

f_value = f(w_traces[-1])

print()
print('lambda =', lambd)
print('number of iterations:', len(w_traces)-1)
print('solution:', w_traces[-1])
print('value:', f_value)
print()

# visualization
Q = X.T@X
b = X.T@y
c = y@y

def f_2d(w1, w2):
    return 0.5 * Q[0, 0] * w1**2 + 0.5 * Q[1, 1] * w2**2 + Q[0, 1] * w1 * w2 \
        - b[0] * w1 - b[1] * w2 - 0.5 * c + lambd * (np.abs(w1) + np.abs(w2))

def gap(w):
    return f(w) - f_value

path = 'figures/4/'
utils.plot_traces_2d(f_2d, w_traces, path+f'ista_traces_lambda{lambd}.png')
utils.plot(gap, w_traces, path+f'ista_gap_lambda{lambd}.png')


import numpy as np

def vec_mse(y, y_hat):
    if type(y) != np.ndarray or type(y_hat) != np.ndarray:
        return None
    if y.shape != y_hat.shape or len(y.shape) != 1:
        return None
    return np.dot(y_hat - y, y_hat - y) / y.size

if __name__ == "__main__":
    X = np.array([0, 15, -9, 7, 12, 3, -21])
    Y = np.array([2, 14, -13, 5, 12, 4, -19])

    print(vec_mse(X, Y))
    print(vec_mse(X, X))


import numpy as np

"""
Version 1.0
Last Updated 12/09/2014

"""

def rsl_get_groundr_and_h(slant_r, elev):

    """
Author: Timothy Lang (timothy.j.lang@nasa.gov)
Given slant range and elevation, return ground range and height.

Inputs
  slant_r  slant range (km)
  elev     elevation (deg)

Outputs
  gr    ground range (km)
  h     height above radar (km)

This Python function is adapted from the Radar Software Library routine
RSL_get_groundr_and_h, written by John Merritt and Dennis Flanigan

    """

    Re = 4.0/3.0 * 6371.1  # Effective earth radius in km.
    h = np.sqrt(Re**2 + slant_r**2 - 2.0 * Re * slant_r *
                np.cos((elev + 90.0) * np.pi / 180.0))
    gr = Re * np.arccos((Re**2 + h**2 - slant_r**2) / (2.0 * Re * h))
    h = h - Re
    return gr, h

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

def rsl_get_slantr_and_elev(gr, h):

    """
Author: Timothy Lang (timothy.j.lang@nasa.gov)
Given ground range and height, return slant range and elevation.

Inputs
  gr  ground range (km)
  h   height (km)

Outputs
  slantr    slant range
  elev      elevation in degrees

This Python function is adapted from the Radar Software Library routine
RSL_get_slantr_and_elev, written by John Merritt and Dennis Flanigan

    """

    Re = 4.0/3.0 * 6371.1  # Effective earth radius in km.
    rh = h + Re
    slantrsq = Re**2 + rh**2 - (2 * Re * rh * np.cos(gr/Re))
    slantr = np.sqrt(slantrsq)
    elev = np.arccos((Re**2 + slantrsq - rh**2)/(2 * Re * slantr))
    elev = elev * 180.0/np.pi
    elev = elev - 90.0
    return slantr, elev


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

import numpy as np
import gym
from gym import wrappers
from time import sleep

class ValueIteration:
    def __init__(self, env, gamma=0.8):
        self.env = env
        self.pi = np.random.choice(env.nA, env.nS)
        self.v = np.zeros(env.nS)
        self.gamma = gamma

    def value_iteration(self):
        v = self.v.copy()
        for s in range(self.env.nS):
            q_sa = np.zeros(self.env.nA)
            for a in range(self.env.nA):
                q_sa[a] = sum([p * (r + self.gamma * self.v[s_]) for p, s_, r, _ in self.env.P[s][a]])

            v[s] = np.max(q_sa)

        return v

    def get_optimal_policy(self):
        for s in range(self.env.nS):
            q_sa = np.zeros(self.env.nA)
            for a in range(self.env.nA):
                q_sa[a] = sum([p * (r + self.gamma * self.v[s_]) for p, s_, r, _ in self.env.P[s][a]])

            self.pi[s] = np.argmax(q_sa)

        return self.pi

    def iterate(self):
        n = 200000
        eps = 1e-20
        for i in range(n):
            v_new = self.value_iteration()

            if (np.all(self.v == v_new)):
                print('Value-Iteration converged at step %d.' %(i+1))
                break

            self.v = v_new

        return self.get_optimal_policy()

    def run_episode(self, render = False, key = False, wait = 0.0):
        obs = self.env.reset()
        total_reward = 0
        step_idx = 0
        while True:
            if render:
                self.env.render()
                if key:
                    temp_key = input('')
                elif wait > 0.0:
                    sleep(wait)

            obs, reward, done , _ = self.env.step(int(self.pi[obs]))
            total_reward += (self.gamma ** step_idx * reward)
            step_idx += 1
            if done:
                break
        return total_reward

if __name__ == '__main__':
    env = gym.make("FrozenLake8x8-v0")
    env = env.unwrapped
    gamma = 0.8
    value_iteration = ValueIteration(env, gamma)

    # random policy
    k = input('run 1 episode with ramdom policy?')
    score = value_iteration.run_episode(True, False, 0.1)
    print('score(random policy) = ', score)

    # policy iteration
    value_iteration.iterate()

    # 1 episode
    k = input('run 1 episode with value iteration?')
    score = value_iteration.run_episode(True, False, 0.1)
    print('score(value iteration, 1 episode) = ', score)

    # multiple episodes
    k = input('run 100 episodes with policy iteration?')
    scores = [value_iteration.run_episode(False) for _ in range(100)]
    score = np.mean(scores)
    print('Average score(value iteration, 100 episodes) = ', score)


import os as _os
on_rtd = _os.environ.get('READTHEDOCS', None) == 'True'
if not on_rtd:
    import numpy as _np

def chisquare(observe, expect, error, ddof, verbose=True):
    """
    Finds the reduced chi square difference of *observe* and *expect* with a given *error* and *ddof* degrees of freedom.

    *verbose* flag determines if the reduced chi square is printed to the terminal.
    """
    chisq = 0
    error   = error.flatten()
    observe = observe.flatten()
    expect  = expect.flatten()
    for i, el in enumerate(observe):
        chisq = chisq + _np.power((el - expect[i]) / error[i], 2)

    red_chisq = chisq / (len(observe) - ddof)
    if verbose:
        # print 'Chi-Squared is {}.'.format(chisq)
        print('Reduced Chi-Squared is {}.'.format(red_chisq))

    return red_chisq


"""活性化関数
"""

import numpy as np

def step(x):
    """
    ステップ関数

    Args:
        x(np.array): 入力値

    Returns: 活性化関数によって変換した出力値

    """
    # xの要素が0より大ならTrue/そうでなければFalseに変換
    y = x > 0

    # Trueを1, Falseを0のフラグに変換
    return y.astype(np.int)

def sigmoid(x):
    """
    シグモイド関数

    Args:
        x(np.array): 入力値

    Returns: 活性化関数によって変換した出力値

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

def relu(x):
    """
    ReLU関数

    Args:
        x(np.array): 入力値

    Returns: 活性化関数によって変換した出力値

    """
    return np.maximum(0, x)  # xと0の大きい方を返す

def identity(x):
    """
    恒等関数

    Args:
        x(np.array): 入力値

    Returns: 入力値と同じ配列

    """
    return x

def softmax(x):
    """

    Args:
        x(np.array): 入力値

    Returns: 入力信号をSoftmaxで変換した配列

    """
    c = np.max(x)

    exp_x = np.exp(x - c)  # オーバーフロー対策
    sum_exp_x = np.sum(exp_x)

    y = exp_x / sum_exp_x

    return y


from __future__ import division
import sys
import operator as op
#import scipy.misc as sm

#def binomialCoeff(n, r):
#    r = min(r, n-r)
#    if r == 0: return 1
#    numer = reduce(op.mul, xrange(n, n-r, -1))
#    denom = reduce(op.mul, xrange(1, r+1))
#    return numer//denom

#def k_permute(n, k):
#    """
#    Compute nPk, i.e., n!/(n-k)!
#    """
#    res = 1
#    for i in xrange(n-k+1, n+1):
#        res *= i
#    return res

def binomialCoeff(n , k):
    """
    Python program for Optimized Dynamic Programming solution to
    Binomail Coefficient. This one uses the concept of pascal
    Triangle and less memory
    """
    # Declaring an empty array
    C = [0 for i in xrange(k+1)]
    C[0] = 1 #since nC0 is 1

    for i in range(1,n+1):

        # Compute next row of pascal triangle using
        # the previous row
        j = min(i ,k)
        while (j>0):
            C[j] = C[j] + C[j-1]
            j -= 1

    return C[k]

def distribute_over_bins_no_empty(k, b):
    """
    This function returns the number of ways that k elements can be distributed
    over b bins such that no bin is empty.
    """
    if k < b: return 0
    if b == 1: return 1
    tot = b ** k
    for i in xrange(1,b):
        tot -= binomialCoeff(b, i) * distribute_over_bins_no_empty(k, i)
    return tot

def probability_page_num_exactly(i, n, k):
    """
    This function computes the probability that distributing k elements
    uniformly at random over n pages exactly i pages are used.
    """
    if i > n: return 0
    return (binomialCoeff(n, i) * distribute_over_bins_no_empty(k, i)) / (n ** k)

def expected_page_num(n, k):
    """
    This function computes the expected number of pages (out of n) unto which
    k records would be distributed, with the records being distributed
    according to a uniform distribution (i.i.d.)
    """
    tot = 0
    for i in xrange(1,k+1):
        tot += i * probability_page_num_exactly(i, n, k)
    return tot

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("Usage: " + sys.argv[0] + " n k")
        sys.exit(1)
    else:
        n = int(sys.argv[1])
        k = int(sys.argv[2])
        res = expected_page_num(n,k)
        print(res)


# from mpl_toolkits.mplot3d import Axes3D i do not see that it is needed
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
import numpy as np

fig = plt.figure() # return matplotlib.figure.Figure instance
ax = fig.gca(projection='3d') #Get current axes, creating one if necessary.

# Make data.
X = np.arange(-5, 5, 0.25) # shape (40,0)
Y = np.arange(-5, 5, 0.25) # shape (40,0)
X, Y = np.meshgrid(X, Y) # following the mesh X.shape is (40,40) and Y.shape is (40,40)
R = np.sqrt(X**2 + Y**2) # R.shape is 40,40
Z = np.sin(R) # R.shape is 40,40

# Plot the surface.
surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm,
                       linewidth=0, antialiased=False)

# Customize the z axis.
ax.set_zlim(-1.01, 1.01)
ax.zaxis.set_major_locator(LinearLocator(10))
ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))

# Add a color bar which maps values to colors.
fig.colorbar(surf, shrink=0.5, aspect=5)

plt.show()


import numpy as np

from . import modulus
from .types import Fp

def inverse_el(el: Fp, p: int) -> Fp:
    """Compute the inverse of an element over Fp

    Args:
        el (Fp): An element in Fp
        p (int): A prime number

    Returns:
        Fp: The inverse of the element over Fp
    """
    return pow(int(el), p-2, p)

def inverse_poly(poly: np.poly1d, p: int, mod_poly: np.poly1d) -> np.poly1d:
    """Compute the inverse of an element over Fpn.

    Args:
        poly (np.poly1d): An element in Fpn
        p (int): A prime number.
        mod_poly (np.poly1d): An monic irreducible polynomial.

    Returns:
        np.poly1d: The inverse of the element over Fpn.
    """
    if len(poly.coeffs) == 1:
        inverse_of_el = inverse_el(poly.coeffs[0], p)
        return np.poly1d(np.array([inverse_of_el]))

    return modulus.modulus_pow_poly(poly,
                                    p**(len(mod_poly.coeffs)-1)-2, p, mod_poly)


from sympy.utilities.lambdify import lambdify
import sympy.parsing.sympy_parser as symp
import sympy.abc
import numpy as np

class ScalarTransferFunction(object):
    def __init__(self, transfer_function_string, symbol=sympy.abc.s):
        self.symbol = symbol
        self.transfer_function_string = transfer_function_string
        self.closure = lambdify(self.symbol, symp.parse_expr(self.transfer_function_string), modules=['sympy'])

    def __call__(self, s):
        return self.closure(s)

    def to_dict(self):
        return {'class': (__name__, self.__class__.__name__), 'function': self.transfer_function_string}

    def imshow(self, rates, times=None, show=True):
        import matplotlib.pyplot as plt

        vals = [self(rate) for rate in rates]
        times = np.linspace(0.0, 1.0, len(rates)) if times is None else times

        fig, ax1 = plt.subplots()
        ax1.set_xlabel('time (seconds)')
        ax1.set_ylabel(str(self.symbol), color='b')
        ax1.plot(times, rates, '--b')
        ax1.tick_params(axis='y', labelcolor='b')

        ax2 = ax1.twinx()
        ax2.set_ylabel('transform', color='r')
        ax2.plot(times, vals, 'r')
        ax2.tick_params(axis='y', labelcolor='r')

        plt.title(self.transfer_function_string)
        if show:
            plt.show()

class MultiTransferFunction(object):
    def __init__(self, symbol_tuple, transfer_function_string):
        self.symbol_tuple = symbol_tuple
        self.transfer_function_string = transfer_function_string
        self.closure = lambdify(self.symbol_tuple, symp.parse_expr(self.transfer_function_string), modules=['sympy'])

    def __call__(self, *s):
        if isinstance(s[0], (float,)):
            return self.closure(*s)
        else:
            return np.array(list(map(lambda x: self.closure(*x), zip(*s))))

    def to_dict(self):
        return {'class': (__name__, self.__class__.__name__), 'function': self.transfer_function_string}


# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt

# Curve-fit y around the peak to find subpixel peak x
def quadraticpeak(y, x=None, npts=7, plotTitle=None):
    if x is None:
        x = np.arange(len(y))
    xmax = np.argmax(y)
    W = int((npts + 1) / 2)
    window = np.arange(xmax - W + 1, xmax + W)
    window = np.clip(window, 0, len(x) - 1)
    coeff = np.polyfit(x[window], y[window], 2)

    if plotTitle:
        plt.figure()
        plt.plot(x[window], y[window], label="fit")
        sx = np.linspace(x[xmax - W], x[xmax + W], 100)
        plt.plot(sx, np.polyval(coeff, sx), label="fit")
        plt.legend()
        plt.title(plotTitle)

    return -coeff[1] / (2 * coeff[0])

if __name__ == "__main__":

    x = np.arange(100)
    max = 50
    y = -(x - max) ** 2 + np.random.uniform(-5, 5, size=len(x))

    plt.figure()
    plt.plot(x, y)
    print(quadraticpeak(y, x, npts=12, plotTitle="Fit"))


from scipy.spatial.distance import pdist, squareform
from scipy import exp
from scipy.linalg import eigh
import numpy as np
from sklearn.datasets import make_moons

'''
Author: Ankur Wasnik
Date 	: Jan 24 0632
Kernel RBF(radial basis function) custom implementation
'''

def rbf_kernel_pca(X , gamma , n_components):
	#1.Calculate pairwise squared euclidean distance
	sq_dist = pdist(X,'sqeuclidean')
	#2.Convert pairwise distance into square matrix
	sq_mat = squareform(sq_dist)
	#3.Compute the kernel square matrix
	K =np.exp(-gamma*sq_mat)
	#4.Center the kernel matrix
	#Most important step
	N = K.shape[0]
	one_n = np.ones((N,N))/N
	K = K -one_n.dot(K) -K.dot(one_n) + one_n.dot(K).dot(one_n)
	#5.Obtaining the eigenvalues and eigenvectors
	eigvals, eigvecs = eigh(K)
	eigvals , eigvecs = eigvals[:,:,-1] , eigvecs[:,:,-1]
	#6.Collect top K eigenvectors
	k_eigv = np.column_stack([eigvals[:,i] for i in range(n_components)])

	return k_eigv

'''
Implementing the kernel rbf to solve half-moon shapes
'''
if __name__=='__main__' :
	X,y = make_moons(n_samples=100 , random_state=69)
	#1.visualizing data
	import matplotlib.pyplot as plt
	plt.scatter(X[y==0,0] , X[y==0,1])
	plt.scatter(X[y==1,0] , X[y==1,1])
	plt.tight_layout()
	plt.show()
	#2.Apply kernel rbf to data
	X_krbf = rbf_kernel_pca(X=X , gamma=15 , n_components=2)
	#3.Visualize reduced data
	fig,ax = plt.subplots(nrows=1,ncols=2)
	ax[0] = plt.scatter(X_krbf[y==0,0],[X_krbf[y==0,1]])
	ax[0] = plt.scatter(X_krbf[y==1,0],[X_krbf[y==1,1]])
	ax[1] = plt.scatter(X_krbf[y==0,0],np.zeros((50,1))+0.02)
	ax[1] = plt.scatter(X_krbf[y==1,0],np.zeros((50,1))-0.02)
	ax[0].set_xlabel('PC1')
	ax[0].set_ylabel('PC2')
	ax[1].set_xlabel('PC1')
	ax[1].set_ylabel('PC2')
	plt.tight_layout()
	plt.show()


import numpy as np
from sklearn import metrics
from sklearn.preprocessing import StandardScaler

class LinearRegression:

    def __init__(self, fit_intercept=True, normalize=False):
        self.coefs_ = None
        self.intercept_ = None
        self.fit_intercept = fit_intercept
        self.normalize = normalize
        self.scaler = StandardScaler()

    def add_constant(self, X):
        return np.c_[X, np.ones(X.shape[0])]

    def fit(self, X, y):
        """
        Returns coefficients b1, b0 of an equation of the form y = b1.x + b0
        which is the least squares solution providing the line of best fit
        :param x: numpy array, representing independent features
        :param y: numpy array, representing dependent feature
        :return:
        """
        if self.fit_intercept:
            X = self.add_constant(X)
        if self.normalize:
            X = self.scaler.fit_transform(X)
        b = (np.linalg.inv(X.T.dot(X)).dot(X.T)).dot(y)
        self.coefs_ = b[:-1]
        self.intercept_ = b[-1]
        return self

    def predict(self, test):
        """
        Return predictions for fitted model
        :param test: numpy array of set of test features
        :return: numpy array of predictions
        """
        if not all(self.coefs_):
            raise ValueError("Fit the model before predicting")
        if self.normalize:
            test = self.scaler.transform()
        predictions = test.dot(self.coefs_) + self.intercept_
        return predictions

    def score(self, actuals, predictions):
        """
        Returns R-squared score for the fitted model
        :param actuals: Matrix of dependent feature
        :param predictions: Matrix of predictions
        :return: R-squared score
        """
        rss = np.square(predictions-actuals).sum()
        tss = np.square(actuals - actuals.mean()).sum()
        r2 = 1 - rss/tss
        return r2

if __name__ == '__main__':
    x = np.random.rand(100, 5)
    actual_coeffs = np.array([4.5, 5.2, 3.7, 9.1, 6.8])
    y = np.array((x * actual_coeffs).sum(axis=1) + 5).reshape(-1, 1)
    print(y.shape, x.shape)
    linear_reg = LinearRegression()
    linear_reg.fit(x, y)
    x_test = np.random.rand(10, 5)
    y_test = np.array((x_test * actual_coeffs).sum(axis=1) + 5).reshape(-1, 1)
    print(linear_reg.coefs_)
    y_pred = linear_reg.predict(x_test)
    err = (abs(y_test - y_pred)/y_test).mean()
    print(err)
    actual_r2 = metrics.r2_score(y_test, y_pred)
    our_r2 = linear_reg.score(y_test, y_pred)
    print(actual_r2, our_r2)


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.preprocessing import scale
import itertools
import plotly.graph_objects as go

def elbow_method(df, num_c = 10, breakdown = False, max_features = 2):
    """
    takes numerical value columns of dataframe --> user has to clean
    if breakdown is True, max_features matters

    Consult SKLearn Documentation for KMeans Algorithm:
    (will run on default KMeans parameters)
    https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html
    """
    assert type(df) is pd.DataFrame
    assert df.shape[1] > 1
    assert max_features > 1

    iter_nums = np.arange(1, num_c)

    if not breakdown:
        X1 = df.values
        inertia = [] #Squared Distance between Centroids and data points
        for c in iter_nums:
            model = KMeans(n_clusters = c)
            model.fit(scale(X1))
            inertia.append(model.inertia_)
        fig = go.Figure()
        fig.add_trace(go.Scatter(x = iter_nums, y = inertia, title = 'All Features',
                             line = dict(color = 'red', dash = 'dot')))
        fig.update_layout(title='Elbow Plot',
                       xaxis_title='Number of Clusters',
                       yaxis_title='Inertia')
        fig.show()
    else:
        combs = get_combinations(df, max_features)
        group_inertia = get_inertias(df, combs, iter_nums)
        plot_features(group_inertia, iter_nums, combs)

def get_combinations(df, max_features):
    assert max_features <= len(df.columns), 'Max Features must be less than existing dataframe features'
    cols = df.columns
    all_combs = []
    for i in range(2, max_features+1):
      combs = []
      for subset in itertools.combinations(cols, i):
        combs.append(subset)
      all_combs.append(combs)
    return all_combs

def get_inertias(df, all_combs, iter_nums):
    group_inertia = []
    for subcomb in all_combs:
      subgroup_inertias = []
      for comb in subcomb:
        comb_inertia = []
        for c in iter_nums:
          model = KMeans(n_clusters = c, algorithm = "elkan")
          model.fit(scale(df[list(comb)].values))
          comb_inertia.append(model.inertia_)
        subgroup_inertias.append(comb_inertia)
      group_inertia.append(subgroup_inertias)
    return group_inertia

def plot_features(group_inertia, iter_nums, all_combs):
    for group in group_inertia:
      fig = go.Figure()
      for combs in group:
        fig.add_trace(go.Scatter(x = iter_nums, y = combs, name = str(all_combs[group_inertia.index(group)][group.index(combs)]), line = dict(color = 'purple', dash = 'dot')))
      fig.update_layout(title='Elbow Plot {} Features'.format(group_inertia.index(group) + 2), xaxis_title='Number of Clusters', yaxis_title='Inertia')
      fig.show()


import numpy as np

matriz = np.array(([10, 3, -2],
                   [2, 8, -1],
                   [1, 1, 5]))

vetorb = np.array(([57, 20, -4]))

# 1x + 1y = 3
# 1x - 3y = -3

# Decompor a Matriz, Identidade(D), Triangular_inferior(E), Triangular_superior(F)
dim = len(matriz)
D = np.zeros((dim, dim)) # Diagonal
F = np.zeros((dim, dim)) # Triangular_superior
E = np.zeros((dim, dim)) # Triangular_inferior
for i in range(0, len(matriz)):
    D[i][i] = matriz[i][i]

for i in range(0, len(matriz)):
    for j in range(i+1, len(matriz)):
        F[i][j] = matriz[i][j]

for i in range(0, len(matriz)):
    for j in range(0, i):
        E[i][j] = matriz[i][j]

E *= -1  # (-E) pois A = D (-E) -F
F *= -1  # (-F) pois A = D -E (-F)

E_F = E+F
matriz_j = np.linalg.inv(D)   # D^(-1)
matriz_j = matriz_j.dot(E_F)  # matriz_j = np.linalg.inv(D).dot(E_F)

# Temos a matriz de jacob

# calcula o c(e uma constante), c = D^(-1)*b -> c = D^(-1)*vetorb
c = np.linalg.inv(D).dot(vetorb)

# iniciando o x Na origem [0,..,0]
x = np.zeros((dim))

#  primeira interacao
x = matriz_j.dot(x)+c
x_anterior = x
# print(x)

#  segunda interacao
x = matriz_j.dot(x) + c
# print(x)

vetor = np.zeros((dim))

for i in range(0, dim):
    vetor[i] = x[i] - x_anterior[i]

# print(vetor)

modulo = 0

for i in range(0, dim):
   modulo += np.absolute(vetor[i])

modulo = modulo ** (1 / 2)
# print(modulo)
ki = 1
#print(f"primeira interacao {x}")
while modulo > 0.00001:
    modulo = 0
    x_anterior = x
    x = matriz_j.dot(x) + c
    ki+=1
    vetor = np.zeros((dim))
    for i in range(0, dim):
        vetor[i] = x[i] - x_anterior[i]
    for i in range(0, dim):
        modulo += np.absolute(vetor[i])
    modulo = modulo ** (1 / 2)
print(f"Interacoes {ki}")
print(np.round(x, 4))


from collections import defaultdict
from unittest import TestCase

import numpy as np

def read_input(filename="input"):
    with open(filename) as f:
        lines = [line.strip() for line in f.readlines() if line.strip()]
    inp = [line.split(' -> ') for line in lines]  # parse here...
    inp = [((int(a.split(',')[0]), int(a.split(',')[1])),
            (int(b.split(',')[0]), int(b.split(',')[1]))
            ) for a, b in inp]
    return inp

def part_1(inp):
    valid_points = [ppair for ppair in inp if is_horiz_or_vert(ppair)]
    return get_answer(valid_points)

def get_answer(valid_points):
    grid = defaultdict(int)
    for point in get_all_line_points(valid_points):
        grid[point] += 1
    return count_points_with_more_than_2(grid)

def count_points_with_more_than_2(grid):
    count = 0
    for val in grid.values():
        if val >= 2:
            count += 1
    return count

def get_all_line_points(all_ppairs):
    for ppair in all_ppairs:
        yield from get_line_points(ppair)

def get_line_points(ppair):
    a, b = ppair
    if a == b:
        yield a
        return
    _a, _b = np.array(a), np.array(b)
    delta = _b - _a
    distance = abs(delta[0]) + abs(delta[1])
    unit_vector = delta / distance
    if 0 < abs(unit_vector[0]) < 1:
        unit_vector = unit_vector * 2
        distance = distance // 2
    for n in range(0, distance + 1):
        point = _a + n * unit_vector
        int_point = (int(point[0]), int(point[1]))
        yield int_point

def is_horiz_or_vert(point_pair):
    a, b = point_pair
    if a[0] == b[0] or a[1] == b[1]:
        return True
    return False

def part_2(inp):
    valid_points = inp
    return get_answer(valid_points)

def main(input_file):
    """Solve puzzle and connect part 1 with part 2 if needed."""
    # part 1
    inp = read_input(input_file)
    p1 = part_1(inp)
    print(f"Solution to part 1: {p1}")

    # part 2
    inp = read_input(input_file)
    p2 = part_2(inp)
    print(f"Solution to part 2: {p2}")
    return p1, p2

def test_sample_1(self):
    # inp = read_input("sample_1")
    pass

def test_sample_2(self):
    pass

if __name__ == "__main__":
    print('*** solving tests ***')
    test_sample_1(TestCase())
    test_sample_2(TestCase())
    print('*** solving main ***')
    main("input")


import numpy as np
from scipy.sparse import issparse

from ya_pca.linalg_utils import svd_wrapper

def select_rank_variance_explained(X, q=0.95, svals=None):
    """
    Selects the PCA rank by finding the components which explains the desired amount of variance.

    Parameters
    ----------
    X: array-like, (n_samples, n_features)

    q: float
        The desired percent of variance to be explained

    svals: array-like, None
        (Optional) Precomputed singular values.

    Output
    ------
    rank_est, out

    rank_est: int
        Estimated rank

    out: dict
        All output from rank selection algorithm.
    """

    if svals is None:
        svals = svd_wrapper(X)[1]

    tot_variance = safe_frob_norm(X) ** 2
    var_expl_prop = svals ** 2 / tot_variance

    assert np.allclose(var_expl_prop.sum(), 1)

    var_expl_cum = np.cumsum(var_expl_prop)
    rank_est = np.where(var_expl_cum > q)[0].min()

    return rank_est, {'tot_variance': tot_variance,
                      'var_expl_prop': var_expl_prop,
                      'var_expl_cum': var_expl_cum}

def safe_frob_norm(X):
    """
    Calculates the Frobenius norm of X whether X is dense or sparse.

    Currently, neither scipy.linalg.norm nor numpy.linalg.norm work for
    sparse matrices.
    """
    if issparse(X):
        return np.sqrt(sum(X.data ** 2))
    else:
        return np.linalg.norm(np.array(X), ord='fro')


#!/usr/bin/python

# Project Euler Problem 7
# Which starting number, under one million, produces the longest Collatz chain?
# Holly Becker

# The following iterative sequence is defined for the set of positive integers:

# n -> n/2 (n is even)
# n -> 3n + 1 (n is odd)

# Using the rule above and starting with 13, we generate the following sequence:
# 13 -> 40 -> 20 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1

# It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.

# Which starting number, under one million, produces the longest chain?

# NOTE: Once the chain starts the terms are allowed to go above one million.

#import networkx as nx
# Add numbers in a sequence to a graph, pointing to it's next neighbour

def collatz(n):
    if n % 2 == 0: # even
        return n/2
    else:
        return 3*n+1

# ~5 sec
def first_try(maximum):
    # Make graph of collatz chains
    collatz_graph = {} # number: next in chain
    for current in range(2, maximum):
        next = collatz(current)
        # Generate chain
        while current > 1:
            if current not in collatz_graph:
                collatz_graph[current] = next
            else: # We've already calculated the rest of the chain
                break
            current, next = next, collatz(next)

    def get_length(start):
        length = 1
        while collatz_graph[start] > 1:
            # Memoize!
            if start not in collatz_length:
                length += 1
                start = collatz_graph[start]
            else: # We already know the length of the rest
                return length + collatz_length[start]
        return length

    # Find all the lengths
    collatz_length = {1: 1} # start number: length
    for start in range(2, maximum):
        if start not in collatz_length:
            collatz_length[start] = get_length(start)

    longest = max(collatz_length, key=collatz_length.get)
    print(("Chain starting at %d is length %d." % (longest, collatz_length[longest])))

if __name__ == '__main__':
    first_try(1000000)


#!/bin/env python
import numpy as np
import matplotlib.pyplot as plt
import sys, os
import argparse

def uqi(x,y):
    """A Universal Image Quality Index, named Q."""
    x = np.array([float(i) for i in x])
    y = np.array([float(i) for i in y])
    cov = np.cov(x,y)
    a_var = cov[0][0]
    b_var = cov[1][1]
    ab_cov = cov[0][1]
    uqi = (       (4 * ab_cov * x.mean() * y.mean() )
        / ((a_var + b_var) * (x.mean() ** 2 + y.mean() ** 2))
        )
    return uqi

def rmse(x,y):
    x = np.array([float(i) for i in x])
    y = np.array([float(i) for i in y])
    return np.sqrt(((x - y) ** 2).mean())

def nrmse(x,y):
    """normalized root-mean-square deviation or error"""
    x = np.array([float(i) for i in x])
    y = np.array([float(i) for i in y])
    nrmse = np.sqrt(((x - y) ** 2).mean())/y.mean()
    return nrmse

def vs_fig(x,y,filename=None,title=None,xlabel=None,ylabel=None,M=None,m=None):
#    font = {'family': 'serif',
#            'color':  'darkred',
#            'weight': 'normal',
#            'size': 16,
#            }
    x = np.array([float(i) for i in x])
    y = np.array([float(i) for i in y])
    fig, ax = plt.subplots()
    ax.scatter(x, y, s=2,color='red',zorder=10)
    lims = [np.min([ax.get_xlim(), ax.get_ylim()]),
            np.max([ax.get_xlim(), ax.get_ylim()]),]
    if M:lims[1]= M
    if m:lims[0]= m
    ax.plot(lims, lims, 'k-', alpha=0.75, zorder=0)
    ax.set_aspect('equal')
    ax.set_xlim(lims)
    ax.set_ylim(lims)
    xynrmse = nrmse(x,y)
    xyrmse = rmse(x,y)
    xyuqi = uqi(x,y)
    #text = "NRMSE:%f\nRMSE:%f\nUQI:%f\n"%(xynrmse,xyrmse,xyuqi)
    text = "RMSE:%f\nUQI:%f\n"%(xyrmse,xyuqi)
    ax.text(.9, .25, text,
            horizontalalignment='right',
            verticalalignment='top',
            transform=ax.transAxes)
    if title:
        ax.set_title(title)
    if xlabel:
        ax.set_xlabel(xlabel)
    if ylabel:
        ax.set_ylabel(ylabel)
    if filename:
        fig.savefig(filename,dpi=300)
        with open(filename+'.log',"w") as f:
            f.write("fig:%s\n"%(title))
            f.write("NRMSE:%f  normalized root-mean-square deviation or error.\n"%(xynrmse))
            f.write(" RMSE:%f  root-mean-square deviation or error.\n"%(xyrmse))
            f.write("  UQI:%f  A Universal Image Quality Index.\n"%(xyuqi))
    else:
        return fig, ax

def getdata(input_filename):
    MAX_COLS = 20
    data = [ [] for i in range(MAX_COLS)]
    with open(input_filename) as f:
        for i in f:
            if i[0] == '#':continue
            dat = i.split()
            for idx, num in enumerate(dat):
                data[idx].append(num)
    return data

def argparser():
    usage = ("To draw a fig vs 2 cols.")
    parser = argparse.ArgumentParser(description=usage)
    parser.add_argument('-f', help="input file.")
    import tempfile
    tf = tempfile.NamedTemporaryFile(prefix="fig.", suffix='.png',dir='.')
    tf = tf.name
    parser.add_argument('-o', default=tf, help="output fig name.")
    parser.add_argument('-x', type=int, help="col number of x, start for 1.")
    parser.add_argument('-y', type=int, help="col number of y, start for 1.")
    parser.add_argument('-t', "--title", help="title of fig.")
    parser.add_argument('-xl', "--xlabel", help="xlabel of fig.")
    parser.add_argument('-yl', "--ylabel", help="ylabel of fig.")
    parser.add_argument("-M", type=float, help="max of x&y")
    parser.add_argument("-m", type=float, help="min of x&y")

    return parser

if __name__=='__main__':
    parser = argparser()
    args = parser.parse_args()
    if len(sys.argv) < 4:
        parser.print_help()
        sys.exit()
    data = getdata(args.f)
    x = data[args.x-1]
    y = data[args.y-1]
    vs_fig(x, y,
           filename=args.o,
           title=args.title,
           xlabel=args.xlabel,
           ylabel=args.ylabel,
           M=args.M,
           m=args.m
           )


"""
Example: scikis.statsmodels.GLS
"""

import scikits.statsmodels.api as sm
import numpy as np
data = sm.datasets.longley.load()
data.exog = sm.add_constant(data.exog)

# The Longley dataset is a time series dataset
# Let's assume that the data is heteroskedastic and that we know
# the nature of the heteroskedasticity.  We can then define
# `sigma` and use it to give us a GLS model

# First we will obtain the residuals from an OLS fit

ols_resid = sm.OLS(data.endog, data.exog).fit().resid

# Assume that the error terms follow an AR(1) process with a trend
# resid[i] = beta_0 + rho*resid[i-1] + e[i]
# where e ~ N(0,some_sigma**2)
# and that rho is simply the correlation of the residuals
# a consistent estimator for rho is to regress the residuals
# on the lagged residuals

resid_fit = sm.OLS(ols_resid[1:], sm.add_constant(ols_resid[:-1])).fit()
print resid_fit.tvalues[0]
print resid_fit.pvalues[0]
# While we don't have strong evidence that the errors follow an AR(1)
# process we continue

rho = resid_fit.params[0]

# As we know, an AR(1) process means that near-neighbors have a stronger
# relation so we can give this structure by using a toeplitz matrix

from scipy.linalg import toeplitz

# # for example
# >>> toeplitz(range(5))
# array([[0, 1, 2, 3, 4],
#       [1, 0, 1, 2, 3],
#       [2, 1, 0, 1, 2],
#       [3, 2, 1, 0, 1],
#       [4, 3, 2, 1, 0]])

order = toeplitz(range(len(ols_resid)))

# so that our error covariance structure is actually rho**order
# which defines an autocorrelation structure

sigma = rho**order

gls_model = sm.GLS(data.endog, data.exog, sigma=sigma)
gls_results = gls_model.fit()

# of course, the exact rho in this instance is not known so it
# it might make more sense to use feasible gls, which currently only
# has experimental support

# We can use the GLSAR model with one lag, to get to a similar result

glsar_model = sm.GLSAR(data.endog, data.exog, 1)
glsar_results = glsar_model.iterative_fit(1)

# comparing gls and glsar results, we see that there are some small
# differences in the parameter estimates and the resulting standard
# errors of the parameter estimate. This might be do to the numerical
# differences in the algorithm, e.g. the treatment of initial conditions,
# because of the small number of observations in the longley dataset.
print gls_results.params
print glsar_results.params
print gls_results.bse
print glsar_results.bse


'''
SMOOTHING A 1D SPECTRUM
-----------------------
The original code for this comes from
https://scipy-cookbook.readthedocs.io/items/SignalSmooth.html

I've modified it to use scipy & allow for a gaussian shape.

'''

import numpy as np
import matplotlib.pyplot as plt
import scipy.signal.windows as w

def smooth(x,window_len=11,window='hann',sigma=2):
    '''
    Window options:
    'flat','gaussian','hann','hamming','bartlett','blackman'

    To access them, use w.[window](window_len)
    '''
    if window_len < 3: # too small, doesn't smooth
        return x

    # np.r_ turns a list into an array, in this case it works like np.concatenate
    # s will be longer than x based on the window_len (will need to crop it)
    s = np.r_[x[window_len-1:0:-1],x,x[-2:-window_len-1:-1]]

    if window == 'flat': # generates a moving average
        w = np.ones(window_len)
    elif window == 'gaussian': # requires sigma input
        w = eval('w.' + window + '(window_len,sigma)')
    else:
        w = eval('w.' + window + '(window_len)')

    # the actual smoothing line
    y = np.convolve(w/w.sum(), s, mode='valid')

    # y will be larger than x based upon the window_len size
    # for now, I've written in a return that slices out the original section
    h = int(window_len/2)
    y = y[h:-h] # removing the increase in array size due to window_len
    return y

def see_smoothing():
    '''
    Just a function that can be used to plot what this can look
    like for the different filters.  Feel free to change it up.
    '''
    window_len = 7
    x = np.linspace(2,4,50)
    y = 3*np.cos(x)**3
    yn = y + np.random.normal(0,0.5,len(x))

    plt.figure(figsize=(8,4.5)); plt.axis('off')
    plt.plot(x,y,label='true',lw=2,ls=':')
    plt.plot(x,yn,label='w/noise')
    plt.text(0.4,0.8,f'window size: {window_len}',transform=plt.gca().transAxes,fontsize=16)

    for f in ['flat','gaussian','hann','hamming','bartlett','blackman']:
        s = smooth(yn,window_len,window=f)
        plt.plot(x,s,label=f,lw=1)

    plt.legend(ncol=3,loc=3,bbox_to_anchor=(0.1,-0.5))
    plt.tight_layout()
    plt.show()
    plt.close()

def see_windows():
    '''
    Just a function that can be used to visualize the different
    smoothing windows.
    '''
    window_len = 19
    filts = ['flat', 'gaussian', 'hann', 'hamming', 'bartlett', 'blackman']

    plt.figure(figsize=(7,4.5)); plt.axis('off')
    plt.text(0.7,0.82,f'window size: {window_len}',transform=plt.gca().transAxes,fontsize=13.5)

    i = 0
    for f in ['flat', 'gaussian', 'hann', 'hamming', 'bartlett', 'blackman']:
        label = f # assigning it so I can add the sigma for gaussian

        if f == 'flat':
            wfilt = np.ones(window_len)
        elif f == 'gaussian':
            wfilt = eval('w.'+f+'(window_len,2)')
            label = f'{f}\n$\sigma$=2' # adding note about sigma
        else:
            wfilt = eval('w.'+f+'(window_len)')

        plt.plot(wfilt,label=label,color=f'C{i+2}') # so the color matches the other plot
        i += 1

    plt.legend(ncol=3,loc=3,bbox_to_anchor=(0.02,-0.5))
    plt.tight_layout()
    plt.show()
    plt.close()

def double_smooth(x,window_len=5,width=11,sigma=2):
    '''
    This function smooths a spectrum using a double gaussian with a
    specified window size & sigma, separated by a width.
    '''
    if window_len < 3: # too small, doesn't smooth
        return x

    # making double gaussian
    window = 'gaussian' # requires sigma input
    w_one = eval('w.' + window + '(window_len,sigma)')

    if width % 2 == 0: w = np.concatenate((w_one,np.zeros(width),w_one,[0]))
    else: w = np.concatenate((w_one,np.zeros(width),w_one))

    # np.r_ turns a list into an array, in this case it works like np.concatenate
    # s will be longer than x based on the window_len (will need to crop it)
    full_window_len = len(w)
    s = np.r_[x[full_window_len-1:0:-1],x,x[-2:-full_window_len-1:-1]]

    # the actual smoothing line
    y = np.convolve(w/w.sum(), s, mode='valid')

    # y will be larger than x based upon the window_len size
    # for now, I've written in a return that slices out the original section
    h0 = int(window_len/2)
    h = int(full_window_len/2)
    y = y[h0:-(h+(h-h0))] # removing the increase in array size due to window_len+width
    return y

def rebin_spec(wave, specin, wavnew):
	'''
	Given wavelength, a spectrum, and new wavelength array, this
    function resamples the spectrum to match new array.
	'''
	import numpy as np
	from pysynphot import observation
	from pysynphot import spectrum

	spec = spectrum.ArraySourceSpectrum(wave=wave, flux=specin,keepneg=True)
	f = np.ones(len(wave))
	filt = spectrum.ArraySpectralElement(wave, f, waveunits='angstrom')
	obs = observation.Observation(spec, filt, binset=wavnew, force='taper')
	return obs.binflux


## philvals.py
## This is my implementation of phivals.m
## Computation of scaling function and wavelet by recursion
## using Python libraries numpy, scipy
##
## The main reference that I'll use is
## Gilbert Strang, and Kevin Amaratunga. 18.327 Wavelets, Filter Banks and Applications, Spring 2003. (Massachusetts Institute of Technology: MIT OpenCourseWare), http://ocw.mit.edu (Accessed 19 Jun, 2015). License: Creative Commons BY-NC-SA
##
##
##
#####################################################################################
## Copyleft 2015, Ernest Yeung <ernestyalumni@gmail.com>
##
## 20150621
##
## This program, along with all its code, is free software;
## you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You can have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software Foundation, Inc.,
## S1 Franklin Street, Fifth Floor, Boston, MA
## 02110-1301, USA
##
## Governing the ethics of using this program, I default to the Caltech Honor Code:
## ``No member of the Caltech community shall take unfair advantage of
## any other member of the Caltech community.''
##
## If you like what I'm doing and would like to help and contribute support,
## please take a look at my crowdfunding campaign at ernestyalumni.tilt.com
## and subscription-based Patreon
## read my mission statement and give your financial support,
## no matter how small or large,
## if you can
## and to keep checking my ernestyalumni.wordpress.com blog and
## various social media channels
## for updates as I try to keep putting out great stuff.
##
## Fund Science! Help my physics education outreach and research efforts at
## Open/Tilt or subscription Patreon - Ernest Yeung
##
## ernestyalumni.tilt.com
##
## Facebook     : ernestyalumni
## gmail        : ernestyalumni
## google       : ernestyalumni
## linkedin     : ernestyalumni
## Patreon      : ernestyalumni
## Tilt/Open    : ernestyalumni
## tumblr       : ernestyalumni
## twitter      : ernestyalumni
## youtube      : ernestyalumni
## wordpress    : ernestyalumni
##
##
################################################################################
##
##
##
##
## EY : 20150621 on the MIT OCW website for 18.327, and in the download, phivals.m isn't even a text file; it's in html for some reason.  However, on the web.mit.edu website, the formating is correct, although it's still a html file.

import numpy as np
import scipy
from scipy.linalg import toeplitz

def phivals(h,i):
    """
    phivals = phivals(h,i)
    Generate a scaling function and its associated wavelet
    using the given filter coefficients

    Matlab original version (but it was a html file!) by Kevin Amaratunga 5 March 1993
    INPUTS:
    h = filter coefficients (sum(h)=2)
    i = discretization parameter. The number of points per integer
    step is 2^i.  Thus, setting i = 0 gives the scaling function
    and wavelet values at integer points

    OUTPUTS: x,phi,psi
    """

    assert i>=0, "phivals: i must be non-negative"

    m,n = h.shape
    assert n==1, "input h is not a column vector"

    g = np.multiply( np.array( [(-1)**i for i in range(0,m)]), h[::-1,0] )

    # The Haar filter produces a singular matrix, but since we know the solution
    # already we treat this as a special case.

    if m == 2 and h == np.vstack( np.array([1,1])):
        phi = np.vstack( np.append(np.ones(2**i), np.zeros(1) ) )

        if i > 0:
            psi = np.vstack( np.append( np.append(np.ones(2**(i-1)),-np.ones(2**(i-1))), np.zeros(1) ))

        elif i==0:
            psi = np.vstack( np.array([1,0]) )
    else:
        ch = np.vstack( (h,np.zeros((m,1)) ))
        rh = np.append( np.array([h[0,0]]), np.zeros(m-1))
        tmp = toeplitz(ch,rh)

        M = tmp.flatten('F')[0:-1:2].reshape((m,m)).T - np.identity(m)

        M[-1,:] = np.ones(m)
        tmp = np.vstack( np.append(np.zeros(m-1),np.identity(1)) )
        phi = np.linalg.solve( M,tmp)

        # Integer values of phi
        if i > 0:
            for k in range(0,i):
                p = 2**(k+1)*(m-1)+1   # No of rows in toeplitz matrix
                q = 2**k *(m-1)+1      # No of columns toeplitz matrix
                if k==0:
                    ch0 = np.vstack( np.append( h, np.zeros(p-1-m)) )
                    ch  = np.vstack( ( ch0, np.zeros(1) ))
                    cg0 = np.vstack( np.append(g, np.zeros(p-1-m)))
                else:
                    ch =  np.vstack( np.append( np.identity(1), np.zeros(2**k-1))).dot(ch0.T)
                    ch = np.vstack( np.append( ch.flatten('F'), np.zeros(1) ) )
                rh = np.append( ch[0], np.zeros(q-1) )
                Th = toeplitz(ch,rh)
                if k == i-1:
                    cg = (np.vstack(np.append(np.identity(1),np.zeros(2**k-1)))).dot( cg0.T)
                    cg = cg.flatten('F') # flatten
                    cg = np.vstack( np.append(cg,np.zeros(1)))
                    rg = np.append( cg[0], np.zeros(q-1) )
                    Tg = toeplitz(cg,rg)
                    psi = Tg.dot(phi)
                phi = Th.dot(phi)
        elif i==0:
            cg0 = np.vstack( np.append( g, np.zeros(m-1) ) )
            cg = np.vstack((cg0, np.zeros(1) ) )
            rg = np.append(cg[0],np.zeros(m-1))
            Tg = toeplitz(cg,rg)
            psi = Tg.dot(phi)
            psi=psi[::2]

    a,b = phi.shape
    x = np.vstack( np.arange(0,a)/2.**i )

    return x,phi,psi

#################
## test values
#################
h_test = np.random.rand(3,1)


# Università di Bologna
# Corso di laurea in Informatica
# 02023 - Calcolo numerico
# 17/11/2021
#
# Stefano Volpe #969766
# lab4.py

import numpy as np
import matplotlib.pyplot as plt

def es0():
    '''
    Esercizio 1: Calcolare lo zero di una funzione
    Scrivere una function che implementi il metodo delle approssimazioni
    successive per il calcolo dello zero di una funzione f(x) per x \\in R^n
    prendendo come input una funzione per l'aggiornamento:
    - g(x) = x - f(x) e ^ (x / 2)
    - g(x) = x - f(x) e ^ (- x / 2)
    - g(x) = x - f(x) / f'(x)
    Testare il risolutore per risolvere f(x) = e ^ x - x ^ 2 = 0, la cui
    soluzione è x* = -0.7034674 ca. In particolare:
    - disegnare il grafico della funzione f nell’intervallo I = [−1,1] e
    verificare che x* sia lo zero di f in [-1, 1];
    - calcolare lo zero della funzione utilizzando entrambe le funzioni
    precedentemente scritte;
    - confrontare l'accuratezza delle soluzioni trovate e il numero di
    iterazioni effettuate dai solutori;
    - modificare le due funzioni in modo da calcolare l'errore ad ogni
    iterazione k-esima e graficare.
    '''
    def succ_app(f, g, tolf, tolx, maxit, xTrue, x0 = 0):
        i = 0
        err = np.zeros(maxit + 1, dtype = np.float64)
        err[0] = tolx + 1 # errori relativi rispetto all'iterato precedente
        vecErrore = np.zeros(maxit + 1, dtype = np.float64) # err. ass. da sol.
        vecErrore[0] = np.abs(x0 - xTrue)
        x = x0
        # scarto assoluto tra iterati
        while (i < maxit and (err[i] > tolx or abs(f(x)) > tolf)):
            x_new = g(x)
            err[i + 1] = abs((x_new - x) / x_new)
            vecErrore[i + 1] = x - xTrue
            i = i + 1
            x = x_new
        err = err[0 : i]
        vecErrore = vecErrore[0 : i]
        return (x, i, err, vecErrore)

    f = lambda x: np.exp(x) - x ** 2
    df = lambda x: np.exp(x) - 2 * x

    g1 = lambda x: x - f(x) * np.exp(x / 2)
    g2 = lambda x: x - f(x) * np.exp(- x / 2)
    g3 = lambda x: x - f(x) / df(x)

    xTrue = -0.7034674
    fTrue = f(xTrue)
    print(fTrue)

    tolx= 10**(-10)
    tolf = 10**(-6)
    maxit = 100
    x0 = 0

    [sol_n, iter_n, err_n, vecErrore_g1] = \
        succ_app(f, g1, tolf, tolx, maxit, xTrue, x0)
    print('Metodo approssimazioni successive g1 \n x =', sol_n, '\n iter_new=',
        iter_n, '\n err_new=', err_n)

    [sol_n, iter_n, err_n, vecErrore_g2] = \
        succ_app(f, g2, tolf, tolx, maxit, xTrue, x0)
    print('Metodo approssimazioni successive g2 \n x =', sol_n, '\n iter_new=',
        iter_n, '\n err_new=', err_n)

    [sol_n, iter_n, err_n, vecErrore_g3] = \
        succ_app(f, g3, tolf, tolx, maxit, xTrue, x0)
    print('Metodo approssimazioni successive g2 \n x =', sol_n, '\n iter_new=',
        iter_n, '\n err_new=', err_n)

    # GRAFICO Errore vs Iterazioni

    # g1
    plt.plot(vecErrore_g1, '.-', color='blue')
    # g2
    plt.plot(vecErrore_g2[ : 3], '.-', color='green')
    # g3
    plt.plot(vecErrore_g3, '.-', color='red')

    plt.legend( ("g1", "g2", "g3"))
    plt.xlabel('iter')
    plt.ylabel('errore')
    plt.title('Errore vs Iterazioni')
    plt.grid()

def es1():
    '''
    Esercizio 2: metodo del gradiente per l'ottimizzazione in R^n
    Scrivere una funzione che implementi il metodo del gradiente rispettivamente
    con step size \\alpha_k variabile, calcolato secondo la procedura di
    backtracking ad ogni iterazione k-esima.
    Testare la function per minimizzare f(x) definita come:
        f(x) = 10 (x - 1)^2 + (y - 2)^2
    In particolare:
    - plotta la superficie f(x) con plt.plot_surface() e le curve di livello con
    plt.contour().
    - plotta, al variare delle iterazioni, la funzione obiettivo, l'errore e la
    norma del gradiente.
    '''
    def f(x, y):
        return (x - 1) ** 2 - (y - 2) ** 2

    x = np.linspace(-1.5, 3.5, 100)
    y = np.linspace(-1, 5, 100)
    X, Y = np.meshgrid(x, y)
    Z=f(X, Y)

    plt.figure(figsize = (15, 8))

    ax1 = plt.subplot(1, 2, 1, projection = '3d')
    ax1.plot_surface(X, Y, Z, cmap = 'viridis')
    ax1.set_title('Surface plot')
    ax1.view_init(elev = 20)

    ax2 = plt.subplot(1, 2, 2, projection = '3d')
    ax2.plot_surface(X, Y, Z, cmap = 'viridis')
    ax2.set_title('Surface plot from a different view')
    ax2.view_init(elev = 5)
    plt.show()

    # plt.figure(figsize=(8, 5))

    contours = plt.contour(X, Y, Z, levels = 10)
    plt.title('Contour plot')
    plt.show()

    # backtracking procedure for the choice of the steplength
    def next_step(x, grad):
        alpha = 1.1
        rho = 0.5
        c1 = 0.25
        p = -grad
        j = 0
        jmax = 10
        while f(x[0] + alpha * p[0], x[1] + alpha * p[1]) > f(x[0], x[1]) + c1 \
            * alpha * grad.T @ p and j < jmax:
            alpha = rho * alpha
            j += 1
        if (j>jmax):
            return -1
        else:
            # print('alpha = ',alpha)
            return alpha

    # funzione che implementa il metodo del gradiente
    def minimize(x0, b, mode, step, MAXITERATION, ABSOLUTE_STOP):
        # declare x_k and gradient_k vectors
        if mode == 'plot_history':
            x = np.zeros((2, MAXITERATION))

        norm_grad_list = np.zeros((1, MAXITERATION))
        function_eval_list = np.zeros((1, MAXITERATION))
        error_list = np.zeros((1, MAXITERATION))

        #initialize first values
        x_last = np.array([x0[0], x0[1]])

        if mode == 'plot_history':
            x[:, 0] = x_last

        k = 0

        function_eval_list[:, k] = f(x_last[0], x_last[1])
        error_list[:, k] = np.linalg.norm(x_last - b)
        norm_grad_list[:, k] = np.linalg.norm(grad_f(x_last))

        while np.linalg.norm(grad_f(x_last)) > ABSOLUTE_STOP \
            and k < MAXITERATION:
            k = k + 1
            # direction is given by gradient of the last iteration
            grad = grad_f(x_last)

            # backtracking step
            step = next_step(x_last, grad)
            # Fixed step
            # step = 0.1

            if(step == -1):
                print('non convergente')
                return k # no convergence

            x_last = x_last - step * grad
            if mode == 'plot_history':
                x[:, k] = x_last

        function_eval_list[:, k] = f(x_last[0], x_last[1])
        error_list[:, k] = np.linalg.norm(x_last - b)
        norm_grad_list[:, k] = np.linalg.norm(grad_f(x_last))

        function_eval_list = function_eval_list[:, :k + 1]
        error_list = error_list[:, :k + 1]
        norm_grad_list = norm_grad_list[:, :k + 1]

        print('iterations = ',k)
        print('last guess: x = (%f, %f)' % (x[0, k], x[1, k]))

        # plots
        if mode == 'plot_history':
            v_x0 = np.linspace(-5, 5, 500)
            v_x1 = np.linspace(-5, 5, 500)
            x0v, x1v = np.meshgrid(v_x0, v_x1)
            z = f(x0v, x1v)

            plt.figure()
            ax = plt.axes(projection = '3d')
            ax.plot_surface(v_x0, v_x1, z, cmap = 'viridis')
            ax.set_title('Surface plot')
            plt.show()

            # plt.figure(figsize=(8, 5))
            contours = plt.contour(x0v, x1v, z, levels = 100)
            plt.plot(x[0, 0:k],x[1, 0:k], '*')
            # plt.axis([-5,5,-5,5])
            plt.axis('equal')
            plt.show()
        return x_last, norm_grad_list, function_eval_list, error_list, k

    b = np.array([1,2])

    def f(x1, x2):
      res = 10 * (x1 - b[0]) ** 2 + (x2 - b[1]) ** 2
      return res

    def grad_f(x):
        return np.array([20 * (x[0] - b[0]), 2 * (x[1] - b[1])])

    step = 0.1
    MAXITERATIONS = 1000
    ABSOLUTE_STOP = 1.e-5
    mode = 'plot_history'
    x0 = np.array((3, -5))
    x_last, norm_grad_list, function_eval_list, error_list, k = \
        minimize(x0, b, mode, step, MAXITERATIONS, ABSOLUTE_STOP)

    plt.plot(norm_grad_list.T, 'o-')
    plt.xlabel('iter')
    plt.ylabel('Norma Gradiente')
    plt.title('Iterazioni vs Norma Gradiente')
    plt.grid()

    plt.plot(error_list.T, 'o-')
    plt.xlabel('iter')
    plt.ylabel('Errore')
    plt.title('Errore vs Iterazioni')
    plt.grid()

    plt.plot(function_eval_list.T, 'o-')
    plt.xlabel('iter')
    plt.ylabel('Funzione Obiettivo')
    plt.title('Iterazioni vs Funzione Obiettivo')
    plt.grid()


# --------------
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# code starts here
df =pd.read_csv(path)
df.head(5)
p_a = df[df['fico'].astype(float)>700].shape[0]/df.shape[0]
print(p_a)

p_b = df[df['purpose'] == 'debt_consolidation'].shape[0]/df.shape[0]
print(p_b)

df1 = df[df['purpose'] == 'debt_consolidation']

p_a_b = df1[df1['fico'].astype(float)>700].shape[0]/df.shape[0]
print(p_a_b)

result = (p_a == p_a_b)
print(result)

# code ends here

# --------------
# code starts here
prob_lp = df[df['paid.back.loan']=='Yes'].shape[0] / df.shape[0]
print(prob_lp)

prob_cs = df[df['credit.policy']=='Yes'].shape[0] / df.shape[0]
print(prob_cs)

new_df = df[df['paid.back.loan']=='Yes']

prob_pd_cs = new_df[new_df['credit.policy']=='Yes'].shape[0] / new_df.shape[0]
print(prob_pd_cs)

bayes = (prob_pd_cs * prob_lp)/prob_cs
print(bayes)
# code ends here

# --------------
# code starts here
df.purpose.value_counts(normalize=True).plot(kind='bar')
plt.title('Probability Distribution')
plt.ylabel('Probability')
plt.xlabel('Number of Purpose')
plt.show()

df1 = df[df['paid.back.loan'] =='No']

df1.purpose.value_counts(normalize=True).plot(kind='bar')
plt.title('Probability Distribution')
plt.ylabel('Probability')
plt.xlabel('Number of Purpose')
plt.show()

# code ends here

# --------------
# code starts here
inst_median = df.installment.median()
inst_mean = df.installment.mean()

df['installment'].hist(normed = True, bins=50)
plt.axvline(x=inst_median,color='r')
plt.axvline(x=inst_mean,color='b')
plt.show()

# code ends here


"""
Implement simple polynomial interpolation to help draw smooth curves
on the merge trees
"""
import numpy as np
import matplotlib.pyplot as plt

def polyFit(X, xs, doPlot = False):
    """
    Given a Nx2 array X of 2D coordinates, fit an N^th order polynomial
    and evaluate it at the coordinates in xs.
    This function assumes that all of the points have a unique X position
    """
    x = X[:, 0]
    y = X[:, 1]
    N = X.shape[0]
    A = np.zeros((N, N))
    for i in range(N):
        A[:, i] = x**i
    AInv = np.linalg.inv(A)
    b = AInv.dot(y[:, None])

    M = xs.size
    Y = np.zeros((M, 2))
    Y[:, 0] = xs
    for i in range(N):
        Y[:, 1] += b[i]*(xs**i)
    if doPlot:
        plt.plot(Y[:, 0], Y[:, 1], 'b')
        plt.hold(True)
        plt.scatter(X[:, 0], X[:, 1], 20, 'r')
        plt.show()
    return Y

if __name__ == '__main__':
    [x1, y1, x3, y3] = [100, 100, 101, 104]
    x2 = 0.5*(x1 + x3)
    y2 = 0.25*y1 + 0.75*y3
    xs = np.linspace(x1, x3, 50)
    X = np.array([[x1, y1], [x2, y2], [x3, y3]])
    Y = polyFit(X, xs, doPlot = False)
    plt.plot(Y[:, 0], Y[:, 1], 'k')
    plt.hold(True)
    plt.scatter(X[:, 0], X[:, 1], 20)
    plt.axis('equal')
    plt.show()


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

"""
Programa 4: Fórmula de Simpson compuesta
"""

"""
Datos de entrada
"""

# Función cuya integral queremos aproximar
import scipy as sp
import numpy as np
from numpy.polynomial import polynomial as P

import math
import scipy.integrate as integrate
import scipy.special as special
def f(x):
	return (math.exp(3*x)*math.sin(3*x))/(x**4+1)

a = 0
b = 2
n = 20

"""
Implementación
"""

# Fórmula de Simpson compuesta
def SimpsonCompuesto(f, a, b, n):
	m = 2 * n
	h = float((b - a)) / float(m)

	nodos = []
	for i in range(m+1):
		nodos.append(a + i * h)

	sum1 = 0
	for i in range(1,n+1):
		sum1 += 4 * f(nodos[2 * i - 1])

	sum2 = 0
	for i in range(2,n+1):
		sum2 += 2 * f(nodos[2 * i - 2])

	return (h / 3) * (f(nodos[0]) + sum1 + sum2 + f(nodos[m]))

"""
Programa principal
"""

i = 0
result = integrate.quad(f, 0, 2)
print("Valor de la integral", result[0])

print("Método de Simpson Compuesto:")
# Ejemplo de ejecución
for i in range(1, n+1):
        print("n =", i, "Error obtenido: ", SimpsonCompuesto(f, a, b, i)-result[0])

def intTrapecio( f, a, b, n ):
     h = float((b-a))/float(n)
     x=[ a+h*i for i in range(n+1)]

     if(n<1):
          resultado=0
     elif(n==1):
          resultado = (f(b) + f(a))*(b-a)/2
     else:
          resultado = ( h *( ( f(x[0]) + f(x[n]) )/2 + sum([f(x[i+1]) for i in range(n-1)]) ) )

     return resultado

a=0
b=2

print("Método del trapecio compuesto")
for i in range(439, 441):
        resultado = intTrapecio( f, a, b, i )
        print("El valor aproximado es:",resultado, "la diferencia con el valor exacto es: ", resultado-result[0], "con n = ", i)


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

import numpy as np, pandas as pd, seaborn as sns, pandas_datareader.data as web
from cmdstanpy import CmdStanModel
from matplotlib import pyplot as plt, ticker as mtick

#%% load data

stock_names = ["GOOG", "AAPL", "AMZN", "TSLA"]
stock_df = pd.DataFrame()
for stock in stock_names:
	stock_data = web.DataReader(stock, 'yahoo', "2015-09-01", "2018-04-27")
	stock_df[stock] = stock_data["Open"]
stock_df.index = stock_data.index
stock_returns = stock_df.pct_change()[1:]

pd.DataFrame({
	"mu": [-.03, .05, .03, -.02],
	"sigma": [.04, .03, .02, .01]
}, index = stock_names)

stock_returns.mean()
stock_returns.cov()

#%% some plot

cum_returns = np.cumprod(1 + stock_returns) - 1
cum_returns.index = stock_returns.index
cum_returns.plot()
plt.legend(loc = "upper left")
plt.ylabel("Return of $1 on first date")
plt.gca().yaxis.set_major_formatter(mtick.PercentFormatter(xmax = 1))

meltt = stock_returns.melt(var_name = "column")
sns.displot(meltt, x = 'value', hue = 'column', bins = "sqrt", kde = True)
g = sns.FacetGrid(meltt, col = 'column', col_wrap = 2)
g.map(sns.histplot, 'value', bins = "sqrt", kde = True)

#%% model

mdl_data = {"N": len(stock_returns), "N_stocks": len(stock_names), "observations": stock_returns.values}
modelfile = "stocks.stan"
with open(modelfile, "w") as file: file.write("""
	data { // avoid putting data in matrix except for linear algebra
		int<lower=0> N;
		int<lower=0> N_stocks;
		row_vector[N_stocks] observations[N];
	}

	transformed data {
		int<lower=2+N_stocks> df = 10;
		row_vector[N_stocks] expert_mus = [-.03, .05, .03, -.02];
		matrix<lower=0>[N_stocks, N_stocks] expert_sigmas = diag_matrix(square([.04, .03, .02, .01]'));
	}

	parameters { // discrete parameters impossible
		row_vector[N_stocks] locs;
		cov_matrix[N_stocks] covs;
	}

	transformed parameters { // Cholesky form, more numerically stabilized
		cholesky_factor_cov[N_stocks] L = cholesky_decompose(covs);
	}

	model {
		locs ~ normal(expert_mus, 1);
		covs ~ wishart(df, expert_sigmas);
		observations ~ multi_normal_cholesky(locs, L); // failed to initialize if not use Cholesky
	}
""")

sm = CmdStanModel(stan_file = modelfile)

#%% reparameterization for more efficient computation: Bartlett decomposition

modelfile_repar = "stocks_repar.stan"
with open(modelfile_repar, "w") as file: file.write("""
	data { // avoid putting data in matrix except for linear algebra
		int<lower=0> N;
		int<lower=0> N_stocks;
		row_vector[N_stocks] observations[N];
	}

	transformed data {
		int<lower=2+N_stocks> df = 10;
		row_vector[N_stocks] expert_mus = [-.03, .05, .03, -.02];
		matrix<lower=0>[N_stocks, N_stocks] expert_sigmas = diag_matrix(square([.04, .03, .02, .01]'));
		cholesky_factor_cov[N_stocks] L = cholesky_decompose(expert_sigmas);
	}

	parameters { // discrete parameters impossible
		row_vector[N_stocks] locs;
		vector[N_stocks] c;
		vector[N_stocks * (N_stocks - 1) / 2] z;
	}

	transformed parameters {
		matrix[N_stocks, N_stocks] A;
		{ // extra layer of brackes let us define a local int for the loop
			int count = 1;
			for (j in 1:(N_stocks-1)) {
				for (i in (j+1):N_stocks) {
					A[i,j] = z[count];
					count += 1;
				}
				for (i in 1:(j-1)) A[i,j] = 0;
				A[j, N_stocks] = 0;
				A[j,j] = sqrt(c[j]);
			}
			A[N_stocks, N_stocks] = sqrt(c[N_stocks]);
		}
	}

	model {
		for (i in 1:N_stocks) c[i] ~ chi_square(df - i + 1);
		z ~ std_normal();
		locs ~ normal(expert_mus, 1);
		observations ~ multi_normal_cholesky(locs, L*A);
	}
""")

Xrange = range(1, 5)
var_name_repar_array = [f"locs[{i}]" for i in Xrange] + [f"A[{i},{i}]" for i in Xrange]
var_name_repar_combi = ["locs", "A"]

sm_repar = CmdStanModel(stan_file = modelfile_repar)

# maximum likelihood estimation
optim_repar = sm_repar.optimize(data = mdl_data).optimized_params_pd
optim_repar[var_name_repar_array]

# variational inference
vb_repar = sm_repar.variational(data = mdl_data)
vb_repar.variational_sample.columns = vb_repar.variational_params_dict.keys()
vb_name_repar = vb_repar.variational_params_pd.columns[~vb_repar.variational_params_pd.columns.str.startswith(("lp", "log_"))]
vb_repar.variational_params_pd[var_name_repar_array]
vb_repar.variational_sample[var_name_repar_array]

# Markov chain Monte Carlo
fit_repar = sm_repar.sample(
	data = mdl_data, show_progress = True, chains = 4,
	iter_sampling = 50000, iter_warmup = 10000, thin = 5
)

fit_repar.draws().shape # iterations, chains, parameters
fit_repar.summary().loc[var_name_repar_array] # pandas DataFrame
print(fit_repar.diagnose())

posterior_repar = {k: fit_repar.stan_variable(k) for k in var_name_repar_combi}

# re-compose the covariance matrix
L_repar = np.linalg.cholesky(np.diag([.04, .03, .02, .01]))
f = lambda a: L_repar @ a @ a.T @ L_repar.T
posterior_repar["covs"] = np.array([f(a) for a in posterior_repar["A"]])

colors = ['#5DA5DA', '#F15854', '#B276B2', '#60BD68']
fig = plt.figure(figsize = (16, 9))
ax1 = fig.add_subplot(121)
ax2 = fig.add_subplot(122)
for i in range(len(stock_names)):
	sns.kdeplot(posterior_repar["locs"][:,i], color = colors[i], ax = ax1)
	sns.kdeplot(posterior_repar["covs"][:,i,i], color = colors[i], ax = ax2)
ax1.legend(labels = stock_names)
ax1.set_title(r"$ \mu $")
ax2.legend(labels = stock_names)
ax2.set_title(r"$ \sigma $")


import numpy as np

from bootstrap import create_normal_ci, create_percentile_ci, create_pivotal_ci

def sample_corr_plugin(ys, zs):
    ys_mean = ys.mean()
    zs_mean = zs.mean()
    numerator = np.sum((ys - ys_mean) * (zs - zs_mean))
    denominator = np.sqrt(
        np.sum((ys - ys_mean) ** 2) * np.sum((zs - zs_mean) ** 2)
    )
    return numerator / denominator

rng = np.random.default_rng(42)

b = 5000
lsat = np.array(
    [576, 635, 558, 578, 666, 580, 555, 661, 651, 605, 653, 575, 545, 572, 594]
)
gpa = np.array(
    [3.39, 3.30, 2.81, 3.03, 3.44, 3.07, 3.00, 3.43, 3.36, 3.13]
    + [3.12, 2.74, 2.76, 2.88, 2.95]
)
n = len(lsat)
idxs = np.arange(0, n)

est_corr = sample_corr_plugin(lsat, gpa)

bootstrap_corrs = np.zeros(b)
for i in range(b):
    random_idxs = rng.choice(idxs, size=n, replace=True)
    lsat_sample = lsat[random_idxs]
    gpa_sample = gpa[random_idxs]

    bootstrap_corrs[i] = sample_corr_plugin(lsat_sample, gpa_sample)

est_corr_se = bootstrap_corrs.std()

print(f"The plug-in estimate for the correlation is {est_corr:.5}.")
print(f"Bootstrap approximation for standard error is {est_corr_se:.4}.")
normal_ci = create_normal_ci(est_corr, bootstrap_corrs)
print(f"95% CI by normal method is [{normal_ci[0]:.4}, {normal_ci[1]:.4}]")
pivotal_ci = create_pivotal_ci(est_corr, bootstrap_corrs)
print(f"95% CI by pivotal method is [{pivotal_ci[0]:.4}, {pivotal_ci[1]:.4}]")
percent_ci = create_percentile_ci(bootstrap_corrs)
print(
    f"95% CI by percentile method is [{percent_ci[0]:.4}, {percent_ci[1]:.4}]"
)


import numpy as np

def zscore(x: np.ndarray) -> np.ndarray:
    """
    平均0 分散1
    """
    return (x-x.mean()) / x.std()

def min_max_normalize(x: np.ndarray) -> np.ndarray:
    """
    最小値0 最大値1
    """
    return (x - x.min()) / (x.max() - x.min())


import numpy as np
import matplotlib.pyplot as plt

N_samples = 10000

mu1 = 100.
mu2 = 100.
sigma1 = 20.
sigma2 = 10.
h = 2

def volume(a1, a2, h):
  return h*(a1 + a2 + np.sqrt(a1*a2))/3

def compute_mu(mu1, mu2, h):
  return volume(mu1, mu2, h)

def compute_sigma(sigma1, sigma2, h):
  return h*np.sqrt(sigma1**2+sigma2**2)/3

def compute_sigma_orig(sigma1, sigma2, h):
  return h*(sigma1+sigma2)/3

# sample X and Y
s1 = np.random.normal(mu1, sigma1, N_samples)
s2 = np.random.normal(mu2, sigma2, N_samples)

# Compute Z
v = volume(s1, s2, h)

# Plot hist of Z
count, bins, ignored = plt.hist(v, 100, normed=True)

# Compute and plot approx of Z
mu = compute_mu(mu1, mu2, h)
sigma = compute_sigma(sigma1, sigma2, h)
sigma_orig = compute_sigma_orig(sigma1, sigma2, h)

plt.plot(
    bins,
    1/(sigma * np.sqrt(2 * np.pi)) * np.exp( - (bins - mu)**2 / (2 * sigma**2) ),
    linewidth=2, color='r')

plt.plot(
    bins,
    1/(sigma_orig * np.sqrt(2 * np.pi)) * np.exp( - (bins - mu)**2 / (2 * sigma_orig**2) ),
    linewidth=2, color='g')
plt.show()


import sys
import numpy as np
from numpy import linalg as LA

def fib(n):
    A = np.matrix([[1, 1], [1, 0]], dtype='object')
    R = LA.matrix_power(A, n - 1)
    return R.item((0, 0))

n = int(sys.argv[1])
print("res = ", fib(n))


# -*- coding: utf-8 -*-
import numpy as np
from matplotlib.mlab import find
from svm_kernels import kernel_svm_rbf
from optim.optimizer import qp_optimizer

def svm_train(X, y, sigma, C):
    """SVM training for a 2 label classification problem. Label -1 and 1 are
    used to distinguise between the two classes.

    Args:
        X (ndarray): Input training data set.\n
        y (ndarray): Label for the training set.\n
        sigma (float): The variance of the RBF kernel.\n
        C (float): Upper bound optimization value.

    Yields:
        SVM (dict): A container of the trained values (support vectors etc.).

    Example:
        Train the synthetic SVM data set

        >>> SVM = svm_train(Train, target, 1, 1000)
    """
    # Scale data set (other scaling can be used instead)
    shift = np.mean(X, axis=0)
    stdiv = np.std(X, axis=0)
    scale = 1/stdiv

    # Apply scaling
    for c in range(len(X[0])):
        X[:, c] = scale[c] * (X[:, c] + shift[c])

    # Generate kernel
    kernel = kernel_svm_rbf(X.T, X.T, sigma)

    # Make kernel symmetric
    kernel = (kernel + kernel.T)/2  # + np.diag(1 / (np.ones((len(y),1)) * C))

    # Formulate as QP as the problem  min:  1/2*x'*H*x + f'*x

    # Construct H: Represents the Hessian matrix
    H = y.dot(y.T) * kernel

    # Make H symmetric
    # H = (H+H.T)/2

    # Construct f: Represents the linear term
    f = -np.ones(len(X))

    # Construct Aeq: Represents the linear coefficients in Aeq*x = beq
    Aeq = y.T

    # Construct beq: Represents the constant vector in Aeq*x = beq
    beq = 0

    # Construct lb: Represents the lower bounds elementwise in lb
    lb = np.zeros(len(y))

    # Construct ub: Represents the upper bounds elemetwise in ub
    ub = C*np.ones(len(y))

    # QP solver
    res = qp_optimizer(H, f, Aeq, beq, lb, ub)

    # The support vectors are non-zero of res.x
    reference = np.sqrt(np.spacing(1))
    support_vector_index = find(res.x > reference)
    support_vector = X[support_vector_index, :]

    # Hat
    alpha_hat = y[support_vector_index].T * res.x[support_vector_index]

    # Find the bias (several possibilities)
    max_pos = np.argmax(res.x)
    bias = y[max_pos] - np.sum(alpha_hat * kernel[support_vector_index, max_pos])

    # Rescale data
    for c in range(len(support_vector[0])):
        support_vector[:, c] = (support_vector[:, c]/scale[c]) - shift[c]

    # Construct a dictonary of the trained values
    SVM = {}
    SVM['support_vector'] = support_vector
    SVM['support_vector_index'] = support_vector_index
    SVM['sigma'] = sigma
    SVM['C'] = C
    SVM['alpha_hat'] = alpha_hat
    SVM['shift'] = shift
    SVM['scale'] = scale
    SVM['bias'] = bias

    return(SVM)