def returns_normal_tests(my_data):

    from scipy.stats import shapiro, anderson, normaltest

    print('---------------------------------------------')
    print('')
    stat, p = shapiro(my_data)
    alpha = 0.05
    if p > alpha:
    	print('Shapiro test fails to reject H0: looks normal :)')
    else:
    	print('Shapiro test rejects H0: not normal :(')
    print('')
    stat, p = normaltest(my_data)
    alpha = 0.05
    if p > alpha:
    	print("D%*\textcolor{codered}{$\textquotesingle$}*)Agostino and Pearson%*\textcolor{codered}{$\textquotesingle$}*)s test fails to reject H0: looks normal")
    else:
    	print("D%*\textcolor{codered}{$\textquotesingle$}*)Agostino and Pearson%*\textcolor{codered}{$\textquotesingle$}*)s test rejects H0: not normal")
    print('')
    result = anderson(my_data)
    print('Anderson-Darling test:')
    for sl, cv in zip(result.significance_level, result.critical_values):
    	if result.statistic < cv:
    		print('%.3f: fails to reject H0: Sample looks normal' % (sl))
    	else:
    		print('%.3f: rejects H0: Sample does not look normal' % (sl))
    print('---------------------------------------------')
    print('')

# Original MnO sample
print('Original MnO sample')
returns_normal_tests(MnO)

# Removing the outliers above 0.27 wt %
print('MnO sample without observations above 0.27 wt %')
MnO_no_outliers = MnO[MnO < 0.27]
returns_normal_tests(MnO_no_outliers)

''' Results:
Original MnO sample
---------------------------------------------

Shapiro test rejects H0: not normal

D%*\textcolor{codegreen}{$\textquotesingle$}*)Agostino and Pearson%*\textcolor{codegreen}{$\textquotesingle$}*)s test rejects H0: not normal

Anderson-Darling test:
15.000: rejects H0: Sample does not look normal
10.000: rejects H0: Sample does not look normal
5.000: rejects H0: Sample does not look normal
2.500: rejects H0: Sample does not look normal
1.000: rejects H0: Sample does not look normal
---------------------------------------------

MnO sample without observations above 0.27 wt %
---------------------------------------------

Shapiro test fails to reject H0: looks normal

D%*\textcolor{codegreen}{$\textquotesingle$}*)Agostino and Pearson%*\textcolor{codegreen}{$\textquotesingle$}*)s test fails to reject H0: looks normal

Anderson-Darling test:
15.000: fails to reject H0: Sample looks normal
10.000: fails to reject H0: Sample looks normal
5.000: fails to reject H0: Sample looks normal
2.500: fails to reject H0: Sample looks normal
1.000: fails to reject H0: Sample looks normal
-----------------------------------------------------------
'''


"""
Filename: simplex_grid.py

Author: Daisuke Oyama

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

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

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

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

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

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

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

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

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

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

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

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

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

    h = m

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

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

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

        if val != 1:
            h = m

    return out

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

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

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

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

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

    """
    if m == 1:
        return 0

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

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

    """
    if m == 1:
        return 0

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

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

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

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

    n : scalar(int)
        Integer to decompose.

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

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


# Lab exercise 1:

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

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

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

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

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

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

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

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

# Now project all points at once:

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

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

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

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

# form the epipolar equations

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

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

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

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

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

# get solution: last row of vh

f = vh_svd[-1,:]

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

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

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


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

Newton-Raphson's method -

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

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

Now x_k+1 = x_k for the next iteration.

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

"""

import numpy as np

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

    Args:
        number:
        accuracy_tolerance:
        num_iterations:

    Returns:
        the estimated square root

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

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

    estimated_root = number

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

    return estimated_root

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


#! /usr/bin/env python

import numpy

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

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

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

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

    return h_a,short_a

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

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

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

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

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

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

    print("\nEnd")


import numpy as np

# Return the floor of the input, element-wise.
# The floor of the scalar x is the largest integer i, such that i <= x. It is often denoted as \lfloor x \rfloor.

a = np.array([-2.8, -2.5, -0.3, 0.3, 1.6, 2.7, 3.0])
print("Floor : ",np.floor(a))


import matplotlib.pyplot as plt
import numpy as np

def generate_signal(w, sigma_n, alpha=None, theta=None, Ts=1, N=100):
    '''
        Generates signal, based on:
            w: frequencies
            sigma_n: white noise std
            (optional) alpha: amplitudes
            (optional) theta: phases
            (optional) Ts: sample period
            (optional) N: number of samples

        Returns:
            y: generated signal
    '''
    # Check params
    n = w.size
    alpha = (
        np.array(alpha) if alpha is not None
        else np.random.uniform(1, 2, n)
    )
    theta = (
        np.array(theta) if theta is not None
        else np.pi * (2*np.random.rand(n) - 1)
    )
    if alpha.size != n or theta.size != n:
        print(w.size, alpha.size, theta.size)
        return None, None

    # Generate the signal
    t = np.arange(0, N * Ts, Ts)
    y = np.zeros(N, dtype=complex)
    for i in range(N):
        for k in range(n):
            y[i] += alpha[k] * np.exp(1j * (w[k] * t[i] + theta[k]))
        y[i] += sigma_n * np.random.randn()
    return y

def apply_method(method, sig, show=True):
    '''
        Applies method to a given signal.
        Additionally, plots resuls if flag show is set to true.
    '''
    method.estimate(sig)
    method.plot_pseudo_spectrum(plt) if method.type != 'ESPRIT' else None
    method.plot_w(plt)


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

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

# In[1]:

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

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

# In[2]:

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

# In[3]:

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

# In[4]:

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

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

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

# In[5]:

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

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

# In[6]:

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

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

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

# In[7]:

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

# In[8]:

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

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

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

# In[9]:

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

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

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

# In[10]:

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

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

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

# In[11]:

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

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

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

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

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

        all_theta[k] = theta
    return all_theta, J_history

# In[12]:

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

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

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

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

# In[13]:

print('Plotting cost function through iterations')

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

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

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

# In[14]:

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

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

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

# In[15]:

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

# In[16]:

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

# In[17]:

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

# In[ ]:

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


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

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

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

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

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

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

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


'''
create a confusion matrix given some randomly generated data

NOTES:
* each row represents a class prediction
* each column represents a class ground truth
* sources:
    - https://machinelearningmastery.com/confusion-matrix-machine-learning/
    - confusion matrix, ElementsofStatisticalLearning,p301
    - https://en.wikipedia.org/wiki/Confusion_matrix

'''

import numpy as np
from sklearn.metrics import confusion_matrix as cm
np.random.seed(0)

def cm2(ypred,ytrue,nCls=None):
    ''' self-made confusion matrix calculation '''
    if(nCls==None):
        nCls=ytrue.max()+1
    arr=np.zeros((nCls,nCls))
    for i in range(len(ytrue)):
        arr[ypred[i],ytrue[i]]+=1
    return arr.astype(int)

# will use 3 classes
yp = np.random.randint(3,size=10) # create artificial predictions
yt = np.random.randint(3,size=10) # create artificial ground truth

print('prediction: ',yp)
print('groundtruth:',yt)
print()
print('results:')
print(cm(yt,yp))
print('\nself-made comparison:')
print(cm2(yt,yp,3))


import numpy as np
import pandas as pd
import pickle

# Load the training and test data from the Pickle file
with open("./datasets/vehicle_price_dataset.pickle", "rb") as f:
      train_data, train_labels, test_data, test_labels = pickle.load(f)

# Insert a column of ones
train_data["ones"] = 1

# Select columns of interest
cols = ["ones", "odometer"]
X = train_data[cols].values
Y = train_labels.values

# Solve the Normal equations: W = (X' * X)^-1 * X' * Y
XT = np.transpose(X)
W = np.linalg.inv(XT @ X) @ XT @ Y
print(W)

# Predict new labels for test data
test_data["ones"] = 1
Xn = test_data[cols].values
Y_pred = Xn @ W

# Print the first few predictions
for idx in range(10):
    print("Predicted: {:6.0f} Correct: {:6d}"\
          .format(Y_pred[idx], test_labels.values[idx]))

# Compute the root mean squared error
error = Y_pred - test_labels.values
rmse = (error ** 2).mean() ** .5
print("RMSE: {:.2f}".format(rmse))


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

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

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

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

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

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

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


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

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

class CurveFit():

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

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

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

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

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

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

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


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

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

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

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

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

T=14       # Time-play

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

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

    return [dS,dI,dR]

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

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

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


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

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

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

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

    return data_set

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

def logistic_regression(D, y_labels):

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

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

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

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

        old_W = np.copy(W)

    return W,epocs

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

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

    E_out = e / N
    return E_out

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

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

        E_out = cross_entropy(D_test,test_labels,W)

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

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

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


import numpy as np
from scipy.stats import skew

a_mean = my_dataset.Zr.mean()
median = my_dataset.Zr.median()
hist, bin_edges = np.histogram(my_dataset['Zr'], bins=20, density=True)
modal_value = (bin_edges[hist.argmax()] + bin_edges[hist.argmax()+1])/2
standard_deviation = my_dataset['Zr'].std()

a1 = (a_mean - modal_value) / standard_deviation
a2 = 3 * (a_mean - median) / standard_deviation
g1 = skew(my_dataset['Zr'])

print ('-------')
print ("Pearson's first coefficient of skewness: {:.2f}".format(a1))
print ("Pearson's 2nd moment of skewness: {:.2f}".format(a2))
print ("Fisher-Pearson's coefficient of skewness: {:.2f}".format(g1))
print ('-------')

'''
Output:
-------
Pearson's first coefficient of skewness: 0.74
Pearson's 2nd moment of skewness: 0.66
Fisher-Pearson's coefficient of skewness: 1.26
-------
'''


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

from matplotlib import pyplot
from numpy.linalg import solve

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

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

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

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

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

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

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

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

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

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

	#Return the normalized prior.
	return p_dist

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

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

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

	dist_seq.add_heads_posterior(p_dist)

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

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

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

	dist_seq.add_tails_posterior(p_dist)

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

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

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

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

def main():
	dist_history = Dist_Sequence(1001)

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

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

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

	#Show the resulting sequence of distributions
	draw(dist_history)

if __name__ == '__main__':
    main()


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

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

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

    def calc_offset(self, angle):

        epsilon = 0.0001

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

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

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

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

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

        return ret_angles

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

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

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

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

        return [grad_mags, grad_angles]

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

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

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

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

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

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

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

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

        return grad_mags_ret

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

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

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

        if no_more_edge:
            return False

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

        return res

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

        return mask

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

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

    def detect_edges(self, image):

        grad_image = self.operator(image)

        image_maxima = self.non_maxima_supp(grad_image)

        mask = self.class_thresholding(image_maxima)

        updated_mask = self.hysterisis(mask, image_maxima)

        return self.apply_mask(updated_mask, image_maxima)


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

import numpy as np

# Code starts here

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

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

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

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

print('page', page)

# Code ends here

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

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

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

# Code ends here

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

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

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

# Code ends here

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

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

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


import keras
print(keras.__version__)  # 2.2.4

# 6.2 RNN introduction

# RNN pseudo code
input_sequence = []

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

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

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

def dot(y, z):
    pass

def activation(x):
    return x

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

# RNN Numpy
import numpy as np

timesteps = 100
input_features = 32
output_features = 64

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

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

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

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

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

# 6.2.1 RNN in Keras introduction

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

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

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

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

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

# IMDB reviews classification by RNN in Keras

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

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

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

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

# build network model
from keras.layers import Dense

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

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

# plot
import matplotlib.pyplot as plt

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

epochs = range(len(acc))

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

plt.figure()

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

plt.show()

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


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

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

__all__ = [
    'cramers_corrected_stat',
]

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

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

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

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

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

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


import math
import numpy as np

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

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

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

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

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

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

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

    return np.transpose(q), r_matrix

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

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

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


import numpy as np
import matplotlib.pyplot as plt

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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


import pandas as pd
import numpy as np
import math
import matplotlib.pyplot as plt
from .metrics import mse_score, rmse_score, r2_score, mae_score
from ..features.build_features import StandardScaler, MinMaxScaler

class LinearRegressor():
    """Linear regressor"""

    def __init__(self, method='normal_equation', normalize=False, lr=0.01, epochs=1000, add_intercept=False):
        assert method in ['normal_equation', 'gradient_descent'], "Method not supported. Supported methods are 'normal_equation' and 'gradient_descent'"
        self.method = method
        self.normalize = normalize
        self.add_intercept = add_intercept
        self._weights = None

        if self.method == 'gradient_descent':
            self.lr = lr
            self.epochs = epochs

        if self.normalize:
            self._feature_scaler = MinMaxScaler()
            self._target_scaler = MinMaxScaler()

    def fit(self, X, y):
        """Fit the model to the data"""

        if self.normalize:
            X = self._feature_scaler.fit_transform(X)
            y = self._target_scaler.fit_transform(y)

        X = X.to_numpy()
        if self.add_intercept:
            X = np.hstack((np.ones((X.shape[0], 1)), X))
        y = y.to_numpy()

        if self.method == 'normal_equation':
            self._weights = np.dot(np.dot(np.linalg.inv(np.dot(X.T, X)), X.T), y)

        else:
            # mse_new = np.inf
            self._weights = np.zeros(X.shape[1])
            self.cost_history = [0] * self.epochs

            for i in range(self.epochs):
                grad = np.dot(X.T, np.dot(X, self._weights) - y) / y.shape[0]
                self._weights = self._weights - self.lr * grad
                self.cost_history[i] = mse_score(y, np.dot(X, self._weights))

            #     if (rmse_new > rmse_old):
            #         print("Stopped at iteration {}".format(i))
            #         break
            plt.scatter(range(self.epochs), self.cost_history)
            plt.xlabel('epoch')
            plt.ylabel('mse')

    def predict(self, X):
        """Use the fitted model to predict on data"""

        assert self._weights is not None, "Model needs to be fitted first. Use the fit method"

        if self.normalize:
            X = self._feature_scaler.transform(X)

        X = X.to_numpy()
        if self.add_intercept:
            X = np.hstack((np.ones((X.shape[0], 1)), X))

        y_pred = np.dot(X, self._weights)
        if self.normalize:
            y_pred = self._target_scaler.inverse_transform(y_pred)

        return np.round(y_pred, 2)

    def get_weights(self):
        """Get weights from the fitted model"""

        assert self._weights is not None, "Model needs to be fitted first. Use the fit method"
        return self._weights

    def score(self, X, y, metric='r2'):
        """Score the model"""

        assert metric in ['r2', 'rmse', 'mae'], "Metric not supported. Supported metrics are 'r2', 'rmse' and 'mae'"

        y_pred = self.predict(X)

        if metric == 'r2':
            score = r2_score(y, y_pred)
        elif metric == 'rmse':
            score = rmse_score(y, y_pred)
        elif metric == 'mae':
            score = mae_score(y, y_pred)

        return score


import functools
import operator
import random
import math
import sympy
from crypy.utils.maths import int_root

class RSA:
    def __init__(self, n, e, d=None, factors=None):
        self.n = n
        self.e = e
        self.d = d
        self.factors = factors

        if factors is not None:
            assert n == functools.reduce(operator.mul, factors)

    @property
    def phi(self):
        return functools.reduce(operator.mul, map(lambda x: x-1, self.factors))

    @staticmethod
    def _convert(data):
        if type(data) == int:
            pass
        elif type(data) == str:
            data = int.from_bytes(data.encode(), 'big')
        elif type(data) == bytes:
            data = int.from_bytes(data, 'big')
        return data

    def encrypt(self, data):
        int_data = self._convert(data)

        return pow(int_data, self.e, self.n)

    def decrypt(self, data):
        int_data = self._convert(data)

        return pow(int_data, self.d, self.n)

    def try_find_pq(self):
        d = self.d
        e = self.e
        n = self.n

        if d is None:
            return None

        k = d*e - 1
        if k % 2 == 1:
            return None

        r = k
        t = 0
        while True:
            t += 1
            r = r//2
            if r % 2 == 1:
                break
        for i in range(100):
            g = random.randint(0, n)
            y = pow(g, r, n)
            if y != 1 and y != n-1:
                for j in range(1, t):
                    x = pow(y, 2, n)
                    if x == 1:
                        break
                    if x == n-1:
                        continue
                    y = x
                x = pow(y, 2, n)
                if x == 1:
                    break
        else:
            return None
        p = math.gcd(y - 1, n)
        q = n//p
        self.factors = [p, q]

        return p, q

    def no_modulo_attack(self, data):
        int_data = self._convert(data)
        return int_root(self.e, int_data)

    def close_primes_attack(self, quantity=2):
        middle = int_root(quantity, self.n)

        if sympy.isprime(middle):
            primes_base = [middle]
            for i in range(quantity):
                primes = primes_base[:]
                for j in range(i):  # previous
                    primes = [sympy.prevprime(primes[0])] + primes
                for j in range(quantity-i-1):  # next
                    primes = primes + [sympy.nextprime(primes[-1])]
                n = functools.reduce(operator.mul, primes)
                if n == self.n:
                    return primes
        else:
            primes_base = [sympy.prevprime(middle), sympy.nextprime(middle)]
            for i in range(1, quantity):
                primes = primes_base[:]
                for j in range(i-1):  # previous
                    primes = [sympy.prevprime(primes[0])] + primes
                for j in range(quantity-i-1):  # next
                    primes = primes + [sympy.nextprime(primes[-1])]
                n = functools.reduce(operator.mul, primes)
                if n == self.n:
                    return primes

        return None


import numpy as np
import random

from spectrum_agents import Agent

class Q(Agent):
    """
    Q-learning Agent inheriting from Agent base class.
    Updates Q-table and e-greedily picks new actions.
    """
    def __init__(self, agent_id, N, seed=None, start=None):
        super().__init__(agent_id, N, seed=seed, start=start)
        self.ns = 2 ** N # number of states
        self.na = N # number of decisions
        self.q = np.zeros((self.ns, self.na))

        # Q-learning parameters
        self.eps = 1.0 # epsilon
        self.eps_min = 0.01
        self.lr = 0.7 # alpha
        self.discount = 0.4 # gamma
        self.eps_schedule = lambda eps: max(eps-1e-2, self.eps_min)

        self.temp = 1.0 # temperature

    def _decide(self,o=None,r=None):
        return self._egreedy(o,r)
#        return self._softmax(o,r)

    def _learn(self,o=None,r=None):
        # Q-table update
        # q(s,a) := q(s,a) + alpha * [r(s,a) + gamma * max[q(s,:)] - q(s,a)]
        if self.s is not None:
            delta = r + \
                    self.discount * np.max(self.q[self.s,:]) - \
                    self.q[self.s,self.a]
            self.q[self.s, self.a] += self.lr * delta

    def _egreedy(self,o=None,r=None):
        self.eps = self.eps_schedule(self.eps)
        if random.random() < self.eps:
            return random.randint(0,self.na-1)
        else:
            return np.argmax(self.q[o,:])

    def _softmax(self,o=None,r=None):
        pdf = np.exp(self.q[o,:]/self.temp)
        pdf = pdf/sum(pdf)
        return np.random.choice(self.na, p=pdf)


"""
Calculus functionality (differentiation and integration) for polynomials expressed in the Bernstein basis (see
:mod:`~polynomials_on_simplices.polynomial.polynomials_unit_simplex_bernstein_basis`).
"""

import numbers

import numpy as np

from polynomials_on_simplices.geometry.primitives.simplex import affine_transformation_from_unit, dimension
from polynomials_on_simplices.polynomial.polynomials_base import get_dimension

def integrate_bernstein_basis_fn_unit_simplex(r, n):
    r"""
    Integrate a degree r Bernstein base polynomial over the n-dimensional unit simplex.

    .. math::

        \int_{\Delta_c^n} b_{\nu, r}(x) \, dx = \frac{1}{\prod_{i = 1}^n (r + i)}.

    Note that this is independent of nu, i.e. each basis polynomial has the same integral over the unit simplex.

    :param int r: Degree of the basis polynomial.
    :param int n: Dimension of the unit simplex.
    :return: Evaluation of the integral of the basis polynomial over the unit simplex.
    :rtype: float

    .. rubric:: Examples

    :math:`\int_{\Delta_c^2} b_{\nu, 2}(x) \, dx = \frac{1}{\prod_{i = 1}^2 (2 + i)} = \frac{1}{3 \cdot 4}`.

    >>> integrate_bernstein_basis_fn_unit_simplex(2, 2) == 1 / 12
    True
    """
    denom = 1
    for i in range(1, n + 1):
        denom *= (r + i)
    return 1 / denom

def integrate_bernstein_polynomial_unit_simplex(r, a, n):
    r"""
    Integrate a degree r Bernstein polynomial over the n-dimensional unit simplex.

    .. math::

        \int_{\Delta_c^n} \sum_{i = 0}^{\dim(\mathcal{P}_r(\mathbb{R}^n)) - 1} a_{\nu_i} b_{\nu_i, r}(x) \, dx
        = \frac{1}{\prod_{i = 1}^n (r + i)} \sum_{i = 0}^{\dim(\mathcal{P}_r(\mathbb{R}^n)) - 1} a_{\nu_i},

    where :math:`\nu_i` is the i:th n-dimensional multi-index of norm <= r (see
    :func:`polynomials_on_simplices.algebra.multiindex.generate` and
    :func:`polynomials_on_simplices.algebra.multiindex.generate_all` for the sequence of and ordering of multi-indices).

    :param int r: Degree of the polynomial.
    :param a: Coefficients :math:`a_{\nu_i}` in the polynomial (array where element i is the coefficient
        :math:`a_{\nu_i}`)
    :param int n: Dimension of the unit simplex.
    :return: Evaluation of the integral of the polynomial over the unit simplex.

    .. rubric:: Examples

    :math:`\int_0^1 2(1 - x) + x \, dx = 1 + \frac{1}{2} = \frac{3}{2}`.

    >>> integrate_bernstein_polynomial_unit_simplex(1, [2, 1], 1) == 3 / 2
    True
    """
    assert len(a) == get_dimension(r, n)
    c = integrate_bernstein_basis_fn_unit_simplex(r, n)
    return c * sum(a)

def integrate_bernstein_basis_fn_simplex(r, vertices):
    r"""
    Integrate a degree r Bernstein base polynomial over an n-dimensional simplex T.

    .. math::

        \int_{T} b_{\nu, r}(x) \, dx
        = \int_{\Phi(\Delta_c^n)} \bar{b}_{\nu, r} \circ \Phi^{-1}(x)
        = |\det D\Phi| \int_{\Delta_c^n} \bar{b}_{\nu, r}(x)
        = |\det D\Phi| \frac{1}{\prod_{i = 1}^n (r + i)}.

    Note that this is independent of nu, i.e. each basis polynomial has the same integral over the simplex T.

    :param int r: Degree of the basis polynomial.
    :param vertices: Vertices of the simplex T ((n + 1) x n matrix where row i contains the i:th vertex of the
        simplex).
    :return: Evaluation of the integral of the basis polynomial over the simplex T.
    :rtype: float
    """
    n = dimension(vertices)
    iu = integrate_bernstein_basis_fn_unit_simplex(r, n)
    a, b = affine_transformation_from_unit(vertices)
    if isinstance(a, numbers.Number):
        det = a
    else:
        det = np.linalg.det(a)
    assert det > 0
    return det * iu

def integrate_bernstein_polynomial_simplex(r, a, vertices):
    r"""
    Integrate a degree r Bernstein polynomial over an n-dimensional simplex T.

    .. math::

        \int_{T} \sum_{i = 0}^{\dim(\mathcal{P}_r(\mathbb{R}^n)) - 1} a_{\nu_i} b_{\nu_i, r}(x) \, dx
        = \int_{\Phi(\Delta_c^n)} \sum_{i = 0}^{\dim(\mathcal{P}_r(\mathbb{R}^n)) - 1}
            a_{\nu_i} (bar{b}_{\nu_i, r} \circ \Phi^{-1})(x) \, dx
        = |\det D\Phi| \int_{\Delta_c^n} \sum_{i = 0}^{\dim(\mathcal{P}_r(\mathbb{R}^n)) - 1}
            a_{\nu_i} bar{b}_{\nu_i, r}(x) \, dx
        = |\det D\Phi| \frac{1}{\prod_{i = 1}^n (r + i)} \sum_{i = 0}^{\dim(\mathcal{P}_r(\mathbb{R}^n)) - 1} a_{\nu_i},

    where :math:`\nu_i` is the i:th n-dimensional multi-index of norm <= r (see
    :func:`polynomials_on_simplices.algebra.multiindex.generate` and
    :func:`polynomials_on_simplices.algebra.multiindex.generate_all` for the sequence of and ordering of multi-indices).

    :param int r: Degree of the polynomial.
    :param a: Coefficients :math:`a_{\nu_i}` in the polynomial (array where element i is the coefficient
        :math:`a_{\nu_i}`)
    :param vertices: Vertices of the simplex T ((n + 1) x n matrix where row i contains the i:th vertex of the
        simplex).
    :return: Evaluation of the integral of the polynomial over the simplex T.
    """
    assert len(a) == get_dimension(r, dimension(vertices))
    c = integrate_bernstein_basis_fn_simplex(r, vertices)
    return c * sum(a)


"""
"""

import numpy
import unittest
from math import pi
from oyb import rot

def norm(v):
    return v.dot(v)**0.5

class VectorRotation(unittest.TestCase):
    def test_x(self):
        v = rot.x(0.5 * pi).dot(numpy.array([0,0,1]))
        self.assertTrue(norm(v - numpy.array([0,-1,0])) < 1e-8)

    def test_y(self):
        v = rot.y(0.5 * pi).dot(numpy.array([0,0,1]))
        self.assertTrue(norm(v - numpy.array([1,0,0])) < 1e-8)

    def test_z(self):
        v = rot.z(0.5 * pi).dot(numpy.array([1,0,0]))
        self.assertTrue(norm(v - numpy.array([0,1,0])) < 1e-8)

class FrameTransformation(unittest.TestCase):
    def test_X(self):
        v = rot.X(0.5 * pi).dot(numpy.array([0,0,1]))
        self.assertTrue(norm(v - numpy.array([0,1,0])) < 1e-8)

    def test_Y(self):
        v = rot.Y(0.5 * pi).dot(numpy.array([0,0,1]))
        self.assertTrue(norm(v - numpy.array([-1,0,0])) < 1e-8)

    def test_Z(self):
        v = rot.Z(0.5 * pi).dot(numpy.array([1,0,0]))
        self.assertTrue(norm(v - numpy.array([0,-1,0])) < 1e-8)

class TransformationSequence(unittest.TestCase):
    def test_example4p7(self):
        O = rot.Z(40 * pi / 180)
        i = rot.X(30 * pi / 180)
        w = rot.Z(60 * pi / 180)
        wiO_act = w.dot(i).dot(O)
        wiO_ref = numpy.array([
            [-0.099068, 0.89593, 0.43301],
            [-0.94175, -0.22496, 0.25],
            [0.32139, -0.38302, 0.86603]])
        dWIO = (wiO_ref - wiO_act).reshape((9,))
        self.assertTrue(dWIO.dot(dWIO)**0.5 < 1e-4)

class SphericalFrame(unittest.TestCase):
    def test_xyz1sph(self):
        xyz = numpy.array([-5.368e6, -1.784e6, 3.691e6])
        sph = rot.xyz2sph(xyz)
        self.assertTrue(abs(sph[0] - 198.4 * pi / 180) / sph[0] < 1e-3)
        self.assertTrue(abs(sph[1] - 33.12 * pi / 180) / sph[1] < 1e-3)
        self.assertTrue(abs(sph[2] - 6.754e6) / sph[2] < 1e-3)

if __name__ == '__main__':
    unittest.main()


from math import *
from sympy import *
global t,deriv,dydx,count
count=0

def func( x ):
    return x*log(x)/log(10) - 1.2

def derivFunc( x ):
    return deriv.doit().subs({t:x})

# Function to find the root
def newtonRaphson( x ):
    global count
    h = func(x) / derivFunc(x)

    while abs(h) >= 0.01:
        count=count+1
	try:
      	    h = func(x)/derivFunc(x)
        except ZeroDivisionError:
            print("Error! - derivative zero for x = ", x)
        # x(i+1) = x(i) - f(x) / f'(x)
        x = x - h

    print("The value of the root is : ",
                             "%.4f"% x)
    print("the no of iterations is ",count)

x0 = input("enter the initial value : ") # Initial val
x0 = int(x0)
#x0 =5
t= Symbol('t')
f=t*log(t)/log(10) - 1.2
deriv= Derivative(f, t)
#print(deriv.doit())
dydx=deriv.doit()
#deriv.doit()
newtonRaphson(x0)


import numpy as np
import matplotlib.pyplot as plt

# defino una funcion para calcular un polinomio
def poly(x, beta):
    """
    Entradas:
    x : array de entrada.
    beta: coeficientes del polinomio: beta[i] = beta_i.

    Salida:
    y : array de salida
    """
    y = np.zeros(len(x))
    for i in range(len(beta)):
        y +=  beta[i] * x**i
    return y

def solve_poly(x, y, m):
    """
    Entradas:
    x : array unidimensional de valores de x.
    y : array unidimensiondal de valores de y.
    m : orden del polinomio que queremos ajustar.

    Salida:
    beta : array con los coeficientes del polinotmi.

    Este codigo resuelve el siguiente sistema de ecuaciones
    S * beta = Y, beta = S^{-1} * Y,
    donde S es una matriz que tiene como vectotes a columnas de potencias de X.

    """
    # matriz que guarda los vectores columna de potencias de x
    S = np.zeros([len(x), m+1])
    for i in range(m+1):
        S[:,i] = x**i

    # Calculo la inversa de S.
    S_inv = np.linalg.inv(S)

    # calculo beta
    beta = np.dot(S_inv, y)

    return beta

# cargo los datos para manipular
data = np.loadtxt("numeros_20.txt")

# diccionario para guardar todos los coeficientes
betas = {}

# distintos valores de m para probas

m_values = [1,2,3,4]

for m in m_values:
    X = data[: m+1, 0]
    Y = data[: m+1, 1]

    betas[m] = solve_poly(X, Y, m)

# preparo finalmene la grafica pedida

plt.figure()

for i,m in enumerate(m_values):
    # vuelvo a sacar los puntos para graficarlos
    X = data[: m+1, 0]
    Y = data[: m+1, 1]

    # array de valores de x que va del minimo al maximo valor considerados
    # para hacer los ajustes
    x_model = np.linspace(np.min(data[:10,0]), np.max(data[:10,0]), 100)

    # valores correspondientes al modelo de orden m
    y_model = poly(x_model, betas[m])

    plt.subplot(2,2,i+1)
    #grafica del modelo
    plt.plot(x_model, y_model)
    #grafica de los puntos
    plt.scatter(X, Y)
    plt.xlabel("X")
    plt.ylabel("Y")
    plt.title("M={}".format(m))

plt.subplots_adjust(hspace=0.5)
plt.savefig("polinomios.png", bbox_inches='tight')


import sys
sys.path.append('../../src/UQpy/')
from Distributions import *
from Surrogates import *
import numpy as np

np.random.seed(1)
dist = Uniform(loc=0, scale=10)
max_degree, n_samples = 2, 10
polys = Polynomials(dist_object=dist, degree=max_degree)

def func(x):
    return x * np.sin(x) / 10

x = dist.rvs(n_samples)
y = func(x)

def poly_func(x):
    p = polys.evaluate(x)
    return p

def pce_model(polys, x, y):
    lstsq = PolyChaosLstsq(poly_object=polys)
    pce = PCE(method=lstsq)
    pce.fit(x, y)
    return pce

def pce_predict(x, c):
    x_ = poly_func(x)
    return x_.dot(c)

# Unit tests

def test_1():
    """
    Test Polynomials class
    """
    assert round(poly_func(x)[1, 1], 3) == 0.763

def test_2():
    """
    Test PCE class coefficients
    """
    assert round(float(pce_model(polys, x, y).C[1]), 3) == 0.328

def test_3():
    """
    Test PCE class prediction
    """
    model = pce_model(polys, x, y)
    assert round(float(pce_predict(x, model.C)[1]), 3) == 0.338

def test_4():
    """
    Test Error Estimation class
    """
    x_val = x + np.random.rand(1)
    y_val = func(x_val)
    error = ErrorEstimation(surr_object=pce_model(polys, x, y))
    assert round(error.validation(x_val, y_val), 3) == 0.432


import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
from torch.utils.data import TensorDataset, DataLoader

# learning this
def f(x):
    return 2 * x + 1

# dataset
N = 100000
l, r = int(-N/2), int(N/2)
inputs = np.array(range(l, r))

# scaling doesn't allow huge gradients for large dataset
inputs = inputs / N
labels = f(inputs)

X = torch.tensor(inputs)
Y = torch.tensor(labels)

train_ds = TensorDataset(X, Y)
batch_size = 4
train_dl = DataLoader(train_ds, batch_size, shuffle=True)

# params init
a = torch.randn(1, requires_grad=True)
b = torch.randn(1, requires_grad=True)

# gradient descent
optimizer = optim.SGD([a, b], lr=0.5)

for i in range(11):
    batch_in, batch_out = next(iter(train_dl))

    # linear regression model
    out = a * batch_in + b
    diff = (out - batch_out)

    loss = torch.sum(diff * diff) / diff.numel()
    # pytorch autograd
    loss.backward()

    # calculating gradients explicitly
    anal_a = (1 / batch_size) * torch.sum(2 * batch_in * ((a * batch_in + b) - batch_out))
    anal_b = (1 / batch_size) * torch.sum(2 * ((a * batch_in + b) - batch_out))

    # take step
    optimizer.step()

    print('step: {}, loss:{}, Y_:{}, a:{}, b {}'.format(i, loss, out, a, b))
    print('Pytorch grad a: {}\tPytorch  grad b: {}'.format(a.grad, b.grad))
    print('Analitical grad a: {}\tAnalitical grad b: {}'.format(anal_a, anal_b))

    optimizer.zero_grad()


import numpy as np
import pandas as pd
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import ui
import scipy.io as sio
import scipy.optimize as opt
import seaborn as sns

def load_data():
    """for ex5
    d['X'] shape = (12, 1)
    pandas has trouble taking this 2d ndarray to construct a dataframe, so I ravel
    the results
    """
    d = sio.loadmat('data/ex5data1.mat')
    return map(np.ravel, [d['X'], d['y'], d['Xval'], d['yval'], d['Xtest'], d['ytest']])

print('载入训练数据')
X, y, Xval, yval, Xtest, ytest = load_data()
print('可视化 X(水位的变化) 和 y(离开大坝的水流量 )')
df = pd.DataFrame({'water_level':X, 'flow':y})

sns.lmplot('water_level', 'flow', data=df, fit_reg=False, size=7)
plt.show()
print('设置训练、验证、测试集')
X, Xval, Xtest = [np.insert(x.reshape(x.shape[0], 1), 0, np.ones(x.shape[0]), axis=1) for x in (X, Xval, Xtest)]

print('代价函数')
def cost(theta, X, y):
    """
    X: R(m*n), m records, n features
    y: R(m)
    theta : R(n), linear regression parameters
    """
    m = X.shape[0]

    inner = X @ theta - y  # R(m*1)

    # 1*m @ m*1 = 1*1 in matrix multiplication
    # but you know numpy didn't do transpose in 1d array, so here is just a
    # vector inner product to itselves
    square_sum = inner.T @ inner
    cost = square_sum / (2 * m)

    return cost
print('用初始化参数计算 cost')
theta = np.ones(X.shape[1])
print(cost(theta, X, y))
print('定义梯度')
def gradient(theta, X, y):
    m = X.shape[0]

    inner = X.T @ (X @ theta - y)  # (m,n).T @ (m, 1) -> (n, 1)

    return inner / m
print('用初始化参数计算梯度')
print(gradient(theta, X, y))
print('正则化梯度')
def regularized_gradient(theta, X, y, l=1):
    m = X.shape[0]

    regularized_term = theta.copy()  # same shape as theta
    regularized_term[0] = 0  # don't regularize intercept theta

    regularized_term = (l / m) * regularized_term

    return gradient(theta, X, y) + regularized_term
print('用初始化参数计算正则化梯度')
print(regularized_gradient(theta, X, y))

print('拟合数据，无正则化项')
def linear_regression_np(X, y, l=1):
    """linear regression
    args:
        X: feature matrix, (m, n+1) # with incercept x0=1
        y: target vector, (m, )
        l: lambda constant for regularization

    return: trained parameters
    """
    # init theta
    theta = np.ones(X.shape[1])

    # train it
    res = opt.minimize(fun=regularized_cost,
                       x0=theta,
                       args=(X, y, l),
                       method='TNC',
                       jac=regularized_gradient,
                       options={'disp': True})
    return res

def regularized_cost(theta, X, y, l=1):
    m = X.shape[0]

    regularized_term = (l / (2 * m)) * np.power(theta[1:], 2).sum()

    return cost(theta, X, y) + regularized_term

theta = np.ones(X.shape[0])
final_theta = linear_regression_np(X, y, l=0).get('x')
print('绘制图像')
b = final_theta[0] # intercept
m = final_theta[1] # slope

plt.scatter(X[:,1], y, label="Training data")
plt.plot(X[:, 1], X[:, 1]*m + b, label="Prediction")
plt.legend(loc=2)
plt.show()

training_cost, cv_cost = [], []

print('1.使用训练集的子集来拟合应模型')
print('2.在计算训练代价和交叉验证代价时，没有用正则化')
print('3.记住使用相同的训练集子集来计算训练代价')
m = X.shape[0]
for i in range(1, m+1):
#     print('i={}'.format(i))
    res = linear_regression_np(X[:i, :], y[:i], l=0)

    tc = regularized_cost(res.x, X[:i, :], y[:i], l=0)
    cv = regularized_cost(res.x, Xval, yval, l=0)
#     print('tc={}, cv={}'.format(tc, cv))

    training_cost.append(tc)
    cv_cost.append(cv)

plt.plot(np.arange(1, m+1), training_cost, label='training cost')
plt.plot(np.arange(1, m+1), cv_cost, label='cv cost')
plt.legend(loc=1)
plt.show()
print('模型欠拟合')
ui.split_line2()
print('创建多项式特征')
def prepare_poly_data(*args, power):
    """
    args: keep feeding in X, Xval, or Xtest
        will return in the same order
    """
    def prepare(x):
        # expand feature
        df = poly_features(x, power=power)

        # normalization
        ndarr = normalize_feature(df).as_matrix()

        # add intercept term
        return np.insert(ndarr, 0, np.ones(ndarr.shape[0]), axis=1)

    return [prepare(x) for x in args]

def poly_features(x, power, as_ndarray=False):
    data = {'f{}'.format(i): np.power(x, i) for i in range(1, power + 1)}
    df = pd.DataFrame(data)

    return df.as_matrix() if as_ndarray else df

X, y, Xval, yval, Xtest, ytest = load_data()

print(poly_features(X, power=3))
print('准备多项式回归数据')
def normalize_feature(df):
    """Applies function along input axis(default 0) of DataFrame."""
    return df.apply(lambda column: (column - column.mean()) / column.std())

X_poly, Xval_poly, Xtest_poly= prepare_poly_data(X, Xval, Xtest, power=8)
print(X_poly[:3, :])

print('画出学习曲线')
def plot_learning_curve(X, y, Xval, yval, l=0):
    training_cost, cv_cost = [], []
    m = X.shape[0]

    for i in range(1, m + 1):
        # regularization applies here for fitting parameters
        res = linear_regression_np(X[:i, :], y[:i], l=l)

        # remember, when you compute the cost here, you are computing
        # non-regularized cost. Regularization is used to fit parameters only
        tc = cost(res.x, X[:i, :], y[:i])
        cv = cost(res.x, Xval, yval)

        training_cost.append(tc)
        cv_cost.append(cv)

    plt.plot(np.arange(1, m + 1), training_cost, label='training cost')
    plt.plot(np.arange(1, m + 1), cv_cost, label='cv cost')
    plt.legend(loc=1)

plot_learning_curve(X_poly, y, Xval_poly, yval, l=0)
plt.show()
print('无正则化，训练代价过低，过拟合')
ui.split_line2()

plot_learning_curve(X_poly, y, Xval_poly, yval, l=1)
plt.show()
print('l=1，减轻了过拟合')

ui.split_line2()

plot_learning_curve(X_poly, y, Xval_poly, yval, l=100)
plt.show()
print('l=100， 正则化过了，变成欠拟合')

print('找到最佳的正则化系数')
l_candidate = [0, 0.001, 0.003, 0.01, 0.03, 0.1, 0.3, 1, 3, 10]
training_cost, cv_cost = [], []
for l in l_candidate:
    res = linear_regression_np(X_poly, y, l)

    tc = cost(res.x, X_poly, y)
    cv = cost(res.x, Xval_poly, yval)

    training_cost.append(tc)
    cv_cost.append(cv)

plt.plot(l_candidate, training_cost, label='training')
plt.plot(l_candidate, cv_cost, label='cross validation')
plt.legend(loc=2)

plt.xlabel('lambda')

plt.ylabel('cost')
plt.show()

print('分别 计算 Cost')
for l in l_candidate:
    theta = linear_regression_np(X_poly, y, l).x
    print('test cost(l={}) = {}'.format(l, cost(theta, Xtest_poly, ytest)))

print('0.3 是最佳系数，这时测试误差最小')


# coding: utf-8

# ### DEMQUA03
# # Area under 1-D and 2-D curves, various methods
#
# Uni- and bi-vaiariate integration using Newton-Cotes, Gaussian, Monte Carlo, and quasi-Monte Carlo quadrature methods.

# In[1]:

import numpy as np
from compecon import qnwtrap, qnwsimp, qnwlege, demo
import matplotlib.pyplot as plt
import pandas as pd

# In[2]:

quadmethods = [qnwtrap, qnwsimp, qnwlege]

# ### Make support function

# In[3]:

a, b = -1, 1
nlist = [5, 11, 21, 31]
N = len(nlist)

def quad(func, qnw, n):
    xi, wi = qnw(n,a,b)
    return np.dot(func(xi),wi)

# ## Evaluating $\int_{-1}^1e^{-x}dx$

# In[4]:

def f(x):
    return np.exp(-x)

f_quad = np.array([[quad(f, qnw, ni) for qnw in quadmethods] for ni in nlist])
f_true = np.exp(1) - 1/np.exp(1)
f_error = np.log10(np.abs(f_quad/f_true - 1))

# ## Evaluating $\int_{-1}^1\sqrt{|x|}dx$

# In[5]:

def g(x):
    return np.sqrt(np.abs(x))

g_quad = np.array([[quad(g, qnw, ni) for qnw in quadmethods] for ni in nlist])
g_true = 4/3
g_error = np.log10(np.abs(g_quad/g_true - 1))

# ## Make table with results

# In[6]:

results = pd.DataFrame(np.r_[f_error,g_error])

results.columns=['Trapezoid rule', "Simpson's rule", 'Gauss-Legendre']
results['Integral'] = [r'$\int_{-1}^1e^{-x}dx$']*N + [r'$\int_{-1}^1\sqrt{|x|}dx$']*N
results['Nodes n'] = nlist*2
results.set_index(['Integral', 'Nodes n'], inplace=True)
results

# ## Plot the functions

# In[7]:

a, b, n = -1, 1, 301
x = np.linspace(a, b, n)

plt.figure(figsize=[10,4])
demo.subplot(1, 2, 1, '$e^{-x}$','','',[a,b],[0,f(a)])
plt.plot(x, f(x), linewidth=3)
plt.xticks([-1,0,1])
plt.yticks([0])

demo.subplot(1, 2, 2, '$\sqrt{|x|}$','','',[a,b],[0,g(a)])
plt.plot(x, g(x), linewidth=3)
plt.xticks([-1,0,1])
plt.yticks([0])

# In[8]:

results.to_latex('figures/demqua03.tex', escape=False, float_format='%.1f')
demo.savefig([plt.gcf()])


#---------------------------------------------------------------------------------------------------#
#Your First Numpy Array
# Create list baseball
baseball = [180, 215, 210, 210, 188, 176, 209, 200]

# Import the numpy package as np
import numpy as np

# Create a Numpy array from baseball: np_baseball
np_baseball = np.array(baseball)

# Print out type of np_baseball
print(type(np_baseball))
#---------------------------------------------------------------------------------------------------#

#Baseball players' height
# height is available as a regular list

# Import numpy
import numpy as np

# Create a Numpy array from height: np_height
np_height = np.array(height)

# Print out np_height
print(np_height)

# Convert np_height to m: np_height_m
np_height_m = np_height * 0.0254

# Print np_height_m
print(np_height_m)
#---------------------------------------------------------------------------------------------------#

#Baseball player's BMI
# height and weight are available as a regular lists

# Import numpy
import numpy as np

# Create array from height with correct units: np_height_m
np_height_m = np.array(height) * 0.0254

# Create array from weight with correct units: np_weight_kg
np_weight_kg = np.array(weight) * 0.453592

# Calculate the BMI: bmi
bmi = np_weight_kg / np_height_m ** 2

# Print out bmi
print(bmi)
#---------------------------------------------------------------------------------------------------#

#Lightweight baseball players
# height and weight are available as a regular lists

# Import numpy
import numpy as np

# Calculate the BMI: bmi
np_height_m = np.array(height) * 0.0254
np_weight_kg = np.array(weight) * 0.453592
bmi = np_weight_kg / np_height_m ** 2

# Create the light array
light = bmi < 21

# Print out light
print(light)
#---------------------------------------------------------------------------------------------------#

#Subsetting Numpy Arrays
# height and weight are available as a regular lists

# Import numpy
import numpy as np

# Store weight and height lists as numpy arrays
np_weight = np.array(weight)
np_height = np.array(height)

# Print out the weight at index 50
print(np_weight[50])

# Print out sub-array of np_height: index 100 up to and including index 110
print(np_height[100:111])
#---------------------------------------------------------------------------------------------------#

#Your First 2D Numpy Array
# Create baseball, a list of lists
baseball = [[180, 78.4],
            [215, 102.7],
            [210, 98.5],
            [188, 75.2]]

# Import numpy
import numpy as np

# Create a 2D Numpy array from baseball: np_baseball
np_baseball = np.array(baseball)

# Print out the type of np_baseball
print(type(np_baseball))

# Print out the shape of np_baseball
print(np_baseball.shape)
#---------------------------------------------------------------------------------------------------#

#Baseball data in 2D form
# baseball is available as a regular list of lists

# Import numpy package
import numpy as np

# Create a 2D Numpy array from baseball: np_baseball
np_baseball = np.array(baseball)

# Print out the shape of np_baseball
print(np_baseball.shape)
#---------------------------------------------------------------------------------------------------#

#Subsetting 2D Numpy Arrays
# baseball is available as a regular list of lists

# Import numpy package
import numpy as np

# Create np_baseball (2 cols)
np_baseball = np.array(baseball)

# Print out the 50th row of np_baseball
print(np_baseball[49,:])

# Select the entire second column of np_baseball: np_weight
np_weight = np_baseball[:,1]

# Print out height of 124th player
print(np_baseball[123, 0])
#---------------------------------------------------------------------------------------------------#

#2D Arithmetic
# baseball is available as a regular list of lists
# update is available as 2D Numpy array

# Import numpy package
import numpy as np

# Create np_baseball (3 cols)
np_baseball = np.array(baseball)

# Print out addition of np_baseball and update
print(np_baseball + update)

# Create Numpy array: conversion
conversion = np.array([0.0254, 0.453592, 1])

# Print out product of np_baseball and conversion
print(np_baseball * conversion)
#---------------------------------------------------------------------------------------------------#

#Average versus median
# np_baseball is available

# Import numpy
import numpy as np

# Create np_height from np_baseball
np_height = np_baseball[:,0]

# Print out the mean of np_height
print(np.mean(np_height))

# Print out the median of np_height
print(np.median(np_height))
#---------------------------------------------------------------------------------------------------#

#Explore the baseball data
# np_baseball is available

# Import numpy
import numpy as np

# Print mean height (first column)
avg = np.mean(np_baseball[:,0])
print("Average: " + str(avg))

# Print median height. Replace 'None'
med = np.median(np_baseball[:,0])
print("Median: " + str(med))

# Print out the standard deviation on height. Replace 'None'
stddev = np.std(np_baseball[:,0])
print("Standard Deviation: " + str(stddev))

# Print out correlation between first and second column. Replace 'None'
corr = np.corrcoef(np_baseball[:,0], np_baseball[:,1])
print("Correlation: " + str(corr))
#---------------------------------------------------------------------------------------------------#

#Blend it all together
# heights and positions are available as lists

# Import numpy
import numpy as np

# Convert positions and heights to numpy arrays: np_positions, np_heights
np_positions = np.array(positions)
np_heights = np.array(heights)

# Heights of the goalkeepers: gk_heights
gk_heights = np_heights[np_positions == 'GK']

# Heights of the other players: other_heights
other_heights = np_heights[np_positions != 'GK']

# Print out the median height of goalkeepers. Replace 'None'
print("Median height of goalkeepers: " + str(np.median(gk_heights)))

# Print out the median height of other players. Replace 'None'
print("Median height of other players: " + str(np.median(other_heights)))

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

1.Intro to Python for Data Science/NumPy - Chapter 4.py


"""
.. _ica:

==================================================
Background on Independent Component Analysis (ICA)
==================================================

.. contents:: Contents
   :local:
   :depth: 2

Many M/EEG signals including biological artifacts reflect non-Gaussian
processes. Therefore PCA-based artifact rejection will likely perform worse at
separating the signal from noise sources.
MNE-Python supports identifying artifacts and latent components using temporal ICA.
MNE-Python implements the :class:`mne.preprocessing.ICA` class that facilitates applying ICA
to MEG and EEG data. Here we discuss some
basics of ICA.

Concepts
========

ICA finds directions in the feature space corresponding to projections with high non-Gaussianity.

- not necessarily orthogonal in the original feature space, but orthogonal in the whitened feature space.
- In contrast, PCA finds orthogonal directions in the raw feature
  space that correspond to directions accounting for maximum variance.
- or differently, if data only reflect Gaussian processes ICA and PCA are equivalent.

**Example**: Imagine 3 instruments playing simultaneously and 3 microphones
recording mixed signals. ICA can be used to recover the sources ie. what is played by each instrument.

ICA employs a very simple model: :math:`X = AS` where :math:`X` is our observations, :math:`A` is the mixing matrix and :math:`S` is the vector of independent (latent) sources.

The challenge is to recover :math:`A` and :math:`S` from :math:`X`.

First generate simulated data
-----------------------------
"""  # noqa: E501

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

from sklearn.decomposition import FastICA, PCA

np.random.seed(0)  # set seed for reproducible results
n_samples = 2000
time = np.linspace(0, 8, n_samples)

s1 = np.sin(2 * time)  # Signal 1 : sinusoidal signal
s2 = np.sign(np.sin(3 * time))  # Signal 2 : square signal
s3 = signal.sawtooth(2 * np.pi * time)  # Signal 3: sawtooth signal

S = np.c_[s1, s2, s3]
S += 0.2 * np.random.normal(size=S.shape)  # Add noise

S /= S.std(axis=0)  # Standardize data
# Mix data
A = np.array([[1, 1, 1], [0.5, 2, 1.0], [1.5, 1.0, 2.0]])  # Mixing matrix
X = np.dot(S, A.T)  # Generate observations

###############################################################################
# Now try to recover the sources
# ------------------------------

# compute ICA
ica = FastICA(n_components=3)
S_ = ica.fit_transform(X)  # Get the estimated sources
A_ = ica.mixing_  # Get estimated mixing matrix

# compute PCA
pca = PCA(n_components=3)
H = pca.fit_transform(X)  # estimate PCA sources

plt.figure(figsize=(9, 6))

models = [X, S, S_, H]
names = ['Observations (mixed signal)',
         'True Sources',
         'ICA estimated sources',
         'PCA estimated sources']
colors = ['red', 'steelblue', 'orange']

for ii, (model, name) in enumerate(zip(models, names), 1):
    plt.subplot(4, 1, ii)
    plt.title(name)
    for sig, color in zip(model.T, colors):
        plt.plot(sig, color=color)

plt.tight_layout()

###############################################################################
# :math:`\rightarrow` PCA fails at recovering our "instruments" since the
# related signals reflect non-Gaussian processes.


from sympy import FiniteSet, pi
def time_period(length):
    g = 9.8
    T = 2*pi*(length/g)**0.5
    return T

if __name__ == '__main__':
    L = FiniteSet(15,18,21,22.5,25)
    for l in L:
        t = time_period(l/100);
        print('Length: {0} cm Time Period: {1:.3f} s'.format(float(l), float(t)))