"""
Given two 2D polygons write a function that calculates the IoU of their areas,
defined as the area of their intersection divided by the area of their union.
The vertices of the polygons are constrained to lie on the unit circle and you
can assume that each polygon has at least 3 vertices, given and in sorted order.

- You are free to use basic math functions/libraries (sin, cos, atan2, numpy etc)
  but not geometry-specific libraries (such as shapely).
- You are free to look up geometry-related formulas, optionally copy paste in
  short code snippets and adapt them to your needs.
- We do care and evaluate your general code quality, structure and readability
  but you do not have to go crazy on docstrings.
"""
import numpy as np
from math import atan2, sqrt

def computeLine(p1, p2):

    """
    Computing the lines parameters m and b given two points

    """

    dx = p1[0] - p2[0]
    return (p1[1] - p2[1]) / dx, (p1[0] * p2[1] - p2[0] * p1[1]) / dx

def cleanPoly(poly):

    """
    Removing duplicate points from polygon list of vertices

    """

    cleanedPoly = []
    for point in poly:
        if isNotInList(point, cleanedPoly):
            cleanedPoly.append(point)

    return cleanedPoly

def computeIntersection(p11, p12, p21, p22, tol=1e-6):

    """
    Computing intersection of two lines

    """

    # Compute difference in x co-ordinates for two lines

    dx1, dx2 = p11[0] - p12[0], p21[0] - p22[0]

    # If both difference in x are below tolerance, the lines are vertical and parallel => no intersection

    if abs(dx1) < tol and abs(dx2) < tol:
        return None

    # If just the first line difference in x is below tolerance, the first line is vertical
    elif abs(dx1) < tol:
            x = (p11[0] + p12[0])/2 # x co-ordinate of intersection
            m2, b2 = computeLine(p21, p22) # get second line parameters
            return x, m2 * x + b2

    # If just the second line difference in x is below tolerance, the second line is vertical
    elif abs(dx2)< tol:
            x = (p21[0] + p22[0]) / 2 # x co-ordinate of intersection
            m1, b1 = computeLine(p11, p12) # get first line parameters
            return x, m1 * x + b1

    # If none of the differences in x difference is below tolerance, none of the line is vertical

    else:
            m1,b1 = computeLine(p11, p12) # get first line parameters
            m2,b2 = computeLine(p21, p22) # get second line parameters
            dm = m1 - m2 # difference in slope

            # if difference in slope is below tolerance, the two lines are parallel i.e. no intersection
            if abs(dm) < tol:
                return None
            # else, compute intersection x, y
            else:
                return (b2 - b1) / dm, (m1 * b2 - b1 * m2) / dm

def distanceBetween(p1, p2):

    """
    Euclidean distance between two points

    """

    return sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)

def iou(poly1, poly2):

    """
    Computing intersection over union for given polygon

    """

    poly1, poly2 = cleanPoly(poly1), cleanPoly(poly2) # clean polygons of duplicate points
    poly3 = polyIntersection(poly1, poly2) # compute intersected polygon

    # if intersection exists (its a convex polygon with atleat 3 vertices)

    if poly3:
        # converting polygons to np arrays

        poly1 = np.array(poly1, dtype = np.float32)
        poly2 = np.array(poly2, dtype = np.float32)
        poly3 = np.array(poly3, dtype = np.float32)

        # computing area of intersection
        intersectionArea = polyArea(poly3[:,0], poly3[:,1])

        # computing area of union (= area of polygon - area of intersection)
        unionArea = polyArea(poly1[:,0], poly1[:,1]) + polyArea(poly2[:,0], poly2[:,1]) - intersectionArea

        # IoU = area of intersection / area of union
        return intersectionArea / unionArea

    # else, ploygons do not intersect i.e. IoU = 0.0
    else:

        return 0.0

def isNotInList(point, list, tol=1e-6):

    """
    Checking if the point is already in the list

    """

    for p in list:

        if distanceBetween(point, p) < tol:
            return False

    return True

def polyArea(x, y):

    """
    Computing the area of polygon using Shoeloace formula given ordered x and y coordinates of its vertices. (https://en.wikipedia.org/wiki/Shoelace_formula).

    """

    area = 0.5 * np.abs(np.dot(y, np.roll(x,1)) - np.dot(x, np.roll(y,1)))
    return area

def polyIntersection(poly1, poly2):

    """
    Computing the intersection between two polygons

    """

    intersections, orientations = [], [] # list of intersection points and respective orientations w.r.t the origin
    n1, n2 = len(poly1), len(poly2) # no. of vertices of two polygons

    # for each vertex in 1st polygon
    for i, currentVertex1 in enumerate(poly1):

        previousVertex1 = poly1[(i + n1 - 1) % n1]         # pervious vertex of 1st polygon

        # bounding box of current edge of 1st polygon
        xMax = max(currentVertex1[0], previousVertex1[0])
        xMin = min(currentVertex1[0], previousVertex1[0])
        yMax = max(currentVertex1[1], previousVertex1[1])
        yMin = min(currentVertex1[1], previousVertex1[1])

        # for each vertex in 2nd polygon
        for j, currentVertex2 in enumerate(poly2):

            previousVertex2 = poly2[(j + n2 - 1) % n2]

            # compute intersection between 2 lines of 2 polygons
            intersect = computeIntersection(currentVertex1, previousVertex1, currentVertex2, previousVertex2)

            # if intersection exists, it is in the bounding box and has not been already accounted
            if intersect:

                if xMin <= intersect[0] <= xMax and yMin <= intersect[1] <= yMax:
                    if isNotInList(intersect, intersections):

                        intersections.append(intersect) # appending it to the list
                        orientations.append(atan2(intersect[1], intersect[0])) # appending to the corresponding orientation

    # if fewer than 3 vertices
    if len(intersections) < 3:

        return None # its not a polygon (intersection is null)
    else:

        #sorting the vertices of polygon by orientation
        intesectionPoly = [x for _, x in sorted(zip(orientations, intersections))]
        return intesectionPoly

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

if __name__ == "__main__":

    cases = []
    # Case 1: a vanilla case (see https://imgur.com/a/dSKXHPF for a diagram)
    poly1 = [
        (-0.7071067811865475, 0.7071067811865476),
        (0.30901699437494723, -0.9510565162951536),
        (0.5877852522924729, -0.8090169943749476),
    ]
    poly2 = [
        (1, 0),
        (0, 1),
        (-1, 0),
        (0, -1),
        (0.7071067811865475, -0.7071067811865477),
    ]
    cases.append((poly1, poly2, "simple case", 0.12421351279682288))
    # Case 2: another simple case
    poly1 = [
        (1, 0),
        (0, 1),
        (-0.7071067811865476, -0.7071067811865476),
    ]
    poly2 = [
        (-0.1736481776669303, 0.984807753012208),
        (-1, 0),
        (0, -1),
    ]
    cases.append((poly1, poly2, "simple case 2", 0.1881047657147776))
    # Case 3: yet another simple case, note the duplicated point
    poly1 = [
        (0, -1),
        (-1, 0),
        (-1, 0),
        (0, 1),
    ]
    poly2 = [
        (0.7071067811865476, 0.7071067811865476),
        (-0.7071067811865476, 0.7071067811865476),
        (-0.7071067811865476, -0.7071067811865476),
        (0.7071067811865476, -0.7071067811865476),
        (0.7071067811865476, -0.7071067811865476),
    ]
    cases.append((poly1, poly2, "simple case 3", 0.38148713966109243))

    # Case 4: shared edge
    poly1 = [
        (-1, 0),
        (-0.7071067811865476, -0.7071067811865476),
        (0.7071067811865476, -0.7071067811865476),
        (1, 0),
    ]
    poly2 = [
        (0, 1),
        (-1, 0),
        (1, 0),
    ]
    cases.append((poly1, poly2, "shared edge", 0.0))

    # Case 5: same polygon
    poly1 = [
        (0, -1),
        (-1, 0),
        (1, 0),
    ]
    poly2 = [
        (0, -1),
        (-1, 0),
        (1, 0),
    ]
    cases.append((poly1, poly2, "same same", 1.0))

    # Case 6: polygons do not intersect
    poly1 = [
        (-0.7071067811865476, 0.7071067811865476),
        (-1, 0),
        (-0.7071067811865476, -0.7071067811865476),
    ]
    poly2 = [
        (0.7071067811865476, 0.7071067811865476),
        (1, 0),
        (0.7071067811865476, -0.7071067811865476),
    ]
    cases.append((poly1, poly2, "no intersection", 0.0))

    import time
    t0 = time.time()

    for poly1, poly2, description, expected in cases:
        computed = iou(poly1, poly2)
        print('-'*20)
        print(description)
        print("computed:", computed)
        print("expected:", expected)
        print("PASS" if abs(computed - expected) < 1e-8 else "FAIL")

    # details here don't matter too much, but this shouldn't be seconds
    dt = (time.time() - t0) * 1000
    print("done in %.4fms" % dt)


import numpy as np

def kullback_leibler(p1, p2):
    return np.sum(p1 * np.log(p1 / p2), axis=-1)

def entropy(p):
    return -np.sum(p * np.log(p), axis=-1)

def logsumexp(s):
    smax = np.amax(s, axis=-1)
    return smax + np.log(
        np.sum(np.exp(s - np.expand_dims(smax, axis=-1)), axis=-1))

def logit2proba(s):
    return np.exp(s - np.expand_dims(logsumexp(s), axis=-1))

def proba2logit(p):
    s = np.log(p)
    s -= np.mean(s, axis=-1, keepdims=True)
    return s

def test_proba2logit():
    p = np.random.dirichlet(np.ones(50), size=300)
    s = proba2logit(p)
    assert np.allclose(0, np.sum(s, axis=-1))

    q = logit2proba(s)
    assert np.allclose(1, np.sum(q, axis=-1)), q
    assert np.allclose(p, q), p - q

if __name__ == "__main__":
    test_proba2logit()


import datetime
import math
from functools import reduce
import statistics

import numpy as np
import pandas as pd
from pandas.plotting import scatter_matrix
from sklearn.metrics import r2_score, mean_squared_error,mean_absolute_error
from sklearn.model_selection import train_test_split
from sklearn import linear_model
import matplotlib.pyplot as plt

from python_helper import Constant as c
from python_helper import EnvironmentHelper, StringHelper, log, ObjectHelper
import globals

import Constants

PLOT_KINDS = ['scatter', 'line', 'bar']

def getFileNameWithPath(fileName):
    return StringHelper.join(['api', 'resource', 'data', fileName], EnvironmentHelper.OS_SEPARATOR)

def readCsv(csvFileName):
    return pd.read_csv(getFileNameWithPath(csvFileName))

def toCsv(content, csvFileName):
    # compression_opts = dict(method='zip', archive_name=getFileNameWithPath(csvFileName))
    # content.to_csv(csvFileName, index=False, compression=compression_opts)
    content.to_csv(getFileNameWithPath(csvFileName), index=False)

def plot(dataFrame, columns, title, kind):
    log.debug(plot, f'dataFrame: {dataFrame[[*columns.values()]]}')
    dataFrame.plot(x=columns.get('x'), y=columns.get('y'), kind=kind)
    plt.title(title)
    plt.show(block=False)

def showData(dataFrame, title):
    # from pandas.plotting import radviz
    # plt.figure()
    # radviz(dataFrame[['ID_GRUPO_SERVICO', 'TEMPOMINUTO', 'ID_AREA']], 'ID_AREA')
    ###- https://pandas.pydata.org/pandas-docs/version/0.9.1/visualization.html
    try:
        scatter_matrix(dataFrame, alpha=0.2, figsize=(8, 8), diagonal='kde')
        plt.title(title)
        plt.show(block=False)
    except Exception as e:
        log.failure(dataAnalysis, f'Not possible to show data of:{c.NEW_LINE}{dataFrame}', exception=e)
        plot(dataFrame, {'x': dataFrame.keys()[0], 'y': dataFrame.keys()[1]}, title, 'scatter')

def dataAnalysis(csvFileName, columnsToAnalyse, analysisBasedOnColumn=None, skipPlots=False):
    if analysisBasedOnColumn:
        dataFrameColumns = {**{k:None for k in columnsToAnalyse.keys()}, **{analysisBasedOnColumn:None}}
    else:
        dataFrameColumns = {k:None for k in columnsToAnalyse.keys()}
    log.prettyPython(dataAnalysis, 'dataFrameColumns', dataFrameColumns, logLevel=log.DEBUG)
    dataFrame, maxMap = getRawDataHandled(
        readCsv(csvFileName),
        dataFrameColumns,
        normalizeIt=False
    )
    showData(dataFrame, csvFileName)
    if not skipPlots:
        for columnToAnalyse in columnsToAnalyse:
            try:
                # plot(dataFrame, {'x':columnToAnalyse,'y':analysisBasedOnColumn}, 'Data Frame', 'scatter')
                solvingTimeByGroupId = {}
                initialType = None
                for sample in dataFrame[[columnToAnalyse, analysisBasedOnColumn]].values:
                    if not initialType:
                        initialType = type(sample[0])
                    if str(sample[0]) not in solvingTimeByGroupId:
                        solvingTimeByGroupId[str(sample[0])] = [float(sample[-1])]
                    else:
                        solvingTimeByGroupId[str(sample[0])].append(float(sample[-1]))
                    # if sample[0] not in solvingTimeByGroupId:
                    #     solvingTimeByGroupId[sample[0]] = [float(sample[-1])]
                    # else:
                    #     solvingTimeByGroupId[sample[0]].append(float(sample[-1]))

                for k,v in {**solvingTimeByGroupId}.items():
                    solvingTimeByGroupId[k] = sum(v) / len(v)
                dataFrameMean = pd.DataFrame(
                    {
                        columnToAnalyse:[initialType(k) for k in solvingTimeByGroupId.keys()],
                        analysisBasedOnColumn:[initialType(v) for v in solvingTimeByGroupId.values()]
                    },
                    columns=[columnToAnalyse,analysisBasedOnColumn]
                )
                sortedDataFrameMean = dataFrameMean.sort_values(by=[analysisBasedOnColumn])
                log.prettyPython(dataAnalysis, 'sortedDataFrameMean', '\n'+str(sortedDataFrameMean), logLevel=log.STATUS)
                plot(dataFrame, {'x':columnToAnalyse,'y':analysisBasedOnColumn}, 'Data Frame', 'scatter')
                plot(sortedDataFrameMean, {'x':analysisBasedOnColumn,'y':columnToAnalyse}, 'Sorted Data Frame Mean', 'scatter')
                # showData(sortedDataFrameMean, 'no title')
            except Exception as e:
                log.failure(dataAnalysis, f'Not possible to analyse data of {columnToAnalyse} vs {analysisBasedOnColumn}', exception=e)
    input('Hit enter to finish excecussion')

def evaluatePredictions(expected: pd.DataFrame, predicted: pd.DataFrame, muteLogs: bool = False):
    r2 = r2_score(expected, predicted)
    rmse = math.sqrt(mean_squared_error(expected, predicted))
    if not muteLogs:
        log.status(evaluatePredictions, f'SSE: {str(np.sum((expected - predicted)**2)).replace(c.NEW_LINE, c.SPACE_DASH_SPACE)}')
        log.status(evaluatePredictions, f'MSE: {mean_squared_error(expected, predicted)}')
        log.status(evaluatePredictions, f'MAE: {mean_absolute_error(expected, predicted)}')
        log.status(evaluatePredictions, f'RMSE: {rmse}')
        log.status(evaluatePredictions, f'R2-score: {r2}')
    return r2, rmse

def sigmoid(x):
    if abs(x) > 709:
        return 1 / (1 + math.exp(-(709 * (abs(x)/x))))
    return 1 / (1 + math.exp(-x))

def mergeLists(listA: list, listB: list):
    return listA + listB

def mergeMultipleLists(multipleLists: list):
    return reduce(mergeLists, multipleLists)

def getRawDataHandled(rawData, relevantColumns, normalizeIt=False, sigmoidIt=False, statsMap=None):
    rawDataFrame = pd.DataFrame(
        rawData, columns=[*relevantColumns.keys()]
    )
    rawDataFrame = rawDataFrame[
        rawDataFrame[
            [*relevantColumns.keys()]
        ].notnull().all(1)
    ]
    # df["id"] = df['id'].str.replace(',', '').astype(float)
    for columnName in [Constants.OPEN_TIME]:
        if columnName in rawDataFrame.keys():
            try:
                rawDataFrame[columnName] = rawDataFrame[columnName].str.replace(',', '.')
            except Exception as e:
                log.warning(getRawDataHandled, f'Not possible to filter {columnName}', e)
    rawDataFrame = rawDataFrame.astype(
        {k:v for k,v in relevantColumns.items() if v}#, errors='ignore'
    )
    try:
        for columnName in [Constants.CREATED_AT]:
            if columnName in [*rawDataFrame.keys()]:
                # rawDataFrame[columnName] = pd.to_datetime(rawDataFrame[columnName]).values.astype(np.int64) // 10 ** 9
                rawDataFrame[columnName] = pd.to_timedelta(rawDataFrame[columnName].str.split().str[-1]).dt.total_seconds().astype(int)
    except Exception as e:
        log.warning(getRawDataHandled, f'Not possible to handle timestamp {columnName}', e)
    if not statsMap:
        statsMap = {
            Constants.MAX: {},
            Constants.MEAN: {}
        }
        for columnName in relevantColumns:
            if columnName not in [Constants.ID, Constants.SOLVING_TIME]:
                try:
                    statsMap[Constants.MAX][columnName] = 1.0 * rawDataFrame[columnName].max()
                    statsMap[Constants.MEAN][columnName] = statistics.mean(rawDataFrame[columnName])
                except Exception as e:
                    log.warning(getRawDataHandled, f'Not possible to properly populate max and mean of {columnName}', e)
    if normalizeIt:
        for columnName in relevantColumns:
            if columnName not in [Constants.ID, Constants.SOLVING_TIME]:
                if sigmoidIt:
                    rawDataFrame[columnName] = (rawDataFrame[columnName] - statsMap[Constants.MEAN][columnName]) / statsMap[Constants.MAX][columnName]
                    rawDataFrame[columnName] = rawDataFrame[columnName].apply(sigmoid)
                else:
                    rawDataFrame[columnName] = rawDataFrame[columnName] / statsMap[Constants.MAX][columnName]
    elif sigmoidIt:
        for columnName in relevantColumns:
            if columnName not in [Constants.ID, Constants.SOLVING_TIME]:
                rawDataFrame[columnName] = rawDataFrame[columnName].apply(sigmoid)
    return rawDataFrame, statsMap

def replaceData(dataFrame: pd.DataFrame, columnName: str, oldValues: list, newValues: list):
    dataFrameCopy = dataFrame.copy(deep=True)
    # print(columnName, oldValues)
    dataFrameCopy[columnName] = dataFrameCopy[columnName].replace(oldValues, newValues)
    return dataFrameCopy

def splitData(trainningDataFrame: pd.DataFrame, inputColumnNames: list, outputColumnNames: list, testSize: float = 0.2, randomState=None):
    if randomState:
        trainningInputData, testingInputData, trainningOutputData, testingOutputData = train_test_split(
            trainningDataFrame[inputColumnNames],
            trainningDataFrame[[*outputColumn.keys()]],
            test_size=testSize,
            random_state=randomState
        )
    else:
        trainningInputData, testingInputData, trainningOutputData, testingOutputData = train_test_split(
            trainningDataFrame[inputColumnNames],
            trainningDataFrame[outputColumnNames],
            test_size=testSize
        )
    return trainningInputData, testingInputData, trainningOutputData, testingOutputData

def getItMerged(data):
    return pd.DataFrame(
        {columnName:[*columnValues] for columnName, columnValues in data.items()}
    )


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

def h(x, theta):
    return 1 / (1 + np.exp(-np.dot(x, theta)))

def cost(x, y, theta):
    _h = h(x, theta)
    if y == 1:
        return -np.log(_h)
    else:
        return -np.log(1 - _h)

def J(X, Y, theta):
    m, n = np.shape(X)
    loss = 0
    for k in range(m):
        loss += cost(X[k], Y[k], theta)
    return loss / m

def bgd(X, Y, alpha=0.01, epsilon=1e-6, trace=True):
    m = len(X)
    _X = np.column_stack((np.ones(m), X))
    m, n = np.shape(_X)
    theta, j1, cnt = np.ones(n), 0, 0
    Xt = _X.T

    while True:
        loss = h(_X, theta) - Y
        gradient = np.dot(Xt, loss) / m
        theta -= alpha * gradient

        j = J(_X, Y, theta)

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

        if abs(j - j1) < epsilon:
            break
        else:
            j1 = j

        cnt += 1
    return theta

def predict2d(theta, x, y):
    data = [1, x, y]
    v = h(theta, data)
    print('predict ({0}, {1}) = {2}, z = {3}'.format(x, y, v, np.dot(theta, data)))
    return v

if __name__ == '__main__':
    import matplotlib.pyplot as plt

    m = 12
    x1 = np.linspace(0, 6, m + 1)
    x2 = np.linspace(0, 6, m + 1)
    X, Y = [], []

    print(x1)
    for i in range(m):
        for j in range(m):
            X.append((x1[i], x2[j]))
            if x1[i] > 5 or x2[j] > 5 or x1[i] + x2[j] > 5:
                Y.append(1)
            else:
                Y.append(0)

    for i in range(len(X)):
        c, m = 'r', 'o'
        if Y[i] == 0:
            c, m = 'b', 'x'
        plt.scatter(X[i][0], X[i][1], c=c, marker=m)

    plt.grid(True)
    plt.show()

    theta2 = bgd(X, Y, 0.5, trace=False)
    print('theta = {0}'.format(theta2))

    predict2d(theta2, 10, 10)
    predict2d(theta2, 10, 1)
    predict2d(theta2, 2, 8)
    predict2d(theta2, 5, 5)
    predict2d(theta2, 4, 4)
    predict2d(theta2, 3, 4)
    predict2d(theta2, 3, 3)
    predict2d(theta2, 2, 4)
    predict2d(theta2, 3, 2.5)
    predict2d(theta2, 2.5, 3)
    predict2d(theta2, 2.5, 2.5)
    predict2d(theta2, 3, 2)
    predict2d(theta2, 1, 1)
    predict2d(theta2, -3, -3)
    predict2d(theta2, -5, -5)
    predict2d(theta2, -10, -10)


# The following code implements the NP-complete problem 'Traveling Salesman Problem' .
# With dynamic programming approach, the algorithm is able to complete in reasonable time.
import numpy as np
import math
from itertools import combinations
from tqdm.auto import tqdm

def read_file(name):
    """Given the path/name of the text file, return the
    """
    file = open(name,'r')
    data = file.readlines()

    # Initialize the vertices list
    vertices = []

    num = int(data[0][0])
    for line in data[1:]:
        item = line.split()
        vertices.append((float(item[0]), float(item[1])))

    return vertices

def euclidean(a,b):
    """Return the euclidean distance of a(x1,y1) and b(x2,y2)
    """
    dis = np.sqrt((a[0] - b[0])**2 + (a[1]- b[1])**2)
    return dis

def n_choose_k(n,k):
    """Return the number of combinations of 'n choose k'
    """
    return int(math.factorial(n)/(math.factorial(k)*math.factorial(n-k)))

def subset(arr, k):
    """Given array arr and integer k, find the combinations of subsets. With 1 prepend.
    """
    sub = []
    a = list(combinations(arr, k))
    for i in a:
        i = tuple([1]+list(i))
        sub.append(i)
    return sub

def find_min(A, vertices, subset, j):
    """Given subset and j, find the minimum value.

    """
    # remove the last vertice.
    subset = list(subset)
    subset.remove(j)

    s_removed = subset

    if len(s_removed)>1:

        s_removed = tuple(s_removed)
        mini = min(A[(s_removed, k)] + euclidean(vertices[k-1],vertices[j-1]) for k in s_removed)

    else:
        s_removed = 1
        mini = A[(1, 1)] + euclidean(vertices[0],vertices[j-1])

    return mini

def find_min_final(A,vertices):
    """Given the whole matrix(graph), find the minimum value of traveling salesman problem.
    """

    mini = min(A[(tuple(range(1,len(vertices)+1)), j)] + euclidean(vertices[j-1], vertices[0]) for j in range(2,len(vertices)+1))

    return mini

def salesman(name):
    """Main function of traveling salesman problem.
    Given the path/name of the file, return the minimum value.
    """

    vertices = read_file(name)
    num = len(vertices)

    # Initialize the matrix
    inf = 1e6
    A = {}
    A[(1,1)] = 0
    keys = {}
    indices = []
    for i in range(1, num):
        current_keys = []
        S = subset(range(2,num+1), i)
        for j in S:
            A[(j,1)] = inf
            indices.append(j)
            current_keys.append(j)
        keys[i+1] = current_keys

    # Fill in the graph(matrix)
    for m in tqdm(range(2, num+1)):
        for key in tqdm(keys[m]):
            s = key
            #print(s)
            for j in s:
                if j !=1:
                    A[(s,j)] = find_min(A, vertices, s, j)

    # Find the minimum value
    mini = find_min_final(A, vertices)

    return mini

def main():
    mini = salesman('tsp.txt')
    print(mini)

if __name__ == '__main__':
    main()

C4: Shortest Path Revisited, NP-Complete/TSP.py


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

pi = np.pi
sin = np.sin
cos = np.cos
log = np.log
inv = np.linalg.inv

def FDM(x0,xn,n,a,b,c,f,alpha,beta):
    """
    Finite Differential Method in 1D coordination system
    ay'' + by' + c = f(x)

    alpha and beta are boundary condition at the begin and the end x0 and xn, respectively
    f(x0) = alpha, f(xn) = beta

    a(x),b(x),c(x) can be either a function of x or constants. (Scalar or Vector with the same length of x
    """

    inv = np.linalg.inv
    x,h = np.linspace(x0,xn,n,retstep = True)
    def sc2vec(a):
        if np.isscalar(a)==True:
            a = np.ones(len(x))*a
        return a
    a,b,c = list(map(sc2vec,[a,b,c]))
    #define A
    diagonal = h**2*c - 2*a
    diagonal_side = a[1:] + h*b[1:]/2
    A = np.diag(diagonal) + np.diag(diagonal_side,1) + np.diag(diagonal_side,-1)
    A = 1/h**2*A

    #define F
    F = f(x)
    F[0] = F[0] - (a[0]/h**2 - b[0]/2/h)*alpha
    F[n-1] = F[n-1] - (a[n-1]/h**2 + b[n-1]/2/h)*beta
    Y = inv(A)@F
    return Y,A,F,x


import numpy as np
from numpy import exp, sqrt, cos, pi, sin

from base_function import BaseFunction

class Ackley(BaseFunction):
    #note: this function is not smooth at the origin.  the gradient will never
    #converge in the minimizer
    target_E = 0.
    xmin = np.array([-5.,-5.])
    xmax = np.array([5.,5.])
    def getEnergy(self, coords):
        x, y = coords
        E = -20. * exp(-0.2 * sqrt(x**2 + y**2)) - \
            exp(0.5 * (cos(2. *pi * x) + cos(2. * pi * y))) + 20. + np.e
        return E

    def getEnergyGradient(self, coords):
        E = self.getEnergy(coords)
        x, y = coords
        R = sqrt(x**2 + y**2)
        term1 = -20. * exp(-0.2 * R)
        term2 = -exp(0.5 * (cos(2. *pi * x) + cos(2. * pi * y)))

        deriv1 = term1 * (-0.2 * 0.5 / R)

        dEdx = 2.* deriv1 * x  - term2 * pi * sin(2.*pi*x)
        dEdy = 2.* deriv1 * y  - term2 * pi * sin(2.*pi*y)

        return E, np.array([dEdx, dEdy])

if __name__ == "__main__":
    f = Ackley()
    f.test_potential(f.get_random_configuration())

    from base_function import makeplot2d
    makeplot2d(f)


import math
import numpy as np
from random import randint

def PrimeGen( n = 10000 ):
    sieve = np.ones ( n//2, dtype = np.bool )
    for i in range( 3, int ( n**0.5 ) + 1, 2 ):
        if sieve[ i//2 ]:
            sieve[ i * i//2::i ] = False
    return np.r_[ 2, 2 * np.nonzero ( sieve )[ 0 ][ 1:: ] + 1 ]

def lcm( p, q ):
    return ( p * q ) / math.gcd ( p,q )

def extended_gcd ( aa, bb ):
    lastremainder, remainder = abs ( aa ), abs ( bb )
    x, lastx, y, lasty = 0, 1, 1, 0
    while remainder:
        lastremainder, ( quotient, remainder) = remainder, divmod ( lastremainder, remainder )
        x, lastx = lastx - quotient*x, x
        y, lasty = lasty - quotient*y, y
    return lastremainder, lastx * ( -1 if aa < 0 else 1 ), lasty * ( -1 if bb < 0 else 1 )

def modinv ( a, m ):
    g, x, y = extended_gcd ( a, m )
    if g !=  1:
        raise ValueError
    return x % m

def mult_inverse ( e, lamda ):
    d = 0
    x1 = 0
    x2 = 1
    y1 = 1
    temp_lamda = lamda

    while e > 0:
        temp1 = temp_lamda / e
        temp2 = temp_lamda - temp1 * e
        temp_lamda = e
        e = temp2

        x = x2- temp1 * x1
        y = d - temp1 * y1

        x2 = x1
        x1 = x
        d = y1
        y1 = y

    if temp_lamda ==  1:
        return d + lamda

def keyGen ( ):

    i_p = randint( 0,20 )
    i_q = randint( 0,20 )
    while i_p == i_q:
        continue
    primes = PrimeGen ( 100 )
    p = primes[ i_p ]
    q = primes[ i_q ]

    n = p * q

    lamda_n = int ( lcm ( p - 1, q - 1 ) )
    e = randint( 1, lamda_n )

    while math.gcd ( e, lamda_n ) != 1:
        e = randint ( 1, lamda_n )

    d = modinv( e, lamda_n )

    return ( ( e, n ), ( d, n ) )

def encrypt( pk, message ):

    key, n = pk

    cipher = [ ( ord ( char ) ** key ) % n for char in message ]

    return cipher

def decrypt( pk, cipher ):

    key, n = pk

    message = [ chr( ( char ** key ) % n ) for char in cipher ]

    return ''.join ( message )


##########################
##                      ##
## Irving Gomez Mendez  ##
##   October 30, 2021   ##
##                      ##
##########################

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

from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA

dat = pd.read_csv('banknotes.csv')

dat

sns.pairplot(data=dat, hue='conterfeit', corner=True)

class PCA_varios_metodos:
    def __init__(self, dat):
        X = dat.drop('conterfeit', axis=1)
        self.n, self.p = X.shape
        self.X = X

    def centrar_X(self):
        self.X_centered = pd.DataFrame(StandardScaler(with_std=False).fit_transform(self.X))

    def calcula_S(self):
        self.S = self.X.cov()

    def SVD(self):
        self.u, self.d, self.v_T  = np.linalg.svd(self.X_centered, full_matrices=False)

    def verifica_SVD(self):
        return(self.u @ np.diag(self.d) @ self.v_T)

    def PCA_con_SVD(self):
        self.SVD_loads       = self.v_T.T
        self.SVD_variance_CP = self.d**2/(self.n-1)
        self.SVD_CP_UD       = (self.u @ np.diag(self.d))
        self.SVD_CP_V        = self.X_centered @ self.v_T.T

    def PCA_con_matriz_cov(self):
        eigval, eigvect    = np.linalg.eig(self.S)
        self.S_loads       = eigvect
        self.S_variance_CP = eigval
        self.S_CP          = self.X_centered @ eigvect

    def PCA_con_sklearn(self):
        pca                      = PCA(n_components = self.p)
        pca_fit                  = pca.fit_transform(self.X)
        self.sklearn_loads       = pca.components_.T
        self.sklearn_variance_CP = pca.explained_variance_
        self.skelarn_CP          = pca_fit

pca_varios = PCA_varios_metodos(dat)
pca_varios.centrar_X()
pca_varios.calcula_S()
pca_varios.SVD()

pca_varios.X_centered

pd.DataFrame(pca_varios.verifica_SVD())

## PCA through SVD
pca_varios.PCA_con_SVD()
pd.DataFrame(pca_varios.SVD_loads)
pca_varios.SVD_variance_CP
pd.DataFrame(pca_varios.SVD_CP_UD)
pca_varios.SVD_CP_V

## PCA through covariance matrix
pca_varios.PCA_con_matriz_cov()
pd.DataFrame(pca_varios.S_loads)
pca_varios.S_variance_CP
pca_varios.S_CP

pca_varios.PCA_con_sklearn()
pd.DataFrame(pca_varios.sklearn_loads)
pca_varios.sklearn_variance_CP
pd.DataFrame(pca_varios.skelarn_CP)

plt.figure(figsize=(12,10))
plt.plot(pca_varios.sklearn_variance_CP.cumsum()/pca_varios.sklearn_variance_CP.sum())

loads = pd.DataFrame(pca_varios.sklearn_loads)
loads.index = dat.drop('conterfeit', axis=1).columns

loads

plt.figure(figsize=(12,10))
sns.scatterplot(x=loads[0], y=loads[1], hue=loads.index, palette='deep', s=300)
plt.axvline(0, color='red', linestyle='--')
plt.axhline(0, color='red', linestyle='--')
plt.legend(fontsize=15)

Components = pd.DataFrame(pca_varios.skelarn_CP)

plt.figure(figsize=(12,10))
sns.scatterplot(x=Components[0], y=Components[1], hue=dat['conterfeit'], palette='deep', s=300)
plt.legend(fontsize=15)

###


import numpy as np

"""
Q:
Write a binomial tree program to calculate the put prices of Bermuda options.
For such options, early exercise is allowed only on specific dates.

Inputs:
S (stock price)
X (strike price)
r (continuously compounded annual interest rate in percentage)
s (annual volatility in percentage)
T (time to maturity in days, which of course is also an exercise date)
E (set of early exercise dates from now)
m (number of periods per day for the tree)

Output:
11.2486

Long put:MAX{X-ST,0}
X (Strike Price)
ST (represent the price of the underlying at maturity)
"""

class node:
    def __init__(self,price):
        self.price = price
        self.value = 0
        self.u_parent = None
        self.d_parent = None
        self.u_child = None
        self.d_child = None

def price(S,X,r,s,T,E,m):
    if T not in E:
        E.append(T)
    deltaT = (T/365)/(T*m)
    R = np.exp(r*deltaT)
    u = np.exp(s*np.sqrt(deltaT))
    d = 1/u
    p = (R - d) / (u-d) #Risk Neutral Probability
    root = node(S)
    BinomialTree = [[root]]

    for period in range(T*m):
        currentLevel = BinomialTree[-1]
        childLevel = [node(currentLevel[0].price * u)]
        #print(childLevel[0].price)
        for currentNode in currentLevel:
            currentNode.u_child = childLevel[-1]
            currentNode.u_child.d_parent = currentNode
            downChild = node(currentNode.price * d)
            downChild.u_parent = currentNode
            currentNode.d_child = downChild
            childLevel.append(downChild)
        BinomialTree.append(childLevel)

    total = T * m
    for levelNodes in BinomialTree[::-1]:
        if int(total/m) in E:
            for tree_node in levelNodes:
                if tree_node.u_child != None:
                    binomialValue = ( ( 1/R ) * (p * tree_node.u_child.value + (1 - p) * tree_node.d_child.value))
                else:
                    exerciseValue = max(0,X - tree_node.price)
                    binomialValue = exerciseValue
                    #print(exerciseValue)

                exerciseValue = max(0,X - tree_node.price)
                tree_node.value = max(binomialValue, exerciseValue)
        else:
            for tree_node in levelNodes:
                binomialValue = ( ( 1/R ) * (p * tree_node.u_child.value + (1 - p) * tree_node.d_child.value))
                tree_node.value = binomialValue
        total -= 1

    putPrice = root.value

    return putPrice

if __name__ == "__main__":
    S = float(input("輸入Stock Price ex:100\n"))
    X = float(input("輸入Strike price ex:110\n"))
    r = float(input("輸入Continuously compounded annual interest rate in percentage(%) ex:3\n"))/100
    s = float(input("輸入Annual volatility in percentage(%) ex:30\n"))/100
    T = int(input("輸入time to maturity in days,which of course is also an exercise date ex:60\n"))
    Temp = input("輸入set of early exercise dates from now ex:10 20 30 40 50\n").split(' ')
    E = []
    for temp in Temp:
        E.append(int(temp))
    m = int(input("輸入number of periods per day for the tree ex:5\n"))
    print("S= %f" %S)
    print("X= %f" %X)
    print("r= %f" %r)
    print("s= %f" %s)
    print("T= %d" %T)
    print("E=",E)
    print("m= %d\n" %m)

    output = price(S,X,r,s,T,E,m)
    print(output)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Feb 10 15:03:10 2022

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

f = lambda x : -.5*x+4
a = -5; b = 5;
J = int(input("what is your delta x"))

x = np.linspace(a,b,J+1)
y = f(x)

X = np.linspace(a,b,J+1)
Y = f(X)

dx = (b-a)/J
x_left = np.linspace(a,b-dx,J)
x_midpoint = np.linspace(dx/2,b - dx/2,J)
x_right = np.linspace(a+dx,b,J)

print("Partition with",J,"subintervals.")
left_riemann_summ = np.sum(f(x_left) * dx)
print("Left Riemann Sum:",left_riemann_summ)

right_riemann_summ = np.sum(f(x_right) * dx)
print("Right Riemann Sum:",right_riemann_summ)

f = lambda x : -.29*x**2 -x +12.5
a = -5; b = 5;
N = int(input("what is your delta x"))

x = np.linspace(a,b,N+1)
y = f(x)

X = np.linspace(a,b,N+1)
Y = f(X)

dx = (b-a)/N
x_left = np.linspace(a,b-dx,N)
x_midpoint = np.linspace(dx/2,b - dx/2,N)
x_right = np.linspace(a+dx,b,N)

print("Partition with",N,"subintervals.")
left_riemann_sum = np.sum(f(x_left) * dx)
print("Left Riemann Sum:",left_riemann_sum)

right_riemann_sum = np.sum(f(x_right) * dx)
print("Right Riemann Sum:",right_riemann_sum)

f = lambda x : 1+10*((x+1)*np.exp(-x**2))
a = -5; b = 5;
R = int(input("what is your delta x"))

x = np.linspace(a,b,R+1)
y = f(x)

X = np.linspace(a,b,R+1)
Y = f(X)

dx = (b-a)/R
x_left = np.linspace(a,b-dx,R)
x_midpoint = np.linspace(dx/2,b - dx/2,R)
x_right = np.linspace(a+dx,b,R)

print("Partition with",R,"subintervals.")
left_riemann_summm = np.sum(f(x_left) * dx)
print("Left Riemann Sum:",left_riemann_summm)

right_riemann_summm = np.sum(f(x_right) * dx)
print("Right Riemann Sum:",right_riemann_summm)

eq1 = ((abs(40 - left_riemann_summ))/((40+left_riemann_summ)/2))*100
print ("left sum percent difference for first equation is", eq1)

eq2 = ((abs(100.83 - left_riemann_sum))/((100.83+left_riemann_sum)/2))*100
print ("left sum percent difference for second equation is", eq2)

eq3 = ((abs(27.72 - left_riemann_summm))/((27.72+left_riemann_summm)/2))*100
print ("left sum percent difference for first equation is", eq3)

x_coordinates = [J, N, R]
y_coordinates = [eq1, eq2, eq3]
plt.xlabel('delta x value')

plt.ylabel('percentage diference')

plt.scatter(x_coordinates, y_coordinates)


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

# Generate the data
visualize = False
verbose = False

w0_t = 2
w1_t = 1
sigma = 1

x_t = np.arange(-100, 101, 0.1)
# x_t = np.arange(0, 10, 1)
noise = sigma * np.random.randn(x_t.size)

y_t = w1_t * x_t + w0_t
y_noise = y_t + noise

if visualize:
    plt.plot(x_t, y_t)
    plt.hold(True)
    plt.plot(x_t, y_noise)
    plt.show()

N = 400  # Number of steps of the simulation
eta = 0.01
w_0 = np.random.rand()
w_1 = np.random.rand()

print ('Random guess about w0 and w1')
print (w_0, w_1)

shuffler = np.random.choice(x_t.size, size=x_t.size, replace=False)
x_data = x_t[shuffler]
y_data = y_noise[shuffler]

# x_data = x_t
# y_data = y_t

def calculate_error(x, y, w0, w1):
    est_y = w0 + x * w1
    diff = est_y - y
    error = np.sum(diff ** 2)

    return np.sqrt(error / x.size)

# This is a cycle
for i in range(N):
    for point in shuffler:
        aux = (w_0 + w_1 * x_data[point] - y_data[point])
        w_0 = w_0 - eta * 2 * aux / x_data.size
        w_1 = w_1 - eta * 2 * x_data[point] * aux / x_data.size
        if verbose:
            print ('Estimated w0 and w1')
            print (w_0, w_1)
    error = calculate_error(x_data, y_data, w_0, w_1)
    print('error = ', error, 'at step = ', i)

# Now we need to calculate the error
print ('Estimated w0 and w1')
print (w_0, w_1)

print ('Truth values of w0 and w1')
print (w0_t, w1_t)


import unittest
import numpy as np

from algorithm_collection.mathematics import prime_factors

class TestPrimeNumbers(unittest.TestCase):
    def test_prime_numbers(self):
        n = 315
        res = [3, 3, 5, 7]

        self.assertTrue(np.array_equal(prime_factors(n), res))


# Credit to Lester Leong and his "Python Risk Management: Monte Carlo Simulations"
# article which helped with starting off and understanding the material.

import datetime as dt
import numpy as np
import pandas as pd
import pandas_datareader as pdr
import matplotlib.pyplot as plt
from scipy.stats import norm

#20
np.random.seed(8) # seeding the pseudorandom number generator to compare output plots more easily
start = dt.datetime(2018,1,1)
end = dt.datetime.now()
ticker = 'INTC' # symbol for Intel Corp
time_steps = 31 # (time_steps - 1) is the amount of steps taken into the future for the simulation
sims = 100 # the number of simulations that will be run

# Setting up data in a DataFrame
# Using adjusted closing prices of Intel stock as an example
data = pd.DataFrame()
data[ticker] = pdr.DataReader(ticker, data_source='yahoo', start=start, end=end)['Adj Close']

# log returns
# pct_change is the percentage change between current and prior element
log_returns = np.log(1 + data.pct_change())

# Setting up the values necessary for the daily_returns expression
mu = log_returns.mean() # average/mean
var = log_returns.var() # variance
drift = mu - (0.5 * var) # drift
sigma = log_returns.std() # standard deviation

daily_returns = np.exp(drift.values + sigma.values * norm.ppf(np.random.rand(time_steps, sims)))

# Takes last data point as as the starting point for the simulations
initial = data.iloc[-1]
monte_list = np.zeros_like(daily_returns)
monte_list[0] = initial

# For the amount of steps taken into the future, this loop calculated the simulation data to be plotted
# Takes input price, multiplies it by the exponential value calculated in daily_returns, sets simulated price
for t in range(1, time_steps):
    monte_list[t] = monte_list[t - 1] * daily_returns[t]

# Histogram for the price frequencies, number of bins can be adjusted
plt.figure(figsize=(10, 6))
plt.hist(monte_list[1], bins=10, density=True)

# Fit a normal distribution to the first simulation point in monte_list data
# Could implement for each successive iteration in the monte_list index (monte_list[2], monte_list[3], ..., monte_list[time_steps - 1])
sim_mu, sim_sig = norm.fit(monte_list[1])

# Probability Density Function
xmin, xmax = plt.xlim() # set the xmin and xmax along the x-axis for the pdf
x = np.linspace(xmin, xmax)
p = norm.pdf(x, sim_mu, sim_sig)

# Plots of raw data; log return; Monte Carlo Simulations;
# and frequencies of the Monte Carle simulations fit to normal distribution
plt.plot(x, p, 'k') # normal distribution fit
plt.xlabel('Adjusted Closing Price')
plt.ylabel('Probability Density')
title = "Histogram for 100 Simulations of Adjusted Closing Price 1 Day into the Future\nPDF fit results: mu = %.4f,  sigma = %.4f" % (sim_mu, sim_sig)
plt.title(title)

#Adjusted Closing Price data acquired from Yahoo Finance
data.plot(figsize=(10, 6))
plt.xlabel('Date')
plt.ylabel('Adjusted Closing Price')
title = "Intel's Adjusted Closing Prices Over Time"
plt.title(title)

# log returns plot
log_returns.plot(figsize=(10, 6))
plt.xlabel('Date')
plt.ylabel('Log Return')
title = "Log Returns Over Time"
plt.title(title)

# Monte Carlo Simulations for each day into the future
plt.figure(figsize=(10, 6))
plt.plot(monte_list) # monte carlo
plt.xlabel('Days into the Future')
plt.ylabel('Adjusted Closing Price')
title = "Monte Carlo Simulations (n = 100) for Intel's Adjusted Closing Prices"
plt.title(title)
plt.show()


import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn import datasets
from math import exp

# the logistic function
def logistic_func(theta, x):
    t = x.dot(theta)
    g = np.zeros(t.shape)
    # split into positive and negative to improve stability
    g[t>=0.0] = 1.0 / (1.0 + np.exp(-t[t>=0.0]))
    g[t<0.0] = np.exp(t[t<0.0]) / (np.exp(t[t<0.0])+1.0)
    return g

# function to compute log-likelihood
def neg_log_like(theta, x, y):
    g = logistic_func(theta,x)
    return -sum(np.log(g[y>0.5])) - sum(np.log(1-g[y<0.5]))

# function to compute the gradient of the negative log-likelihood
def log_grad(theta, x, y):
    g = logistic_func(theta,x)
    return -x.T.dot(y-g)

# implementation of gradient descent for logistic regression
def grad_desc(theta, x, y, alpha, tol, maxiter):
    nll_vec = []
    nll_vec.append(neg_log_like(theta, x, y))
    nll_delta = 2.0*tol
    iter = 0
    while (nll_delta > tol) and (iter < maxiter):
        theta = theta - (alpha * log_grad(theta, x, y))
        nll_vec.append(neg_log_like(theta, x, y))
        nll_delta = nll_vec[-2]-nll_vec[-1]
        iter += 1
    return theta, np.array(nll_vec)

# function to compute output of LR classifier
def lr_predict(theta,x):
    # form Xtilde for prediction
    shape = x.shape
    Xtilde = np.zeros((shape[0],shape[1]+1))
    Xtilde[:,0] = np.ones(shape[0])
    Xtilde[:,1:] = x
    return logistic_func(theta,Xtilde)

## Generate dataset
np.random.seed(2017) # Set random seed so results are repeatable
x,y = datasets.make_blobs(n_samples=100,n_features=2,centers=2,cluster_std=6.0)

## build classifier
# form Xtilde
shape = x.shape
xtilde = np.zeros((shape[0],shape[1]+1))
xtilde[:,0] = np.ones(shape[0])
xtilde[:,1:] = x

# Initialize theta to zero
theta = np.zeros(shape[1]+1)

# Run gradient descent
alpha = ????
tol = 1e-3
maxiter = 10000
theta,cost = grad_desc(theta,xtilde,y,alpha,tol,maxiter)

## Plot the decision boundary.
# Begin by creating the mesh [x_min, x_max]x[y_min, y_max].
h = .02  # step size in the mesh
x_delta = (x[:, 0].max() - x[:, 0].min())*0.05 # add 5% white space to border
y_delta = (x[:, 1].max() - x[:, 1].min())*0.05
x_min, x_max = x[:, 0].min() - x_delta, x[:, 0].max() + x_delta
y_min, y_max = x[:, 1].min() - y_delta, x[:, 1].max() + y_delta
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
Z = lr_predict(theta,np.c_[xx.ravel(), yy.ravel()])

# Create color maps
cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA'])
cmap_bold = ListedColormap(['#FF0000', '#00FF00'])

# Put the result into a color plot
Z = Z.reshape(xx.shape)
plt.figure()
plt.pcolormesh(xx, yy, Z, cmap=cmap_light)

## Plot the training points
plt.scatter(x[:, 0], x[:, 1], c=y, cmap=cmap_bold)

## Show the plot
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.title("Logistic regression classifier")
plt.show()


import numpy as np

def gaussian(x, y, mean, cov):

	sigmax = np.sqrt(cov[0,0])
	sigmay = np.sqrt(cov[1,1])
	mux = mean[0]
	muy = mean[1]

	max_f = (2*np.pi*sigmax*sigmay)**(-1)

	ex = -(x-mux)**2/(2*sigmax**2)
	ey = -(y-muy)**2/(2*sigmay**2)

	return max_f*np.exp(ex + ey)

def generate_gaussian(mean, cov, N):
	'''
	Sample the 2d Gaussian distribution
	with independent variables.
	'''
	sigmax = np.sqrt(cov[0,0])
	sigmay = np.sqrt(cov[1,1])
	mux = mean[0]
	muy = mean[1]

	max_f = (2*np.pi*sigmax*sigmay)**(-1)

	result = []

	while len(result) < N:

		x = 8*sigmax*np.random.rand() - 4*sigmax + mux
		y = 8*sigmay*np.random.rand() - 4*sigmay + muy
		z = max_f*np.random.rand()

		if z < gaussian(x,y,mean,cov):
			result.append([x,y])

	return np.array(result)


import numpy as np
from matplotlib import pyplot as plt
from sklearn.linear_model import LinearRegression
import pandas as pd
from scipy.stats import pearsonr

df = pd.DataFrame([[27,20],[19,23],[15,18],[26,25],[17,26],[25,24],[21,23],[14,24],[27,20],[26,22],[23,26],[18,28]])
df.columns = ['x', 'y']
X_train = df['x'].values[:,np.newaxis]
Y_train = df['y'].values

model_reg = LinearRegression()
model_reg.fit(X_train,Y_train) #fase training

#regression coefficients
print('Coefficients b = {}'.format(model_reg.coef_))
print('Constant a ={} '.format(model_reg.intercept_))

#model regresi yang didapat
print('Y = ', model_reg.intercept_ ,'+', model_reg.coef_,'X')

#prediksi satu data jika nilai X = 28
print('Y = {}'.format(model_reg.predict([[28]])))

# Apply the pearsonr()
corr, _ = pearsonr(df['x'],df['y'])
print('Pearsons correlation: %.2f' % corr)

# Apply the koef determination
correlation_matrix = np.corrcoef(df['x'],df['y'])
correlation_xy = correlation_matrix[0,1]
koefdet = correlation_xy**2
print("Koefisien Determinasi : {:.0%}" .format(correlation_xy**2))

#prepare plot
pb = model_reg.predict(X_train)
dfc = pd.DataFrame({'x': df['x'],'y':pb})
plt.scatter(df['x'],df['y'])
plt.plot(dfc['x'],dfc['y'],color='red',linewidth=1)
plt.title('Correlation = : %.2f' % corr)
plt.xlabel('Dampak Virus Covid-19')
plt.ylabel('Laju Ekonomi')
plt.show()


'''
ANKIT KHANDELWAL
15863
Exercise 8
'''

from math import exp

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

blur = pd.read_csv("blur.txt", sep=' ', header=None)

def G(x, y):
    return exp(-(x ** 2 + y ** 2) / (2 * 25 ** 2))

gauss = np.ones((1024, 1024))
for i in range(1024):
    for j in range(1024):
        gauss[i - 512][j - 512] = G(i - 512, j - 512)

plt.imshow(blur)
plt.title('Blur')
plt.figure()
plt.imshow(gauss)
plt.title('Gauss')
plt.figure()
blur_fft = np.fft.rfft2(blur)
gauss_fft = np.fft.rfft2(gauss)
unblur = np.ones((1024, 513), complex)

for i in range(1024):
    for j in range(513):
        if gauss_fft[i][j] > 10 ** -3:
            unblur[i][j] = blur_fft[i][j] / gauss_fft[i][j] / 1024 ** 2
        else:
            unblur[i][j] = blur_fft[i][j] / 1024 ** 2

unblur_fft = np.fft.irfft2(unblur)
plt.imshow(unblur_fft)
plt.title('Un-Blur')
plt.show()

'''
There are two reasons limiting our ability to un-blur a photo:
    1. We don't always know the point spread function (PSF).
    2. Even when we approximate the PSF, we can not get arbitrary accuracy
       as we can not divide by very small numbers (or zero) which we get
       from FFT of the PSF.
'''

Ankit Khandelwal_HW4/Exercise 8/exercise 8.py


import numpy as np

def fdaxis(TimeAxis=None,*args,**kwargs):
    '''
    fdaxis, Frequency domain axis
    -----------------------------
    Returns a vector FreqAxis containing the frequency-
    domain axis of the FFT of a N-point time-
    domain vector TimeAxis sampled with period dT.

    This script is freely inspired by the easyspin suite from the Stefan Stoll lab
    (https://github.com/StollLab/EasySpin/)
    (https://easyspin.org/easyspin/)

    Script written by Timothée Chauviré (https://github.com/TChauvire/EPR_ESR_Suite/), 09/09/2020

    Parameters
    ----------
    TimeAxis : time-domain vector TimeAxis, TYPE numpy 1D data array, optional
        DESCRIPTION. The default is None.

    Returns
    -------
    FreqAxis : Frequency axis associated to the input time axis after Fourier Transformation.
        DESCRIPTION.

    '''
    if (TimeAxis.shape[0] != np.ravel(TimeAxis).shape[0]):
        raise ValueError('The file data must be a column vector')
    else:
        TimeAxis = np.ravel(TimeAxis)
    dT=TimeAxis[1] - TimeAxis[0]
    N=len(TimeAxis)
    NyquistFrequency=1/(2*dT)
    UnitAxis=np.multiply(2/N,np.arange(0,N)-np.fix(N/2))
    FreqAxis=NyquistFrequency*UnitAxis
    return FreqAxis


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

def XPx(x,px):
	soma = 0
	sum = 0
	for i in range(len(x)):
		soma += x[i] * px[i]
		sum += px[i]
	print("Soma de P(x) = %.2f" %sum)
	return soma

def VAR(media, x, px):
	var = 0
	for i in range(len(x)):
		sigma = ((media - x[i])**2) * px[i]
		var += sigma
	return var

def DP(var):
	return math.sqrt(var)

def desvio(media, dp):
	min = media - dp
	max = media + dp

	min2 = media - (2*dp)
	max2 = media + (2*dp)

	min3 = media - (3*dp)
	max3 = media + (3*dp)
	print("\n")
	print("Desvio 1 - 68%%   - Min %.2f Max %.2f" %(min, max))
	print("Desvio 2 - 95%%   - Min %.2f Max %.2f" %(min2, max2))
	print("Desvio 3 - 99.7%% - Min %.2f Max %.2f" %(min3, max3))
	return (min, max, min2, max2, min3, max3)

def graph(x, px, media, var, dp, desvio):
	plt.figure(figsize=(8, 6))
	plt.title("[Media  %.2f]   [VAR  %.2f]   [DP  %.2f]" %(media, var, dp))
	#plt.xlabel("X")
	plt.ylabel("P(x)")
	plt.grid(True)

	plt.bar(x, px, color='purple', width=.97, edgecolor='gray')
	m = sum(px) / float(len(px))

	plt.plot(desvio[0:2], [m+(m/2), m+(m/2)], ls='--', color = '#10A0DF', label="68%% Min %.2f Max %.2f"%(desvio[0], desvio[1]))
	plt.plot(desvio[2:4], [m, m], ls='--', color = 'red',  label="95%% Min %.2f Max %.2f"%(desvio[2], desvio[3]))
	plt.plot(desvio[4:6], [(m/2), (m/2)], ls='--', color = '#E68400', label="99.7%% Min %.2f Max %.2f"%(desvio[4], desvio[5]))
	plt.legend()
	plt.show()

x = list(range(-4, 5))
px = [.02, .07, .1, .15, .3, .18, .1, .06, .02]

media = XPx(x, px)
var = VAR(media, x, px)
dp = DP(var)
print("Media - %.2f" %media)
print("VAR - %.2f" %var)
print("DP - %.2f" %dp)

d = desvio(media, dp)
# Descomentar para visualizar o grafico
graph(x, px, media, var, dp, d)


#T# the common multiples of a given set of numbers, are themselves multiples of the least common multiple of said set

#T# to calculate the least common multiple, the numpy package is used
import numpy as np

#T# the lcm function from the numpy package calculates the least common multiple of two numbers
num1 = 8
num2 = 12
num3 = np.lcm(num1, num2) # 24

#T# the reduce function from the lcm module of the numpy package calculates the least common multiple of a set of numbers inside a one dimensional array
arr1 = np.array([2, 5, 2, 1])
num1 = np.lcm.reduce(arr1) # 10


import math
import numpy as np, pandas as pd
from scipy.stats import t
from scipy.stats import norm
import statistics as s
import matplotlib.pyplot as plt

def confidence_intervals():
    np.random.seed(1234)
    replications = 100
    n = 30
    x = range(replications)
    y = np.random.normal(0, 1, size=(replications, n)) # realisations
    alpha = 0.95 # confidence level
    z = t.ppf(1-(1-alpha)/2, n-1) # inverse t distribution
    y_mean = [s.mean(y[r]) for r in range(replications)]
    e = [z*s.stdev(y[r])/math.sqrt(n) for r in range(replications)]
    ec = ['red' if (y_mean[r]+z*s.stdev(y[r])/math.sqrt(n) < 0 or
                    y_mean[r]-z*s.stdev(y[r])/math.sqrt(n) > 0)
                else 'black' for r in range(replications)]
    plt.errorbar(x, y_mean, yerr=e, ecolor=ec, fmt='none')
    plt.grid(True)
    plt.show()

def prediction_intervals_known_parameters():
    np.random.seed(4321)
    replications = 100
    x = range(replications)
    mu, sigma = 10, 2
    y = np.random.normal(mu, sigma, replications) # realisations
    alpha = 0.95 # confidence level
    z = norm.ppf(1-(1-alpha)/2) # inverse standard normal distribution
    plt.plot(x,[mu-z*sigma for k in x], color='blue', linestyle='dashed')
    plt.plot(x,[mu+z*sigma for k in x], color='blue', linestyle='dashed')
    ec = ['red' if y[r]>mu+z*sigma or y[r]<mu-z*sigma
                else 'blue' for r in range(replications)]
    plt.scatter(x, y, color=ec)
    plt.grid(True)
    plt.show()

def prediction_intervals_unknown_parameters():
    np.random.seed(4321)
    replications = 100
    mu, sigma = 10, 2
    x = range(replications)
    y = np.random.normal(mu, sigma, replications) # realisations
    alpha = 0.95 # confidence level
    z = lambda n: t.ppf(1-(1-alpha)/2, n-1) # inverse t distribution
    y_mean = [s.mean(y[0:r+1]) for r in range(replications)]
    e = [z(r-1)*s.stdev(y[0:r+1])*math.sqrt(1+1/r)
        if r > 2 else 30*sigma for r in range(replications)]
    plt.errorbar(x[:-1], y_mean[:-1], yerr=e[:-1], fmt='none')
    ec = ['red' if y[1:][r]>y_mean[:-1][r]+e[:-1][r] or
                y[1:][r]<y_mean[:-1][r]-e[:-1][r]
                else 'blue' for r in range(replications-1)]
    plt.scatter(x[:-1], y[1:], color=ec)
    plt.grid(True)
    plt.show()

def sample_random_walk(X0, realisations):
    np.random.seed(1234)
    errors = np.random.normal(0, 1, realisations)
    Xt = X0
    for e in errors:
        Xt = Xt + e
        yield Xt

def naive(series, t):
    """Forecasts periods t+1, t+2, ... of series
    """
    forecasts = np.empty(len(series))
    forecasts[:t+1] = np.nan
    forecasts[t+1:] = series[t]
    return forecasts

def naive_rolling(series):
    return series.shift(periods=1)

def residuals(realisations, forecasts):
    return realisations - forecasts

def plot(realisations, forecasts, stdev, alpha):
    f = plt.figure(1)
    plt.title("Naïve method")
    plt.xlabel('Period')
    first, last = next(x for x, val in enumerate(forecasts) if ~np.isnan(val)), len(forecasts)-1
    plt.axvspan(first, last, alpha=0.2, color='blue')
    plt.plot(forecasts, "r", label="Naïve forecasts")
    plt.plot(realisations, "b", label="Actual values")
    z = t.ppf(1-(1-alpha)/2, len(realisations)-1) # inverse t distribution
    plt.fill_between(range(first, last+1),
                     [forecasts[first+k]-z*stdev*math.sqrt(k) for k in range(last-first+1)],
                     [forecasts[first+k]+z*stdev*math.sqrt(k) for k in range(last-first+1)],
                     color='r', alpha=0.1)
    plt.legend(loc="upper left")
    plt.grid(True)
    f.show()

def prediction_intervals_naive():
    N, t, window, alpha = 200, 160, 1, 0.95
    realisations = pd.Series(list(sample_random_walk(0, N)), range(N))
    forecasts = naive(realisations, t)
    forecasts_roll = naive_rolling(realisations)
    res = residuals(realisations[window:], forecasts_roll[window:])
    plot(realisations, forecasts, s.stdev(res), alpha)
    print("E[e_t] = "+str(s.mean(res)))
    print("Stdev[e_t] = "+str(s.stdev(res)))
    plt.show()

#confidence_intervals()
#prediction_intervals_known_parameters()
#prediction_intervals_unknown_parameters()
prediction_intervals_naive()


"""
In the DFP example we will search for z=(a, b, c, d)
that minimizes Sum_i || F(z, X_i) - Y_i ||^2
for the function
F(x0, x1) = a^3 + b * x0 + c * x1 + d * (x0^2+x1^2)

Suppose we have the following measurements
X_0 = [0, 1]; Y_0 = 15
X_1 = [1, 0]; Y_1 = 8
X_2 = [1, 1]; Y_2 = 80
X_3 = [3, 4]; Y_3 = 100
X_4 = [1, 15]; Y_4 = 150

subjected to a>=4, c<=30
(we could handle other constraints as well: Ax <= b, Aeq x = beq, c(x) <= 0, h(x) = 0)
"""
from openopt import DFP
from numpy import inf

f = lambda z, X: z[0]**3 + z[1]*X[0] + z[2]*X[1] + z[3]*(X[0]+X[1])**2
df = lambda z, X: [3*z[0]**2, X[0], X[1], (X[0]+X[1])**2]
initEstimation = [0] * 4 # start point for solver: [0, 0, 0, 0]
X = ([0, 1], [1, 0], [1, 1], [3, 4], [1, 15]) # list, tuple, numpy array or array-like are OK as well
Y = [15, 8, 80, 100, 150]
lb = [4, -inf, -inf, -inf]
ub = [inf, inf, 30, inf]
p = DFP(f, initEstimation, X, Y, df = df, lb=lb, ub=ub)

r = p.solve('nlp:ralg', plot=0, iprint = 10)
print('solution: '+str(r.xf)+'\n||residuals||^2 = '+str(r.ff)+'\nresiduals: '+str([f(p.xf, X[i])-Y[i] for i in xrange(len(Y))]))
#solution: [  3.99999936   5.99708861 -12.25696614   1.04221073]
#||residuals||^2 = 5992.63887806
#residuals: [37.785213926923028, 63.039268675751572, -18.091065285780857, -15.968303801844399, 2.9485118103557397]


# Author:       Brian Murphy
# Date started: 07/05/2020
# Last updated: <06/05/2020 05:49:32 (BrianM)>

import numpy as np
import PSO

def find_the_centre_of_a_circle():
    """
    Find the centre of a circle of the form (x-a)^2 + (y-b)^2 = r^2 where x, y and r equal 3, 4 and 5 respectfully

    Example - how to run:
        import demos
        demos.find_the_centre_of_a_circle()

    """
    # Define the cost function
    def circle_cost(positions, args):
        return np.abs(25 - ((3 - positions[0]) ** 2 + (4 - positions[1]) ** 2))

    cost_function = circle_cost

    # Set maximum values of a and b
    varmin = [-1000, -1000]  # a min, b min
    varmax = [1000, 1000]  # a max, b max

    # Create problem dictionary
    problem = {'cost_function': cost_function, 'varmin': varmin, 'varmax': varmax}

    # Create PSO parameters dictionary
    params = {'maxit': 15, 'n_part': 30, 'c1': 2, 'c2': 2, 'w': 0.9, 'wdamp': 0.2, 'con': 1, 'display_info': 1,
              'early_stopping': 1, 'early_stopping_rounds': 7}

    # Run PSO and return lowest cost, a,b values and the costs per iteration
    gbest_value, gbest_position, best_costs = PSO.PSO(problem, params)

    print('Found the centre of the circle as a = %f and b = %f' % (gbest_position[0], gbest_position[1]))
    print('The error was %f' % gbest_value)


import numpy as np

def euclidean(x, y):
    """
    Compute the Euclidean ("L2") distance between two vectors

    :param x: {array-like} 'ndarray <numpy ndarray>' of shape: [vector_length, ]
    :param y: {array-like} 'ndarray <numpy ndarray>' of shape: [vector_length, ]
    :return:  float, the L2 distance between 'x' vector and 'y' vector

    ----------
    Example:
    >>> x = np.array([1, 2, 3, 4, 5])
    >>> y = np.array([6, 7, 8, 9, 10])
    >>> euclidean(x, y)
    11.180339887498949
    """

    return np.sqrt(np.sum((x - y) ** 2))

def manhattan(x, y):
    """
    Compute the Manhattan ('L1') distance between two vectors

    :param x: {array-like} 'ndarray <numpy ndarray>' of shape: [vector_length, ]
    :param y: {array-like} 'ndarray <numpy ndarray>' of shape: [vector_length, ]
    :return:  float, the L1 distance between 'x' vector and 'y' vector

    ----------
    Example:
    >>> x = np.array([1, 2, 3, 4, 5])
    >>> y = np.array([6, 7, 8, 9, 10])
    >>> manhattan(x, y)
    25
    """
    return np.sum(np.abs(x - y))

def chebyshev(x, y):
    """
    Compute the Chebyshev ($$ L_\infty $$ ) distance between two vectors

    :param x: {array-like} 'ndarray <numpy ndarray>' of shape: [vector_length, ]
    :param y: {array-like} 'ndarray <numpy ndarray>' of shape: [vector_length, ]
    :return:  float, the Chebyshev distance between 'x' vector and 'y' vector

    ----------
    Example:
    >>> x = np.array([1, 2, 3, 4, 5])
    >>> y = np.array([6, 7, 8, 9, 10])
    >>> chebyshev(x, y)
    5
    """
    return np.max(np.abs(x - y))

def hamming(x, y):
    """
    Compute the Hamming distance between two integer-valued vectors

    :param x: {array-like} 'ndarray <numpy ndarray>' of shape: [vector_length, ]
    :param y: {array-like} 'ndarray <numpy ndarray>' of shape: [vector_length, ]
    :return:  float, the Hamming distance.

    ----------
    Example:
    >>> x = np.array([1, 2, 3, 4, 5])
    >>> y = np.array([6, 7, 8, 9, 10])
    >>> hamming(x, y)
    1.0
    """
    return np.sum(x != y) / len(x)


import numpy as np
import scipy.stats

'''
log(sum(exp(z))) = M + log(sum(exp(z - M)))
z is a matrix of shape (p, k)
Sum is over k
'''
def log_sum_exponent(z, axis = 1):
    zmax = np.max(z, axis = axis)
    if axis == 0:
        sub_zmax = zmax.reshape(1, -1)
    elif axis == 1:
        sub_zmax = zmax.reshape(-1, 1)
    logsum = np.log(np.sum(np.exp(z - sub_zmax), axis = axis)) + zmax
    return logsum

def logpdf(X, sk, xzero = 1e-4):
    p = X.shape[0]
    k = sk.shape[0]
    delta_logprob_nonzeroX = np.repeat(-5e23, p) # scipy.stats.norm(0, 1e-12).logpdf(1)
    delta_logprob_zeroX = np.repeat(26.7121, p)  # scipy.stats.norm(0, 1e-12).logpdf(0)
    nonzero_Xmask = np.array(np.abs(X) >= xzero, dtype = bool)
    nonzero_smask = np.array(sk != 0, dtype = bool)
    assert (np.sum(~nonzero_smask) <= 1)
    log_prob = np.zeros((p, k))
    if np.sum(~nonzero_smask) == 1:
        log_prob[nonzero_Xmask, ~nonzero_smask] = delta_logprob_nonzeroX[nonzero_Xmask]
        log_prob[~nonzero_Xmask, ~nonzero_smask] = delta_logprob_zeroX[~nonzero_Xmask]
    nzk = np.sum(nonzero_smask)
    nzSK = sk[nonzero_smask].reshape(1, nzk)
    log_prob[:, nonzero_smask]  = - 0.5 * np.square(X.reshape(p, 1) / nzSK)
    log_prob[:, nonzero_smask] += - 0.5 * np.log(2 * np.pi * np.square(nzSK))
    return log_prob

def em_one_step(X, sk, wk, xzero = 1e-4):
    p = X.shape[0]
    k = wk.shape[0]
    nonzero_widx  = np.where(wk != 0)[0]
    logLjk = logpdf(X, sk, xzero = xzero)
    wknew = np.zeros(k)
    logwkLjk = logLjk[:, nonzero_widx] + np.log(wk[nonzero_widx])
    log_partition_func = log_sum_exponent(logwkLjk, axis = 1).reshape(-1, 1)
    log_nonzeroFjk = logwkLjk - log_partition_func
    sum_Fjk = log_sum_exponent(log_nonzeroFjk, axis = 0)
    wknew[nonzero_widx] = np.exp(sum_Fjk) / p
    return wknew

def emfit(X, sk, wk = None,
          max_iter = 1000, tol = 1e-3,
          xzero = 1e-4):
    k = sk.shape[0]
    if wk is None: wk = np.repeat(1/k, k)
    for itr in range(max_iter):
        wknew = em_one_step(X, sk, wk, xzero = xzero)
        diff = np.sum(np.abs(wk - wknew))
        wk = wknew
        if diff <= tol:
            break
    return wk


from mpmath import asin, floor, ellipfun, mp

def jacobi_am_f(x, m):
    """Borrowed from sagemath."""
    ctx = mp
    prec = ctx.prec
    try:
        # print(x)
        # print(m)
        x = ctx.convert(x)
        m = ctx.convert(m)
        if not isinstance(x, ctx.mpf) or not isinstance(m, ctx.mpf):
            raise ValueError("arguments must be real")
        if abs(m) == 1:
            # gd(x)
            ctx.prec += 10
            tanhx = ctx.tanh(x)
            ctx.prec += 10
            return ctx.asin(tanhx)
        elif abs(m) > 1:
            ctx.prec += 10
            # Real values needed for atan2; as per "Handbook of Elliptic
            # Integrals for Engineers and Scientists" 121.02, sn is real for
            # real x. The imaginary components can thus be safely discarded.
            snx = ctx.ellipfun("sn", x, m).real
            cnx = ctx.ellipfun("cn", x, m).real
            ctx.prec += 10
            return ctx.atan2(snx, cnx)
        else:
            ctx.prec += 10
            K = ctx.ellipk(m)
            if abs(x) <= K:
                snx = ctx.ellipfun("sn", x, m).real
                cnx = ctx.ellipfun("cn", x, m).real
                ctx.prec += 10
                return ctx.atan2(snx, cnx)
            else:
                # Do argument reduction on x to end up with z = x - 2nK, with
                # abs(z) <= K
                ctx.prec += 10
                tK = 2 * K
                ctx.prec += 10
                n = ctx.floor(x / tK)
                ctx.prec += 10
                tnK = n * tK
                npi = n * ctx.pi()
                ctx.prec += 10
                z = x - tnK
                ctx.prec += 10
                # z (and therefore sn(z, m) and cn(z, m)) is real because K(m)
                # is real for abs(m) <= 1.
                snz = ctx.ellipfun("sn", z, m).real
                cnz = ctx.ellipfun("cn", z, m).real
                ctx.prec += 10
                return ctx.atan2(snz, cnz) + npi
    finally:
        ctx.prec = prec

def am(x, m):
    """
    Jacobi amplitude function for real input parameters

    (JacobiAmplitude[] in Mathematica)

    Parameters:
        x (float)
        m (float)

    Returns:
        am (float)
    """
    if m == 0:
        return x
    elif x == 0:
        return 0
    else:
        return jacobi_am_f(x, m)


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

def calc_e_small(x):
    n = 10
    f = np.arange(1, n+1).cumprod()
    b = np.array([x]*n).cumprod()
    return np.sum(b / f) + 1

def calc_e(x):
    reverse = False
    if x < 0:                           #处理负数
        x = -x
        reverse = True
    ln2 = 0.69314718055994530941723212145818
    c = x / ln2
    a = int(c + 0.5)
    b = x - a * ln2
    y = (2 ** a) * calc_e_small(b)
    if reverse:
        return 1 / y
    return y

if __name__ == "__main__":
    t1 = np.linspace(-2, 0, 10, endpoint= False)
    t2 = np.linspace(0, 2, 20)
    t = np.concatenate((t1, t2))
    print(t1)
    print(t2)
    print(t)                             #横轴数据
    y = np.empty_like(t)
    for i, x in enumerate(t):
        y[i] = calc_e(x)
        print( 'e^', x, '=', y[i], '(近似值)\t', math.exp(x))
        # print '误差' , y[i] - math.exp(x)

    mpl.rcParams['font.sans-serif'] = [u'SimHei']
    mpl.rcParams['axes.unicode_minus'] = False
    plt.plot(t, y, 'r-', t, y, 'go', linewidth = 2)
    plt.title(u'Taylor展式的应用', fontsize = 18)
    plt.xlabel('x', fontsize = 15)
    plt.ylabel('exp(x)', fontsize = 15)
    plt.grid(True)
    plt.show()


#!/usr/bin/env python

import sys
import time
import math
import numpy
import random
import scipy.linalg

#=================
def ellipsePoints(angleinc, center, a, b, alpha):
	'''
	Generate a sequence of x,y points given the parameters of an
	ellipse, and an angular increment.

	convention note: ellipse points are created as x,y coordinates, so alpha
		is measured as positive values towards the y-axis

	note: generate_ellipse() below is a faster version of this
	'''
	cosa = numpy.cos(alpha)
	sina = numpy.sin(alpha)
	points = []
	for angle in numpy.arange(0, 2*numpy.pi, angleinc):
		acosangle = a * numpy.cos(angle)
		bsinangle = b * numpy.sin(angle)
		row = center[0] + acosangle * cosa - bsinangle * sina
		col = center[1] + acosangle * sina + bsinangle * cosa
		points.append((row,col))
	return points

#=================
def ellipseKeyPoints(center, a, b, alpha):
	'''
	Calulate the points at each end of the ellipse axes.

	convention note: ellipse points are created as x,y coordinates, so alpha
		is measured as positive values towards the y-axis
	'''
	points = ellipsePoints(numpy.pi/2.0, center, a, b, alpha)
	keypoints = {}
	center = tuple(center)
	keypoints[center] = {'axis': 'center', 'angle': None}
	axes = ['a','b']
	for i in range(4):
		axis = axes[i%2]
		angle = alpha+i*numpy.pi/2.0
		while angle < 0:
			angle += 2*numpy.pi
		keypoints[points[i]] = {'axis': axis, 'angle': angle}
	return keypoints

#=================
def drawEllipse(shape, angleinc, center, a, b, alpha):
	'''
	Generate a zero initialized image array with an ellipse drawn
	by setting pixels to 1.

	convention note: ellipse points are x,y coordinates, so alpha
		is measured as positive values towards the y-axis
	'''
	result = numpy.zeros(shape, numpy.int)
	points = ellipsePoints(angleinc, center, a, b, alpha)
	for point in points:
		point = map(int, point)
		try:
			result[int(point[0]), int(point[1])] = 1
		except:
			continue
	return result

#=================
def algebraic2parametric(coeff):
	'''
	Based on matlab function "ellipse_param.m" which accompanies
	"Least-Squares Fitting of Circles and Ellipses", W. Gander, G. H. Golub, R. Strebel,
		BIT Numerical Mathematics, Springer 1994

	convert the coefficients (a,b,c,d,e,f) of the algebraic equation:
		ax^2 + bxy + cy^2 + dx + ey + f = 0
	to the parameters of the parametric equation.  The parameters are
	returned as a dictionary containing:
		center - center of the ellipse
		a - major axis
		b - minor axis
		alpha - angle of major axis

	convention note: alpha is measured as positive values towards the y-axis
	'''
	#print coeff
	#print ("A=%.3f B=%.3f C=%.3f D=%.3f E=%.3f F=%.3f"
	#	%(coeff[0], coeff[1], coeff[2], coeff[3], coeff[4], coeff[5],))

	if numpy.any(numpy.isnan(coeff)) or numpy.any(numpy.isinf(coeff)):
		return None

	A   = numpy.array((coeff[0], coeff[1]/2, coeff[1]/2, coeff[2]))
	A.shape = 2,2
	bb  = numpy.asarray(coeff[3:5])
	c   = coeff[5]

	D,Q = scipy.linalg.eig(A)
	D = D.real
	det = D[0]*D[1]
	if det <= 0:
		return None
	else:
		bs = numpy.dot(Q.transpose(), bb)
		alpha = numpy.arctan2(Q[1,0], Q[0,0])

		zs = scipy.linalg.solve(-2*numpy.diagflat(D), bs)
		z = numpy.dot(Q, zs)
		h = numpy.dot(-bs.transpose(), zs) / 2 - c

		a = numpy.sqrt(h/D[0])
		b = numpy.sqrt(h/D[1])

	## correct backwards major/minor axes
	## 'major axis as a, minor axis as b'
	if b > a:
		temp = b
		b = a
		a = temp
		alpha = math.pi/2 + alpha

	#print "alpha", alpha
	if alpha <= -math.pi/2:
		alpha += math.pi
	elif alpha > math.pi/2:
		alpha -= math.pi

	return {'center':z, 'a':a, 'b':b, 'alpha':alpha}

#=================
def solveEllipseB2AC(points):
	'''
	Based on Matlab code from:  "Direct Least Square Fitting of Ellipses"
	Andrew Fitzgibbon, Maurizio Pilu, Robert B. Fisher.  Tern Analysis
	and Machine Intelligence, Vol 21, No 5, May 1999.

	This method has a tendency to crash, but is very fast
	probably should use QR decomposition to avoid crashing on singularities

	convention note: ellipse points are x,y coordinates, so alpha
		is measured as positive values towards the y-axis
	'''
	X = numpy.array(points, numpy.float)
	D = numpy.column_stack((X[:,0]**2, X[:,0]*X[:,1], X[:,1]**2, X[:,0], X[:,1], numpy.ones(X.shape[0])))
	S = numpy.dot(D.transpose(), D)
	C = numpy.zeros((6,6), numpy.float)
	C[0,2] = -2
	C[1,1] = 1
	C[2,0] = -2
	### replace eig with QR decomp
	geval,gevec = scipy.linalg.eig(a=S, b=C)
	geval = geval.real
	gevec = gevec.real

	Neg = numpy.nonzero(numpy.logical_and(geval<0, numpy.logical_not(numpy.isinf(geval))))
	a = gevec[:,Neg]
	a = numpy.ravel(a)

	if len(a) == 0:
		return None
	return algebraic2parametric(a)

##========================
##========================
def solveEllipseByQRdecomp(points, center=(0,0)):
	"""
	QR decomposition is not the fastest method
	but it is by far the most stable
	"""
	t0 = time.time()
	xy = numpy.array(points, dtype=numpy.float64) - numpy.array(center, dtype=numpy.float64)
	X = numpy.column_stack((
			xy[:,0]**2,
			xy[:,0]*xy[:,1],
			xy[:,1]**2,
		))
	Y = numpy.ones(xy.shape[0])
	### solve it by QR decomposition
	Q, R = numpy.linalg.qr(X)
	if numpy.linalg.det(R) == 0:
		print "Singular matrix in calculation"
		return None
	QT = numpy.transpose(Q)
	Rinv = numpy.linalg.inv(R)
	beta = numpy.dot(numpy.dot(Rinv, QT), Y)

	algebraic = (beta[0], beta[1], beta[2], 0, 0, -1)

	params = algebraic2parametric(algebraic)
	if params is None:
		return None

	params['center'] = center

	return params

##========================
def weightedLeastSquares(X, Y, W):
	"""
	solve using the normal equations with no manipulation
	"""
	### solve it
	XTW = numpy.transpose(X)*W
	XTWX = numpy.dot(XTW, X)
	if numpy.linalg.det(XTWX) == 0:
		print "Singular matrix in calculation"
		return None
	XTWXinv = numpy.linalg.inv(XTWX)
	beta = numpy.dot(numpy.dot(XTWXinv, XTW), Y)
	return beta

#=================
def totalLeastSquareEllipse(points, center=(0,0), weights=None, epsilon=1e-5, maxiter=10):
	'''
	This was implemented by Neil Voss

	uses simple linear least squares to solve the general equation for
	an ellipse, but implements the total least squares algorithm.

	http://en.wikipedia.org/wiki/Total_least_squares

	total least squares assumes some points are better than others
	so it uses an iterative approach to
	down weight points with higher fit error
	and points with smaller error are weighed higher

	takes a (N,2) numpy array containing ellipse points and
	return the best least square fit for an ellipse
	values A,B,C
	where
	Ax^2 + Bxy +Cy^2 + Dx + Ey + F = 0
	D = E = 0 to center the ellipse on the origin
	F = -1 to force the general conic equation to be an ellipse

	convention note: ellipse points are x,y coordinates, so alpha
		is measured as positive values towards the y-axis
	'''
	t0 = time.time()
	xy = numpy.array(points, dtype=numpy.float64) - numpy.array(center, dtype=numpy.float64)
	X = numpy.column_stack((
			xy[:,0]**2,
			xy[:,0]*xy[:,1],
			xy[:,1]**2,
		))
	Y = numpy.ones(xy.shape[0])

	### setup weights if necessary
	W = weights
	if W is None:
		W = numpy.ones(Y.shape) # even weights for the observations

	### solve it
	sys.stderr.write("total least squares")
	err0 = None
	for i in range(maxiter):
		sys.stderr.write(".")
		beta = weightedLeastSquares(X, Y, W)
		if beta is None:
			return None

		## calculate the absolute mean error
		err = numpy.absolute(numpy.dot(X, beta) - Y).ravel()
		#print "totalLeastSquares iter %d error: %.4f"%(i, err.mean())
		## fit to a normal distribution
		normerr = ( err - err.min() )/err.std()
		## calculate new weights based on
		W = numpy.exp( -1 * normerr**2 )
		if W.sum() == 0:
			apDisplay.printWarning("Failed to set weights")
			return beta
		## see if we can stop
		if err0 is not None:
			change = numpy.absolute(err-err0).mean()
			if change < epsilon:
				break
		err0 = err

	algebraic = (beta[0], beta[1], beta[2], 0, 0, -1)

	params = algebraic2parametric(algebraic)
	if params is None:
		return None

	params['center'] = center

	return params

#=================
def solveEllipseGander(points):
	'''
	Solve the ellipse that best fits the given points.
	Based on the matlab function "algellipse.m" in the files that
	accompany:  "Least-Squares Fitting of Circles and Ellipses", W. Gander, G. H. Golub, R. Strebel,
		BIT Numerical Mathematics, Springer 1994

	This method seems to go O(n^2), so can be slow with lots of points

	convention note: ellipse points are x,y coordinates, so alpha
		is measured as positive values towards the y-axis
	'''
	X = numpy.array(points)
	a = numpy.column_stack((X[:,0]**2, X[:,0]*X[:,1], X[:,1]**2, X[:,0], X[:,1], numpy.ones(X.shape[0])))
	U, S, Vh = scipy.linalg.svd(a)
	V = Vh.transpose()
	u = numpy.ravel(V[:,5:6])
	return algebraic2parametric(u)

#=================
def solveEllipseOLS(points, center=(0,0)):
	"""
	Solve Ellipse using oridinary least squares (OLS) closed form equation

	Note: this method is designed to have the center to be 0,0
		because the CTF is always centered

	This was implemented by Neil Voss for use in the ACE2 program in 2010
	* Algebra was performed using the maxima program
	* Designed to have a fixed center point

	takes a (N,2) numpy array containing ellipse points and
	return the best least square fit for an ellipse
	values A,B,C
	where
	Ax^2 + Bxy +Cy^2 + Dx + Ey + F = 0
	D = E = 0 to center the ellipse on the origin
	F = -1 to force the general conic equation to be an ellipse

	convention note: ellipse points are x,y coordinates, so alpha
		is measured as positive values towards the y-axis
	"""

	### power twos
	X = numpy.array(points, numpy.float) - numpy.array(center, numpy.float)

	### power twos
	p2 = numpy.power(X, 2.0)
	Sx2 = p2[:,0].sum()
	Sy2 = p2[:,1].sum()
	Sxy = (X[:,0]*X[:,1]).sum()
	### power fours
	p4 = numpy.power(X, 4.0)
	Sx4 = p4[:,0].sum()
	Sy4 = p4[:,1].sum()
	Sx2y2 = (p2[:,0]*p2[:,1]).sum()
	Sx3y = (numpy.power(X[:,0], 3.0)*X[:,1]).sum()
	Sxy3 = (X[:,0]*numpy.power(X[:,1], 3.0)).sum()

	### Calculate ellipse parameters
	A = (Sx3y*(Sxy3*Sy2-Sxy*Sy4)+Sx2y2*(Sx2*Sy4+Sxy*Sxy3)
		-numpy.power(Sx2y2,2.0)*Sy2-Sx2*numpy.power(Sxy3,2.0))/(Sx4*(Sx2y2*Sy4-numpy.power(Sxy3,2.0))
		-numpy.power(Sx3y,2.0)*Sy4+2.0*Sx2y2*Sx3y*Sxy3-numpy.power(Sx2y2,3.0));

	B = -(Sx4*(Sxy3*Sy2-Sxy*Sy4)+Sx3y*(Sx2*Sy4-Sx2y2*Sy2)-Sx2*Sx2y2*Sxy3
		+numpy.power(Sx2y2,2.0)*Sxy)/(Sx4*(Sx2y2*Sy4-numpy.power(Sxy3,2.0))
		-numpy.power(Sx3y,2.0)*Sy4+2.0*Sx2y2*Sx3y*Sxy3-numpy.power(Sx2y2,3.0));

	C = (Sx4*(Sx2y2*Sy2-Sxy*Sxy3)-numpy.power(Sx3y,2.0)*Sy2+Sx3y*(Sx2*Sxy3+Sx2y2*Sxy)
		-Sx2*numpy.power(Sx2y2,2.0))/(Sx4*(Sx2y2*Sy4-numpy.power(Sxy3,2.0))
		-numpy.power(Sx3y,2.0)*Sy4+2.0*Sx2y2*Sx3y*Sxy3-numpy.power(Sx2y2,3.0));

	algebraic = (A, B, C, 0, 0, -1)

	params = algebraic2parametric(algebraic)
	if params is None:
		return None

	params['center'] = center

	return params

#=================
def generate_ellipse(a, b, alpha, center=(0,0), numpoints=3, noise=None,
		method="step", integers=False):
	"""
	a - major axis radius
	b - minor axis radius
	alpha - angle (in radians)
	center = x0,y0 - position of center of ellipse
	numpoints - # of points that make an ellipse
	noise - float of the amount of noise to add

	this is a faster version of ellipsePoints() function above
		without the "for" loop and with extra features

	convention note: ellipse points are created as x,y coordinates, so alpha
		is measured as positive values towards the y-axis
	"""

	cosa = numpy.cos(alpha)
	sina = numpy.sin(alpha)

	if method == "step":
		thetas = numpy.linspace(0, 2*math.pi, numpoints)
	elif method == "random":
		thetas = numpy.random.random(numpoints) * 2*math.pi
	else:
		print "unknown method", method
		return None
	rows = center[0] + a* numpy.cos(thetas) * cosa -  b* numpy.sin(thetas) * sina
	cols = center[1] + a* numpy.cos(thetas) * sina +  b* numpy.sin(thetas) * cosa

	points = numpy.vstack((rows,cols)).T
	#print points[:5,:]

	if noise is not None:
		rand = numpy.random.standard_normal(points.shape)
		points += rand * noise
	#print points[0]

	## use only integers
	if integers is True:
		points = numpy.array(numpy.around(points, 0), dtype=numpy.int)
	#print points[0]
	#print points[:5,:]

	return points

#=================
def printParamsDict(params):
	printParams(params['center'], params['a'], params['b'], params['alpha'])
	return

#=================
def printParams(center, a, b, alpha):
	print ("%.3f %.3f < %.2f (%.1f, %.1f)"%
		(a, b, alpha*180/math.pi, center[0], center[1]))
	return

"""
Speed and accuracy notes:

NumPoints = 3777 ; Noise = 0.1 pixels
orig   5.829 1.737 < -76.84 (4.0, 16.0)
b2ac   5.813 1.747 < -76.83 (4.0, 16.0)
gander 5.834 1.740 < -76.60 (4.0, 16.0)
ols    5.833 1.753 < -76.83 (4.0, 16.0)

b2ac   complete in 8.585 millisec  ** crashes sometimes
gander complete in 924.305 millisec ** way too slow for more than 500 points
ols    complete in 5.268 millisec ** has fixed center
"""

### test code
if __name__ == '__main__':
	## randomly generate a noisy ellipse
	# note: center is (col,row) i.e. (x,y) while shape is (row,col)
	xdim = numcol = 32
	ydim = numrow = 16
	shape = (numrow,numcol)
	alpha = random.random()*math.pi - math.pi/2
	center = numpy.array((numrow, numcol), dtype=numpy.float)/2.0
	majormax = min( abs(numrow/math.cos(alpha)) , abs(numcol/math.sin(alpha)) )/3.0 - 1
	minormax = min( abs(numrow/math.sin(alpha)) , abs(numcol/math.cos(alpha)) )/3.0 - 1
	print alpha, majormax, minormax
	major = (majormax-2) * random.random() + 2
	minor = (min(minormax,major)-1) * random.random() + 1
	numpoints = 8 + int(100000*random.random()*random.random()*random.random())
	noise = 0.2 #random.random()
	print "NumPoints = %d ; Noise = %.1f"%(numpoints, noise)
	printParams(center, major, minor, alpha)

	### draw real ellipse
	points = generate_ellipse(major, minor, alpha, center, numpoints,
		noise, method="step", integers=False)
	params = {'center':center, 'a':major, 'b':minor, 'alpha':alpha}
	grid = numpy.zeros(shape, dtype=numpy.int)
	intpoints = numpy.array(points, dtype=numpy.int)
	print intpoints
	grid[intpoints[:,0], intpoints[:,1]] = 1
	#for point in points:
	#	p = numpy.floor(point)
	#	grid[p[0],p[1]] = 1
	print grid
	print ""

	print drawEllipse(shape, 4*numpy.pi/180.0, **params)

	### draw b2ac ellipse
	t0 = time.time()
	params1 = solveEllipseB2AC(points)
	print '\nB2AC', params1
	if params1 is not None:
		print drawEllipse(shape, 4*numpy.pi/180.0, **params1)
	b2actime = time.time() - t0

	### draw gander ellipse
	t0 = time.time()
	if numpoints < 10000:
		params2 = solveEllipseGander(points)
		print '\nGANDER', params2
		print drawEllipse(shape, 4*numpy.pi/180.0, **params2)
	else:
		print "skipping GANDER"
		params2 = None
	gandertime = time.time() - t0

	### draw ols ellipse
	t0 = time.time()
	params3 = solveEllipseOLS(points, center)
	print '\nORDINARY LEAST SQUARES', params3
	print drawEllipse(shape, 4*numpy.pi/180.0, **params3)
	olstime = time.time() - t0

	### draw QR ellipse
	t0 = time.time()
	params4 = solveEllipseByQRdecomp(points, center)
	print '\nQR DECOMP', params4
	if params4 is not None:
		print drawEllipse(shape, 4*numpy.pi/180.0, **params4)
	qrdecomp = time.time() - t0

	### draw Total Least Squares ellipse
	t0 = time.time()
	params5 = totalLeastSquareEllipse(points, center)
	print '\nTotal Least Squares', params5
	if params5 is not None:
		print drawEllipse(shape, 4*numpy.pi/180.0, **params5)
	totallsq = time.time() - t0

	print majormax, minormax
	print "NumPoints = %d ; Noise = %.1f"%(numpoints, noise)
	print "Actual values"
	printParams(center, major, minor, alpha)
	print "Fit values"
	if params1 is not None:
		printParams(**params1)
	else:
		print "b2ac failed"
	if params2 is not None:
		printParams(**params2)
	else:
		print "gander skipped"
	printParams(**params3)
	if params4 is not None:
		printParams(**params4)
	else:
		print "qr decomp failed"
	if params5 is not None:
		printParams(**params5)
	else:
		print "total lsq failed"
	print "b2ac   complete in %.3f millisec"%(b2actime*1000)
	print "gander complete in %.3f millisec"%(gandertime*1000)
	print "ols    complete in %.3f millisec"%(olstime*1000)
	print "qr     complete in %.3f millisec"%(qrdecomp*1000)
	print "total  complete in %.3f millisec"%(totallsq*1000)


import random as ra
import numpy as np
import math

simulations = 10000
runs = 10
final_counts = []

#Lenght of the line segment is 2 *sqrt( radius^2 - distance^2 )

for j in range(runs):
    count = 0
    actual_count = 0
    for i in range(simulations):

        x_0 = (ra.random()*100) - 50
        y_0 = (ra.random()*100) - 50
        tita = (ra.random() * math.pi) - (math.pi/2)
        m = math.tan(tita)
        distance = abs((y_0 - m * x_0) / (math.sqrt(m**2 + 1)))

        if distance < 1:
            actual_count += 1
            length = 2 * math.sqrt(1 - distance**2)
            if length > math.sqrt(3):
                count += 1
    final_counts.append(count/actual_count)

print(" The probability is ", np.mean(final_counts))


from sympy import ( symbols, solve, diff, integrate, exp, sqrt, lambdify, Integral, ln, pprint, oo )
# Researchers have shown that the number of successive dry days that occur after a rainstorm for a particular region is a random variable that is distributed exponentially with a mean of 9 days
mu = 9

t = symbols( 't' )
a = 1/mu
pdf = a * exp( -a*t )

# What is the probability that 11 or more successive dry days occur after a rainstorm?

prob = integrate( pdf, ( t, 11, oo ) ).doit()
round( prob, 4 )

# What is the probability that fewer than 4 dry days occur after a rainstorm?

prob = integrate( pdf, ( t, 0, 2 ) ).doit()
round( prob, 4 )


import os

""" First change the following directory link to where all input files do exist """

os.chdir("D:\Book writing\Codes\Chapter 1")

import numpy as np
from scipy import stats

data = np.array([4,5,1,2,7,2,6,9,3])

# Calculate Mean
dt_mean = np.mean(data) ; print ("Mean :",round(dt_mean,2))

# Calculate Median
dt_median = np.median(data) ; print ("Median :",dt_median)

# Calculate Mode
dt_mode =  stats.mode(data); print ("Mode :",dt_mode[0][0])

# Deviance calculations

import numpy as np
from statistics import variance,stdev

game_points = np.array([35,56,43,59,63,79,35,41,64,43,93,60,77,24,82])

# Calculate Variance
dt_var = variance(game_points) ; print ("Sample variance:", round(dt_var,2))

# Calculate Standard Deviation
dt_std = stdev(game_points) ; print ("Sample std.dev:",round(dt_std,2))

# Calculate Range
dt_rng = np.max(game_points,axis=0) - np.min(game_points,axis=0) ; print ("Range:",dt_rng)

#Calculate percentiles
print ("Quantiles:")
for val in [20,80,100]:
    dt_qntls = np.percentile(game_points,val)
    print (str(val)+"%" ,dt_qntls)

# Calculate IQR
q75, q25 = np.percentile(game_points, [75 ,25]); print ("Inter quartile range:",q75-q25 )

# Hypothesis testing
#import scipy

from scipy import stats

xbar = 990; mu0 = 1000; s = 12.5; n = 30
# Test Statistic
t_smple  = (xbar-mu0)/(s/np.sqrt(float(n))); print ("Test Statistic:",round(t_smple,2))
# Critical value from t-table
alpha = 0.05
t_alpha = stats.t.ppf(alpha,n-1); print ("Critical value from t-table:",round(t_alpha,3))
#Lower tail p-value from t-table
p_val = stats.t.sf(np.abs(t_smple), n-1); print ("Lower tail p-value from t-table", p_val)

# Normal Distribution
from scipy import stats
xbar = 67; mu0 = 52; s = 16.3

# Calculating z-score
z = (67-52)/16.3

# Calculating probability under the curve
p_val = 1- stats.norm.cdf(z)
print ("Prob. to score more than 67 is ",round(p_val*100,2),"%")

# Chi-square independence test
import pandas as pd
from scipy import stats

survey = pd.read_csv("survey.csv")
# Tabulating 2 variables with row & column variables respectively
survey_tab = pd.crosstab(survey.Smoke, survey.Exer, margins = True)
# Creating observed table for analysis
observed = survey_tab.ix[0:4,0:3]

contg = stats.chi2_contingency(observed= observed)
p_value = round(contg[1],3)
print ("P-value is: ",p_value)

#ANOVA
import pandas as pd
from scipy import stats

fetilizers = pd.read_csv("fetilizers.csv")

one_way_anova = stats.f_oneway(fetilizers["fertilizer1"], fetilizers["fertilizer2"], fetilizers["fertilizer3"])

print ("Statistic :", round(one_way_anova[0],2),", p-value :",round(one_way_anova[1],3))

# Train & Test split
import pandas as pd
from sklearn.model_selection import train_test_split

original_data = pd.read_csv("mtcars.csv")

train_data,test_data = train_test_split(original_data,train_size = 0.7,random_state=42)

# Linear Regressio vs. Gradient Descent

import numpy as np
import pandas as pd

train_data = pd.read_csv("mtcars.csv")

X = np.array(train_data["hp"])  ; y = np.array(train_data["mpg"])
X = X.reshape(32,1); y = y.reshape(32,1)

from sklearn.linear_model import LinearRegression
model = LinearRegression(fit_intercept = True)

model.fit(X,y)
print ("Linear Regression Results")
print ("Intercept",model.intercept_[0] ,"Coefficient",model.coef_[0])

def gradient_descent(x, y,learn_rate, conv_threshold,batch_size,max_iter):
    converged = False
    iter = 0
    m = batch_size

    t0 = np.random.random(x.shape[1])
    t1 = np.random.random(x.shape[1])

    MSE = (sum([(t0 + t1*x[i] - y[i])**2 for i in range(m)])/ m)

    while not converged:
        grad0 = 1.0/m * sum([(t0 + t1*x[i] - y[i]) for i in range(m)])
        grad1 = 1.0/m * sum([(t0 + t1*x[i] - y[i])*x[i] for i in range(m)])

        temp0 = t0 - learn_rate * grad0
        temp1 = t1 - learn_rate * grad1

        t0 = temp0
        t1 = temp1

        MSE_New = (sum( [ (t0 + t1*x[i] - y[i])**2 for i in range(m)] ) / m)

        if abs(MSE - MSE_New ) <= conv_threshold:
            print ('Converged, iterations: ', iter)
            converged = True

        MSE = MSE_New
        iter += 1

        if iter == max_iter:
            print ('Max interactions reached')
            converged = True

    return t0,t1

if __name__ == '__main__':
    Inter, Coeff = gradient_descent(x = X,y = y,learn_rate=0.00003 ,conv_threshold=1e-8, batch_size=32,max_iter=1500000)
    print ("Gradient Descent Results")
    print (('Intercept = %s Coefficient = %s') %(Inter, Coeff))

# Train Validation Test split

import pandas as pd
from sklearn.model_selection import train_test_split

original_data = pd.read_csv("mtcars.csv")

def data_split(dat,trf = 0.5,vlf=0.25,tsf = 0.25):
    nrows = dat.shape[0]
    trnr = int(nrows*trf)
    vlnr = int(nrows*vlf)

    tr_data,rmng = train_test_split(dat,train_size = trnr,random_state=42)
    vl_data, ts_data = train_test_split(rmng,train_size = vlnr,random_state=45)

    return (tr_data,vl_data,ts_data)

train_data, validation_data, test_data = data_split(original_data,trf=0.5,vlf=0.25,tsf=0.25)

# Grid search on Decision Trees
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.metrics import classification_report,confusion_matrix,accuracy_score
from sklearn.pipeline import Pipeline

input_data = pd.read_csv("ad.csv",header=None)

X_columns = set(input_data.columns.values)
y = input_data[len(input_data.columns.values)-1]
X_columns.remove(len(input_data.columns.values)-1)
X = input_data[list(X_columns)]

X_train, X_test,y_train,y_test = train_test_split(X,y,train_size = 0.7,random_state=33)

pipeline = Pipeline([
    ('clf', DecisionTreeClassifier(criterion='entropy'))
])
parameters = {
    'clf__max_depth': (50,100,150),
    'clf__min_samples_split': (2, 3),
    'clf__min_samples_leaf': (1, 2, 3)
}

grid_search = GridSearchCV(pipeline, parameters, n_jobs=-1, verbose=1, scoring='accuracy')
grid_search.fit(X_train, y_train)

y_pred = grid_search.predict(X_test)

print ('\n Best score: \n', grid_search.best_score_)
print ('\n Best parameters set: \n')
best_parameters = grid_search.best_estimator_.get_params()
for param_name in sorted(parameters.keys()):
    print ('\t%s: %r' % (param_name, best_parameters[param_name]))
print ("\n Confusion Matrix on Test data \n",confusion_matrix(y_test,y_pred))
print ("\n Test Accuracy \n",accuracy_score(y_test,y_pred))
print ("\nPrecision Recall f1 table \n",classification_report(y_test, y_pred))

Chapter01/Chapter 01_Journey from Statistics to Machine Learning.py


import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
import matplotlib.pyplot as plt

# Data preprocessing
data = pd.read_csv("data.csv")

# Converting Pandas dataframe to numpy array
X = data.x.values.reshape(-1, 1)
Y = data.y.values.reshape(-1, 1)

# Polynomial Features
# (simply add x^2 values to the array as a new column)
"""
# you can do that by yourself just add new column (x^2 values) to X
x2 = X**2
X = np.append(X, x2, axis=1)
"""
poly_reg = PolynomialFeatures(degree=2)  #  Change degree and see what happens
X_poly = poly_reg.fit_transform(X)

# Model Intialization (RBF kernel)
reg = LinearRegression()
# Data Fitting to SVR Model
reg = reg.fit(X_poly, Y)
# Predicted Values
Y_pred = reg.predict(X_poly)

# Model Evaluation
def rmse(Y, Y_pred):
    rmse = np.sqrt(sum((Y - Y_pred) ** 2) / Y.shape[0])
    return rmse

def r2_score(Y, Y_pred):
    mean_y = np.mean(Y)
    ss_tot = sum((Y - mean_y) ** 2)
    ss_res = sum((Y - Y_pred) ** 2)
    r2 = 1 - (ss_res / ss_tot)
    return r2

# Print Scores
print("RMSE = ", rmse(Y, Y_pred))
print("R2 Score = ", r2_score(Y, Y_pred))

# Visualization
# Ploting Line
plt.plot(X, Y_pred, color='#c93e4e', label='Regression Line')
# Ploting Scatter Points
plt.scatter(X, Y, c='#54a774', label='Scatter Plot')
plt.xlabel('Size')
plt.ylabel('Price')
plt.legend()
plt.show()


from pyomo.environ import exp, log, tanh

def softplus_activation_function(x):
    r"""
    Applies the softplus function.

    .. math::

        \begin{align*}
        y &= log(exp(\hat x) + 1)
        \end{align*}

    """
    return log(exp(x) + 1)

def sigmoid_activation_function(x):
    r"""
    Applies the sigmoid function.

    .. math::

        \begin{align*}
        y &= \frac{1}{1 + exp(-\hat x)}
        \end{align*}

    """
    return 1 / (1 + exp(-x))

def tanh_activation_function(x):
    r"""
    Applies the tanh function.

    .. math::

        \begin{align*}
        y &= tanh(x)
        \end{align*}

    """
    return tanh(x)

def softplus_activation_constraint(net_block, net, layer_block, layer):
    r"""
    Softplus activation constraint generator

    Generates the constraints for the softplus activation function.

    .. math::

        \begin{align*}
        z_i &= log(exp(\hat z_i) + 1) && \forall i \in N
        \end{align*}

    """
    return smooth_monotonic_activation_constraint(net_block, net, layer_block, layer, softplus_activation_function)

def sigmoid_activation_constraint(net_block, net, layer_block, layer):
    r"""
    Sigmoid activation constraint generator

    Generates the constraints for the sigmoid activation function.

    .. math::

        \begin{align*}
        z_i &= \frac{1}{1 + exp(-\hat z_i)} && \forall i \in N
        \end{align*}

    """
    return smooth_monotonic_activation_constraint(net_block, net, layer_block, layer,
                                                  sigmoid_activation_function)

def tanh_activation_constraint(net_block, net, layer_block, layer):
    r"""
    tanh activation constraint generator

    Generates the constraints for the tanh activation function.

    .. math::

        \begin{align*}
        z_i &= tanh(\hat z_i) && \forall i \in N
        \end{align*}

    """
    return smooth_monotonic_activation_constraint(net_block, net, layer_block, layer, tanh_activation_function)

def smooth_monotonic_activation_constraint(net_block, net, layer_block, layer, fcn):
    r"""
    Activation constraint generator for a smooth monotonic function

    Generates the constraints for the activation function fcn if it
    is smooth and monotonic

    .. math::

        \begin{align*}
        z_i &= fcn(\hat z_i) && \forall i \in N
        \end{align*}

    """
    @layer_block.Constraint(layer.output_indexes)
    def _smooth_monotonic_activation_constraint(b, *output_index):
        zhat_lb, zhat_ub = b.zhat[output_index].bounds
        if zhat_lb is not None:
            b.z[output_index].setlb(fcn(zhat_lb))
        if zhat_ub is not None:
            b.z[output_index].setub(fcn(zhat_ub))
        return b.z[output_index] == fcn(b.zhat[output_index])


import numpy as np
import scipy.integrate as spi
import matplotlib.pyplot as plt

#t is the independent variable
P = 3. #period value
BT=-6. #initian value of t (begin time)
ET=6. #final value of t (end time)
FS=1000 #number of discrete values of t between BT and ET

#the periodic real-valued function f(t) with period equal to P
f = lambda t: ((t % P) - (P / 2.)) ** 3

#all discrete values of t in the interval from BT and ET
t_range = np.linspace(BT, ET, FS)
y_true = f(t_range) #the true f(t)

#function to integrate on complex field
def complex_quad(func, a, b, **kwargs):
    def real_func(x):
        return np.real(func(x))
    def imag_func(x):
        return np.imag(func(x))
    real_integral = spi.quad(real_func, a, b, **kwargs)
    imag_integral = spi.quad(imag_func, a, b, **kwargs)
    integral = (real_integral[0] + 1j*imag_integral[0], real_integral[1:], imag_integral[1:])
    return integral

#function that computes the complex fourier coefficients c-N,.., c0, .., cN
def compute_complex_fourier_coeffs(func, N):
    result = []
    for n in range(-N, N+1):
        cn = (1./P) * complex_quad(lambda t: func(t) * np.exp(-1j * 2 * np.pi * n * t / P), 0, P)[0]
        result.append(cn)
    return np.array(result)

#function that computes the complex form Fourier series using cn coefficients
def fit_func_by_fourier_series_with_complex_coeffs(t, C):
    result = 0. + 0.j
    L = int((len(C) - 1) / 2)
    for n in range(-L, L+1):
        c = C[n+L]
        result +=  c * np.exp(1j * 2. * np.pi * n * t / P)
    return result

maxN=8
COLs = 2 #cols of plt
ROWs = 1 + (maxN-1) // COLs #rows of plt
plt.rcParams['font.size'] = 8
fig, axs = plt.subplots(ROWs, COLs)
fig.tight_layout(rect=[0, 0, 1, 0.95], pad=3.0)
fig.suptitle('f(t) = ((t % P) - (P / 2.)) ** 3 where P=' + str(P))

#plot, in the range from BT to ET, the true f(t) in blue and the approximation in red
for N in range(1, maxN + 1):
    C = compute_complex_fourier_coeffs(f, N)
    #C contains the list of cn complex coefficients for n in 1..N interval.

    y_approx = fit_func_by_fourier_series_with_complex_coeffs(t_range, C)
    #y_approx contains the discrete values of approximation obtained by the Fourier series

    row = (N-1) // COLs
    col = (N-1) % COLs
    axs[row, col].set_title('case N=' + str(N))
    axs[row, col].scatter(t_range, y_true, color='blue', s=1, marker='.')
    axs[row, col].scatter(t_range, y_approx, color='red', s=2, marker='.')
plt.show()


from math import factorial

from numpy import ones, copy, cos, tan, linspace
from numpy import sqrt, pi, exp

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, z):
    p = z / (1 - (z ** 2))
    return ((1 + (z ** 2)) / ((1 - (z ** 2)) ** 2)) * (p ** 2) * (
            ((1 / (sqrt((2 ** n) * factorial(n) * sqrt(pi)))) * exp(-0.5 * (p ** 2)) * H(n, p)) ** 2)

n = int(input("Enter the order of the wave function: "))
N = 100
a = -1.0
b = 1.0
x, w = gaussxw(N)
xp = 0.5 * (b - a) * x + 0.5 * (b + a)
wp = 0.5 * (b - a) * w
s = 0.0
for k in range(N):
    s += wp[k] * wave_func(n, xp[k])

print("Uncertainty for the ", n, "th order state:", sqrt(s))

Ankit Khandelwal_HW2/exercise 5/exercise 5c.py