"""

Write a program to implement the naïve Bayesian classifier for a sample training data set stored as a .CSV file. Compute the accuracy of the classifier, considering few test data sets.

"""

print("\nNaive Bayes Classifier for concept learning problem")
import numpy as np
import csv
import random
import math
import operator
def safe_div(x,y):
    if y == 0:
        return 0
    return x / y

def loadCsv(filename):
	lines = csv.reader(open(filename))
	dataset = list(lines)
	for i in range(len(dataset)):
		dataset[i] = [float(x) for x in dataset[i]]
	return dataset

def splitDataset(dataset, splitRatio):
	trainSize = int(len(dataset) * splitRatio)
	trainSet = []
	copy = list(dataset)
	i=0
	while len(trainSet) < trainSize:
		trainSet.append(copy.pop(i))
	return [trainSet, copy]

def separateByClass(dataset):
	separated = {}
	for i in range(len(dataset)):
		vector = dataset[i]
		if (vector[-1] not in separated):
			separated[vector[-1]] = []
		separated[vector[-1]].append(vector)
	return separated

def mean(numbers):
	return safe_div(sum(numbers),float(len(numbers)))

def stdev(numbers):
	avg = mean(numbers)
	variance = safe_div(sum([pow(x-avg,2) for x in numbers]),float(len(numbers)-1))
	return math.sqrt(variance)

def summarize(dataset):
	summaries = [(mean(attribute), stdev(attribute)) for attribute in zip(*dataset)]
	del summaries[-1]
	return summaries

def summarizeByClass(dataset):
	separated = separateByClass(dataset)
	summaries = {}
	for classValue, instances in separated.items():
		summaries[classValue] = summarize(instances)
	return summaries

def calculateProbability(x, mean, stdev):
	exponent = math.exp(-safe_div(math.pow(x-mean,2),(2*math.pow(stdev,2))))
	final = safe_div(1 , (math.sqrt(2*math.pi) * stdev)) * exponent
	return final

def calculateClassProbabilities(summaries, inputVector):
	probabilities = {}
	for classValue, classSummaries in summaries.items():
		probabilities[classValue] = 1
		for i in range(len(classSummaries)):
			mean, stdev = classSummaries[i]
			x = inputVector[i]
			probabilities[classValue] *= calculateProbability(x, mean, stdev)
	return probabilities

def predict(summaries, inputVector):
	probabilities = calculateClassProbabilities(summaries, inputVector)
	bestLabel, bestProb = None, -1
	for classValue, probability in probabilities.items():
		if bestLabel is None or probability > bestProb:
			bestProb = probability
			bestLabel = classValue
	return bestLabel

def getPredictions(summaries, testSet):
	predictions = []
	for i in range(len(testSet)):
		result = predict(summaries, testSet[i])
		predictions.append(result)
	return predictions

def getAccuracy(testSet, predictions):
	correct = 0
	for i in range(len(testSet)):
		if testSet[i][-1] == predictions[i]:
			correct += 1
	accuracy = safe_div(correct,float(len(testSet))) * 100.0
	return accuracy

def main():
	filename = 'ConceptLearning.csv'
	splitRatio = 0.9
	dataset = loadCsv(filename)
	trainingSet, testSet = splitDataset(dataset, splitRatio)
	print('Split {0} rows into'.format(len(dataset)))
	print('Number of Training data: ' + (repr(len(trainingSet))))
	print('Number of Test Data: ' + (repr(len(testSet))))
	print("\nThe values assumed for the concept learning attributes are\n")
	print("OUTLOOK=> Sunny=1 Overcast=2 Rain=3\nTEMPERATURE=> Hot=1 Mild=2 Cool=3\nHUMIDITY=> High=1 Normal=2\nWIND=> Weak=1 Strong=2")
	print("TARGET CONCEPT:PLAY TENNIS=> Yes=10 No=5")
	print("\nThe Training set are:")
	for x in trainingSet:
		print(x)
	print("\nThe Test data set are:")
	for x in testSet:
		print(x)
	print("\n")
	# prepare model
	summaries = summarizeByClass(trainingSet)
	# test model
	predictions = getPredictions(summaries, testSet)
	actual = []
	for i in range(len(testSet)):
		vector = testSet[i]
		actual.append(vector[-1])
	# Since there are five attribute values, each attribute constitutes to 20% accuracy. So if all attributes match with predictions then 100% accuracy
	print('Actual values: {0}%'.format(actual))
	print('Predictions: {0}%'.format(predictions))
	accuracy = getAccuracy(testSet, predictions)
	print('Accuracy: {0}%'.format(accuracy))
main()


# Calculate terminal velocity, ut, from drag coefficient, Cd, and particle sphericity
# from Kunii1991 book, pg 80, Eqs 28-29

# use Python 3 print function and division
from __future__ import print_function
from __future__ import division

# libraries
import numpy as np

#--- INPUTS

# air properties at T = 300K, P = 1 atm
rhog = 1.17     # density (kg/m^3)
ug = 1.85e-5    # dynamic viscosity (kg/ms)
g = 9.81        # gravity (m/s^2)

# particle properties
dp = 0.000207   # diameter of particle (m)
rhos = 2500     # density of particle (kg/m^3)
sp = 0.8        # sphericity of the particle, perfect sphere = 1.0

#--- OUTPUTS

# guess range for terminal velocity, ut (m/s)
ut = np.arange(0.001, 20, 0.001)

# Re, Reynolds number (-)
# Cd, drag coefficient as function of Re and sphericity (-)
# Cdd, drag coefficient as function of ut, etc. (-)
Re = (dp*rhog*ut)/ug
Cd = (24/Re)*(1+(8.1716*np.exp(-4.0655*sp))*Re**(0.0964+0.5565*sp)) + (73.69*np.exp(-5.0748*sp)*Re)/(Re+5.378*np.exp(6.2122*sp))
Cdd = (4*g*dp*(rhos-rhog))/(3*(ut**2)*rhog)

delta = np.abs(Cd-Cdd)  # compare difference between Cd and Cdd
idx = np.argmin(delta)  # find index of minimum value in delta

# print results to console
print('--- Kunii1991 ---')
print('ut =', ut[idx])
print('Re =', Re[idx])
print('Cd =', Cd[idx])
print('Cdd =', Cdd[idx])
print('delta =', delta[idx])


#Importing Libraries
import os
import numpy as np
from matplotlib import pyplot
from scipy import optimize
import utils

#Loading the data
data = np.loadtxt(os.path.join('Data', 'ex2data1.txt'), delimiter=',')
X, y = data[:, 0:2], data[:, 2]

#Visualising the data
def plotdata(X, y):
    fig = pyplot.figure()
    pyplot.plot(X[pos, 0], X[pos, 1], 'k*', lw=2, ms=10)
    pyplot.plot(X[neg, 0], X[neg, 1], 'ko', mfc='y', ms=8, mec='k', mew=1)

plotData(X, y)

#Defining the Logistic Sigmoid Function 𝜎(𝑧)
def sigmoid(z):
    return 1/(1 + np.exp(-z))

#Cost and Gradient at Initialization
A = sigmoid(np.dot(w.T, X) + b)
cost = (- 1 / m) * np.sum(Y * np.log(A) + (1 - Y) * (np.log(1 - A)))

#Implement Gradient Descent from Scratch

#Plotting the Convergence of 𝐽(𝜃)

#Plotting the Decision Boundary

#Predictions Using the Optimized 𝜃 Values


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

eps = np.finfo(float).eps
vala = []
valb = []
valx = []

def f(x):
    return ((x-1)*math.exp((x-2)**2))-1

def printar(n,a,b,x):
    list = [n+1,a,b,x,f(a),f(b),f(x)]
    print("Iteracao {}: \nValor de a: {} \nValor de b: {} \nValor de x: {} \nValor de função de a:{} \nValor de função de b: {} \nValor de função de x: {}".format(*list))
    vala.append(a)
    valb.append(b)
    valx.append(x)

def bisseccao(a,b,eps,it,iteracoes):
    while(it<iteracoes):
        if(b-a<eps):
            return (random.uniform(a,b))
        else:
            x = (a+b)/2
            if(f(x) == 0):
                return x
            if(f(a)<0 and f(b)>0):
                if(f(x) < 0):
                    printar(it,a,b,x)
                    a=x
                    it=it+1
                else:
                    printar(it,a,b,x)
                    b=x
                    it=it+1
            elif(f(a)>0 and f(b)<0):
                if(f(x) > 0):
                    printar(it,a,b,x)
                    b=x
                    it=it+1
                else:
                    printar(it,a,b,x)
                    a=x
                    it=it+1
            else:
                print("meu amigo, queria dizer não, mas vai ter que usar algo que ainda não aprendi")
    return None

def relerror(x,apr):
    return abs(x-aprox)/abs(x)

#Exemplo da Tabela 3.1 realizado do livro da UFRGS
a = float(0)
b = float(3)
bi = bisseccao(a,b,(1e-6),0,300)

if bi == None:
    print("Passou do limite, bro, fez sol!")
else:
    print("Caralho, mermão, toma uma raiz aproximada: {}".format(bi))

valerr = []

for aprox in valx:
    valerr.append(relerror(bi,aprox))

plt.plot(valerr, color="#00FF00")
plt.show()


import numpy as np

inputs = [[1.0, 2.0, 3.0, 2.5],
          [2.0, 5.0, -1.0, 2.0],
          [-1.5, 2.7, 3.3, -0.8]]
weights = [[0.2, 0.8, -0.5, 1.0],
           [0.5, -0.91, 0.26, -0.5],
           [-0.26, -0.27, 0.17, 0.87]]
biases = [2.0, 3.0, 0.5]

layer_outputs = np.dot(inputs, np.array(weights).T) + biases

print(layer_outputs)

# a = [[2,3,4,5],
#      [3,4,5,7]]
# print(a)
# b = np.array(a)
# print(b)

'''
>>>
array([[ 4.8    1.21   2.385],
       [ 8.9   -1.81   0.2  ],
       [ 1.41   1.051  0.026]])
'''


import numpy as np
import cv2

image = cv2.imread('1.jpg')
sharpen = np.array([[0, -1, 0],
                    [-1, 5, -1],
                    [0, -1, 0]])
print(sharpen)
sharpen_result = cv2.filter2D(image, -1, sharpen)
cv2.imshow('sharpen_result', sharpen_result)
cv2.imwrite('sharpen_result.png', sharpen_result)

laplacian = np.array([[0, 1, 0],
                      [1, -4, 1],
                      [0, 1, 0]])

print(laplacian)
laplacian_result = cv2.filter2D(image, -1, laplacian)
cv2.imshow('laplacian_result', laplacian_result)
cv2.imwrite('laplacian_result.png', laplacian_result)

emboss = np.array([[-2, -1, 0],
                   [-1, 1, 1],
                   [0, 1, 2]])

print(emboss)
emboss_result = cv2.filter2D(image, -1, emboss)
cv2.imshow('emboss_result', emboss_result)
cv2.imwrite('emboss_result.png', emboss_result)

outline = np.array([[-1, -1, -1],
                    [-1, 8, -1],
                    [-1, -1, -1]])

print(outline)
outline_result = cv2.filter2D(image, -1, outline)
cv2.imshow('outline_result', outline_result)
cv2.imwrite('outline_result.png', outline_result)

bottom_sobel = np.array([[-1, -2, -1],
                         [0, 0, 0],
                         [1, 2, 1]])

print(bottom_sobel)
bottom_sobel_result = cv2.filter2D(image, -1, bottom_sobel)
cv2.imshow('bottom_sobel_result', bottom_sobel_result)
cv2.imwrite('bottom_sobel_result.png', bottom_sobel_result)

left_sobel = np.array([[1, 0, -1],
                       [2, 0, -2],
                       [1, 0, -1]])

print(left_sobel)
left_sobel_result = cv2.filter2D(image, -1, left_sobel)
cv2.imshow('left_sobel_result', left_sobel_result)
cv2.imwrite('left_sobel_result.png', left_sobel_result)

right_sobel = np.array([[-1, 0, 1],
                        [-2, 0, 2],
                        [-1, 0, 1]])

print(right_sobel)
right_sobel_result = cv2.filter2D(image, -1, right_sobel)
cv2.imshow('right_sobel_result', right_sobel_result)
cv2.imwrite('right_sobel_result.png', right_sobel_result)

top_sobel = np.array([[1, 2, 1],
                      [0, 0, 0],
                      [-1, -2, -1]])

print(top_sobel)
top_sobel_result = cv2.filter2D(image, -1, top_sobel)
cv2.imshow('top_sobel_result', top_sobel_result)
cv2.imwrite('top_sobel_result.png', top_sobel_result)

cv2.waitKey()


from sklearn.cluster import KMeans
import numpy as np
import matplotlib.pyplot as plt

X = np.array([ [1,2], [1,4], [1,0], [4,2], [4,4], [4,0] ], dtype=float)

x = KMeans(n_clusters=2).fit(X)

print x.cluster_centers_
print x.labels_==1

print X[x.labels_==1,0]
print X[x.labels_==1,1]
plt.scatter(X[x.labels_==1,0], X[x.labels_==1,1])
plt.scatter(X[x.labels_==0,0], X[x.labels_==0,1], c=u'r')
plt.show()

#2ndExample
X = np.zeros([200,2])

X[:100,0]  = np.random.randint(1,2,100) + np.random.random(100)*2
X[100:,0]  = np.random.randint(1,2,100) - np.random.random(100)*6

X[:,1] = np.random.randint(1,2,200) + np.random.random(200)

plt.scatter(X[:,0], X[:,1])
plt.show()

x = KMeans(n_clusters=2).fit(X)
plt.scatter(X[x.labels_==1,0], X[x.labels_==1,1])
plt.scatter(X[x.labels_==0,0], X[x.labels_==0,1], c=u'r')
plt.show()

#3rd example
#let's make 4 clusters out of randomly generated X data set

x = KMeans(n_clusters=4).fit(X)

plt.scatter(X[x.labels_==1,0], X[x.labels_==1,1])
plt.scatter(X[x.labels_==0,0], X[x.labels_==0,1], c=u'r')
plt.scatter(X[x.labels_==2,0], X[x.labels_==2,1], c=u'y')
plt.scatter(X[x.labels_==3,0], X[x.labels_==3,1], c=u'g')
plt.show()


# 05 Confidence intervals

'''
If we assume that a particular distribution is normal, then
the Student's t-distribution can be used to compute
the confidence interval for the mean of the distribution.

A n% confidence interval means that the
true mean of a distribution falls within the
computed confidence interval with an estimated 95%
probability.

Confidence intervals are often used to describe the
uncertainty in sampled values such as survey data
or simulation results.
'''

import numpy as np
import scipy.stats as st

def ci(data):
    return st.t.interval(alpha=0.95, df=len(data)-1, loc=np.mean(data), scale=st.sem(data))

def between(x,ci):
    return x >= ci[0] and x <= ci[1]

def test(mu,sigma):
    # mu and sigma are the true mean and sample deviation

    # empirical means
    m = np.empty(10)

    # generate distributions
    for i in range(10):
        s = np.random.normal(mu, sigma, 10)
        m[i] = np.mean(s)

    # Is the true mean within the C.I. of the empirical means (m)?
    return between(mu, ci(m))

if __name__ == "__main__":
    count = 0
    nTests = 10000

    for x in range(nTests):
        if test(0,1):
            count += 1
    print('Proportion of tests where the 95% confidence interval includes the true mean:', count/nTests)


import numpy as np
import matplotlib.pyplot as plt

dataset = [
    [2632359, 171450],
    [3524093, 215708],
    [3966793, 235781],
    [4442173, 220126],
    [3421561, 224398],
    [4356888, 254213],
    [3364653, 249005],
    [3172396, 320535],
    [2288357, 180506],
    [2890958, 201915],
    [7594840, 394900],
    [3725373, 265283],
    [4250672, 401145],
    [3378163, 230699],
    [3261286, 241574],
    [3157336, 281438],
    [3888997, 373184],
    [2575002, 239034],
    [4418910, 455106],
    [2485337, 213187]
    ]

def create_graph():
    x =  [i[0] for i in dataset]
    y =  [i[1] for i in dataset]

    coef = np.polyfit(x,y,1)
    poly1d_fn = np.poly1d(coef)

    plt.plot(x,y, 'yo', x, poly1d_fn(x), '--k')
    plt.xlim(0, len(dataset))
    plt.ylim(0, len(dataset))

def regression(data):
    a=b=x=y=xx=xy=0
    n = len(data)
    for i in range(n):
        x+=data[i][0]
        y+=data[i][1]
        xx+=data[i][0]**2
        xy+=data[i][0]*data[i][1]
    a = (n*xy-x*y)/(n*xx-x**2)
    b = (y-a*x)/n
    return a, b

def predict(a, b, x):
    return b+a*x

def init():
    a, b = regression(dataset)
    x = input("Сколько просмотров: ")
    prediction = predict(a, b , int(x))
    print('Лайков будет примерно - ', prediction)
    create_graph()

init()


# Import libraries
###############################
import numpy # numerics
from matplotlib import pyplot # plotting
from matplotlib import cm # colormap
from mpl_toolkits.mplot3d import Axes3D # 3d plot

######################################################################
# FUNCTION DEFINITIONS                                               #
######################################################################
def laplace2d(p, y, dx, dy, l1norm_target):
    l1norm = 1
    pp = numpy.empty_like(p) # p at previous step

    while l1norm > l1norm_target:
        pp = p.copy()
        p[1:-1,1:-1] = (dy**2*(pp[2:,1:-1]+pp[0:-2,1:-1])+\
                        dx**2*(pp[1:-1,2:]+pp[1:-1,0:-2]))/(2*(dx**2+dy**2))

        p[0,:] = 0  # p = 0 @ x = 0
        p[-1,:] = y # p = y @ x = 2
        p[:,0] = p[:,1] # dp/dy = 0 @ y = 0
        p[:,-1] = p[:,-2]   # dp/dy = 0 @ y = 1
        l1norm = (numpy.sum(numpy.abs(p[:])-numpy.abs(pp[:])))\
                 /numpy.sum(numpy.abs(pp[:]))

    return p

def plot2d(x, y, p, title):
    fig = pyplot.figure(figsize=(11, 7), dpi=100)
    ax = fig.gca(projection='3d')
    X, Y = numpy.meshgrid(x, y, indexing='ij')
    surf = ax.plot_surface(X, Y, p, rstride=1, cstride=1, cmap=cm.coolwarm, \
            linewidth=0, antialiased=False)
    ax.set_xlim(0,2)
    ax.set_ylim(0,1)
    ax.view_init(30,225)
    pyplot.title(title)

######################################################################
# USER INPUT                                                         #
######################################################################

# Physical parameters
##############################

# Geometry and spatial discretization
##############################
nx = 31 # Remark: Must not be too large --> small dx --> instability?
ny = 31
xmin = 0
xmax = 2
ymin = 0
ymax = 1
dx = (xmax-xmin)/(nx-1)
dy = (ymax-ymin)/(ny-1)
x = numpy.linspace(xmin, xmax, nx)
y = numpy.linspace(ymin, ymax, ny)

# Temporal discretization
##############################
#nt = 201 # Remark: nt had to be increased compared to 07 again

# Initial condition
##############################
# Initialize dependent variables
p = numpy.zeros((nx, ny))
p[0,:] = 0  # p = 0 @ x = 0
p[-1,:] = y # p = y @ x = 2
p[:,0] = p[:,1] # dp/dy = 0 @ y = 0
p[:,-1] = p[:,-2]   # dp/dy = 0 @ y = 1

######################################################################
# SOME FUN                                                           #
######################################################################
plot2d(x, y, p, 'initial')
p = laplace2d(p, y, dx, dy, 1e-4)
plot2d(x, y, p, 'L1=1e-4')
pyplot.show()


''' Principal component analysis (PCA) is a dimensionality reduction
technique that can used in Unsupervised Learning. It is important to
minimise the number of dimensions when working with a data set that has
a large number of features.

'''
#https://deepblade.com/artificial-intelligence/machine-learning/principal-component-analysis-pca/

import numpy as np
import matplotlib.pyplot as plt

# create dataset as numpy array
data = np.array([[40, 20],
                [55, 30],
                [70, 60],
                [50, 35],
                [45, 40],
                [62, 75],
                [45, 30],
                [68, 80],
                [80, 70],
                [75, 90]])
n=len(data)
# feature scaling

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaled_data = scaler.fit_transform(data)

#for i in range(n):
#    print(data[i][0], scaled_data[i][0], data[i][1], scaled_data[i][1] )

print(scaled_data)

''' create a covariance matrix to measure the relationships between the
features. Then we can identify the principal components (PCs) by
calculating eigenvalues and eigenvectors using the covariance matrix.

the number of principal components equal to the number of dimensions of
the problem. this example gives a maximum of two
principal components.
'''

from sklearn.decomposition import PCA
pca = PCA(n_components=2)
pca.fit(data)

print(pca.explained_variance_)
print(pca.explained_variance_ratio_)

#number of dimensions in the data set has been reduced from 2 to 1.

data_pca = pca.transform(data)
print("Original shape:", data.shape)
print("Transformed shape:", data_pca.shape)

new_data = pca.inverse_transform(data_pca)
plt.scatter(data[:, 0], data[:, 1], alpha=0.2)
plt.scatter(new_data[:, 0], new_data[:, 1])
plt.show()


# Hierarchical Clustering
# This chapter focuses on a popular clustering algorithm - hierarchical clustering - and its implementation in SciPy. In addition to the procedure to perform hierarchical clustering, it attempts to help you answer an important question - how many clusters are present in your data? The chapter concludes with a discussion on the limitations of hierarchical clustering and discusses considerations while using hierarchical clustering.

# Hierarchical clustering: ward method
# It is time for Comic-Con! Comic-Con is an annual comic-based convention held in major cities in the world. You have the data of last year's footfall, the number of people at the convention ground at a given time. You would like to decide the location of your stall to maximize sales. Using the ward method, apply hierarchical clustering to find the two points of attraction in the area.

# The data is stored in a Pandas data frame, comic_con. x_scaled and y_scaled are the column names of the standardized X and Y coordinates of people at a given point in time.

# Import the fcluster and linkage functions
from scipy.cluster.hierarchy import fcluster, linkage

# Use the linkage() function
distance_matrix = linkage(comic_con[['x_scaled', 'y_scaled']], method = 'ward', metric = 'euclidean')

# Assign cluster labels
comic_con['cluster_labels'] = fcluster(distance_matrix, 2, criterion='maxclust')

# Plot clusters
sns.scatterplot(x='x_scaled', y='y_scaled',
                hue='cluster_labels', data = comic_con)
plt.show()

# Hierarchical clustering: single method
# Let us use the same footfall dataset and check if any changes are seen if we use a different method for clustering.

# The data is stored in a Pandas data frame, comic_con. x_scaled and y_scaled are the column names of the standardized X and Y coordinates of people at a given point in time.

# Import the fcluster and linkage functions
from    scipy.cluster.hierarchy import fcluster, linkage

# Use the linkage() function
distance_matrix = linkage(comic_con[['x_scaled', 'y_scaled']], method = 'single', metric = 'euclidean')

# Assign cluster labels
comic_con['cluster_labels'] = fcluster(distance_matrix, 2, criterion ='maxclust')

# Plot clusters
sns.scatterplot(x='x_scaled', y='y_scaled',
                hue='cluster_labels', data = comic_con)
plt.show()

# Hierarchical clustering: complete method
# For the third and final time, let us use the same footfall dataset and check if any changes are seen if we use a different method for clustering.

# The data is stored in a Pandas data frame, comic_con. x_scaled and y_scaled are the column names of the standardized X and Y coordinates of people at a given point in time.

# Import the fcluster and linkage functions
from scipy.cluster.hierarchy import fcluster, linkage

# Use the linkage() function
distance_matrix = linkage(comic_con[['x_scaled','y_scaled']], method ='complete', metric = 'euclidean')

# Assign cluster labels
comic_con['cluster_labels'] = fcluster(distance_matrix, 2, criterion='maxclust')

# Plot clusters
sns.scatterplot(x='x_scaled', y='y_scaled',
                hue='cluster_labels', data = comic_con)
plt.show()

# Visualize clusters with matplotlib
# We have discussed that visualizations are necessary to assess the clusters that are formed and spot trends in your data. Let us now focus on visualizing the footfall dataset from Comic-Con using the matplotlib module.

# The data is stored in a Pandas data frame, comic_con. x_scaled and y_scaled are the column names of the standardized X and Y coordinates of people at a given point in time. cluster_labels has the cluster labels. A linkage object is stored in the variable distance_matrix.

# Import the pyplot class
from matplotlib import pyplot as plt

# Define a colors dictionary for clusters
colors = {1:'red', 2:'blue'}

# Plot a scatter plot
comic_con.plot.scatter(x='x_scaled',
                	   y='y_scaled',
                	   c=comic_con['cluster_labels'].apply(lambda x: colors[x]))
plt.show()

# Visualize clusters with seaborn
# Let us now visualize the footfall dataset from Comic Con using the seaborn module. Visualizing clusters using seaborn is easier with the inbuild hue function for cluster labels.

# The data is stored in a Pandas data frame, comic_con. x_scaled and y_scaled are the column names of the standardized X and Y coordinates of people at a given point in time. cluster_labels has the cluster labels. A linkage object is stored in the variable distance_matrix.

# Import the seaborn module
import seaborn as sns

# Plot a scatter plot using seaborn
sns.scatterplot(x='x_scaled',
                y='y_scaled',
                hue='cluster_labels',
                data = comic_con)
plt.show()

# Create a dendrogram
# Dendrograms are branching diagrams that show the merging of clusters as we move through the distance matrix. Let us use the Comic Con footfall data to create a dendrogram.

# The data is stored in a Pandas data frame, comic_con. x_scaled and y_scaled are the column names of the standardized X and Y coordinates of people at a given point in time. cluster_labels has the cluster labels. A linkage object is stored in the variable distance_matrix.

# Import the dendrogram function
from scipy.cluster.hierarchy import dendrogram

# Create a dendrogram
dn = dendrogram(distance_matrix)

# Display the dendogram
plt.show()

# Exercise
# Exercise
# FIFA 18: exploring defenders
# In the FIFA 18 dataset, various attributes of players are present. Two such attributes are:

# sliding tackle: a number between 0-99 which signifies how accurate a player is able to perform sliding tackles
# aggression: a number between 0-99 which signifies the commitment and will of a player
# These are typically high in defense-minded players. In this exercise, you will perform clustering based on these attributes in the data.

# This data consists of 5000 rows, and is considerably larger than earlier datasets. Running hierarchical clustering on this data can take up to 10 seconds.

# The following modules are pre-loaded: dendrogram, linkage, fcluster from scipy.cluster.hierarchy, matplotlib.pyplot as plt, seaborn as sns. The data is stored in a Pandas dataframe, fifa.

# Fit the data into a hierarchical clustering algorithm
distance_matrix = linkage(fifa[['scaled_sliding_tackle', 'scaled_aggression']], 'ward')

Cluster Analysis in Python/Hierarchical_Clustering.py


"""
Power spectrum related functions.
"""
import numpy as np

def growth_func(z, Om, Ol, Ok=0):
    """
    The growth function.

    .. math::

       P(k,z) = 2*\\pi^{2} * norm_z0 * pfunc * growth_func(z)^{2}
    """
    D0 = 2.5*Om / (Om**(4./7) - Ol + (1 + 0.5*Om)*(1 + Ol/70.))

    zp1 = 1 + z
    zp1_2 = zp1**2
    zp1_3 = zp1**3
    temp =  Ol + Ok*zp1_2 + Om*zp1_3
    omegaz = Om * zp1_3 / temp
    omegalz = Ol / temp

    temp = omegaz**(4./7) - omegalz + (1 + 0.5*omegaz)*(1 + omegalz/70.)
    Dz = 1./zp1 * 2.5 * omegaz / temp
    return Dz / D0

def cdm_corr_z2p5(rvals, fudge=4.9, sigma8 = 0.809, omegam = 0.272,
                  omegal = 0.728):
    """
    Return the dark matter correlation function at separations given by rvals at z=2.5

    rvals in h^-1 Mpc
    """
    rvals = np.asarray(rvals)

    assert rvals.max() < 180
    assert rvals.min() > 1e-3
    import astro
    prefix = astro.__path__[0]
    r,xi0 = np.loadtxt(prefix + '/data/slosar09_corr.txt', unpack=1)
    xivals = np.interp(rvals, r, xi0)

    # just normalisation, don't worry too much about it
    norm = (sigma8 / 0.00039453207450944561)**2
    xi1 = 1. / (2*np.pi)**3 * xivals * norm * growth_func(2.5, omegam, omegal)

    return fudge * xi1

def powerspec(y, dt, fig=None):
    """ Find the power spectrum using an FFT.

    The samples y must be equally spaced with spacing dt. It is
    assumed y is real.

    return the coords in fourier transform space (e.g. 1/t) and the power
    spectrum values, 2 * abs(fft)**2
    """
    fft = np.fft.fft(y)
    nu = np.fft.fftfreq(len(y), dt)
    pspec = (2*np.abs(fft)**2)[:len(y)//2 + 1]
    pnu = np.abs(nu)[:len(y)//2 + 1]
    if fig is not None:
        import pylab as pl
        ax = fig.add_subplot(211)
        ax.plot(np.arange(len(y))*dt, y)
        ax.set_ylabel('$y$')
        ax.set_xlabel('T')
        ax = fig.add_subplot(212)

        ax.semilogy(pnu, pspec)
        ax.set_ylabel(r'$2*abs(fft(y))^2$')
        ax.set_xlabel('f = 1/T')

    return pnu, pspec


import cvxpy as cp
import fire
import numpy as np

rng = np.random.Generator(np.random.MT19937(seed=12345))
n = 20
# _A and _C are internal - you don't need them.
_A = rng.standard_normal((2 * n, n))
_C = np.diag(0.5 * np.exp(rng.standard_normal((n,))))

Sigma = _C @ _A.T @ _A @ _C
Sigma = 0.5 * (Sigma + Sigma.T)
M = np.ones(n) * 0.2
sigma = np.sqrt(np.diag(Sigma))

def main():
    def compute_dr(_x):
        return sigma @ _x / ((Sigma @ _x @ _x) ** 0.5)

    x = cp.Variable(n)
    cons = [x >= 0., x - M * cp.sum(x) <= 0., sigma @ x == 1., ]
    obj = cp.Minimize(cp.quad_form(x, Sigma))
    cp.Problem(objective=obj, constraints=cons).solve()

    x_star = x.value / (np.sum(x.value))
    d_x_star = compute_dr(x_star)
    print(f'x_star: {x_star}, d_x_star: {d_x_star:.6f}')

    x = cp.Variable(n)
    cons = [x >= 0., x <= M, cp.sum(x) == 1]
    obj = cp.Minimize(cp.quad_form(x, Sigma))
    cp.Problem(objective=obj, constraints=cons).solve()
    x_mv = x.value
    d_x_mv = compute_dr(x_mv)
    print(f'x_mv: {x_mv}, d_x_mv: {d_x_mv:.6f}')

    import matplotlib.pyplot as plt
    plt.bar(np.arange(0, 20), x_star, width=0.5, label="Max diversification")
    plt.bar((np.arange(0, 20) * 2 + 1) / 2, x_mv, width=0.5, label="Min variance")
    plt.legend()
    plt.show()

if __name__ == "__main__":
    fire.Fire(main)


import classy.datasets
from .Struct import Struct
import numpy as np
from numpy import sqrt,sum,exp,pi,min,max,linspace

def normal(x,mu,sd):
    return 1.0/sqrt(2*pi*sd**2)*exp(-(x-mu)**2/(2*sd**2))

def overlap(means_,covars_):
    # http://en.wikipedia.org/wiki/Bhattacharyya_distance
    # overlap is a dot product

    s1,s2=covars_
    m1,m2=means_

    minx=min([m1-4*s1,m2-4*s2])
    maxx=min([m1+4*s1,m2+4*s2])

    x=linspace(minx,maxx,1000)
    dx=x[1]-x[0]

    BC=sum(dx*sqrt(normal(x,m1,s1)*normal(x,m2,s2)))

    return BC

def GMM_features_from_1D_vectors2(origdata,number_of_gaussians_list,verbose=True):
    from sklearn.mixture import GMM

    data=Struct(origdata)
    data.vectors=[]

    data.feature_names=[]
    for M in number_of_gaussians_list:
        for G in range(M):
            data.feature_names+=['M%d mu%d' % (M,G+1),'M%d sd%d' % (M,G+1)]

    for X in origdata.vectors:
        vec=[]
        for M in number_of_gaussians_list:
            model = GMM(M).fit(X)
            means=model.means_.ravel()
            stddevs=model.covars_.ravel()

            for m,s in zip(means,stddevs):
                vec.append(m)
                vec.append(s)

        data.vectors.append(vec)

    data.vectors=np.array(data.vectors)

    if verbose:
        classy.datasets.summary(data)

    return data

def GMM_features_from_1D_vectors(origdata,number_of_gaussians,verbose=True):
    from sklearn.mixture import GMM

    data=Struct(origdata)
    data.vectors=[]

    data.feature_names=[]
    for i in range(number_of_gaussians):
        data.feature_names+=['mu%d' % (i+1),'sd%d' % (i+1)]
    L=number_of_gaussians
    for i in range(L):
        for j in range(i+1,L):
            data.feature_names+=['overlap %d-%d' % (i+1,j+1)]

    for X in origdata.vectors:
        model = GMM(number_of_gaussians).fit(X)
        means=model.means_.ravel()
        stddevs=model.covars_.ravel()
        vec=[]
        for m,s in zip(means,stddevs):
            vec.append(m)
            vec.append(s)

        L=number_of_gaussians
        for i in range(L):
            for j in range(i+1,L):
                vec.append(overlap([means[i],means[j]],[stddevs[i],stddevs[j]]))

        data.vectors.append(vec)

    data.vectors=np.array(data.vectors)

    if verbose:
        classy.datasets.summary(data)

    return data


from typing import Union, Optional

import gin
import jax.numpy as jnp
import matplotlib.pyplot as plt
import seaborn as sns

from myriad.custom_types import Params
from myriad.systems import IndirectFHCS

@gin.configurable
class MouldFungicide(IndirectFHCS):
  """
    Taken from: Optimal Control Applied to Biological Models, Lenhart & Workman (Chapter 6, Lab 2)
    This environment models the concentration level of a mould population that we try to control by
    applying a fungicide. The state ( \\(x\\) ) is the population concentration, while the control ( \\(u\\) ) is
    the amount of fungicide added. We are trying to minimize:

    .. math::

      \\begin{align}
      & \\min_u \\quad &&\\int_0^T Ax^2(t) + u^2(t) dt \\\\
      &\\; \\mathrm{s.t.}\\quad && x'(t) = r(M - x(t)) - u(t)x(t) \\\\
      & && x(0)=x_0 \\;
      \\end{align}
  """

  def __init__(self, r=0.3, M=10., A=10., x_0=1.0, T=5):
    super().__init__(
      x_0=jnp.array([x_0]),  # Starting state
      x_T=None,  # Terminal state, if any
      T=T,  # Duration of experiment
      bounds=jnp.array([  # Bounds over the states (x_0, x_1, ...) are given first,
        [0., 5.],  # followed by bounds over controls (u_0, u_1, ...)
        [0., 5.],  # nh: I replaced [-inf, inf] with [0, 5] in both of the bounds
      ]),
      terminal_cost=False,
      discrete=False,
    )

    self.adj_T = None  # Final condition over the adjoint, if any
    self.r = r
    """Growth rate"""
    self.M = M
    """Carrying capacity"""
    self.A = A
    """Weight parameter, balancing between controlling the population and limiting the fungicide use"""

  def dynamics(self, x_t: jnp.ndarray, u_t: Union[float, jnp.ndarray],
               v_t: Optional[Union[float, jnp.ndarray]] = None, t: Optional[jnp.ndarray] = None) -> jnp.ndarray:
    d_x = self.r * (self.M - x_t) - u_t * x_t

    return d_x

  def parametrized_dynamics(self, params: Params, x_t: jnp.ndarray, u_t: Union[float, jnp.ndarray],
                            v_t: Optional[Union[float, jnp.ndarray]] = None,
                            t: Optional[jnp.ndarray] = None) -> jnp.ndarray:
    r = params['r']
    M = params['M']
    d_x = r * (M - x_t) - u_t * x_t

    return d_x

  def cost(self, x_t: jnp.ndarray, u_t: Union[float, jnp.ndarray], t: Optional[jnp.ndarray] = None) -> float:
    return self.A * x_t ** 2 + u_t ** 2

  def parametrized_cost(self, params: Params, x_t: jnp.ndarray, u_t: Union[float, jnp.ndarray],
                        t: Optional[jnp.ndarray] = None) -> float:
    return self.A * x_t ** 2 + u_t ** 2  # don't learn the cost for now

  def adj_ODE(self, adj_t: jnp.ndarray, x_t: Optional[jnp.ndarray], u_t: Optional[jnp.ndarray],
              t: Optional[jnp.ndarray]) -> jnp.ndarray:
    return adj_t * (self.r + u_t) - 2 * self.A * x_t

  def optim_characterization(self, adj_t: jnp.ndarray, x_t: Optional[jnp.ndarray],
                             t: Optional[jnp.ndarray]) -> jnp.ndarray:
    char = 0.5 * adj_t * x_t
    return jnp.minimum(self.bounds[-1, 1], jnp.maximum(self.bounds[-1, 0], char))


import pycuda.autoinit
import pycuda.driver as drv
from pycuda import gpuarray
from pycuda.compiler import SourceModule
import numpy as np

# https://docs.nvidia.com/cuda/cuda-math-api/index.html

MonteCarloKernelTemplate = '''
#include <curand_kernel.h>

#define ULL  unsigned long long
#define _R(z)   ( 1.0f / (z) )
#define _P2(z)   ( (z) * (z) )

// p stands for "precision" (single or double)
__device__ inline %(p)s  f(%(p)s x)
{
     %(p)s y;

     %(math_function)s;

    return y;
}

extern "C" {
__global__ void monte_carlo(int iters, %(p)s lo, %(p)s hi, %(p)s * ys_out)
{
    curandState cr_state;

	int tid = blockIdx.x * blockDim.x + threadIdx.x;

    int num_threads = blockDim.x * gridDim.x;

    %(p)s t_width = (hi - lo) / ( %(p)s ) num_threads;

    %(p)s density = ( ( %(p)s ) iters ) / t_width;

    %(p)s t_lo = t_width*tid + lo;
    %(p)s t_hi = t_lo + t_width;

	curand_init( (ULL)  clock() + (ULL) tid, (ULL) 0, (ULL) 0, &cr_state);

     %(p)s y, y_sum = 0.0f;

     %(p)s rand_val, x;
     for (int i=0; i < iters; i++)
     {
         rand_val = curand_uniform%(p_curand)s(&cr_state);

         x = t_lo + t_width * rand_val;

         y_sum += f(x);
     }

     y = y_sum / density;

     ys_out[tid] = y;
}

}
'''

class MonteCarloIntegrator:

    def __init__(self, math_function='y = sin(x)', precision='d', lo=0, hi=np.pi, samples_per_thread=10**5, num_blocks=100):

        self.math_function = math_function

        if precision in [None, 's', 'S', 'single', np.float32]:
            self.precision = 'float'
            self.numpy_precision = np.float32
            self.p_curand = ''
        elif precision in ['d','D', 'double', np.float64]:
            self.precision = 'double'
            self.numpy_precision = np.float64
            self.p_curand = '_double'
        else:
            raise Exception('precision is invalid datatype!')

        if (hi - lo <= 0):
            raise Exception('hi - lo <= 0!')
        else:
            self.hi = hi
            self.lo = lo

        MonteCarloDict = {'p' : self.precision, 'p_curand' : self.p_curand, 'math_function' : self.math_function}

        self.MonteCarloCode = MonteCarloKernelTemplate % MonteCarloDict

        self.ker = SourceModule(no_extern_c=True , options=['-w'], source=self.MonteCarloCode)

        self.f = self.ker.get_function('monte_carlo')

        self.num_blocks = num_blocks

        self.samples_per_thread = samples_per_thread

    def definite_integral(self, lo=None, hi=None, samples_per_thread=None, num_blocks=None):

        if lo is None or hi is None:
            lo = self.lo
            hi = self.hi

        if samples_per_thread is None:
            samples_per_thread = self.samples_per_thread

        if num_blocks is None:
            num_blocks = self.num_blocks
            grid = (num_blocks,1,1)
        else:
            grid = (num_blocks,1,1)

        block = (32,1,1)

        num_threads = 32*num_blocks

        self.ys = gpuarray.empty((num_threads,) , dtype=self.numpy_precision)

        self.f(np.int32(samples_per_thread), self.numpy_precision(lo), self.numpy_precision(hi), self.ys, block=block, grid=grid)

        self.nintegral = np.sum(self.ys.get() )

        return np.sum(self.nintegral)

if __name__ == '__main__':

    integral_tests = [('y =log(x)*_P2(sin(x))', 11.733 , 18.472, 8.9999), ('y = _R( 1 + sinh(2*x)*_P2(log(x)) )', .9, 4, .584977), ('y = (cosh(x)*sin(x))/ sqrt( pow(x,3) + _P2(sin(x)))', 1.85, 4.81,  -3.34553) ]

    for f, lo, hi, expected in integral_tests:
        mci = MonteCarloIntegrator(math_function=f, precision='d', lo=lo, hi=hi)
        print('The Monte Carlo numerical integration of the function\n \t f: x -> %s \n \t from x = %s to x = %s is : %s ' % (f, lo, hi, mci.definite_integral()))
        print('where the expected value is : %s\n' % expected)


"""
Core algorithm: MergeSort
Created on Tue May 29 12:19:47 2018

@author: jialinyi
"""

def MergeArray(B, C):
    A = []
    B_copy, C_copy = B[:], C[:]

    while len(B_copy) > 0 and len(C_copy) > 0:
        if B_copy[0] <= C_copy[0]:
            item = B_copy.pop(0)
        else:
            item = C_copy.pop(0)
        A.append(item)

    if not B_copy:
        return A + C_copy
    else:
        return A + B_copy

def MergeSort(A):
    if len(A) < 2:
        return A
    else:
        index = int(len(A)/2)
        B = A[:index]
        C = A[index:]
        B_sorted = MergeSort(B)
        C_sorted = MergeSort(C)
        A_sorted = MergeArray(B_sorted, C_sorted)
    return A_sorted

if __name__ == '__main__':
    import numpy as np
    A = np.random.randn(200)
    A = np.ndarray.tolist(A)
    A_sorted = MergeSort(A)
    A.sort()
    print(A_sorted == A)

algorithms/stanford-algorithms-design and-analysis/programming assignments/Programming Question 1/mergesort.py


import numpy as np
import pandas as pd
import statsmodels.api as sm
tsa = sm.tsa # as shorthand

mdata = sm.datasets.macrodata.load().data
type(mdata)

endog = np.log(mdata['m1'])
exog = np.column_stack([np.log(mdata['realgdp']), np.log(mdata['cpi'])])
exog = sm.add_constant(exog, prepend=True)
exog
res1 = sm.OLS(endog, exog).fit()

acf, ci, Q, pvalue = tsa.acf(res1.resid, nlags=4,alpha=.05, qstat=True,unbiased=True)
acf
pvalue

tsa.pacf(res1.resid, nlags=4)

#==============================================================================
# FILTER
#==============================================================================

from scipy.signal import lfilter
data = sm.datasets.macrodata.load()
infl = data.data.infl[1:]
data.data.shape

# get 4 qtr moving average
infl = lfilter(np.ones(4)/4, 1, infl)[4:]
unemp = data.data.unemp[1:]

#To apply the Hodrick-Prescott filter to the data 3, we can do
infl_c, infl_t = tsa.filters.hpfilter(infl)
unemp_c, unemp_t = tsa.filters.hpfilter(unemp)

#The Baxter-King filter 4 is applied as
infl_c = tsa.filters.bkfilter(infl)
unemp_c = tsa.filters.bkfilter(unemp)

#The Christiano-Fitzgerald filter is similarly applied 5
infl_c, infl_t = tsa.filters.cfilter(infl)
unemp_c, unemp_t = tsa.filters.cfilter(unemp)

#plot
INFLA=pd.DataFrame(infl_c,columns=['INFLA'])
UNEMP=pd.DataFrame(unemp_c[4:],columns=['UNEMP'])
pd.concat([INFLA,UNEMP],axis=1).plot()

INFLA=pd.DataFrame(infl_t,columns=['INFLA'])
UNEMP=pd.DataFrame(unemp_t[4:],columns=['UNEMP'])
pd.concat([INFLA,UNEMP],axis=1).plot()

#==============================================================================
# BENCHMARKING TO STANDARDISE LOWER FREQ TO HIGHER FREQ
#==============================================================================
iprod_m = np.array([ 87.4510, 86.9878, 85.5359, #INDUSTRIAL PRODUCTION INDEX
                    84.7761, 83.8658, 83.5261, 84.4347,
                    85.2174, 85.7983, 86.0163, 86.2137,
                    86.7197, 87.7492, 87.9129, 88.3915,
                    88.7051, 89.9025, 89.9970, 90.7919,
                    90.9898, 91.2427, 91.1385, 91.4039,
                    92.5646])
gdp_q = np.array([14049.7, 14034.5, 14114.7,14277.3, 14446.4, 14578.7, 14745.1,14871.4])
gdp_m = tsa.interp.dentonm(iprod_m, gdp_q,freq="qm")

a=[]
[a.extend([i]*4) for i in gdp_q]

x=pd.DataFrame([iprod_m,gdp_m],index=['IPROD','GDP MONTHLY']).T
x.plot(secondary_y='IPROD')
pd.DataFrame([gdp_m,a],index=['monthly','quarterly']).T.plot(secondary_y='quarterly')

mdata = sm.datasets.macrodata.load().data
mdata = mdata[['realgdp','realcons','realinv']]
names = mdata.dtype.names
data = mdata.view((float,3))
data = np.diff(np.log(data), axis=0)
#statsmodels.tsa.vector_ar.var_model.VAR
import statsmodels
data
model = statsmodels.tsa.vector_ar.var_model.VAR(data)
model.endog_names = names
res = model.fit(maxlags=2)
res.plot_forecast(5)
res.fevd().plot()

#autocorrelation
res.plot_sample_acorr()
# impulse response
irf = res.irf(10) # 10 periods
irf.plot()

# granger causality with VAR.fit
res.test_causality(equation='y1',variables=['y2'])
res.test_causality(equation='y1',variables=['y2','y3'])

wordpress-py-scripts/scipy timeseries test 1.py

import numpy,from scipy,import statsmodels


# <nbformat>2</nbformat>

# <markdowncell>

# # Eigenvalue distribution of Gaussian orthogonal random matrices

# <markdowncell>

# The eigenvalues of random matrices obey certain statistical laws. Here we construct random matrices
# from the Gaussian Orthogonal Ensemble (GOE), find their eigenvalues and then investigate the nearest
# neighbor eigenvalue distribution $\rho(s)$.

# <codecell>

from rmtkernel import ensemble_diffs, normalize_diffs, GOE
import numpy as np
from IPython.parallel import Client

# <markdowncell>

# ## Wigner's nearest neighbor eigenvalue distribution

# <markdowncell>

# The Wigner distribution gives the theoretical result for the nearest neighbor eigenvalue distribution
# for the GOE:
#
# $$\rho(s) = \frac{\pi s}{2} \exp(-\pi s^2/4)$$

# <codecell>

def wigner_dist(s):
    """Returns (s, rho(s)) for the Wigner GOE distribution."""
    return (np.pi*s/2.0) * np.exp(-np.pi*s**2/4.)

# <codecell>

def generate_wigner_data():
    s = np.linspace(0.0,4.0,400)
    rhos = wigner_dist(s)
    return s, rhos

# <codecell>

s, rhos = generate_wigner_data()

# <codecell>

plot(s, rhos)
xlabel('Normalized level spacing s')
ylabel('Probability $\rho(s)$')

# <markdowncell>

# ## Serial calculation of nearest neighbor eigenvalue distribution

# <markdowncell>

# In this section we numerically construct and diagonalize a large number of GOE random matrices
# and compute the nerest neighbor eigenvalue distribution. This comptation is done on a single core.

# <codecell>

def serial_diffs(num, N):
    """Compute the nearest neighbor distribution for num NxX matrices."""
    diffs = ensemble_diffs(num, N)
    normalized_diffs = normalize_diffs(diffs)
    return normalized_diffs

# <codecell>

serial_nmats = 1000
serial_matsize = 50

# <codecell>

%timeit -r1 -n1 serial_diffs(serial_nmats, serial_matsize)

# <codecell>

serial_diffs = serial_diffs(serial_nmats, serial_matsize)

# <markdowncell>

# The numerical computation agrees with the predictions of Wigner, but it would be nice to get more
# statistics. For that we will do a parallel computation.

# <codecell>

hist_data = hist(serial_diffs, bins=30, normed=True)
plot(s, rhos)
xlabel('Normalized level spacing s')
ylabel('Probability $P(s)$')

# <markdowncell>

# ## Parallel calculation of nearest neighbor eigenvalue distribution

# <markdowncell>

# Here we perform a parallel computation, where each process constructs and diagonalizes a subset of
# the overall set of random matrices.

# <codecell>

def parallel_diffs(rc, num, N):
    nengines = len(rc.targets)
    num_per_engine = num/nengines
    print "Running with", num_per_engine, "per engine."
    ar = rc.apply_async(ensemble_diffs, num_per_engine, N)
    diffs = np.array(ar.get()).flatten()
    normalized_diffs = normalize_diffs(diffs)
    return normalized_diffs

# <codecell>

client = Client()
view = client[:]
view.run('rmtkernel.py')
view.block = False

# <codecell>

parallel_nmats = 40*serial_nmats
parallel_matsize = 50

# <codecell>

%timeit -r1 -n1 parallel_diffs(view, parallel_nmats, parallel_matsize)

# <codecell>

pdiffs = parallel_diffs(view, parallel_nmats, parallel_matsize)

# <markdowncell>

# Again, the agreement with the Wigner distribution is excellent, but now we have better
# statistics.

# <codecell>

hist_data = hist(pdiffs, bins=30, normed=True)
plot(s, rhos)
xlabel('Normalized level spacing s')
ylabel('Probability $P(s)$')


from math import inf, isnan
import numpy as np

def xy_to_complex(xy):
    return xy[0] + 1j*xy[1]

def complex_to_xy(comp):
    return [np.real(comp), np.imag(comp)]

def complex_plane(width=1000, height=1000, centered=True):
    x, x_step = np.linspace(0, 1, num=width, endpoint=False, retstep=True)
    y, y_step = np.linspace(0, 1, num=height, endpoint=False, retstep=True)
    if centered:
        x += 0 if isnan(x_step) else (x_step / 2)
        y += 0 if isnan(y_step) else (y_step / 2)
    return x[np.newaxis,:] + 1j*y[:,np.newaxis]

def distance_plane(complex_plane, point):
    return np.abs(complex_plane - point)

def waveform_plane(distance_plane, cycle_count=inf):
    source_phase = np.pi/2 - (cycle_count % 1) * 2*np.pi if cycle_count != inf else 0
    phase_plane = distance_plane * 2*np.pi + source_phase
    wave = np.exp(1j*phase_plane)
    np.putmask(wave, distance_plane > cycle_count, 0)
    return wave

def source_waveform_plane(complex_plane, source, wavelength=1, cycle_count=inf, spreading=True, min_spreading_distance=1e-14):
    distance = distance_plane(complex_plane, source)
    source_waveform_plane = waveform_plane(distance / wavelength, cycle_count)
    if spreading: source_waveform_plane /= np.fmax(distance, min_spreading_distance)
    return source_waveform_plane


import numpy as np

def gaussian( stdx, stdy, A, x, y ):

    return A * np.exp( -1. * ( x*x/(2*stdx*stdx) + y*y/(2*stdy*stdy) ))

A = 1.
stdx = .1
stdy = .1
nx = 5
ny = 5
shiftx = -2
shifty = -2
x = np.linspace(-.4, .4, nx)
y = np.linspace(-.4, .4, ny)

xv, yv = np.meshgrid(x,y, sparse=False, indexing='ij')

f = open('handoff_scalar.dat','w')
f.write('gaussian variable\n')
f.write('0.2 0.2\n')
f.write(np.str(nx*ny)+'\n')

for i in range(nx):
    for j in range(ny):

        g = gaussian(stdx, stdy, A, xv[i][j], yv[i][j])
        to_write = '0 '+np.str(i+shiftx)+' '+np.str(j+shifty)+' '+np.str(g)+'\n'
        f.write(to_write)

f.close()

f = open('handoff_velocity.dat','w')
f.write('gaussian_variable\n')
f.write('0.2 0.2\n')
f.write(np.str(nx*ny)+'\n')

for i in range(nx):
    for j in range(ny):

        g = gaussian(stdx, stdy, A, xv[i][j], yv[i][j])
        to_write = '0 '+np.str(i+shiftx)+' '+np.str(j+shifty)+' '+np.str(g)+' 1. 1.\n'
        f.write(to_write)

f.close()


import numpy as np
x = np.array([6,8,12,14,18])
y = np.array([7,9,13,15,19])

def gradiant_descent(x,y):
    m = c = 0
    loop = 10
    alpha = 0.3
    n = len(x)
    for i in range(loop):
        yp = m*x + c
        costfunc = (1/n)*sum(val*val for val in (y-yp))
        dm = -(2/n)*sum(x*(y-yp))
        dn = -(2/n)*sum(y-yp)
        m = m - alpha*dm
        c = c - alpha*dn
        print(f"m:{m} c:{c} y:{yp} cost: {costfunc}")

gradiant_descent(x,y)


#Python3 Steven
#common proability distrubutions
#import math
import numpy as np
from scipy import integrate
from scipy.special import gamma,beta,factorial
#from sklearn.preprocessing import Normalizer
#https://en.wikipedia.org/wiki/Gamma_function
#https://en.wikipedia.org/wiki/Beta_function
#https://en.wikipedia.org/wiki/Factorial
from permutationAndCom import combinat #,permut

#---------------------------Discrete distribution------------------------------#
def Discrete_uniform_distribution(x, N=5):#https://en.wikipedia.org/wiki/Discrete_uniform_distribution
    return np.zeros(len(x)) + 1/N

def Binomial_distribution(N, p=1): #https://en.wikipedia.org/wiki/Binomial_distribution
    assert N>=1
    assert 0<=p<=1
    def Binomial(k):
        return combinat(N,k)*np.power(p,k)*np.power(1-p,N-k)

    return list(map(Binomial, range(N)))

def Geometric_distribution(N, p):#https://en.wikipedia.org/wiki/Geometric_distribution
    def Geometric(k):
        return np.power(1-p,k)*p

    return list(map(Geometric, range(N)))

def Hypergeometric_distribution(N, K, n): #https://en.wikipedia.org/wiki/Hypergeometric_distribution
    def Hypergeometric(k):
        return combinat(K,k)*combinat(N-K,n-k)/combinat(N,n)

    return list(map(Hypergeometric, range(n)))

def Poisson_distribution(N=20, lam=1): #https://en.wikipedia.org/wiki/Poisson_distribution
    def Poisson(k):
        return np.power(lam,k)*np.power(np.e, -1*lam)/factorial(k)

    return list(map(Poisson, range(N)))

def ZipfsLaw(N=10, s=1):#https://en.wikipedia.org/wiki/Zipf%27s_law
    v = np.sum(1/np.power([i+1 for i in range(N)],s))
    def ZipfLaw(k):
        return (1/np.power(k,s))/v

    return list(map(ZipfLaw, [i+1 for i in range(N)]))

def Beta_binomial_distribution(N=10, alpha=0.2, bta=0.25): #https://en.wikipedia.org/wiki/Beta-binomial_distribution
    def Beta_binomial(k):
        return combinat(N,k)*beta(k+alpha, N-k+bta)/beta(alpha,bta)

    return list(map(Beta_binomial, range(N)))

def Logarithmic_distribution(N, p=0.33): #https://en.wikipedia.org/wiki/Logarithmic_distribution
    def Logarithmic(k):
        return -1*np.power(p,k)/(np.log(1-p)*k)

    return list(map(Logarithmic, [i+1 for i in range(N)]))

def Conway_Maxwell_Poisson_distribution(N=20, lam=1, v=1.5): # https://en.wikipedia.org/wiki/Conway%E2%80%93Maxwell%E2%80%93Poisson_distribution
    def Conway(k):
        return np.power(lam,k)/np.power(factorial(k),v)

    max_num = 10000
    z = np.sum(list(map(Conway, range(max_num))))
    res = list(map(Conway, range(N)))
    return res/z

def Modified_Bessel_functions(x, alpha=0): #https://en.wikipedia.org/wiki/Bessel_function#Modified_Bessel_functions
    def Bessel(k):
        return 1/(factorial(k)*gamma(k+alpha+1))*np.power(0.2*x,2*k+alpha)

    max_num = 10000
    return np.sum(list(map(Bessel, range(max_num))))

def Skellam_distribution(N=8, u1=1, u2=1): #https://en.wikipedia.org/wiki/Skellam_distribution
    def Skellam(k):
        return np.exp(-u1-u2)*np.power(u1/u2, 0.5*k)*Modified_Bessel_functions(x=2*np.sqrt(u1*u2),alpha=k)
    return list(map(Skellam, [i-N/2 for i in range(N+1)]))

def Yule_Simon_distribution(N=20, ru=0.25): #https://en.wikipedia.org/wiki/Yule%E2%80%93Simon_distribution
    def Yule_Simon(k):
        return ru*beta(k, ru+1)
    return list(map(Yule_Simon, range(1, N+1)))

def Riemann_zeta_function(s=2):#https://en.wikipedia.org/wiki/Riemann_zeta_function
    def Riemann_zeta(k):
        return 1/np.power(k,s)

    max_num = 100
    return np.sum(list(map(Riemann_zeta, range(1, max_num+1))))

def Zeta_distribution(N=16, s=2): #https://en.wikipedia.org/wiki/Zeta_distribution
    def Zeta(k):
        return 1/(Riemann_zeta_function(s=s)*np.power(k,s))
    return list(map(Zeta, range(1, N+1)))

#---------------------------Continuous distribution------------------------------#
def Uniform_distribution(N, a=1, b=3): #https://en.wikipedia.org/wiki/Uniform_distribution_(continuous)
    return np.zeros(N) + 1/(b-a)

def Error_function(x): #https://en.wikipedia.org/wiki/Error_function
    def erf(t):
        return (2/np.sqrt(np.pi))*np.exp(-t**2)
    return integrate.quad(erf, 0, x)[0]

def NormalDistribution(x, delta=1, u=0): #https://en.wikipedia.org/wiki/Normal_distribution
    return (1/(delta*np.sqrt(2*np.pi)))*np.exp(-0.5*((x-u)/delta)**2)

def Cauchy_pdf(x, x0=0, scaler=1):#https://en.wikipedia.org/wiki/Cauchy_distribution
    return (1/(np.pi*scaler))*(scaler**2/((x-x0)**2+scaler**2))

def Generalized_logistic_distribution(x, alpha=1):#https://en.wikipedia.org/wiki/Generalized_logistic_distribution
    return alpha*np.exp(-1*x)/np.power(1+np.exp(-1*x),alpha+1)

def Gumbel_distribution(x, u=0, belta=1):#https://en.wikipedia.org/wiki/Gumbel_distribution
    z = (x-u)/belta
    return np.exp(-1*(z + np.exp(-1*z)))/belta

def Laplace_distribution(x, u=0, b=1):#https://en.wikipedia.org/wiki/Laplace_distribution
    return np.exp(-1*np.abs(x-u)/b)

def Logistic_distribution(x, u=0, s=1):#https://en.wikipedia.org/wiki/Logistic_distribution
    z = np.exp(-1*(x-u)/s)
    return z/(s*(1+z)**2)

def Gamma_distribution(x, k=1, theta=2): #https://en.wikipedia.org/wiki/Gamma_distribution
    return np.power(x,k-1)*np.exp(-1*x/theta)/(gamma(k)*np.power(theta,k))

def StudentT_distribution(x, v=1):#https://en.wikipedia.org/wiki/Student%27s_t-distribution
    z = np.power(1+x**2/v, -0.5*(v+1))
    return z*gamma((v+1)/2)/(gamma(v/2)*np.sqrt(np.pi*v))
    #return z/(beta(0.5, v/2)*np.sqrt(v))

def Log_normal_distribution(x, delta=1, u=0):#https://en.wikipedia.org/wiki/Log-normal_distribution
    z = -1*(np.log(x)-u)**2/(2*delta**2)
    return (1/(x*delta*np.sqrt(2*np.pi)))* np.exp(z)

def Weibull_distribution(x, lamda=1, k=1): #https://en.wikipedia.org/wiki/Weibull_distribution
    y = np.zeros((len(x),))
    l = np.where(x < 0)
    if len(l) != 0:
        y[l[0]]=0

    l = np.where(x >= 0)
    if len(l) != 0:
        y[l[0]] = (k/lamda)*np.power(x[l[0]]/lamda,k-1)*np.exp(-1*np.power(x[l[0]]/lamda,k))
    return y

def Pareto_distribution(x, alpha=1, Xm=1):#https://en.wikipedia.org/wiki/Pareto_distribution
    y = np.zeros((len(x),))
    l = np.where(x < Xm)
    if len(l) != 0:
        y[l[0]]=0

    l = np.where(x >= Xm)
    if len(l) != 0:
        y[l[0]] = alpha*np.power(Xm,alpha)/np.power(x[l[0]],alpha+1)
    return y

def Rayleigh_distribution(x, delta=0.5):#https://en.wikipedia.org/wiki/Rayleigh_distribution
    y = np.zeros((len(x),))
    l = np.where(x >= 0)
    if len(l) != 0:
        y[l[0]] = (x/delta**2)*np.exp(-1*x**2/(2*delta**2))
    return y

def Beta_distribution(x, alpha=0.5, bta=0.5): #https://en.wikipedia.org/wiki/Beta_distribution
    z = gamma(alpha)*gamma(bta)/gamma(alpha+bta)
    return np.power(x, alpha-1)*np.power(1-x, bta-1)/z

def Chi_distribution(x, k=1): #https://en.wikipedia.org/wiki/Chi_distribution
    return (2/ (np.power(2,k/2)* gamma(k/2)))*np.power(x,k-1)*np.exp(-0.5*x**2)

def Erlang_distribution(x, k=1, u=2.0): #https://en.wikipedia.org/wiki/Erlang_distribution
    return np.power(x,k-1)*np.exp(-1*x/u)/(np.power(u,k)*factorial(k-1))

def Exponential_distribution(x, lam=1): #https://en.wikipedia.org/wiki/Exponential_distribution
    return lam*np.exp(-1*lam*x)

def Von_Mises_distribution(x, u=0, k=0): #https://en.wikipedia.org/wiki/Von_Mises_distribution
    return np.exp(k*np.cos(x-u))/(2*np.pi*Modified_Bessel_functions(alpha=0,x=k))

def Boltzmann_distribution(x, a=1): #https://en.wikipedia.org/wiki/Maxwell%E2%80%93Boltzmann_distribution
    return x**2*np.sqrt(2/np.pi)*np.exp(-0.5*x**2/a**2)/a**3

def logit(x):#https://en.wikipedia.org/wiki/Logit
    return np.log(x/(1-x))

def Logit_normal_distribution(x, deta=0.2, u=0): #https://en.wikipedia.org/wiki/Logit-normal_distribution
    z = np.exp(-1*((logit(x)-u)**2)/(2*deta**2))
    return z/(deta*np.sqrt(2*np.pi)*x*(1-x))

def Irwin_Hall_distribution(x,n=1): #https://en.wikipedia.org/wiki/Irwin%E2%80%93Hall_distribution
    def Irwin_Hall(x):
        def f(k):
            return np.power(-1,k)*combinat(n,k)*np.power(x-k,n-1)
        #print('x_=',np.floor(x))
        NN = int(np.floor(x))
        res = np.array(list(map(f, range(NN+1))))
        res = np.sum(res)*(1/factorial(n-1))
        return res

    return list(map(Irwin_Hall, list(x)))

def Bates_distribution(x, n=1, a=0, b=1): #https://en.wikipedia.org/wiki/Bates_distribution
    def sgn(x, k):
        if x < k:
            return -1
        elif x == k:
            return 0
        return 1

    def Bates(x):
        def f(k):
            return np.power(-1, k)*combinat(n,k)*np.power((x-a)/(b-a)-k/n,n-1)*sgn((x-a)/(b-a),k/n)
        return np.sum(list(map(f, range(n))))

    return list(map(Bates, list(x)))

def Kumaraswamy_distribution(x, a=0.5, b=0.5): #https://en.wikipedia.org/wiki/Kumaraswamy_distribution
    return a*b*np.power(x,a-1)*np.power(1-np.power(x,a),b-1)

def PERT_distribution(x, a=0, b=10, c=100): #https://en.wikipedia.org/wiki/PERT_distribution
    alpha = 1+4*(b-a)/(c-a)
    bta = 1+4*(c-b)/(c-a)
    return np.power(x-a, alpha-1)*np.power(c-x, bta-1)/(beta(alpha, bta)*np.power(c-a, alpha+bta-1))

def Reciprocal_distribution(x, a=1, b=4): #https://en.wikipedia.org/wiki/Reciprocal_distribution
    return 1/x*np.log(b/a)

def Triangular_distribution(x, a=1, c=3, b=4): #https://en.wikipedia.org/wiki/Triangular_distribution
    assert(a < c < b)
    y = np.zeros((len(x),))
    l = np.where(x > b)
    if len(l) != 0:
        y[l[0]]=0

    l = np.where(x <= b)
    if len(l) != 0:
        y[l[0]]= 2*(b-x[l[0]])/((b-a)*(b-c))
    l = np.where(x <= c)
    if len(l) != 0:
        y[l[0]]= 2*(x[l[0]]-a)/((b-a)*(c-a))
    l = np.where(x < a )
    if len(l) != 0:
        y[l[0]]= 0
    return y

def Trapezoidal_distribution(x, a=-3, b=-2, c=-1, d=0): #https://en.wikipedia.org/wiki/Trapezoidal_distribution
    assert(a<b<c<d)
    y = np.zeros((len(x),))
    l = np.where(x <= d)
    if len(l) != 0:
        y[l[0]]=2*(d-x[l[0]])/((d+c-a-b)*(d-c))

    l = np.where(x <= c)
    if len(l) != 0:
        y[l[0]]=2/(d+c-a-b)

    l = np.where(x < b)
    if len(l) != 0:
        y[l[0]]=2*(x[l[0]]-a)/((d+c-a-b)*(b-a))
    return y

def PIFuc(x):
    return 0.5*(1+Error_function(x/np.sqrt(2)))

def Truncated_normal_distribution(x, a=-10, b=10, u=-8, deta=2): #https://en.wikipedia.org/wiki/Truncated_normal_distribution
    return (1/deta)*NormalDistribution((x-u)/deta)/(PIFuc((b-u)/deta)-PIFuc((a-u)/deta))

def Wigner_semicircle_distribution(x, r=0.25): #https://en.wikipedia.org/wiki/Wigner_semicircle_distribution
    return 2*np.sqrt(r**2-x**2)/(np.pi*r**2)

def Dagum_distribution(x, b=1, p=1, a=0.5): #https://en.wikipedia.org/wiki/Dagum_distribution
    z1=(a*p/x)*np.power(x/b, a*p)
    z2 = np.power(np.power(x/b, a)+1, p+1)
    return z1/z2

def F_distribution(x,d1=1,d2=1): #https://en.wikipedia.org/wiki/F-distribution
    z = np.power(d1*x,d1)*np.power(d2,d2)/np.power(x*d1+d2,d1+d2)
    return np.sqrt(z)/(x*beta(0.5*d1,0.5*d2))

def Folded_normal_distribution(x, u=1, deta=1): #https://en.wikipedia.org/wiki/Folded_normal_distribution
    z=1/(deta*np.sqrt(2*np.pi))
    z1 = z*np.exp(-0.5*(x-u)**2/deta**2)
    z2 = z*np.exp(-0.5*(x+u)**2/deta**2)

    y = z1+z2
    l = np.where(x < 0)
    if len(l) != 0:
        y[l[0]]=0
    return y

def Frechet_distribution(x, alpha=1, s=1, m=0): #https://en.wikipedia.org/wiki/Fr%C3%A9chet_distribution
    z=(x-m)/s
    z1=np.power(z, -1-alpha)
    z2 = np.exp(-1*np.power(z, -1*alpha))
    return (alpha/s)*z1*z2

def Gompertz_distribution(x, eta=0.1, b=1): #https://en.wikipedia.org/wiki/Gompertz_distribution
    z=eta+b*x-eta*np.exp(b*x)
    return b*eta*np.exp(z)

def Half_normal_distribution(x, delta=1): #https://en.wikipedia.org/wiki/Half-normal_distribution
    return np.sqrt(2)/(delta*np.sqrt(np.pi))*np.exp(-0.5*x**2/delta**2)

def Nakagami_distribution(x, m=0.5, w=1): #https://en.wikipedia.org/wiki/Nakagami_distribution
    z = gamma(m)*np.power(w,m)
    return (2*np.power(m,m)/z)*np.power(x,2*m-1)*np.exp(-1*m*x**2/w)

def Levy_distribution(x, u=0, c=0.5): #https://en.wikipedia.org/wiki/L%C3%A9vy_distribution
    return np.sqrt(0.5*c/np.pi)*np.exp(-0.5*c/(x-u))/np.power(x-u, 1.5)

def Shifted_Gompertz_distribution(x, b=0.4, ni=0.01): #https://en.wikipedia.org/wiki/Shifted_Gompertz_distribution
    z=np.exp(-1*b*x)
    return b*z*np.exp(-1*ni*z)*(1+ni*(1-z))

def JohnsonSU_distribution(x, gama=-2, deta=2, xi=1.1, lam=1.5): #https://en.wikipedia.org/wiki/Johnson%27s_SU-distribution
    z1=deta/(lam*np.sqrt(2*np.pi))
    z2=1/np.sqrt(1+((x-xi)/lam)**2)
    z3=np.exp(-0.2*(gama+deta*np.arcsinh((x-xi)/lam))**2)
    return z1*z2*z3

def Landau_distribution(x, u=0, c=1): #https://en.wikipedia.org/wiki/Landau_distribution
    def getFunctionSympy(t,x=x,u=u,c=c):
        #print('x,u,c=',x,u,c)
        y=(1/np.pi*c)*np.exp(-t)*np.cos(t*((x-u)/c)+ 2*t/np.pi*np.log(t/c))
        #y=np.exp(-t)
        return y

    return integrate.quad(getFunctionSympy, 0, np.inf)[0]

def Stable_distribution(x, beta=0, c=1, alpha=0.5): #https://en.wikipedia.org/wiki/Stable_distribution
    def sgnArray(x,k):
        return np.where(x>k, 1, 0) + np.where(x<k, -1, 0)

    z1 = np.power(np.abs(x),1+alpha)
    z2 = np.power(c,alpha)*(1+sgnArray(x,0)*beta)*np.sinh(0.5*np.pi*alpha)
    z3 = gamma(alpha+1)/np.pi
    res = z2*z3/z1
    # res = res.reshape(1,-1)
    # res = Normalizer().fit(res).transform(res)
    # res = res.reshape((len(x)))
    # print(res.shape,len(x))
    return res

def PIFuc2(x):
    #return 0.5*(1+Error_function(x/np.sqrt(2)))
    return np.array(list(map(PIFuc, list(x))))

def Skew_normal_distribution(x, alpha=-4): #https://en.wikipedia.org/wiki/Skew_normal_distribution
    return 2* NormalDistribution(x)*PIFuc2(alpha*x)

def Noncentral_t_distribution(x, v=1): #https://en.wikipedia.org/wiki/Noncentral_t-distribution
    return StudentT_distribution(x,v=v)


import math
import pandas as pd
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt

#We will draw samples from phi(x)*I_{x>c}

#This is the _err_ function needed for the Gaussian distribution CDF
def err(x):
    err_x = 0
    for i in range(125):
        err_x += ((-1.0)**i) * (x**((2.0*i)+1))/(math.factorial(i)*((2*i)+1))
    err_x = (2.0/math.sqrt(math.pi))*err_x
    return err_x

#Approximation to Gaussian Distribution CDF
def Phi(x):
    return 0.5*(1.0+err(x/math.sqrt(2.0)))

#Inverve of Exponential CDF with parameter lambda_0
def inverse_exp(x,lambda_0):
    return -1.0*math.log(1.0-x)/float(lambda_0)

#Exponential density
def expo(x,lambda_0):
    return lambda_0*math.exp(-lambda_0*x)

#Gaussian density
def phi(x):
    return math.exp((-(x**2.0))/2.0)/math.sqrt(2.0*math.pi)

def truncated_gaussian_sampler(n,c):
	Phi_c = Phi(c)
	lambda_0 = (c + math.sqrt((c**2.0)+4.0))/2.0
	b = math.exp(((lambda_0**2.0) - (2.0*lambda_0*c))/2.0)/(math.sqrt(2.0*math.pi)*lambda_0*(1.0-Phi_c))
	const = ((1-Phi_c)*b)
	samples = []
	while len(samples)<n:
		x_inv = np.random.uniform()
		x = inverse_exp(x_inv, lambda_0)
		r = (phi(x+c)/(expo(x,lambda_0))*const)
		coin = np.random.uniform()
		if coin<r:
			samples.append(x+c)
	return np.array(samples)

n=1
c = 4
print(truncated_gaussian_sampler(n,c))


#import libraries
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression

#importing datasets
dataset = pd.read_csv('50_Startups.csv')

#Extracting Independent and dependent Variable
x = dataset.iloc[: , :-1].values
y = dataset.iloc[: , 4].values

#Catgorical data
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
ct = ColumnTransformer(transformers=[('encoder', OneHotEncoder(), [3])], remainder='passthrough')
# converting from matrix to array
x = np.array(ct.fit_transform(x))

# #avoiding the dummy variable trap: ---- Removing one dummy variable
x=x[:, 1:]

# Splitting the dataset into training and test set.
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test= train_test_split(x, y, test_size= 0.2, random_state=0)

#Fitting the MLR model to the training set:
from sklearn.linear_model import LinearRegression
regressor= LinearRegression()
regressor.fit(x_train, y_train)

#Predicting the Test set result;
y_pred= regressor.predict(x_test)

df = pd.DataFrame({'Real Values':y_test, 'Predicted Values':y_pred})
print(df)

# trying to predict the first x_test variable
pred= regressor.predict([[1.0,0.0,66051.52,182645.56,118148.2]]).reshape(-1,1)
print("I predict for you : ", pred)

#Checking the score
print('Train Score: ', regressor.score(x_train, y_train))
print('Test Score: ', regressor.score(x_test, y_test))


#!/usr/bin/env python3
import numpy as np
import matplotlib.pyplot as plt

y0 = np.arange(0, 11) ** 3

mean = [69, 0]
cov = [[15, 8], [8, 15]]
np.random.seed(5)
x1, y1 = np.random.multivariate_normal(mean, cov, 2000).T
y1 += 180

x2 = np.arange(0, 28651, 5730)
r2 = np.log(0.5)
t2 = 5730
y2 = np.exp((r2 / t2) * x2)

x3 = np.arange(0, 21000, 1000)
r3 = np.log(0.5)
t31 = 5730
t32 = 1600
y31 = np.exp((r3 / t31) * x3)
y32 = np.exp((r3 / t32) * x3)

np.random.seed(5)
student_grades = np.random.normal(68, 15, 50)

fig = plt.figure(tight_layout=True)
plt.suptitle('All in One')

fig.add_subplot(321)
plt.xlim(0, 10)
plt.plot(y0, 'r-')

fig.add_subplot(322)
plt.title("Men's Height vs Weight", fontsize="x-small")
plt.xlabel("Height (in)", fontsize="x-small")
plt.ylabel("Weight (lbs)", fontsize="x-small")
plt.plot(x1, y1, color="magenta", marker=".", linestyle="")

fig.add_subplot(323)
plt.title("Exponential Decay of C-14", fontsize="x-small")
plt.xlabel("Time (years)", fontsize="x-small")
plt.ylabel("Fraction Remaining", fontsize="x-small")
plt.xlim(0, max(x2))
plt.plot(x2, y2)
plt.yscale('log')

fig.add_subplot(324)
plt.title("Exponential Decay of C-14", fontsize="x-small")
plt.xlabel("Time (years)", fontsize="x-small")
plt.ylabel("Fraction Remaining", fontsize="x-small")
plt.ylim(bottom=0)
plt.xlim(0, max(x3))
plt.plot(x3, y31, label="C-14", linestyle="dashed", color="red")
plt.plot(x3, y32, label="Ra-226", color="green")
plt.legend(loc='upper right', fontsize='x-small')

fig.add_subplot(313)
plt.xlim(0, 100)
plt.ylim(0, 30)
plt.hist(student_grades, range=(0, 100), edgecolor='black')
plt.title("Project A", fontsize='x-small')
plt.xlabel("Grades", fontsize='x-small')
plt.ylabel("Number of Students", fontsize='x-small')

plt.show()


import numpy as np

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

training_inputs = np.array([ [0,0,1], [1,1,1], [1,0,1], [0,1,1] ])
training_outputs = np.array([[0,1,1,0]]).T

np.random.seed(1)

synaptic_weights = 2 * np.random.random((3,1)) - 1

print ("Սկզբնարժեքավորման պատահական կշիռներ։")
print(synaptic_weights)
print()

# Ետ տարածման մեթոդ
for i in range(200000):
  input_layer = training_inputs
  outputs = sigmoid( np.dot( input_layer, synaptic_weights ))

  err = training_outputs - outputs
  adjustments = np.dot( input_layer.T, err * ( outputs * ( 1-outputs )) )

  synaptic_weights += adjustments

print( "Կշիռները սովորեցնելուց հետո ։" )
print(synaptic_weights)
print()

print( "Արդյունքը սովորեցնելուց հետո ։" )
print(outputs)

new_inputs = np.array([1, 1, 0])
output = sigmoid( np.dot( new_inputs, synaptic_weights ))
print()

print("Նոր իրադարձություն ։")
print(new_inputs, " ==> ", output)


# Custom Functions
import numpy as np
import pandas as pd

def ATransformMatrix (theta): #A
    ATransform = np.array([[np.cos(theta), -np.sin(theta)],
                            [np.sin(theta), np.cos(theta)]])
    return ATransform

def ATransformMatrixTHETA (theta): #A_theta
    ATransformTHETA = np.array([[-np.sin(theta), -np.cos(theta)],
                                [np.cos(theta), -np.sin(theta)]])
    return ATransformTHETA

def prettyMatVect(matVect):
    prettyMatVect = pd.DataFrame(matVect, columns =
                                ['R1x', 'R1y', 'theta1',
                                'R2x','R2y','theta2',
                                'R3x','R3y','theta3',
                                'R4x','R4y','theta4'])
    return prettyMatVect

def calcGenCoor(qi, u_bar_2O, u_bar_2A, u_bar_3A, u_bar_3B, u_bar_4B):
    # To calculate Point of Interest positions
    # GLOBAL COORDINATES
    R1 = np.array([qi[0], qi[1]], dtype = float)
    R2 = np.array([qi[3], qi[4]], dtype = float)

    # Point O at link 1
    r1O = R1
    # Point O at link 2
    r2O = R2 + np.matmul(ATransformMatrix(float(qi[5])), u_bar_2O)

    # Point A at link 2
    r2A = R2 + np.matmul(ATransformMatrix(float(qi[5])), u_bar_2A)
    # Point A at link 3
    R3 = np.array([qi[6], qi[7]], dtype = float)
    r3A = R3 + np.matmul(ATransformMatrix(float(qi[8])), u_bar_3A)

    # Point B at link 3
    r3B = R3 + np.matmul(ATransformMatrix(float(qi[8])),u_bar_3B)
    # Point B at link 4
    R4 = np.array([qi[9], qi[10]], dtype = float)
    r4B = R4 + np.matmul(ATransformMatrix(float(qi[11])),u_bar_4B)

    return r1O, r2O, r2A, r3A, r3B, r4B

def constraintEquation(constraintVector, qi, r1O, r2O, r2A,
                    r3A, r3B, r4B, sliderHeight, theta2Initial,
                    omega2, timeNow):
    # Ground constraint
    for i in range(3):
        constraintVector[i] = qi[i]

    # Pin joint O
    constraintPinO = r2O # r1O -
    for i in range(np.size(constraintPinO)):
    # Equation 4-5
        constraintVector[i+3] = constraintPinO[i]

    # Pin joint A
    constraintPinA = r2A - r3A
    for i in range(np.size(constraintPinA)):
    # Equation 6-7
        constraintVector[i+5] = constraintPinA[i]

    # Pin joint B
    constraintPinB = r3B - r4B
    for i in range(np.size(constraintPinB)):
    # Equation 8-9
        constraintVector[i+7] = constraintPinB[i]

    # Equation 10 - 12
    constraintVector[9] = qi[10]-sliderHeight
    constraintVector[10] = qi[11] - 0
    constraintVector[11] = qi[5] - theta2Initial - omega2*timeNow

    return constraintVector

def jacobianMatrix(qi, u_bar_2O, u_bar_2A, u_bar_3A, u_bar_3B, u_bar_4B):
    n = np.size(qi)
    jacobianMatrixCq = np.zeros((n,n), dtype = float)
    identity3x3 = np.identity(3)
    identity2x2 = np.identity(2)

    # row 1-3
    jacobianMatrixCq[0:3,0:3] = identity3x3

    # row 4-5
    Cq45 = np.matmul(ATransformMatrixTHETA(float(qi[5])), u_bar_2O)
    jacobianMatrixCq[3:5,3:5] = identity2x2
    jacobianMatrixCq[3:5,5:6] = Cq45

    # row 6-7
    Cq67_link2 = np.matmul(ATransformMatrixTHETA(float(qi[5])), u_bar_2A)
    Cq67_link3 = np.matmul(ATransformMatrixTHETA(float(qi[8])), u_bar_3A)
    jacobianMatrixCq[5:7,3:5] = identity2x2
    jacobianMatrixCq[5:7,5:6] = Cq67_link2
    jacobianMatrixCq[5:7,6:8] = -identity2x2
    jacobianMatrixCq[5:7,8:9] = -Cq67_link3

    # row 8-9
    Cq89_link3 = np.matmul(ATransformMatrixTHETA(float(qi[8])), u_bar_3B)
    Cq89_link4 = np.matmul(ATransformMatrixTHETA(float(qi[11])), u_bar_4B)
    jacobianMatrixCq[7:9,6:8] = identity2x2
    jacobianMatrixCq[7:9,8:9] = Cq89_link3
    jacobianMatrixCq[7:9,9:11] = -identity2x2
    jacobianMatrixCq[7:9,11:12] = -Cq89_link4

    # row 10-11
    jacobianMatrixCq[9:11,10:12] = identity2x2

    # row 12
    jacobianMatrixCq[11][5] = 1

    return jacobianMatrixCq

def constrEqDot(constraintVectorVel, omega):

    constraintVectorVel[11] = -omega

    return constraintVectorVel

def positionAnalysis(constraintVector, jacobianMatrix, qi):
    inverse_jacobian = np.linalg.inv(jacobianMatrix)
    delta_qi = - np.matmul(inverse_jacobian, constraintVector)
    delta_qi_norm = np.linalg.norm(delta_qi)
    qi = qi + delta_qi

    return qi, delta_qi_norm

def velocityAnalysis(constraintVectorVel, jacobianMatrix, qiDot):
    inverse_jacobian = np.linalg.inv(jacobianMatrix)
    qiDot= - np.matmul(inverse_jacobian, constraintVectorVel)

    return qiDot

def accelerationAnalysis(jacobianMatrix, qiDotDot, qiDot, qi,
                        u_bar_2O, u_bar_2A, u_bar_3A, u_bar_3B, u_bar_4B):
    # Qd line 3-4
    Qd34 = np.square(float(qiDot[5]))*np.matmul(ATransformMatrix(float(qi[5])), u_bar_2O)

    # Qd line 5-6
    Qd56a = np.square(float(qiDot[5]))*np.matmul(ATransformMatrix(float(qi[5])), u_bar_2A)
    Qd56b = np.square(float(qiDot[8]))*np.matmul(ATransformMatrix(float(qi[8])), u_bar_3A)
    Qd56 = Qd56a-Qd56b

    # Qd line 7-8
    Qd78a = np.square(float(qi[8]))*np.matmul(ATransformMatrix(float(qi[8])), u_bar_3B)
    Qd78b = np.square(float(qi[11]))*np.matmul(ATransformMatrix(float(qi[11])), u_bar_4B)
    Qd78 = Qd78a-Qd78b

    Qd = np.array([[0],[0],[0], Qd34[0], Qd34[1],
                    Qd56[0], Qd56[1], Qd78[0], Qd78[1],
                    [0], [0], [0]])

    inverse_jacobian = np.linalg.inv(jacobianMatrix)
    qiDotDot= np.matmul(inverse_jacobian, Qd)

    return qiDotDot


import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

def sigmoid(x, x0, k):
    y = 1 / (1 + np.exp(-k*(x-x0)))
    return y

(x0, k), _ = curve_fit(sigmoid, x, y)

xnew = np.linspace(-1, 31, 50)
yfit = sigmoid(xnew, x0, k)

fig, ax = plt.subplots(figsize=(12,6))
ax.scatter(x, y, marker='o', color="r", label="data")
ax.plot(xnew, yfit, color="blue");


import numpy as np
import math
import scipy.integrate as integrate
from __future__ import division

def jzs_corbf(r,n):
    # This function computes the Bayes Factor to evaluate evidence for or against a linear relationship
    # H0: no linear relationship
    # H1: linear relationship exists
    # For interpretation of the result see below

    # Usage
    # r = correlation_coefficient from sample
    # n = n_samples (e.g. datapoints)
    # BF10 = jzs_corbf(r,n)

    # Interpretation:
    #       >   100   Decisive evidence for H1
    # 30    -   100   Very Strong evidence for H1
    # 10    -   30    Strong evidence for H1
    # 3     -   10    Substantial evidence for H1
    # 1     -   3     Anecdotal evidence for H1
    # 1               No evidence
    # 1/3   -   1     Anecdotal evidence for H0
    # 1/10  -  1/3    Substantial evidence for H0
    # 1/30  -  1/10   Strong evidence for H0
    # 1/100 -  1/30   Very Strong evidence for H0
    #       <  1/100  Decisive evidence for H0

    # As described in Wetzels & Wagemakers 2012
    # Psychon Bull Rev. 2012 Dec; 19(6): 1057–1064.
    # doi:  10.3758/s13423-012-0295-x

    g1 = lambda g: (1 + g)**((n - 2)/2) * (1+(1-r**2)*g)**(-(n-1)/2) * g**(-3/2) * np.exp(-n/(2*g))
    BF10 = (np.sqrt(n/2)/math.gamma(1/2))* integrate.quad(g1, 0,np.inf)[0]
    return BF10

def eval_null(SSE1, SSE0, k1,k0, n)
    # Model Comparisons using SSE/SST:
    # To identify posterior probability of null
    # It is often useful to consider the delta BIC10 quantity using BF01
    # Note that BF01 != BF10

    # Usage
    # SSE1: sum of squared errors for H1 (alternative)
    # SSE0: sum of squared errors for H0 (null)
    # k1: # parameters for alternative model
    # k0: # parameters for null model
    # n:number of subjects

    # BF01
    #       >   100   Decisive evidence for H1
    # 30    -   100   Very Strong evidence for H1
    # 10    -   30    Strong evidence for H1
    # 3     -   10    Substantial evidence for H1
    # 1-3      Anecdotal evidence for H1

    # As described in Wetzels & Wagemakers 2012
    # Psychon Bull Rev. 2012 Dec; 19(6): 1057–1064.
    # doi:  10.3758/s13423-012-0295-x

    deltaBIC10 = n*np.log(SSE1/SSE0) + (k1 - k0)*np.log(n)
    BF01 = np.exp(deltaBIC10/2)
    return BF01


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

def sigmoid(z) :

    return 1 / (1 + np.exp(-z))

def initialize_with_zeros(dim) :

    w = np.zeros((dim, 1))
    b = 0

    return w, b

def propagate(w, b, X, Y) :

    # No. of training examples
    m = X.shape[1]

    # Forward propagation
    A = sigmoid(np.dot(w.T, X) + b)     # Activation function
    cost = (-1 / m) * np.sum(Y * np.log(A) + (1 - Y) * np.log(1 - A))   # Cost function

    # Backward propagation
    dw = (1 / m) * np.dot(X, (A - Y).T)    # dJ/dw
    db = (1 / m) * np.sum(A - Y)    # dJ/db

    cost = np.squeeze(cost)

    grads = {'dw' : dw, 'db' : db}

    return grads, cost

def optimize(w, b, X, Y, num_iterations, learning_rate, print_cost = False) :

    costs = []

    for i in range(num_iterations) :

        # Cost and gradient calculation
        grads, cost = propagate(w, b, X, Y)

        dw = grads['dw']
        db = grads['db']

        # Gradient descent
        w = w - learning_rate * dw
        b = b - learning_rate * db

        if i % 100 == 0 :
            costs.append(cost)

        if print_cost and i % 100 == 0 :
            print(f"Cost after iteration {i} : {cost}")

    params = {'w' : w, 'b' : b}
    grads = {'dw' : dw, 'db' : db}

    return params, grads, costs

def predict(w, b, X) :

    m = X.shape[1]
    Y_prediction = np.zeros((1, m))
    w = w.reshape((X.shape[0], 1))

    A = sigmoid(np.dot(w.T, X) + b)

    for i in range(A.shape[1]) :

        # Binary classification
        Y_prediction[0, i] = 0 if A[0, i] <= 0.5 else 1

    return Y_prediction

def model(X_train, Y_train, X_test, Y_test, num_iterations = 2000, learning_rate = 0.5, print_cost = False) :

    w, b = initialize_with_zeros(X_train.shape[0])

    parameters, grads, costs = optimize(w, b, X_train, Y_train, num_iterations, learning_rate, print_cost)

    w = parameters['w']
    b = parameters['b']

    Y_prediction_test = predict(w, b, X_test)
    Y_prediction_train = predict(w, b, X_train)

    print(f'\nTraining accuracy : {100 - np.mean(np.abs(Y_prediction_train - Y_train)) * 100}')
    print(f'Testing accuracy : {100 - np.mean(np.abs(Y_prediction_test - Y_test)) * 100}')

    d = {'costs' : costs,
         'Y_prediction_test' : Y_prediction_test,
         'T_prediction_train' : Y_prediction_train,
         'w' : w,
         'b' : b,
         'grads' : grads,
         'learning_rate' : learning_rate,
         'num_iterations' : num_iterations}

    return d

def binary_sex(sex) :
    return 1 if sex == 'male' else 0

def ternary_embarked(s) :
    if s == 'S' :
        return 0
    if s == 'C' :
        return 1
    if s == 'Q' :
        return 2

    return -1

def preprocess_data(file_obj) :

    df = file_obj.copy()

    df.drop(columns = ['Name', 'Ticket', 'Cabin'], inplace = True)

    df['Age'].fillna(value = df['Age'].median(), inplace = True)
    df['Embarked'].fillna(value = 'N', inplace = True)

    df['Sex'] = df['Sex'].apply(binary_sex)
    df['Embarked'] = df['Embarked'].apply(ternary_embarked)

    dataset = df.to_numpy()

    return dataset

def load_dataset() :

    file_obj = pd.read_csv('titanic_x_y_train.csv')

    training_data = preprocess_data(file_obj)

    X = training_data[ : , : -1]
    Y = training_data[ : , -1 ]

    # Normalizing data
    X = StandardScaler().fit_transform(X)

    X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size = 0.2)

    return X_train.T, Y_train.reshape((1, Y_train.shape[0])), X_test.T, Y_test.reshape((1, Y_test.shape[0]))

# Main
X_train, Y_train, X_test, Y_test = load_dataset()

learning_rates = [0.0001, 0.001, 0.01, 0.1]
models = {}

for lr in learning_rates :

    print(f'learning rate is : {lr}')

    models[str(lr)] = model(X_train, Y_train, X_test, Y_test, num_iterations = 2000, learning_rate = lr, print_cost = False)

    print('\n' + "-------------------------------------------------------" + '\n')

# Plot learning curve (with costs)
for lr in learning_rates :

    d = models[str(lr)]

    costs = np.squeeze(d['costs'])
    plt.plot(costs, label = str(d['learning_rate']))

plt.ylabel('cost')
plt.xlabel('iterations (per hundred)')

legend = plt.legend(loc='upper right', shadow = True)

plt.show()


import numpy as np
import math

# Fixed for the time being...
ADV_WAVE_FREQ = 1  # This scalar defines the speed of the wave
IMAGE_DIMENSION = 64
NUM_FRAMES = 100
dt = 0.01  # Constant now (Don't change this)

# This vector defines the direction of the travelling wave.
# The magnitude of this vector defines the "length" of the wave
ADV_WAVE_VECTOR = np.array([1, 0])

def create_adv_diff_wave(
    image_dimension=IMAGE_DIMENSION,
    num_frames=NUM_FRAMES,
    adv_wave_vector=ADV_WAVE_VECTOR,
    adv_wave_freq=ADV_WAVE_FREQ,
):

    # Degrees between wave direction and x-axis
    theta = math.atan2(adv_wave_vector[1], adv_wave_vector[0]) * 180 / math.pi

    # Data to generate
    data = np.zeros((num_frames, image_dimension, image_dimension))

    # Deltas, num ticks in example
    dx = 2 * np.pi / (image_dimension - 1)
    dy = dx
    ticks = np.linspace(0, dt * num_frames, num_frames)

    # Create frames
    for k in range(num_frames):
        t0 = ticks[k]
        for i in range(image_dimension):
            for j in range(image_dimension):
                x = dx * j
                y = (image_dimension - i) * dy
                r = np.array([x, y])
                data[k, i, j] = math.sin(
                    np.dot(adv_wave_vector, r) - adv_wave_freq * t0
                )

    return data, theta


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

# # Contaminant Concentration

#
# ## Task 1
# A saline solution with a concentration of 370mg/l is itroduced to a 2-m-longsand column in which the pores are initially filled with distilled water.If the solution drains through the column at an average linear velocity of 0.79 m/day and the dynamic dispersivity of the sand columnis 15 cm, what would the conceration of the effluent be at 1.8 days after the flow begins?
#
# source: "Applied Hydrogeology" by C.W. Fetter <br>
#

# In[1]:

import math
import scipy.special as sc

# In[2]:

# A.inputs
C0 = 370  #mg/l initial concentration
L = 2 #m length of the sand column
Vx = 0.79  #m/d linear velocity of groundwater flow
Disp = 0.15 #m dispersivity of sand column
t = 1.8  #days after the flow begins
print("A. Given information: ")
print("Initial concentration = {} mg/l\nlength of the sand column = {} m\nLinear velocity of groundwater flow = {} m/d\nDispersivity = {} m\nTime={} d".format(C0, L, Vx, Disp, t),"\n")

# B.Calculations of :
DL=Disp*Vx # longitudinal dispersivity coefficient

X=(L-(Vx*t))/(2*((DL*t)**0.5))#  Error functions
Y=(L+(Vx*t))/(2*((DL*t)**0.5))#  Error functions
C=(C0/2)*(sc.erfc(X)+(math.exp((Vx*L)/DL)*sc.erfc(Y)))# Concentration after t days

#  Defining a concentration function and conditional statemen based on error functions
print("B. Calculations: ")

if X>3 and Y<3:
    sc.erfc(X)==0, print("Error function of X [erfc(X)] is negligible or zero\n")
    C=(C0/2)*(math.exp((Vx*L)/DL)*sc.erfc(Y))
    rsults=C
else :
    (math.exp((Vx*L)/DL)*sc.erfc(Y))==0, print("Error function of Y [erfc(Y)] is negligble or zero\n")
    C=(C0/2)*(math.erfc(X))
    results= C

# C.output
print("C. Output: ")
print("Concentration after 1.8 days is: ", C, "mg/l")

# In[ ]:


import scipy as sp
data = sp.genfromtxt("data/web_traffic.tsv", delimiter="\t")

# 先頭10件を表示
print(data[:10])

# 1列目を1次元配列で取り出す(経過時間？)
x = data[:, 0]

# 2列目を1次元配列で取り出す(アクセス数)
y = data[:, 1]

# 不正なデータが入っている要素を除去(アクセス数が不正な値(NAN)の行を除去)

invalid_data = ~sp.isnan(y)
x = x[invalid_data]
y = y[invalid_data]

print("x[-1] = %d" % x[-1])

# フォント
import matplotlib
matplotlib.rcParams['font.family'] = 'IPAexGothic'

# 近似関数(1次)を得る
fp1, residuals, rank, sv, rcond = sp.polyfit(x, y, 1, full=True)
print("Model parameters: %s" % fp1)
print("residuals: %s" % residuals)

# 近似関数からモデル関数を作る
f1 = sp.poly1d(fp1)

# モデル関数(f1)と実測値(x,y)から誤差を得る
def error(f,x,y):
    return sp.sum((f(x) - y) ** 2)

print(error(f1, x, y )) # 317389767.339778

# 近似関数(2次)を得る
fp2, residuals, rank, sv, rcond = sp.polyfit(x, y, 2, full=True)
print("Model parameters: %s" % fp2) # Model parameters: [ 1.05322215e-02 -5.26545650e+00  1.97476082e+03]
print("residuals: %s" % residuals) # residuals: [1.79983508e+08]

# 近似関数からモデル関数を作る
f2 = sp.poly1d(fp2)
print(error(f2, x, y )) # 179983507.8781792 (f1と比べて半分ぐらいに減った！)

# 表示
import matplotlib.pyplot as plt
plt.scatter(x,y)
plt.title("先月のWebトラフィック量")
plt.xlabel("時間")
plt.ylabel("件/時")
plt.xticks([w*7*24 for w in range(10)], ['week %i'% w for w in range(10)]) # 1週間(7日*24時間)毎に区切る。0周目～9周目まで。
plt.autoscale(tight=True) # 実際は4周目分のデータしかないので、表示を0周目～4周目までを収まるようにスケール
plt.grid()

# # モデル関数f1を使い、線を引く
fx = sp.linspace(0, x[-1], 1000) # 間隔が等しい数列を1000個作る。始点:0,終点:x[-1]=743,数:1000個 => 約0.743づつ増加する1000個の数列
# # print(sp.linspace(0, x[-1], 1000)) # 数列を確認

# 変化がある3.5週目から分けて２つの直線で近似させる
inflection = int(3.5 * 7 * 24)
xa = x[:inflection]
ya = y[:inflection]
xb = x[inflection:]
yb = y[inflection:]

fa = sp.poly1d(sp.polyfit(xa, ya, 1))
fb = sp.poly1d(sp.polyfit(xb, yb, 1))

fa_error = error(fa, xa, ya)
fb_error = error(fb, xb, yb)
print("fa_error = %s" % fa_error )
print("fb_error = %s" % fb_error )
print("fa_error+fb_error = %s" % (fa_error + fb_error) )

# 3.5週目以降のデータのうち、
# 30%をテストデータとして使う

# 再現性を出すためのseed固定
sp.random.seed(314159263)

frac = 0.30
split_idx = int(frac * len(xb))
shuffled = sp.random.permutation(list(range(len(xb))))
test = sorted(shuffled[:split_idx])
train = sorted(shuffled[split_idx:])

fbt1 = sp.poly1d(sp.polyfit(xb[train], yb[train], 1))
fbt2 = sp.poly1d(sp.polyfit(xb[train], yb[train], 2))
fbt3 = sp.poly1d(sp.polyfit(xb[train], yb[train], 3))
fbt10 = sp.poly1d(sp.polyfit(xb[train], yb[train], 10))
fbt100 = sp.poly1d(sp.polyfit(xb[train], yb[train], 100))

# 学習データで誤差を見る
print("(train)fbt1_error  = %s" % error(fbt1, xb[train], yb[train]) ) # 15846249.623390418
print("(train)fbt2_error  = %s" % error(fbt2, xb[train], yb[train]) ) # 14048047.808891317
print("(train)fbt3_error  = %s" % error(fbt3, xb[train], yb[train]) ) # 14014812.664947439
print("(train)fbt10_error = %s" % error(fbt10, xb[train], yb[train]) )# 13092597.979928792
print("(train)fbt100_error = %s" % error(fbt100, xb[train], yb[train]) )# 12652070.062779315 <= 最も誤差が小さい、が、学習データに最適化されている状態なので、評価としては不適切。

# 未知データで誤差を見る
print("(test) fbt1_error  = %s" % error(fbt1, xb[test], yb[test]) ) # 6387914.410987866
print("(test) fbt2_error  = %s" % error(fbt2, xb[test], yb[test]) ) # 5841997.167708391 <= 最も誤差が小さい。乱数を変えても大体これが良い結果に。
print("(test) fbt3_error  = %s" % error(fbt3, xb[test], yb[test]) ) # 5949556.660118614
print("(test) fbt10_error = %s" % error(fbt10, xb[test], yb[test]) )# 6525801.591164470
print("(test)fbt100_error = %s" % error(fbt100, xb[test], yb[test]))# 6677906.164012078

### 描画 ###

# 未来を含めて描画(10週目まで描画してみる。)
fx = sp.linspace(0, 7*24*10, 1000)

# # f1
# plt.plot(fx, f1(fx), linewidth=2) # 直線を描く(xに対するy(f1(x))の線を引く)
# plt.legend(["d=%i" % f1.order], loc="upper left") # 凡例

# # f2
# plt.plot(fx, f2(fx), linewidth=2) # 直線を描く(xに対するy(f1(x))の線を引く)
# plt.legend(["d=%i" % f2.order], loc="upper left") # 凡例

# # 変化がある3.5週目から分けて２つの直線を引く(fa,fb)
# plt.plot(fx, fa(fx), linewidth=2)
# plt.plot(fx, fb(fx), linewidth=2)
# plt.legend(["d=%i" % fa.order, "d=%i" % fb.order], loc="upper left") # 凡例

# 変化がある3.5週目から70%を学習に使って作ったモデルで線を引く
plt.plot(fx, fbt1(fx), linewidth=2)
plt.plot(fx, fbt2(fx), linewidth=2)
plt.plot(fx, fbt3(fx), linewidth=2)
plt.plot(fx, fbt10(fx), linewidth=2)
plt.plot(fx, fbt100(fx), linewidth=2)

plt.legend(["d=%i" % fbt1.order, "d=%i" % fbt2.order, "d=%i" % fbt3.order, "d=%i" % fbt10.order, "d=%i" % fbt100.order], loc="upper left") # 凡例

plt.show()


"""
Gaussian Transformation
- Some machine learning models like linear and logistic regression assume that the variables are normally distributed.
        Often, variables are not normally distributed, but, transforming the variables to map their distribution to
        a Gaussian distribution may, and often does, boost the performance of the machine learning algorithm.

- If a variable is not normally distributed, it is often possible to find a mathematical transformation to
        normalise its distribution.

How can we transform variables so that they follow a normal distribution?
The most commonly used methods to transform variables are:
- Logarithmic transformation - np.log(X)
- Reciprocal transformation - 1 / X
- Square root transformation - X**(1/2)
- Exponential transformation (more general, you can use any exponent)
- Box-Cox transformation
- Yeo-Johnson transformation

You can find the formulas for Box-Cox and Yeo-Johnson here https://scikit-learn.org/stable/modules/preprocessing.html#mapping-to-a-gaussian-distribution

Briefly,
- the Box-Cox transformation is an adaptation of the exponential transformation, scanning through various
        exponents, and it already represents the untransformed variable, as well as the log transformed,
        reciprocal, square and cube root transformed, as the lambda varies across the range of -5 to 5
        (see formula, to understand this better).
        So by doing Box-Cox transformation, in a way, we are evaluating all the other transformations and
        choosing the best one. Box-Cox can only be applied to positive variables.
- Yeo-Johnson is a modification of the Box-Cox transformation so that it can be applied as well to non-positive
        variables

To read more about the Box-Cox transformation visit any of these links:
- http://www.statisticshowto.com/box-cox-transformation/
- http://www.itl.nist.gov/div898/handbook/eda/section3/eda336.htm
- http://onlinestatbook.com/2/transformations/box-cox.html

To read more about the Yeo-Johnson transformation follow this link: https://www.stat.umn.edu/arc/yjpower.pdf

In this example:
- We will see how to implement variable transformations using NumPy and the House Prices dataset.
 """
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as stats

# load the data
data = pd.read_csv('dataset/house-prices-advanced-regression-techniques/train.csv')

data.head()
"""
   Id  MSSubClass MSZoning  LotFrontage  LotArea Street Alley LotShape LandContour Utilities  ... PoolArea PoolQC Fence MiscFeature MiscVal MoSold YrSold  SaleType  SaleCondition  SalePrice
0   1          60       RL         65.0     8450   Pave   NaN      Reg         Lvl    AllPub  ...        0    NaN   NaN         NaN       0      2   2008        WD         Normal     208500
1   2          20       RL         80.0     9600   Pave   NaN      Reg         Lvl    AllPub  ...        0    NaN   NaN         NaN       0      5   2007        WD         Normal     181500
2   3          60       RL         68.0    11250   Pave   NaN      IR1         Lvl    AllPub  ...        0    NaN   NaN         NaN       0      9   2008        WD         Normal     223500
3   4          70       RL         60.0     9550   Pave   NaN      IR1         Lvl    AllPub  ...        0    NaN   NaN         NaN       0      2   2006        WD        Abnorml     140000
4   5          60       RL         84.0    14260   Pave   NaN      IR1         Lvl    AllPub  ...        0    NaN   NaN         NaN       0     12   2008        WD         Normal     250000 """

# let's explore the distribution of the numerical variables
data.hist(figsize=(20,20))
plt.show()

"""
Plots to assess normality
- To visualise the distribution of the variables, we plot a histogram and a Q-Q plot.
- In the Q-Q pLots, if the variable is normally distributed, the values of the variable should fall in a 45 degree
        line when plotted against the theoretical quantiles.
 """

# plot the histograms to have a quick look at the variable distribution
# histogram and Q-Q plots

def diagnostic_plots(df, variable):

    # function to plot a histogram and a Q-Q plot
    # side by side, for a certain variable

    plt.figure(figsize=(15,6))
    plt.subplot(1, 2, 1)
    df[variable].hist(bins=30)

    plt.subplot(1, 2, 2)
    stats.probplot(df[variable], dist="norm", plot=plt)

    plt.show()

# Original distribution
diagnostic_plots(data, 'GrLivArea')

""" We can see in the plots that the variable is not normally distributed.
The values depart from the red line towards the ends of the distribution and we can see in the histogram that
 it is skewed to the right.
 """

# Logarithmic transformation
### Logarithmic transformation

data['GrLivArea_log'] = np.log(data['GrLivArea'])

diagnostic_plots(data, 'GrLivArea_log')

# The logarithmic transformation returned a more Gaussian for this variable.

# Reciprocal transformation
data['GrLivArea_reciprocal'] = 1 / (data['GrLivArea'])

# np.reciprocal(data['GrLivArea'])

diagnostic_plots(data, 'GrLivArea_reciprocal')

# The reciprocal transformation was not useful to transform this variable.

# Square root transformation
data['GrLivArea_sqr'] = data['GrLivArea']**(1/2)

# np.power(data['GrLivArea'], 1/2), np.sqrt(data['GrLivArea'])

diagnostic_plots(data, 'GrLivArea_sqr')

# The square root transformation offers a good alternative to normalise this variable.

# Exponential transformation
data['GrLivArea_exp'] = data['GrLivArea']**(1/1.5) # you can vary the exponent as needed

# np.power(data['GrLivArea'], any exponent we want)

diagnostic_plots(data, 'GrLivArea_exp')

# The exponential transformation did not work so nicely for this variable.

# Box-Cox transformation
"""
The Box-Cox transformation is defined as:
- T(Y)=(Y exp(λ)−1)/λ if λ!=0, or log(Y) otherwise.
        - where Y is the response variable and λ is the transformation parameter.
            λ varies from -5 to 5.
            In the transformation, all values of λ are considered and the optimal value for a given variable
            is selected.

- Briefly, for each λ (the transformation tests several λs), the correlation coefficient of the Probability Plot
        (Q-Q plot below, correlation between ordered values and theoretical quantiles) is calculated
        (this optimisation equation actually varies with the implementation).
- The value of λ corresponding to the maximum correlation on the plot is then the optimal choice for λ.

In python, we can evaluate and obtain the best λ with the stats.boxcox function from the package scipy.
Let's have a look. """

data['GrLivArea_boxcox'], param = stats.boxcox(data['GrLivArea'])

print('Optimal λ: ', param)
# Optimal λ:  0.006304886038020439

diagnostic_plots(data, 'GrLivArea_boxcox')

"""
Yeo-Johnson transformation
- Yeo-Johnson is the same as Box-Cox for the positive values of the variable, but it has different equations
        for the negative values of the variable as described here

- Again, the function searches over a bunch of λ and selects the one that returns the best fit to a normal distribution.
 """

# to avoid a NumPy error
data['GrLivArea'] = data['GrLivArea'].astype('float')
data['GrLivArea_yeojohnson'], param = stats.yeojohnson(data['GrLivArea'])

print('Optimal λ: ', param)
# Optimal λ:  0.005539641278705955

diagnostic_plots(data, 'GrLivArea_yeojohnson')

"""
- We can see that after the transformation, the quantiles are somewhat more aligned over the 45 degree
        line with the theorical quantiles of the Gaussian distribution. """


__all__ = ['SigmoidFunction']

import numpy as np

class SigmoidFunction:
    def __call__(self, inputs):
        # fix overflow
        inputs = np.clip(inputs, -500, 500)
        return 1. / (1. + np.exp(-inputs))

    def derivative(self, inputs, outputs=None):
        if outputs is None:
            outputs = self(inputs)
        return outputs * (1 - outputs)

    def __repr__(self):
        return "SigmoidLayer()"


import matplotlib.pyplot as plt
import numpy as np

class utilsClass:

    def pdfFunction():
        sample = np.random.normal(size=1000)

        plt.hist(sample, bins=20)
        plt.show()

        sample_mean = np.mean(sample)
        sample_std = np.std(sample)
        print(sample_mean)
        print(sample_std)

    def generateGaussians():

        x = np.linspace(-3,3,120)
        for mu, sigma in [(-1,1),(0,2),(2,3)]:
            plt.plot(x, np.exp(-np.power(x-mu, 2.) / (2 * np.power(sigma, 2))))

        plt.show()

if __name__ == "__main__":

    utilsClass.generateGaussians()


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

"""
@author: krakowiakpawel9@gmail.com
@site: e-smartdata.org
"""

import pandas as pd
import numpy as np

np.random.seed(10)

# Normal distribution, mean = 5, sigma = 10
s = pd.Series(10 * np.random.randn(20) + 5)

# %% applying built-in functions to Series
s.apply(abs)
s.apply(float.is_integer)
s.apply(int)

# %% applying custom functions to Series
s.apply(lambda x: 100 * x)
s.apply(lambda x: abs(x))
s_norm = s.apply(lambda x: (x - np.mean(s)) / np.std(s))
sigmoid = s_norm.apply(lambda x: 1 / (1 + np.exp(x)))

def custom_function(x):
    return 10 * x

s.apply(custom_function)

def simple_trans(x):
    return x + 100

series_trans = s.apply(simple_trans)

def more_complex(x):
    import math
    return math.sqrt(np.exp(x))

series_complex = s.apply(more_complex)

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

series_sigmoid = s.apply(sigmoid)