"""Measurements using spatial objects."""
import numpy as np

from skspatial.objects import Points
from skspatial.objects import Vector
from skspatial.typing import array_like

def area_triangle(point_a: array_like, point_b: array_like, point_c: array_like) -> np.float64:
    """
    Return the area of a triangle defined by three points.

    The points are the vertices of the triangle. They must be 3D or less.

    Parameters
    ----------
    point_a, point_b, point_c : array_like
        The three vertices of the triangle.

    Returns
    -------
    np.float64
        The area of the triangle.

    References
    ----------
    http://mathworld.wolfram.com/TriangleArea.html

    Examples
    --------
    >>> from skspatial.measurement import area_triangle

    >>> area_triangle([0, 0], [0, 1], [1, 0])
    0.5

    >>> area_triangle([0, 0], [0, 2], [1, 1])
    1.0

    >>> area_triangle([3, -5, 1], [5, 2, 1], [9, 4, 2]).round(2)
    12.54

    """
    vector_ab = Vector.from_points(point_a, point_b)
    vector_ac = Vector.from_points(point_a, point_c)

    # Normal vector of plane defined by the three points.
    vector_normal = vector_ab.cross(vector_ac)

    return 0.5 * vector_normal.norm()

def volume_tetrahedron(
    point_a: array_like,
    point_b: array_like,
    point_c: array_like,
    point_d: array_like,
) -> np.float64:
    """
    Return the volume of a tetrahedron defined by four points.

    The points are the vertices of the tetrahedron. They must be 3D or less.

    Parameters
    ----------
    point_a, point_b, point_c, point_d : array_like
        The four vertices of the tetrahedron.

    Returns
    -------
    np.float64
        The volume of the tetrahedron.

    References
    ----------
    http://mathworld.wolfram.com/Tetrahedron.html

    Examples
    --------
    >>> from skspatial.measurement import volume_tetrahedron

    >>> volume_tetrahedron([0, 0], [3, 2], [-3, 5], [1, 8])
    0.0

    >>> volume_tetrahedron([0, 0, 0], [2, 0, 0], [1, 1, 0], [0, 0, 1]).round(3)
    0.333

    >>> volume_tetrahedron([0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]).round(3)
    0.167

    """
    vector_ab = Vector.from_points(point_a, point_b)
    vector_ac = Vector.from_points(point_a, point_c)
    vector_ad = Vector.from_points(point_a, point_d)

    vector_cross = vector_ac.cross(vector_ad)

    # Set the dimension to 3 so it matches the cross product.
    vector_ab = vector_ab.set_dimension(3)

    return 1 / 6 * abs(vector_ab.dot(vector_cross))

def area_signed(points: array_like) -> float:
    """
    Return the signed area of a simple polygon given the 2D coordinates of its veritces.

    The signed area is computed using the shoelace algorithm. A positive area is
    returned for a polygon whose vertices are given by a counter-clockwise
    sequence of points.

    Parameters
    ----------
    points : array_like
         Input 2D points.

    Returns
    -------
    area_signed : float
        The signed area of the polygon.

    Raises
    ------
    ValueError
        If the points are not 2D.
        If there are fewer than three points.

    References
    ----------
    https://en.wikipedia.org/wiki/Shoelace_formula
    https://alexkritchevsky.com/2018/08/06/oriented-area.html
    https://rosettacode.org/wiki/Shoelace_formula_for_polygonal_area#Python

    Examples
    --------
    >>> from skspatial.measurement import area_signed

    >>> area_signed([[0, 0], [1, 0], [0, 1]])
    0.5

    >>> area_signed([[0, 0], [0, 1], [1, 0]])
    -0.5

    >>> area_signed([[0, 0], [0, 1], [1, 2], [2, 1], [2, 0]])
    -3.0

    """
    points = Points(points)
    n_points = points.shape[0]

    if points.dimension != 2:
        raise ValueError("The points must be 2D.")

    if n_points < 3:
        raise ValueError("There must be at least 3 points.")

    X = points[:, 0]
    Y = points[:, 1]

    indices = np.arange(n_points)
    indices_offset = indices - 1

    return 0.5 * np.sum(X[indices_offset] * Y[indices] - X[indices] * Y[indices_offset])


import numpy as np
from numba import jit, njit, vectorize, guvectorize

@njit
def haversine(lat1, lon1, lat2, lon2):
    """
    Haversine distance in kilometers between two points given in degrees.
    r = 6371.009, 2r = 12742.018
    Because the haversine distance assumes a spherical Earth, it will only
    be accurate within ~0.5%. The mean earth radius is used (6371km).
    """
    λ1 = np.radians(lat1)
    λ2 = np.radians(lat2)
    φ1 = np.radians(lon1)
    φ2 = np.radians(lon2)
    Δλ = λ2 - λ1
    Δφ = φ2 - φ1
    return 12742.018 * np.arcsin(np.sqrt(
        np.sin(Δλ/2.0)**2 + (np.cos(λ1) * np.cos(λ2) * np.sin(Δφ/2.0)**2)))

@guvectorize([("void(float64[:], float64[:], float64[:], float64[:],"
               " float64[:])")],
             "(n),(n),(n),(n)->(n)")
def haversine_elementwise(lat1, lon1, lat2, lon2, res):
    """ Elementwise haversine distance between vectors
        of latitudes and longitudes

        lat1, lon1: vectors for latitude and longitude of locations
        lat2, lon2: vectors for latitude and longitude of locations
    """
    for i in range(lat1.shape[0]):
        res[i] = haversine(lat1[i], lon1[i], lat2[i], lon2[i])

@guvectorize(["void(float64, float64, float64[:], float64[:], float64[:])"],
             "(),(),(n),(n)->(n)")
def haversine_vector(lat1, lon1, latcol, loncol, res):
    """ Haversine distance between a fixed lat/lon and vectors of lat/lon
    lat1, lon1: Fixed latitude and longitude
    latvec, lonvec: vector of latitudes and longitudes
    """
    for i in range(latcol.shape[0]):
        res[i] = haversine(lat1, lon1, latcol[i], loncol[i])

@guvectorize([("void(float64[:], float64[:], float64[:], float64[:],"
               " float64[:,:])")],
             "(n),(n),(m),(m)->(n,m)")
def haversine_outer_product(lat1, lon1, lat2, lon2, res):
    """ Haversine distance between vectors of latitudes and longitudes
        (outer product)

        lat1, lon1: vectors for latitude and longitude of locations
        lat2, lon2: vectors for latitude and longitude of locations
    """
    for i in range(lat1.shape[0]):
        for j in range(lat2.shape[0]):
            res[i, j] = haversine(lat1[i], lon1[i], lat2[j], lon2[j])


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

def calc_d1(St, K, r, s, T, t=0, q=0):
    return (np.log(St / K) + (r - q + 0.5 * s ** 2) * (T - t)) \
           / (s * np.sqrt(T - t))

def calc_d2(d1, s, T, t=0):
    return d1 - s * np.sqrt(T - t)

def problem2a():
    T_final = 5
    Ts = np.arange(dt, T_final, dt)

    mus_c = []
    sgs_c = []
    for T in Ts:
        d1 = calc_d1(St, K, r, sg, T, q=q)
        d2 = calc_d2(d1, sg, T)
        delta = np.exp(-q * T) * norm.cdf(d1)
        gamma = norm.pdf(d1) * np.exp(-q * T) / (St * sg * np.sqrt(T))
        theta = -(St * norm.pdf(d1) * sg * np.exp(-q * T)) / (2 * np.sqrt(T)) \
                + q * St * norm.cdf(d1) * np.exp(-q * T) \
                - r * K * np.exp(-r * T) * norm.cdf(d2)
        Ct = St * np.exp(-q * T) * norm.cdf(d1) - K * np.exp(-r * T) * norm.cdf(d2)
        mu_call = (1. / Ct) * (theta + mu * St * delta + 0.5 * sg ** 2 * St ** 2 * gamma)
        sg_call = (1. / Ct) * sg  * St * delta
        mus_c.append(mu_call)
        sgs_c.append(sg_call)
    plt.figure()
    plt.plot(Ts, mus_c)
    plt.ylabel('Price')
    plt.xlabel('Time to maturity')
    plt.figure()
    plt.plot(Ts, sgs_c)
    plt.ylabel('Price')
    plt.xlabel('Time to maturity')
    plt.show()

def problem2b():
    T = 1
    Sts = np.arange(0.01, 100, 0.1)
    mus_c = []
    sgs_c = []
    for St in Sts:
        d1 = calc_d1(St, K, r, sg, T, q=q)
        d2 = calc_d2(d1, sg, T)
        delta = np.exp(-q * T) * norm.cdf(d1)
        gamma = norm.pdf(d1) * np.exp(-q * T) / (St * sg * np.sqrt(T))
        theta = -(St * norm.pdf(d1) * sg * np.exp(-q * T)) / (2 * np.sqrt(T)) \
                + q * St * norm.cdf(d1) * np.exp(-q * T) \
                - r * K * np.exp(-r * T) * norm.cdf(d2)
        Ct = St * np.exp(-q * T) * norm.cdf(d1) - K * np.exp(-r * T) * norm.cdf(d2)
        mu_call = (1. / Ct) * (theta + mu * St * delta + 0.5 * sg ** 2 * St ** 2 * gamma)
        sg_call = (1. / Ct) * sg  * St * delta
        mus_c.append(mu_call)
        sgs_c.append(sg_call)
    plt.figure()
    plt.plot(Sts, mus_c)
    plt.ylabel('Price')
    plt.xlabel('Stock Price')
    plt.figure()
    plt.plot(Sts, sgs_c)
    plt.ylabel('Price')
    plt.xlabel('Stock Price')
    plt.show()

if __name__ == '__main__':

    K = 50
    sg = 0.5
    mu = 0.15
    q = 0.08
    r = 0.13
    St = 50
    dt = 1 / 252.

    # problem2a()
    problem2b()


import numpy as np
import math

"""Pauli Gates X, Y, Z"""
X = np.array([[0,1],[1,0]])
Y = np.array([[0,-1j],[-1j,0]])
Z = np.array([[1,0],[0,-1]])

"""Hadamard Gate H"""
H = (1/np.sqrt(2))*np.array([[1,1],[1,-1]])

"""Phase Gate S"""
S = np.array([[1,0],[0,-1j]])

"""π/8 Gate T"""
T_pi = np.array([[1,0],[0,math.e**((math.pi/4)*1j)]])

"""T dagger"""
T_dag = np.array([[1,0],[0,math.e**((math.pi/4)*-1j)]])

"""Controlled NOT, CNOT"""
cnot = np.array([[1,0,0,0],[0,1,0,0],[0,0,0,1],[0,0,1,0]])

"""SWAP Gate swap"""
swap = np.array([[1,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,1]])

# """Controlled Z cZ"""
# cz = np.array([[1,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,1]])

"""Controlled Phase Gate cS"""
cs = np.array([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,-1j]])

"""Double Controlled NOT or Toffoli, ccNOT"""
ccnot = np.array([[1,0,0,0,0,0,0,0],[0,1,0,0,0,0,0,0],[0,0,1,0,0,0,0,0],[0,0,0,1,0,0,0,0],[0,0,0,0,1,0,0,0],[0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1],[0,0,0,0,0,0,1,0]])

"""Controlled Swap, Fredkin Gate, cSwap"""
cswap = np.array([[1,0,0,0,0,0,0,0],[0,1,0,0,0,0,0,0],[0,0,1,0,0,0,0,0],[0,0,0,1,0,0,0,0],[0,0,0,0,1,0,0,0],[0,0,0,0,0,0,1,0],[0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1]])

"""Controlled Pauli Z"""
cz = np.array([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,-1]])

"""Square root of NOT"""
sqrt_not = np.array([[(1+1j)/2 , (1-1j)/2],[(1-1j)/2 , (1+1j)/2]])

"""P"""
p = np.array([[1,0],[0,1j]])


import numpy as np
import imageio
import math

def hough_line(img, angle_step=1, lines_are_white=True, value_threshold=5):
    """
    Hough transform for lines
    Input:
    img - 2D binary image with nonzeros representing edges
    angle_step - Spacing between angles to use every n-th angle
                 between -90 and 90 degrees. Default step is 1.
    lines_are_white - boolean indicating whether lines to be detected are white
    value_threshold - Pixel values above or below the value_threshold are edges
    Returns:
    accumulator - 2D array of the hough transform accumulator
    theta - array of angles used in computation, in radians.
    rhos - array of rho values. Max size is 2 times the diagonal
           distance of the input image.
    """
    # Rho and Theta ranges
    thetas = np.deg2rad(np.arange(-90.0, 90.0, angle_step))
    width, height = img.shape
    diag_len = int(round(math.sqrt(width * width + height * height)))
    rhos = np.linspace(-diag_len, diag_len, diag_len * 2)

    # Cache some resuable values
    cos_t = np.cos(thetas)
    sin_t = np.sin(thetas)
    num_thetas = len(thetas)

    # Hough accumulator array of theta vs rho
    accumulator = np.zeros((2 * diag_len, num_thetas), dtype=np.uint8)
    # (row, col) indexes to edges
    are_edges = img > value_threshold if lines_are_white else img < value_threshold
    y_idxs, x_idxs = np.nonzero(are_edges)

    # Vote in the hough accumulator
    for i in range(len(x_idxs)):
        x = x_idxs[i]
        y = y_idxs[i]

        for t_idx in range(num_thetas):
            # Calculate rho. diag_len is added for a positive index
            rho = diag_len + int(round(x * cos_t[t_idx] + y * sin_t[t_idx]))
            accumulator[rho, t_idx] += 1

    return accumulator, thetas, rhos

def show_hough_line(img, accumulator, thetas, rhos, save_path=None):
    import matplotlib.pyplot as plt

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

    ax[0].imshow(img, cmap=plt.cm.gray)
    ax[0].set_title('Input image')
    ax[0].axis('image')

    ax[1].imshow(
        accumulator, cmap='jet',
        extent=[np.rad2deg(thetas[-1]), np.rad2deg(thetas[0]), rhos[-1], rhos[0]])
    ax[1].set_aspect('equal', adjustable='box')
    ax[1].set_title('Hough transform')
    ax[1].set_xlabel('Angles (degrees)')
    ax[1].set_ylabel('Distance (pixels)')
    ax[1].axis('image')

    # plt.axis('off')
    if save_path is not None:
        plt.savefig(save_path, bbox_inches='tight')
    plt.show()

if __name__ == '__main__':
    imgpath = 'imgs/binary_crosses.png'
    img = imageio.imread(imgpath)
    if img.ndim == 3:
        img = rgb2gray(img)
    accumulator, thetas, rhos = hough_line(img)
show_hough_line(img, accumulator, save_path='imgs/output.png')


#! /usr/bin/env python
# -*- coding: utf-8 -*-
#======================================================================
#
# GradientDescent.py -
#
# Created by skywind on 2019/03/14
# Last Modified: 2019/03/14 21:00:27
#
#======================================================================
from __future__ import print_function, unicode_literals
import sys
import time

#----------------------------------------------------------------------
# GradientDescent
#----------------------------------------------------------------------
def GradientDescent(x, y, theta, alpha, iterations, limit):
    rows = len(x)
    if rows == 0:
        raise ValueError('Data size must great than zero.')
    cols = len(x[0])
    theta = [ t for t in theta ]
    for count in range(iterations):
        # iterate feature columns
        update = [ 1.0 ] * cols
        for j in range(cols):
            # calculate derivation
            derivation = 0
            for i in range(rows):
                h = sum([ x[i][n] * theta[n] for n in range(cols) ])
                derivation += (h - y[i]) * x[i][j]
            derivation = derivation / float(rows)
            update[j] = theta[j] - alpha * derivation
        # update theta
        theta = update
        # calculate error
        error = 0
        for i in range(rows):
            h = sum([ x[i][n] * theta[n] for n in range(cols) ])
            error += (h - y[i]) * (h - y[i])
        error = error / float(rows)
        if error < limit:
            break
    return theta

#----------------------------------------------------------------------
# GradientDescent
#----------------------------------------------------------------------
def GradientStep(x, y, theta, alpha):
    cols = len(x)
    if cols == 0:
        raise ValueError('Feature size must great than zero.')
    h = sum([ x[n] * theta[n] for n in range(cols) ])
    update = [ 1.0 ] * cols
    for j in range(cols):
        derivation = (h - y) * x[j]
        update[j] = theta[j] - alpha * derivation
    return update

#----------------------------------------------------------------------
# Increamental GradientDescent
#----------------------------------------------------------------------
def GradientDescent2(x, y, theta, alpha, iterations, limit):
    rows = len(x)
    if rows == 0:
        raise ValueError('Data size must great than zero.')
    cols = len(x[0])
    for count in range(iterations):
        for i in range(rows):
            theta = GradientStep(x[i], y[i], theta, alpha)
        # calculate error
        error = 0
        for i in range(rows):
            h = sum([ x[i][n] * theta[n] for n in range(cols) ])
            error += (h - y[i]) * (h - y[i])
        error = error / float(rows)
        if error < limit:
            break
    return theta

#----------------------------------------------------------------------
# numpy
#----------------------------------------------------------------------
def GradientDescent3(x, y, theta, alpha, iterations, limit):
    rows = len(x)
    if rows == 0:
        raise ValueError('Data size must great than zero.')
    import numpy
    x = numpy.array(x)
    y = numpy.array(y)
    theta = numpy.array([ t for t in theta ])
    t = x.transpose()
    for count in range(iterations):
        h = numpy.dot(x, theta)
        error = h - y
        derivation = numpy.dot(t, error) / float(rows)
        theta = theta - float(alpha) * derivation
        # update error
        e = numpy.dot(x, theta) - y
        s = sum(e * e) / float(rows)
        if s < limit:
            break
    return theta

#----------------------------------------------------------------------
# test
#----------------------------------------------------------------------
def TestGD(proc, x, y, alpha, maxiter, limit = 0.0001):
    k = [ 1 ] * len(x[0])
    t = time.time()
    k = proc(x, y, k, alpha, maxiter, limit)
    t = time.time() - t
    print('GradientDescent time:', t)
    print('Theta:', k)
    error = 0
    X = [[3.1, 5.5], [3.3, 5.9], [3.5, 6.3], [3.7, 6.7], [3.9, 7.1]]
    Y = [9.5, 10.2, 10.9, 11.6, 12.3]
    for i in range(len(X)):
        h = sum([ X[i][n] * k[n] for n in range(len(k)) ])
        error += (h - Y[i]) * (h - Y[i])
        print(Y[i], h)
    error /= len(X)
    print('error', error)
    print()
    return 0

#----------------------------------------------------------------------
# Samples
#----------------------------------------------------------------------
X = [[1.1, 1.5], [1.3, 1.9], [1.5, 2.3], [1.7, 2.7], [1.9, 3.1],
    [2.1, 3.5], [2.3, 3.9], [2.5, 4.3], [2.7, 4.7], [2.9, 5.1]]
Y = [2.5, 3.2, 3.9, 4.6, 5.3, 6, 6.7, 7.4, 8.1, 8.8]

TestGD(GradientDescent, X, Y, 0.1, 50000)
TestGD(GradientDescent2, X, Y, 0.1, 50000)
TestGD(GradientDescent3, X, Y, 0.1, 50000)


# -*- coding: utf-8 -*-
"""
Created on Fri Jul 26 08:20:48 2019

@author: MAHDI
"""
import numpy as np
import matplotlib.pyplot as plt
def GetY(solution , xval):
    Y=0.0
    for i in range(len(solution)):
        Y = Y+ xval**i * solution[i]
    return Y
def DrawPolinomial(solution,mycolor,mylabel):
    x= np.linspace(0.0,11,100)
#    print(x)
    #y=np.array( [GetY(solution,xval) for xval in x])
    y=GetY(solution,x)
#    print(y)
    plt.plot(x,y,color=mycolor,label=mylabel)
def PolinomialRegression(x,y,n,m):
    """
    m= order of polinomial
    """
# =============================================================================
#     if n<m+1:
#         return "impossible"
# =============================================================================
    a=np.zeros((m+1,m+1))
    b=np.zeros((m+1))
#    print(a,b)
    for i in range(m+1):
        sum = np.sum(x**i)
        xid=0
        yid=i
        while yid>=0:
            a[xid][yid]=sum
            xid = xid +1
            yid = yid -1
    for i in range(m+1,m+m+1):
        sum= np.sum(x**i)
        xid=i-m
        yid=m
        while xid<=m:
            a[xid][yid]=sum
            xid = xid +1
            yid = yid -1
#    print(a)
    for i in range(m+1):
        sum = np.sum([(xx**i) * yy for (xx,yy) in zip(x,y) ])
#        print(sum)
        b[i]=sum
#    print(b)
    sol = np.linalg.solve(a,b)
    return sol
def PrintSolution(Solution,x,y):
    print('----------============----------')
    print('Order of polynomial',len(Solution)-1)
    for i in range(len(Solution)):
        print('a',i,' = ',Solution[i],sep='')
    print('Regression coefficient:',RegressionCoefficient(Solution,x,y))
    print('----------============----------')
def RegressionCoefficient(Solution, x,y):
    yavg = np.sum(y) / len(y)
#    print(yavg)
    St = np.sum(np.array([(yval-yavg)*(yval-yavg) for yval in y]))
#    print(St)
    Sr = np.sum(np.array([(yval - GetY(Solution,xval))*(yval - GetY(Solution,xval)) for (xval,yval) in zip(x,y)]))
    return np.sqrt(1.0-Sr/St)

if __name__ == '__main__':
    file = open('data.txt', 'r+')
    data = [list(map(float,line.split(' '))) for line in file.readlines() ]
#    print(data)
    x= [dat[0] for dat  in data]
    y= [dat[1] for dat  in data]
    x=np.array(x)
    y=np.array(y)
    assert(len(x)==len(y))
    n=len(x)
# =============================================================================
#     for i in zip(x,y):
#         print(i)
# =============================================================================
    plt.figure(figsize=(15,15))
    plt.scatter(x,y,s=0.5,color = 'purple',label='original data')
    sol1 = PolinomialRegression(x,y,n,1)
    DrawPolinomial(sol1,'red','First order fit')

    sol2 = PolinomialRegression(x,y,n,2)
    DrawPolinomial(sol2,'black','Second order fit')

    sol3 = PolinomialRegression(x,y,n,3)
    DrawPolinomial(sol3,'green','Third order fit')

    plt.legend(loc='best',title='Curve Fitting Example')

# =============================================================================
#     sol100=PolinomialRegression(x,y,n,100)
#     DrawPolinomial(sol100,'pink','100th Order fit')
# =============================================================================

    PrintSolution(sol1,x,y)
    PrintSolution(sol2,x,y)
    PrintSolution(sol3,x,y)
#    PrintSolution(sol100,x,y)
# =============================================================================
#     print(sol1)
#     print(RegressionCoefficient(sol1,x,y))
#
#     print(sol2)
#     print(RegressionCoefficient(sol2,x,y))
#     print(sol3)
#     print(RegressionCoefficient(sol3,x,y))
# =============================================================================

Numerical/Offline 3 on Curve Fitting/1705003.py


import numpy as np

EPSILON = 1e-10

def _error(actual: np.ndarray, predicted: np.ndarray):
    """ Simple error """
    return actual - predicted

def me(actual: np.ndarray, predicted: np.ndarray):
    """ Mean Error """
    return np.mean(_error(actual, predicted))

def _percentage_error(actual: np.ndarray, predicted: np.ndarray):
    """
    Percentage error

    Note: result is NOT multiplied by 100
    """
    return _error(actual, predicted) / (actual + EPSILON)

def mae(actual: np.ndarray, predicted: np.ndarray):
    """ Mean Absolute Error """
    return np.mean(np.abs(_error(actual, predicted)))

def mse(actual: np.ndarray, predicted: np.ndarray):
    """ Mean Squared Error """
    return np.mean(np.square(_error(actual, predicted)))

def rmse(actual: np.ndarray, predicted: np.ndarray):
    """ Root Mean Squared Error """
    return np.sqrt(mse(actual, predicted))


"""
auralib module containing various window functions for signal processing.

Author:   Wes Hamlyn
Created:  24-Mar-2020
Last Mod: 24-Mar-2020
"""

import numpy as np

def papoulis(nsamp, normed=True):
    """
    Calculate a time-domain Papoulis (a.k.a Bohman) window

    Input:
    ------
        nsamp = number of samples to include in the window

    Output:
    -------
        w = window amplitudes

    Reference:
    ----------
        https://prod-ng.sandia.gov/techlib-noauth/access-control.cgi/2017/174042.pdf
        page: 84
    """

    tmin = -0.5
    tmax = 0.5
    dt = (tmax-tmin)/(nsamp-1)

    t = np.arange(nsamp)*dt + tmin

    w = (np.pi**2)/4 * (1-2*np.abs(t))*np.cos(2*np.pi*np.abs(t)) + \
        np.pi/4*np.sin(2*np.pi*np.abs(t))

    if normed:
        w = w / w.max()

    return w

def cosine(nsamp, taper_len):
    """
    Calculate a time-domain window with cosine tapers at each end

    nsamp = total length of window operator
    nsamp_taper = length of cosine taper in samples at ends of window
    """

    # build cosine ramp from zero to one
    x = np.linspace(-np.pi, 0.0, taper_len)
    costaper = 0.5*(np.cos(x)+1)

    # make window with ones everwhere and add cosine tapers to ends
    w = np.ones(nsamp)
    w[0:taper_len] = costaper
    w[-taper_len:] = costaper[-1::-1]

    return w


# usage of regressions to find coefficients of formula to sum terms `i^m` from 0 to n
import numpy as np
from numpy.linalg import inv

def plot(y,z):
  import matplotlib.pyplot as plt

  plt.plot(y, '.')
  plt.plot(z)
  plt.show()

# solve Ordinary Least Squares
def solveOLS(X, Y):
  Z = inv(X.T*X)
  return Z*X.T*Y

# generate `n` samples
n = 15

# exponent
m = 8

x = np.arange(0,n,1)

# theory
z = .5*x*(x+1)

# generate output function
y = np.cumsum(x**m)
# format output
y.shape = (n,1)
Y = np.asmatrix(y)

# prepare matrix
X = np.ones((n,1))

x.shape = (n,1)

# add column of input until m+1 (inclusive)
for i in range(1, m+2):
  X = np.append(X, x**i, axis =1)

X = np.asmatrix(X)
r = solveOLS(X, Y)
print r
print np.cumsum(r)

# m=0: (1,   1)
# m=1: (0, 1/2, 1/2)
# m=2: (0, 1/6, 1/2, 1/3)
# m=3: (0,   0, 1/4, 1/2,  1/4)
# m=4: (0,   -1/30,   0, 1/3,  1/2, 1/5)
# m=5: (0,   0,   0,   0, 5/12, 1/2, 1/6)
#
# sum always 1!!? (except for 0)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Jan 26 16:48:41 2019

@author: alankar
"""
import numpy as np
import matplotlib.pyplot as plt

def quad_solve1(a,b,c):
    D = b**2-4*a*c
    return np.array([(-b+np.sqrt(D))/(2*a),(-b-np.sqrt(D))/(2*a)])

def quad_solve2(a,b,c):
    D = b**2-4*a*c
    return np.array([(2*c)/(-b-np.sqrt(D)),(2*c)/(-b+np.sqrt(D))])

print('Using form 1:')
print('Roots are:',end=' ')
print(quad_solve1(.001, 1000, .001))
print('Using form 2:')
print('Roots are:',end=' ')
print(quad_solve2(.001, 1000, .001))

"""
The two functions differ in their results. This happens when $b^2>>|4ac|$. In either of the two
formulae, finding one of the roots involve subtracting two nearly equal quantities (Discriminant is almost $b^2$).
This results in loss of numerical precision corresponding to that root. So in one formula if Root 1 is more accurate
than Root 2, then in the other formula, Root2 is more accurate than Root 1. Now the question is which root is more accurate
in which formula?
Well that depends on the sign of $b$ in $ax^2+bx+c=0$
When $b>0$, $-b-\sqrt{b^2-4ac}$ doesn't involve subtracting two nearly equal quantities. So Root 2 of quad_solve1 and
Root 1 of quad_solve2 gives accurate results.
Converse happens for $b<0$

Lets code this in the following function:
"""

def quad_solve_acc(a,b,c):
    if b>0:
        return np.array([quad_solve2(a,b,c)[0],quad_solve1(a,b,c)[1]])
    else:
        return np.array([quad_solve1(a,b,c)[10],quad_solve2(a,b,c)[1]])

print('Accurate Roots are:',end=' ')
print(quad_solve_acc(.001, 1000, .001))

x = -np.linspace(0,14,100)*1e-7
plt.plot(x,0.001*x**2+1000*x+0.001)
plt.grid()
plt.show()


"""
Example 2 - Multi Variable Linear Regression

NOTE: The example and sample data is being taken from the "Machine Learning course by Andrew Ng" in Coursera.

Problem:
  Suppose you are the CEO of a restaurant franchise and are considering
  different cities for opening a new outlet. The chain already has trucks
  in various cities and you have data for profits and populations from
  the cities. You would like to use this data to help you select which
  city to expand to next.

  The file 'data/linear_reg/ex1data1.txt' contains the dataset for our
  linear regression problem. The first column is the population of a city
  and the second column is the profit of a food truck in that city.
  A negative value for profit indicates a loss.
"""

# initial imports
import numpy as np
import matplotlib.pyplot as plt
from models.data_preprocessing import feature_normalize, add_bias_unit
from models.linear_regression import gradient_descent, normal_equation

plt.ion()

# ----------------Loading X and y matrix ---------------
print('Loading data ...')

data = np.loadtxt('data/ex1data2.txt', delimiter=',')
X = data[:, :-1]  # 47x2
y = data[:, -1, None]  # 47x1
m = y.size  # 47

# printing first 5 elements
print(X[0:5, :])

# ----------------Feature Normalization -----------------
print("Normalizing the features")
X, mu, sigma = feature_normalize(X)

# adding intercept term to X
X = add_bias_unit(X)

print('Running gradient descent ...')

# Choose some alpha value
alpha = 0.03
num_iters = 400

# Init Theta and Run Gradient Descent
theta = np.zeros((X.shape[1], 1))
theta, J_history = gradient_descent(X, y, theta, alpha, num_iters)

# Plot the convergence graph
fig = plt.figure("Covariance Graph")
ax = fig.subplots()
ax.plot(range(J_history.size), J_history, lw=2)
ax.set_xlabel('Number of iterations')
ax.set_ylabel('Cost J')
fig.show()

# Display gradient descent's result
print('Theta computed from gradient descent: ')
print(theta)

# Estimate the price of a 1650 sq-ft, 3 br house

test_data = np.array([1650, 3]).reshape(1, 2)
test_data, _, __ = feature_normalize(test_data, mu, sigma)
test_data = add_bias_unit(test_data)
price = test_data.dot(theta)

# ============================================================

print('Predicted price of a 1650 sq-ft, 3 br house (using gradient descent): {}'.format(price))

# ================Normal Equations ================

print('Solving with normal equations...')

# ----------------Loading X and y matrix ---------------
print('Loading data ...')

data = np.loadtxt('data/ex1data2.txt', delimiter=',')
X = data[:, :-1]  # 47x2
y = data[:, -1, None]  # 47x1
m = y.size  # 47

# Add intercept term to X
X = add_bias_unit(X)

# Calculate the parameters from the normal equation
theta = normal_equation(X, y)

# Display normal equation's result
print('Theta computed from the normal equations: ')
print(theta)

# Estimate the price of a 1650 sq-ft, 3 br house
test_data = np.array([1650, 3]).reshape(1, 2)
test_data = add_bias_unit(test_data)
price = test_data.dot(theta)

print('Predicted price of a 1650 sq-ft, 3 br house (using normal equations): {}'.format(price))

# bloking matplotlib figures for obervations
plt.ioff()
plt.show()


import numpy as np

np.array([1, 2])

# Exercice 2.3

print("Question 1 \n")

A, x = np.array([[1, 2, 3], [4, 5, 6]]), np.array([1, 2, 3])

print(A.shape, x.shape)
print(A.size, x.size)
print(A.ndim, x.ndim)
print(A.dtype, x.dtype)
print(A.sum(), x.sum())
print(A.prod(), x.prod())

print("\n Question2 \n")

nbColsA, nbLignesA = A.shape

print(nbColsA, nbLignesA)

prodLignesA = A.prod(axis=1)
prodColA = A.prod(axis=0)

print(prodLignesA, prodColA)

print("\nQuestion 3\n")

print(A*x)
# Multiplie chaque ligne de A par x (coefficient à coefficient)

print(A.dot(x))
# Fait la multiplication matricielle pour A et x

print(np.dot(A, x))
# Fait la multiplication matricielle pour A et x

# Exercice 2.3
print("\nExercice 2.3\n")
A, B, C, D = np.array([[7, 0], [-1, 5], [-1, 2]]), np.array([[1, 4], [-4, 0]]), np.array([7, 3]), np.array([8, 2])

print("A x B=", np.dot(A, B))
print("A x C=", np.dot(A, C))
print("C x D=", np.dot(C, D))
print("D x C=", np.dot(D, C))
print("D x B X C=", np.dot(np.dot(D, B), C))
print("AT x A=", np.dot(A.T, A))
print("A x AT=", np.dot(A, A.T))

# Exercice 2.4
print("\nExercice 2.4")

v1 = np.arange(1, 17, 1)
v2 = np.arange(0.0, 2.1, 0.2)
v3 = np.array([2**x for x in range(7)])

print(v1)
print(v2)
print(v3)

print("\nQuestion 2\n")
# Sûrement à refaire, en fonction du cours
A = np.array([[y**x for x in range(9)]for y in [2, 3, 5]])
B = np.array([np.arange(.0, 1.1, .2) for x in range(4)])
C = np.array([[y for x in range(7)] for y in [.0, .5, 1.]])

print(A)
print(B)
print(C)

print("\nQuestion 3\n")

A = np.array([[1 if (x == 0 or x == 9) else (1 if (y == 0 or y == 9) else (1 if x == y else 0)) for x in range(10)] for y in range(10)])

print(A)

print("\nQuestion 4\n")

L = np.array([[2 if i == j else (-1 if (i == j - 1 or i == j + 1) else 0) for j in range(10)] for i in range(10)])

print(L)

print("\nQuestion 5\n")

T = np.array([[1 if ((i + j) % 2 == 0) else 0 for j in range(10)] for i in range(10)])

print(T)


# My Gauss Siedel Program implemented in Python submitted to GeeksforGeeks: (under review)

import numpy as np

# Iteration Limit.
Limit = 10
"""
Co-efficients of matrix considered : (LHS vectors)
[[10., -1., 2., 0.],[-1., 11., -1., 3.],[2., -1., 10., -1.],[0., 3., -1., 8.]]=A
Corresponding constants of equation on other side: (RHS vector)
[6., 25., -11., 15.]=B
-> We will solve for Ax=B, where x=[x1,x2,x3,x4]
"""

# Initialize the matrix we want to perform Gauss Siedel Method on.
A = np.array([[10., -1., 2., 0.],
              [-1., 11., -1., 3.],
              [2., -1., 10., -1.],
              [0., 3., -1., 8.]])
# Initialize the RHS column vector.
b = np.array([6., 25., -11., 15.])

print("System of equations:")
# Displaying in matrix form, x1*(co-efficient) + x2*(co-efficient) +...
for i in range(A.shape[0]):
    row = ["{0:3g}*x{1}".format(A[i, j], j + 1) for j in range(A.shape[1])]
    print("[{0}] = [{1:3g}]".format(" + ".join(row), b[i]))

# Returning array of zeros for RHS vector (b) for initial approximation.
x = np.zeros_like(b)
for it_count in range(1, Limit):
    x_new = np.zeros_like(x)
    # Display solution-vector/approximate values of x1,x2,x3,x4 for each iteration.
    print("Iteration {0}: {1}".format(it_count, x))
    for i in range(A.shape[0]):
        s1 = np.dot(A[i, :i], x_new[:i])
        s2 = np.dot(A[i, i + 1:], x[i + 1:])
        x_new[i] = (b[i] - s1 - s2) / A[i, i]

     # Using tolerance limit to reach closer approximation to answer and checking if desired accuracy is obtained. (considering relative tolerance/error limit=1e-8, and checking between arrays x and new x) if desired accuracy is obtained, break.

    if np.allclose(x, x_new, rtol=1e-8):
        break
    x = x_new

# Solution to our matrix, vector x=[x1,x2,x3,x4]
print("Solution: {0}".format(x))
error = np.dot(A, x) - b
# Approximation error.
print("Error: {0}".format(error))

Computational Mathematics | Python/Gauss_Siedel.py


import numpy as _np

def euler(f, initial, interval, h):
    """This function solves the differential equation using Euler's method and initial
    value condition.

    Parameters
    ----------
    f : function
        function form of the differential equation to be solved
    initial : tuple
        tuple of the initial values
    interval : tuple
        tuple of the interval in which the differential eq
    h : float
        step size for each iteration

    Returns
    -------
    ts : 1d array
        array of t's
    ys : 1d array
        array of corresponding y's

    """
    a, b = interval
    ts = _np.arange(a, b + h, h)
    ys = _np.zeros_like(ts)

    if initial[0] != interval[0]:
        print("The point for initial value doesn't match the start of interval")
        return None, None

    ys[0] = initial[1]

    for i in range(len(ts) - 1):
        ys[i + 1] = ys[i] + f(ys[i], ts[i]) * h

    return ts, ys

def midpoint_euler(f, initial, interval, h):
    """This function solves the differential equation using Ralstone's method and initial
    value condition.

    Parameters
    ----------
    f : function
        function form of the differential equation to be solved
    initial : tuple
        tuple of the initial values
    interval : tuple
        tuple of the interval in which the differential eq
    h : float
        step size for each iteration

    Returns
    -------
    ts : 1d array
        array of t's
    ys : 1d array
        array of corresponding y's

    """
    A = 0.5
    B1 = 0.0
    B2 = 1
    a, b = interval
    ts = _np.arange(a, b + h, h)
    ys = _np.zeros_like(ts)

    if initial[0] != interval[0]:
        print("The point for initial value doesn't match the start of interval")
        return None, None

    ys[0] = initial[1]

    for i in range(len(ts) - 1):
        p_i = f(ys[i], ts[i])
        q_i = f(ys[i] + A * h * p_i, ts[i] + h * A)
        ys[i + 1] = ys[i] + (B1 * p_i + B2 * q_i) * h

    return ts, ys

def heun(f, initial, interval, h):
    """This function solves the differential equation using Heun's method and initial
    value condition.

    Parameters
    ----------
    f : function
        function form of the differential equation to be solved
    initial : tuple
        tuple of the initial values
    interval : tuple
        tuple of the interval in which the differential eq
    h : float
        step size for each iteration

    Returns
    -------
    ts : 1d array
        array of t's
    ys : 1d array
        array of corresponding y's

    """
    A = 1
    B1 = 0.5
    B2 = 0.5
    a, b = interval
    ts = _np.arange(a, b + h, h)
    ys = _np.zeros_like(ts)

    if initial[0] != interval[0]:
        print("The point for initial value doesn't match the start of interval")
        return None, None

    ys[0] = initial[1]

    for i in range(len(ts) - 1):
        p_i = f(ys[i], ts[i])
        q_i = f(ys[i] + A * h * p_i, ts[i] + h * A)
        ys[i + 1] = ys[i] + (B1 * p_i + B2 * q_i) * h

    return ts, ys

def ralstone(f, initial, interval, h):
    """This function solves the differential equation using Ralstone's method and initial
    value condition.

    Parameters
    ----------
    f : function
        function form of the differential equation to be solved
    initial : tuple
        tuple of the initial values
    interval : tuple
        tuple of the interval in which the differential eq
    h : float
        step size for each iteration

    Returns
    -------
    ts : 1d array
        array of t's
    ys : 1d array
        array of corresponding y's

    """
    A = 2 / 3
    B1 = 0.25
    B2 = 0.75
    a, b = interval
    ts = _np.arange(a, b + h, h)
    ys = _np.zeros_like(ts)

    if initial[0] != interval[0]:
        print("The point for initial value doesn't match the start of interval")
        return None, None

    ys[0] = initial[1]

    for i in range(len(ts) - 1):
        p_i = f(ys[i], ts[i])
        q_i = f(ys[i] + A * h * p_i, ts[i] + h * A)
        ys[i + 1] = ys[i] + (B1 * p_i + B2 * q_i) * h

    return ts, ys

def rk3(f, initial, interval, h):
    """This function solves the differential equation using 3rd order Runga-Kutta
    method and initial value condition.

    Parameters
    ----------
    f : function
        function form of the differential equation to be solved
    initial : tuple
        tuple of the initial values
    interval : tuple
        tuple of the interval in which the differential eq
    h : float
        step size for each iteration

    Returns
    -------
    ts : 1d array
        array of t's
    ys : 1d array
        array of corresponding y's

    """
    a, b = interval
    ts = _np.arange(a, b + h, h)
    ys = _np.zeros_like(ts)

    if initial[0] != interval[0]:
        print("The point for initial value doesn't match the start of interval")
        return None, None

    ys[0] = initial[1]

    for i in range(len(ts) - 1):
        p_i = f(ys[i], ts[i])
        q_i = f(ys[i] + 0.5 * h * p_i, ts[i] + h * 0.5)
        r_i = f(ys[i] - p_i * h + 2 * q_i * h, ts[i] + h)
        ys[i + 1] = ys[i] + (p_i + 4 * q_i + r_i) * h / 6

    return ts, ys

def rk4(f, initial, interval, h):
    """This function solves the differential equation using 4th order Runga-Kutta
    method and initial value condition.

    Parameters
    ----------
    f : function
        function form of the differential equation to be solved
    initial : tuple
        tuple of the initial values
    interval : tuple
        tuple of the interval in which the differential eq
    h : float
        step size for each iteration

    Returns
    -------
    ts : 1d array
        array of t's
    ys : 1d array
        array of corresponding y's

    """
    a, b = interval
    ts = _np.arange(a, b + h, h)
    ys = _np.zeros_like(ts)

    if initial[0] != interval[0]:
        print("The point for initial value doesn't match the start of interval")
        return None, None

    ys[0] = initial[1]

    for i in range(len(ts) - 1):
        p_i = f(ys[i], ts[i])
        q_i = f(ys[i] + 0.5 * h * p_i, ts[i] + h * 0.5)
        r_i = f(ys[i] + 0.5 * h * q_i, ts[i] + h * 0.5)
        s_i = f(ys[i] + h * r_i, ts[i] + h)
        ys[i + 1] = ys[i] + (p_i + 2 * q_i + 2 * r_i + s_i) * h / 6

    return ts, ys


"""Gell-Mann matrices."""
from scipy.sparse import csr_matrix

import numpy as np

def gell_mann(ind: int, is_sparse: bool = False) -> np.ndarray:
    r"""
    Produce a Gell-Mann operator [WikGM]_.

    Generates the 3-by-3 Gell-Mann matrix indicated by the value of
    :code:`ind`.  When :code:`ind = 0` gives the identity matrix, while values
    1 through 8 each indicate one of the other 8 Gell-Mann matrices.

    The 9 Gell-Mann matrices are defined as follows:

    .. math::
        \begin{equation}
            \begin{aligned}
                \lambda_0 = \begin{pmatrix}
                                1 & 0 & 0 \\
                                0 & 1 & 0 \\
                                0 & 0 & 1
                            \end{pmatrix}, \quad
                \lambda_1 = \begin{pmatrix}
                                0 & 1 & 0 \\
                                1 & 0 & 0 \\
                                0 & 0 & 0
                            \end{pmatrix}, \quad &
                \lambda_2 = \begin{pmatrix}
                                0 & -i & 0 \\
                                i & 0 & 0 \\
                                0 & 0 & 0
                            \end{pmatrix},  \\
                \lambda_3 = \begin{pmatrix}
                                1 & 0 & 0 \\
                                0 & -1 & 0 \\
                                0 & 0 & 0
                            \end{pmatrix}, \quad
                \lambda_4 = \begin{pmatrix}
                                0 & 0 & 1 \\
                                0 & 0 & 0 \\
                                1 & 0 & 0
                            \end{pmatrix}, \quad &
                \lambda_5 = \begin{pmatrix}
                                0 & 0 & -i \\
                                0 & 0 & 0 \\
                                i & 0 & 0
                            \end{pmatrix},  \\
                \lambda_6 = \begin{pmatrix}
                                0 & 0 & 0 \\
                                0 & 0 & 1 \\
                                0 & 1 & 0
                            \end{pmatrix}, \quad
                \lambda_7 = \begin{pmatrix}
                                0 & 0 & 0 \\
                                0 & 0 & -i \\
                                0 & i & 0
                            \end{pmatrix}, \quad &
                \lambda_8 = \frac{1}{\sqrt{3}} \begin{pmatrix}
                                                    1 & 0 & 0 \\
                                                    0 & 1 & 0 \\
                                                    0 & 0 & -2
                                                \end{pmatrix}.
                \end{aligned}
            \end{equation}

    Examples
    ==========

    The Gell-Mann matrix generated from :code:`idx = 2` yields the following
    matrix:

    .. math::

        \lambda_2 = \begin{pmatrix}
                            0 & -i & 0 \\
                            i & 0 & 0 \\
                            0 & 0 & 0
                    \end{pmatrix}

    >>> from toqito.matrices import gell_mann
    >>> gell_mann(2)
    [[ 0.+0.j, -0.-1.j,  0.+0.j],
     [ 0.+1.j,  0.+0.j,  0.+0.j],
     [ 0.+0.j,  0.+0.j,  0.+0.j]]

    References
    ==========
    .. [WikGM] Wikipedia: Gell-Mann matrices,
        https://en.wikipedia.org/wiki/Gell-Mann_matrices

    :param ind: An integer between 0 and 8 (inclusive).
    :param is_sparse: Boolean to determine whether matrix is sparse.
    """
    if ind == 0:
        gm_op = np.identity(3)
    elif ind == 1:
        gm_op = np.array([[0, 1, 0], [1, 0, 0], [0, 0, 0]])
    elif ind == 2:
        gm_op = np.array([[0, -1j, 0], [1j, 0, 0], [0, 0, 0]])
    elif ind == 3:
        gm_op = np.array([[1, 0, 0], [0, -1, 0], [0, 0, 0]])
    elif ind == 4:
        gm_op = np.array([[0, 0, 1], [0, 0, 0], [1, 0, 0]])
    elif ind == 5:
        gm_op = np.array([[0, 0, -1j], [0, 0, 0], [1j, 0, 0]])
    elif ind == 6:
        gm_op = np.array([[0, 0, 0], [0, 0, 1], [0, 1, 0]])
    elif ind == 7:
        gm_op = np.array([[0, 0, 0], [0, 0, -1j], [0, 1j, 0]])
    elif ind == 8:
        gm_op = np.array([[1, 0, 0], [0, 1, 0], [0, 0, -2]]) / np.sqrt(3)
    else:
        raise ValueError("Gell-Mann index values can only be values from 0 to " "8 (inclusive).")

    if is_sparse:
        gm_op = csr_matrix(gm_op)

    return gm_op


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

def composite_midpoint(f, m, a=0.0, b=1.0):
    h = (b - a) / m
    return h * sum([f((a+h/2.0) + i*h) for i in xrange(0, m)])

def composite_trapezium(f, m, a=0.0, b=1.0):
    h = (b - a) / m
    return h/2.0 * (f(a) + f(b) + 2 * sum([ f(a + i * h) for i in xrange(1, m)]))

def composite_simpson(f, m, a=0.0, b=1.0):
    sum = float(f(a) + f(b))
    h   = (b-a) / (2*m)
    oddSum, evenSum = 0.0, 0.0

    for i in range(1, m): #evaluating all odd values of n (not first and last)
        oddSum += f(2 * h * i + a)
    sum += oddSum * 2
    for i in range(1,m+1): #evaluating all even values of n (not first and last)
        evenSum += f(h * (-1 + 2 * i) + a)
    sum += evenSum * 4
    return sum * h / 3

def debug(abs_err_cm, abs_err_ct, abs_err_cs, debug=True):
    if debug == True:
        print("DEBUG MODE STATUS = <ON>")
        print("Composite Midpoint\tComposite trapezium\tComposite_Simpson")
        for m, t, s in zip(abs_err_cm, abs_err_ct, abs_err_cs):
                print "{:.20f}     ".format(m), \
                      "{:.20f}     ".format(t), \
                      "{:.20f}     ".format(s)

def plot_abs_errs(abs_err_cm, abs_err_ct, abs_err_cs):
    plt.title("|xc-x| of: The Composite Midpoint, Simpson & \
              Trapezium Methods against h")
    plt.ylabel("Composite Midpoint vs Composite Simpson vs Composite Trapezium")
    plt.xlabel("Number of Points")
    plt.xscale('log')
    plt.yscale('log')
    plt.plot(M, abs_err_cm, 'k-', label="Composite Midpoint")
    plt.plot(M, abs_err_ct, 'r-', label="Composite Trapezium")
    plt.plot(M, abs_err_cs, 'b-', label="Composite Simpson")
    plt.legend(bbox_to_anchor=(.95, .9))
    plt.show()

if __name__ == "__main__":
    import matplotlib.pyplot as plt
    from math import (exp, pi, sin)
    from scipy import (integrate, special)
    from numpy import (abs, array, linspace)

    f = lambda x : exp(sin(2 * pi * x))
    I = integrate.quad(f, 0.0, 1.0)[0]
    M = linspace(3, 19, 5)

    abs_err_cm = [abs(composite_midpoint(f, int(m)) - I) for m in M]
    abs_err_ct = [abs(composite_trapezium(f, int(m)) - I) for m in M]
    abs_err_cs = [abs(composite_simpson(f, int(m)) - I) for m in M]
    debug(abs_err_cm, abs_err_ct, abs_err_cs, debug=True)
    plot_abs_errs(abs_err_cm, abs_err_ct, abs_err_cs)
else:
    from sys import exit
    exit("USAGE: python question2.py")


import numpy as np
import matplotlib.pyplot as plt

# 평균 제곱 오차 mean squared error
def mean_squared_error(y,t):
    return 0.5 * np.sum((y-t)**2)

y = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]
t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]

# print(mean_squared_error(np.array(y), np.array(t)))

y = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]
# print(mean_squared_error(np.array(y), np.array(t)))

# 교차 엔트로피 오차 cross entropy error
x = np.arange(0.001, 1.0, 0.001)
y = np.log(x)

# plt.plot(x, y)
# plt.ylim(-5.0, 0.0) # y축의 범위 지정
# plt.show()

def cross_entropy_error(y,t):
    delta = 1e-7
    return -np.sum(t * np.log(y + delta)) # 아주 작은 값 delta를 더하는 이유 : np.log에 함수 0을 입력하면 -inf(무한)가 되어 계산 x

t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
y = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]

# print(cross_entropy_error(np.array(y), np.array(t)))

y = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]
# print(cross_entropy_error(np.array(y), np.array(t)))

# 미니 배치 학습

import sys, os
sys.path.append(os.pardir)
from dataset.mnist import load_mnist

(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)

print(x_train.shape)
print(t_train.shape)

train_size = x_train.shape[0]
batch_size = 10
batch_mask = np.random.choice(train_size, batch_size)
# 훈련 데이터에서 무작위로 10장만 꺼내기? np.random.choice() 사용
# np.random.choice(60000,10)은 0에서 60000 미만의 수 중 무작위로 10개를 골라냄
x_batch = x_train[batch_mask]
t_batch = t_train[batch_mask]

# (배치용) 교차 엔트로피 오차 구현하기
def cross_entropy_error(y, t):
    if y.ndim == 1:
        t = t.reshape(1, t.size)
        y = y.reshape(1, y.size)

    batch_size = y.shape[0]
    return -np.sum(t * np.log(y)) / batch_size


###
# Introduction to Data Science Homework Assignment # 1
# Student: Alan Fernandez, aefernandez@wpi.edu
# Date: 08/29/18
# Course: DS501, Introduction to Data Science (Grad Level)
# Worcester Polytechnic Institute (WPI), Worcester, MA
###

import numpy as np

from problem3 import random_walk
from problem4 import compute_S

#-------------------------------------------------------------------------
'''
    Problem 5: Solving sink-region problem in PageRank
    In this problem, we implement the pagerank algorithm which can solve both the sink node problem and sink region problem.
    We will consider a random surfer model where a user has 2 options at every timestep: (option 1) randomly follow a link on the page or (option 2) randomly go to any page in the graph.
    The probabilities are as follows:
        Randomly follow a link: alpha, for example, 0.95
        Randomly go to any page in the graph: (1 - alpha), for example, 0.05
    You could test the correctness of your code by typing `nosetests test5.py` in the terminal.
'''

#--------------------------
def compute_G(A, alpha = 0.95):
    '''
        compute the pagerank transition Matrix G from addjacency matrix A, which solves both the sink node problem and the sing region problem.
        G[j][i] represents the probability of moving from node i to node j.
        If node i is a sink node, S[j][i] = 1/n.
        Input:
                A: adjacency matrix, a (n by n) numpy matrix of binary values. If there is a link from node i to node j, A[j][i] =1. Otherwise A[j][i]=0 if there is no link.
                alpha: a float scalar value, which is the probability of choosing option 1 (randomly follow a link on the page)
        Output:
                G: the transition matrix, a (n by n) numpy matrix of float values.  G[j][i] represents the probability of moving from node i to node j.
    The values in each column of matrix G should sum to 1.
    '''
    #########################################
    ## INSERT YOUR CODE HERE
    # Generate the new matrix with equal probabilities for every node
    n = A.shape[0]

    equal_probability_matrix = np.zeros(list(A.shape))
    equal_probability_matrix.fill(1/n)

    # Compute the transitional matrix with the sink node problem solved
    S = compute_S(A)

    # Combine the two matrices to form the final transitional matrix
    G = equal_probability_matrix * (1-alpha) + S * alpha

    #########################################
    return G

#--------------------------
def pagerank(A, alpha = 0.95):
    '''
        The final PageRank algorithm, which solves both the sink node problem and sink region problem.
        Given an adjacency matrix A, compute the pagerank score of all the nodes in the network.
        Input:
                A: adjacency matrix, a numpy matrix of binary values. If there is a link from node i to node j, A[j][i] =1. Otherwise A[j][i]=0 if there is no link.
                alpha: a float scalar value, which is the probability of choosing option 1 (randomly follow a link on the page)
        Output:
                x: the ranking scores, a numpy vector of float values, such as np.array([[.3], [.5], [.7]])
    '''

    # Initialize the score vector with all one values
    num_nodes, _ = A.shape # get the number of nodes (n)
    x_0 =  np.ones((num_nodes,1)) # create an all-one vector of shape (n by 1)

    # compute the transition matrix from adjacency matrix
    G = compute_G(A, alpha)

    # random walk
    x, n_steps = random_walk(G,x_0)
    return x


import numpy
from matplotlib import pyplot

def euler_pc(f, x_end, y0, N):
    x, dx = numpy.linspace(0, x_end, N+1, retstep=True)
    y = numpy.zeros((len(y0),N+1))
    y[:,0] = y0
    for n in range(N):
        fn = f(x[n], y[:,n])
        yp = y[:,n] + dx * fn
        y[:,n+1] = y[:,n] + dx / 2 * (fn + f(x[n+1], yp))
    return x, dx, y

def ab2(f, x_end, y0, N):
    x, dx = numpy.linspace(0, x_end, N+1, retstep=True)
    y = numpy.zeros((len(y0),N+1))
    fn = numpy.zeros((len(y0),N+1))
    y[:,0] = y0
    fn[:,0] = f(x[0], y[:,0])
    x_epc, dx_epc, y_epc = euler_pc(f, dx, y0, 1)
    y[:,1] = y_epc[:,1]
    for n in range(1,N):
        fn[:,n] = f(x[n], y[:,n])
        y[:,n+1] = y[:,n] + dx * (3 * fn[:,n] - fn[:,n-1]) / 2
    return x, dx, y

def milne(f, x_end, y0, N):
    x, dx = numpy.linspace(0, x_end, N+1, retstep=True)
    y = numpy.zeros((len(y0),N+1))
    fn = numpy.zeros((len(y0),N+1))
    y[:,0] = y0
    fn[:,0] = f(x[0], y[:,0])
    x_epc, dx_epc, y_epc = euler_pc(f, dx, y0, 1)
    y[:,1] = y_epc[:,1]
    for n in range(1,N):
        fn[:,n] = f(x[n], y[:,n])
        yp = y[:,n] + dx * (3 * fn[:,n] - fn[:,n-1]) / 2 #AB2 predictor
        fp = f(x[n+1], yp)
        y[:,n+1] = y[:,n-1] + dx * (fp + 4 * fn[:,n] + fn[:,n-1]) / 3
    return x, dx, y

if __name__=="__main__":

    def f_exp(x, y):
        return -y

    x, dx, y_ab2 = ab2(f_exp, 30, [1], 3000)
    pyplot.figure(figsize=(12,6))
    pyplot.plot(x, y_ab2[0,:])
    pyplot.ylim(-1.1,1.1)
    pyplot.xlabel(r"$x$")
    pyplot.ylabel("Adams-Bashforth 2")
    pyplot.show()

    x, dx, y_milne = milne(f_exp, 30, [1], 3000)
    pyplot.figure(figsize=(12,6))
    pyplot.plot(x, y_milne[0,:])
    pyplot.ylim(-1.1,1.1)
    pyplot.xlabel(r"$x$")
    pyplot.ylabel("Milne")
    pyplot.show()


import matplotlib
matplotlib.rcParams = matplotlib.rc_params_from_file('../../../matplotlibrc')

import numpy as np
import numpy.linalg as la
from matplotlib import pyplot as plt

def mc_circle():
    np.random.seed(42)
    points = np.random.rand(2, 500).T
    points = 4*(points-.5)
    pointsNorm = np.hypot(points[:,0],points[:,1]) <= 1
    InCircle = points[pointsNorm]
    OutCircle = points[~pointsNorm]
    plt.plot(InCircle[:,0], InCircle[:,1], 'r.')
    plt.plot(OutCircle[:,0], OutCircle[:,1], 'b.')

    # Plot the circle
    theta = np.linspace(0, 2*np.pi, 50)
    plt.plot(np.cos(theta),np.sin(theta),'k')

    plt.axes().set_aspect('equal')
    plt.axis([-2, 2, -2, 2])

    plt.savefig("figures/MC_Circle.pdf")
    plt.clf()

def prob1(N=10000):
    """Return an estimate of the volume of the unit sphere using Monte
    Carlo Integration.

    Input:
        N (int, optional) - The number of points to sample. Defaults
            to 10000.

    """
    points = np.random.rand(3, N)
    points = points*2 - 1
    radiusMask = la.norm(points,axis=0)
    radiusMask[radiusMask>1] = 0
    numInSphere = np.count_nonzero(radiusMask)
    return 8.*numInSphere/N

def mc_error_plot(numIters=50):
    actual = 4.1887902047863905

    N = [i*1000 for i in xrange(1,51)]
    N = [50,100,500] + N
    errors = []

    for n in N:
        meanErr = 0.
        for i in xrange(numIters):
            I = prob1(n)
            err = np.abs(I - actual)/actual
            meanErr += err
        errors.append(meanErr/float(numIters))

    plt.plot(N,errors,label='Error')
    plt.plot(N,[1./n**0.5 for n in N],'r--',label=r'$1/\sqrt{N}$')
    plt.ylim([0,max(errors)])
    plt.xlim([0,max(N)])
    plt.xlabel(r'$N$')
    plt.ylabel('Relative error')
    plt.legend()

    plt.savefig("figures/MC_error_2.pdf")
    plt.clf()

if __name__ == "__main__":
    #mc_circle()
    mc_error_plot()


import numpy as np
from sympy import *
import matplotlib.pyplot as plt
import time

def actual_result(func, val):
	x = Symbol('x')
	dfunc = diff(func, 'x')
	x = val
	return eval(str(dfunc))

def two_point(func, x, h):
	funcx = eval(str(func))
	x = x+h
	funcxh = eval(str(func))
	return (funcxh - funcx)/h

def three_point(func, x, h):
	x = x+h
	funcxh = eval(str(func))
	x = x-2*h
	funcxmh = eval(str(func))
	return (funcxh - funcxmh)/(2*h)

def plot(Result2Point,Result3Point,Error2Point,Error3Point):
	plt.plot(Result2Point, 'k--',label= "2 Point")
	plt.plot(Result3Point,'k:',label= "3 Point")
	plt.plot(Error2Point,'k',label= "2 Point Error")
	plt.plot(Error3Point,'k',label= "3 Point Error")

	legend = plt.legend(loc='upper center', shadow=True)
	frame = legend.get_frame()
	frame.set_facecolor('0.90')

	plt.show()

def differenceMethods(x,y,z):
	return 0

def main():
	x = Symbol('x')
	Result2Point= []
	Result3Point= []
	Error2Point = []
	Error3Point = []

	## User input
	func = sin(x)
	xval = 0.0
	h=[0.1,0.01,0.001]

	start = time.time()
	actualResult = actual_result(func, xval)
	for item in h:
		Result2Point.append(two_point(func, xval, item))
		Result3Point.append(three_point(func, xval, item))

	Error2Point = np.asarray(Result2Point) - actualResult
	Error3Point = np.asarray(Result3Point) - actualResult

	end = time.time()
	timeElapsed = end-start
	print ("Elapsed time: %f" % timeElapsed)

	plot(Result2Point, Result3Point, Error2Point, Error3Point)

	#print actual_result(func, xval)

if __name__ =='__main__':
	main()


# pylint: disable=invalid-name

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

# CUSTOMIZABLE: Collect/Prepare data
datapoint_size = 1000
batch_size = 1000
steps = 10000
actual_W1 = 2
actual_W2 = 5
actual_b = 7
learn_rate = 0.001
log_file = "logs/feature_2"

# Model linear regression y = Wx + b
x = tf.placeholder(tf.float32, [None, 2], name="x")
W = tf.Variable(tf.zeros([2, 1]), name="W")
b = tf.Variable(tf.zeros([1]), name="b")
with tf.name_scope("Wx_b") as scope:
    product = tf.matmul(x, W)
    y = product + b

# Add summary ops to collect data
W_hist = tf.summary.histogram("weights", W)
b_hist = tf.summary.histogram("biases", b)
y_hist = tf.summary.histogram("y", y)

y_ = tf.placeholder(tf.float32, [None, 1])

# Cost function sum((y_-y)**2)
with tf.name_scope("cost") as scope:
    cost = tf.reduce_mean(tf.square(y_ - y))
    cost_sum = tf.summary.scalar("cost", cost)

# Training using Gradient Descent to minimize cost
with tf.name_scope("train") as scope:
    train_step = tf.train.GradientDescentOptimizer(learn_rate).minimize(cost)

all_xs = []
all_ys = []
for i in range(datapoint_size):
    # Create fake data for y = 2.x_1 + 5.x_2 + 7
    x_1 = i % 10
    x_2 = np.random.randint(datapoint_size / 2) % 10
    y = actual_W1 * x_1 + actual_W2 * x_2 + actual_b
    # Create fake data for y = W.x + b where W = [2, 5], b = 7
    all_xs.append([x_1, x_2])
    all_ys.append(y)

all_xs = np.array(all_xs)
all_ys = np.transpose([all_ys])

sess = tf.Session()

# Merge all the summaries and write them out to logs
merged = tf.summary.merge_all()
writer = tf.summary.FileWriter(log_file, sess.graph)

init = tf.init = tf.global_variables_initializer()
sess.run(init)

for i in range(steps):
    if datapoint_size == batch_size:
        batch_start_idx = 0
    elif datapoint_size < batch_size:
        raise ValueError("datapoint_size: %d, must be greater than batch_size: %d" % (
            datapoint_size, batch_size))
    else:
        batch_start_idx = (i * batch_size) % (datapoint_size - batch_size)

    batch_end_idx = batch_start_idx + batch_size
    batch_xs = all_xs[batch_start_idx:batch_end_idx]
    batch_ys = all_ys[batch_start_idx:batch_end_idx]
    xs = np.array(batch_xs)
    ys = np.array(batch_ys)
    all_feed = {x: all_xs, y_: all_ys}

    # Record summary data, and the accuracy every 10 steps
    if i % 10 == 0:
        result = sess.run(merged, feed_dict=all_feed)
        writer.add_summary(result, i)
    else:
        feed = {x: xs, y_: ys}
        sess.run(train_step, feed_dict=feed)
    print("After %d iteration:" % i)
    print("W: %s" % sess.run(W))
    print("b: %f" % sess.run(b))
    print("cost: %f" % sess.run(cost, feed_dict=all_feed))

# close the writer when you're done using it
writer.flush()
writer.close()

# Step 9: output the values of w and b
w_value, b_value = sess.run([W, b])

# NOTE: W should be close to actual_W1, actual_W2, and b should be close
# to actual_b
# NOTE: Run tensorboard --logdir=path/to/log-directory to visualize


from numpy import quantile, corrcoef
from numpy.random import seed, normal

# Correlation arising from selection (see start of Chapter 6).
seed(5)
N = 200  # The number of grant proposals.
P = 0.1  # The proportion of proposals that get accepted.
news = normal(size=N)
trust = normal(size=N)
# Simulate the selection process by finding the top 10% of combined scores.
score = news + trust
accepted_score = quantile(score, 1 - P)
selected = score >= accepted_score
# Find that the correlation coefficient of truly uncorrelated values now ...
correlation_coef = corrcoef(news[selected], trust[selected])
rounded_correlation_coef = round(correlation_coef[0][1], 2)
print(f"The apparent correlation is {rounded_correlation_coef}.")


# plots.py
import matplotlib
matplotlib.rcParams = matplotlib.rc_params_from_file('../../matplotlibrc')

from matplotlib import pyplot as plt
import numpy as np
from scipy import linalg as la
from scipy import optimize as opt

def newtonsMethod1d(f, df, ddf, x, niter=10):   # Keep!
    '''
    Perform Newton's method to minimize a function from R to R.
    Inputs:
        f -- objective function (twice differentiable)
        df -- first derivative
        ddf -- second derivative
        x -- initial guess
        niter -- integer, giving the number of iterations
    Returns:
        the approximated minimizer
    '''
    for i in xrange(niter):
        x = x-df(x)/ddf(x)
    return x, f(x)

def myFunc(x):   # Keep!
    return 4*x**2 - 13*x + 40 + 6*np.sin(4*x)
def myDFunc(x):   # Keep!
    return 8*x - 13+24*np.cos(4*x)
def myDDFunc(x):   # Keep!
    return 8-96*np.sin(4*x)

def newton():  # Keep!
    x1,f1 = newtonsMethod1d(myFunc, myDFunc, myDDFunc, 1, niter=200)
    x2,f2 = newtonsMethod1d(myFunc, myDFunc, myDDFunc, 4, niter=200)
    dom = np.linspace(-10,10,100)
    plt.plot(dom, myFunc(dom))
    plt.plot(x1, f1, '*')
    plt.plot(x2, f2, '*')
    plt.annotate('Global Minimum', xy=(x1, f1), xytext=(-4, 200),
                arrowprops=dict(facecolor='black', shrink=0.1),)
    plt.annotate('Local Minimum', xy=(x2,f2), xytext=(2, 175),
                    arrowprops=dict(facecolor='black', shrink=0.1),)
    plt.savefig('newton.pdf')
    plt.clf()

newton()


import numpy as np

# This file contains the suggested examples from Section 9.3.2
# they all assume the input x is of the correct dimension, and a column vector

def obj_quadratic_r2(x, gamma=2):
    """ This is the objective function:
    f(x) = 1/2 * (x_1^2 + gamma*x_2^2)

    Args:
        x: input, a 2x1 numpy array
        gamma: defaults to 2, can be used to control the condition number of
            the sublevel sets of the function.
            condition number = max(gamma, 1/gamma)
    """
    _A = np.array(
        [[1, 0],
         [0, gamma]], dtype=float
    )
    return 0.5 * x.T @ _A @ x

def obj_quadratic_r2_jac(x, gamma=2):
    """ This is the objective function:
    f(x) = 1/2 * (x_1^2 + gamma*x_2^2)

    Args:
        x: input, a 2x1 numpy array
        gamma: defaults to 2, can be used to control the condition number of
            the sublevel sets of the function.
            condition number = max(gamma, 1/gamma)
    """
    _A = np.array(
        [[1, 0],
         [0, gamma]], dtype=float
    )
    return _A @ x

def obj_nonquadratic_r2(x):
    """ This is the objective function:
    f(x) = exp(x_1 + 3x_2 - 0.1) + exp(x_1 - 3x_2 - 0.1) + exp(-x_1 - 0.1)

    Args:
        x: input, a 2x1 numpy array. Recommend keeping inputs reasonably small.
    """
    x1, x2 = x.flatten()
    return np.exp(x1+3*x2-0.1) + np.exp(x1-3*x2-0.1) + np.exp(-x1-0.1)


import numpy as np

class Distance:

    @staticmethod
    def euclidian_distance(item_1, item_2):
        return np.sqrt(np.sum((item_1 - item_2) ** 2))

    @staticmethod
    def hamming_distance(item_1, item_2):
        return np.sum(np.abs(item_1 - item_2))/len(item_1)

    @staticmethod
    def manhattan_distance(item_1, item_2):
        return np.sum(np.abs(item_1 - item_2))

    @staticmethod
    def minkowski_distance(item_1, item_2, p):
        return np.sum((item_1 - item_2) ** p)**(1/p)


from scipy.integrate import simps
from scipy.integrate import trapz
from scipy.integrate import romb
import numpy as np

def f(x):
    """
    """
    return 1

def g(x):
    """
    Function taken from https://www.math.duke.edu/vigre/pruv/studentwork/atwood.nearsing.pdf
    """

    a = 10e-3

    return f(x)* np.log(x**2 + a**2)

def simpson(f, a, b, n):
    """
    Simpson composite rule
    """
    h=(b-a)/n
    k=0.0
    x=a + h
    for i in range(1,n/2 + 1):
        k += 4.*f(x)
        x += 2.*h

    x = a + 2.*h
    for i in range(1,n/2):
        k += 2.*f(x)
        x += 2.*h
    return (h/3.)*(f(a)+f(b)+k)

# Computing integral using less interval
# Correct answer is -3.99372

I = -3.99372

i1 = simpson(g, -1., 1., 2**5+ 1)

i2 = simpson(g, -1., 1., 2**10+1)

print 'Reference answer is ' + str(I)
print 'Previous code answer is ' + str(i1)

print 'Current code answer is ' + str(i2)

print 'Previous code absolute error is ' + str(np.abs(I-i1))

print 'Current code absolute error is ' + str(np.abs(I-i2))


#%%
'''
reproduction of https://ipython-books.github.io/134-simulating-a-stochastic-differential-equation/

Stochastic differential equations (SDEs) model dynamical systems that are subject to noise.
In this recipe, we simulate an Ornstein-Uhlenbeck process, which is a solution of the Langevin equation.
The Ornstein-Uhlenbeck process is stationary, Gaussian, and Markov, which makes it a good candidate to represent stationary random noise.
We will simulate this process with a numerical method called the Euler-Maruyama method.
'''
#%%
import numpy as np
import matplotlib.pyplot as plt
#%%
b = 0.5
sigma = 1.
#%%
dt = .001  # Time step.
T = 1.  # Total time.
n = int(T / dt)  # Number of time steps.
t = np.linspace(0., T, n)  # Vector of times.
#%%
x = np.zeros(n)
#%%
'''
discretized stochastic differential equation and process
x_{t+1} = x_t + (-b * x_t) * dt + sigma * (dt)^1/2 * N(0, 1)

where
b = 1/2, sigma = 1
x_{t+1} = x_t + (-1/2 * x_t) * dt + 1 * (dt)^1/2 * N(0, 1)
and (-1/2 * x_t) = score function of N(0, 1)
and distribution of x_T converges to N(0, \sigma^2 / 2b) = N(0, 1)
'''
for i in range(n - 1):
    x[i + 1] = x[i] + (-b * x[i]) * dt + sigma * np.sqrt(dt) * np.random.randn()
#%%
fig, ax = plt.subplots(1, 1, figsize=(8, 4))
ax.plot(t, x, lw=2)
ax.set_title('simulation of langevin equation')
#%%
ntrials = 10000
X = np.zeros(ntrials)
# We create bins for the histograms.
bins = np.linspace(-3., 3., 100)
fig, ax = plt.subplots(1, 1, figsize=(8, 4))
for i in range(n):
    # We update the process independently for all trials
    X += (-b * X) * dt + sigma * np.sqrt(dt) * np.random.randn(ntrials)
    # We display the histogram for a few points in time (10000 points of process)
    if i in (5, 50, 900):
        hist, _ = np.histogram(X, bins=bins, density=True)
        ax.plot((bins[1:] + bins[:-1]) / 2, hist,
                {5: '-', 50: '-.', 900: '--', }[i],
                label=f"t={i * dt:.2f}")
hist, _ = np.histogram(np.random.randn(X.shape[0]), bins=bins, density=True)
ax.plot((bins[1:] + bins[:-1]) / 2, hist, ':', label='N(0,1)')
ax.legend()
#%%
# '''
# numerical solution
# '''
# np.random.seed(520)
# ntrials = 10000
# # true
# X = np.zeros(ntrials)
# fig, ax = plt.subplots(1, 1, figsize=(8, 4))
# for i in range(n):
#     X += (-b * X) * dt + sigma * np.sqrt(dt) * np.random.randn(ntrials)
# hist, _ = np.histogram(np.random.randn(X.shape[0]), density=True)
# ax.plot(hist, '-.', label='N(0,1)')

# # solution
# X0 = np.random.normal(0, 1, (ntrials, ))
# X = np.exp(-b * T) * X0 + np.sum(sigma * np.exp(-b * (T - dt)) * np.random.normal(0, dt, (ntrials, ntrials)), axis=1)
# hist, _ = np.histogram(X, density=True)
# ax.plot(hist, '-', label='solution')
# ax.legend()
#%%
'''
The error of the Euler-Maruyama method is of order sqrt(dt). The Milstein method is a more precise numerical scheme, of order dt.
'''
#%%


# -*- coding: utf-8 -*-
"""
Spyder Editor

This is a temporary script file.
"""
# for math
import numpy as np
# for physical cosntants
import scipy.constants as const
# for plots
import matplotlib.pyplot as plt

# charge settings
N_1 = -1
N_2 = 1
N_3 = -1
N_4 = 1

# coulomb constant
k_C = 1 / (4 * np.pi * const.epsilon_0)

# charges
q_1 = N_1 * const.e
q_2 = N_2 * const.e
q_3 = N_3 * const.e
q_4 = N_4 * const.e

# position of the charged points
q_1_x = 0.5
q_1_y = 0.5
q_2_x = 0.5
q_2_y = - 0.5
q_3_x = -0.5
q_3_y = -0.5
q_4_x = -0.5
q_4_y = 0.5

print('charges')
print('q_1 = ', q_1, 'x = ', q_1_x, 'y = ', q_1_y)
print('q_2 = ', q_2, 'x = ', q_2_x, 'y = ', q_2_y)
print('q_3 = ', q_3, 'x = ', q_3_x, 'y = ', q_3_y)
print('q_4 = ', q_4, 'x = ', q_4_x, 'y = ', q_4_y)

# Meshgrid
size = 1
s = (size / 2)
n_s = 100
x, y = np.meshgrid(np.linspace(-s, s, n_s),
                   np.linspace(-s, s, n_s))

# radius
r_1 = np.sqrt((q_1_x - x)**2 + (q_1_y - y)**2)
r_2 = np.sqrt((q_2_x - x)**2 + (q_2_y - y)**2)
r_3 = np.sqrt((q_3_x - x)**2 + (q_3_y - y)**2)
r_4 = np.sqrt((q_4_x - x)**2 + (q_4_y - y)**2)

# helper varables
k_1 = q_1 / (r_1*r_1*r_1)
k_2 = q_2 / (r_2*r_2*r_2)
k_3 = q_3 / (r_3*r_3*r_3)
k_4 = q_4 / (r_4*r_4*r_4)

# https://www.geeksforgeeks.org/how-to-plot-a-simple-vector-field-in-matplotlib/

# Directional vectors
E_x = k_C * (k_1 * (q_1_x - x) + k_2 * (q_2_x - x) + k_3 * (q_3_x - x) + k_4 * (q_4_x - x));
E_y = k_C * (k_1 * (q_1_y - y) + k_2 * (q_2_y - y) + k_3 * (q_3_y - y) + k_4 * (q_4_y - y));

# Plotting Vector Field with QUIVER
plt.quiver(x, y, E_x, E_y, color='g')
plt.title('Vector Field')

# Setting x, y boundary limits
boundary = 1
plt.xlim(-boundary, boundary)
plt.ylim(-boundary, boundary)

# Show plot with gird
plt.grid()
plt.show()

# Depict illustration
plt.figure(figsize=(10, 10))
plt.streamplot(x,y,E_x,E_y, density=1.4, linewidth=None, color='#A23BEC')
plt.plot(q_1_x,q_1_y,'-or')
plt.plot(q_2_x,q_2_y,'-og')
plt.plot(q_3_x,q_3_y,'-ob')
plt.plot(q_4_x,q_4_y,'-oc')
plt.title('Electromagnetic Field')

boundary = 0.6
plt.xlim(-boundary, boundary)
plt.ylim(-boundary, boundary)

# Show plot with gird
plt.grid()
plt.show()


from math import factorial

import matplotlib.pylab as plt
from numpy import ones, copy, cos, tan
from numpy import sqrt, pi, exp, linspace, zeros

def gaussxw(N):
    # Initial approximation to roots of the Legendre polynomial
    a = linspace(3, 4 * N - 1, N) / (4 * N + 2)
    x = cos(pi * a + 1 / (8 * N * N * tan(a)))

    # Find roots using Newton's method
    epsilon = 1e-15
    delta = 1.0
    while delta > epsilon:
        p0 = ones(N, float)
        p1 = copy(x)
        for k in range(1, N):
            p0, p1 = p1, ((2 * k + 1) * x * p1 - k * p0) / (k + 1)
        dp = (N + 1) * (p0 - x * p1) / (1 - x * x)
        dx = p1 / dp
        x -= dx
        delta = max(abs(dx))

    # Calculate the weights
    w = 2 * (N + 1) * (N + 1) / (N * N * (1 - x * x) * dp * dp)

    return x, w

def gaussxwab(N, a, b):
    x, w = gaussxw(N)
    return 0.5 * (b - a) * x + 0.5 * (b + a), 0.5 * (b - a) * w

def H(n, x):
    def H_iter(a, b, count):
        if count == 0:
            return b
        else:
            return H_iter(2 * x * a - 2 * (count - 1) * b, a, count - 1)

    return H_iter(2 * x, 1, n)

def wave_func(n, x):
    return (1 / (sqrt((2 ** n) * factorial(n) * sqrt(pi)))) * exp(-0.5 * (x ** 2)) * H(n, x)

N = 200
d = linspace(-4, 4, N)
y = zeros([N, 4], float)
for j in range(0, 4, 1):
    for i in range(0, N, 1):
        y[i, j] = wave_func(j, d[i])
y2 = []
d2 = linspace(-10, 10, 500)
for m in range(0, 500, 1):
    y2.append(wave_func(30, d2[m]))
f1 = plt.figure(1)
plt.plot(d2, y2, 'b-', label=r"$\psi_{30}$", linewidth=1)
plt.xlabel("x")
plt.ylabel(r"$\psi(x)$")
f2 = plt.figure(2)
plt.plot(d, y[:, 0], label=r"$\psi_0$")
plt.plot(d, y[:, 1], label=r"$\psi_1$")
plt.plot(d, y[:, 2], label=r"$\psi_2$")
plt.plot(d, y[:, 3], label=r"$\psi_3$")
plt.xlabel("x")
plt.ylabel(r"$\psi(x)$")
plt.show()

Ankit Khandelwal_HW2/exercise 5/exercise 5a.py


# Copyright 2017 Battelle Energy Alliance, LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# from https://en.wikipedia.org/wiki/Test_functions_for_optimization
#
# takes any number of input parameters x[i]
# returns value in "ans"
# optimal minimum at f(1,1,...,1,1) = 0, only minimum for up to 3 inputs
# note for 4 to 7 inputs, a second local minima exists near (-1,1,...,1), and it gets complicated after that
# parameter range is -inf <= x[i] <= inf

import numpy as np

def evaluate2d(X,Y):
  return 100*(Y-X*X)**2 + (X-1)**2

def evaluate(*args):#xs):
  xs = np.array(args)
  return np.sum( 100.*(xs[1:] - xs[:-1]**2)**2 + (xs[:-1] - 1.)**2 )

def run(self,Inputs):
  self.ans = evaluate(Inputs.values())


import numpy as np
import matplotlib.pyplot as pyplot
import scipy.spatial.distance as sd
import sys
import os
import copy

sys.path.append(os.path.dirname(os.getcwd())+"/code_material_python")
from helper import *
from graph_construction.generate_data import *

def build_similarity_graph(X, var=1, eps=0, k=0):
  """     Computes the similarity matrix for a given dataset of samples.

   Input
   X:
       (n x m) matrix of m-dimensional samples
   k and eps:
       controls the main parameter of the graph, the number
       of neighbours k for k-nn, and the threshold eps for epsilon graphs
   var:
       the sigma value for the exponential function, already squared

   Output
   W:
       (n x n) dimensional matrix representing the adjacency matrix of the graph
   similarities:
       (n x n) dimensional matrix containing
       all the similarities between all points (optional output)
  """

  assert eps + k != 0, "Choose either epsilon graph or k-nn graph"

  if eps:
    print("Constructing eps-Graph ...")
  else:
    print("Constructing k-NN Graph ...")

  # euclidean distance squared between points
  dists = sd.squareform(sd.pdist(X))**2
  similarities = np.exp(-dists/(2*var))

  if eps:
    W = similarities * (similarities-eps>=0)
    print("eps-Graph constructed !")
    return W, similarities

  if k:
    W = similarities.copy()
    for i in range(W.shape[0]):
      W[i,i] = 0
      kNearestNodes = np.argsort(-W[i,:])
      kIdx = kNearestNodes[k:]
      W[i,kIdx] = 0
    print("k-NN Graph constructed !")
    return np.maximum(W, W.T), similarities

def plot_similarity_graph(X, Y, eps=0.1, k=0, var=1):

    W, similarities = build_similarity_graph(X, var, eps=eps, k=k)
    plot_graph_matrix(X,Y,W)

def how_to_choose_epsilon(gen_param):

    # the number of samples to generate
    num_samples = 100
    gen_param =   gen_param
    [X, Y] = worst_case_blob(num_samples,gen_param)

    var =  0.5

    dists = sd.squareform(sd.pdist(X))**2
    similarities = np.exp(-dists/(2*var))

    # Building the max spanning tree
    max_tree = max_span_tree(similarities)
    A = similarities*max_tree
    # Finding the optimal epsilon
    eps = np.min(A[np.where(max_tree>0)])
    print("Best epsilon found: ", eps)

    plot_similarity_graph(X, Y, eps=eps, var=var)
    return eps

how_to_choose_epsilon(2)
[X,Y] = blobs(200,2,0.2)
[X, Y] = worst_case_blob(100,3)
[X, Y] = two_moons(200,1,2)
plot_similarity_graph(X, Y, eps=eps, k=0, var=0.5)
plot_similarity_graph(X, Y, eps=0, k=10, var=0.5)


# Plot error surface for linear regression model.
# Based on https://github.com/probml/pmtk3/blob/master/demos/contoursSSEdemo.m

import superimport

import numpy as np
import matplotlib.pyplot as plt
import pyprobml_utils as pml

from mpl_toolkits.mplot3d import axes3d, Axes3D

np.random.seed(0)

N = 21
x = np.linspace(0.0, 20, N)
X0 = x.reshape(N,1)
X = np.c_[np.ones((N,1)), X0]
w = np.array([-1.5, 1/9.])
y =  w[0]*x + w[1]*np.square(x)
y = y + np.random.normal(0, 1, N) * 2

w = np.linalg.lstsq(X, y, rcond=None)[0]
W0, W1 = np.meshgrid(np.linspace(-8,0,100), np.linspace(-0.5,1.5,100))

SS = np.array([sum((w0*X[:,0] + w1*X[:,1] - y)**2) for w0, w1 in zip(np.ravel(W0), np.ravel(W1))])
SS = SS.reshape(W0.shape)

plt.figure()
plt.contourf(W0, W1, SS)
pml.savefig('linregHeatmapSSE.pdf')
plt.colorbar()
plt.show()

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
surf = ax.plot_surface(W0, W1, SS)
pml.savefig('linregSurfSSE.pdf')
plt.show()

fig,ax = plt.subplots()
CS = plt.contour(W0, W1, SS, levels=np.linspace(0,2000,10), cmap='jet')
plt.plot(w[0], w[1],'x')
pml.savefig('linregContoursSSE.pdf')
plt.show()


import scipy as sp

w = sp.poly1d([1, 2, 3, 4])

# metoda trapezow
a = 1
b = 3

def ctN(a, b, Np):
    x = sp.linspace(a, b, Np + 1)
    y = w(x)
    dx = x[1] - x[0]

    return (sum(y[1:-1]) + (y[0] + y[-1]) / 2) * dx

def ctS(a, b, Np):
    x = sp.linspace(a, b, Np + 1)
    y = w(x)
    dx = x[1] - x[0]

    return sum((y[1:] + y[:-1]) / 2) * dx

def cS(a, b, Np):
    x = sp.linspace(a, b, Np + 1)
    y = w(x)
    dx = x[1] - x[0]
    return (y[0] + y[-1] + 2 * sum(y[2:-1:2]) + 4 * sum(y[1:-1:2])) * dx / 3

"""metoda newtona"""

def It38(a, b, Np):
    x = sp.linspace(a, b, Np + 1)
    y = w(x)
    dx = x[1] - x[0]
    return (y[0] + y[-1] + 2 * sum(y[3:-3:3]) + 3 * sum(y[1:Np:3]) + 3 * sum(y[2:-1:3])) * 3 * dx / 8

def cw(a, b):
    tmp = w.integ()
    return tmp(b) - tmp(a)

lp = [12, 24, 36, 60, 90]
wd = cw(a, b)
"""
for i in range(len(lp)):
    print("wartosc dokladna: {}".format(wd))
    c1 = ctN(a,b,lp[i])
    b1= (c1-wd)/wd
    c2 = ctN(a, b, lp[i]*2)
    b2 = (c2 - wd) / wd
    cr= 4*c2/3-c1/3
    br=(cr-wd)/wd
    print('liczby podzialu: {} i {}\nc1 = {}, b1 = {:6.2e}\nc = {}, b2 = {:6.2e}\n cr = {}, br = {:6.2e}'.format(lp[1],lp[i]*2,c1,b1,c2,b2,cr,br))
"""
for i in range(len(lp)):
    print("wartosc dokladna: {}".format(wd))
    c1 = It38(a, b, lp[i])
    b1 = (c1 - wd) / wd
    c2 = It38(a, b, lp[i] * 2)
    b2 = (c2 - wd) / wd
    cr = 10 * c2 / 15 - c1 / 15
    br = (cr - wd) / wd
    print('liczby podzialu: {} i {}\nc1 = {}, b1 = {:6.2e}\nc = {}, b2 = {:6.2e}\n cr = {}, br = {:6.2e}\n\n'.format(
        lp[1],
        lp[
            i] * 2,
        c1, b1,
        c2, b2,
        cr,
        br))


# You have an N by N board. Write a function that, given N, returns the
# number of possible arrangements of the board where N queens can be
# placed on the board without threatening each other, i.e. no two
# queens share the same row, column, or diagonal.

import numpy as np

def place_queen(board, queen_row):
    if queen_row in board:
        return False

    queen_col = len(board)
    for col, row in enumerate(board):
        if abs(row - queen_row) == abs(col - queen_col):
            return False
    return True

def queens_on_board(N, board = []):
    if N == len(board):
        return 1

    variations = 0
    for row in range(N):
        if place_queen(board, row):
            variations += queens_on_board(N, board + [row])
    return variations

# Driver code:
result = queens_on_board(4)
print(result)

result = queens_on_board(1)
print(result)

result = queens_on_board(2)
print(result)

result = queens_on_board(10)
print(result)


import scipy as sp
import scipy.linalg as la
import numpy as np
'''
U,s,Vh = la.svd(A)
S = sp.diag(s)
S = S*(S>tol)
r = sp.count_nonzero(S)
B = sp.dot(U,sp.sqrt(S))
C = sp.dot(sp.sqrt(S),Vh)
B = B[:,0:r]
C = C[0:r,:]
'''

#Problem 3
#When I feed the second example matrix into my function,
#it comes out with "almost" the correct Drazin Inverse,
#but the top two rows are 1/2 of what they should be.
#The other matricies come out right
def drazin(A,tol):
    CB = A.copy()

    Bs = []
    Cs = []
    k = 1

    while( not (sp.absolute(CB)<tol).all() and sp.absolute(la.det(CB)) < tol):
        U,s,Vh = la.svd(CB)
        S = sp.diag(s)
        S = S*(S>tol)
        r = sp.count_nonzero(S)
        B = sp.dot(U,sp.sqrt(S))
        C = sp.dot(sp.sqrt(S),Vh)
        B = B[:,0:r]
        Bs.append(B)
        C = C[0:r,:]
        Cs.append(C)
        CB = sp.dot(C,B)
        k+=1

    D = sp.eye(A.shape[0])
    for B in Bs:
        D = sp.dot(D,B)
    if( (sp.absolute(CB)<tol).all() ):
        D = sp.dot( D,CB)
    else:
        D = sp.dot( D,np.linalg.matrix_power(CB,-(k+1)))
    for C in reversed(Cs):
        D = sp.dot(D,C)
    return D


import matplotlib.pyplot as plt
from numpy import arange, ones, zeros
from numpy import sum as npsum

from scipy.optimize import least_squares
from scipy.special import gamma

from autocorrelation import autocorrelation

def FitFractionalIntegration(dx, l_, d0):
    # Fit of a fractional integration process on X
    #  INPUTS
    #  x         : [vector] (1 x t_end) data dx=diff[x]
    #  l_        : [scalar] fractional integration process is approximated considering the first l_ terms of its Taylor expansion
    #  d0        : [scalar] initial guess for the parameter d
    # OUTPUTS
    # d          : [scalar] estimate of d (where d+1 is the order of the fractional integration process)
    # epsFI      : [vector] (1 x t_end) residuals of the fractional integration process fit
    #             The operator (1+L)**{d} is computed by means of its Taylor expansion truncated at order l_(see the note below)
    # coeff      : [vector] (l_+1 x 1) first l_+1 coefficients (including coeff_0=1) are considered in the Taylor expansion
    #Note: If L is the lag operator the residuals are defined as eps = (1-L)**(1+d)X =(1-L)**d dX , where (1-L)**{d} \approx \sum_l=0**{l_} coeff_l L**l

    # options
    # if exist(OCTAVE_VERSION,builtin) == 0
    #     options = optimoptions(lsqnonlin, TolX, 10**-9, TolFun, 10**-9, MaxFunEvals, 1200, MaxIter, 400, Display, off)
    # else:
    #     options = optimset(TolX, 10**-9, TolFun, 10**-9, MaxFunEvals, 1200, MaxIter, 400, Display, off)

    lb = -0.5
    ub = 0.5
    res = least_squares(objective,d0,args=(dx,l_),bounds=(lb,ub),ftol=1e-9,xtol=1e-9)
    d, exitFlag, resNorm = res.x, res.status, None
    epsFI, coeff = FractIntegrProcess(d,dx,l_+1)

    return d, epsFI, coeff, exitFlag, resNorm

def objective(d, dx, l_):
    eps, _ = FractIntegrProcess(d,dx,l_)
    F = npsum(autocorrelation(eps,10)**2)
    return F

def FractIntegrProcess(d,x,l_):
    # estimate a fractional integration process
    #Compute the first l_ coeff and the approximated residuals of a Fractional Integration Process of order d+1

    t_ = x.shape[0]
    l = arange(1,l_)
    coeff = ones((1,l_))
    coeff[0,1:l_] = (-1)**l*gamma(1+d)/gamma(l+1)/gamma(1+d-l)

    eps = zeros((1,t_-l_+1))
    for t in range(l_,t_):
        if t==l_:
            LX = x[t-1::-1]
        else:
            LX = x[t-1:t-l_-1:-1]
        eps[0,t-l_] = coeff@LX.T
    return eps, coeff


import numpy as np

EXAMPLE=3

if EXAMPLE==1:
    '''
    The trasition matrix defines the Markov Chain. If you change to higher dimentions and want to start from
    a state diferent from 0, then you should change the dimension of variables v and state, accordingly.
    '''
    Transition=np.array([\
                [0.5,0.3,0.1,0.1],\
                [0.05,0.45,0.4,0.1],\
                [0.25,0.35,0.3,0.1],\
                [0.4,0.1,0.25,0.25]
                ])#Reminder: the sum of each row sums up to 1.

if EXAMPLE==2:
    '''
    The trasition matrix defines the Markov Chain. If you change to higher dimentions and want to start from
    a state diferent from 0, then you should change the dimension of variables v and state, accordingly.
    '''
    Transition=np.array([\
                [0.2,0.7,0.1],\
                [0,0,1],\
                [1,0,0]\
                ])#Reminder: the sum of each row sums up to 1.

'''
Generate a random Markov Chain (with N_dim #states) and see if it reaches equilibrium (the most probable scenario is that it will, since I generate random rows
with numbers that add up to 1)
'''
N_dim=5
if EXAMPLE==3:
    Transition=np.random.dirichlet(np.ones(N_dim),N_dim)

#=============================================================Begin
#Number of steps in both the Iteration and Simulation.
N_tot=5000
#Doing the following you start at state 0 automatically.
len_T=len(Transition[0])
init_s=np.zeros(len_T)
init_s[0]=1

'''
Iterative solution to w.P=w.
Iteratively find w^{(n)}=w^{(0)}.P^{(n+1)}.
'''
#v=[1,0,0,0]#play around with this (the final result should not change as long as the v.v=1)
v=init_s[:]#start at state 0 automatically

'''
Simulation.
Simulate the Markov Chain
'''
#state=[1,0,0,0]#This is the initial sate vector, which indicates the current state. e.g [1,0,0] indicates that the system is in state 0 (I start counting from 0).
state=init_s[:]#start at state 0 automatically
_visits=np.zeros(len(state))

for i in np.arange(N_tot):

    '''
    Iterative solution:
    Calculate v^{(n+1)}=P^{T}v^{(n)}
    '''
    v=np.dot(Transition.T,v)

    '''
    Simulation:
    The next state in the simulation is determined by the multinomial distribution,
    which is included in numpy ( you can find how to samlpe from the multinomial in misc/multinomial.py ).
    '''
    state= np.random.multinomial(1,np.dot(Transition.T,state))
    _visits+=state#Fortunately, all notations click together. Since states are defined in "binary", we can add them up to obtain the number of visits for each state.

print( "iterative=", v)

s=np.array(_visits)/float(N_tot)
print( 'simulation=', s)#probabilities is the fraction of visits over time.

print( r"Maximum discrepancy:" , np.max(np.abs(v-s))/np.max(np.abs(v)) , r"%" )

#=============================================================Done

#


'''
Write a short Python function that takes a positive integer n and returns
the sum of the squares of all the positive integers smaller than n.
'''

import numpy as np

def squaresum(a: int):
    arr = np.arange(a) * np.arange(a)
    arr = np.sum(arr)
    return arr

'''
Write a short Python function that takes a positive integer n and returns
the sum of the squares of all the odd positive integers smaller than n.
'''

def squaresumodds(a: int):
    arr = np.arange(a) * np.arange(a)
    i = 0
    res = []
    while i < len(arr):
        if bool(arr[i]&(1<<0)):
            res.append(1)
        else:
            res.append(0)
        i += 1
    arr = arr * np.array(res)
    arr = np.sum(arr)
    return arr

'''
The sum of the squares of the first ten natural numbers is,

The square of the sum of the first ten natural numbers is,

Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is .

Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.

'''
def sumsquaredif(a: int):
    sum_squares = squaresum(a)
    arr = np.arange(a)
    arr = np.sum(arr)*np.sum(arr)
    return (arr - sum_squares)

def main():
    a = 101
    print('a vector: ', np.arange(a))
    print('sum of squares of a: ', squaresum(a))
    print('sum of squares of odds of a: ', squaresumodds(a))
    print('difference between sum of squares: ', sumsquaredif(a))

if __name__=='__main__':
    main()


#!/usr/bin/env python3
"""
Markov Module
"""
import numpy as np

def markov_chain(P, s, t=1):
    """
    Determines the probability of a markov chain being in a particular state
    after a specified number of iterations:

    P is a square 2D numpy.ndarray of shape (n, n) representing the transition
    matrix
        P[i, j] is the probability of transitioning from state i to state j
        n is the number of states in the markov chain
    s is a numpy.ndarray of shape (1, n) representing the probability of
    starting in each state
    t is the number of iterations that the markov chain has been through

    Returns: a numpy.ndarray of shape (1, n) representing the probability of
    being in a specific state after t iterations, or None on failure
    """
    if type(P) is not np.ndarray or len(P.shape) != 2:
        return None
    if type(s) is not np.ndarray or len(s.shape) != 2:
        return None
    if P.shape[0] != P.shape[1] or s.shape[0] != 1:
        return None
    if P.shape[0] != s.shape[1]:
        return None
    if type(t) is not int or t <= 0:
        return None
    if np.sum(P, axis=1).all() != 1:
        return None
    if np.sum(s) != 1:
        return None

    st = np.linalg.matrix_power(P, t)
    sm = np.matmul(s, st)
    return sm


from math import *

import scipy.constants as sc

def simpsons_rule(f, a, b):
    c = (a + b) / 2.0
    h3 = abs(b - a) / 6.0
    return h3 * (f(a) + 4.0 * f(c) + f(b))

def recursive_asr(f, a, b, eps, whole):
    c = (a + b) / 2.0
    left = simpsons_rule(f, a, c)
    right = simpsons_rule(f, c, b)
    if abs(left + right - whole) <= 15 * eps:
        return left + right + (left + right - whole) / 15.0
    return recursive_asr(f, a, c, eps / 2.0, left) + recursive_asr(f, c, b, eps / 2.0, right)

def adaptive_simpsons_rule(f, a, b, eps):
    return recursive_asr(f, a, b, eps, simpsons_rule(f, a, b))

def f(x):
    return x ** 3 / (exp(x) - 1)

Ans = adaptive_simpsons_rule(f, 0 + 10 ** -10, 100, 10 ** -10)

stefan = Ans * sc.Boltzmann ** 4 / 4 / pi ** 2 / sc.speed_of_light ** 2 / sc.hbar ** 3
print(stefan, 'value from program')
print(sc.Stefan_Boltzmann, 'Actural value')

Ankit Khandelwal_HW2/exercise 4/exercise 4.py


"""
Mapping between Ternary and Cartesian Coordinates.

Functions for converting ternary coordinates into cartesian system used in Matplotlib and vice-versa. All the values will be scaled so that the side length of the triangle is equal to one.
"""

import numpy as np

# Define constants to avoid code repetitions
_sqrt3 = np.sqrt(3.)
_half_sqrt3 = _sqrt3 / 2.

# Ternary to Cartesian Mapping
def ternaryToCartesian(coordinates):
    """
    Maps ternary coordinates to cartesian coordinates.

    Consider an equilateral ternary plot where a = 1 is placed at (0,0) and b = 1 is placed at (1,0). Then c = 1 will be at (1/2, sqrt(3)/2).
    The 3-tuple (a,b,c) will have the cartesian coordinates (b+c/2, sqrt(3)c/2, z), where a+b+c = 1.

    Parameters
    ----------
    coordinates: list / tuple / numpy array of size three
                 The coordinates to be converted from ternary to cartesian

    Returns
    -------
    numpy array of size two
    """
    return(np.array([(coordinates[1] + coordinates[2] / 2.), (_half_sqrt3 * coordinates[2])]))

# Cartesian to Ternary Mapping
def cartesianToTernary(coordinates, sigma = 1.):
    """
    Maps cartesian coordinates to ternary coordinates.

    Mapping from cartesian to ternary coordinates requires an additional equation. If the sum of the ternary coordinates is known (say n), one can use the equations
    for ternary to cartesian mapping and a+b+c = n to get (x-y/sqrt(3), 2y/sqrt(3), n-a-b)

    Parameters
    ----------
    coordinates: list / tuple / numpy array of size two
                The coordinates to be converted from cartesian to ternary

    sigma: Real
            Sum of (a, b, c) that the ternary coordinates should sum to.

    Returns
    -------
    numpy array of size three
    """
    c = coordinates[1] / _half_sqrt3
    b = coordinates[0] - c / 2.
    a = sigma - (b + c)
    return(np.array([a,b,c]))


import numpy as np

def tilde_w(w, dt):
    return (2./dt)*np.arcsin(w*dt/2.)

def plot_frequency_approximations():
    w = 1  # relevant value in a scaled problem
    stability_limit = 2./w
    dt = np.linspace(0.2, stability_limit, 111)  # time steps
    series_approx = w + (1./24)*dt**2*w**3
    P = 2*np.pi/w  # one period
    num_timesteps_per_period = P/dt  # more instructive
    import scitools.std as plt
    plt.plot(num_timesteps_per_period, tilde_w(w, dt), 'r-',
             num_timesteps_per_period, series_approx, 'b--',
             legend=('exact discrete frequency', '2nd-order expansion'),
             xlabel='no of time steps per period',
             ylabel='numerical frequency')
    plt.savefig('discrete_freq.png')
    plt.savefig('discrete_freq.pdf')

plot_frequency_approximations()


import numpy as np
from sklearn import linear_model, datasets
import matplotlib.pyplot as plt

def onehot(y):
    n = len(np.unique(y))
    m = y.shape[0]
    b = np.zeros((m, n))
    for i in xrange(m):
        b[i, y[i]] = 1
    return b

def softmax(X):
    return (np.exp(X).T / np.sum(np.exp(X), axis=1)).T

def h_func(theta, X):
    h = np.dot(np.c_[np.ones(X.shape[0]), X], theta)
    return softmax(h)

def h_gradient(theta, X, y, lam=0.1):
    n = X.shape[0]
    y_mat = onehot(y)
    preds = h_func(theta, X)
    return -1./n * np.dot(np.c_[np.ones(n), X].T, y_mat - preds) + lam * theta

def softmax_cost_func(theta, X, y, lam=0.1):
    n = X.shape[0]
    y_mat = onehot(y)
    return -1./n * np.sum(y_mat * np.log(h_func(theta, X))) + lam/2. * np.sum(theta * theta)

# gradient descent
def softmax_grad_desc(theta, X, y, lr=.01, converge_change=.0001, max_iter=100, lam=0.1):
    # normalize
    #X = (X - np.mean(X, axis=0)) / np.std(X, axis=0)

    cost_iter = []
    cost = softmax_cost_func(theta, X, y, lam=lam)
    cost_iter.append([0, cost])
    change_cost = 1
    i = 1
    while change_cost > converge_change and i < max_iter:
        pre_cost = cost
        theta -= lr * h_gradient(theta, X, y)
        cost = softmax_cost_func(theta, X, y)
        cost_iter.append([i, cost])
        change_cost = abs(pre_cost - cost)
        i += 1
    return theta, np.array(cost_iter)

def softmax_pred_val(theta, X):
    probs = h_func(theta, X)
    preds = np.argmax(probs, axis=1)
    return probs, preds

def softmax_regression():
    # Load the diabetes dataset
    dataset = datasets.load_digits()

    # Use all the features
    X = dataset.data[:, :]
    y = dataset.target[:, None]

    # Gradiend Descent
    theta = np.random.rand(X.shape[1]+1, len(np.unique(y)))
    fitted_val, cost_iter = softmax_grad_desc(theta, X, y, lr=0.01, max_iter=1000, lam=0.1)
    probs, preds = softmax_pred_val(fitted_val, X)

    #print(fitted_val)
    print(cost_iter[-1,:])
    print('Accuracy: {}'.format(np.mean(preds[:, None] == y)))

    plt.plot(cost_iter[:, 0], cost_iter[:, 1])
    plt.ylabel("Cost")
    plt.xlabel("Iteration")
    plt.show()

def main():
    softmax_regression()

if __name__ == "__main__":
    main()


#!/usr/bin/python3
# reflection.py

import sys
import os
import numpy as np

class Reflection:
    """
    Class for calculating the reflection of a, through the orthogonal matrix of v.

    ...

    Attributes
    ----------
    v: numpy array
        vector, shape(m,1), to initialize the Housholder transformation matrix.

    Methods
    -------
    __mul__(a)
        Transforms the vector a using the Housholder transformation
        H = I - 2((vv(T)) / |v|**2).
    """

    def __init__(self, v):
        """
        Vector v shape(m,1), to initialize the Housholder transformation.
        """

        self.v = v

    def __mul__(self, a):
        """
        Transforms the vector a using the Housholder transformation H = I - 2((vv(T)) / |v|**2).

        Calculate the matrix product for the
        reflection of vector a orthogonal matrix H.
        The dimension of a needs to be bigger or equal
        to the dimesion of v.
        If the dimension of v is smaller than the dimension of a,
        v can be filled with zeros.

        Parameters
        ----------
        a: numpy array
            vector, shape(m,1) input vector to be transformed.

        Returns
        -------
        reflection: numpy array
            vector, shape(m,1), a reflected through H.
        """

        if len(a) < len(self.v):
            raise Exception('Length of a is smaller than length of v!')
        elif len(a) > len(self.v):
            differenceav = (len(a) - len(self.v))
            add = np.zeros(differenceav)
            velong = np.insert(self.v,0,add).reshape(len(a),1) # add zeros at the end
            self.v = velong
        else:
            self.v = self.v

        gamma = ((np.linalg.norm(self.v))**2)/2
        vvtrans = self.v * np.transpose(self.v)
        H =  np.identity((len(a))) - (vvtrans/gamma)
        reflection = np.dot(H,a)

        return(reflection)


"""
implementation of gradient descent
n the solution of the linear equation
https://en.wikipedia.org/wiki/Gradient_descent#Solution_of_a_linear_system
"""

import numpy as np
from tqdm import trange

def cost_function(y_true, y_pred):
    """Computes the cost of linear regression
    """
    n, _ = y_true.shape
    cost = 1 / (2 * n) * np.sum((y_true - y_pred) ** 2)
    return cost

def normalize(X):
    """Returns a normalized version of X where
    the mean value of each feature is 0
    and the standard deviation is 1
    """
    # calculate mean value along zero axis
    X_mean = np.mean(X, axis=0)
    # calculate standard deviation along zero axis
    X_std = np.std(X, axis=0)
    # Standard scaler
    # z = (x - mu) / sigma
    X_norm = (X - X_mean) / X_std
    return X_norm, X_std

def gradient_descent(X, y, theta=None, alpha=0.05, num_epoch=10, verbose=True):
    """Performs gradient descent to learn theta
    by taking n steps
    """
    n, m = X.shape
    if theta is None:
        # set theta as random weights
        theta = np.random.rand(m + 1, 1)
    # add intercept value to X
    X0 = np.concatenate([np.ones((n, 1)), X], axis=1)
    # set dict with costs values
    cost = {}
    t = trange(num_epoch)
    for epoch in t:
        # set new theta value
        # theta = theta - alpha * 1 / m * X' * (X * theta - y)
        theta = theta - alpha * 1 / n * X0.T @ (X0 @ theta - y)
        # calculate predicted value with new theta
        y_pred = X0 @ theta
        # calculate cost value
        cost[epoch] = cost_function(y, y_pred)
        if verbose:
            t.set_description(
                "epoch: {:4d} cost: {:.4f}".format(epoch, cost[epoch]))
    return theta

def inverse_transform(theta_normalize, X, X_std):
    """transform theta normilize to original feature space
    """
    n = X_std.shape[0]
    # rescale theta
    theta_rescaled = (theta_normalize.flatten()[1:] / X_std).reshape((n, 1))
    # get predictions
    y_pred = X @ theta_rescaled
    # calculate mean bias values
    theta_0 = (y - y_pred).mean()
    # concatenate
    theta = np.concatenate([[[theta_0]], theta_rescaled], axis=0)
    return theta

if __name__ in '__main__':
    # set X vector
    X = np.array([
        [-1, 0],
        [1, 100],
        [2, 200],
        [3, 300],
        [4, 400],
        [5, 500],
    ])
    # set y based on equation y = 5 + X0 * 20 + X1 * 1
    theta_true = np.array([
        [5.], [20.], [1.]
        ])
    y = X @ theta_true[1:, :] + theta_true[0, :]
    print("X:\n{}".format(X))
    print("y:\n{}".format(y))
    # transfom all components in X to normalize view
    # for proper working of the gradient descent
    X_normalize, X_std = normalize(X)
    # obtaine theta (normalize) vector using gradient descent algorithm
    theta_normilize = gradient_descent(
        X_normalize, y, alpha=0.1, num_epoch=10000, verbose=True)
    # convert theta normilize to original feature space
    theta = inverse_transform(theta_normilize, X, X_std)
    print("\n\n")
    print("theta:\n{}".format(theta))
    print("theta_true:\n{}".format(theta_true))