import numpy as np
from numpy import *
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

class AmplitudeModulation():
	def __init__(self, Ac, Am, fc, fm):
		'''
		parameters:
		=================
		Ac: Amplitude of carrier signal
		Am: Amplitude of message signal
		fc: frequency of carrier signal
		fm: freaquency of message signal

		'''
		self.Ac= Ac
		self.Am= Am
		self.fc= fc
		self.fm= fm
		self.t= np.arange(0, 2*pi, 0.01)

	def createSignals(self):
		'''
		creates 'carrier', 'message' and 'modulated' signals

		c= Ac.sin(2.π.fc.t)
		m= Am.sin(2.π.fm.t)
		am= (Ac+Am.sin(2.π.fm.t)).sin(2.π.fc.t)

		'''
		#carrier signal
		c= lambda t: self.Ac*sin(2*pi*self.fc*t)

		#message signal
		m= lambda t: self.Am*sin(2*pi*self.fm*t)

		#modulated signal
		am= lambda t: (self.Ac+m(t))*sin(2*pi*self.fc*t)

		return c, m, am

	def plot(self, c, m, am, labels, *args):
		'''
		parameters
		===================
		c: carrier signal
		m: message signal
		am: modulated signal
		labels: dictionary of labels for the graph
		'''

		if len(args)==1:
			fig, (ax1, ax2, ax3, ax4)= plt.subplots(4,1)
			ax= (ax1, ax2, ax3, ax4)
		else:
			fig, (ax1, ax2, ax3)= plt.subplots(3,1)
			ax= (ax1, ax2, ax3)

		fig.suptitle(labels['title'])

		for each in ax:
			each.set_ylabel(labels['ylabel'])
			each.set_xlabel(labels['xlabel'])
			each.axhline()

		ax1.set_title(labels['subtitle1'])
		ax2.set_title(labels['subtitle2'])
		ax3.set_title(labels['subtitle3'])

		line1, =ax1.plot(self.t, c(self.t))
		line2, =ax2.plot(self.t, m(self.t))
		line3, =ax3.plot(self.t, am(self.t), color='r')

		anim1= FuncAnimation(fig, self.animate, fargs= (c, line1), init_func= None, interval=2, blit=True, save_count=50 )
		anim2= FuncAnimation(fig, self.animate, fargs= (m, line2), init_func= None, interval=2, blit=True, save_count=50 )
		anim3= FuncAnimation(fig, self.animate, fargs= (am, line3), init_func= None, interval=2, blit=True, save_count=50 )

		if len(args)==1:
			ax4.set_title(labels['subtitle4'])
			line4, =ax4.plot(self.t, args[0](self.t), color='r')
			#anim3=''
			anim4= FuncAnimation(fig, self.animate, fargs= (am, line4), init_func= None, interval=2, blit=True, save_count=50 )

		plt.tight_layout()
		plt.show()

	def animate(self, i, *fargs):
		func= fargs[0]
		line= fargs[1]
		line.set_ydata(func(self.t+i/40))
		return line,

if __name__=='__main__':

	labels= {
	'title': '====Amplitude Modulation====',
	'xlabel': 'Time(Sec)',
	'ylabel': 'Amplitude',
	'subtitle1': 'Carrier Signal: Ac.sin(Wc*t)',
	'subtitle2': 'Message Signal: Am.sin(Wm*t)',
	'subtitle3': 'Amplitude Modulated Signal: [Ac+m(t)]sin(Wc.t)',
	'subtitle4': 'optional'
	}

	am= AmplitudeModulation(Ac= 3, Am= 2, fc= 5, fm= 1)
	am.plot(*am.createSignals(), labels)


import numpy as np

from . import Operation, Tensor

class CrossEntropy(Operation):
    """
    the cross entropy cost function
    """

    def __call__(self, h, y, eps):
        """
        given the hypothesis and the correct
        outputs, calculate the log loss between
        h and y assuming one-hot encoded

        :type h: np.ndarray
        :desc h: predicted classes [m x k]

        :type y: np.ndarray
        :desc y: actual classes [m x k]

        :type eps: float
        :desc eps: make all values in h between (eps, 1-eps)
                   so we dont get any divide by 0 errors
        """
        self.__previous = getattr(h, 'previous', None)

        h = np.clip(h, eps, 1 - eps)
        self.__input = y, h

        cost = y * np.log(h) + (1 - y) * np.log(1 - h)
        operation = self if self.__previous else None
        return Tensor(-np.mean(cost), operation)

    def backprop(self, sigma, optim):
        """
        the cross entropy function is:
            y * np.log(h) + (1 - y) * np.log(1 - h)

        after some math, the derivative
        with respect to h is:
            (1 - y) / (1 - h) - y / h

        and we multiply this by the backpropagated error
        """
        if self.__previous:
            y, h = self.__input
            change = (1 - y) / (1 - h) - y / h
            next_sigma = change * sigma
            self.__previous.backprop(next_sigma, optim)

def cross_entropy(h, y, eps=1e-9):
    """
    a helper function for creating a
    cross entropy cost so that it
    looks nicer when we call it later
    """
    return CrossEntropy()(h, y, eps)


from numpy import sqrt, sum, dot, square, shape, mean, array
from numpy.linalg.linalg import svd
from numpy.linalg import inv

def procrustes(m1, m2):

    # centralize matrices
    mean_m1 = [mean(column) for column in m1.T]
    m1 = m1-mean_m1
    mean_m2 = [mean(column) for column in m2.T]
    m2 = m2-mean_m2

    # scaling
    scale_m1 = sqrt(sum(square(m1))/(m1.shape[1]))
    scale_m2 = sqrt(sum(square(m2))/(m2.shape[1]))
    m2 = (m2/scale_m2)*scale_m1

    # rotation
    u, s, v = svd(dot(m1.T, m2))
    r = dot(v.T, u.T)
    m2 = dot(m2, r)

    # set m2 center to m1 center
    m2 = m2+mean_m1

    return m2

def procrustes_distance(m1, m2):
    distance = sum(square(m1 - m2))

    return distance

def scale_width(m, width):
    # scale width model m to width

    # get width of model
    min_x_mean = min(m[:,0])
    max_x_mean = max(m[:,0])
    meanwidth = max_x_mean-min_x_mean

    # center model
    mean_m = [mean(column) for column in m.T]
    m -= mean_m

    # scale model
    m = (m/meanwidth)*width

    # uncenter model
    m += mean_m

    return m

def get_reverse_transforms(mat1, mat2):
    # get the reverse procrustes transformation to align m2 with m1

    m1 = array(mat1)
    m2 = array(mat2)

    # centralize matrices
    mean_m1 = [mean(column) for column in m1.T]
    m1 = m1-mean_m1
    mean_m2 = [mean(column) for column in m2.T]
    m2 = m2-mean_m2

    t = array(mean_m2)-array(mean_m1)

    # scaling
    scale_m1 = sqrt(sum(square(m1))/(m1.shape[1]))
    scale_m2 = sqrt(sum(square(m2))/(m2.shape[1]))
    m2 = (m2/scale_m2)*scale_m1

    sc = scale_m2/scale_m1

    # rotation
    u, s, v = svd(dot(m1.T, m2))
    r = inv(dot(v.T, u.T))

    return sc, r, mean_m1, mean_m2

def transform(mat, s, r, mean1, mean2):
    # transform matrix via transform t, scale s, rotation r

    m = array(mat)

    mean_m = [mean(column) for column in m.T]
    m -= mean_m
    # TODO : which mean should I subtract here?
    #m -= mean1
    m = dot(m, r)
    m *= s
    #m += t
    #m += mean_m
    m += mean2
    return m


from math import factorial, pow, e, fabs, pi, sqrt
from probability import combination
import scipy.integrate as integrate
from functools import reduce

# Define binomial se usa cuando se tiene un tamano de muestra una probabilidad de exito y valor a encontrar probabilidad
# Por ejemplo probabilidad que de 30 personas(length) 8 (number_succes) con un porcentaje de exito del 0.5 (succes probability)
def binomial_distribution(length, succes_probability, number_succes):
  div = factorial(length) / (factorial(number_succes) * factorial(length - number_succes))
  multiply = pow(succes_probability, number_succes) * pow(1 - succes_probability, length - number_succes)

  return  div * multiply

# Se toma cuando en la distrubucion binomial se pide encontrar la probabilidad de algun rango, por ejemplo x < 3
# se pone [0,1,2,3]
def acumulated_binomial(cases, length, succes_probability):
  cases_binomial = map(lambda x: binomial_distribution(length, succes_probability, float(x)), cases)
  probability = reduce(lambda a,b: a + b, cases_binomial)

  return probability

def hypergeometric(length, sample_especial, sample_length, x):
  first = float(combination(sample_especial, x))
  second = float(combination(length - sample_especial, sample_length - x))
  third = float(combination(length, sample_length))

  return first * second / third

def acumulated_hypergeometric(length, sample_especial, sample_length, cases):
  cases_hypergeometric = map(lambda x: hypergeometric(length, sample_especial, sample_length, x), cases)
  probability = reduce(lambda a,b: a + b, cases_hypergeometric)
  return probability

def poisson(x, average):
  return (pow(average, x) * pow(e, -average)) / factorial(x)

def exponential(gap, average):
  return 1 - pow(e, -average * gap)

def uniform(x1, x2, greather, less):
  return fabs((x2 - x1) / (greather - less))

def norm(deviation, average, x1, x2):
  inte = integrate.quad(lambda x : pow(e,-0.5 * (pow(x - average, 2) / pow(deviation, 2)) ), x1, x2)
  result = inte[0]
  constant = 1 / (sqrt(2 * pi) * deviation)

  return constant * result

def get_z(x_, average, deviation, n):
    return (x_ - average) / (deviation / sqrt(n))

def when_get_x(average, deviation, percent):
  from scipy.stats import norm
  return norm(average, deviation).ppf(percent)


import numpy as np

# a function that takes as input a list of numbers, and returns
# the list of values given by the softmax function.
def softmax(L):
   expL = np.exp(L)
   return np.divide (expL, expL.sum())

def cross_entropy(Y, P):
    Y = np.float_(Y)
    P = np.float_(P)
    return -np.sum(Y * np.log(P) + (1 - Y) * np.log(1 - P))


import numpy as np

# Метод параболической аппроксимации Пауэлла
def powell(func, a: float, b: float, eps =0.01):
    # step 1
    x1 = a
    x2 = (a + b) / 2
    x3 = b

    X = [x1, x2, x3]
    # step 2
    while (True):
        min_x = X[0]
        for i in X:
            if (func(i)<func(min_x)):
                min_x = i

        # step 3
        num = (X[1] ** 2 - X[2] ** 2) * func(X[0]) + (X[2] ** 2 - X[0] ** 2) * func(X[1]) + (X[0] ** 2 - X[1] ** 2)* func(X[2])
        denum = (X[1] - X[2]) * func(X[0]) + (X[2] - X[0]) * func(X[1]) + (X[0] - X[1]) * func(X[2])
        X.append(0.5 * (num / denum))
        # step 4
        if(abs(X[3] - min_x) <= eps):
            break
        #step 5
        X.sort()

        #step 6
        max_x = 0
        for i in range(4):
            if (func(X[i])>func(X[max_x])):
                max_x = i
        X.pop(max_x)

 #step 7
    return X[-1]


import numpy as np

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

def d_sigmoid(_x_set):
    return (1 - sigmoid(_x_set)) * sigmoid(_x_set)

def softmax(_x_set):
    x_row_max = _x_set.max(axis=-1)
    x_row_max = x_row_max.reshape(list(_x_set.shape)[:-1] + [1])
    _x_set = _x_set - x_row_max
    x_exp = np.exp(_x_set)
    x_exp_row_sum = x_exp.sum(axis=-1).reshape(list(_x_set.shape)[:-1] + [1])
    return x_exp / x_exp_row_sum

def relu(_x_set):
    return np.maximum(0, _x_set)

def d_relu(_x_set):
    _x_set[_x_set <= 0] = 0
    _x_set[_x_set > 0] = 1
    return _x_set

def tanh(_x_set):
    return np.tanh(_x_set)

def d_tanh(_x_set):
    return 1 - np.tanh(_x_set) ** 2

def activation_function(method, x):
    if method == 'relu':
        _a = relu(x)
    elif method == 'sigmoid':
        _a = sigmoid(x)
    elif method == 'softmax':
        _a = softmax(x)
    elif method is None:
        _a = x
    else:
        _a = []
        print("No such activation: {}!".format(method))
        exit(1)
    return _a

def derivative_function(method, x):
    if method == 'relu':
        _d = d_relu(x)
    elif method == 'sigmoid':
        _d = d_sigmoid(x)
    elif method is None:
        _d = 1
    else:
        _d = []
        print("No such activation: {}!".format(method))
        exit(1)
    return _d


# -*- coding: utf-8 -*-
"""
Created on Tue Mar  1 16:53:49 2022

@author: Luminous Isaac
"""
######################## Linear Programming Plt #############################
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
#from pylab import figure, text, scatter, show

# Construct lines
x = np.linspace(0.0,50,100)
y1 = 3.0*x - 33
y2 = (-1/15)*x + 15
y3 = (14/5)*x - 28

# Make plot
plt.plot(x, y1, label=r'$y1 = 3.0*x - 33$')
plt.plot(x, y2, label=r'$y2 = (-1/15)*x + 15$')
plt.plot(x, y3, label=r'$y3 = (14/5)*x - 28$')

plt.xlim((0.0, 50.000))
plt.ylim((0.0, 50.000))
plt.xlabel(r'$x$')
plt.ylabel(r'$y$')

# Fill feasible region
y5 = np.minimum(y1, y3)
#y6 = np.maximum(y1, y3)
plt.fill_between(x, y5, y2, where=y5>y2, color='grey', alpha=0.5)

plt.grid(True, linestyle='-.')
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)

#plt.savefig('ordering_constraints.eps',dpi=600,bbox_inches='tight')
plt.show()

######################## Hadley-Whitin Algorithm ############################
from sympy import *
import math

def expectation():
    x = Symbol('x')
    Ex = integrate(x*1/32, (x, 0, 32)) ##change
    return Ex

def HWA(D, K, h, p, n):
    y_hat = math.sqrt((2 * D * (K + p * expectation())) / h)
    y_wave = (p * D) / h
    if y_wave < y_hat:
        return "Hadley-Whitin method will not converge."
    else:
        y = math.sqrt(2 * D * K / h)
        R = 32*(1 - y * h / (p * D)) ## change
        if n == 1:
            return y, R
        else:
            for i in range(2, n+1):
                x = Symbol('x')
                S_R = integrate((x - R) / 32, (x, R, 32)) ##change
                y = math.sqrt((2 * D * (K + p * S_R)) / h)
                R = 32*(1 - y * h / (p * D)) ## change
    return y_hat, y_wave, y, R

HWA(30, 4, 0.48, 1.11, 3)


#Importing Dependencies

import math
import numpy as np
import h5py
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.python.framework import ops
from tf_utils import load_dataset, random_mini_batches, convert_to_one_hot, predict

%matplotlib inline
np.random.seed(1)

#Computing the following loss using tensorflow
#Loss(y_hat, y) = np.power((y_hat - y),2)

y_hat = tf.constant(36, name='y_hat')            # Define y_hat constant. Set to 36.
y = tf.constant(39, name='y')                    # Define y. Set to 39

loss = tf.Variable((y - y_hat)**2, name='loss')  # Create a variable for the loss

init = tf.global_variables_initializer()         # When init is run later (session.run(init)),
                                                 # the loss variable will be initialized and ready to be computed
with tf.Session() as session:                    # Create a session and print the output
    session.run(init)                            # Initializes the variables
    print(session.run(loss))                     # Prints the loss

#Output = 9

a = tf.constant(2)
b = tf.constant(10)
c = tf.multiply(a,b)
print(c)

#Output
#Tensor("Mul:0", shape=(), dtype=int32)

print(sess.run(c))

#Output = 20

x = tf.placeholder(tf.int64, name = 'x')
print(sess.run(2 * x, feed_dict = {x: 3}))
sess.close()

#Ouptut = 6

#X = tf.constant(np.random.randn(3,1), name = "X")

#You might find the following functions helpful:

#    tf.matmul(..., ...) to do a matrix multiplication
#    tf.add(..., ...) to do an addition
#    np.random.randn(...) to initialize randomly

def linear_function():
    """
    Implements a linear function:
            Initializes W to be a random tensor of shape (4,3)
            Initializes X to be a random tensor of shape (3,1)
            Initializes b to be a random tensor of shape (4,1)
    Returns:
    result -- runs the session for Y = WX + b
    """

    np.random.seed(1)

    X = tf.constant(np.random.randn(3, 1), name = 'x')
    W = tf.constant(np.random.randn(4, 3), name = 'W')
    b = tf.constant(np.random.randn(4, 1), name = 'b')
    Y = tf.add(tf.matmul(W, X), b

    sess = tf.Session()
    result = sess.run(Y)

    # close the session
    sess.close()

    return result

print( "result = " + str(linear_function()))

#Output := result 	[[-2.15657382] [ 2.95891446] [-1.08926781] [-0.84538042]]

#Note that there are two typical ways to create and use sessions in tensorflow:

#Method 1:

#sess = tf.Session()
# Run the variables initialization (if needed), run the operations
#result = sess.run(..., feed_dict = {...})
#sess.close() # Close the session

#Method 2:

#with tf.Session() as sess:
    # run the variables initialization (if needed), run the operations
    # result = sess.run(..., feed_dict = {...})
    # This takes care of closing the session for you :)

def sigmoid(z):
    """
    Computes the sigmoid of z

    Arguments:
    z -- input value, scalar or vector

    Returns:
    results -- the sigmoid of z
    """

    # Create a placeholder for x. Name it 'x'.
    x = tf.placeholder(tf.float32, name = 'x')

    # compute sigmoid(x)
    sigmoid = tf.sigmoid(x)

    with tf.Session() as sess:
        # Run session and call the output "result"
        result = sess.run(sigmoid, feed_dict = {x : z})

    return result
print ("sigmoid(0) = " + str(sigmoid(0)))
print ("sigmoid(12) = " + str(sigmoid(12)))

#Output
sigmoid(0) = 0.5
sigmoid(12) = 0.999994

#1.3 - Computing the Cost

def cost(logits, labels):
    """
    Computes the cost using the sigmoid cross entropy

    Arguments:
    logits -- vector containing z, output of the last linear unit (before the final sigmoid activation)
    labels -- vector of labels y (1 or 0)

    Note: What we've been calling "z" and "y" in this class are respectively called "logits" and "labels"
    in the TensorFlow documentation. So logits will feed into z, and labels into y.

    Returns:
    cost -- runs the session of the cost (formula (2))
    """

    # Creating the placeholders for "logits" (z) and "labels" (y)
    z = tf.placeholder(tf.float32, name = 'z')
    y = tf.placeholder(tf.float32,   name = 'x')

    # Using the loss function
    cost = tf.nn.sigmoid_cross_entropy_with_logits(logits = z, labels = y)

    # Creating a session
    sess = tf.Session()

    # Running the session
    cost = sess.run(cost, feed_dict = {z : logits, y : labels})

    # Closing the session (approx. 1 line). See method 1 above.
    sess.close()

    return cost

logits = sigmoid(np.array([0.2,0.4,0.7,0.9]))
cost = cost(logits, np.array([0,0,1,1]))
print ("cost = " + str(cost))

#Output
cost 	 = [ 1.00538719 1.03664088 0.41385433 0.39956614]

#1.4 - Using One Hot encodings

#Many times in deep learning you will have a y vector with numbers ranging from 0 to C-1, where C is the
#number of classes. If C is for example 4, then you might have the following y vector which you will need to convert as follows:

#This is called a "one hot" encoding, because in the converted representation exactly one element of each column is
#"hot" (meaning set to 1). To do this conversion in numpy, you might have to write a few lines of code.
#In tensorflow, you can use one line of code:

    #tf.one_hot(labels, depth, axis)

def one_hot_matrix(labels, C):
    """
    Creates a matrix where the i-th row corresponds to the ith class number and the jth column
                     corresponds to the jth training example. So if example j had a label i. Then entry (i,j)
                     will be 1.

    Arguments:
    labels -- vector containing the labels
    C -- number of classes, the depth of the one hot dimension

    Returns:
    one_hot -- one hot matrix
    """

    # Creating a tf.constant equal to C (depth), name it 'C'. (approx. 1 line)
    C = tf.constant(C, tf.int32, name = 'C')

    # Using tf.one_hot, be careful with the axis
    one_hot_matrix = tf.one_hot(labels,C, axis = 0)

    # Creating the session
    sess = tf.Session()

    # Running the session
    one_hot = sess.run(one_hot_matrix)

    # Closing the session (approx. 1 line). See method 1 above.
    sess.close()

    return one_hot

labels = np.array([1,2,3,2,1])
one_hot = one_hot_matrix(labels, C = 3)
print ("one_hot = " + str(one_hot))

#Output
one_hot = [[ 0.  0.  0.  0.  0.]
 [ 1.  0.  0.  0.  1.]
 [ 0.  1.  0.  1.  0.]]

 #1.5 - Initialize with zeros and ones
def ones(shape):
    """
    Creates an array of ones of dimension shape

    Arguments:
    shape -- shape of the array you want to create

    Returns:
    ones -- array containing only ones
    """

    # Creating "ones" tensor using tf.ones(...).
    ones = tf.ones(shape)

    # Creating the session
    sess = tf.Session()

    # Running the session to compute 'ones'
    ones = sess.run(ones)

    # Closing the session
    sess.close()

    return ones

print ("ones = " + str(ones([3])))

#Output
ones = [ 1.  1.  1.]

#2 - Building your first neural network in tensorflow

 #   Training set: 1080 pictures (64 by 64 pixels) of signs representing numbers from 0 to 5 (180 pictures per number).
 #   Test set: 120 pictures (64 by 64 pixels) of signs representing numbers from 0 to 5 (20 pictures per number).

#Note that this is a subset of the SIGNS dataset. The complete dataset contains many more signs.

#Here are examples for each number, and how an explanation of how we represent the labels. These are the original
#pictures, before we lowered the image resolutoion to 64 by 64 pixels.

# Loading the dataset
X_train_orig, Y_train_orig, X_test_orig, Y_test_orig, classes = load_dataset()

#Change the index below and run the cell to visualize some examples in the dataset.

# Example of a picture
index = 0
plt.imshow(X_train_orig[index])
print ("y = " + str(np.squeeze(Y_train_orig[:, index])))

#Output y = 5

#As usual you flatten the image dataset, then normalize it by dividing by 255. On top of that, you will convert each label to a
#one-hot vector as shown in Figure 1. Run the cell below to do so.

# Flatten the training and test images
X_train_flatten = X_train_orig.reshape(X_train_orig.shape[0], -1).T
X_test_flatten = X_test_orig.reshape(X_test_orig.shape[0], -1).T
# Normalize image vectors
X_train = X_train_flatten/255.
X_test = X_test_flatten/255.
# Convert training and test labels to one hot matrices
Y_train = convert_to_one_hot(Y_train_orig, 6)
Y_test = convert_to_one_hot(Y_test_orig, 6)

print ("number of training examples = " + str(X_train.shape[1]))
print ("number of test examples = " + str(X_test.shape[1]))
print ("X_train shape: " + str(X_train.shape))
print ("Y_train shape: " + str(Y_train.shape))
print ("X_test shape: " + str(X_test.shape))
print ("Y_test shape: " + str(Y_test.shape))

#Output
number of training examples = 1080
number of test examples = 120
X_train shape: (12288, 1080)
Y_train shape: (6, 1080)
X_test shape: (12288, 120)
Y_test shape: (6, 120)

#Note that 12288 comes from 64×64×364×64×3. Each image is square, 64 by 64 pixels, and 3 is for
#the RGB colors. Please make sure all these shapes make sense to you before continuing.

#The model is LINEAR -> RELU -> LINEAR -> RELU -> LINEAR -> SOFTMAX. The SIGMOID output layer has been
#converted to a SOFTMAX. A SOFTMAX layer generalizes SIGMOID to when there are more than two classes.

#2.1 - Create placeholders

#Your first task is to create placeholders for X and Y. This will allow you to later pass your training
#data in when you run your session.

def create_placeholders(n_x, n_y):
    """
    Creates the placeholders for the tensorflow session.

    Arguments:
    n_x -- scalar, size of an image vector (num_px * num_px = 64 * 64 * 3 = 12288)
    n_y -- scalar, number of classes (from 0 to 5, so -> 6)

    Returns:
    X -- placeholder for the data input, of shape [n_x, None] and dtype "float"
    Y -- placeholder for the input labels, of shape [n_y, None] and dtype "float"

    Tips:
    - You will use None because it let's us be flexible on the number of examples you will for the placeholders.
      In fact, the number of examples during test/train is different.
    """

    X = tf.placeholder(tf.float32,[n_x,None],name = "X")
    Y = tf.placeholder(tf.float32,[n_y,None],name = "Y")

    return X, Y

X, Y = create_placeholders(12288, 6)
print ("X = " + str(X))
print ("Y = " + str(Y))

#Output
X = Tensor("X:0", shape=(12288, ?), dtype=float32)
Y = Tensor("Y:0", shape=(6, ?), dtype=float32)

#2.2 - Initializing the parameters
#W1 = tf.get_variable("W1", [25,12288], initializer = tf.contrib.layers.xavier_initializer(seed = 1))
#b1 = tf.get_variable("b1", [25,1], initializer = tf.zeros_initializer())

def initialize_parameters():
    """
    Initializes parameters to build a neural network with tensorflow. The shapes are:
                        W1 : [25, 12288]
                        b1 : [25, 1]
                        W2 : [12, 25]
                        b2 : [12, 1]
                        W3 : [6, 12]
                        b3 : [6, 1]

    Returns:
    parameters -- a dictionary of tensors containing W1, b1, W2, b2, W3, b3
    """

    tf.set_random_seed(1)                   # so that your "random" numbers match ours

    W1 = tf.get_variable("W1",[25,12288],initializer=tf.contrib.layers.xavier_initializer(seed = 1))
    b1 = tf.get_variable("b1",[25,1], initializer = tf.zeros_initializer())
    W2 = tf.get_variable("W2",[12,25],initializer=tf.contrib.layers.xavier_initializer(seed = 1))
    b2 = tf.get_variable("b2",[12,1], initializer = tf.zeros_initializer())
    W3 = tf.get_variable("W3",[6,12],initializer=tf.contrib.layers.xavier_initializer(seed = 1))
    b3 = tf.get_variable("b3",[6,1], initializer = tf.zeros_initializer())

    parameters = {"W1": W1,
                  "b1": b1,
                  "W2": W2,
                  "b2": b2,
                  "W3": W3,
                  "b3": b3}

    return parameters

  tf.reset_default_graph()
with tf.Session() as sess:
    parameters = initialize_parameters()
    print("W1 = " + str(parameters["W1"]))
    print("b1 = " + str(parameters["b1"]))
    print("W2 = " + str(parameters["W2"]))
    print("b2 = " + str(parameters["b2"]))

#Output
W1 = <tf.Variable 'W1:0' shape=(25, 12288) dtype=float32_ref>
b1 = <tf.Variable 'b1:0' shape=(25, 1) dtype=float32_ref>
W2 = <tf.Variable 'W2:0' shape=(12, 25) dtype=float32_ref>
b2 = <tf.Variable 'b2:0' shape=(12, 1) dtype=float32_ref>
#As expected, the parameters haven't been evaluated yet.

#2.3 - Forward propagation in tensorflow

 #   tf.add(...,...) to do an addition
 #   tf.matmul(...,...) to do a matrix multiplication
 #   tf.nn.relu(...) to apply the ReLU activation

def forward_propagation(X, parameters):
    """
    Implements the forward propagation for the model: LINEAR -> RELU -> LINEAR -> RELU -> LINEAR -> SOFTMAX

    Arguments:
    X -- input dataset placeholder, of shape (input size, number of examples)
    parameters -- python dictionary containing your parameters "W1", "b1", "W2", "b2", "W3", "b3"
                  the shapes are given in initialize_parameters

    Returns:
    Z3 -- the output of the last LINEAR unit
    """

    # Retrieve the parameters from the dictionary "parameters"
    W1 = parameters['W1']
    b1 = parameters['b1']
    W2 = parameters['W2']
    b2 = parameters['b2']
    W3 = parameters['W3']
    b3 = parameters['b3']

                                                                        # Numpy Equivalents:
    Z1 = tf.add(tf.matmul(W1,X),b1)                                     # Z1 = np.dot(W1, X) + b1
    A1 = tf.nn.relu(Z1)                                                 # A1 = relu(Z1)
    Z2 = tf.add(tf.matmul(W2,A1),b2)                                    # Z2 = np.dot(W2, a1) + b2
    A2 = tf.nn.relu(Z2)                                                 # A2 = relu(Z2)
    Z3 = tf.add(tf.matmul(W3,A2),b3)                                    # Z3 = np.dot(W3,Z2) + b3

    return Z3

tf.reset_default_graph()

with tf.Session() as sess:
    X, Y = create_placeholders(12288, 6)
    parameters = initialize_parameters()
    Z3 = forward_propagation(X, parameters)
    print("Z3 = " + str(Z3))

#Output
Z3 = Tensor("Add_2:0", shape=(6, ?), dtype=float32)

#2.4 Compute cost
 def compute_cost(Z3, Y):
    """
    Computes the cost

    Arguments:
    Z3 -- output of forward propagation (output of the last LINEAR unit), of shape (6, number of examples)
    Y -- "true" labels vector placeholder, same shape as Z3

    Returns:
    cost - Tensor of the cost function
    """

    # to fit the tensorflow requirement for tf.nn.softmax_cross_entropy_with_logits(...,...)
    logits = tf.transpose(Z3)
    labels = tf.transpose(Y)

    cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = logits, labels = labels))

    return cost

tf.reset_default_graph()

with tf.Session() as sess:
    X, Y = create_placeholders(12288, 6)
    parameters = initialize_parameters()
    Z3 = forward_propagation(X, parameters)
    cost = compute_cost(Z3, Y)
    print("cost = " + str(cost))

 #Output
 cost = Tensor("Mean:0", shape=(), dtype=float32)

#2.5 - Backward propagation & parameter updates
def model(X_train, Y_train, X_test, Y_test, learning_rate = 0.0001,
          num_epochs = 1500, minibatch_size = 32, print_cost = True):
    """
    Implements a three-layer tensorflow neural network: LINEAR->RELU->LINEAR->RELU->LINEAR->SOFTMAX.

    Arguments:
    X_train -- training set, of shape (input size = 12288, number of training examples = 1080)
    Y_train -- test set, of shape (output size = 6, number of training examples = 1080)
    X_test -- training set, of shape (input size = 12288, number of training examples = 120)
    Y_test -- test set, of shape (output size = 6, number of test examples = 120)
    learning_rate -- learning rate of the optimization
    num_epochs -- number of epochs of the optimization loop
    minibatch_size -- size of a minibatch
    print_cost -- True to print the cost every 100 epochs

    Returns:
    parameters -- parameters learnt by the model. They can then be used to predict.
    """

    ops.reset_default_graph()                         # to be able to rerun the model without overwriting tf variables
    tf.set_random_seed(1)                             # to keep consistent results
    seed = 3                                          # to keep consistent results
    (n_x, m) = X_train.shape                          # (n_x: input size, m : number of examples in the train set)
    n_y = Y_train.shape[0]                            # n_y : output size
    costs = []                                        # To keep track of the cost

    # Create Placeholders of shape (n_x, n_y)

    X, Y = create_placeholders(n_x, n_y)

    # Initialize parameters

    parameters = initialize_parameters()

    # Forward propagation: Build the forward propagation in the tensorflow graph

    Z3 = forward_propagation(X, parameters)

    # Cost function: Add cost function to tensorflow graph

    cost = compute_cost(Z3, Y)

    # Backpropagation: Define the tensorflow optimizer. Use an AdamOptimizer.

    optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)

    # Initialize all the variables
    init = tf.global_variables_initializer()

    # Start the session to compute the tensorflow graph
    with tf.Session() as sess:

        # Run the initialization
        sess.run(init)

        # Do the training loop
        for epoch in range(num_epochs):

            epoch_cost = 0.                       # Defines a cost related to an epoch
            num_minibatches = int(m / minibatch_size) # number of minibatches of size minibatch_size in the train set
            seed = seed + 1
            minibatches = random_mini_batches(X_train, Y_train, minibatch_size, seed)

            for minibatch in minibatches:

                # Select a minibatch
                (minibatch_X, minibatch_Y) = minibatch

                # IMPORTANT: The line that runs the graph on a minibatch.
                # Run the session to execute the "optimizer" and the "cost", the feedict should contain a minibatch for (X,Y).

                _ , minibatch_cost = sess.run([optimizer, cost], feed_dict={X: minibatch_X, Y: minibatch_Y})

                epoch_cost += minibatch_cost / num_minibatches

            # Print the cost every epoch
            if print_cost == True and epoch % 100 == 0:
                print ("Cost after epoch %i: %f" % (epoch, epoch_cost))
            if print_cost == True and epoch % 5 == 0:
                costs.append(epoch_cost)

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

        # lets save the parameters in a variable
        parameters = sess.run(parameters)
        print("Parameters have been trained!")

        # Calculate the correct predictions
        correct_prediction = tf.equal(tf.argmax(Z3), tf.argmax(Y))

        # Calculate accuracy on the test set
        accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

        print("Train Accuracy:", accuracy.eval({X: X_train, Y: Y_train}))
        print("Test Accuracy:", accuracy.eval({X: X_test, Y: Y_test}))

        return parameters

parameters = model(X_train, Y_train, X_test, Y_test)

Cost after epoch 0: 1.855702
Cost after epoch 100: 1.016458
Cost after epoch 200: 0.733102
Cost after epoch 300: 0.572940
Cost after epoch 400: 0.468774
Cost after epoch 500: 0.381021
Cost after epoch 600: 0.313822
Cost after epoch 700: 0.254158
Cost after epoch 800: 0.203829
Cost after epoch 900: 0.166421
Cost after epoch 1000: 0.141486
Cost after epoch 1100: 0.107580
Cost after epoch 1200: 0.086270
Cost after epoch 1300: 0.059371
Cost after epoch 1400: 0.052228

Parameters have been trained!
Train Accuracy: 0.999074
Test Accuracy: 0.716667

Tensorflow Tutorial, Neural Network Using Tensorflow .py


# 1d linear regression.
# Make the data and plot it.

import matplotlib.pyplot as plt
import numpy as np
from utils.linreg_model import LinregModel

def make_fun_1d(fun_type):
    if fun_type == 'linear':
        params_true = np.array([1, 1])
        true_fun = lambda x: params_true[1] + params_true[0]*x
        ttl = 'w*x + b'
    if fun_type == 'sine':
        params_true = np.array([1, 1])
        true_fun = lambda x: params_true[1] + params_true[0]*np.sin(x)
        ttl = 'w*sin(x) + b'
    if fun_type == 'quad':
        # 'thibaux' parameters from here:
        #https://github.com/probml/pmtk3/blob/master/matlabTools/stats/polyDataMake.m
         #w = [-1.5; 1/9];
        #fun = @(x) w(1)*x + w(2)*x.^2;
        params_true = np.array([1, 1])
        true_fun = lambda x: params_true[0]*x + params_true[1]*np.square(x)
        ttl = 'w*x^2 + b'
    return params_true, true_fun, ttl

# Sample (x,y) pairs from a noisy function
def make_data_linreg_1d(N, fun_type, matlab_hack=False):
    if '-' in fun_type:
        parts = fun_type.split('-')
        fun_type = parts[0]
        centered = (parts[1] == 'centered')
    else:
        centered = True
    params_true, true_fun, fun_name = make_fun_1d(fun_type)
    if centered:
        xtrain = np.random.normal(0, 3, N)
    else:
        xtrain = np.linspace(0, 20, N)
    ytrain_clean = true_fun(xtrain)
    sigma2 = 1
    noise = np.random.normal(0, 1, xtrain.shape) * np.sqrt(sigma2)
    Ytrain = ytrain_clean + noise
    Xtrain = np.reshape(xtrain, (N, 1))
    if matlab_hack:
        # Match matlab's https://github.com/probml/pmtk3/blob/master/demos/contoursSSEdemo.m
        Ytrain = np.array([3.560, 1.831, 0.924, 1.475, 0.531, 0.686, 2.720, 3.061, -1.233, 1.369, 2.990, 1.546, 3.425,
        1.406, 3.306, 0.729, 4.050, 1.879, 0.313, 0.369])
        xtrain = np.array([1.749, 0.133, 0.325, -0.794, 0.315, -0.527, 0.932, 1.165, -2.046, -0.644, 1.741, 0.487, 1.049,
        1.489, 1.271, -1.856, 2.134, 1.436, -0.917, -1.106])
        N = len(xtrain)
        Xtrain = np.reshape(xtrain, [N,1])
    return Xtrain, Ytrain, params_true, true_fun, fun_name

# Plot 2d error surface around model's parameter vaulues
def plot_error_surface_2d(loss_fun, params_opt, params_true, fun_type, ax=None):
    if ax is None:
        fig = plt.figure()
        ax = fig.add_subplot(111)
    # Choose the range to make a pretty plot
    if fun_type == 'quad':
        w0_range = [-1, 2]
        w1_range = [-1, 6]
    elif fun_type == 'sine':
        w0_range = [-3, 3]
        w1_range = [-1, 3]
    else:
        w0_range = [-1, 3]
        w1_range = [-1, 3]
    w0s = np.linspace(w0_range[0], w0_range[1], 100)
    w1s = np.linspace(w1_range[0], w1_range[1], 100)
    w0_grid, w1_grid = np.meshgrid(w0s, w1s)
    lossvec = np.vectorize(loss_fun)
    z = lossvec(w1_grid, w0_grid)
    cs = ax.contour(w1s, w0s, z)
    ax.clabel(cs)
    ax.plot(params_opt[1], params_opt[0], 'rx', markersize=14)
    ax.plot(params_true[1], params_true[0], 'k+', markersize=14)
    return ax

def plot_param_trace_2d(params_trace, ax):
    '''Plot 2d trajectory of parameters on top of axis,
    param_trace is list of weight vectors'''
    n_steps = len(params_trace)
    xs = np.zeros(n_steps)
    ys = np.zeros(n_steps)
    for step in range(1, n_steps):
        xs[step] = params_trace[step][1]
        ys[step] = params_trace[step][0]
    ax.plot(xs, ys, 'o-')

def plot_data_and_predictions_1d(xtrain, ytrain, true_fun, pred_fun, ax=None):
    if ax is None:
        fig = plt.figure()
        ax = fig.add_subplot(111)
    ax.plot(xtrain, ytrain, 'o', label='observed')
    x_range = np.linspace(np.min(xtrain), np.max(xtrain), 100)
    x_range = np.reshape(x_range, [100,1])
    yhat_range = pred_fun(x_range)
    ax.plot(x_range, yhat_range, 'r--', label='predicted')
    y_range = true_fun(x_range)
    ax.plot(x_range, y_range, 'k-', label='truth')
    return ax

def main():
    for fun_type in ['linear', 'quad', 'sine']:
        np.random.seed(1)
        N = 20
        Xtrain, Ytrain, params_true, true_fun, ttl = make_data_linreg_1d(N, fun_type)

        model = LinregModel(1, True)
        params_ols, loss_ols = model.ols_fit(Xtrain, Ytrain)
        print(ttl)
        print(params_ols)

        # Plot data
        predict_fun = lambda x: model.prediction(params_ols, x)
        ax = plot_data_and_predictions_1d(Xtrain, Ytrain, true_fun, predict_fun)
        ax.set_title(ttl)

        # Plot error surface
        loss_fun = lambda w0, w1: model.objective([w0, w1], Xtrain, Ytrain)
        ax  = plot_error_surface_2d(loss_fun, params_ols, params_true, fun_type)
        ax.set_title(ttl)
    plt.show()

if __name__ == "__main__":
    main()


"""
Wrapper for activation functions and their derivatives
to be used with the DNN classes
"""

import numpy as np

# Logistic
def myLogistic(X):
    return 1.0 / (1.0 + np.exp(-X))

def myLogisticPrime(X):
    S = myLogistic(X)
    return np.multiply(S, 1.0 - S)

# Hyperbolic tangent
def myTanh(X):
    return np.tanh(X)

def myTanhPrime(X):
    return 1 - np.square(np.tanh(X))

# Rectified linear units
def myRelu(X):
    return np.maximum(0.0, X)

def myReluPrime(X):
    return (X > 0.0).astype(X.dtype)

# Absolute value (fully rectified)
def myAbs(X):
    return np.abs(X)

def myAbsPrime(X):
    return np.sign(X)

# Squared
def mySquare(X):
    return np.square(X)

def mySquarePrime(X):
    return X

# Half squared
def myHalfSquare(X):
    return myRelu(mySquare(X))

def myHalfSquarePrime(X):
    return myRelu(X)

## activation functions are regitered in the following dictionary
func_list = {'sigmoid':(myLogistic, myLogisticPrime),     \
             'tanh':(myTanh, myTanhPrime),        \
             'relu':(myRelu, myReluPrime),        \
             'abs':(myAbs, myAbsPrime),         \
             'square':(mySquare, mySquarePrime),      \
             'half_square':(myHalfSquare, myHalfSquarePrime)}


#Eulers method
import numpy as np

def dy(ynew,xnew,y,x,h):
    dyvalue = y-x
    return dyvalue
 #Note: change the derivative function based on question!!!!!!  Example: y-x

y0 = 0.5  #float(input"what is the y(0)?")

h = 0.1 #float(input"h?")

x_final = 0.3 #float(input"x_final")

#initiating input variables
x = 0
y = y0
# remember to change yn+1 and xn+1 values if you already know them!!!
ynew = 0
xnew = 0
i = 0

#####################################################
iterations = x_final/h

while x <= x_final:
    derivative_of_y = dy(ynew,xnew,y,x,h)
    xnew = x + h
    ynew = y + (xnew - x)*(derivative_of_y)
    print("iteration:        ____            ")
    print(i)
    print("\n")
    print("x = ")
    print(xnew)
    print("\n")
    print("y = ")
    print(ynew)
    x = xnew
    y = ynew
    i+=1


#
import math
import numpy as np

class HoltWinters(object):
    def __init__(self):
        self.name = 'HoltWinters'

    def startup(self):
        self.predict_by_mean()

    def predict_by_mean(self):
        y = np.array([3,10,12,13,12,10,12], dtype=np.float32)
        return np.mean(y)

    def weighted_average(self, series, weights):
        mean = 0.0
        weights.reverse()
        for i in range(len(weights)):
            mean += series[-i-1] * weights[i]
        return mean

    def expopential_smoothing(self, series, alpha):
        result = [series[0]]
        for t in range(1, len(series)):
            result.append(alpha * series[t] + (1 - alpha) * result[t-1])
        return result

    def double_exponential_smoothing(self, series, alpha, beta):
        result = [series[0]]
        for n in range(1, len(series)+1):
            if n == 1:
                level, trend = series[0], series[1] - series[0]
            if n >= len(series): # we are forecasting
              value = result[-1]
            else:
              value = series[n]
            last_level, level = level, alpha*value + (1-alpha)*(level+trend)
            trend = beta*(level-last_level) + (1-beta)*trend
            result.append(level+trend)
        return result

    def initial_trend(self, series, slen):
        sum = 0.0
        for i in range(slen):
            sum += float(series[i+slen] - series[i]) / slen
        return sum / slen

    def initial_seasonal_components(self, series, slen):
        seasonals = {}
        season_averages = []
        n_seasons = int(len(series)/slen)
        # compute season averages
        for j in range(n_seasons):
            season_averages.append(sum(series[slen*j:slen*j+slen])/float(slen))
        # compute initial values
        for i in range(slen):
            sum_of_vals_over_avg = 0.0
            for j in range(n_seasons):
                sum_of_vals_over_avg += series[slen*j+i]-season_averages[j]
            seasonals[i] = sum_of_vals_over_avg/n_seasons
        return seasonals

    def triple_exponential_smoothing(self, series, slen, alpha, beta, gamma, n_preds):
        result = []
        seasonals = self.initial_seasonal_components(series, slen)
        for i in range(len(series)+n_preds):
            if i == 0: # initial values
                smooth = series[0]
                trend = self.initial_trend(series, slen)
                result.append(series[0])
                continue
            if i >= len(series): # we are forecasting
                m = i - len(series) + 1
                result.append((smooth + m*trend) + seasonals[i%slen])
            else:
                val = series[i]
                last_smooth, smooth = smooth, alpha*(val-seasonals[i%slen]) + (1-alpha)*(smooth+trend)
                trend = beta * (smooth-last_smooth) + (1-beta)*trend
                seasonals[i%slen] = gamma*(val-smooth) + (1-gamma)*seasonals[i%slen]
                result.append(smooth+trend+seasonals[i%slen])
        return result


"""
Notes
-----
Build an array of power levels
Slide a 3x3 window & calculate sum of power levels
"""
import numpy as np
from typing import Tuple

def build_power_levels(serial_no: int) -> np.ndarray:
    n_x = 300
    n_y = 300
    power_levels = np.empty((n_x, n_y), dtype=int)

    for x in range(n_x):
        for y in range(n_y):
            power_levels[x, y] = get_power_level(x + 1, y + 1, serial_no)

    return power_levels

def get_power_level(x: int, y: int, serial_no: int) -> int:
    rack_id = x + 10
    power_level = (rack_id * y + serial_no) * rack_id
    power_level = power_level // 100 % 10 - 5
    return power_level

def get_largest_square(power_levels: np.ndarray,
                       width: int = 3,
                       height: int = 3) -> Tuple[int, int, int]:
    best_x = np.nan
    best_y = np.nan
    best_power_level = -np.inf
    for x in range(0, power_levels.shape[0] - width + 2):
        for y in range(0, power_levels.shape[1] - height + 2):
            square = power_levels[x:(x + width), y:(y + height)]
            power_level = square.sum()
            if power_level > best_power_level:
                best_x = x
                best_y = y
                best_power_level = power_level

    return (best_x + 1, best_y + 1, best_power_level)

def get_largest_total_square(power_levels: np.ndarray):
    best_x = np.nan
    best_y = np.nan
    best_size = np.nan
    best_power_level = -np.inf
    for size in range(100):
        x, y, power_level = get_largest_square(power_levels,
                                               width=size,
                                               height=size)
        if power_level > best_power_level:
            best_x = x
            best_y = y
            best_size = size
            best_power_level = power_level
        elif power_level < 0:
            break

    return (best_x, best_y, best_size, best_power_level)

assert get_power_level(3, 5, 8) == 4
assert get_power_level(122, 79, 57) == -5
assert get_power_level(217, 196, 39) == 0
assert get_power_level(101, 153, 71) == 4

test_power_levels_18 = build_power_levels(18)
assert get_largest_square(test_power_levels_18) == (33, 45, 29)

test_power_levels_42 = build_power_levels(42)
assert get_largest_square(test_power_levels_42) == (21, 61, 30)

assert get_largest_total_square(test_power_levels_18) == (90, 269, 16, 113)
assert get_largest_total_square(test_power_levels_42) == (232, 251, 12, 119)

power_levels = build_power_levels(4455)
print(get_largest_square(power_levels))
print(get_largest_total_square(power_levels))


"""
 linear_regression_SGD.py  (author: Anson Wong / git: ankonzoid)
"""
import os
import numpy as np
import pandas as pd
class LinearRegressorSGD:
	def __init__(self):
		pass
	def fit(self, X, y):
		print("Fitting...")
		N, d = X.shape
		a_fit = np.random.normal(size=d + 1)
		loss_tolerance = 1e-6
		fit_tolerance = 1e-4
		eta = 1e-6
		converge = False
		loss = 9e99
		iter = 0
		while not converge:
			i_random = np.random.choice(N)
			gradient = np.zeros(d + 1)
			y_hat_i = a_fit[0] + np.dot(a_fit[1:], X[i_random])
			y_i = y[i_random]
			gradient[0] += 2 * (y_hat_i - y_i)
			gradient[1:] += 2 * (y_hat_i - y_i) * X[i_random, 0:]
			a_fit_new = a_fit - eta * gradient
			y_pred = []
			for x in X:
				y_pred_i = a_fit_new[0] + np.dot(a_fit_new[1:], x)
				y_pred.append(y_pred_i)
			y_pred = np.array(y_pred)
			loss_new = np.linalg.norm(y_pred - y) ** 2 / N
			if iter % N:
				print("loss = {}".format(loss))
			if np.abs(loss_new - loss) < loss_tolerance and np.linalg.norm(a_fit_new - a_fit) < fit_tolerance:
				converge = True
			a_fit = a_fit_new
			loss = loss_new
			iter += 1
		self.a_fit = a_fit
	def predict(self, X):
		y_pred = []
		for x in X:
			y_pred_i = self.a_fit[0] + np.dot(self.a_fit[1:], x)
			y_pred.append(y_pred_i)
		y_pred = np.array(y_pred)
		return y_pred
if __name__ == "__main__":
	X = np.arange(100).reshape(-1, 1)
	y = 0.4 * X.flatten() + 3 + np.random.uniform(-10, 10, size=(100,))
	model = LinearRegressorSGD()
	model.fit(X, y)
	y_pred = model.predict(X)
	mse = ((y_pred - y) ** 2).mean(axis=0)
	print("mse =", mse)
	import matplotlib.pyplot as plt
	plt.figure(1)
	plt.plot(X.flatten(), y, "o")
	plt.plot(X.flatten(), y_pred, "r")
	plt.show()


import numpy as np

class Loss():
    pass

                            ##########Regression Cost Functions#############

class MSE(Loss):

    def compute_cost(self,AL, Y):
        """
        Implement the MSE cost function

        Arguments:
        AL --  vector corresponding to your label predictions
        Y -- true "label" vector

        Returns:
        cost -- MSE regression cost
        grad -- MSE regression cost gradient
        """

        m = Y.shape[0]

        cost=(Y-AL)**2
        cost=cost/(m*2)

        grad=-(Y-AL)/m

        cost = np.squeeze(cost)      # To make sure your cost's shape is what we expect (e.g. this turns [[17]] into 17).
        assert(cost.shape == ())

        cost[np.isnan(cost)] = 0
        grad[np.isnan(grad)] = 0

        return cost,grad

                                        ##########Classification Cost Functions#############

class BinaryCrossEntropyLoss(Loss):

    def compute_cost(self,AL, Y):
        """
        Implement the cost function

        Arguments:
        AL -- probability vector corresponding to your label predictions
        Y -- true "label" vector

        Returns:
        cost -- Binary cross-entropy cost
        grad -- Binary cross-entropy gradient
        """

        m = Y.shape[0]

        # Compute loss from aL and y.
        cost = (1./m) * (-np.dot(Y.T,np.log(AL)) - np.dot((1-Y).T, np.log(1-AL)))

        grad = - (1./m) * (np.divide(Y, AL) - np.divide(1 - Y, 1 - AL))

        cost = np.squeeze(cost)      # To make sure your cost's shape is what we expect (e.g. this turns [[17]] into 17).
        assert(cost.shape == ())

        cost[np.isnan(cost)] = 0
        grad[np.isnan(grad)] = 0

        return cost,grad

class CategoricalCrossEntropyLoss(Loss):

    def compute_cost(self,AL, Y):
        """
        Implement the cost function

        Arguments:
        AL -- probability vector corresponding to your label predictions
        Y -- true "label" vector

        Returns:
        cost -- Categorical cross-entropy cost
        grad -- Categorical cross-entropy gradient
        """

        m = Y.shape[0]

        # Compute loss from aL and y.
        cost = -(1./m) * (Y*np.log(AL))
        cost=np.array(np.sum(cost))

        grad = - (1./m) * (np.divide(Y, AL))

        cost = np.squeeze(cost)      # To make sure your cost's shape is what we expect (e.g. this turns [[17]] into 17).
        assert(cost.shape == ())

        cost[np.isnan(cost)] = 0
        grad[np.isnan(grad)] = 0

        return cost,grad


# -*- coding: utf-8 -*-
from __future__ import absolute_import

from __future__ import print_function

from __future__ import division
#---------------------------------------------------------------------------

__author__ = 'Hui'

#---------------------------------------------------------------------------

import numpy as np

from scipy.special import comb

#---------------------------------------------------------------------------

def bernstein_poly(i, n, t, reverse=True):
    """
     The Bernstein polynomial of n, i as a function of t
    """
    if reverse:
        return comb(n, i) * ( t**(n-i) ) * (1 - t)**i
    else:
        return comb(n, i) * ( (1 - t)**(n-i) ) * t**i

# from control_points to curve_points:
def bezier_curve(points, nTimes=500, is_poly=False, is_crv=False):
    """
       Given a set of control points, return the
       bezier curve defined by the control points.

       points should be a list of lists, or list of tuples
       such as [ [1,1],
                 [2,3],
                 [4,5], ..[Xn, Yn] ]
        nTimes is the number of time steps, defaults to 1000

        See http://processingjs.nihongoresources.com/bezierinfo/

    Hui Note: given points, the returned crv points in reverse direction:
                Q[0] == points[-1]; Q[-1] == points[0]
    """
    if is_poly:
        from geometrylab.geometry import Polyline
        return Polyline(points,closed=False)
    else:
        nPoints = len(points)
        xPoints = np.array([p[0] for p in points])
        yPoints = np.array([p[1] for p in points])
        zPoints = np.array([p[2] for p in points])

        t = np.linspace(0.0, 1.0, nTimes)

        polynomial_array = np.array([ bernstein_poly(i, nPoints-1, t) for i in range(0, nPoints)])

        xvals = np.dot(xPoints, polynomial_array)
        yvals = np.dot(yPoints, polynomial_array)
        zvals = np.dot(zPoints, polynomial_array)
        Q = np.flip(np.c_[xvals,yvals,zvals],axis=0)

        if is_crv:
            crv = Polyline(Q,closed=False)
            return crv
        else:
            return Q

def berstein_matrix(n):
 #bezierM = lambda ts: np.matrix([[bernstein_poly(i,5,t) for i in range(6)] for t in ts])
    ts = np.linspace(0.0, 1.0, n)
    m = []
    for t in ts:
        m.append([bernstein_poly(i,n-1,t) for i in range(n)])
    m.reverse()
    return np.array(m)

# from curve_points to control_points:
def bezier_controlPoints(P):
    n = len(P)
    M = berstein_matrix(n)
    Q = np.dot(np.linalg.inv(M), P)
    return Q

def bezier_degree_evaluation(P, deg_evl):
    "Qi = i/(n+1) * P_{i-1} + (1-i/(n+1)) * P_i"
    "only from current curves' control_points_P to get evaluated control_points_Q"
    "deg_evl > len(P)-1 = n"
    num = len(P) # num=4, control points, P0,P1,P2,P3
    n = num-1    # degree=3, deg_evl=5

    Q = np.zeros((deg_evl+1,3))
    Q[0,:] = P[0,:]
    Q[-1,:] = P[-1,:]

    while n < deg_evl:   # 3<5
        for j in range(n): # 0,1,2
            i = j+1        # 1,2,3
            Q[i,:] = float(i)/(n+1)*P[i-1,:] + (1-float(i)/(n+1))*P[i,:]
        n += 1 # 4
        P = np.vstack((Q[:n,:], P[-1,:]))

    return Q

# def bezier_derivative(points, nTimes=100, d=1, is_poly=False, is_crv=False): #Hui add:
#     if d==1:
#         "first derivative"
#         nPoints = len(points)-1
#         xPoints = np.array([p[0] for p in points])
#         yPoints = np.array([p[1] for p in points])
#         zPoints = np.array([p[2] for p in points])

#         dx = xPoints[1:]-xPoints[:-1]
#         dy = yPoints[1:]-yPoints[:-1]
#         dz = zPoints[1:]-zPoints[:-1]

#         t = np.linspace(0.0, 1.0, nTimes)

#         polynomial_array = np.array([ bernstein_poly(i, nPoints-1, t) for i in range(0, nPoints)])

#         xvals = np.dot(dx, polynomial_array) * len(points)
#         yvals = np.dot(dy, polynomial_array) * len(points)
#         zvals = np.dot(dz, polynomial_array) * len(points)
#         Q = np.flip(np.c_[xvals,yvals,zvals],axis=0)

#     if is_crv:
#         from geometrylab.geometry import Polyline
#         crv = Polyline(Q,closed=False)
#         return crv
#     else:
#         return Q

def bezier_tangent_atparameters(ctrl_points,ti):
    "len(ti)>=1"
    n = len(ctrl_points) #==6
    dP = ctrl_points[1:,:] - ctrl_points[:-1,:]
    arr1 = np.array([bernstein_poly(i,n-2,ti,False) for i in range(0, n-1)]) # len=n-1

    xvals = np.dot(dP[:,0], arr1)
    yvals = np.dot(dP[:,1], arr1)
    zvals = np.dot(dP[:,2], arr1)
    Q = np.flip(np.c_[xvals,yvals,zvals],axis=0)
    T = Q / np.linalg.norm(Q,axis=1)[:,None]
    return T

def bezier_curvature_ataparameter(ctrl_points,ti,surfN=None,is_absolute=True):
    "P'(ti), P''(ti), P'''(ti) ,  ti=1/5, 2/5, 3/5, 4/5"
    n = len(ctrl_points) #==6
    n1,n2,n3 = n-1, n-2, n-3

    P = ctrl_points
    dP = P[1:,:] - P[:-1,:]
    ddP = dP[1:,:] - dP[:-1,:]
    dddP = ddP[1:,:] - ddP[:-1,:]

    arr  = np.array([bernstein_poly(i,n -1,ti,False) for i in range(0, n)])  # len=n
    arr1 = np.array([bernstein_poly(i,n1-1,ti,False) for i in range(0, n1)]) # len=n-1
    arr2 = np.array([bernstein_poly(i,n2-1,ti,False) for i in range(0, n2)]) # len=n-2
    arr3 = np.array([bernstein_poly(i,n3-1,ti,False) for i in range(0, n3)]) # len=n-3

    Pi = np.sum(P*arr,axis=0)
    dP = np.sum(dP*arr1,axis=0) * comb(n-1, 1)
    ddP = np.sum(ddP*arr2,axis=0) * comb(n-1, 2)
    dddP = np.sum(dddP*arr3,axis=0) * comb(n-1, 3)

    T = dP / np.linalg.norm(dP)
    k = np.linalg.norm(np.cross(dP,ddP)) / np.linalg.norm(dP)**3
    tau = np.dot(np.cross(dP,ddP), dddP) / np.linalg.norm(np.cross(dP,ddP))**2
    kg,kn,d = None,None,None
    if surfN is not None:
        kg = np.dot(np.cross(surfN,dP),ddP) / np.linalg.norm(dP)**3
        kn = np.dot(surfN,ddP) / np.linalg.norm(dP)**2
        if is_absolute:
            k,kg,kn,tau = np.abs(k),np.abs(kg),np.abs(kn),np.abs(tau)
        S = np.cross(surfN,T)
        d = tau*T-kn*S+kg*surfN
        d = d / np.linalg.norm(d)
    return Pi, T, [k,tau,kg,kn,d]

def bezier_curvature_atequalparameters(ctrl_points,is_asy_or_geo=True,num=5):
    "DENSE: P'(ti), P''(ti), P'''(ti) ,  ti=1/5, 2/5, 3/5, 4/5"
    n = len(ctrl_points)-1#==6-1
    n1,n2,n3 = n-1, n-2, n-3
    ti = np.arange(num+1) / num  #### ti==[0, 0.2, 0.4, 0.6, 0.8, 1]
    P = ctrl_points
    dP = P[1:,:] - P[:-1,:]
    ddP = dP[1:,:] - dP[:-1,:]
    dddP = ddP[1:,:] - ddP[:-1,:]

    arr  = np.array([bernstein_poly(i,n,ti,False) for i in range(0, n+1)])  # len=6
    arr1 = np.array([bernstein_poly(i,n1,ti,False) for i in range(0, n1+1)]) # len=5
    arr2 = np.array([bernstein_poly(i,n2,ti,False) for i in range(0, n2+1)]) # len=4
    arr3 = np.array([bernstein_poly(i,n3,ti,False) for i in range(0, n3+1)]) # len=3

    xvals = np.dot(P[:,0], arr)
    yvals = np.dot(P[:,1], arr)
    zvals = np.dot(P[:,2], arr)
    #Pi = np.flip(np.c_[xvals,yvals,zvals],axis=0)
    Pi = np.c_[xvals,yvals,zvals]

    xvals = np.dot(dP[:,0], arr1)
    yvals = np.dot(dP[:,1], arr1)
    zvals = np.dot(dP[:,2], arr1)
    T = np.c_[xvals,yvals,zvals]*n
    E1 = T / np.linalg.norm(T,axis=1)[:,None]

    xvals = np.dot(ddP[:,0], arr2)
    yvals = np.dot(ddP[:,1], arr2)
    zvals = np.dot(ddP[:,2], arr2)
    dT = np.c_[xvals,yvals,zvals]*n*(n-1)
    E2 = dT / np.linalg.norm(dT,axis=1)[:,None] ##NOTE: infact, for general t, E2 is not _|_  E1, but E3//E1XE2

    xvals = np.dot(dddP[:,0], arr3)
    yvals = np.dot(dddP[:,1], arr3)
    zvals = np.dot(dddP[:,2], arr3)
    ddT = np.c_[xvals,yvals,zvals]*n*(n-1)*(n-2)

    k = np.linalg.norm(np.cross(T,dT),axis=1) / np.linalg.norm(T,axis=1)**3
    tau = np.einsum('ij,ij->i',np.cross(T,dT), ddT) / np.linalg.norm(np.cross(T,dT),axis=1)**2

    tau = np.abs(tau) ##IF NOT ABS, WILL CHANGE THE DIRECTION
    #print('tau:[min,mean,max]=','%.2g' % np.min(tau),'%.2g' % np.mean(tau),'%.2g' % np.max(tau))

    E3 = np.cross(E1,E2)
    E3 = E3 / np.linalg.norm(E3,axis=1)[:,None]
    d = E1*tau[:,None]+E3*k[:,None]
    d = d / np.linalg.norm(d,axis=1)[:,None]

    if is_asy_or_geo:
        "asymptotic: surf_normal = binormal _|_ osculating_normal"
        srfN = E3 ## len==len(ti)
    else:
        "geodesic: surf_normal = osculating_normal"
        srfN = E2

    kg = np.einsum('ij,ij->i',np.cross(srfN,T),dT) / np.linalg.norm(T,axis=1)**3
    kn = np.einsum('ij,ij->i',srfN,dT) / np.linalg.norm(T,axis=1)**2

    kg,kn = np.abs(kg), np.abs(kn)

    return Pi,[E1,E2,E3],[kg,kn,k,tau,d]


import numpy as np
import matplotlib.pyplot as plt

n = np.arange(14)
fn=(-1/2)**n
hn1=np.pad(fn, (0,2), 'constant', constant_values=(0))
hn2=np.pad(fn, (2,0), 'constant', constant_values=(0))
h = hn1+hn2

nh=len(h)
x=np.array([1.0,2.0,3.0,4.0,2.0,1.0])
nx = len(x)

y = np.zeros(nx+nh-1)

for k in range(0,nx+nh-1):
	for n in range(0,nx):
		if k-n >= 0 and k-n < nh:
			y[k]+=x[n]*h[k-n]

print(y)
#plots
plt.stem(range(0,nx+nh-1),y)
plt.title('Filter Output using Convolution')
plt.xlabel('$n$')
plt.ylabel('$y(n)$')
plt.grid()# minor

plt.savefig('ynconv.png')


import numpy as np
import scipy.spatial.distance as dis
import matplotlib.pyplot as plt

__all__ = ['k_means']

# KMeans主函数
def k_means(data_set, cluster_count):
    point_count = np.shape(data_set)[0]  # 数据集中的待分类点个数

    # 列1：数据集归类的聚类中心（0,1,2,3），列2:数据集行向量到聚类中心的距离
    point_cluster_distances = np.zeros((point_count, 2), dtype=float)
    cluster_centers = data_set[:cluster_count, :]  # 取前4个点作为初始聚类中心

    iteration_flag = True  # 迭代结束标识
    iteration_count = 0  # 迭代次数

    while iteration_flag:
        iteration_flag = False
        iteration_count += 1

        # 遍历数据集中的所有点，计算每个点与聚类中心的最小欧式距离
        for index in range(point_count):
            # 遍历当前点到所有聚类中心的距离，获取最短距离的聚类中心
            current_point_to_cluster_distances = [dis.euclidean(data_set[index, :],
                                                                cluster_centers[j, :]) for j in range(cluster_count)]
            min_distance = min(current_point_to_cluster_distances)
            min_distance_cluster_index = current_point_to_cluster_distances.index(min_distance)

            # 找到了一个新聚类中心，重置标志位为True，继续迭代，如果没有找到新的聚类中心，说明迭代已经收敛，不再迭代
            if point_cluster_distances[index, 0] != min_distance_cluster_index:
                iteration_flag = True

            # 更新当前点找到的聚类中心以及距离
            point_cluster_distances[index, :] = min_distance_cluster_index, min_distance ** 2

        # 重新计算已经得到的各个聚类的质心
        for index in range(cluster_count):
            # 当前聚类的所有距离下标
            current_cluster_distance_indexes = np.nonzero(point_cluster_distances[:, 0].T == index)[0]
            # 当前聚类的所有点
            current_cluster_points = data_set[current_cluster_distance_indexes]
            cluster_centers[index, :] = np.mean(current_cluster_points, axis=0)

    print('cluster_centers: \n', cluster_centers)
    return cluster_centers, point_cluster_distances

def train(cluster_count=4):
    data_set_path = r"../data/point-set-kmeans.txt"
    # data_set_path = r"../data/point-set-bi-kmeans.txt"  # 错误的聚类
    data_set = np.loadtxt(data_set_path, dtype=float, delimiter='\t')
    cluster_centers, point_cluster_distances = k_means(data_set, cluster_count)
    cluster_point_distance_1 = point_cluster_distances[:, :1]
    colors = ['blue', 'green', 'red', 'gray', 'pink', 'cyan']

    for index in range(len(cluster_point_distance_1)):
        plt.scatter(data_set[index, 0], data_set[index, 1], c=colors[int(cluster_point_distance_1[index])], marker='o')

    plt.scatter(cluster_centers.T[0], cluster_centers.T[1], s=60, c='black', marker='D')
    plt.show()

if __name__ == '__main__':
    train()  # 5个点时效果很差


"""Individuals."""

from typing import List, Tuple

import math
import numpy as np
import random

# Custom types
Chromosome = List[float]
SearchSpace = Tuple[float, float]

class AB:
    """Approximated Brachistochrone.

    Approximated brachistochrones are the individuals that going to be evolving
    during the main algorithm execution. Each AB is represented as a set of
    n-1 vertical coordinates representing the overall curve, where n is the
    number of evenly distributed "slots" between the starting point and the
    final point.
    """

    def __init__(
            self,
            n: int,
            y: float,
            x: float,
            std: float,
            search_space: SearchSpace,
            chromosome: Chromosome = None
    ) -> None:
        """AB initialization."""
        self.n = n
        self.y = y
        self.x = x

        self.std = std

        self.search_space = search_space
        self.chromosome = chromosome if chromosome else self.initialize()

    def initialize(self) -> Chromosome:
        """Return a real-valued random vector constrained by the search space."""
        chromosome = []
        for _ in range(self.n - 1):
            value = self.y
            while value >= self.y:
                value = random.randint(*self.search_space)
            chromosome.append(value)
        return chromosome

    @property
    def fitness(self) -> float:
        """Compute AB's fitness based on Borschbach-Dreckmann."""
        total_sum = 0.0
        points = [self.y] + self.chromosome + [0]
        bin_width = self.x / self.n
        for i in range(self.n):
            si = np.sqrt(
                ((bin_width)**2) +
                ((points[i+1] - points[i])**2)
            )
            d = np.sqrt(self.y - points[i]) + np.sqrt(self.y - points[i+1])
            total_sum += si/d
        return total_sum


'''
  Module that contains the function that calculates a Local Outlier Factor.
  https://www.dbs.ifi.lmu.de/Publikationen/Papers/LOF.pdf
'''
import numpy

def distance(vector1, vector2):
    '''
    Euclidean distance.
    '''
    array1 = numpy.array(vector1)
    array2 = numpy.array(vector2)
    return numpy.linalg.norm(array1-array2)

def reach(candidate, k_distance, cluster_member, cluster):

    '''
    k-distance of candidate object p is defined as the distance d(p,o)
    between candidate p and an object o in cluster D such that:
        i)  For at least k objects o' in D/{p} d(p,o') <= d(p,o)
        ii) For at most k-1 objects o' in D/{p} d(p,o') < d(p,o)
    '''
    distances = list()
    for member in cluster:
        d = distance(candidate, member)
        if d > 0:
            distances.append(d)
    distances.sort()
    result = max(distances[:k_distance]) if distances[:k_distance] else 0.
    return max([result, distance(candidate, cluster_member)])

def local_reachability_density(test_point, k_distance, cluster):
    '''
    Local Reachability Density
    '''
    denominator = sum([reach(test_point, k_distance, member, cluster)
                       for member in cluster])
    return len(cluster)/denominator if denominator else 0.

def local_outlier_factor(test_point, k_distance, cluster):
    '''
    Return the LocalOutlierFactor for point 'p' compared
    to collection of reference points in 'D', using k-distance 'k'.
    '''
    ratios = list()
    for member in cluster:
        numerator = local_reachability_density(member,
                                               k_distance,
                                               cluster)

        denominator = local_reachability_density(test_point,
                                                 k_distance,
                                                 cluster)
        if denominator:
            ratios.append(numerator/denominator)

    result = sum(ratios)/float(len(ratios)) if ratios else 0.
    return result


from __future__ import division

import math
import numpy as np

from time import time

import sympy as sp

import mpmath as mp

from mpmath.ctx_mp_python import mpf

from scipy.misc import factorial
from scipy.special import gamma

precision = 53
mp.prec = precision
mp.pretty = True

def calculate_factorial_ratio(n, i):
	# This function calculates (n + i - 1)! / (n - i)!

	mp.dps = 50

	k = (n - i)

	result = 1
	for j in range(k + 2*i - 1, k, -1):
		result = mp.fmul(result, j)

	return result

def n_choose_k(n, k):

	j = n - k

	numerator = 1
	for i in range(1, k + 1):
		numerator *= (j + i)

	denominator = factorial(k)

	return numerator / denominator

def dirichlet_eta(s, N):

	def calculate_d_n(n):
		total = 0.0
		for k in range(n + 1):
			if k % 2 == 0:
				alternating_factor = 1
			else:
				alternating_factor = -1

			total += alternating_factor * n_choose_k(n, k) / ( k + 1)**s
		return total

	eta = 0.0
	for n in range(N + 1):
		d_n = calculate_d_n(n)
		eta += d_n / (2**(n + 1))

	return eta

def alternating_series(s, N):
	eta = dirichlet_eta(s, N)
	denominator = 1 - 2**(1 - s)
	zeta = eta / denominator

	return zeta

def riemann_siegel_theta(t):
	first_term = np.angle( gamma( (2.j*t + 1) / 4) )
	second_term = t * np.log(np.pi) / 2

	return first_term - second_term

def zeta_function(s, N):
	z = alternating_series(s, N)

	return z

def z_function(t, N=100000):
	zeta = zeta_function(1/2 + (1.j)*t, N)

	return mp.re( np.exp( 1.j * riemann_siegel_theta(t) ) * zeta )

def calculate_z(t):	# Convenient wrapper to use for roots.py
	return z_function(t, N=25)

if __name__ == '__main__':

	# print zeta_function(s=1/2 + 25.j, N=1000)
	# print z_function(t=18, N=100)

	start = time()

	eta = dirichlet_eta(1, N=25)
	print eta
	print abs(eta - np.log(2))

	end = time()

	print "Calculated using alternating series in {:.4f} seconds.".format(float(end - start))

import numpy,from scipy,import sympy,import mpmath,from mpmath


'''
The idea here is to have functions to analyse correlations between data.
y : data to be explained
x : explicative data
eps : random error
a, b : parameters to be estimated

Hypothesis A0:
y[i] is observed and random
x[i] is observed and not random
esp[i] is not observed and random

Hypothesis A1: errors are centered
E[esp[i]] = 0 for i = 1..n
E[y[i]] = 0 for i = 1..n (equivalent)

Hypothesis A2: Homogeneity of variances
Var(eps[i]) = sigma^2 for i = 1..n
Var(y[i]) = sigma^2 for i = 1..n (equivalent)

Hypothesis A3: esp[i] not correlated
Cov[esp[i], esp[j]] = 0 for i != j
Cov[esp[i], esp[j]] = 0 for i != j (equivalent)

Hypothesis A4: esp[i] normalised
esp[i] follow N(0, sigma^2)
'''

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

def average(x):
    res = 0
    n = 0
    for el in x:
        res += el
        n += 1
    return res/n

def cov(x, y):
    n = len(x)
    if n != len(y):
        return 'error: sizes of data are not matching'
    else:
        sum_x = 0
        sum_y = 0
        prod_mixte = 0
        for i in range(n):
            prod_mixte += x[i]*y[i]
            sum_x += x[i]
            sum_y += y[i]
        return (prod_mixte - sum_x * sum_y / n) / n

def var(x):
    return cov(x, x)

def coef_correlation(x, y):
    return cov(x, y)/np.sqrt(var(x)*var(y))

def linear_regression_coef(x, y):
    a = cov(x, y) / cov(x, x)
    b = average(y) - a * average(x)
    return a, b

class Regression:
    def __init__(self, x, y, model='linear'):
        self.model = model
        self.x = x
        self.y = y
        self.n = len(x)
        '''
        linear : y = a * x + b
        power : y = a * x ** b
        x, y : real data
        X, Y : linearized data
        y_approx : regression law applied to x
        Y_approx : regression law applied to X
        '''
        if self.model == 'power':
            self.X = np.log(self.x)
            self.Y = np.log(self.y)
            self.b, a_temp = linear_regression_coef(self.X, self.Y)
            self.a = np.exp(a_temp)
            self.eps = []
            self.y_approx = []
            self.Y_approx = []
            for k in range(self.n):
                self.eps.append(self.y[k] - self.a * self.x[k] ** self.b)
                self.y_approx.append(self.a * self.x[k] ** self.b)
                self.Y_approx.append(self.b * self.X[k] + a_temp)

        if self.model == 'linear':
            self.X = self.x
            self.Y = self.y
            self.a, self.b = linear_regression_coef(self.X, self.Y)
            self.eps = []
            self.y_approx = []
            self.Y_approx = []
            for k in range(self.n):
                self.eps.append(self.y[k] - self.a * self.x[k] - self.b)
                self.y_approx.append(self.a * self.x[k] + self.b)
                self.Y_approx.append(self.a * self.X[k] + self.b)

    def get_correlation(self):
        return coef_correlation(self.X, self.Y)

    def get_law(self):
        def create_fun(_a, _b, model):
            if model == 'linear':
                def fun(_x):
                    return _a * _x + _b
                return fun
            if model == 'power':
                def fun(_x):
                    return _a * _x ** _b
                return fun
        return create_fun(self.a, self.b, self.model)

    def get_str_law(self):
        if self.model == 'linear':
            return 'y = ' + str(np.round(self.a, decimals=4)) + ' * x + ' + str(np.round(self.b, decimals=4))

        if self.model == 'power':
            return 'y = ' + str(np.round(self.a, decimals=4)) + ' * x ^ ' + str(np.round(self.b, decimals=4))

    def get_sigma2(self):
        sigma2 = 0
        for el in self.eps:
            sigma2 += el ** 2
        sigma2 /= (self.n - 2)
        return sigma2

    def get_R2(self):
        return var(self.Y_approx)/var(self.Y)

    def plot(self):
        min_x = np.min(self.x)
        max_x = np.max(self.x)
        t = np.linspace(min_x, max_x, 500)
        fun_law = self.get_law()
        law_t = fun_law(t)
        legend = self.get_str_law() + '\n'\
            + 'R2 = ' + str(self.get_R2()) + '\n'\
            + 'sigma^2 = ' + str(self.get_sigma2())

        plt.figure()
        plt.scatter(self.x, self.y, color='black', marker='+')
        plt.plot(t, law_t, label=legend)
        plt.legend()
        plt.xlabel('X')
        plt.ylabel('Y')
        plt.show()

class DataAnalysis:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.regressions = []

    def regression(self, model='linear'):
        self.regressions.append(Regression(self.x, self.y, model))
        return 0

    def plot(self):
        min_x = np.min(self.x)
        max_x = np.max(self.x)
        t = np.linspace(min_x, max_x, 500)

        plt.figure()
        plt.scatter(self.x, self.y, color='black', marker='+')

        for regression in self.regressions:
            plt.scatter(self.x, regression.y_approx)
            fun_law = regression.get_law()
            law_t = fun_law(t)
            legend = regression.get_str_law() + '\n' \
                + 'R2 = ' + str(np.round(regression.get_R2(), decimals=4)) + '\n' \
                + 'sigma = ' + str(np.round(np.sqrt(regression.get_sigma2()), decimals=4))
            plt.plot(t, law_t, label=legend)
            plt.legend()

        plt.xlabel('X')
        plt.ylabel('Y')
        plt.show()

x0 = [28, 50, 55, 110, 60, 48, 70]
y0 = [130, 280, 268, 500, 320, 250, 400]
analyse = DataAnalysis(x0, y0)
analyse.regression('linear')
analyse.regression('power')
analyse.plot()


import numpy as np
import scipy.stats as stats

twain_data_str = ".225 .262 .217 .240 .230 .229 .235 .217"
snodgrass_data_str = ".209 .205 .196 .210 .202 .207 .224 .223 .220 .201"
twain_data = np.array([float(x) for x in twain_data_str.split()])
snodgrass_data = np.array([float(x) for x in snodgrass_data_str.split()])

# Wald test
twain_mu = twain_data.mean()
snodgrass_mu = snodgrass_data.mean()
diff_hat = twain_mu - snodgrass_mu
diff_se = np.sqrt(
    twain_data.var() / twain_data.size
    + snodgrass_data.var() / snodgrass_data.size
)

alpha = 0.05
z_alpha = stats.norm.ppf(1 - alpha / 2)
ci = (diff_hat - z_alpha * diff_se, diff_hat + z_alpha * diff_se)
w = np.abs(diff_hat - 0) / diff_se
p_value = 2 * stats.norm.cdf(-w)
print(
    "A 95% CI for the difference of means is given by",
    f"[{ci[0]:.3}, {ci[1]:.3}].",
)
print(f"The p-value for the Wald test is {p_value:.5f}.")

# permutation test
"""
The combined sample size is too large to iterate over all permutations,
so we sample instead.
"""
rng = np.random.default_rng()
joined_data = np.concatenate((twain_data, snodgrass_data))
twain_size = twain_data.size
b = 200000
positive_perms = 0
for _ in range(b):
    permuted_data = np.random.permutation(joined_data)
    perm_twain_data = permuted_data[:twain_size]
    perm_snodgrass_data = permuted_data[twain_size:]
    perm_diff = perm_twain_data.mean() - perm_snodgrass_data.mean()
    if perm_diff > diff_hat:
        positive_perms += 1

perm_p_value = positive_perms / b
print(f"The p-value for the permutation test is {perm_p_value:.5}.")


from numpy import random, pi
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

# Parameters
N = 10_000  # number of required points
Ntrials, Nhits = 0, 0
acc_x, acc_y, acc_z = [], [], []  # accepted x, y
rej_x, rej_y, rej_z = [], [], []  # rejected x, y

# Rejection Sampling
while Nhits < N:
    Ntrials += 1
    x, y, z = random.uniform(-1, 1, 3)

    if x**2 + y**2 + z**2 < 1:
        acc_x.append(x)
        acc_y.append(y)
        acc_z.append(z)
        Nhits += 1
    else:
        rej_x.append(x)
        rej_y.append(y)
        rej_z.append(z)

print("Total number of samples drawn %d" % Ntrials)
print("Number of samples in the disk %d" % N)

fig = plt.figure()
ax = fig.gca(projection='3d')

ax.scatter(acc_x, acc_y, acc_z, color = 'green', s = 1) # parameter s determines the size of each dot in the scatter plot
ax.scatter(rej_x, rej_y, rej_z, color = 'red', s = 1)

ax.set_xlim([-1, 1])
ax.set_ylim([-1, 1])
ax.set_zlim([-1, 1])
#ax.set_aspect('equal')  # set aspect ratio 1:1

plt.show()


"""
Content under Creative Commons Attribution license CC-BY 4.0,
code under MIT license (c)2018 Sergio Rojas (srojas@usb.ve)

http://en.wikipedia.org/wiki/MIT_License
http://creativecommons.org/licenses/by/4.0/

Created on march, 2018
Last Modified on: may 15, 2018

   This program finds the algebraic solution of the equation
   a*x + b = c*x + d
"""

from sympy import symbols, Eq, solveset
x, a, b, c, d = symbols('x, a, b, c, d')

LHS = a*x + b
RHS = c*x + d

thesol = list( solveset( Eq(LHS, RHS), x) )

#rearrange the equation to read: LHS - RHS = 0
newLHS = LHS - RHS

newLHS = newLHS.subs(x, thesol[0])

if newLHS.simplify() == 0:
   print('The solution of {0} = {1}, is x = {2}'.format(LHS,RHS,thesol[0]))


# Activation Functions(활성함수)
# This function introduces activation functions in Tensorflow

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

# Open graph session
sess = tf.Session()                                               # 항상 그렇듯이 이렇게 tensorflow graph를 실행해야 한다.

x_vals = np.linspace(start=-10., stop=10., num=100)

# ReLU activation       - 가장 일반적이고 널리 쓰임, max(0,x)와 같음
print(sess.run(tf.nn.relu([-3., 3., 10.])))
y_relu = sess.run(tf.nn.relu(x_vals))

# ReLU-6 activation         - min(max(0,x), 6)와 같음. CNN과 RNN에서 자주 쓰이는 함수 중 하나. 출력이 [0 3 6]이 된다.
print(sess.run(tf.nn.relu6([-3., 3., 10.])))
y_relu6 = sess.run(tf.nn.relu6(x_vals))

# Sigmoid activation          - smooth activation 중에서 가장 많이 사용되며 logistic function이라고도 불린다. 하지만 경사소실이 잦다. 0~1의 치역
print(sess.run(tf.nn.sigmoid([-1., 0., 1.])))
y_sigmoid = sess.run(tf.nn.sigmoid(x_vals))

# Hyper Tangent activation  - sigmoid와 같은 성ㅅ질을 가지지만, -1~1의 치역
print(sess.run(tf.nn.tanh([-1., 0., 1.])))
y_tanh = sess.run(tf.nn.tanh(x_vals))

# Softsign activation           - sign 함수의 부드러운 버젼. x / (abs(x)+1), -1~1의 치역
print(sess.run(tf.nn.softsign([-1., 0., 1.])))
y_softsign = sess.run(tf.nn.softsign(x_vals))

# Softplus activation           - ReLU 함수의 부드러운 버젼. log( exp(x)+1 ). 0~1의 치역
print(sess.run(tf.nn.softplus([-1., 0., 1.])))
y_softplus = sess.run(tf.nn.softplus(x_vals))

# Exponential linear activation(ELU)     - softplus와 비슷하지만, -1~1의 치역을 가진다. x <0 일 때 exp(x)+1, x >0 일 때 x
print(sess.run(tf.nn.elu([-1., 0., 1.])))
y_elu = sess.run(tf.nn.elu(x_vals))

# Plot the different functions
plt.plot(x_vals, y_softplus, 'r--', label='Softplus', linewidth=2)
plt.plot(x_vals, y_relu, 'b:', label='ReLU', linewidth=2)
plt.plot(x_vals, y_relu6, 'g-.', label='ReLU6', linewidth=2)
plt.plot(x_vals, y_elu, 'k-', label='ExpLU', linewidth=0.5)
plt.ylim([-1.5,7])
plt.legend(loc='top left')
plt.show()

plt.plot(x_vals, y_sigmoid, 'r--', label='Sigmoid', linewidth=2)
plt.plot(x_vals, y_tanh, 'b:', label='Tanh', linewidth=2)
plt.plot(x_vals, y_softsign, 'g-.', label='Softsign', linewidth=2)
plt.ylim([-2,2])
plt.legend(loc='top left')
plt.show()


import numpy as np
import random

def gen(var,n,m):
        beta = np.random.randint(9,size=m+1)
        X = np.random.rand(n,m+1)
        X[:,0] = 1
        h = np.dot(X, beta)
        e = np.random.normal(0,var,n)
        Y = h #+ e
        X = np.delete(X,0,1)
        print("this is known beta")
        print(beta)
        return beta, X, Y

def costf(x,y,beta,m,n):
        h = np.dot(x, beta)
        r = h - y
        return (1/(2*n))*(np.dot(r, r))**2

def grad_desc(X,Y,beta,alpha,k,n,m):
    for i in range(k+1):
        temp = X
        temp = np.transpose(temp)
        h = np.dot(X, beta)
        #print("hey this is h-y",h-Y)
        #beta = beta - (alpha/n)*np.sum(np.dot((h - Y), temp))
        beta = beta - (alpha/n)*((np.sum(np.transpose((h-Y)*np.transpose(X)),axis=0)))
        #print(costf(X,Y,beta,n,m))
    print("this is after descending the slope")
    print(beta)

    return beta

def lin_reg(X,Y,k,alpha):
    #add x_0 = 1
    #X[:,0] = 1
    m = len(X[0,:])
    n = len(X[:,0])
    X = np.append(np.ones(len(X[:,0]))[...,None],X,1)
    beta = np.zeros(m+1)
    beta = grad_desc(X,Y,beta,alpha,k,n,m)
    return beta #, cost(X,Y,beta,m,n)

beta,X,Y = gen(0.5,6,5)

k = 100000
alpha = 0.1
lin_reg(X,Y,k,alpha)


from superdifferentiator.forward.functions import X
import numpy as np
import math

def bgfs(f, init_x, accuracy = 1e-8, alphas =[.00001,.00005,.0001,.0005,0.001,0.005,0.01,0.05,0.1,0.5,1,5],
         max_iter = 1000,verbose = False):

    x_current = [X(init_x[i],'x'+str(i)) for i in  range(len(init_x))]
    B = np.eye(len(init_x))

    for i_iter in range(max_iter):
        func = f(x_current)
        f_jac = func.jacobian()[1][0].T
        p = -np.linalg.pinv(B) @f_jac

        f_minmin = 10**13
        alpha_minmin = .00001
        for alpha in alphas:
            f_min = f([x_current[i] + alpha * p[i,0] for i in range(len(x_current))])
            if f_min.val[0] < f_minmin:
                f_minmin = f_min.val[0]
                alpha_minmin = alpha

        if math.isnan(float(p[0])):
            print("It doesn't converge using bgfs! Please use some other methods or check if a maximum/minimum exists!")
            return [x_current[i].val[0] for i in range(len(x_current))]

        s = alpha_minmin * p
        if np.linalg.norm(s) <= accuracy:
            print('Since the shifted distance is smaller than {}, we stop the loop at {}th iteration.'.format(accuracy,i_iter))
            break
        x_current = [x_current[i] + alpha_minmin * p[i,0] for i in range(len(x_current))]
        if verbose:
            print('At {}th iteration, current x value is: '.format(i_iter),[x_current[i].val[0] for i in range(len(x_current))],
                  ', the step taken is: ',s,'.\n' )
        y_current = f(x_current).jacobian()[1][0].T - f_jac

        B += y_current.dot(y_current.T)/(y_current.T.dot(s)) - B.dot(s).dot(s.T).dot(B.T)/(s.T.dot(B).dot(s))

    final_del = [x_current[i].val[0] for i in range(len(x_current))]
    if i_iter == max_iter-1:
        print("Notice that the change in distance of x is still larger than input accuracy! It probably doesn't converge using bgfs! ")
    if verbose:
        print('The final value we get is',final_del,'.')
    return final_del


"""
Lun. 12 Sep 2018

Author: Abdollah RIDA
"""

#IMPORTING LIBS

import numpy as np
import scipy.stats as si
import matplotlib.pyplot as plt

#Helper functions:

def d_m(x, v):
    d_ = np.log(x) / np.sqrt(v) - .5 * np.sqrt(v)
    return d_

#Q1-a

def C0(r, T, S0, K, sigma):

    X0 = S0 / (K * np.exp(-r*T))

    C = si.norm.cdf(- d_m(X0, sigma**2 * T))

    return np.exp(-r*T) * C

def Delta0(r, T, S0, K, sigma):

    X0 = S0 / (K * np.exp(-r*T))

    D = si.norm.pdf(- d_m(X0, sigma**2 * T))

    return - np.exp(-r*T) * D / (S0 * np.sqrt(sigma**2 * T))

#Q1-b

def Brownian(n, i, T):
	#We fist define the time step Dt
    dt = T/n

    #We then create an array of i drawings following N(0, Dt)
    z = np.random.normal(0, 1, i) * np.sqrt(dt)

    #We specify W_0 = 0
    z[0] = 0

    #We then compute the cumulative sums to obtain W
    W = np.cumsum(z)
    return list(W)

def S_(r, sigma, S0, T, n, W):
    S__ = []

    for i in range(n):
    	S__ += [S0 * np.exp((r - sigma**2 / 2) * i * T/n + sigma * W[i])]

    return S__

def MC_C(r, T, S0, K, sigma, M, n):
    Ind_ = []

    for k in range(M):
        W = Brownian(n, n, T)
        S_T = S_(r, sigma, S0, T, n, W)[-1]
        if S_T <= K:
            Ind_ += [1]
        else:
            Ind_ += [0]

    Ind_ = np.array(Ind_)
    Esp = np.cumsum(Ind_)[-1] / M

    return np.exp(-r * T) * Esp

def Diff_Delta0(r, T, S0, K, sigma, M, n, epsilon):
    return (MC_C(r, T, S0 + epsilon, K, sigma, M, n) - MC_C(r, T, S0 - epsilon, K, sigma, M, n))/ (2 * epsilon)

def MC_Delta(r, T, S0, K, sigma, M, n):
    Ind_ = []

    for k in range(M):
        W = Brownian(n, n, T)
        S_T = S_(r, sigma, S0, T, n, W)[-1]
        if S_T <= K:
            Ind_ += [W[-1] / (S0 * sigma * T)]
        else:
            Ind_ += [0]

    Ind_ = np.array(Ind_)
    Esp = np.cumsum(Ind_)[-1] / M

    return np.exp(-r * T) * Esp


import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

# create a relatively long impulse response
inputSignal = np.zeros(2048)
# make the first sample == 1
inputSignal[0] = 1
# use this container to get a copy of the b and a coefficiencts for each 4th order filter
filterSystems = []

# ---------- butterworth filter ----------
bArray = [] # for b coeffecients
aArray = [] # for a coeffecients
wArray = [] # for omega
hArray = [] # for H
orderArray = [1, 2, 4, 5] # orders to use
omega_c = 0.25 # cutoff frequency

for i in orderArray:
    b, a = signal.butter(N=i, Wn=omega_c)
    if i == 4:
        filterSystems.append([b,a])
    w, h = signal.freqz(b, a)
    bArray.append(b)
    aArray.append(a)
    wArray.append(w)
    hArray.append(h)

fig = plt.figure(figsize=(16, 9))
for index in range(len(orderArray)):
    plt.plot(wArray[index], 20 * np.log10(abs(hArray[index])), label="order = " + str(orderArray[index]))
plt.title('Butterworth Filter Frequency Response: Comparison')
plt.xlabel('Frequency [up to Nyquist]')
plt.xlim([0, np.pi])
plt.ylim([-60, 12])
plt.ylabel('Amplitude [dB]')
plt.grid(which='both', axis='both')
plt.axvline(omega_c*np.pi, color='black') # cutoff frequency
plt.legend()
plt.savefig('Butterworth.png')

# ---------- chebyshev 1 ----------
bArray = []
aArray = []
wArray = []
hArray = []
orderArray = [1, 2, 4, 5]
omega_c = 0.25
for i in orderArray:
    b, a = signal.cheby1(N=i, rp=6, Wn=omega_c)
    if i == 4:
        filterSystems.append([b,a])
    w, h = signal.freqz(b, a)
    bArray.append(b)
    aArray.append(a)
    wArray.append(w)
    hArray.append(h)

fig = plt.figure(figsize=(16, 9))
for index in range(len(orderArray)):
    plt.plot(wArray[index], 20 * np.log10(abs(hArray[index])), label="order = " + str(orderArray[index]))
plt.title('Chebyshev Type 1 Filter Frequency Response: Comparison')
plt.xlabel('Frequency [up to Nyquist]')
plt.xlim([0, np.pi])
plt.ylim([-60, 12])
plt.ylabel('Amplitude [dB]')
plt.grid(which='both', axis='both')
plt.axvline(omega_c*np.pi, color='black') # cutoff frequency
plt.legend()
plt.savefig('ChebyshevT1.png')

# ---------- chebyshev 2 ----------
bArray = []
aArray = []
wArray = []
hArray = []
orderArray = [1, 2, 4, 5]
omega_c = 0.25
for i in orderArray:
    b, a = signal.cheby2(N=i, rs=54, Wn=omega_c)
    if i == 4:
        filterSystems.append([b,a])
    w, h = signal.freqz(b, a)
    bArray.append(b)
    aArray.append(a)
    wArray.append(w)
    hArray.append(h)

fig = plt.figure(figsize=(16, 9))
for index in range(len(orderArray)):
    plt.plot(wArray[index], 20 * np.log10(abs(hArray[index])), label="order = " + str(orderArray[index]))
plt.title('Chebyshev Type 2 Filter Frequency Response: Comparison')
plt.xlabel('Frequency [up to Nyquist]')
plt.xlim([0, np.pi])
plt.ylim([-60, 12])
plt.ylabel('Amplitude [dB]')
plt.grid(which='both', axis='both')
plt.axvline(omega_c*np.pi, color='black') # cutoff frequency
plt.legend()
plt.savefig('ChebyshevT2.png')

# ---------- elliptic ----------
bArray = []
aArray = []
wArray = []
hArray = []
orderArray = [1, 2, 4, 5]
omega_c = 0.25
for i in orderArray:
    b, a = signal.ellip(N=i, rp=6, rs=54, Wn=omega_c)
    if i == 4:
        filterSystems.append([b,a])
    w, h = signal.freqz(b, a)
    bArray.append(b)
    aArray.append(a)
    wArray.append(w)
    hArray.append(h)

fig = plt.figure(figsize=(16, 9))
for index in range(len(orderArray)):
    plt.plot(wArray[index], 20 * np.log10(abs(hArray[index])), label="order = " + str(orderArray[index]))
plt.title('Elliptic Filter Frequency Response: Comparison')
plt.xlabel('Frequency [up to Nyquist]')
plt.xlim([0, np.pi])
plt.ylim([-60, 12])
plt.ylabel('Amplitude [dB]')
plt.grid(which='both', axis='both')
plt.axvline(omega_c*np.pi, color='black') # cutoff frequency
plt.legend()
plt.savefig('Elliptic.png')

# ---------- graph the impulse responses ----------
names = ["Butterworth","Chebyshev T1","Chebyshev T2","Elliptic"]
fig = plt.figure(figsize=(16, 9))
nameIndex = 0
for coef in filterSystems:
    fImpulse = signal.lfilter(coef[0], coef[1], inputSignal) # calculate impulse response
    plt.plot(fImpulse, label=names[nameIndex])
    nameIndex += 1
plt.title('Compare 4th Order Filter Impulse Response')
plt.xlabel('Time [samples]')
plt.xlim([0, 128])
plt.ylabel('Amplitude')
plt.grid(which='both', axis='both')
plt.legend()
plt.savefig('CompareFilterTime.png')


import numpy as np
import cvxpy as cp
from geometry import Ellipsoid

def cvx_ellipsoid(A, b):
    dim = len(A[0])
    m = len(b)
    C = cp.Variable((dim, dim), symmetric=True)
    d = cp.Variable(dim)
    objective = cp.Maximize(cp.atoms.log_det(C))
    constraints = [C >> 0.]
    constraints += [cp.atoms.norm(C @ A[i].T, 2) + A[i] @ d <= b[i] for i in range(m)]

    prob = cp.Problem(objective, constraints)
    prob.solve(verbose=True)
    # return C.value, d.value, prob.value
    return Ellipsoid(dim, C.value, d.value), prob.value

if __name__ == '__main__':
    #Vertices of a pentagon in 2D
    p = [[0., 0.], [1., 3.], [5.5, 4.5], [7., 4.], [7., 1.], [3., -2.]]
    nVerts = len(p)

    #The hyperplane representation of the same polytope
    A = [[-p[i][1] + p[i - 1][1], p[i][0] - p[i - 1][0]]
         for i in range(len(p))]
    b = [A[i][0] * p[i][0] + A[i][1] * p[i][1] for i in range(len(p))]
    A = np.array(A)
    b = np.array(b)

    # Po, co = lownerjohn_outer(p)
    ellipsoid, volume = cvx_ellipsoid(A, b)
    print(ellipsoid.C_, ellipsoid.d_, volume)

    #Visualization
    try:
        import numpy as np
        import matplotlib
        matplotlib.use('Agg')
        import matplotlib.pyplot as plt
        import matplotlib.patches as patches

        #Polygon
        fig = plt.figure()
        ax = fig.add_subplot(111)
        ax.add_patch(patches.Polygon(p, fill=False, color="red"))
        #The inner ellipse
        theta = np.linspace(0, 2 * np.pi, 100)
        Ci, di = ellipsoid.C_, ellipsoid.d_
        x = Ci[0][0] * np.cos(theta) + Ci[0][1] * np.sin(theta) + di[0]
        y = Ci[1][0] * np.cos(theta) + Ci[1][1] * np.sin(theta) + di[1]
        ax.plot(x, y)
        #The outer ellipse
        # x, y = np.meshgrid(np.arange(-1.0, 8.0, 0.025), np.arange(-3.0, 6.5, 0.025))
        # ax.contour(x, y, (Po[0][0] * x + Po[0][1] * y - co[0])**2 + (Po[1][0] * x + Po[1][1] * y - co[1])**2, [1])
        # ax.autoscale_view()
        ax.xaxis.set_visible(False)
        ax.yaxis.set_visible(False)
        fig.savefig('ellipsoid.png')
    except:
        print("Inner:")
        print("  C = ", Ci)
        print("  d = ", di)
        # print("Outer:")
        # print("  P = ", Po)
        # print("  c = ", co)


import matplotlib.pylab as pylab
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import animation
from scipy.integrate import odeint
from pylab import plot,xlabel,ylabel,title,legend,figure,subplots
from pylab import cos, pi, arange, sqrt, pi, array, array

def MassSpringDamper(state,t):

    k=2.714;            # spring constant (N/m)
    c=0.437;           #damping coefficient (Ns/m)
    m=4.871;             # mass (kg)
    # unpack the state vector
    x,xd = state # displacement,x and velocity x'
    # compute acceleration xdd = x''
    # Force F is a sinusoidal with below parameters

    A = 5.0 # amplitude
    xdd = -k*x/m -c*xd + A*cos(2*pi*t)
    return [xd, xdd]

z = input("input initial Displacement Z")
z = float(z)
print(z)
state0 = [z, 0]
ti = 0.0
tf = 4.0  # final time
step = 0.001  # step
t = arange(ti, tf, step)
state = odeint(MassSpringDamper, state0, t)
x = array(state[:,[0]])
xd = array(state[:,[1]])

# Plotting displacement and velocity
pylab.rcParams['figure.figsize'] = (15, 12)
pylab.rcParams['font.size'] = 18

fig, ax1 = pylab.subplots()
ax2 = ax1.twinx()
ax1.plot(t,x*1e3,'b',label = r'$x (mm)$', linewidth=2.0)
ax2.plot(t,xd,'g--',label = r'$\dot{x} (m/sec)$', linewidth=2.0)
ax2.legend(loc='lower right')
ax1.legend()
ax1.set_xlabel('time , sec')
ax1.set_ylabel('disp (m)',color='b')
ax2.set_ylabel('velocity (m/s)',color='g')
pylab.title('Mass-Spring System')
pylab.grid()
pylab.show()

fig = plt.figure()
fig.set_dpi(50)
fig.set_size_inches(7, 6.5)
a=np.arange(1,10,0.1)
animati=[]
ax = plt.axes(xlim=(-3, 3), ylim=(0, 1))
patch = plt.Rectangle((1, 0),0.8, 0.2, fc='g')
animati.append(patch)
l1,=ax.plot([],[],lw=2,color='k')
animati.append(l1)
l2,=ax.plot([],[],lw=2,color='b')
animati.append(l2)

def init():
    animati[0].set_xy([state0[0],0])
    ax.add_patch(animati[0])
    animati[1].set_data([],[])
    animati[2].set_data([],[])
    return animati

def animate(i):
    animati[0].set_xy([x[i],0])
    animati[1].set_data([-5,x[i]],[0.05,0.05])
    animati[2].set_data([-5,x[i]],[0.15,0.15])
    return animati

anim = animation.FuncAnimation(fig, animate,
                               init_func=init,
                               frames=10000,
                               interval=0.00001,
                               blit="True")

plt.show()

Design Study Assignment 1/sineSignalInputCart.py


from scipy import linalg
import numpy as np
import matplotlib.cm as cm
from matplotlib.mlab import bivariate_normal
import matplotlib.pyplot as plt
# %matplotlib inline

# == Set up the Gaussian prior density p == #
Σ = [[0.3**2, 0.0], [0.0, 0.3**2]]
Σ = np.matrix(Σ)
x_hat 	 = np.matrix([0.5, -0.5]).T
# == Define the matrices G and R from the equation y = G x + N(0, R) == #
G = [[1, 0], [0, 1]]
G = np.matrix(G)
R = 0.5 * Σ
# == The matrices A and Q == #
A = [[1.0, 0], [0, 1.0]]
A = np.matrix(A)
Q = 0.3 * Σ
# == The observed value of y == #
y = np.matrix([2.3, -1.9]).T

# == Set up grid for plotting == #
x_grid = np.linspace(-1.5, 2.9, 100)
y_grid = np.linspace(-3.1, 1.7, 100)
X, Y = np.meshgrid(x_grid, y_grid)

def gen_gaussian_plot_vals(μ, C):
    "Z values for plotting the bivariate Gaussian N(μ, C)"
    m_x, m_y = float(μ[0]), float(μ[1])
    s_x, s_y = np.sqrt(C[0, 0]), np.sqrt(C[1, 1])
    s_xy = C[0, 1]
    return bivariate_normal(X, Y, s_x, s_y, m_x, m_y, s_xy)

fig, ax = plt.subplots(figsize=(10, 8))
ax.grid()

# Plot the figure
# Density 1
Z = gen_gaussian_plot_vals(x_hat, Σ)
cs1 = ax.contour(X, Y, Z, 6, colors="black")
ax.clabel(cs1, inline=1, fontsize=10)

# Density 2
#Kalman Gain
K = Σ * G.T * linalg.inv(G * Σ * G.T + R)
# Update the state estimate
x_hat_F = x_hat + K*(y - G * x_hat)
#update covariance estimation
Σ_F = Σ - K * G * Σ
Z_F = gen_gaussian_plot_vals(x_hat_F, Σ_F)
cs2 = ax.contour(X, Y, Z_F, 6, colors="black")
ax.clabel(cs2, inline=1, fontsize=10)

# Density 3
# Predict next state of the feature with the last state and predicted motion
#https://stackoverflow.com/questions/14058340/adding-noise-to-a-signal-in-python
new_x_hat = A * x_hat_F
# print(new_x_hat)
#predict next covariance
new_Σ = A * Σ_F * A.T + Q
new_Z = gen_gaussian_plot_vals(new_x_hat, new_Σ)
cs3 = ax.contour(X, Y, new_Z, 6, colors="black")
ax.clabel(cs3, inline=1, fontsize=10)
ax.contourf(X, Y, new_Z, 6, alpha=0.6, cmap=cm.jet)
ax.text(float(y[0]), float(y[1]), "$y$", fontsize=20, color="black")

plt.show()
dt = 33.3e-3
#state update matrices
A = np.matrix( ((1, 0, dt, 0),(0, 1, 0, dt),(0, 0, 1, 0),(0, 0, 0, 1)) )
Q = np.matrix( (30, 68, 0, 0) ).transpose()
B = np.matrix( ((dt**2/2),(dt**2/2), dt, dt)).transpose()
C = np.matrix( ((1,0,0,0),(0,1,0,0)) ) #this is our measurement function C, that we apply to the state estimate Q to get our expect next/new measurement
Q_estimate = Q
u = .005 #define acceleration magnitude

marker_noise_mag = .1; #process noise: the variability in how fast the Hexbug is speeding up (stdv of acceleration: meters/sec^2)
tkn_x = 1;  #measurement noise in the horizontal direction (x axis).
tkn_y = 1;  #measurement noise in the horizontal direction (y axis).
Ez = np.matrix(((tkn_x,0),(0,tkn_y)))
Ex = np.matrix( ((dt**4/4,0,dt**3/2,0),(0,dt**4/4,0,dt**3/2),(dt**3/2,0,dt**2,0),(0,dt**3/2,0,dt**2)) )*marker_noise_mag**2# Ex convert the process noise (stdv) into covariance matrix
P = Ex; # estimate of initial Hexbug position variance (covariance matrix)

# Predict next state of the Hexbug with the last state and predicted motion.
Q_estimate = A*Q_estimate + B*u;
# predic_state = [predic_state; Q_estimate(1)] ;
# predict next covariance
P = A*P*A.T + Ex;
# predic_var = [predic_var; P] ;
# predicted Ninja measurement covariance
# Kalman Gain
K = P*C.T*linalg.inv(C*P*C.T + Ez);
# Update the state estimate
x_avg = 32
y_avg = 70
Q_loc_meas = np.matrix( (x_avg, y_avg) ).transpose()
Q_estimate = Q_estimate + K * (Q_loc_meas - C*Q_estimate);
print(Q_estimate)
# update covariance estimation.
P = (np.identity(4) - K*C)*P;

import csv

float_list = [1.13, 0.25, 3.28]

# with open('ANN_0.csv', "w") as file:
#     writer = csv.writer(file, delimiter=',')
#     writer.writerow(Ez)

outfile = open('./ANN_0.csv','w')
writer=csv.writer(outfile)
writer.writerow(float_list)
# writer.writerow(['SNo', 'States', 'Dist', 'Population'])
# writer.writerows(list_of_rows)
writer.writerow(float_list)
writer.writerow(float_list)
writer.writerow(float_list)
writer.writerow(float_list)


import numpy as np

class LeastSquares:

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

    def lin_matrix(self):
        one_arr = np.ones([self.data.size,1]) #array of ones concatenated to matrices
        lin = np.hstack([one_arr, self.data]) #appending array of ones to array of data matrix
        return lin

    def quad_matrix(self):
        lin = self.lin_matrix()
        quad = np.hstack([lin,self.data**2]) #appending lin to array of data squared
        return quad

    def cub_matrix(self):
        quad = self.quad_matrix()
        cub = np.hstack([quad,self.data**3]) ##appending quad to array of data cubed
        return cub

    def pow_matrix(self):
        one_arr = np.ones([self.data.size,1])
        pow_m = np.hstack([one_arr,np.log(self.data)]) #appending array of ones to array of log xvalues
        return pow_m

    #parameters data_matrix, y points, and noise covariance
    #returns y_model, x_bar (parameters for fit) and error covariance
    def ymodel(self,data_matrix,yval,noise_cov=None):
        if noise_cov == None:
            noise_cov = np.identity(data_matrix.shape[0])

        #calculating parameters
        dot_matrix = np.dot(data_matrix.T,np.linalg.inv(noise_cov)) #Step 1
        doty_matrix = np.dot(dot_matrix,yval) #Step 2
        inv_matrix = np.linalg.inv(np.dot(dot_matrix,data_matrix)) #Step 3
        x_bar = np.dot(inv_matrix, doty_matrix) #Step 4
        predict_y = np.dot(data_matrix, x_bar) #Step 5
        return predict_y, x_bar, inv_matrix

    def coef(self,data_matrix,yval,noise_cov=None):
        predict_y,x_bar,inv_matrix = self.ymodel(data_matrix,yval)
        return x_bar

    #args extended data_matrix (with extra x points added), y points, index where actual data begins in data_matrix_extend
    #returns y_model, x_bar (parameters for fit) and error covariance
    def ymodel_extend(self,data_matrix_extend,yval,index_begin_x):
        data_matrix = data_matrix_extend[index_begin_x:] #slicing array to section with only x values from data
        predict_y,x_bar,inv_matrix = self.ymodel(data_matrix,yval)
        predict_y = np.dot(data_matrix_extend, x_bar)
        return predict_y,x_bar,inv_matrix

    def error_bar(self,err_cov):
        err = np.sqrt(np.diag(err_cov)) #taking the square root of the diagonal of V
        return err


import numpy as np
import matplotlib.pyplot as plt

def f(x) :

    s = np.power(x,3) + 4*np.power(x,2) - 10

    return s

def Bisection(a,b,Tol,Nmax) :

    Fa = f(a);Fb = f(b)
    d = b - a
    c = a + d/2
    Fc = f(c)
    n = 1
    d = d/2
    while n < Nmax and Fc != 0 and d > Tol :
          if np.sign(Fa) == np.sign(Fc) :
             a = c
             Fa = Fc
          else :
             b = c
             Fb = Fc

          c = a + d/2
          Fc = f(c)
          d = d/2
          n += 1

    return c,n,d,Fc

#------------ MAIN PROGRAMME -------------#
a=1;b=2 ;Tol=10**(-8) ;Nmax=100
c,n,d,Fc = Bisection(a,b,Tol,Nmax)

print ('Number of steps is ' , n )
print ('Approximation is' , c )
print ('The value of function is' , Fc )
print ('Distance from root less than ' , d)

t=np.linspace(1,2,100)
y=f(t)

plt.plot(t,y,'orange')
plt.legend(['f(x)'])
plt.ylabel('y')
plt.xlabel('x')
plt.show()