#! /usr/bin/env python

"""
File: adaptive_trapezint.py
Copyright (c) 2016 Austin Ayers
License: MIT

Course: PHYS227
Assignment: 3.8
Date: Feb 11, 2016
Email: ayers111@mail.chapman.edu
Name: Austin Ayers
Description: Adaptive trapezoidal rule that decides how many trapezoids to use in order to achieve a desierd accuracy
"""
import numpy as np

def II_derivative_max(f, a, b, n=654321):
    """
    Calculates the maximum of the second derivative using many points: 654,321 of them to find the max of those points.
    """
    delta = (b - a) / float(n)
    max = abs(II_derivative(f, a))
    for i in range(n):
        current = abs(II_derivative(f, a + delta * (i + 1)))
        if current > max:
            max = current
    return max

def II_derivative(f, x, h=1e-6):
    return (f(x - h) - 2 * f(x) + f(x + h)) / float(h**2)

def trapezint(f, a, b, n):
    """
    Function from excercise 3.6
    """
    h = (b-a) / float(n)
    sum = 0
    for i in range(int(n)):
        sum = sum + (1/2.0)*h*(f(a + h*i) + f(a + h*(i + 1)))
    return sum

def adaptive_trapezint(f, a, b, eps=1E-5):
    """
    Adaptive trapezoidal rule that decides how many trapezoids to use in order to achieve a desierd accuracy
    """
    h = np.sqrt(12*eps)*(((b-a)*II_derivative_max(f, a, b))**(-1/2.0))
    n = (b-a)/float(h)
    return (trapezint(f, a, b, n), n)

def outputInformation():
    """
    Outputs the information of the exact error and estimated n for each case of adaptive_trapezint(f, a, b, eps=1E-5)
    """
    cos1 = adaptive_trapezint(cos, 0, np.pi)
    sin1 = adaptive_trapezint(sin, 0, np.pi)
    sin2 = adaptive_trapezint(sin, 0, np.pi/2)

    error1 = abs(cos1[0]-0)
    error2 = abs(sin1[0]-2)
    error3 = abs(sin2[0]-1)

    print("Function\tError\t\t\tEstimated n")
    print("Cos [0,Pi]\t" + str(error1) + "\t" + str(cos1[1]))
    print("Sin [0,Pi]\t" + str(error2) + "\t" + str(sin1[1]))
    print("Sin [0,Pi/2]\t" + str(error3) + "\t" + str(sin1[1]))
def line(x):
    return 2*x + 2
def sin(x):
    return np.sin(x)
def cos(x):
    return np.cos(x)

def test_trap_rule():
    """
    Area of a triangle = 1/2*b*h = 8 for the line 2x+2 integrated from 0 to 2
    """
    print(abs(trapezint(line, 0, 2, 100)))
    assert (abs(trapezint(line, 0, 2, 100) - 8) < 1E-5)


import numpy as np
import pandas as pd

def accuracy_score(y_true, y_pred):
    '''Class performance metric that computes the accuracy and y_pred'''
    correct = 0
    for true, pred in zip(y_true, y_pred):
        if true == pred:
            correct += 1                                  # Counts the correct predictions
    accuracy = correct/len(y_true)
    return accuracy

def mse(y_true, y_pred, squared = True):
    '''Mean squared error regression loss funcion.
    Parameters

    :param numpy.array y_true: array-like of shape(n_samples,)
        Ground truth (correct) target values
    :param numpy.array y_pred: array-like of shape(n_samples,)
        Estimated target values
    _param bool squared: If True resturns MSE, if false returns RMSE'''
    y_true = np.array(y_true)
    y_pred = np.array(y_pred)
    errors = np.average((y_true-y_pred)**2, axis = 0)
    if not squared:
        errors = np.sqrt(errors)
    return np.average(errors)

def mse_prime(y_true, y_pred):
    return 2*(y_pred-y_true)/y_true.size

def cross_entropy(y_true, y_pred):
    return -(y_true * np.log(y_pred)).sum()

def cross_entropy_prime(y_true, y_pred):
    return y_pred - y_true

def r2_score(y_true, y_pred):
    """
    R^2 regression score function.
        R^2 = 1 - SS_res / SS_tot
    where SS_res is the residual sum of squares and SS_tot is the total
    sum of squares.
    :param numpy.array y_true : array-like of shape (n_samples,) Ground truth (correct) target values.
    :param numpy.array y_pred : array-like of shape (n_samples,) Estimated target values.
    :returns: score (float) R^2 score.
    """
    # Residual sum of squares
    numerator = ((y_true - y_pred) ** 2).sum(axis=0)
    # Total sum of squares
    denominator = ((y_true - np.average(y_true, axis=0)) ** 2).sum(axis=0)
    # R^2
    score = 1 - numerator / denominator
    return score

def mse(y_true, y_pred):
    """
    Mean squared error regression loss function.
    Parameters
    :param numpy.array y_true: array-like of shape (n_samples,)
        Ground truth (correct) target values.
    :param numpy.array y_pred: array-like of shape (n_samples,)
        Estimated target values.
    :returns: loss (float) A non-negative floating point value (the best value is 0.0).
    """
    return np.mean(np.power(y_true-y_pred, 2))

class ConfusionMatrix:

    def __init__(self, true_y, predict_y):
        '''Confusion Matrix implementation for the
        evaluation of the performance model by comparing the true vs the predicted values.'''
        self.true_y = np.array(true_y)
        self.predict_y = np.array(predict_y)

    def build_matrix(self):
        import pandas as pd

        # Computing a cross tabulation - frequency table of the factors
        cm = pd.crosstab(self.true_y,self.predict_y, rownames = ["True values"], colnames = ["Predicted values"])
        return cm

    def toDataframe(self):
        import pandas as pd
        return pd.DataFrame(self.build_matrix())


'''
Assortativity measures the similarity of connections in the graph with respect to the node degree.

Associative mixing by degree can be quantified in a number of ways, one of them is to use the correlation coefficient.

Graphs that have only single edges between vertices tend in the absence of other biases to show disassortative mixing by degree because the number of edges that can fall between high-degree vertex pairs is limited. Since most networks are represented as simple graphs this implies that most should be disassortative.

'''

import networkx as nx

def calculate(network):
    try:
        n = nx.degree_assortativity_coefficient(network)
    except:
        n = 0
    return round(n,7)


"""
Module for computing vertical motion
characteristics for a projectile.
"""
def y(v0, t):
    """
    Compute vertical position at time t, given the initial vertical
    velocity v0. Assume negligible air resistance.
    """
    g = 9.81
    return v0*t - 0.5*g*t**2

def time_of_flight(v0):
    """
    Compute time in the air, given the initial vertical
    velocity v0. Assume negligible air resistance.
    """
    g = 9.81
    return 2*v0/g

def max_height(v0):
    """
    Compute maximum height reached, given the initial vertical
    velocity v0. Assume negligible air resistance.
    """
    g = 9.81
    return v0**2/(2*g)

def application():
    import numpy as np
    import matplotlib.pyplot as plt
    import sys

    print("""This program computes vertical motion characteristics for a
    projectile. Given the intial vertical velocity, it computes height
    (as it develops with time), maximum height reached, as well as time
    of flight.""")

    try:
        v_initial = float(input('Give the initial velocity: '))
    except:
        print('You must give a valid number!')
        sys.exit(1)

    H = max_height(v_initial)
    T = time_of_flight(v_initial)
    print('Maximum height: {:g} m, \nTime of flight: {:g} s'.format(H, T))

    # compute and plot position as function of time
    dt = 0.001
    # just pick a "small" time step
    N = int(T/dt)
    # number of time steps
    t = np.linspace(0, N*dt, N+1)
    position = y(v_initial, t)
    # compute all positions (over T)
    plt.plot(t, position, 'b--')
    plt.xlabel('Time (s)')
    plt.ylabel('Vertical position (m)')
    plt.show()
    return

if __name__ == '__main__':
    application()


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Numerical differentiation."""

import numpy as np

from jpy.maths.matrix import tridiag

def make_stencil(n, i, i_, _i):
    """Create a tridiagonal stencil matrix of size n.
    Creates a matrix to dot with a vector for performing discrete spatial computations.
    i, i_ and _i are multipliers of the ith, i+1 and i-1 values of the vector respectively.
    e.g. to calculate an average at position i based on neighbouring values:
    >>> s = make_stencil(N, 0, 0.5, 0.5)
    >>> avg_v = np.dot(s, v)
    The stencil has periodic boundaries.

    Returns an nxn matrix.
    """
    m = tridiag(n, i, i_, _i)
    m[-1,0] = i_
    m[0,-1] = _i
    return m

def make_central_difference1(n, dx):
    """Returns a function dfdx that calculates the first derivative
    of a list of values discretised with n points of constant separation dx.
    >>> x = np.arange(0, 1, 0.01)
    >>> y = np.sin(2*np.pi*x)
    >>> dfdx = make_central_difference1(len(x), 0.01)
    >>> dfdx(y)  #=> ~ 2π cos(2πx)"""
    m = make_stencil(n, 0, 1, -1) / (2*dx)
    def dfdx(phi):
        return np.dot(m, phi)
    return dfdx

def make_central_difference2(n, dx):
    """Returns a function df2dx that calculates the second derivative
    of a list of values discretised with n points of constant separation dx.
    >>> x = np.arange(0, 1, 0.01)
    >>> y = np.sin(2*np.pi*x)
    >>> d2fdx = make_central_difference2(len(x), 0.01)
    >>> dfdx(y)  #=> ~ -4π² sin(2πx)"""
    m = make_stencil(n, -2, 1, 1) / (dx**2)
    def d2fdx(phi):
        return np.dot(m, phi)
    return d2fdx

if __name__ == '__main__':
    # test: plot sin(2pi x) and dy/dx = cos(2pi x) [normalised]
    import matplotlib.pyplot as plt
    X = 1.0
    dx = 0.01
    x = np.arange(0,X,dx)
    y = np.sin(2*np.pi*x/X)
    dfdx = make_central_difference1(len(x), dx)
    d2fdx = make_central_difference2(len(x), dx)
    plt.plot(x, y)
    plt.plot(x, dfdx(y) / (2*np.pi))
    plt.plot(x, d2fdx(y) / (4*np.pi*np.pi))
    plt.legend(['y=sin(x)','dy/dx','d2y/dx'])
    plt.show()


# compute primes up to max number using the Sieve algorithm
# https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
#

import sys
import math
from numpy import arange
from datetime import *

def print_usage(name):
    print('python3 {} <max_number>'.format(name))

def create_number_list(max: int):
    numbers = arange(1, max, 2)
    return numbers

def mark_multiples_of_prime(numbers, prime_index: int, max: int):
    # print('Checking prime:{}'.format(prime))

    prime = numbers[prime_index]
    array_length = len(numbers)

    # the for loop will start at one multiple past the current prime
    # it will walk the list of numbers by multiples of prime
    # this logic removes the need for any if statements inside the loop
    for i in range(prime_index+prime, array_length, prime):
        numbers[i] = 0

def compute_primes(max: int):
    start_time = datetime.now()

    numbers = create_number_list(max)

    # print('Numbers = {}'.format(numbers))

    print('Computing primes from 0 to {}'.format(max))

    half_length = int(len(numbers)/2)

    for index in range(int(1), half_length):
        if (numbers[index] > 1):
            # print('index: {}, prime: {}'.format(index, numbers[index]))
            mark_multiples_of_prime(numbers, index, max)

    primes = [i for i in numbers if i>0]

    mid_time = datetime.now()

    # print('Primes = {}'.format(primes))

    finish_time = datetime.now()

    print('Start: {}, Mid: {}, Finish: {}'.format(start_time, mid_time, finish_time))
    print('Compute time: {}. \nFound {} prime numbers less than {}'.format(mid_time - start_time, len(primes), max))
    # print('Print time: {}'.format(finish_time - mid_time))

def main():
    if (len(sys.argv) > 1):
        compute_primes(int(sys.argv[1]))
    else:
        print_usage(sys.argv[0])

if __name__ == "__main__":
    main()


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

def convereged(new_mu, old_mu):
    return np.all(np.sort(new_mu) == np.sort(old_mu))

def recalculate_mu(clusters):
    mu = np.zeros(shape=(len(clusters.keys()), len(clusters.values()[0][0])))
    for k, points in clusters.items():
        if len(points) > 0:
            mu[k] = np.mean(points, axis=0)
    return mu

def calculate_center(data, mu, k):
    clusters = {i:[] for i in range(k)}
    for point in data:
        min_distance = sys.maxint
        best_k = 0
        for i, _muk in enumerate(mu):
            distance = np.linalg.norm(point - _muk)**2
            if distance < min_distance:
                min_distance = distance
                best_k = i
        clusters[best_k].append(point)
    new_mu = recalculate_mu(clusters)
    return new_mu, clusters

def k_means(data, k, label="", plot="False"):
    old_mu = np.array(random.sample(data, k))
    new_mu, clusters = calculate_center(data, old_mu, k)
    while not convereged(old_mu, new_mu):
        old_mu = new_mu
        new_mu, clusters = calculate_center(data, old_mu, k)
    if plot:
        colors = ['r', 'g', 'b', 'y', 'c']

        for k, points in clusters.items():
            np_points = np.array(points)
            plt.scatter(np_points[:, 0], np_points[:, 1], color=colors[k])
            plt.scatter(new_mu[k][0], new_mu[k][1], marker="^", color=colors[k], edgecolors='black', lw=1, s=50)
        plt.savefig("./images/{}-{}.png".format(label, k + 1))
        plt.close()

    return new_mu, clusters


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

import os
import sys
import numpy as np

def get_positive_y_max(b_bar, y):
    assert(len(b_bar) == len(y))

    j_min_ = None
    theta = float('inf')

    for i, (b_, y_) in enumerate(zip(b_bar, y)):
        if y_ <= 0.0:
            continue
        tmp = b_/y_
        if theta > tmp:
            theta = tmp
            j_min_ = i
    return j_min_, theta

if __name__ == '__main__':
    A = np.asarray([[1.0, 0.0, 1.0, 0.0, 0.0, 0.0],
                    [0.0, 1.0, 0.0, 1.0, 0.0, 0.0],
                    [1.0, -1.0, 0.0, 0.0, 1.0, 0.0],
                    [2.0, -1.0, 0.0, 0.0, 0.0, -1.0]])

    b = np.asarray([2.0, 3.0, 1.0, -1.0])
    c = np.asarray([-1.0, -2.0, 0.0, 0.0, 0.0, 0.0]) # need 0.0

    # initial index (they must be feasible...)
    B_index = np.asarray([2, 3, 4, 5])
    N_index = np.asarray([0, 1])

    # initial feasible solution
    B = A[:, B_index]
    B_inverse = np.linalg.inv(B)
    b_bar = np.dot(B_inverse, b)
    x = np.zeros(len(c), dtype = float)
    for x_, idx in zip(b_bar, B_index):
        x[idx] = x_

    # simplex loop
    while(True):
        c_B = c[B_index]
        c_N = c[N_index]
        B = A[:, B_index]
        N = A[:, N_index]
        B_inverse = np.linalg.inv(B)

        # pricing
        tmp = np.dot(B_inverse.transpose(), c_B)
        rho = c_N - np.dot(N.transpose(), tmp)
        k_ = np.argmin(rho)
        k = N_index[k_]

        if rho[k_] >= 0.0:
            break

        # ratio test
        b_bar = np.dot(B_inverse, b)
        y = np.dot(B_inverse, A[:, k])
        j_min_, theta = get_positive_y_max(b_bar, y)
        j_min = B_index[j_min_]

        # pivot
        x[k] = theta
        for tmp, idx in zip(y, B_index):
            x[idx] -= tmp * theta
        print(x)
        B_index = np.insert(B_index[B_index != j_min], 0, k)
        N_index = np.insert(N_index[N_index != k], 0, j_min)

    print(x)
    print('obj = {}'.format(np.dot(x, c)))


from __future__ import division
import numpy as np
import pylab as pl
import random
import math
import matplotlib.pyplot as plt
import matplotlib as mpl

'''
# plot sigmoid function
x = np.arange(-10,10,0.001)
# sigmoid = [i*i for i in x]
sigmoid = 1. / ( 1 + np.exp(-x) )
den = pow((1 + np.exp(-x)),2)
sigmoidDer = np.exp(-x) / ( den  )

fig = pl.figure()
pl.grid(True)
pl.xlim(-10, 10)
pl.ylim(-1, 1)
# pl.title('Sigmoid')
pl.plot(x, sigmoid, 'r-', label='Sigmoid function')
pl.plot(x, sigmoidDer, 'b--', label='Derivative of sigmoid function')
pl.legend()
# pl.xlabel('')
# pl.ylabel(u"sf")
pl.show()
fig.savefig('sigmoid.png')

'''

'''
# plot tanh function
x = np.arange(-10,10,0.001)
# sigmoid = [i*i for i in x]
tanh = (np.exp(x) - np.exp(-x)) / ( np.exp(x) + np.exp(-x) )
tanhDer = 1 - pow(tanh,2)

fig = pl.figure()
pl.grid(True)
pl.xlim(-10, 10)
pl.ylim(-1, 1)
# pl.title('Sigmoid')
pl.plot(x, tanh, 'r-', label='tanh function')
pl.plot(x, tanhDer, 'b--', label='Derivative of tanh function')
pl.legend()
# pl.xlabel('')
# pl.ylabel(u"sf")
pl.show()
fig.savefig('tanh.png')

'''

'''
# plot ReLU function
x = np.arange(-10,10,0.001)
# sigmoid = [i*i for i in x]
relu = np.where(x<0,0,x)
reluDer = np.where(x<0,0,1)

fig = pl.figure()
pl.grid(True)
pl.xlim(-2, 2)
pl.ylim(-2, 2)

pl.spines['top'].set_color('none')

# pl.title('Sigmoid')
pl.plot(x, relu, 'r-', label='ReLU function')
pl.plot(x, reluDer, 'b--', label='Derivative of ReLU function')
pl.legend()
# pl.xlabel('')
# pl.ylabel(u"sf")
pl.show()
fig.savefig('relu.png')
'''

'''
mpl.rcParams['axes.unicode_minus']=False

fig = plt.figure(figsize=(6,4))
ax = fig.add_subplot(111)

x = np.arange(-10, 10)
y = np.where(x<0,0,x)

plt.xlim(-11,11)
plt.ylim(-11,11)

ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')

ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.set_xticks([-10,-5,0,5,10])
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))
ax.set_yticks([-10,-5,5,10])

plt.plot(x,y,label="ReLU",color = "red")
plt.legend()
plt.show()
fig.savefig('relu.png')

'''

'''
# plot leak ReLU function
mpl.rcParams['axes.unicode_minus']=False

fig = plt.figure(figsize=(6,4))
ax = fig.add_subplot(111)

x = np.arange(-10, 10)
y = np.where(x<0,0.2*x,x)

plt.xlim(-11,11)
plt.ylim(-11,11)

ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')

ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.set_xticks([-10,-5,0,5,10])
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))
ax.set_yticks([-10,-5,5,10])

plt.plot(x,y,label="Leak ReLU",color = "red")
plt.legend()
plt.show()
fig.savefig('leakRelu.png')

'''

# plot ELU function
mpl.rcParams['axes.unicode_minus']=False

fig = plt.figure(figsize=(6,4))
ax = fig.add_subplot(111)

x = np.arange(-10, 10)
y = np.where(x<0,1*(np.exp(x)-1),x)

plt.xlim(-11,11)
plt.ylim(-11,11)

ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')

ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.set_xticks([-10,-5,0,5,10])
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))
ax.set_yticks([-10,-5,5,10])

plt.plot(x,y,label="ELU",color = "red")
plt.legend()
plt.show()
fig.savefig('ELU.png')


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

mu = 0 # mean
sigma = 1 # standard deviation
normal_sample = np.random.normal(mu, sigma, 15000)

# plot the histogram of the sample distribution
fig, ax = plt.subplots()
ax.hist(normal_sample, bins='auto', density=True, color='#c7ddf4', edgecolor='#000000', label='Random sample with normal distribution')

# probability density function
x = np.arange(-5,5, 0.01)
normal_pdf = norm.pdf(x, loc= mu, scale = sigma)
ax.plot(x, normal_pdf, color='#ff464a', linewidth=1.5, linestyle='--', label=r'Normal PDF with $\mu$=0 and 1$\sigma$=1')
ax.legend(title='Normal Distribution')
ax.set_xlabel('x')
ax.set_ylabel('Probability Density')
ax.set_xlim(-5,5)
ax.set_ylim(0,0.6)

# Descriptive statistics
aritmetic_mean = normal_sample.mean()
standard_deviation = normal_sample.std()

print('Sample mean equal to {:.4f}'.format(aritmetic_mean))
print('Sample standard deviation equal to {:.4f}'.format(standard_deviation))

'''
Output: (your results will be sighly different because of the pseudo-random nature of the distribution)
Sample mean equal to -0.0014
Sample standard deviation equal to 1.0014
'''


#!/usr/bin/python
"""
author  : Bhekimpilo Ndhlela
author  : 18998712
module  : Applied Mathematics(Numerical Methods) TW324
task    : computer assignment 05 question 5
since   : Friday-27-04-2018
"""

def gauss_legendre(n=5.0):
    X, C = gauss(5, [-1, 1])
    f = lambda x : exp(x) / sqrt(1 - x**2)
    return sum([f(float(x)) * float(c) for x, c in zip(X, C)])

def gauss_chebyshev(n=5.0):
    X = [cos(((2.0 * i - 1) * pi) / (2 * n)) for i in xrange(1, int(n + 1))]
    return (pi * (sum([exp(x) for x in X]))) / n

def abs_error(xc, x):
    return abs(float(xc) - float(x))

if __name__ == "__main__":
    from scipy import (integrate, special)
    from math import (sqrt, exp, cos, pi)
    from gauss import gauss

    exact_integral = integrate.quad(lambda x : exp(x)/sqrt(1-x**2),-1,1)[0]
    gauss_chebyshev, gause_legendre = gauss_chebyshev(), gauss_legendre()

    debug = True
    if debug == True:
        print("Debug Mode Status: <ON>")
        print("Exact Integral  = {:.20f}".format(float(exact_integral)))
        print("Gauss Chebyshev = {:.20f}".format(abs_error(gauss_chebyshev, exact_integral)))
        print("Gauss Legendre  = {:.20f}".format(abs_error(gause_legendre, exact_integral)))
else:
    from sys import exit
    exit("USAGE: python question1.py")


import collections
import numpy as np

def mackey_glass(sample_len=1000, tau=17, seed=None, n_samples = 1):
    '''
    mackey_glass(sample_len=1000, tau=17, seed = None, n_samples = 1) -> input
    Generate the Mackey Glass time-series. Parameters are:
        - sample_len: length of the time-series in timesteps. Default is 1000.
        - tau: delay of the MG - system. Commonly used values are tau=17 (mild
          chaos) and tau=30 (moderate chaos). Default is 17.
        - seed: to seed the random generator, can be used to generate the same
          timeseries at each invocation.
        - n_samples : number of samples to generate
    '''
    delta_t = 10
    history_len = tau * delta_t
    # Initial conditions for the history of the system
    timeseries = 1.2

    if seed is not None:
        np.random.seed(seed)

    samples = []

    for _ in range(n_samples):
        history = collections.deque(1.2 * np.ones(history_len) + 0.2 * \
                                    (np.random.rand(history_len) - 0.5))
        # Preallocate the array for the time-series
        inp = np.zeros((sample_len,1))

        for timestep in range(sample_len):
            for _ in range(delta_t):
                xtau = history.popleft()
                history.append(timeseries)
                timeseries = history[-1] + (0.2 * xtau / (1.0 + xtau ** 10) - \
                             0.1 * history[-1]) / delta_t
            inp[timestep] = timeseries

        # Squash timeseries through tanh
        inp = np.tanh(inp - 1)
        samples.append(inp)
    return samples

def mso(sample_len=1000, n_samples = 1):
    '''
    mso(sample_len=1000, n_samples = 1) -> input
    Generate the Multiple Sinewave Oscillator time-series, a sum of two sines
    with incommensurable periods. Parameters are:
        - sample_len: length of the time-series in timesteps
        - n_samples: number of samples to generate
    '''
    signals = []
    for _ in range(n_samples):
        phase = np.random.rand()
        x = np.atleast_2d(np.arange(sample_len)).T
        signals.append(np.sin(0.2 * x + phase) + np.sin(0.311 * x + phase))
    return signals

def lorentz(sample_len=1000, sigma=10, rho=28, beta=8 / 3, step=0.01):
    """This function generates a Lorentz time series of length sample_len,
    with standard parameters sigma, rho and beta.
    """

    x = np.zeros([sample_len])
    y = np.zeros([sample_len])
    z = np.zeros([sample_len])

    # Initial conditions taken from 'Chaos and Time Series Analysis', J. Sprott
    x[0] = 0;
    y[0] = -0.01;
    z[0] = 9;

    for t in range(sample_len - 1):
        x[t + 1] = x[t] + sigma * (y[t] - x[t]) * step
        y[t + 1] = y[t] + (x[t] * (rho - z[t]) - y[t]) * step
        z[t + 1] = z[t] + (x[t] * y[t] - beta * z[t]) * step

    x.shape += (1,)
    y.shape += (1,)
    z.shape += (1,)

    return np.concatenate((x, y, z), axis=1)


# coding=utf-8
#Simple matrix inversion example
#Translated to Python by Kyrre Ness Sjøbæk

import numpy, computationalLib, math

myLib = computationalLib.pylib(inputcheck=False, cpp=False)

A = numpy.array([[1,3,4],[3,4,6],[4,6,8]],numpy.double)
print "Initial matrix A:\n", A

#LU-decompose A
matr = A.copy()
(matr,index,d) = myLib.luDecomp(matr);
print "LU-decomposed matrix:\n", matr
print "Index array:\n", index
print "Parity:\n", d

#Invert A column-by-column:
Ainv = numpy.zeros((3,3),numpy.double)
for j in xrange(3):
    col = numpy.zeros(3)
    col[j] = 1;

    Ainv[:,j] = myLib.luBackSubst(matr,index,col)

print "Inverse of A:\n", Ainv

#Test matrix inversion: AxAinv should be identity
test = True
ZERO = 1.0E-10
identity = numpy.zeros((3,3),numpy.double)
for i in xrange(3):
    for j in xrange(3):
        #Calculate and evaluate each element in resulting matrix:
        sum = 0.0;
        for k in xrange(3):
            sum = sum + A[i,k]*Ainv[k,j];
        if (i != j) and (sum > ZERO):
            test = False;
        if (i == j) and (math.fabs(sum - 1) > ZERO):
            test = False
        identity[i,j] = sum;
print "A*Ainv:\n", identity
if test:
    print "Status: OK"
else:
    print "Status: FAILED!"


import numpy as np

class Matrix:

    def __init__(self, A, b):
        if A.shape[0] != b.shape[0]:
            raise Exception('matrix dimension error')
        self.A = A
        self.b = b
        self.B = None
        self.q = None
        self.xk = np.zeros(b.shape[0])

    def find_matrix(self):
        self.q = self.b / self.A.diagonal()
        self.B = self.A / (-1 * self.A.diagonal()[:, None])
        np.fill_diagonal(self.B, np.zeros(self.q.shape[0]))

    def simple_iteration_method(self):
        c = self.A.dot(self.xk) != self.b
        while c.all():
            self.xk = self.B.dot(self.xk) + self.q
            c = self.A.dot(self.xk) != self.b
        return self.xk

    def get_xk(self):
        self.find_matrix()
        return self.simple_iteration_method()

if __name__ == "__main__":
    # Матрица A(по условию квадратная на множестве рациональных чисел)
    A = np.array([[2.0, 0.5, 0.1], [1.0, 5.0, 0.7], [0.6, 1.01, 8.0]])
    # Вектор b(по условию на множестве рациональных чисел)
    b = np.array([3.0, 3.0, 1.5])
    matrix = Matrix(A, b)
    print(f'x* = {matrix.get_xk()}')


import numpy as np
import sys
from matplotlib import pyplot as plt
import math

def function(x):
  #compute the value at the given coordinate
  try:
    x1 = np.float(x[0])
    x2 = np.float(x[1])
  except:
    print("input must be 2-D numerical vector")
    sys.exit(1)
  part_1 = math.sqrt(0.5*(x1*x1 + x2*x2))
  part_2 = 0.5*(math.cos(2*np.pi*x1) + math.cos(2*np.pi*x2))
  value = math.exp(1) + 20 -20*math.exp(-0.2 * part_1) - math.exp(part_2)

  #compute the gradient at the given coordinate
  part_1 = math.sqrt(0.5*(x1*x1 + x2*x2))
  part_2 = 0.5*(math.cos(2*math.pi*x1) + math.cos(2*math.pi*x2))
  gradient = [0,0]
  if np.abs(part_1) > 1e-12:
    gradient = 2 / part_1 * np.exp(-0.2 * part_1) * np.asarray([x1,x2]) + math.exp(part_2) * math.pi * np.sin(2*math.pi*np.asarray([x1,x2]))

  return value, gradient

def ackley_function_range(x_range_array):
  #returns an array of values for the given x range of values
  value = np.empty([len(x_range_array[0])])
  for i in range(len(x_range_array[0])):

    #returns the point value of the given coordinate
    part_1 = -0.2*math.sqrt(0.5*(x_range_array[0][i]*x_range_array[0][i] + x_range_array[1][i]*x_range_array[1][i]))
    part_2 = 0.5*(math.cos(2*np.pi*x_range_array[0][i]) + math.cos(2*np.pi*x_range_array[1][i]))

    value_point = math.exp(1) + 20 -20*math.exp(part_1) - math.exp(part_2)
    value[i] = value_point
  #returning the value array
  return value

def plot_general(fig):
  #this function will plot a general ackley function just to view it.
  limit = 1000 #number of points
  #common lower and upper limits for both x1 and x2 are used
  lower_limit = -5
  upper_limit = 5
  #generating x1 and x2 values
  x = np.linspace(-5, 5, 100)
  y = np.linspace(-5, 5, 100)
  X, Y = np.meshgrid(x, y)
  Z = np.zeros((len(X),len(Y)))
  for i in range(len(X)):
    for j in range(len(Y)):
        Z[i,j], _ = function([X[i,j],Y[i,j]])
  #plotting the function
  plt.contour(X, Y, Z, label='Ackley Function')

  def plot_ackley(x1_range,x2_range):
    #This would be the input for the Function
    x_range_array = [x1_range,x2_range]
    #generate the z range
    z_range = ackley_function_range(x_range_array)
    #plotting the function
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    ax.scatter(x1_range, x2_range, z_range, label='Ackley Function')
    return fig, ax


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
data=pd.read_csv('brain_head.csv')
print(data.head())
print(data.describe())

X=data['Head Size(cm^3)'].values
Y=data['Brain Weight(grams)'].values

mean_x=np.mean(X)
mean_y=np.mean(Y)

n=len(X)

a=0
b=0

for i in range(n):
	a+=(X[i]-mean_x)*(Y[i]-mean_y)
	b+=(X[i]-mean_x)**2

b1=a/b
b0=mean_y -(b1*mean_x)

print(b1,b0)
#the predicted line will be y=b0 + b1*x

print("Predicted regression line: y=" + str(b0) + str(b1)+"x")

x_max = np.max(X) + 100
x_min = np.min(X) - 100

#calculating line values of x and y
x = np.linspace(x_min, x_max, 1000)
y = b0 + b1 * x

#plotting line
plt.plot(x, y, color='#00ff00', label='Linear Regression')

#plot the data point
plt.scatter(X, Y, color='#ff0000', label='Data Point')

# x-axis label
plt.xlabel('Head Size (cm^3)')

#y-axis label
plt.ylabel('Brain Weight (grams)')

rmse = 0
for i in range(n):
    y_pred=  b0 + b1* X[i]
    rmse += (Y[i] - y_pred) ** 2

rmse = np.sqrt(rmse/n)

print(rmse)

sumofsquares = 0
sumofresiduals = 0

for i in range(n) :
    y_pred = b0 + b1 * X[i]
    sumofsquares += (Y[i] - mean_y) ** 2
    sumofresiduals += (Y[i] - y_pred) **2

score  = 1 - (sumofresiduals/sumofsquares)

print(score)
plt.legend()
plt.show()


# illustrate automatic differentiation using jax
# https://github.com/google/jax
import numpy as onp # original numpy
import jax.numpy as np
from jax import grad, hessian

onp.random.seed(42)
D = 5
w = onp.random.randn(D) # jax handles RNG differently

x = onp.random.randn(D)
y = 0 # should be 0 or 1

def sigmoid(x): return 0.5 * (np.tanh(x / 2.) + 1)

#d/da sigmoid(a) = s(a) * (1-s(a))
deriv_sigmoid = lambda a: sigmoid(a) * (1-sigmoid(a))
deriv_sigmoid_jax = grad(sigmoid)
a0 = 1.5
assert np.isclose(deriv_sigmoid(a0), deriv_sigmoid_jax(a0))

# mu(w)=s(w'x), d/dw mu(w) = mu * (1-mu) .* x
def mu(w): return sigmoid(np.dot(w,x))
def deriv_mu(w): return mu(w) * (1-mu(w)) * x
deriv_mu_jax =  grad(mu)
assert np.allclose(deriv_mu(w), deriv_mu_jax(w))

# NLL(w) = -[y*log(mu) + (1-y)*log(1-mu)]
# d/dw NLL(w) = (mu-y)*x
def nll(w): return -(y*np.log(mu(w)) + (1-y)*np.log(1-mu(w)))
#def deriv_nll(w): return -(y*(1-mu(w))*x - (1-y)*mu(w)*x)
def deriv_nll(w): return (mu(w)-y)*x
deriv_nll_jax = grad(nll)
assert np.allclose(deriv_nll(w), deriv_nll_jax(w))

# Now do it for a batch of data

def predict(weights, inputs):
    return sigmoid(np.dot(inputs, weights))

def loss(weights, inputs, targets):
    preds = predict(weights, inputs)
    logprobs = np.log(preds) * targets + np.log(1 - preds) * (1 - targets)
    return -np.sum(logprobs)

N = 3
X = onp.random.randn(N, D)
y = onp.random.randint(0, 2, N)

from jax import vmap
from functools import partial

preds = vmap(partial(predict, w))(X)
preds2 = vmap(predict, in_axes=(None, 0))(w, X)
preds3 = [predict(w, x) for x in X]
preds4 = predict(w, X)
assert np.allclose(preds, preds2)
assert np.allclose(preds, preds3)
assert np.allclose(preds, preds4)

grad_fun = grad(loss)
grads = vmap(partial(grad_fun, w))(X,y)
assert grads.shape == (N,D)
grads2 = np.dot(np.diag(preds-y), X)
assert np.allclose(grads, grads2)

grad_sum = np.sum(grads, axis=0)
grad_sum2 = np.dot(np.ones((1,N)), grads)
assert np.allclose(grad_sum, grad_sum2)

# Now make things go fast
from jax import jit

grad_fun = jit(grad(loss))
grads = vmap(partial(grad_fun, w))(X,y)
assert np.allclose(grads, grads2)

# Logistic regression
H1 = hessian(loss)(w, X, y)
mu = predict(w, X)
S = np.diag(mu * (1-mu))
H2 = np.dot(np.dot(X.T, S), X)
assert np.allclose(H1, H2)


import numpy as np
import numpy.linalg as la
from io import StringIO

def print_mat(mat):

    stream = StringIO()
    np.savetxt(stream, mat, fmt="%.3f")
    print( stream.getvalue() )

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

def get_convergent_vector(L, r_0, threshold=0.01):

    '''
    :param L: transition matrix
    :param r_0: initial vector
    :param threshold: parameter for convergence condition
    :return: convergent vector
    '''

    r_cur = r_0

    while True:

        r_next = np.matmul(L, r_cur)

        if la.norm(r_next - r_cur) < threshold:
            # check convergence condition is met or not
            break

        r_cur = r_next

    return r_cur

# -----------------------------------
def get_matrix_with_damping(matrix, damping=0.5):

    # get the size of matrix
    n, _ = matrix.shape

    return matrix * damping + ( 1 - damping ) * np.ones((n, n)) / n

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

tokens = input().split()
n, damping_factor = int( tokens[0] ), float( tokens[1] )

matrix = [ [ 0.0 for x in range(n)] for y in range(n) ]

for y in range(n):
    matrix[y] = [ *map( float, input().split() ) ]

# convert to numpy array
matrix = np.array(matrix)

matrix_with_damping = get_matrix_with_damping(matrix, damping=damping_factor)

r_0 = ( np.ones(n) / n) * 100

# compute pagerank
r_pagerank = get_convergent_vector(L=matrix_with_damping, r_0=r_0, threshold=0.01)

# output result
print_mat(r_pagerank)


"""
Reference from the book <<Machine learning in action>>

@author: Peter Harrington
"""

import numpy as np

class PCA(object):

    def __init__(self, dataMat, percent=0.99):
        """

        :param dataMat: 输入训练集
        :param percent: 特征值数量的占比
        """
        self.percent = percent
        self.dataMat = dataMat

    def _zeroMean(self, dataMat):
        """
        对样本矩阵进行零均值处理
        :param dataMat: 按列进行求均值，每一列代表一个特征值
        :return:
        """
        meanMat = np.mean(dataMat, axis=0)
        zeroMat = dataMat - meanMat

        return zeroMat, meanMat

    def _getTopNFeatures(self, eigVals):
        """
        找到出现概率最多的N个特征
        :param eigVals: 特征值
        :return:
        """
        descendOrder = np.sort(eigVals)[-1::-1]
        orderSum = np.sum(descendOrder)
        tmp = 0
        num = 0
        for i in descendOrder:
            tmp += i
            num += 1
            if tmp > orderSum * self.percent:
                return num

    def pcaImplement(self):
        zeroMat, meanMat = self._zeroMean(self.dataMat)
        #计算协方差矩阵
        covMat = np.cov(zeroMat, rowvar=0)
        eigVals, eigVects = np.linalg.eig(np.mat(covMat))
        topN = self._getTopNFeatures(eigVals)
        eigValIndice = np.argsort(eigVals)
        topN_eigValIndice = eigValIndice[-1:-(topN - 1):-1]
        topN_eigVect = eigVects[:, topN_eigValIndice]
        #构建低维的特征空间的数据
        lowDDataMat = zeroMat * topN_eigVect
        reconMat = np.multiply(lowDDataMat, topN_eigVect.T) + meanMat

        return reconMat, lowDDataMat

class LoadData(object):

    def __init__(self, filepath, delimt='\t'):
        self.filepath = filepath
        self.delimt = delimt

    def _loadDataSet(self, filepath, delimt):
        """
        加载数据
        :param filepath:文件的位置
        :param delimt:文件里面的分隔符
        :return:
        """
        file = open(filepath)
        stringArr = [line.strip().split(delimt) for line in file]
        dataArr = [map(float, str) for str in stringArr]

        return np.mat(dataArr)

    def replaceNanWithMean(self):
        """
        将数据为空的字段替换掉
        :return:
        """
        dataMat = self._loadDataSet(self.filepath, self.delimt)
        numFeat = dataMat.shape[1]
        for i in range(numFeat):
            meanVal = np.mean(dataMat[np.nonzero(~np.isnan(dataMat[:, i].A))[0], i])
            dataMat[np.nonzero(np.isnan(dataMat[:, i].A))[0], i] = meanVal
        return dataMat


# -*- coding: utf-8 -*-
import numpy as np

def linear_gd(X, Y, alpha=0.01, epsilon=1e-8, trace=True):
    m = len(X)
    _X = np.column_stack((np.ones(m), X))
    m, n = np.shape(_X)
    theta, sse2, cnt = np.ones(n), 0, 0
    Xt = _X.T
    while True:
        loss = np.dot(_X, theta) - Y
        sse = np.dot(loss.T, loss) / (2 * m)
        if abs(sse - sse2) < epsilon:
            break
        else:
            sse2 = sse

        if trace:
            print("[ Epoch {0} ] theta = {1}, loss = {2}, error = {3})".format(cnt, theta, loss, sse))

        gradient = np.dot(Xt, loss) / m
        theta -= alpha * gradient
        cnt += 1

    return theta


import numpy as np
import scipy

a = [1,2,3,4,5.]

# A trick when you want to flatten a matrix X of shape (a,b,c,d) to a matrix X_flatten of shape (b ∗∗ c ∗∗ d, a) is to use:
# X_flatten = X.reshape(X.shape[0], -1).T      # X.T is the transpose of X

q = np.random.randint(7, size=(2, 3, 4))

# GRADED FUNCTION: sigmoid
def sigmoid(z):
    """
    Compute the sigmoid of z

    Arguments:
    z -- A scalar or numpy array of any size.

    Return:
    s -- sigmoid(z)
    """

    ### START CODE HERE ### (≈ 1 line of code)
    s = 1 / (1 + np.e ** (-z))
    ### END CODE HERE ###

    return s

# GRADED FUNCTION: initialize_with_zeros
def initialize_with_zeros(dim):
    """
    This function creates a vector of zeros of shape (dim, 1) for w and initializes b to 0.

    Argument:
    dim -- size of the w vector we want (or number of parameters in this case)

    Returns:
    w -- initialized vector of shape (dim, 1)
    b -- initialized scalar (corresponds to the bias)
    """

    ### START CODE HERE ### (≈ 1 line of code)
    w = np.zeros(shape=(dim, 1))
    b = 0
    ### END CODE HERE ###

    assert (w.shape == (dim, 1))
    assert (isinstance(b, float) or isinstance(b, int))

    return w, b

# GRADED FUNCTION: propagate
def propagate(w, b, X, Y):
    """
    Implement the cost function and its gradient for the propagation explained above

    Arguments:
    w -- weights, a numpy array of size (num_px * num_px * 3, 1)
    b -- bias, a scalar
    X -- data of size (num_px * num_px * 3, number of examples)
    Y -- true "label" vector (containing 0 if non-cat, 1 if cat) of size (1, number of examples)

    Return:
    cost -- negative log-likelihood cost for logistic regression
    dw -- gradient of the loss with respect to w, thus same shape as w
    db -- gradient of the loss with respect to b, thus same shape as b

    Tips:
    - Write your code step by step for the propagation. np.log(), np.dot()
    """

    m = X.shape[1]

    # FORWARD PROPAGATION (FROM X TO COST)
    ### START CODE HERE ### (≈ 2 lines of code)
    A = sigmoid(np.dot(w.T, X) + b)  # compute activation
    cost = - np.mean(Y * np.log(A) + (1 - Y) * np.log(1 - A))  # compute cost
    ### END CODE HERE ###

    # BACKWARD PROPAGATION (TO FIND GRAD)
    ### START CODE HERE ### (≈ 2 lines of code)
    dw = (1 / m) * np.dot(X, (A - Y).T)
    db = np.mean(A - Y)
    ### END CODE HERE ###

    assert (dw.shape == w.shape)
    assert (db.dtype == float)
    cost = np.squeeze(cost)
    assert (cost.shape == ())

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

    return grads, cost


import numpy as np
from scipy.spatial import distance

def cayley_menger_analysis(vertices, d = 2):
    """
    Determines volume and circumradius for a tetrahedron given the vertices
    https://westy31.home.xs4all.nl/Circumsphere/ncircumsphere.htm#Coxeter
    """
    if d == 3:
        cm_matrix = np.array([[0, 1, 1, 1, 1], [1, 0, distance.sqeuclidean(vertices[0], vertices[1]),
                            distance.sqeuclidean(vertices[0], vertices[2]),
                            distance.sqeuclidean(vertices[0], vertices[3])],
                            [1, distance.sqeuclidean(vertices[1], vertices[0]), 0,
                            distance.sqeuclidean(vertices[1], vertices[2]),
                            distance.sqeuclidean(vertices[1], vertices[3])],
                            [1, distance.sqeuclidean(vertices[2], vertices[0]),
                            distance.sqeuclidean(vertices[2], vertices[1]), 0,
                            distance.sqeuclidean(vertices[2], vertices[3])],
                            [1, distance.sqeuclidean(vertices[3], vertices[0]),
                            distance.sqeuclidean(vertices[3], vertices[1]),
                            distance.sqeuclidean(vertices[3], vertices[2]), 0]])

        cm_inv = np.linalg.inv(cm_matrix)
        centroid = [(vertices[0, 0] + vertices[1, 0] + vertices[2, 0] + vertices[3, 0])/4, \
                    (vertices[0, 1] + vertices[1, 1] + vertices[2, 1] + vertices[3, 1])/4, \
                    (vertices[0, 2] + vertices[1, 2] + vertices[2, 2] + vertices[3, 2])/4]
        v_simplex = np.sqrt(np.divide(np.linalg.det(cm_matrix), 288))
        r_simplex = np.sqrt(cm_inv[0,0]/-2)

    if d == 2:
        cm_matrix = np.array([[0, 1, 1, 1], [1, 0, distance.sqeuclidean(vertices[0], vertices[1]),
                            distance.sqeuclidean(vertices[0], vertices[2])],
                            [1, distance.sqeuclidean(vertices[1], vertices[0]), 0,
                            distance.sqeuclidean(vertices[1], vertices[2])],
                            [1, distance.sqeuclidean(vertices[2], vertices[0]),
                            distance.sqeuclidean(vertices[2], vertices[1]), 0]])

        cm_inv = np.linalg.inv(cm_matrix)
        centroid = [(vertices[0, 0] + vertices[1, 0] + vertices[2, 0])/3, (vertices[0, 1] + vertices[1, 1] + vertices[2, 1])/3]
        v_simplex = np.sqrt(np.divide(np.linalg.det(cm_matrix), -16))
        r_simplex = np.sqrt(cm_inv[0,0]/-2)

    return v_simplex, r_simplex, cm_inv[1::], centroid

def get_simplex_properties(tri, d = 2):

    if d == 2:
        area = []
        circumradius = []
        circumcenter = []
        centroid = []
        for i in tri.simplices:
            a, r, center, centr = cayley_menger_analysis(tri.points[i], d = d)
            area.append(a)
            circumradius.append(r)
            circumcenter.append(center)
            centroid.append(centr)

        return np.array(area), np.array(circumradius), np.array(circumcenter), np.array(centroid)

    if d == 3:
        volume = []
        circumradius = []
        circumcenter = []
        centroid = []
        for i in tri.simplices:
            a, r, center, centr = cayley_menger_analysis(tri.points[i], d = d)
            volume.append(a)
            circumradius.append(r)
            circumcenter.append(center)
            centroid.append(centr)

        return np.array(volume), np.array(circumradius), np.array(circumcenter), np.array(centroid)


# Para visualizar gráficos en la terminal interactiva
from IPython import get_ipython
get_ipython().run_line_magic('matplotlib', 'ipympl')

"""
# Actividad en clases: Aliasing

Objetivos:

- Reconstruir señales usando los resultados del teorema del muestreo
- Estudiar de forma práctica el fenomeno de aliasing

Para esta actividad consideremos la siguiente señal periódica con componentes 1Hz, 12Hz y 23Hz, respectivamente

"""

import numpy as np
import scipy.fft
import matplotlib.pyplot as plt

Fs = 1000
tn = np.arange(0, 2, step=1/Fs)
sn = np.cos(2.0*np.pi*tn) + 0.5*np.cos(2.0*np.pi*tn*12) + 0.25*np.cos(2.0*np.pi*tn*23)
S = scipy.fft.rfft(sn)
f = scipy.fft.rfftfreq(n=len(tn), d=1/Fs)

fig, ax = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
ax[0].plot(tn, sn, '.', markersize=1)
ax[1].plot(f, np.abs(S))

"""

Primero visualice la señal y el espectro de amplitud para Fs=1000, Fs=50, Fs=10. ¿En qué casos se pueden detectar sin ambiguedad las frecuencias de la señal?

"""

"""
El teorema del muestreo dice que una señal digital sn cuya frecuencia máxima sea menor que la mitad de la frecuencia de muestreo Fs puede reconstruirse sin perdidas usando la fórmula de interpolación indicada en https://phuijse.github.io/UACH-INFO183/lectures/unit1/lecture4.html#teorema-del-muestreo

que usando NumPy sería

s = np.sum(sn*np.sinc(Fs*(t-tn)))

Utilice la formula para reconstruir la señal usando una frecuencia de muestreo arbitrariamente alta (Fs = 10000) y discuta sobre lo que observa

"""


import numpy as np

"""
print(np.array([1, 2, 3, 4, 5]))
print(np.array(['1', 2, 3, 4, 5]))
print(np.array([1, 2, 3, 4], dtype=float))
print(np.zeros(10))
print(np.ones((3, 2)))
print(np.full((3, 2), 3.14))
print(np.arange(10))
print(np.eye(3))

a3 = np.random.randint(10, size=(3, 4, 5))
print(a3.ndim)
print(a3.shape)
print(a3.size)  # != len
print(a3[0, 2], a3[0][2])
"""

"""
a = np.arange(10)
print(a, a[-5:])
print(a, a[:-5])

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

a2_sub = a2[2:, 2:]  # share pointers
a2_sub = a2[2:, 2:].copy()  # dont share pointers

print(np.arange(1, 10).reshape((3, 3)))
"""

a1 = np.array([1, 2, 3])
a2 = np.array([4, 5, 6])
a3 = np.concatenate([a1, a2])
print(a3)

a4 = np.array([[1, 2, 3], [4, 5, 6]])
a5 = np.concatenate([a4, a4])
print(a5)
a6 = np.concatenate([a4, a4], axis=1)
print(a6)


import numpy as np

# First 20 countries with employment data
countries = np.array([
    'Afghanistan', 'Albania', 'Algeria', 'Angola', 'Argentina',
    'Armenia', 'Australia', 'Austria', 'Azerbaijan', 'Bahamas',
    'Bahrain', 'Bangladesh', 'Barbados', 'Belarus', 'Belgium',
    'Belize', 'Benin', 'Bhutan', 'Bolivia',
    'Bosnia and Herzegovina'
])

# Employment data in 2007 for those 20 countries
employment = np.array([
    55.70000076,  51.40000153,  50.5       ,  75.69999695,
    58.40000153,  40.09999847,  61.5       ,  57.09999847,
    60.90000153,  66.59999847,  60.40000153,  68.09999847,
    66.90000153,  53.40000153,  48.59999847,  56.79999924,
    71.59999847,  58.40000153,  70.40000153,  41.20000076
])

# Change False to True for each block of code to see what it does

# Accessing elements
if False:
    print countries[0]
    print countries[3]

# Slicing
if False:
    print countries[0:3]
    print countries[:3]
    print countries[17:]
    print countries[:]

# Element types
if False:
    print countries.dtype
    print employment.dtype
    print np.array([0, 1, 2, 3]).dtype
    print np.array([1.0, 1.5, 2.0, 2.5]).dtype
    print np.array([True, False, True]).dtype
    print np.array(['AL', 'AK', 'AZ', 'AR', 'CA']).dtype

# Looping
if False:
    for country in countries:
        print 'Examining country {}'.format(country)

    for i in range(len(countries)):
        country = countries[i]
        country_employment = employment[i]
        print 'Country {} has employment {}'.format(country,
                country_employment)

# Numpy functions
if False:
    print employment.mean()
    print employment.std()
    print employment.max()
    print employment.sum()

def max_employment(countries, employment):
    '''
    Fill in this function to return the name of the country
    with the highest employment in the given employment
    data, and the employment in that country.
    '''
    max_country = None      # Replace this with your code
    max_value = None   # Replace this with your code

    return (max_country, max_value)


import numpy as np

# Forward kinematics.
# Calculation relies on cosine rule.

# Four-bar linkage solution process inspired by: https://www.youtube.com/watch?v=4O-XPJ7flLU&t=321s
# Animation source code inspiration: DIYwalkers.com

#####################################
# User input, two servo angles.

servo_angle_femur = -45 # degrees
servo_angle_tibia = 150  # degress

#####################################
# Frame parameters, set my physical model.
# Lower servo origin, tibia control.
Ax = -20
Ay = -20

# Upper servo origin, femur control.
Dx = 0
Dy = 0

# Link lengths
L2 = 23
L3 = 30
L4 = 23
L5 = 22
L6 = 23
L7 = 100
L8 = 100
L9 = 23
L10 = 100

#####################################
# Calculations
L1 = np.sqrt(np.square(Dx - Ax) + np.square(Dy - Ay))

theta1 = np.arcsin((Dy - Ay) / L1)
theta2 = np.radians(servo_angle_tibia)

AC = np.sqrt(np.square(L1) + np.square(L2) - 2 * L1 * L2 * np.cos(theta1 - theta2))
beta = np.arccos((np.square(L1) + np.square(AC) - np.square(L2)) / (2 * L1 * AC));
psi = np.arccos((np.square(L3) + np.square(AC) - np.square(L4)) / (2 * L3 * AC));
lamda = np.arccos((np.square(L4) + np.square(AC) - np.square(L3)) / (2 * L4 * AC));

theta3 = psi - beta + theta1;
theta4 = np.pi - lamda - beta + theta1;

Bx = Ax + L2 * np.cos(theta2)
By = Ay + L2 * np.sin(theta2)
Cx = Dx + L4 * np.cos(theta4)
Cy = Dy + L4 * np.sin(theta4)

kappa = np.arccos((np.square(L4) + np.square(L6) - np.square(L5)) / (2 * L4 * L6))

theta5 = np.radians(servo_angle_femur)
theta6 = theta4 - kappa

EG = np.sqrt(np.square(L6) + np.square(L8) - 2 * L6 * L8 * np.cos(theta6 - theta5))
mu = np.arccos((np.square(L8) + np.square(EG) - np.square(L6)) / (2 * L8 * EG));
omega = np.arccos((np.square(L7) + np.square(EG) - np.square(L9)) / (2 * L7 * EG));
rho = np.arccos((np.square(EG) + np.square(L9) - np.square(L7)) / (2 * EG * L9));

theta7 = mu - omega + theta5;
theta8 = np.pi - rho - mu + theta5;

Ex = Dx + L6 * np.cos(theta6)
Ey = Dy + L6 * np.sin(theta6)
Gx = Dx + L8 * np.cos(theta5)
Gy = Dy + L8 * np.sin(theta5)
Fx = Gx + L9 * np.cos(theta8)
Fy = Gy + L9 * np.sin(theta8)
Hx = Gx + L10 * np.cos(theta8 - np.pi)
Hy = Gy + L10 * np.sin(theta8 - np.pi)

#####################################
# Print results.

print("A = (%.2f, %.2f)" % (Ax, Ay))
print("B = (%.2f, %.2f)" % (Bx, By))
print("C = (%.2f, %.2f)" % (Cx, Cy))
print("D = (%.2f, %.2f)" % (Dx, Dy))
print("E = (%.2f, %.2f)" % (Ex, Ey))
print("F = (%.2f, %.2f)" % (Fx, Fy))
print("G = (%.2f, %.2f)" % (Gx, Gy))
print("H = (%.2f, %.2f)" % (Hx, Hy))

print("AC:", np.around(AC, 2))
print("EG:", np.around(EG, 2))

print("beta = %.2f" % (np.degrees(beta)))
print("psi = %.2f" % (np.degrees(psi)))
print("lamda = %.2f" % (np.degrees(lamda)))
print("kappa = %.2f" % (np.degrees(kappa)))
print("mu = %.2f" % (np.degrees(mu)))
print("omega = %.2f" % (np.degrees(omega)))
print("rho = %.2f" % (np.degrees(rho)))

print("theta1 = %.2f" % (np.degrees(theta1)))
print("theta2 = %.2f" % (np.degrees(theta2)))
print("theta3 = %.2f" % (np.degrees(theta3)))
print("theta4 = %.2f" % (np.degrees(theta4)))
print("theta5 = %.2f" % (np.degrees(theta5)))
print("theta6 = %.2f" % (np.degrees(theta6)))
print("theta7 = %.2f" % (np.degrees(theta7)))
print("theta8 = %.2f" % (np.degrees(theta8)))


# 1. Reebok is designing a new type of Crossfit shoe, the Nano X. The fixed cost for the
# production will be $24,000. The variable cost will be $36 per pair of shoes. The shoes will
# sell for $107 for each pair. Using Python, graph the cost and revenue functions and
# determine how many pairs of sneakers will have to be sold for the company to break even on
# this new line of shoes.

import matplotlib.pyplot as plt
import math

# Expenses
# y = 36x + 24000
exp_slope = 36
exp_int   = 24000

exp_x0 = 0
exp_y0 = exp_slope * exp_x0 + exp_int
exp_x1 = 1000
exp_y1 = exp_slope * exp_x1 + exp_int

# Revenue
# y = 107x
rev_slope = 107
rev_int   = 0

rev_x0 = 0
rev_y0 = rev_slope * rev_x0 + rev_int
rev_x1 = 1000
rev_y1 = rev_slope * rev_x1 + rev_int

# Breakeven
# 107x = 36x + 24000
#  71x = 24000
#    x = 338.028
#    y = 107(338.028) = 36169.014

be_x = 24000 / 71
be_y = 107 * be_x

# Plot the lines
fig, shoe = plt.subplots()
shoe.scatter([exp_x0, exp_x1],
             [exp_y0, exp_y1],
             c = 'r')
shoe.plot([exp_x0, exp_x1],
          [exp_y0, exp_y1],
          c = 'r', alpha = 0.3)

shoe.scatter([rev_x0, rev_x1],
             [rev_y0, rev_y1],
             c = 'g')
shoe.plot([rev_x0, rev_x1],
          [rev_y0, rev_y1],
          c = 'g', alpha = 0.3)

shoe.scatter([be_x],
             [be_y],
             c = 'b', s = 100)
plt.xlim(0, 750)
plt.ylim(0, 75000)
plt.show()

print("To break even, Reebok must sell",
      math.ceil(be_x), "shoes.")

# 2. Nicole invests a total of $17,500 in three products. She invests one part in a mutual fund
# which has an annual return of 11%. She invests the second part in government bonds at 7%
# per year. The third part she puts in CDs at 5% per year. She invests twice as much in the
# mutual fund as in the CDs. In the first year Nicole's investments bring a total return of $1495.
# How much did she invest in each product?

import numpy as np
from numpy.linalg import inv
import matplotlib.pyplot as plt
# x + y + z = 17500
# 0.11x + 0.07y + 0.05z = 1495
# x - 2z = 0

a = inv(np.matrix('1 1 1; 11 7 5; 1 0 -2'))
b = np.array([17500, 149500, 0])
res = a.dot(b)
print("mutual funds=", res[0, 0],
      "gov't bonds =", res[0, 1],
      "CDs         =", res[0, 2])

labels = 'Mut Funds', "Gov't Bonds", 'CDs'
sizes  =  [res[0, 0], res[0, 1], res[0, 2]]
colors = ['lightskyblue', 'pink', 'yellowgreen']

plt.pie(sizes, labels = labels, colors = colors,
        autopct = '%1.1f%%', startangle = 140)

plt.axis('equal')
plt.show()

# 3. A company has 252 sales reps, each to be assigned to one of four marketing teams. If the first
# team is to have three times as many members as the second team and the third team is to
# have twice as many members as the fourth team, how can the members be distributed among
# the teams?

import pandas as pd
# w + x + y + z = 252
# w = 3x
# y = 2z
# 3x + x + 2z + z = 252
# 4x + 3z = 252
# 4x = 252 - 3z
#  x = 63 - 3/4z
#  w = 3 * (63 - 3/4z)
#  w = 189 - 9/4z

res = []
for z in range(253):
    z = float(z)
    x = float(63 - 3 * z / 4)
    y = float(2 * z)
    w = float(189 - 9 * z / 4)
    a,b = False,False
    if (w > 0) & (x > 0) & (y > 0) & (z > 0):
        a = True
    if (w.is_integer()) & (x.is_integer()) & (y.is_integer()) & (z.is_integer()):
        b = True
    if a & b: res.append([w, x, y, z])

teams = ['team1', 'team2', 'team3', 'team4']
print(pd.DataFrame(res, columns = teams))
pd.DataFrame(res, columns = teams).plot(kind = 'bar', stacked = True)

# 4. A company makes three types of artisanal chocolate bars: cherry, almond, and raisin. Matrix
# A gives the amount of ingredients in one batch. Matrix B gives the costs of ingredients from
# suppliers J and K. Using Python, calculate the cost of 100 batches of each candy using
# ingredients from supplier K.

import numpy as np
a = np.matrix('6 8 1; 6 4 1; 5 7 1')
b = np.matrix('4 3; 4 5; 2 2')

batch = a.dot(b)
print("100 cherry =", batch[0, 1] * 100,
      "100 almond =", batch[1, 1] * 100,
      "100 raisin =", batch[2, 1] * 100)

# 5. Welsh-Ryan Arena seats 15,000 people. Courtside seats cost $8, first level seats cost $6, and
# upper deck seats cost $4. The total revenue for a sellout is $76,000. If half the courtside seats,
# half the upper deck seats, and all the first level seats are sold, then the total revenue is
# $44,000. How many of each type of seat are there?

import numpy as np
from numpy.linalg import inv
#  x +  y +  z = 15000
# 8x + 6y + 4z = 76000
# 0.5(8x + 4z) + 6y = 44000
# 4x + 6y + 2z = 44000

a = inv(np.matrix('1 1 1; 8 6 4; 4 6 2'))
b = np.array([15000, 76000, 44000])
res = a.dot(b)
print("courtside  =", res[0, 0],
      "first level=", res[0, 1],
      "upper deck =", res[0, 2])

# 6. Due to new environmental restrictions, a chemical company must use a new process to
# reduce pollution. The old process emits 6 g of Sulphur and 3 g of lead per liter of chemical
# made. The new process emits 2 g of Sulphur and 4 g of lead per liter of chemical made. The
# company makes a profit of 25¢ per liter under the old process and 16¢ per liter under the new
# process. No more than 18,000 g of Sulphur and no more than 12,000 g of lead can be emitted
# daily. How many liters of chemicals should be made daily under each process to maximize
# profits? What is the maximum profit?

from scipy.optimize import linprog as lp
import numpy as np
# maximize: 0.25x + 0.16y
# subject to:
#   6x + 2y <= 18000
#   3x + 4y <= 12000
#      x, y >= 0

A = np.array([[6,  2], [3, 4]])
b = np.array([18000, 12000])
liters = lp(np.array([-0.25, -0.16]), A, b)

print("old method=", round(liters.x[0], 2), "liters.",
      "new method=", round(liters.x[1], 2), "liters.")
print("Max daily profit=",
      round(0.25 * liters.x[0] + 0.16 * liters.x[1], 2))

# 7. Northwestern is looking to hire teachers and TA’s to fill its staffing needs for its summer
# program at minimum cost. The average monthly salary of a teacher is $2400 and the average
# monthly salary of a TA is $1100. The program can accommodate up to 45 staff members and
# needs at least 30 to run properly. They must have at least 10 TA’s and may have up to 3 TA’s
# for every 2 teachers. Using Python, find how many teachers and TA’s the program should
# hire to minimize costs. What is the minimum cost?

from scipy.optimize import linprog as lp
import numpy as np
# minimize: 2400x + 1100y
# subject to:
#   x + y <= 45
#   x + y >= 30
#       y >= 10
#      2y <= 3x
#    x, y >= 0

A = np.array([[-1, -1], [-3, 2]])
b = np.array([-30, 0])
x_bounds = (0,  45)
y_bounds = (10, 45)
hire = lp(np.array([2400, 1100]), A, b,
          bounds = (x_bounds, y_bounds))

print("Hire", hire.x[0], "teachers.",
      "Hire", hire.x[1], "TAs.")
print("Minimum cost=",
      2400 * hire.x[0] + 1100 * hire.x[1])

# 8. To be at his best as a teacher, Roger needs at least 10 units of vitamin A, 12 units of vitamin
# B, and 20 units of vitamin C per day. Pill #1 contains 4 units of A and 3 of B. Pill #2 contains
# 1 unit of A, 2 of B, and 4 of C. Pill #3 contains 10 units of A, 1 of B, and 5 of C. Pill #1 costs
# 6 cents, pill #2 costs 8 cents, and pill #3 costs 1 cent. How many of each pill must Roger take
# to minimize his cost, and what is that cost?

from scipy.optimize import linprog as lp
import numpy as np
# minimize: 0.06x + 0.08y + 0.01z
# subject to:
#   4x +  y + 10z >= 10
#   3x + 2y +   z >= 12
#        4y +  5z >= 20
#         x, y, z >= 0

A = np.array([[-4, -1, -10], [-3, -2, -1], [0, -4, -5]])
b = np.array([-10, -12, -20])
pills = lp(np.array([0.06, 0.08, 0.01]), A, b)

print("Pill #1=", pills.x[0],
      "Pill #2=", pills.x[1],
      "Pill #3=", pills.x[2],)
print("Minimum cost=",
      0.06 * pills.x[0] + 0.08 * pills.x[1] + 0.01 * pills.x[2])

# 9. An electronics store stocks high-end DVD players, surround sound systems, and televisions.
# They have limited storage space and can stock a maximum of 210 of these three machines.
# They know from past experience that they should stock twice as many DVD players as stereo
# systems and at least 30 television sets. If each DVD player sells for $450, each surround
# sound system sells for $2000, and each television sells for $750, how many of each should be
# stocked and sold for maximum revenues? What is the maximum revenue?

from scipy.optimize import linprog as lp
import numpy as np
# maximize: 450x + 2000y + 750z
# subject to:
#   x + y + z <= 210
#   x >= 2y
#   z >= 30
#   x, y, z >= 0

A = np.array([[1, 1, 1], [-1, 2, 0], [0, 0, -1]])
b = np.array([210, 0, -30])
units = lp(np.array([-450, -2000, -750]), A, b)

print("DVDs =", units.x[0],
      "SS Systems=", units.x[1],
      "TVs =", units.x[2],)
print("Maximum revenue=",
      450 * units.x[0] + 2000 * units.x[1] + 750 * units.x[2])

# 10. A fast-food company is conducting a sweepstakes, and ships two boxes of game pieces to a
# particular franchise. Box A has 4% of its contents being winners, while 5% of the contents of
# box B are winners. Box A contains 27% of the total tickets. The contents of both boxes are
# mixed in a drawer and a ticket is chosen at random. Using Python, find the probability it
# came from box A if it is a winner.

is_box_a  = 0.27
box_a_win = 0.04
box_b_win = 0.05

a = is_box_a * box_a_win
b = (1 - is_box_a) * box_b_win
prob = a / (a + b)

print("Probability that winner came from Box A is",
      round(prob * 100, 3), "%.")

# Heatmap of probabilities for drawing random card
import pandas as pd
import seaborn as sns

a2 = is_box_a * (1 - box_a_win)
b2 = (1 - is_box_a) * (1 - box_b_win)
prob2 = a  / (a + b + a2 + b2)
prob3 = b  / (a + b + a2 + b2)
prob4 = a2 / (a + b + a2 + b2)
prob5 = b2 / (a + b + a2 + b2)

df = pd.DataFrame([[prob2, prob4], [prob3, prob5]],
                  index = ['Box A', 'Box B'],
                  columns = ['Winner', 'Loser'])
sns.heatmap(df)


import pandas as pd
import numpy as np
from scipy.integrate import solve_ivp, odeint
import matplotlib.pyplot as plt

"""
Transmission rate = What percentage of contacts do you transmit the disease to?
Contact rate = Number of contacts per unit time. Here we can define "unit of time" as 1 day.

If TR = 30% and CR = 1 person per day, then beta = 0.3
Where Beta is effective contact rate

If A people recover or die every B days (unit of time), then removal rate is A/B.
However, the model does not take into account the population change due to deaths (or new births).
"""

# Function for simulating a simple SIR model which takes population,
def sir_simple(t, state, N, beta, gamma):
    #state is a shape(n,) array
    S, I, R = state
    dSdt = - (beta * I * S)/N
    dIdt = ((beta * I * S)/N) - (gamma * I)
    dRdt = gamma * I
    return dSdt, dIdt, dRdt

def sir_vitaldynamics(t, state, N, beta, gamma, death_rate, birth_rate):
    #state is a shape(n,) array
    S, I, R = state
    dSdt = birth_rate - (death_rate * S) - (beta * I * S)/N
    dIdt = ((beta * I * S)/N) - (gamma * I) - (death_rate * I)
    dRdt = (gamma * I) - (death_rate * R)
    return dSdt, dIdt, dRdt

if __name__ == '__main__':
    beta = 0.25 # 1/beta is the typical time between contacts
    gamma = 0.1 # 1/gamma is the typical time until removal

    #The R0 of the disease is beta/gamma = 0.3/0.1 = 3

    population = 1000
    removed = 0
    infected = 1
    susceptible = population - infected - removed
    time_eval = np.linspace(start=0, stop=365, num=365)
    time_span = (time_eval[0], time_eval[len(time_eval) - 1])

    death_rate = 0.004
    birth_rate = 0.005

    """Documentation: https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html"""
    res = solve_ivp(fun=sir_simple, t_span=time_span, y0=[susceptible, infected, removed],
                    args=(population, beta, gamma), t_eval=time_eval)

    df_sir = pd.DataFrame({"time": res.t, "susceptible":res.y[0], "infected":res.y[1], "removed":res.y[2]})

    res2 = solve_ivp(fun=sir_vitaldynamics, t_span=time_span, y0=[susceptible, infected, removed],
                    args=(population, beta, gamma, death_rate, birth_rate), t_eval=time_eval)

    df_sir2 = pd.DataFrame({"time":res2.t, "susceptible":res2.y[0], "infected":res2.y[1], "removed":res.y[2]})

    #Plotting the pandemic
    plt.style.use('fivethirtyeight')
    df_sir2.plot(x='time')
    plt.show()


import numpy as np

class SimpleSolver:
    def __init__(self, A, b, N_idx, B_idx, C):
        self.A = A
        self.b = b
        self.N_idx = N_idx
        self.B_idx = B_idx
        self.C = C

        self.x_B = np.zeros(len(B_idx))
        self.x_N = np.zeros(len(N_idx))

    def solve(self, max_iter=100):
        optimal_solution = np.zeros(len(self.B_idx) + len(self.N_idx))

        for itr in range(max_iter):
            print("N_idx is ", [i + 1 for i in self.N_idx])
            print("B_idx is ", [i + 1 for i in self.B_idx])

            b_hat = np.linalg.inv(self.A[:, self.B_idx]).dot(self.b)
            print("b_hat is ", b_hat)

            c_hat_N = self.C[self.N_idx] - self.A[:, self.N_idx].T.dot(
                np.linalg.inv(self.A[:, self.B_idx]).T
            ).dot(self.C[self.B_idx])
            print("c_hat_N is", c_hat_N)
            if np.max(c_hat_N) <= 0:
                z = self.C[self.B_idx].T.dot(b_hat)
                optimal_solution[self.B_idx] = b_hat
                print("Done!")
                print("optimal z is ", z)
                print("optimal solution is ", optimal_solution)

                break

            k = np.where(c_hat_N > 0)[0][-1]

            a_hat_k = self.A[:, self.N_idx][:, k]
            print("a_hat_k", a_hat_k)
            if np.max(a_hat_k) <= 0:
                break

            temp_thetas = [b_hat[i] / a_ik for i, a_ik in enumerate(a_hat_k)]
            min_i = np.argmin(temp_thetas)
            theta = temp_thetas[min_i]

            self.x_N[k] = theta
            self.x_B = b_hat - theta * a_hat_k

            print(f"swap x_{self.B_idx[min_i]+1} ans x_{self.N_idx[k]+1}")
            temp_i = self.B_idx[min_i]
            temp_k = self.N_idx[k]
            self.B_idx[min_i] = temp_k
            self.N_idx[k] = temp_i

            temp_x_i = self.x_B[min_i]
            temp_x_k = self.x_N[k]
            self.x_B[min_i] = temp_x_k
            self.x_N[k] = temp_x_i
            print("x_B is ", self.x_B)
            print("x_N is ", self.x_N)

        return optimal_solution, z

if __name__ == "__main__":
    print("example")
    A = np.array([[1, 1, 1, 0, 0], [1, 3, 0, 1, 0], [2, 1, 0, 0, 1]])
    b = np.array([6, 12, 10])
    B_idx = [2, 3, 4]
    N_idx = [0, 1]
    C = np.array([1, 2, 0, 0, 0])
    simplexsolver = SimpleSolver(A, b, N_idx, B_idx, C)
    simplexsolver.solve()

    print("2.4.1")
    A = np.array([[1, 1, 1, 1, 0, 0], [3, 4, 6, 0, 1, 0], [4, 5, 3, 0, 0, 1]])
    b = np.array([20, 100, 100])
    B_idx = [3, 4, 5]
    N_idx = [0, 1, 2]
    C = np.array([4, 8, 10, 0, 0, 0])
    simplexsolver = SimpleSolver(A, b, N_idx, B_idx, C)
    simplexsolver.solve()

    print("2.4.3")
    A = np.array([[1, 0, 1, 0], [20, 1, 0, 1]])
    b = np.array([1, 100])
    B_idx = [2, 3]
    N_idx = [0, 1]
    C = np.array([10, 1, 0, 0])
    simplexsolver = SimpleSolver(A, b, N_idx, B_idx, C)
    simplexsolver.solve()


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

# Data
alpha = 0.05
true_mean = 79.3
true_std = 0.3
print(f'True mean: {true_mean} | True std {true_std}')

for i,n in enumerate([10,20,50,100]):
    x = np.random.normal(loc=true_mean, scale=true_std, size=n)

    ### Frequentist model - Confidence interval ###
    x_bar = np.sum(x)/n
    z = norm.ppf(1-alpha/2)
    freq_left = round(x_bar - z*true_std/np.sqrt(n), 3)
    freq_right = round(x_bar + z*true_std/np.sqrt(n), 3)
    print('')
    print(f'n = {str(n).zfill(3)} | 95% confidence interval for mean: ({freq_left}, {freq_right})')

    ### Bayesian model - Credible interval ###
    """
    References:
        * https://stats.stackexchange.com/questions/82292/example-of-real-life-use-of-bayesian-inference-on-mu-from-a-normal-distribu
        * Casella, G. (1985). An Introduction to Empirical Bayes Data Analysis. The American Statistician, 39(2), 83-87.
    """
    # prior distribution
    prior_mean = 75
    prior_std = 4

    tau = 1/true_std**2
    b = 1/prior_std
    x_bar = np.sum(x)/n

    # posterior distribution
    theta_mean = (prior_mean*b + x_bar*n*tau) / (b + n*tau)
    theta_std = np.sqrt(1 / (b + n*tau))
    z = norm.ppf(1-alpha/2)

    bayesian_left = round(theta_mean - z*theta_std/np.sqrt(n), 3)
    bayesian_right = round(theta_mean + z*theta_std/np.sqrt(n), 3)

    print(f'n = {str(n).zfill(3)} | 95% credible interval for mean: ({bayesian_left}, {bayesian_right})')

    ### Plot the results ###
    plt.subplot(2,2,i+1)
    plt.title(f'Analysis with {n} data points')
    x_ = np.linspace(true_mean - 5*true_std, true_mean + 5*true_std, 500)
    y_ = norm.pdf(x_, loc=true_mean, scale=true_std) # true normal distribution
    plt.plot(x_, y_, label='original data')
    plt.vlines(true_mean, min(y_), max(y_), colors='k', label='true mean', zorder=2)
    plt.hlines(0.005,freq_left, freq_right, color='r', label='frequentist interval')
    plt.hlines(0.007,bayesian_left, bayesian_right, color='y', label='bayesian interval')
    plt.legend(loc="lower right")
    plt.tight_layout()
plt.show() # display all the graphs


import numpy as np
import matplotlib.pyplot as plt
import chaotic_maps as cm

fig, axes = plt.subplots(2, 2)
cm.cobweb_plot(cm.sin_map(.7), .1, 50, domain=np.linspace(0, 1), ax=axes[0][0], ylabel=r'$x_{n+1}$')
cm.cobweb_plot(cm.sin_map(.8), .1, 10, domain=np.linspace(0, 1), ax=axes[0][1])
cm.cobweb_plot(cm.sin_map(.85), .1, 50, domain=np.linspace(0, 1), ax=axes[1][0], xlabel=r'$x_n$', ylabel=r'$x_{n+1}$')
cm.cobweb_plot(cm.sin_map(.9), .1, 150, domain=np.linspace(0, 1), ax=axes[1][1], xlabel=r'$x_n$')
axes[0][0].set_title(r'$\mu = 0.7$')
axes[0][1].set_title(r'$\mu = 0.8$')
axes[1][0].set_title(r'$\mu = 0.85$')
axes[1][1].set_title(r'$\mu = 0.9$')
plt.tight_layout()
plt.savefig("sin_cobwebs.png", dpi=300)

cm.bifurcation_and_lyapunov_plots(
   cm.sin_map,
   init=0.2,
   parameter_range=np.linspace(0.6, 1, num=10000),
   deriv_generator=cm.sin_map_deriv,
   y_points=500,
   xlabel=r"$\mu$",
   ylabel=r"$x$",
   file_name="sine.png",
)

fig, axes = plt.subplots(1,2, figsize=(12,5))

cm.bifurcation_plot(
    cm.gauss_map_family(alpha=5),
    init=0.1,
    parameter_range=np.linspace(-0.9, 1, 10000),
    y_points=500,
    xlabel=r"$\beta$",
    ylabel=r"$x$",
    set_title=r"$\alpha = 5$",
    ax=axes[0]
)

cm.bifurcation_plot(
    cm.gauss_map_family(alpha=6.5),
    init=0.1,
    parameter_range=np.linspace(-0.9, 1, 10000), #10000
    y_points=500,
    xlabel=r"$\beta$",
    ylabel=r"$x$",
    set_title=r"$\alpha = 6.5$",
    ax=axes[1]
)

plt.savefig("gauss.png", dpi=300)


import sys
import getopt
import numpy as np
import matplotlib.pyplot as plt
import math
import pywt
from scipy.fftpack import dct, idct
from PIL import Image

'''
References:
    https://sukhbinder.wordpress.com/2014/09/11/karhunen-loeve-
    transform-in-python/

    http://stackoverflow.com/questions/3680262/how-to-slice-a-2d-python-
    array-fails-with-typeerror-list-indices-must-be-int

    http://stackoverflow.com/questions/16856788/slice-2d-array-into-smaller
    -2d-arrays
'''

def KLT(array):

    val, vec = np.linalg.eig(np.cov(array))
    klt = np.dot(vec, array)
    return klt, vec, val

def load_image_as_array(imgFile):
	img = Image.open(imgFile)
	imgArray = np.asarray(img)

	return imgArray

def get_2d_list_slice(self, matrix, start_row, end_row, start_col, end_col):
    return [row[start_col:end_col] for row in matrix[start_row:end_row]]

"""
Return an array of shape (n, nrows, ncols) where
n * nrows * ncols = arr.size

If arr is a 2D array, the returned array should look like n subblocks with
each subblock preserving the "physical" layout of arr.
"""
def blockshaped(arr, nrows, ncols):
    h, w = arr.shape
    return (arr.reshape(h//nrows, nrows, -1, ncols)
               .swapaxes(1,2)
               .reshape(-1, nrows, ncols))

"""
Return an array of shape (h, w) where
h * w = arr.size

If arr is of shape (n, nrows, ncols), n sublocks of shape (nrows, ncols),
then the returned array preserves the "physical" layout of the sublocks.
"""
def unblockshaped(arr, h, w):
    n, nrows, ncols = arr.shape
    return (arr.reshape(h//nrows, -1, nrows, ncols)
               .swapaxes(1,2)
               .reshape(h, w))

def dct_loop(img_array, loop_times):
    i = 0

    for i in range(0, loop_times):
        # slice into 8x8 chunks
        blockArr = blockshaped(img_array, 8, 8)

        # run DCT on each chunk
        j = 0
        for j in range (0, 4096): # for all the 8x8 blocks
            blockArr[j] = dct(np.array(blockArr[j]), 2, norm='ortho')

        # reshape
        dct_arr = unblockshaped(blockArr, 512, 512)
        img_array = dct_arr

    return dct_arr

def idct_loop(img_array, loop_times):
    i = 0

    for i in range(0, loop_times):
        # slice into 8x8 chunks
        blockArr = blockshaped(img_array, 8, 8)

        # run DCT on each chunk
        j = 0
        for j in range (0, 4096):
            blockArr[j] = idct(np.array(blockArr[j]), 2, norm='ortho')

        # reshape
        dct_arr = unblockshaped(blockArr, 512, 512)
        img_array = dct_arr

    return dct_arr

def calculate_error(img1_arr, img2_arr):
    arr1 = img1_arr.ravel()
    arr2 = img2_arr.ravel()

    i = 0
    error = 0.0
    for i in range (0, 262144):
        error += math.exp(int(arr1[i]) - int(arr2[i]))
        error = error / 262144

    return error

def main(argv):
    inputFile = ""

    # load file with command line args
    try:
        opts, args = getopt.getopt(argv,"i:")
    except getopt.GetoptError:
        print("USAGE: python3 main.py -i <file>")
        sys.exit(2)

    for opt, arg in opts:
        if opt == "-i":
            inputFile = arg
        else:
            print("USAGE: python3 main.py -i <file>")
            sys.exit()

    if (inputFile is ""):
        print("USAGE: python3 main.py -i <file>")
        sys.exit()

    # load image as array
    print("Loading image...")
    imgArr = load_image_as_array(inputFile)
    print("    Image loaded!")
    print()

    # do klt
    print("Determining KLT values...")
    ktm, vect, val = KLT(imgArr);
    print("    Found KLT values!")
    print()

    # run it through DCT 8x8 at a time
    # 4096 8x8 blocks in 512 x 512 array
    # 64 blocks in row, col

    print("Printing image array...")
    print(imgArr)
    print("    Done!")
    print()

    print("Applying one-level DWT...")
    coeffs = pywt.dwt2(imgArr, 'haar')
    cA, (cH, cV, cD) = coeffs
    print("    Done!")

    dwtCompList = [cA, cH, cV, cD]
    stitchArr = unblockshaped(np.array(dwtCompList), 512, 512)

    print("Displaying image...")
    #pass1 = Image.fromarray(stitchArr, 'L')
    pass1 = Image.fromarray(stitchArr)
    pass1.show()
    #pass1.save('DWT2D_transform.spi', format='SPIDER')
    print("    Done!")

    print("Applying inverse transform and displaying image...")
    finalArr = np.array((pywt.idwt2(coeffs, 'haar')), dtype=np.uint8)
    pass2 = Image.fromarray(finalArr)
    pass2.save('iDWT2D_reconstruction.bmp')
    print("    Done!")
    print()

    '''
    Calculate the error between the two images
    '''
    print("Calculating error between the original image and final...")
    imgError = calculate_error(np.asarray(imgArr), np.asarray(finalArr))
    print ("Mean squared error: ""{:.12}%".format(float(imgError * 100)))

if __name__ == "__main__":
	main(sys.argv[1:])


import numpy as np
def unitStep(v):
    if v>=0:
        return 1
    else:
        return 0

def perceptronModel(x,w,b):
     v = np.dot(w,x)+b
     y= unitStep(v)
     return y

def OR_logicfunction(x):
     w = np.array([0.5,0.5])
     b = -0.3
     return perceptronModel(x,w,b)

test1 = np.array([0, 0])
test2 = np.array([0, 1])
test3 = np.array([1, 0])
test4 = np.array([1, 1])

print("OR({},{}) = {}".format(0, 0,OR_logicfunction(test1)))
print("OR({},{}) = {}".format(0, 1, OR_logicfunction(test2)))
print("OR({},{}) = {}".format(1, 0, OR_logicfunction(test3)))
print("OR({},{}) = {}".format(1, 1, OR_logicfunction(test4)))


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

Xvet = np.array([8,12], dtype=np.float)
Fvet = np.array([ 0.9030900,1.0791812], dtype=np.float)

def polinom(coefs,x):
    resultado = 0
    for i in range(0,len(coefs)):
        resultado = resultado + coefs[i]*math.pow(x,i)

    return resultado

def Interpol(xs, fs):
    M = np.zeros((len(xs),len(xs)), dtype=np.float)
    Y = fs.copy()

    for j in range(0,len(xs)):
        for i in range(0,len(xs)):
            M[i][j] = math.pow(xs[i],j)

    coefs = ElimGauss(M,Y)
    return coefs

def ElimGauss(matriz, coef):
    A = matriz.copy()
    b = coef.copy()

    for i in range(0, len(coef)):
        for j in range(0, len(coef)):
            if ( i != j) :
                fator = A[j][i]/A[i][i]
                b[j] = b[j] -fator*b[i]
                for k in range(0,len(coef)):
                    A[j][k] = A[j][k] - fator*A[i][k]

    for i in range(0,len(coef)):
        b[i] = b[i] / A[i][i]
        A[i][i] = 1

    return b

coefs = Interpol( Xvet, Fvet)
#print(coefs)
x = 10
y = polinom(coefs,x)
print("O valor do polinômio interpolador no ponto "+str(x)+" eh "+str(y))
erro = abs( math.log( x, 10) - y  )/abs(math.log( x, 10) )
print("O erro relativo eh "+str(erro*100)+"%")


"""
This code implements a linear regression per week 3 assignment of the machine learning module part of Columbia University Micromaster programme in AI.
Written using Python 3.X for running on Vocareum
"""

# builtin modules
import os
#import psutil
import requests
import sys
import math

# 3rd party modules
import pandas as pd
import numpy as np

def RidgeRegression(X, y, l:int = 2):

    """
    This function implements the ℓ2 -regularized least squares linear regression algorithm (aka ridge regression) which takes the form:
    wRR=argminw(∥y−Xw∥^2 ) + λ * ∥w∥^2.

    Inputs:
    y : vector 'y' from the split dataset
    X : matrix 'X' from the split dataset
    l : an arbitray value for lambda "λ"

    Outputs:
    wRR : calculated as expressed above
    """
    n, m = X.shape
    I = np.identity(m)
    cov_matrix = np.linalg.inv(np.dot(X.T, X) + l * I)
    wRR = np.dot(np.dot(cov_matrix, X.T), y)
    #_, S, _ = np.linalg.svd(X)
    #deg_f = np.sum(np.square(S) / (np.square(S) + l))

    return wRR

def update_posterior(X, y, xx_old, xy_old, l:int = 2, sigma2:int = 3):
    n, m = X.shape
    I = np.identity(m)

    xx_old = np.dot(X.T, X) + xx_old  # XoXoT + XiXiT
    xy_old = np.dot(X.T, y) + xy_old  # Xoyo + Xiyi

    new_cov = np.linalg.inv(l * I + (1 / sigma2) * xx_old) # new covariance Σ, captures uncertainty about w as Var[wRR]
    new_mean = np.dot((np.linalg.inv(l * sigma2 * I + xx_old)),xy_old) # new µ

    return new_cov, new_mean, xx_old, xy_old

def activeLearning(X, y, X_test, l:int = 2, sigma2:int = 3):

    n, m = X.shape

    I = np.identity(m)

    X_indexes = []

    # set up an xx_old and xy_old to zero to start with
    xx_old = np.zeros((m, m))
    xy_old = np.zeros(m)

    new_cov, new_mean, xx_old, xy_old = update_posterior(X, y, xx_old, xy_old, l, sigma2)

    #Select the 10 data points to measure as per the assignment requirements
    for i in range(10):
        # Pick x0 for which sigma20 is largest

        cov_matrix = np.dot(np.dot(X_test, new_cov), X_test.T)
        row_largest = np.argmax(np.diagonal(cov_matrix))

        # update x and y values
        # first reset indexes for X_test dataframe so you can call it from its row index number using 'row_largest'
        #X_test = X_test.reset_index(drop=True) #this line is not needed when running in Vocareum presumuably because the X_data.csv does not include an index column.
        # then get x0 and pass it onto the X matrix
        #x0 = X_test.iloc[[row_largest]].to_numpy()[0]
        # use the following when running on Vocareum
        x0 = X_test[row_largest] #.to_numpy()[0]

        #X.loc[row_largest] = x0

        # use the following when running on Vocareum
        X[row_largest] = x0

        # calculate y0 and update the y vector
        y0 = np.dot(X, new_mean)
        y = y0

        #row, _ = X_test.shape
        #X_index = list(range(row))[row_largest]
        X_indexes.append(row_largest)

        # Remove x0
        #X_test = X_test.drop(index = row_largest)

        # use the following when running on Vocareum
        X_test = np.delete(X_test, (row_largest), axis=0)
        # Update the posterior distribution
        new_cov, new_mean, xx_old, xy_old = update_posterior(X, y, xx_old, xy_old, l, sigma2)

    # Create 1-based indexes
    X_indexes = [i + 1 for i in X_indexes]

    return X_indexes

def main():
    """
    ## $ python3 hw1_regression.py lambda sigma2 X_train.csv y_train.csv X_test.csv
    """
    # get inputs into local variables
    lambda_input = int(sys.argv[1])
    sigma2_input = float(sys.argv[2])
    X_train = np.genfromtxt(sys.argv[3], delimiter = ",")
    y_train = np.genfromtxt(sys.argv[4])
    X_test = np.genfromtxt(sys.argv[5], delimiter = ",")

    #### Part 1
    wRR = RidgeRegression(X_train, y_train, lambda_input)
    # write the output csv file with the wRR values
    np.savetxt("wRR_" + str(lambda_input) + ".csv", wRR, fmt='%1.2f', delimiter="\n")

    #### Part 2
    X_indexes = activeLearning(X_train, y_train, X_test, lambda_input, sigma2_input)
    # write the output csv file
    np.savetxt("active_" + str(lambda_input) + "_" + str(int(sigma2_input)) + ".csv", X_indexes, fmt='%.d', delimiter="\n")

if __name__ == '__main__':
    main()


'''
AlvinXY Utility Module

All of this is based on WHOI's original implementations in C and MATLAB.

'''

from math import *
import numpy as np

def  mdeglat(lat):
    '''
    Provides meters-per-degree latitude at a given latitude

    Args:
      lat (float): latitude

    Returns:
      float: meters-per-degree value
    '''
    latrad = lat*2.0*pi/360.0 ;

    dy = 111132.09 - 566.05 * cos(2.0*latrad) \
         + 1.20 * cos(4.0*latrad) \
         - 0.002 * cos(6.0*latrad)
    return dy

def mdeglon(lat):
    '''
    Provides meters-per-degree longitude at a given latitude

    Args:
      lat (float): latitude in decimal degrees

    Returns:
      float: meters per degree longitude
    '''
    latrad = lat*2.0*pi/360.0
    dx = 111415.13 * cos(latrad) \
         - 94.55 * cos(3.0*latrad) \
	+ 0.12 * cos(5.0*latrad)
    return dx

def ll2xy(lat, lon, orglat, orglon):
    '''
    AlvinXY: Lat/Long to X/Y
    Converts Lat/Lon (WGS84) to Alvin XYs using a Mercator projection.

    Args:
      lat (float): Latitude of location
      lon (float): Longitude of location
      orglat (float): Latitude of origin location
      orglon (float): Longitude of origin location

    Returns:
      tuple: (x,y) where...
        x is Easting in m (Alvin local grid)
        y is Northing in m (Alvin local grid)
    '''
    x = (lon - orglon) * mdeglon(orglat);
    y = (lat - orglat) * mdeglat(orglat);
    return (x,y)

def xy2ll(x, y, orglat, orglon):

    '''
    X/Y to Lat/Lon
    Converts Alvin XYs to Lat/Lon (WGS84) using a Mercator projection.

    Args:
      x (float): Easting in m (Alvin local grid)
      x (float): Northing in m (Alvin local grid)
      orglat (float): Latitude of origin location
      orglon (float): Longitude of origin location

    Returns:
      tuple: (lat,lon)
    '''
    lon = x/mdeglon(orglat) + orglon
    lat = y/mdeglat(orglat) + orglat

    return (lat, lon)

# Vectorize
vxy2ll = np.vectorize(xy2ll)
vll2xy = np.vectorize(ll2xy)


import numpy as np
import matplotlib.pyplot as plt
import scipy.interpolate as si
plt.style.use('dark_background')

def f(x) :

    s = 1/(1+25*np.power(x,2))

    return s

n=20
x_nodes=[]
for e in range(0,n) :
    s = np.cos(((2*e+1)/(n+1))*(np.pi/2))
    x_nodes.append(s)

y_val=f(x_nodes)
polynomial = si.lagrange(x_nodes, y_val)

#x=np.linspace(-1,1,1000)
#y=polynomial(x)

x=[]
for e in range(0,n) :
    s = np.cos(((2*e+1)/(n+1))*(np.pi/2))
    x.append(s)

y=polynomial(x)

plt.plot(x,f(x),'blue')
plt.plot(x,y,'cyan')
plt.plot(x_nodes,y_val,'go')

plt.xlabel('x')
plt.ylabel('y')
plt.xlim(-1.1,1.1)
plt.ylim(-0.3,1.2)
plt.legend(['f(x)','Lagrange/Chebyshev','points'])
plt.show()


'''
Created on 2 Jul 2013

@author: Matthew Daggitt
'''

from scipy import stats
import numpy as np

from core.geom import Line

def calculateSingleLineRegression(xs,ys):
    """ Returns the least squares regression line through the provided coordinates """
    if len(xs) == 2:
        # Case needed as stats.linregress occasionaly throughs warnings for length 2 datasets
        slope = (ys[1]-ys[0])/(xs[1]-xs[0])
        intercept = ys[0] - slope*xs[0]
    else:
        slope, intercept = stats.linregress(xs, ys)[0:2]

    return Line(slope,intercept)

def residualSumOfSquares(xs,ys,func):
    """Return the residual sum of squares."""
    return sum([(func(xs[i])-ys[i])**2 for i in range(len(xs))])

def meanRelativeSquaredError(xs,ys,func):
    """Return the mean relative squared error."""
    return sum([((func(x)-y)/y)**2 for x, y in zip(xs,ys)])/len(xs)

def calculateMultiLineRegression(xs, ys, numberOfSegments):
    """
    Fits a specified number of linear segments to the provided data

    Arguments
    xs -- the x coordinates of the data
    ys -- the y coordinates of the data
    numberOfSegments -- the number of linear segments to fit to the data

    Returns
    segmentLines:list           --  list of Line objects each representing a linear segment
    segmentLimits:list          --  list of n+1 integers, segmentLines[i] is valid between segmentLimits[i] and segmentLimits[i+1]
    """

    xs, ys = zip(*sorted(zip(xs,ys), key=lambda x: x[0]))

    uniqueXValues = set(xs)
    m = len(uniqueXValues)
    if len(uniqueXValues) < numberOfSegments*2:
        raise ValueError("Cannot perform linear regression for " + str(numberOfSegments) + " segment" +
                         (" " if numberOfSegments == 1 else "s ") +
                         "with only " + str(m) + " unique x-value" + (" " if m == 1 else "s "))

    n = len(xs)
    allLines = {}
    allErrors = {}

    for j in range(1,n):
        for i in range(0,j):
            segXs, segYs = xs[i:j+1], ys[i:j+1]
            allLines[(i,j)] = calculateSingleLineRegression(segXs,segYs)
            allErrors[(i,j)] = residualSumOfSquares(segXs,segYs,allLines[(i,j)].calcY) if allLines[(i,j)] is not None else float("inf")

    minTraversal = _findMinTraversal(allErrors,n,numberOfSegments)
    segmentLines = [allLines[(x,y)] for (x,y) in minTraversal]
    segmentLimits = _calculateSegments(xs,ys,segmentLines,minTraversal)

    return (segmentLines, segmentLimits)

def _calculateSegments(xs,ys,lines,minTraversal):
    bounds = [xs[0]]
    for i in range(0,len(lines)-1):
        intersectionPoint = lines[i].intersection(lines[i+1])
        if intersectionPoint is None or lines[i].m > lines[i+1].m:
            bounds.append((xs[minTraversal[i][1]]+xs[minTraversal[i+1][0]])/2)
        else:
            bounds.append(intersectionPoint.x)
    bounds.append(xs[-1])

    return bounds

def _findMinTraversal(scores,numberOfPoints,numberOfSteps):

    traversals = _compilePossibleTraversals(0,numberOfPoints,numberOfSteps)

    minScore = float("inf")
    minTraversal = []
    for t in traversals:
        currentScore = 0
        for (x,y) in t:
            currentScore += scores[(x,y)]
        if currentScore < minScore:
            minScore = currentScore
            minTraversal = t

    return minTraversal

def _compilePossibleTraversals(start,end,n):
    if start == end and n == 0:
        return [[]]
    elif start == end or n == 0:
        return None
    else:
        possiblities = []
        for i in range(start+1,end):
            results = _compilePossibleTraversals(i+1,end,n-1)
            if results != None:
                for r in results:
                    r = r.insert(0,(start,i))
                possiblities += results
        return possiblities


from numpy.linalg import eig, inv, norm, cond
import numpy as np
from tabulate import tabulate

myA=[
 [-0.81417, -0.01937, 0.41372],
 [-0.01937, 0.54414, 0.00590],
 [0.41372, 0.00590, -0.81445]
]

def Jacobi(n, A, epsilon):
 E = np.eye(n)
 C = B = np.ones((n, n))
 Akplus1 = Ak = A
 ik = jk = 0
 diagA = np.triu(Ak, k=0)
 maxel = 0
 X = np.zeros((n, n))
 for i in range(n):
  for j in range(n):
   if abs(Ak[i][j]) > maxel:
    maxel = Ak[i][j]
    ik = i
    jk = j
   if maxel >= epsilon:
    Akplus1 = rotate(Ak, Akplus1, ik, jk, n)
  Ak = Akplus1
 eigval = np.diag(Akplus1)
 eigvect = C
 return eigval, eigvect

def rotate(Ak, Akplus1, ik, jk, n):
 d = np.sqrt((Ak[ik][ik] - Ak[jk][jk]) ** 2 + 4 * (Ak[ik][jk] ** 2))
 c = np.sqrt(0.5 * (1 + abs(Ak[ik][ik] - Ak[jk][jk]) / d))
 s = np.sign(Ak[ik][jk] * (Ak[ik][ik] - Ak[jk][jk])) * np.sqrt(0.5 * (1 - abs(Ak[ik][ik] - Ak[jk][jk]) / d))
 Akplus1[ik][ik] = c ** 2 * Ak[ik][ik] - 2 * c * s * Ak[ik][jk] + s ** 2 * Ak[jk][jk]
 Akplus1[jk][jk] = s ** 2 * Ak[ik][ik] - 2 * c * s * Ak[ik][jk] + c ** 2 * Ak[jk][jk]
 Akplus1[ik][jk] = Akplus1[jk][ik] = 0
 for l in range(n):
  for m in range(n):
   if l != ik & l != jk & m != ik & m != jk:
    Akplus1[l][m] = Ak[l][m]
   elif l != ik & l != jk:
    Akplus1[l][ik] = Akplus1[ik][l] = c * Ak[l][ik] + s * Ak[l][jk]
    Akplus1[l][jk] = Akplus1[jk][l] = -s * Ak[l][ik] + c * Ak[l][jk]
 return Akplus1

def frobnorm(A):
 sum = 0.0
 for i in range(len(A)):
  for j in range(len(A[0])):
   sum += abs(A[i][j])
 return sum ** 0.5

def aposter(A, Y, l):
 return frobnorm(A @ Y - l * Y) / frobnorm(Y)

def powermethod(n, A, epsilon):
 Yk = [1, 1, 1]
 maxl = maxk = 0
 l = l_ = 0
 for i in range(n):
     k = 0
     while (k >= 0):
         Ykplus1 = A @ Yk
         l_ = Ykplus1[i] / Yk[i]
         if abs(l - l_) < epsilon & abs(l_) > maxl:
             maxl = l_
             maxk = k
             k = 0
             break
         l = l_
         k += 1
     Yk = Ykplus1
 return maxl, maxk, Ykplus1

def dotproductmethod():
 Y0 = np.ones((3, 1))

print("Вариант 1:")
# 1)
epsilon = 0.000001
eig = Jacobi(3, myA, epsilon)
#eig1 = np.linalg.eig(myA)
print(eig[0])
#rint(eig1[0])

# 2)
epsilon = 0.001


import math
import numpy as np

def correlation( x, y ):
	if len( x ) != len( y ):
		print( 'arrays must have same dimension' )
	else:
		n = len( x )

		xy = x*y
		xsq = x ** 2
		ysq = y ** 2

		m1 = n * sum( xy ) - sum( x ) * sum( y )
		m2 = n * sum( xsq ) - sum( x ) ** 2

		m = m1/m2

		b = ( sum( y ) - m * sum( x ) ) / n

		return m, b

if __name__ == '__main__':

	x = np.array( [ 20.00, 30.00, 40.00, 50.00, 60.00, 70.00, 80.00, 90.00, 100.00, 110.00 ] )
	y = np.array( [ 71.20, 80.50, 73.40, 60.30, 52.10, 56.20, 46.50, 36.90, 34.00, 39.10 ] )

	correlation( x, y )


"""
Author: Shreck Ye
Date: June 16, 2019
Time complexity: O(log(N))
Note: the solution does not run on LeetCode because importing NumPy is currently not supported by LeetCode.

Let's think in the mathematical way. Obviously, the recursion formula represents a linear relationship.
By viewing it as a recursion formula of a single vector F_n = (f_n, f_{n + 1})' with a transition matrix M = (0, 1; 1, 1),
which is (f_{n + 1}, f_{n + 2})' = (0, 1; 1, 1) (f_n, f_{n + 1})' namely F_{n + 1} = M F_n,
we can get the result using matrix exponentiation and reduce the number of recursions.
"""
import numpy as np

F_0 = np.array([0, 1])
M = np.array([[0, 1], [1, 1]])

class Solution:
    def fib(self, N: int) -> int:
        return np.matmul(np.linalg.matrix_power(M, N), F_0)[0]

# Test cases
s = Solution()
print(s.fib(0), s.fib(1), s.fib(2), s.fib(3), s.fib(4), s.fib(5))


import numpy as np

def TrapezoidalMethod(f, a, b, n):
    I = 0
    for i in np.linspace(a,b,num=n,endpoint=False)[1:]:
        I = I + f(i)
    I = ( b - a ) * ( I * 2 + f(a) + f(b) ) / ( 2 * n)
    return I

def Simpsons13Rule(f, a, b ):
    return (b - a) / 6 * ( f(a)  + 4 * f((a + b) / 2) + f(b) )

def Simpsons13Rule_n(f, a, b, n):
    h = (b - a)/n
    even = []
    odd = []
    for i, v in enumerate(np.linspace(a, b, num= n , endpoint=False)[1:]):
        if not(i % 2):
            even.append(v)
        elif (i % 2):
            odd.append(v)
    I = (b - a) * (f(a) + 4 * sum(map(f, even)) + 2 * sum(map(f, odd)) + f(b))/( 3 * n )
    return I

def GaussQuadrature_nPoint(f, a, b, n):
    X, C = np.polynomial.legendre.leggauss(n)

    g = lambda t: f(t *(b - a)/2 + (b + a)/2) * (b - a)/2

    I = 0
    for i in range(1 - 1, n + 1 - 1):
        I += C[i] + g(X[i])
    return I


from typing import TypeVar
from numbers import Number
import math
import numpy as np

__version__ = None

try:
    import pkg_resources

    __version__ = pkg_resources.get_distribution("datasci").version
except Exception:
    pass

Numeric = TypeVar("Numeric", Number, np.ndarray)

def logistic(x: Numeric) -> Numeric:
    """
    Compute the standard logistic function,
    which maps x ∈ ℝ into the range (0, 1).
    As x → +∞, logistic(x) → 1
    As x → -∞, logistic(x) → 0
    """
    return 1 / (1 + np.exp(-x))

def logit(p: Numeric) -> Numeric:
    """
    Compute the logit (AKA log-odds) function,
    which maps a probability into ℝ.
    """
    assert 0.0 <= p <= 1.0, "p must be in the range [0, 1]"
    if p == 0:
        return -math.inf
    if p == 1:
        return math.inf
    return np.log(p / (1 - p))


import numpy as np
import matplotlib.pyplot as plt
from scipy.fftpack import dct, idct
from cosamp_fn import cosamp
import cvxpy as cvx

n = 4096 # High resolutions samples
t = np.linspace(0,1,n)
x =  np.cos(2 * 97 * np.pi * t) + np.cos(2 * 777 * np.pi * t)

## Randomly samples the signal
p = 128
perm = np.floor(np.random.rand(p) * n).astype(int)
# perm = np.random.choice(n, p, replace=False)
# perm.sort()
y = x[perm]

## Plot
time_window = np.array([1024, 1280])/n

fig,axes = plt.subplots(1,2)
axes = axes.reshape(-1)

axes[0].plot(t,x)
axes[0].plot(t[perm],y,'x',ms = 12)
axes[0].set_xlim(time_window[0],time_window[1])
axes[0].set_ylim(-2,2)

# ## Solve compressed sensing problem
Psi = dct(np.identity(n))
print(Psi.shape)
Theta = Psi[perm,:]
s = cosamp(Theta,y,10,epsilon=1.e-50,max_iter=1000)
xrecon = idct(s)

## Solve with other methods
# vx = cvx.Variable(n)
# objective = cvx.Minimize(cvx.norm(vx, 1))
# constraints = [Theta*vx == y]
# prob = cvx.Problem(objective, constraints)
# result = prob.solve(verbose=True)
# s = np.array(vx.value)
# s = np.squeeze(s)
# xrecon = idct(s)

## Plot
axes[0].plot(t,xrecon,'r')
# axes[1].set_xlim(time_window[0],time_window[1])
# axes[1].set_ylim(-2,2)

axes[1].imshow(Theta)

plt.show()

print("Norm")
print(np.linalg.norm(x-xrecon, ord=2))
print(np.linalg.norm(xrecon, ord=1))


import numpy as np

input_data = np.array([1, 2, 3])

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

target = 0

# Calculate the predictions: preds
preds = (weights * input_data).sum()

# Calculate the error: error
error = preds - target

# Calculate the slope: slope
slope = input_data * error * 2

# Print the slope
print(slope)

## improving the model weights

# Set the learning rate: learning_rate
learning_rate = 0.01

# Calculate the predictions: preds
preds = (weights * input_data).sum()

# Calculate the error: error
error = preds - target

# Calculate the slope: slope
slope = 2 * input_data * error

# Update the weights: weights_updated
weights_updated = weights - (learning_rate * slope)

# Get updated predictions: preds_updated
preds_updated = (weights_updated * input_data).sum()

# Calculate updated error: error_updated
error_updated = preds_updated - target

# Print the original error
print(error)

# Print the updated error
print(error_updated)


#!/usr/bin/env python3

import math
from decimal import *

import numpy as np

# CHANGEME:
probtab = np.loadtxt(open("data/probability_table.csv", "rb"), delimiter=",").astype(Decimal)

print("The marginal probabilities of all the values of 𝑋")
print(probtab)
print("- " * 10)

px = np.sum(probtab, axis=0)
py = np.sum(probtab, axis=1)

print("P(X):", px)
print("P(Y):", py)

# sum of all columns and rows must be one
assert sum(px) == 1
assert sum(py) == 1

print("Shannon’s entropy of the plaintext")
print("𝐻(𝑋)=−∑𝑃(𝑥)log2𝑃(𝑥)")
hx = -sum([i * math.log2(i) for i in px])
print("-(", end="")
for i in px:
  print(f"{i:.3f}*log2({i:.3f})", end=" + ")
print(f") = {hx:.3f} bits")
print("- " * 10)

print("The conditional entropy 𝐻(𝑋|𝑌)")
print("𝐻(𝑋|𝑌)=−∑y∑x𝑃(𝑥,𝑦)log2𝑃(𝑥|𝑦)")
hxy = 0
print("-(", end="")
for k, i in zip(py, probtab):
  for j in i:
    hxy += (j * math.log2(j / k))
    print(f"{j}*log2({j}/{k})", end=" + ")
hxy = -hxy
print(f") = {hxy:.3f} bits")
print("- " * 10)

print("The mutual information")
print("𝐼(𝑋,𝑌)=𝐻(𝑋)−𝐻(𝑋|𝑌)")
print(f"{hx:.3f} - {hxy:.3f} = {(hx - hxy):.3f} bits")

if (hx - hxy) == 0:
  print("The cipher is perfectly secret")

else:
  print("The cipher is not perfectly secret because I(X,Y) != 0")
  # The uncertainty about the plaintext is reduced afer receieving the ciphertext


#-------------------------------------------------------------------------------
# Name:        module1
# Purpose:
#
# Author:      milad
#
# Created:     25/11/2020
# Copyright:   (c) milad 2020
# Licence:     <your licence>
#-------------------------------------------------------------------------------

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

Rn = np.random.seed(100)
N = 20
beta0 = -4
beta1 = 2
x = np.random.randn(N)
e = np.random.randn(N)

#If positive int_like arguments are provided, randn generates an array of shape (d0, d1, ..., dn),
#filled with random floats sampled from a univariate “normal” (Gaussian) distribution of mean 0 and variance 1.
# A single float randomly sampled from the distribution is returned if no argument is provided.

y = beta0 + beta1 * x + e

true_x = np.linspace(min(x), max(x), num=50)
true_y = beta0 + beta1*true_x

fig, ax = plt.subplots()
sns.scatterplot(x, y, s= 40, label = 'Data')
sns.lineplot(true_x, true_y, color = 'red', label = 'True Model')
ax.set_xlabel('x', fontsize = 14)
ax.set_title(fr"$y = {beta0} + ${beta1}$x + \epsilon$", fontsize = 16)
ax.set_ylabel('y', fontsize=14, rotation=0, labelpad=10)
ax.legend(loc = 4)
sns.despine() # will put the frame around the figure

plt.show()


import matplotlib
matplotlib.use('MacOSX')
import matplotlib.pyplot as plt
plt.style.use('./my.mplstyle')
import numpy as np

def set_axis(ax):
    ax.set_xlabel('log N')
    ax.set_xlim([1, 5])
    ax.set_ylabel(r'log(e)')
    ax.set_ylim([-4,  1])

def plot_n_slope(ax, log2N, I_err, color, label):
    logN = log2N * np.log10(2.)
    logErr = np.log10(abs(I_err))
    ax.plot(logN, logErr, 'o', color=color, label=label)

    m = np.polyfit(logN[-4:], logErr[-4:], 1)
    print(log2N[-4:])
    print (f"slope = {m[0]:6.3f}")
    print (f"norm = {m[1]:6.3f}")
#    x = np.linspace(0, 10, 1000)
#    ax.plot(x, m[1] + m[0] * x, color=color, linestyle=':')

fig = plt.figure(figsize=(10.5,8))
ax = fig.add_subplot(111)
set_axis(ax)

filename = 'advection_convergence_test.txt'
log2N, I1_err, I2_err, I3_err = np.loadtxt(filename, skiprows=0, usecols=(0,1,2,3), unpack=True)

plot_n_slope(ax, log2N, I1_err, 'tab:red', 'Lax-Friedrichs')
plot_n_slope(ax, log2N, I2_err, 'tab:orange', 'Upwind')
plot_n_slope(ax, log2N, I3_err, 'tab:green', 'Lax-Wendroff')

ax.legend()

plt.savefig('AdvectionError.pdf')