import numpy as np
import math

def sum_squared_error( outputs, targets, derivative=False ):
    if derivative:
        return outputs - targets
    else:
        return 0.5 * np.mean(np.sum( np.power(outputs - targets,2), axis = 1 ))
#end cost function

def hellinger_distance( outputs, targets, derivative=False ):
    """
    The output signals should be in the range [0, 1]
    """
    root_difference = np.sqrt( outputs ) - np.sqrt( targets )

    if derivative:
        return root_difference/( np.sqrt(2) * np.sqrt( outputs ))
    else:
        return np.mean(np.sum( np.power(root_difference, 2 ), axis=1) / math.sqrt( 2 ))
#end cost function

def binary_cross_entropy_cost( outputs, targets, derivative=False, epsilon=1e-11 ):
    """
    The output signals should be in the range [0, 1]
    """
    # Prevent overflow
    outputs = np.clip(outputs, epsilon, 1 - epsilon)
    divisor = np.maximum(outputs * (1 - outputs), epsilon)

    if derivative:
        return (outputs - targets) / divisor
    else:
        return np.mean(-np.sum(targets * np.log( outputs ) + (1 - targets) * np.log(1 - outputs), axis=1))
#end cost function
cross_entropy_cost = binary_cross_entropy_cost

def softmax_categorical_cross_entropy_cost( outputs, targets, derivative=False, epsilon=1e-11 ):
    """
    The output signals should be in the range [0, 1]
    """
    outputs = np.clip(outputs, epsilon, 1 - epsilon)

    if derivative:
        return outputs - targets
    else:
        return np.mean(-np.sum(targets * np.log( outputs ), axis=1))
#end cost function
softmax_neg_loss = softmax_categorical_cross_entropy_cost


import math
import numpy

def gaussian(x, mu, sig):
    '''
    Gaussian function.
    '''
    return (1 / math.sqrt(2 * math.pi * sig ** 2)) * \
        numpy.exp(-(x - mu) ** 2 / (2 * sig ** 2))

def logistic(x, x0, L, M, k):
    '''
    Logistic function.
    '''
    return M + (L / (1 + numpy.exp(-k * (x - x0))))

def entropy (num1, num2):
    percnt1 = num1/(num1+num2)
    percnt2 = num2/(num1+num2)
    return (-(percnt1*math.log2(percnt1) + percnt2*math.log2(percnt2)))

if __name__ == "__main__":
    print(entropy(5,9))
    print(entropy(3,2))
    print(entropy(2,3))


## QR Algorithm
# Author: Kelly Rivera

# This code is an implementation of a PageRank Algorithm variant using QR Decomposition
# Implementing Householder and Gram-Schmidt Process

### Import Libraries
import numpy as npy
import scipy as sp
import scipy.linalg as spl  # SciPy Linear Algebra Library
import matplotlib.pyplot as plt

### Householder transformation method
def qr_householder(x):
    Q, R = npy.linalg.qr(x)
    return Q, R

def qr_Algorithm_HH(x,iterations):
    m, n = x.shape
    Q_last = npy.identity(n)
    for _ in range(iterations):
        Q, R = qr_householder(x)
        # This update matrix A, by dot product of reverse QR
        x = npy.dot(R, Q)

        eigenvectors = npy.dot(Q_last, Q)
        Q_last = eigenvectors

    eigenvalues = npy.diag(x)  #outputs only the values on the main diaginal
    return eigenvalues, eigenvectors

### Gram-Schmidt Process
def qr_GS(x):
    m, n = x.shape
    Q = npy.zeros((m, n)) # Q is all zero
    R = npy.zeros((n, n))

    for j in range(n):
        v = x[:, j] # x[:,0] returns the first* column* of x, x[:,1] reutrns the second column etc

        for i in range(j):
            q = Q[:, i]
            R[i, j] = q.dot(v)
            v = v - R[i, j] * q

        vNorm = npy.linalg.norm(v)
        R[j, j] = vNorm
        Q[:, j] = v / vNorm

    return Q, R

def qr_Algorithm(x,iterations):
    m, n = x.shape
    Q_last = npy.identity(n)
    for _ in range(iterations):
        Q, R = qr_GS(x)
        # This update matrix A, by dot product of reverse QR
        x = npy.dot(R, Q)

        eigenvectors = npy.dot(Q_last, Q)
        Q_last = eigenvectors
    eigenvalues = npy.diag(x)  #outputs only the values on the main diaginal
    return eigenvalues, eigenvectors

### QR Gram-Schmidt with Shift
def shiftedQR_Algorithm(x, iterations):
    m, n = x.shape
    I = npy.identity(n)
    Q_last = npy.identity(n)

    for _ in range(iterations):
        μ = x[[n-1],[n-1]]         # shift: μ = a_nn
        Q, R = qr_GS((x - (μ*I)))  # A − μI = QR: preforms the gram schmidt process with shift

        x = npy.dot(R,Q) + (μ*I)   # This update matrix A, by dot product of reverse QR and adding back the shift

        eigenvectors = npy.dot(Q_last, Q)
        Q_last = eigenvectors

    eigenvalues = npy.diag(x)  #outputs only the values on the main diaginal
    return eigenvalues, eigenvectors


# coding: utf-8

# In[11]:

from scipy.stats import beta
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['figure.figsize']=(7,5)

# In[3]:

a=np.array([0.1,1.0,2.0,8.0])
b=np.array([0.1,1.0,3.0,4.0])

# In[14]:

for (new_a,new_b) in zip(a,b):
    print(new_a,new_b)
    x = np.linspace(beta.ppf(0.0001,new_a,new_b),
                   beta.ppf(0.9999,new_a,new_b),100)
    plt.plot(x,beta.pdf(x,new_a,new_b),label='a={},b={}'.format(new_a,new_b))
ax = plt.gca()
ax.set_ylim((0,3))
ax.set_xlim((0,1))
ax.legend()


import numpy as np
import matplotlib.pyplot as plt

def lin_reg_coef(x_list, y_list):
    """
    function that returns Linear Regression coefficients

    Inputs:
    1. x_list : list of data on x-axis
    2. y_list : list of data on y-axis

    Output: Tuple of Linear Regression Coefficients
    """
    # converting the list into array
    x = np.array(x_list)
    y = np.array(y_list)

    # number of observations/points
    n = np.size(x)

    # mean of x and y vector
    m_x = np.mean(x)
    m_y = np.mean(y)

    # calculating cross-deviation and deviation about x
    SS_xy = np.sum(y*x) - n*m_y*m_x
    SS_xx = np.sum(x*x) - n*m_x*m_x

    # calculating regression coefficients
    b_1 = SS_xy / SS_xx
    b_0 = m_y - b_1*m_x
    #c = b_0, m = b_1 in y=mx+c
    return (b_0, b_1)


import numpy as np
import matplotlib.pyplot as plt
pixel=30
img = np.fromfunction(lambda u,v: np.sin(u)+np.cos(v) ,(pixel,pixel))

print(img)
fourier= np.fft.fft2(img)
fourier_s=np.fft.fftshift(fourier)
print(fourier)
plt.subplot(1,2,1)
plt.imshow(img)
plt.subplot(1,2,2)
plt.imshow(abs(fourier_s))
plt.show()
# magnitude_spectrum = 20*np.log(np.abs(F2))
# b.pltx(bw_img,magnitude_spectrum)


# loss function损失函数常用的mean squared error（均方误差） 0.5 * (for i in range(n): np.sum((yi - ti) ** 2)
import numpy as np
# y: softmax function output
# t：test data set label
def mean_squared_error(y , t):
    return 0.5 * np.sum((y - t) ** 2)

# 人为设定test label为2，即当前标签为digit 2
t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]

# example 1
# y1中代表softmax predict 从0～9的概率
y1 = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]
print('y1: ', mean_squared_error(np.array(y1), np.array(t)))

# example 2
y2 = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]
print('y2: ', mean_squared_error(np.array(y2), np.array(t)))

'''
由mean_squared_error可以看出第一个神经网络输出的结果比第二个神经网络的误差较小，所以example1更加接近正解
'''


import numpy as np
import time
from rich import print as rprint

"""
The Interpolation Search is an improvement over
Binary Search for instances, where the values in
a sorted array are uniformly distributed. Binary
Search always goes to the middle element to check.
On the other hand, interpolation search may go to
different locations according to the value of the
key being searched. For example, if the value of
the key is closer to the last element, interpolation
search is likely to start search toward the end side.

pos = lo + (x - arr[lo]) *(hi - lo)/(arr[hi] - arr[lo])
"""

def search(array, lo, hi, x):
	pos = lo + (hi - lo) // 2
	if (lo <= hi and x >= array[lo] and x <= array[hi]):

		pos = lo + (x - array[lo]) *(hi - lo) // (array[hi] - array[lo])
		if array[pos] == x:
			return pos

		elif array[pos] > x:
			return search(array, lo, pos - 1, x)

		else:
			return search(array, pos + 1, hi, x)

	else:
		return -1

def main():
	array = np.arange(1, 9999999, 1)
	query = np.random.randint(1, 9999999)
	size = len(array)
	start_time = time.time()
	result = search(array=array, lo=0, hi=size - 1, x=query)
	stop_time = time.time()
	if result == -1:
		rprint("[red]Element {} is not present in the array.".format(query))
	else:
		rprint("[green]ELement[/green] {} [green]found in the array at index:[/green] {}".format(query, result))
	rprint("[yellow]Total time taken:", stop_time - start_time, "[yellow]seconds.")

if __name__ == "__main__":
	main()


#!/usr/bin/env python
#
# Author: Ying Xiong.
# Created: Mar 19, 2014.

import numpy as np

def numerical_jacobian(fcn, x0, dx=1e-6, method=0, return_f0=False):
    """Compute the numerical Jacobian matrix of a given function.

    Parameters
    ----------
    fcn: function handle
        Takes an N-vector as input and return an M-vector.
    x0: ndarray
        An input N-vector.
    dx: scalar
        For small change in x0.
    method: int or string
        With following options:
          * {0, 'forward'}: compute the Jacobian as (f(x0+dx)-f(x0))/dx.
          * 1, 'central' : compute the Jacobian as (f(x0+dx)-f(x0-dx))/2/dx.
    return_f0: boolean
        If set to true, also return fcn(x0).

    Returns
    -------
    J : `ndarray`
        The `MxN` Jacobian matrix.
    f0 : `ndarray`
        The function value at x0.

    Examples
    --------
    >>> J = numerical_jacobian(fcn, x0, ...)
    >>> (J, f0) = numerical_jacobian(fcn, x0, ..., return_f0=True)
    """
    N = len(x0)
    if method==0 or method=="forward":
        # Forward difference.
        f0 = fcn(x0)
        M = len(f0)
        J = np.zeros((M,N))
        for j in xrange(N):
            xj = x0.copy()
            xj[j] += dx
            fj = fcn(xj)
            J[:,j] = (fj-f0) / dx
        if return_f0:
            return (J, f0)
        else:
            return J
    elif method==1 or method=="central":
        # Central difference.
        for j in xrange(N):
            xj1 = x0.copy()
            xj2 = x0.copy()
            xj1[j] -= dx
            xj2[j] += dx
            fj1 = fcn(xj1)
            fj2 = fcn(xj2)
            if j == 0:
                M = len(fj1)
                J = np.zeros((M,N))
            J[:,j] = (fj2-fj1) / 2 / dx
        if return_f0:
            return (J, fcn(x0))
        else:
            return J
    else:
        assert False, "Unknown method '" + method + "'."


class Solution:
    def climbStairs(self, n: int) -> int:
        # 我的思路是，不管前面怎么走，最后就剩1个台阶的时候，1种，2个台阶的时候2种；前面只是看得到多少条路径，分叉到最后一层，得到有多少种方法
        global comb_num
        comb_num = 0
        def count(s):
            global comb_num
            if s == 2:
                comb_num += 2
            elif s == 1:
                comb_num += 1
            else:
                steps = [1, 2]
                for step in steps:
                    count(s - step)
        count(n)
        return comb_num

    def climbStairs_Dynamic(self, n: int) -> int: # 动态规划
        import numpy as np
        steps = list(np.zeros(n + 1))
        for i, s in enumerate(steps):
            if i == 1:
                steps[i] = 1
            elif i == 2:
                steps[i] = 2
            else:
                steps[i] = steps[i - 1] + steps[i - 2]
        print(steps)
        return steps[n]

    def climbStairs_demo(self, n: int):
        if (n == 1):
            return 1
        if (n == 2):
            return 2
        output = self.climbStairs_demo(n - 1) + self.climbStairs_demo(n - 2)
        return output

nums = 38
solution = Solution()
output = solution.climbStairs(nums)
print(output)
output = solution.climbStairs_Dynamic(nums)
print(output)


"""
generate 5 different test signals of the form: a₁cos(ω₁t + φ₁)

John M. O' Toole, University College Cork
Started: 04-09-2019
last update: <2019-09-04 13:36:01 (otoolej)>
"""
import numpy as np
from matplotlib import pyplot as plt
import matplotlib

def gen_signals(sig_num=0, DBplot=True):
    """define some simple test signals of the form: a₁cos(ω₁t + φ₁)

    Parameters
    ----------
    sig_num: string, {'0', '1', '2', '3', '4'}
        which signal type
    DBplot: bool
        plot or not

    Returns
    -------
    x_dt : dict, keys: 'x' and 'fwe'
        returns test signal 'x' and the expected frequency-weighted energy 'fwe'
    """

    N = 256
    Nh = np.ceil(N / 2)
    n = np.arange(N)
    w1 = np.pi / (N / 32)
    w2 = np.pi / (N / 8)
    ph1 = -np.pi + 2 * np.pi * np.random.rand(1)
    ph2 = -np.pi + 2 * np.pi * np.random.rand(1)
    a1 = 1.3
    a2 = 3.1
    x1 = a1 * np.cos(w1 * n + ph1)
    x2 = a2 * np.cos(w2 * n + ph2)

    def sig0():
        # ---------------------------------------------------------------------
        # stationary signal: a₁cos(ω₁t + φ₁)
        # ---------------------------------------------------------------------
        x = x2  # / max(x2)
        extact_x = np.full(N, (a2 ** 2) * (w2 ** 2))
        return({'x': x, 'fwe': extact_x})

    def sig1():
        # ---------------------------------------------------------------------
        # concatentated (in time) signals: a₁cos(ω₁t + φ₁) PLUS a₂cos(ω₂t + φ₂)
        # ---------------------------------------------------------------------
        a1 = 1
        a2 = 1
        w1 = np.pi / (N / 32)
        w2 = np.pi / (N / 16)

        x = np.hstack((a1 * np.cos(w1 * np.arange(Nh + 1)),
                       a2 * np.cos(w2 * np.arange(Nh + 1, N))))
        extact_x = np.hstack((np.full((int(Nh)), a1 ** 2) * np.sin(w1) ** 2,
                              np.full((int(Nh)), a2 ** 2) * np.sin(w2) ** 2))
        return({'x': x, 'fwe': extact_x})

    def sig2():
        # ---------------------------------------------------------------------
        # signal with amplitude modulation: e^{rt} a₁cos(ω₁t + φ₁)
        # ---------------------------------------------------------------------
        r1 = 0.005
        x = np.exp(-r1 * n) * x1

        extact_x = (a1 ** 2) * np.exp(-2*r1*n) * (np.sin(w1) ** 2+r1 ** 2)
        return({'x': x, 'fwe': extact_x})

    def sig3():
        # ---------------------------------------------------------------------
        # signal with frequency modulation: a₁cos(φ(t))
        # ---------------------------------------------------------------------
        if_law = 0.1 + 0.3 * np.sin(n * np.pi / N)
        ph = np.cumsum(if_law)
        x = a1 * np.cos(ph + ph1)
        extact_x = (a1 ** 2) * (if_law) ** 2
        # extact_x = (a1 ** 2) * (np.sin(if_law)) ** 2
        return({'x': x, 'fwe': extact_x})

    def sig4():
        # ---------------------------------------------------------------------
        # sum of two signals: a₁cos(ω₁t + φ₁) + a₂cos(ω₂t + φ₂)
        # ---------------------------------------------------------------------
        x = x1 + x2
        edo_x1 = (a1 ** 2) * (w1 ** 2)
        edo_x2 = (a2 ** 2) * (w2 ** 2)
        a_12 = 2 * a1 * a2 * w1 * w2
        extact_x = edo_x1 + edo_x2 + a_12 * np.cos(n * (w1 - w2) + ph1 - ph2)
        return({'x': x, 'fwe': extact_x})

    def default_sig():
        # -------------------------------------------------------------------
        # default option
        # -------------------------------------------------------------------
        print('Invalid signal name; defaulting to sig0')
        return(sig0())

    # pick which function to execute
    which_sig = {'0': sig0, '1': sig1, '2': sig2, '3': sig3, '4': sig4}

    def get_sig(name):
        return which_sig.get(name, default_sig)()

    x_dt = get_sig(sig_num)

    if DBplot:
        plt.figure(10, clear=True)
        plt.plot(x_dt['x'], '-x')
        plt.plot(x_dt['fwe'], '-o')

    return(x_dt)

# testing :
# xd = gen_signals('0', True)


import numpy as np
from utils import to_ndarray
from utils.math_functions import euclidian_distance

class KMeans:

    k: int
    x: np.ndarray
    labels: np.ndarray
    gen_mode: str
    centroids: np.ndarray

    def __init__(self, k=3, gen_mode='rnd_element'):
        """
        Args:
            k (int, optional): number of centroids. Defaults to 3.
            gen_mode (str, optional): centroid generation mode. Defaults to 'rnd_element'.
                * 'rnd_element' will select k elements randomly.
                * 'rnd_values' generate random values between min and max of elements for each centroid
        """

        self.k = k
        self.gen_mode = gen_mode
        self.labels = np.array([])
        self._verify_params()

    def _verify_params(self):
        if self.gen_mode not in ['rnd_element', 'rnd_values']:
            raise Exception("incorrect centroid generation mode. available modes: 'rnd_element', and 'rnd_values'")

    def _init_centroids_random(self):
        min_values = self.x.min(axis=0)
        max_values = self.x.max(axis=0)

        centroid = []

        for i in range(self.k):
            centroid.append([])
            for j in range(self.x.shape[1]):
                centroid[i].append(np.random.uniform(low=min_values[j], high=max_values[j]))

        return np.array(centroid)

    def _init_centroids_by_select(self):
        attempts = 50
        centroids = None

        # Select k random points while not duplicates, or attempts == 0
        while attempts > 0:
            centroids_idx = np.random.choice(len(self.x), size=self.k, replace=False)
            centroids = self.x[centroids_idx]

            if len(np.unique(centroids, axis=0)) == self.k:
                return centroids

            attempts -= 1

        print('warn: two or more centroids are equal')

        return centroids

    def _init_centroids(self):
        if self.gen_mode == 'rnd_element':
            return self._init_centroids_by_select()
        elif self.gen_mode == 'rnd_values':
            return self._init_centroids_random()

        raise Exception("incorrect centroid generation mode. available modes: 'rnd_element', and 'rnd_values'")

    def _define_labels(self, elements):
        labels = []

        for element in elements:
            distances = euclidian_distance(element, self.centroids)
            labels.append(np.argmin(distances))

        return np.array(labels)

    def _calculate_centroids(self):
        centroids = []

        for index in range(self.k):
            mask = self.labels == index
            selected = self.x[mask]
            mean = np.mean(selected, axis=0)
            centroids.append(mean)

        return np.array(centroids)

    def fit(self, x, max_iter=1000):
        self._verify_params()

        self.x = to_ndarray(x)
        self.centroids = self._init_centroids()

        while max_iter > 0:
            max_iter -= 1

            labels = self._define_labels(self.x)
            if np.array_equal(labels, self.labels):
                break
            else:
                self.labels = labels
                self.centroids = self._calculate_centroids()

    def predict(self, x):
        values = to_ndarray(x)
        return self._define_labels(values)


import numpy as np
import matplotlib.pyplot as plt
import sklearn
import mglearn

from sklearn.decomposition import PCA
from sklearn.datasets import load_digits
from sklearn.manifold import TSNE

####################################################################################################################################################
### Load Digits Dataset ############################################################################################################################
####################################################################################################################################################
digits = load_digits()

# Plot 10 examples from the dataset
fig, axes = plt.subplots(2, 5, figsize=(10, 5), subplot_kw={'xticks':(), 'yticks': ()})
for ax, img in zip(axes.ravel(), digits.images):
    ax.imshow(img)

print(digits.images.shape)  # Print the shape of image

####################################################################################################################################################
### Principle Component Analysis of Digits Dataset #################################################################################################
####################################################################################################################################################
pca = PCA(n_components=2)   # PCA object that produces 2 principle components
pca.fit(digits.data)        # Produce 2 principle components with Digits dataset

digits_pca = pca.transform(digits.data)     # Re-Organize/Transform Digits dataset with principle components

# Plot the distribution of PCA-based Digits dataset
colors = ["#476A2A", "#7851B8", "#BD3430", "#4A2D4E", "#875525",
          "#A83683", "#4E655E", "#853541", "#3A3120", "#535D8E"]
plt.figure(figsize=(10, 10))
plt.xlim(digits_pca[:, 0].min(), digits_pca[:, 0].max())    # Set the limit of X axis
plt.ylim(digits_pca[:, 1].min(), digits_pca[:, 1].max())    # Set the limit of Y axis

# For each data in Digits dataset, plot the data based on the values of 1st and 2nd principle components
for i in range(len(digits.data)):
    plt.text(digits_pca[i, 0], digits_pca[i, 1], str(digits.target[i]),
             color = colors[digits.target[i]],
             fontdict={'weight': 'bold', 'size': 9})

plt.xlabel("First principal component")
plt.ylabel("Second principal component")
plt.show()

####################################################################################################################################################
### t-SNE (t-Stochastic Neighbor Embedding) of Digits Dataset ######################################################################################
####################################################################################################################################################
tsne = TSNE(random_state=42)    # t-SNE object that produces t-SNE features

digits_tsne = tsne.fit_transform(digits.data)   # Re-Organize/Transform the dataset with t-SNE

plt.figure(figsize=(10, 10))
plt.xlim(digits_tsne[:, 0].min(), digits_tsne[:, 0].max() + 1)  # Set the limit of X axis
plt.ylim(digits_tsne[:, 1].min(), digits_tsne[:, 1].max() + 1)  # Set the limit of Y axis

# For each data in Digits dataset, plot the data based on the values of t-SNE features
for i in range(len(digits.data)):
    plt.text(digits_tsne[i, 0], digits_tsne[i, 1], str(digits.target[i]),
             color = colors[digits.target[i]],
             fontdict={'weight': 'bold', 'size': 9})
plt.xlabel("t-SNE feature 0")
plt.xlabel("t-SNE feature 1")
plt.show()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Created by techno at 27/05/19

#Feature:  #Enter feature name here
# Enter feature description here

#Scenario:  # Enter scenario name here
# Enter steps here

import numpy as np

a = np.array([ True,True,False,False])
b = np.array([ True,False,True,False])

print ( np.logical_and(a,b))
print(np.logical_or(a,b))
print(np.logical_not(a,b))

"""
However, you can also compare entire arrays with each other! In this case,
 you use the np.array_equal() function. Just pass in the two arrays that
 you want to compare with each other, and you’re done.

Note that, besides comparing, you can also perform logical operations
on your arrays. You can start with np.logical_or(), np.logical_not()
and np.logical_and(). This basically works like your typical OR,
NOT and AND logical operations;

In the simplest example, you use OR to see whether your elements are the same
(for example, 1), or if one of the two array elements is 1. If both of them
are 0, you’ll return FALSE. You would use AND to see whether your second
element is also 1 and NOT to see if the second element differs from 1.
"""


import numpy as np
from datetime import datetime

a = np.array([[1, 2, 2],
	       [2, 7, 3],
	       [-1, 7, -3]],float)

b = np.array([3, 1, -14], float)

num_elements = len(b)

x = np.zeros(num_elements, float)

# Elimination

start_time = datetime.now()
# Go through the fixed rows
for i in range(num_elements-1):

# Take the rows under the fixed row, row by row inorder to apply the row operations
	for j in range(i + 1, num_elements):
		factor = a[i, i] / a[j, i]
		b[j] = b[i] - factor*b[j]
		# element subtraction
		for k in range(i, num_elements):
			a[j, k] = a[i, k] - factor*a[j, k]

# Back Substitution

# Start with last row
x[num_elements - 1] = b[num_elements - 1] / a[num_elements - 1, num_elements - 1]
for i in range(num_elements - 2, -1, -1):
	# Summation of terms
	terms = 0
	for j in range(i + 1, num_elements):
		terms += a[i, j] * x[j]
	x[i] = (b[i] - terms) / a[i, i]
total_time = datetime.now() - start_time
print(f'It took {total_time.microseconds} microseconds to solve the system.')
print('Solution saved to file')

# Save to file
np.savetxt('linear_sysFile.txt', x, fmt='%4.8f', delimiter=' ')


import numpy
import numpy as np

#Parametros de entrada
#A matriz nxn, #b matriz de valores independientes
#Salida
#x matriz  de las soluciones
def fact_lu(A, b):
    n = A.shape[0]#Obtiene el numero de filas de A
    m = A.shape[1]#Obtiene el numero de columnas de A
    t = b.shape[0]#Obtiene el numero de filas de b
    o = b.shape[1]#Obtiene el numero de columnas de B
    if n != m:#Comprueba que la matriz sea cuadrada
        raise ValueError("La matriz no es cuadrada")
    if t != n or o!=1:#Comprueba que las matriz b sea las dimensiones adecuadas
        raise ValueError("La matriz b no tiene las dimensiones correctas")
    if teorema_2_lu(A,n) == False:#Comprueba las submatrices sean invertibles
        raise ValueError("La matriz no cumple el teorema 2 de Fact LU")

    M = matriz_inf_lu(A, n)#Obtiene la matriz de inferior y superior en version LU

    y = hacia_Adelante(M[1], b, n)#Resuelve Ly=b
    x = hacia_Atras(M[0], y, n)#Resuleve Ux=y
    return x

#Parametros de entrada
#A matriz  cuadrada, #n largo de la matriz
#Salida
#Valor booleado que identifica si se cumple o no el teorema 2
#Evaluacion del Teorema de LU
def teorema_2_lu(A, n):#Comprueba que las submatrices tiene determinante diferente de 0
    Valor = True#Booleano que sirve para identificar si se cumplio o no el teorema
    for k in range(0, n):
        if np.linalg.det(A[0:k, 0:k]) == 0:
            Valor = False#Se detiene si una submatriz no cumple el teorema 2
            break
    return Valor#True se cumple, #False se incumple

#Parametros de entrada
#A matriz cuadrada, #n largo de la matriz
#Salida
#U matriz Triangular superior LU, #L Matriz Triangular inferior LU
#Matrices inferior y superior version Factorizacion de LU
def matriz_inf_lu(A,n):
    U=A
    L=np.zeros((n,n))

    for k in range(0,n-1):#Columnas
        for i in range(k+1,n):#Filas
            Mik=U[i,k]/U[k,k]
            L[i,k]=Mik#Agrega a la matriz los valores ocupuesto a los "Multiplicadores" de la matriz
            for j in range(k,n):#Ciclo para agregar los nuevos valores de la matriz U
                U[i,j]=U[i,j]-Mik*U[k,j]
                if i==j:
                    L[i,j]=1
    L[0,0]=1
    return U,L

#Parametros de entrada
#A matriz  triangular superior, #b nueva matriz de valores independientes, #n largo de la matriz
#Salida
#soluciones matriz de soluciones "x#"
#Sustitucion hacia atras
def hacia_Atras(A, b, n):
    soluciones = np.zeros((n, 1))
    i = n - 1;

    while (i >= 0):
        sumatoria = 0
        for j in range(i + 1, n):
            sumatoria = sumatoria + (A[i, j] * soluciones[j])

        x = (1 / A[i, i]) * (b[i] - sumatoria)
        soluciones[i] = x
        i = i - 1
    return soluciones

#Parametros de entrada
#A matriz  triangular inferior, #b nueva matriz de valores independientes, #n largo de la matriz
#Salida
#soluciones matriz de soluciones "x#"
#Sustitucion hacia adelante
def hacia_Adelante(A, b, n):
    soluciones = np.zeros((n, 1))#Matriz de soluciones
    soluciones[0] = b[0] / A[0, 0]#Primera solucion
    i = 1;

    while (i < n):#Mueve las filas
        sumatoria = 0
        for j in range(0, i):#Mueve columnas
            sumatoria = sumatoria + (A[i, j] * soluciones[j])#Sumatoria necesaria

        x = (b[i] - sumatoria) / A[i, i]#Calcular el valor de la solucion "x"
        soluciones[i] = x#Agrega la solucion a la matriz de soluciones
        i = i + 1
    return soluciones

if __name__ == '__main__':
    #Ejemplos de ingresos de datos
    A = np.matrix('4 -2 1; 20 -7 12;-8 13 17', float)
    A2 = np.matrix('25 15 -5 -10;15 10 1 -7;-5 1 21 4;-10 -7 4 18',float)

    b = numpy.matrix('11;70;17')
    b2 = np.matrix('-25;-19;-21;-5')
    print("Ejemplo 1 tiene como resultado:")
    print(fact_lu(A, b))
    print("Ejemplo 2 tiene como resultado:")
    print(fact_lu(A2, b2))

Catalogo/03. Sistemas de Ecuaciones/Python/fact_lu.py


import numpy as np
import numba
from numba import prange

@numba.jit(nopython=True, parallel=True, nogil=True)
def edge_ratio(cells, points):
    edge_ids = np.asarray([[0,1],[0,2],[0,3],[1,2],[1,3],[2,3]], dtype=np.int32)
    ncells = cells.shape[0]
    ratios = np.zeros((ncells,1), dtype=np.float64)
    for id in prange(ncells):
        vtx_coords = points[cells[id]]
        edge_lengths = np.sqrt(np.square(vtx_coords[edge_ids[:,0],:] - vtx_coords[edge_ids[:,1],:]).sum(axis=1))
        ratios[id] = np.amax(edge_lengths)/np.amin(edge_lengths)
    return ratios

@numba.jit(nopython=True, parallel=True, nogil=True)
def aspect_frobenius(cells, points):
    VERDICT_DBL_MIN = 1.0E-30
    VERDICT_DBL_MAX = 1.0E+30
    normal_exp = 1. / 3.

    ncells = cells.shape[0]
    af = np.zeros((ncells,1))
    for id in prange(ncells):
        coordinates = points[cells[id]]

        u = np.array( [[coordinates[1][0] - coordinates[0][0]],
                       [coordinates[1][1] - coordinates[0][1]],
                       [coordinates[1][2] - coordinates[0][2]]] )

        v = np.array( [[coordinates[2][0] - coordinates[0][0]],
                       [coordinates[2][1] - coordinates[0][1]],
                       [coordinates[2][2] - coordinates[0][2]]] )

        w = np.array( [[coordinates[3][0] - coordinates[0][0]],
                       [coordinates[3][1] - coordinates[0][1]],
                       [coordinates[3][2] - coordinates[0][2]]] )

        denominator = 3. * (2. * (u % ( v * w ))**2)**normal_exp

        if denominator < VERDICT_DBL_MIN:
            af[id] = VERDICT_DBL_MAX
            continue

        numerator = 1.5 * ( u[0] * u[0] + u[1] * u[1] + u[2] * u[2]
                          + v[0] * v[0] + v[1] * v[1] + v[2] * v[2]
                          + w[0] * w[0] + w[1] * w[1] + w[2] * w[2] ) \
                    - v[0] * u[0] + v[1] * u[1] + v[2] * u[2] \
                    - w[0] * u[0] + w[1] * u[1] + w[2] * u[2] \
                    - w[0] * v[0] + w[1] * v[1] + w[2] * v[2]

        aspect_frobenius = numerator / denominator

        if aspect_frobenius > 0: af[id] = np.minimum( aspect_frobenius, VERDICT_DBL_MAX )
        else:                    af[id] = np.maximum( aspect_frobenius, -VERDICT_DBL_MAX )

    return af


from math import sqrt
from numba import njit, prange

@njit()
def divisor_counter(number: int) -> int:
    s = 0

    for i in prange(1, int(sqrt(number) + 1)):
        if number % i == 0:
            if number // i == i:
                s += 1
            else:
                s += 2

    return s

@njit()
def triangular_number(divisor_number: int) -> int:
    triangle_number = 0
    s = 0

    while True:
        s += triangle_number

        if divisor_counter(s) >= divisor_number:
            return s
        else:
            triangle_number += 1

if __name__ == '__main__':
    n = triangular_number(500)

    print(n)


import numpy as np

def sigmoid(z):
    """The sigmoid is a squashing function that compresses the entire real line
    into the unit interval.
    """
    return 1. / (1. + np.exp(-z))

def sigmoid_derivative(z):
    """Derivative of the sigmoid function with respect to its input."""
    p = sigmoid(z)
    return p * (1. - p)


from matplotlib import pyplot as plt
import pandas as pd
import numpy as np
import math
import scipy.stats as stats

from . import t
from . import chi2
from . import p
from . import ind
from . import anova
from . import non

"""
Using z statistic for hypothesis testing and confidence intervals.

+ rejection_region_method(x_mean, mu, std, n, alpha, option='left', precision=4, show=True, ignore=False)
+ testing_statistic_method
+ p_value_method
+ power_test
+ sample_size
+ type2_plot
+ power_plot
"""

def rejection_region_method(x_mean, mu, std, n, alpha, option='left', precision=4, show=True, ignore=False):
    """
    Input: x_mean, mu, std, n, alpha, option='left', precision=4, show=True, ignore=False
    Output:
        if opt == 't':
            return x_l, x_u
        else:
            return x_c
    """
    opt = option.lower()[0]
    if opt == 't':
        option = 'Two-Tail Test'
        z_value = stats.norm.ppf(1 - alpha / 2)
        x_u = mu + z_value * std / math.sqrt(n)
        x_l = mu - z_value * std / math.sqrt(n)
        flag = x_mean < x_l or x_mean > x_u
        if not ignore:
            result = f'''======= The Rejection Region Method =======
Significant Level (alpha) = {alpha:.{precision}f}
z_value = {z_value:.{precision}f}

Using {option}:
x̄ =  {x_mean:.{precision}f}
x_l (Lower bound for the critical value) = {x_l:.{precision}f}
x_u (Upper bound for the critical value) = {x_u:.{precision}f}
Reject H_0 → {flag}
            '''
        else:
            result = f'''======= The Rejection Region Method =======
Significant Level (alpha) = {alpha:.{precision}f}
z_value = {z_value:.{precision}f}

Using {option}:
x_l (Lower bound for the critical value) = {x_l:.{precision}f}
x_u (Upper bound for the critical value) = {x_u:.{precision}f}
            '''

    else:
        if opt == 'l':
            # left tail
            option = 'One-Tail Test (left tail)'
            z_value = stats.norm.ppf(alpha)  # negative
            x_c = mu + z_value * std / math.sqrt(n)
            flag = x_mean < x_c
        elif opt == 'r':
            option = 'One-Tail Test (right tail)'
            z_value = stats.norm.ppf(1 - alpha)
            x_c = mu + z_value * std / math.sqrt(n)
            flag = x_mean > x_c
        if not ignore:
            result = f'''======= The Rejection Region Method =======
Significant Level (alpha) = {alpha:.{precision}f}
z_value = {z_value:.{precision}f}

Using {option}:
x̄ =  {x_mean:.{precision}f}
x_c (Critical value) = {x_c:.{precision}f}
Reject H_0 → {flag}
            '''
        else:
            result = f'''======= The Rejection Region Method =======
Significant Level (alpha) = {alpha:.{precision}f}
z_value = {z_value:.{precision}f}

Using {option}:
x_c (Critical value) = {x_c:.{precision}f}
            '''

    if show:
        print(result)

    if opt == 't':
        return x_l, x_u
    else:
        return x_c

def testing_statistic_method(x_mean, mu, std, n, alpha, option='left', precision=4, ignore=False):
    """
    Input: x_mean, mu, std, n, alpha, option='left', precision=4, ignore=False
    Output:
        if opt == 't':
            return z, z_l, z_u
        else:
            return z, z_value
    """
    opt = option.lower()[0]
    z = (x_mean - mu)/(std / math.sqrt(n))
    if opt == 't':
        option = 'Two-Tail Test'
        z_value = stats.norm.ppf(1 - alpha / 2)
        z_u = z_value
        z_l = -z_value
        flag = z < z_l or z > z_u

        if not ignore:
            result = f'''======= Testing Statistic Method =======
Significant Level (alpha) = {alpha:.{precision}f}
z_value = {z_value:.{precision}f}

Using {option}:
z =  {z:.{precision}f}
z_l (Lower bound for the critical value) = {z_l:.{precision}f}
z_u (Upper bound for the critical value) = {z_u:.{precision}f}
Reject H_0 → {flag}
            '''
        else:
            result = f'''======= Testing Statistic Method =======
Significant Level (alpha) = {alpha:.{precision}f}
z_value = {z_value:.{precision}f}

Using {option}:
z_l (Lower bound for the critical value) = {z_l:.{precision}f}
z_u (Upper bound for the critical value) = {z_u:.{precision}f}
            '''

    else:
        if opt == 'l':
            # left tail
            option = 'One-Tail Test (left tail)'
            z_value = stats.norm.ppf(alpha)  # negative
            flag = z < z_value
        elif opt == 'r':
            option = 'One-Tail Test (right tail)'
            z_value = stats.norm.ppf(1 - alpha)
            flag = z > z_value

        if not ignore:
            result = f'''======= Testing Statistic Method =======
Significant Level (alpha) = {alpha:.{precision}f}
z_value = {z_value:.{precision}f}

Using {option}:
z =  {z:.{precision}f}
z_alpha (Critical value) = {z_value:.{precision}f}
Reject H_0 → {flag}
            '''

        else:
            result = f'''======= Testing Statistic Method =======
Significant Level (alpha) = {alpha:.{precision}f}
z_value = {z_value:.{precision}f}

Using {option}:
z_alpha (Critical value) = {z_value:.{precision}f}
            '''

    print(result)
    if opt == 't':
        return z, z_l, z_u
    else:
        return z, z_value

def inter_p_value(p_value):
    # interpretation
    if p_value >= 0 and p_value < 0.01:
        inter_p = 'Overwhelming Evidence'
    elif p_value >= 0.01 and p_value < 0.05:
        inter_p = 'Strong Evidence'
    elif p_value >= 0.05 and p_value < 0.1:
        inter_p = 'Weak Evidence'
    elif p_value >= .1:
        inter_p = 'No Evidence'
    return inter_p

def p_value_method(x_mean, h0_mean, h0_std, samp_num, siglevel, option='left', precision=4):
    """
    Input: x_mean, h0_mean, h0_std (standard deviation of population), samp_num (sample size), siglevel (alpha), option='left', precision=4):
    Output: zcv, p_value
    """
    z_value = (x_mean - h0_mean) / (h0_std/(samp_num ** 0.5))
    alpha = siglevel
    opt = option.lower()[0]
    if opt == 't':
        # two-tail test
        option = 'Two-Tail Test'
        p_value = (1 - stats.norm.cdf(z_value)) * 2
        if (p_value > 1):
            p_value = (stats.norm.cdf(z_value)) * 2
        zcv = stats.norm.ppf(1 - siglevel/2)
        flag = p_value < alpha
        sub_result = f'''Using {option}:
Difference = {x_mean - h0_mean}
z (Critical value) = {-zcv:.{precision}f}, {zcv:.{precision}f}
z (Observed value) = {z_value:.{precision}f}
p-value = {p_value:.{precision}f} ({inter_p_value(p_value)})
Reject H_0 → {flag}
        '''
    else:
        if opt == 'l':
            option = 'One-Tail Test (left tail)'
            p_value = stats.norm.cdf(z_value)
            zcv = stats.norm.ppf(siglevel)
        elif opt == 'r':
            option = 'One-Tail Test (right tail)'
            p_value = stats.norm.sf(z_value)
            zcv = stats.norm.ppf(1 - siglevel)
        flag = p_value < alpha
        sub_result = f'''Using {option}:
Difference = {x_mean - h0_mean}
z (Critical value) = {zcv:.{precision}f}
z (Observed value) = {z_value:.{precision}f}
p-value = {p_value:.{precision}f} ({inter_p_value(p_value)})
Reject H_0 → {flag}
        '''

    result = f"""======= p-value Method =======
Mean = {x_mean:.{precision}f}
Number of Observation = {samp_num:.{precision}f}
Hypothesized Mean (H0 Mean) = {h0_mean:.{precision}f}
Assumed Standard Deviation = {h0_std:.{precision}f}
Significant Level (alpha) = {siglevel:.{precision}f}

""" + sub_result

    print(result)

    return zcv, p_value

def power_test(x_mean, h0_mean, std, n, alpha, h1_mean, option='left', precision=4, show=True, ignore=True):
    """
    Input: x_mean (not necessary if ignore=True), h0_mean, std, n, alpha, h1_mean, option='left', precision=4, show=True, ignore=True
    Output: type2_p (beta), ptest (power of a test)
    """
    opt = option.lower()[0]
    if opt == 't':
        option = 'Two-Tail Test'
        x_l, x_u = rejection_region_method(
            x_mean, h0_mean, std, n, alpha, option=opt, precision=precision, show=show, ignore=ignore)
        z_value = stats.norm.ppf(1 - alpha / 2)
        z_l = -z_value
        z_u = z_value
        z_type2_l = (x_l - h1_mean) / (std / (n ** 0.5))
        z_type2_u = (x_u - h1_mean) / (std / (n ** 0.5))
        type2_p_l = stats.norm.cdf(z_type2_l)
        type2_p_u = stats.norm.cdf(z_type2_u)
        type2_p = type2_p_u - type2_p_l
        ptest = 1 - type2_p
        result = f'''======= Evaluating Type II Errors ({option}) =======
μ = {h1_mean}
z (lower bound) = {z_type2_l:.{precision}f}
z (upper bound) = {z_type2_u:.{precision}f}

z_l (Lower bound for the critical value) = {z_l:.{precision}f}
z_u (Upper bound for the critical value) = {z_u:.{precision}f}

x_l (Lower bound for x critical value) = {x_l:.{precision}f}
x_u (Upper bound for x critical value) = {x_u:.{precision}f}

P(Type II Error) = {type2_p:.{precision}f}
Power of a Test = {ptest:.{precision}f}
        '''
    else:
        x_c = rejection_region_method(
            x_mean, h0_mean, std, n, alpha, option=opt, precision=precision, show=show, ignore=ignore)
        # if x_c > h1_mean:
        #     opt = 'l'
        # else:
        #     opt = 'r'

        if opt == 'l':
            option = 'One-Tail Test (left tail)'
            z_c = -stats.norm.ppf(1 - alpha)
            z_type2 = (x_c - h1_mean) / (std / (n ** 0.5))
            type2_p = 1 - stats.norm.cdf(z_type2)
            ptest = 1 - type2_p

        elif opt == 'r':
            option = 'One-Tail Test (right tail)'
            z_c = stats.norm.ppf(1 - alpha)
            z_type2 = (x_c - h1_mean) / (std / (n ** 0.5))
            type2_p = stats.norm.cdf(z_type2)
            ptest = 1 - type2_p

        result = f'''======= Evaluating Type II Errors ({option}) =======
μ = {h1_mean}
z = {z_type2:.{precision}f}

z critical value = {z_c:.{precision}f}
x critical value = {x_c:.{precision}f}

P(Type II Error) = {type2_p:.{precision}f}
Power of a Test = {ptest:.{precision}f}
'''

    if show:
        print(result)

    return type2_p, ptest

def sample_size(h0_mean, h1_mean, std, alpha, beta):
    """
    Input: h0_mean, h1_mean, std (population), alpha, beta
    Output: desired sample size
    """
    z_a = stats.norm.ppf(1 - alpha)
    z_b = stats.norm.ppf(1 - beta)
    n = (((z_a + z_b) * (std))**2) / ((h0_mean - h1_mean) ** 2)
    return n

def power_plot(h0_mean, psigma, nsizes, alpha, ranges, option='r', figsize=(12, 6), show=True):
    means, betas, xticks, yticks = type2_plot(
        h0_mean, psigma, nsizes, alpha, ranges, option=option, figsize=figsize, pf=True, label=True, show=show)
    if show:
        plt.clf()
        plt.plot(means, 1 - betas)
        plt.xticks(xticks, rotation=45, fontsize=8)
        plt.yticks(yticks, fontsize=8)
        plt.title('Power Function Curve')
        plt.margins(x=.01, tight=False)

def type2_plot(h0_mean, psigma, nsizes, alpha, ranges, option='right', figsize=(12, 6), pf=False, label=True, show=True):
    """
    Caution: 外面要自己 plt.show()

    Input: h0_mean, psigma, nsizes (list or one value), alpha, ranges, option='right', figsize=(12, 6), pf=False, label=True, show=True
    → set show to false to only get the values for powers
    Output: (if pf=True: means, betas, xticks, yticks)
    """

    try:
        _ = iter(nsizes)
    except TypeError as te:
        nsizes = [nsizes]

    opt = option.lower()[0]
    # options
    if opt == 'r':
        zcv = stats.norm.ppf(1-alpha)
    elif opt == 'l':
        zcv = -stats.norm.ppf(1-alpha)
    elif opt == 't':
        zcv = stats.norm.ppf(1 - alpha / 2)

    means = np.arange(ranges[0], ranges[1], 0.1)
    betas = np.zeros(means.shape[0])
    powers = betas.copy()

    if show:
        fig, ax = plt.subplots(figsize=figsize)

    for nsize in nsizes:
        means = np.arange(ranges[0], ranges[1], 0.1)
        betas = np.zeros(means.shape[0])
        powers = betas.copy()
        i = 0
        if opt == 'r':
            x_c = h0_mean + zcv * psigma / (nsize ** 0.5)
            for h1_mean in means:
                z_type2 = (x_c - h1_mean) / (psigma / (nsize ** 0.5))
                type2_p = stats.norm.cdf(z_type2)
                betas[i] = type2_p
                powers[i] = 1 - type2_p
                i += 1
        elif opt == 'l':
            x_c = h0_mean + zcv * psigma / (nsize ** 0.5)
            for h1_mean in means:
                z_type2 = (x_c - h1_mean) / (psigma / (nsize ** 0.5))
                type2_p = 1 - stats.norm.cdf(z_type2)
                betas[i] = type2_p
                powers[i] = 1 - type2_p
                i += 1
        elif opt == 't':
            x_u = h0_mean + zcv * psigma / math.sqrt(nsize)
            x_l = h0_mean - zcv * psigma / math.sqrt(nsize)
            # x_l, x_u = rejection_region_method(_, h0_mean, psigma, nsize, alpha, option=opt, precision=4, show=False, ignore=True)
            for h1_mean in means:
                z_type2_l = (x_l - h1_mean) / (psigma / (nsize ** 0.5))
                z_type2_u = (x_u - h1_mean) / (psigma / (nsize ** 0.5))
                type2_p_l = stats.norm.cdf(z_type2_l)
                type2_p_u = stats.norm.cdf(z_type2_u)
                type2_p = type2_p_u - type2_p_l
                betas[i] = type2_p
                powers[i] = 1 - type2_p
                i += 1

        if pf:
            if show:
                plt.plot(means, betas, label=f'OC ({nsize})')
                plt.plot(means, powers, label=f'PF ({nsize})')
        else:
            if show:
                plt.plot(means, betas, label=f'n = {nsize}')

    if len(ranges) == 3:
        xticks = np.arange(ranges[0], ranges[1] + 1, ranges[2])
    else:  # default
        xticks = np.arange(ranges[0], ranges[1] + 1, 1)
    yticks = np.arange(0, 1.1, .1)

    if show:
        plt.xlabel("H1 Mean")
        plt.xticks(xticks, rotation=45, fontsize=8)
        plt.yticks(yticks, fontsize=8)
        plt.ylabel("Probability of a Type II Error")
        plt.margins(x=.01, tight=False)
        if label:
            plt.legend()

    if pf:
        return means, betas, xticks, yticks

# 2021-04-18

def _single_pop(url=None):
    quit_signal = ['quit', 'q', 'Q', 'Quit', 'QUIT', 'exit']
    print('Describe a single population:')
    cmd = (input(f'''Data Type?
1. Interval
2. Nominal
'''))
    while(cmd not in quit_signal):
        try:
            cmd = int(cmd)
        except:
            pass
        if cmd == 1:
            cmd = (input(f'''Type of descriptive measurements?
1. Central location
2. Variability
'''))
            try:
                cmd = int(cmd)
            except:
                pass
            dic = {1: 't-test and estimator of mu',
                   2: 'chi2-test and estimator of sigma2'}
            print(dic[cmd])
        elif cmd == 2:
            cmd = (input(f'''Number of categories?
1. Two
2. Two or more
'''))
            try:
                cmd = int(cmd)
            except:
                pass
            dic = {1: 'z-test and estimator of p',
                   2: f'chi2-goodness-of-fit test (code: {url}/MGT2002/workflow/Chi-Squared-Tests-Workflow/#goodness-of-fit-test-a-multinomial-population)'}
            print(dic[cmd])

        break

def _experimental_design(url=None):
    quit_signal = ['quit', 'q', 'Q', 'Quit', 'QUIT', 'exit']
    cmd = (input(f'''Experimental design?
1. Independent samples
2. Matched Pairs
'''))
    while(cmd not in quit_signal):
        try:
            cmd = int(cmd)
        except:
            pass
        if cmd == 1:
            cmd = (input(f'''Population distributions?
1. Normal
2. Nonnormal
'''))
            try:
                cmd = int(cmd)
            except:
                pass
            dic = {
                1: _variance, 2: f'Wilcoxon Rank Sum Test ({url}/MGT2002/Chap-19-Nonparametric-Methods/#python-code-for-wilcoxon-rank-sum-test | code: {url}/MGT2002/workflow/Nonparametric-Methods-Workflow/#wilcoxon-rank-sum-test)'}
            if callable(dic[cmd]):
                dic[cmd](url=url)
            else:
                print(dic[cmd])
            # if type(dic[cmd]) == str:
            #     print(dic[cmd])
        elif cmd == 2:
            cmd = (input(f'''Distribution of differences?
1. Normal
2. Nonnormal
'''))
            try:
                cmd = int(cmd)
            except:
                pass
            dic = {1: f't-test and estimator of \mu_D (code: {url}/MGT2002/workflow/Difference-Between-Two-Means/#matched-pair-experiment)',
                   2: f'Wilcoxon Signed Rank Sum Test (code: {url}/MGT2002/workflow/Nonparametric-Methods-Workflow/#wilcoxon-signed-rank-sum-test)'}
            print(dic[cmd])

        break

def _variance(url=None):
    quit_signal = ['quit', 'q', 'Q', 'Quit', 'QUIT', 'exit']
    cmd = (input(f'''Population variances?
1. Equal
2. Unequal
'''))
    while(cmd not in quit_signal):
        try:
            cmd = int(cmd)
        except:
            pass
        dic = {1: f't-test and estimator of \mu_1 - \mu_2 (equal-variances) ({url}/MGT2002/Chap-13-Inference-about-Comparing-Two-Population/#python-code-and-interpretation) \n code: {url}/MGT2002/workflow/Difference-Between-Two-Means/#independent-samples',
               2: f't-test and estimator of \mu_1 - \mu_2 (unequal-variances) ({url}/MGT2002/Chap-13-Inference-about-Comparing-Two-Population/#python-code-and-interpretation) \n code: {url}/MGT2002/workflow/Difference-Between-Two-Means/#independent-samples'}
        print(dic[cmd])
        break

def _two_pop(url=None):
    quit_signal = ['quit', 'q', 'Q', 'Quit', 'QUIT', 'exit']
    cmd = (input(f'''Data Type?
1. Interval
2. Ordinal
3. Nominal
'''))
    while(cmd not in quit_signal):
        try:
            cmd = int(cmd)
        except:
            pass
        if cmd == 1:
            cmd = (input(f'''Type of descriptive measurements?
1. Central location
2. Variability
'''))
            try:
                cmd = int(cmd)
            except:
                pass
            dic = {1: _experimental_design,
                   2: 'chi2-test and estimator of sigma2'}
            if callable(dic[cmd]):
                dic[cmd](url=url)
            else:
                print(dic[cmd])
            # if type(dic[cmd]) == str:
            #     print(dic[cmd])
        elif cmd == 2:
            cmd = (input(f'''Experimental Design?
1. Independent samples
2. Matched pairs
'''))
            try:
                cmd = int(cmd)
            except:
                pass
            dic = {
                1: f'Wilcoxon Rank Sum Test ({url}/MGT2002/Chap-19-Nonparametric-Methods/#python-code-for-wilcoxon-rank-sum-test | code: {url}/MGT2002/workflow/Nonparametric-Methods-Workflow/#wilcoxon-rank-sum-test)', 2: f'Sign Test (code: {url}/MGT2002/workflow/Nonparametric-Methods-Workflow/#sign-test)'}
            print(dic[cmd])
        elif cmd == 3:
            cmd = (input(f'''Number of categories?
1. Two
2. Two or more
'''))
            try:
                cmd = int(cmd)
            except:
                pass
            dic = {
                1: f'z-test and estimator of p_1 - p_2 ({url}/MGT2002/Chap-13-Inference-about-Comparing-Two-Population/#python-code-and-interpretation_2) \n code: {url}/MGT2002/workflow/Difference-Between-Two-Means/#the-difference-between-two-population-proportions', 2: f'chi2-test of a contingency table ({url}/MGT2002/Chap-15-Chi-Squared-Tests/#python-code-for-contingency-test | code: {url}/MGT2002/workflow/Chi-Squared-Tests-Workflow/#tests-of-independence-contingency-table)'}
            print(dic[cmd])

        break

def _pop_dist(url=None):
    quit_signal = ['quit', 'q', 'Q', 'Quit', 'QUIT', 'exit']
    cmd = (input(f'''Population distributions?
1. Normal
2. Nonnormal
'''))
    while(cmd not in quit_signal):
        try:
            cmd = int(cmd)
        except:
            pass
        dic = {1: f'One-way and two-factor analysis of variance \nOne-way: {url}/MGT2002/Chap-14-I-Analysis-of-Variance-ANOVA/#testing-for-the-equality-of-k-population-means | code: {url}/MGT2002/workflow/One-way-ANOVA-workflow/#one-way-anova-workflow \nTwo-factor: | code: {url}/MGT2002/workflow/Two-way-ANOVA-workflow/#two-way-anova-two-factors-workflow',
               2: f'Kruskal-Wallis Test (code: {url}/MGT2002/workflow/Nonparametric-Methods-Workflow/#kruskal-wallis-test)'}
        print(dic[cmd])
        break

def _pop_dist_2(url=None):
    quit_signal = ['quit', 'q', 'Q', 'Quit', 'QUIT', 'exit']
    cmd = (input(f'''Population distributions?
1. Normal
2. Nonnormal
'''))
    while(cmd not in quit_signal):
        try:
            cmd = int(cmd)
        except:
            pass
        dic = {
            1: f'Randomized block analysis of variance ({url}/MGT2002/Chap-14-II-Analysis-of-Variance-ANOVA/#randomized-block-anova-test | code: {url}/MGT2002/workflow/Two-way-ANOVA-Randomized-Block-workflow/#two-way-anova-randomized-block-workflow)', 2: f'Friedman Test (code: {url}/MGT2002/workflow/Nonparametric-Methods-Workflow/#friedman-test)'}
        print(dic[cmd])
        break

def _two_or_more_pop(url=None):
    quit_signal = ['quit', 'q', 'Q', 'Quit', 'QUIT', 'exit']
    cmd = (input(f'''Data Type?
1. Interval
2. Ordinal
3. Nominal
'''))
    while(cmd not in quit_signal):
        try:
            cmd = int(cmd)
        except:
            pass
        if cmd == 1:
            cmd = (input(f'''Experimental design?
1. Independent samples
2. Blocks
'''))
            try:
                cmd = int(cmd)
            except:
                pass
            dic = {1: _pop_dist, 2: _pop_dist_2}
            if callable(dic[cmd]):
                dic[cmd](url=url)
            else:
                print(dic[cmd])

        elif cmd == 2:
            cmd = (input(f'''Experimental Design?
1. Independent samples
2. Blocks
'''))
            try:
                cmd = int(cmd)
            except:
                pass
            dic = {
                1: f'Kruskal-Wallis Test (code: {url}/MGT2002/workflow/Nonparametric-Methods-Workflow/#kruskal-wallis-test)', 2: f'Friedman Test (code: {url}/MGT2002/workflow/Nonparametric-Methods-Workflow/#friedman-test)'}
            print(dic[cmd])
        elif cmd == 3:
            print(
                f'chi2-test of a contingency table ({url}/MGT2002/Chap-15-Chi-Squared-Tests/#python-code-for-contingency-test | code: {url}/MGT2002/workflow/Chi-Squared-Tests-Workflow/#tests-of-independence-contingency-table)')

        break

def _relationship(url=None):
    quit_signal = ['quit', 'q', 'Q', 'Quit', 'QUIT', 'exit']
    cmd = (input(f'''Data Type?
1. Interval
2. Ordinal
3. Nominal
'''))
    while(cmd not in quit_signal):
        try:
            cmd = int(cmd)
        except:
            pass
        if cmd == 1:
            cmd = (input(f'''Population distributions?
1. Error is normal or x and y bivariate normal
2. x and y not bivariate normal
'''))
            try:
                cmd = int(cmd)
            except:
                pass
            dic = {1: f'Simple linear regression and correlation (code: {url}/MGT2002/workflow/Nonparametric-Methods-Workflow/#pearson-correlation-coefficient)',
                   2: f'Spearman rank correlation (code: {url}/MGT2002/workflow/Nonparametric-Methods-Workflow/#spearman-rank-correlation-coefficient)'}
            if type(dic[cmd]) == str:
                print(dic[cmd])
        elif cmd == 2:
            print(
                f'Spearman rank correlation (code: {url}/MGT2002/workflow/Nonparametric-Methods-Workflow/#spearman-rank-correlation-coefficient)')
        elif cmd == 3:
            print(
                f'chi2-test of a contingency table ({url}/MGT2002/Chap-15-Chi-Squared-Tests/#python-code-for-contingency-test | code: {url}/MGT2002/workflow/Chi-Squared-Tests-Workflow/#tests-of-independence-contingency-table)')

        break

def which(location='local'):
    url = ''
    if (location == 'local'):
        url += 'http://127.0.0.1:8000'
    else:
        url = location
    quit_signal = ['quit', 'q', 'Q', 'Quit', 'QUIT', 'exit']
    cmd = input(f'''Declare objective:
1. Describe a single population
2. Comapre two populations
3. Compare two or more populations
4. Analyze relationships between two variables

(type 'quit' to quit the program)
''')
    while(cmd not in quit_signal):
        try:
            cmd = int(cmd)
        except:
            pass
        if cmd == 1:
            _single_pop(url=url)
        elif cmd == 2:
            _two_pop(url=url)
        elif cmd == 3:
            _two_or_more_pop(url=url)
        elif cmd == 4:
            _relationship(url=url)

        cmd = input(f'''=======
Declare objective:
1. Describe a single population
2. Comapre two populations
3. Compare two or more populations
4. Analyze relationships between two variables

(type 'quit' to quit the program)
''')


"""
This script shows how to do linear regression with tensorflow.
"""

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

# Generating some sample data
train_X = np.array([3.3,4.4,5.5,6.71,6.93,4.168,9.779,6.182,7.59,2.167,7.042,10.791,5.313,7.997,5.654,9.27,3.1])
train_Y = np.array([1.7,2.76,2.09,3.19,1.694,1.573,3.366,2.596,2.53,1.221,2.827,3.465,1.65,2.904,2.42,2.94,1.3])
num_samples = train_X.shape[0]

# Parameters
learning_rate = 0.01
iterations = 2000

### ------ ** Creating the graph ** -------

# Placeholders - where the data can come into the graph
X = tf.placeholder(tf.float32, [None])
Y = tf.placeholder(tf.float32, [None])

# Creating the parameters for y = mx + c
c = tf.Variable(np.random.randn(), name='c')
m = tf.Variable(np.random.randn(), name='m')

# Creating the model: y = mx + c
model = tf.add(c, tf.multiply(m, X))

# Creating the cost function
cost_function = 0.5 * (1.0/num_samples) * tf.reduce_sum(tf.pow(model - Y, 2))

# Defining the method to do the minimisation of the cost function
optimiser = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost_function)

### -------- ** Initialising all the variables ** --------

init = tf.global_variables_initializer()

### -------- ** Starting the session ** ----------

with tf.Session() as sess:
    sess.run(init)

    for i in range(iterations):
        sess.run(optimiser, feed_dict={X: train_X, Y: train_Y})

        if (i+1)%50 == 0:
            cost = sess.run(cost_function, feed_dict={X: train_X, Y: train_Y})
            print("Step:", '%04d' % (i+1), "cost=", "{:.9f}".format(cost), "m=", sess.run(m), "c=", sess.run(c))

    slope = sess.run(m)
    intercept = sess.run(c)

### -------- ** Plotting the results ** ------------

sns.set()
fig, ax = plt.subplots()
ax.scatter(train_X, train_Y)
plot_x = [np.amin(train_X)-2, np.amax(train_X)+2]
plot_y = [slope*plot_x[0] + intercept , slope*plot_x[1] + intercept ]
ax.plot(plot_x, plot_y, color=sns.xkcd_rgb["medium green"])
ax.set_xlabel('x')
ax.set_ylabel('y')

plt.show()


import numpy as np

def softmax_single_array(N = 5):
    """
    Returns the probability of each of the output nodes
    """
    #Final output of a neural network
    a = np.random.randn(5)
    # These values represent the output of the output neurons
    #start by exponetiating the values:
    exp_a = np.exp(a)
    prob_answer_sin = exp_a / exp_a.sum()

    return prob_answer_sin

def softmax_matrix(N = 100, D = 5):
    """
    Returns the probability of each of the output nodes for a matrix of output
    """
    #100 samples in 5 classes
    a = np.random.randn(N, D)

    exp_a = np.exp(a)

    #Use this to sum along the rows, the keepdims is so (100,5) (100,) can be added
    prob_answer_mat = exp_a / exp_a.sum(axis = 1, keepdims = True)

    #shows that each row sums to 1
    print(prob_answer_mat.sum(axis = 1))


import sympy as sp

print('ompute length of an arc of planar curve by SymPy definite integrate')
print('Example 1-04 arclength')
print('Length of arc of parametric curve x(t)=cos^3(t) and y(t)=sin^3(t) from t=0 to t=2pi')

t = sp.Symbol('t')
x = sp.cos(t) ** 3
y = sp.sin(t) ** 3
dx_dt = sp.diff(x, t)
dy_dt = sp.diff(y, t)
print('Symbolic derivative of x(t) is ', dx_dt)
print('Symbolic derivative of y(t) is ', dy_dt)

integrand = sp.sqrt(dx_dt**2 + dy_dt ** 2)
a = 0.
b = 2 * sp.pi
integral = sp.integrate(integrand, (t, a, b))
integral = integral.evalf()
print('Result is ', integral)


import numpy as np
from math import sin, cos, atan, pi
def prvect(v):
	print("( ", end="")
	for i in v:
		print(format(float(i), ".4f"), end=" ")
	print(")")

def prmatr(m):
	print("[")
	for i in m:
		prvect(i)
	print("]")

x0 = np.array([0, 0])

F_str = ["{0}-1/2*sin(({0}-{1})/2)", "{1}-1/2*cos(({0}+{1})/2)"]

F = np.array([
	x0[0]-1/2*sin((x0[0]-x0[1])/2),
	x0[1]-1/2*cos((x0[0]+x0[1])/2)
])

A = np.array([
	[1 - 1/4*cos((x0[0]-x0[1])/2), 1/4*cos((x0[0]-x0[1])/2)],
	[1/4*sin((x0[0]+x0[1])/2), 1+1/4*sin((x0[0]+x0[1])/2)]
])

A1 = np.linalg.inv(A)

x = x0 - A1.dot(F)
x_p = x0.copy()

eps = 10e-8

i = 0

print("Modified Newton")
print(F_str[0].format("x", "y"), "= 0")
print(F_str[1].format("x", "y"), "= 0", end="\n")

print("\nA: ")
prmatr(A)

print("\nF'(x0):")
prvect(F)

print("\n")

while np.linalg.norm(x-x_p) > eps and i < 100:

	x_p = x.copy()
	F[0] = eval(F_str[0].format(x_p[0], x_p[1]))
	F[1] = eval(F_str[1].format(x_p[0], x_p[1]))
	x = x - A1.dot(F)
	i+=1

print("Answer:")
prvect(x)

print("Steps: ", i)

print("\n======================\n")

def find_absmax(A):
	temp = np.absolute(A)
	max_el = -1
	ind = (0, 1)
	for i in range(len(temp)):
		for j in range(len(temp[i])):
			if i == j:
				continue
			if temp[i, j] > max_el:
				max_el = temp[i, j]
				ind = (i, j)
	return ind

def find_max(A):
	temp = np.absolute(A)
	max_el = -1
	for i in range(len(temp)):
		for j in range(len(temp[i])):
			if i == j:
				continue
			if temp[i, j] > max_el:
				max_el = temp[i, j]
	return max_el

def count_non_d(A):
	res = 0
	for i in range(len(A)):
		for j in range(len(A[i])):
			if i == j:
				continue
			res += A[i, j] ** 2
	return res

print("Jacobi\n")

print("A0:")

A = np.array([
	[5, -1, 1],
	[-1, 0, -2],
	[1, -2, 1]
])
prmatr(A)
count = 1
while count < 10000 and find_max(A) > eps:
	count+=1
	V = np.eye(3)

	i0, j0 = find_absmax(A)
	phi = 1/2*atan(2*A[i0, j0]/(A[i0, i0] - A[j0, j0])) if A[i0, i0] != A[j0, j0] else pi/4

	V[i0, i0] = cos(phi)
	V[i0, j0] = -sin(phi)
	V[j0, i0] = sin(phi)
	V[j0, j0] = cos(phi)

	A = V.T.dot(A.dot(V))
print("\nResult:")
prmatr(A)
print("\nSteps: ", count)


import numpy as np

def softmax(x: np.ndarray) -> np.ndarray:
    return np.exp(x)/np.exp(x).sum(axis=1).reshape(1,-1).T


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

tn = 1000  # end time
h = 1  # step size
t = np.arange(start=0, stop=tn, step=h, dtype=float)  # time array

m0: float = 1  # initial mass
t12: float = 100  # half life
dc = math.log(2) / t12  # decay constant

m_1 = np.zeros([tn])  # array for analytical solution

m_2 = np.zeros([tn])  # array for numerical solution
m_2[0] = m0

for i in range(0, tn):  # solving decay equation analytically
    m_1[i] = m0 * math.exp(- dc * t[i])

for j in range(1, tn):  # solving decay equation numerically
    m_2[j] = m_2[j-1] + h * (-dc * m_2[j-1])

# mpl.plot(t, m_1) # plotting analytical solution
plt.plot(t, m_2)  # plotting numerical solution
plt.xlabel("seconds")
plt.ylabel("mass (kg)")
plt.title("Spontaneous nuclear decay")
plt.show()  # showing graph


"""
Created on Tue Sep 14 2018
@author: Supratim Haldar
@Description: My implementation of logistic regression (classifier) algorithm
"""
import numpy as np
from scipy import optimize

# =============================================================================
# Function to calculate value Sigmoid Function of any variable z.
# z can be a matrix, vector or scalar
# sigmoid g(z) = 1/(1 + e^-z)
# =============================================================================
def sigmoid(z):
    sig = 1.0/(1.0 + np.exp(-z))

    # Due to floating point presision related issues, e^-z might return very
    # small or very large values, resulting in sigmoid = 1 or 0. Since we will
    # compute log of these values later in cost function, we want to avoid
    # sig = 1 or 0, and hardcode to following values instead.
    sig[sig == 1.0] = 0.9999
    sig[sig == 0.0] = 0.0001

    return sig

# =============================================================================
# Compute cost of Logistic Regression with multiple features
# Vectorized implementation
# Input: data_X = mxn matrix, data_y = m-dim vector, theta = n-dim vector
# Output: cost = 1-dim vector
# =============================================================================
def computeCost(theta, data_X, data_y, lambda_reg = 0):
    m = len(data_X) # No of rows
    n = len(data_X[0]) # No of features
    theta = theta.reshape(n,1)

    # h(x) = g(z) = g(theta0 + theta1*X1 + theta2*X2 + .. + thetan*Xn)
    # h(x) = g(X * theta) = Sigmoid(X * theta) = m-dim vector
    hx = sigmoid(np.dot(data_X, theta))
    cost = - np.dot(data_y.T, np.log(hx)) - np.dot((1 - data_y).T, np.log(1 - hx))

    # This is unregularized cost
    J = cost/m

    # Adding regularization. Setting theta0 to 0, because theta0 will not be
    # regularized
    J_reg = (lambda_reg/(2*m)) * np.dot(theta[1:,:].T, theta[1:,:])
    J = J + J_reg

    return J

# =============================================================================
# Compute gradient or derivative of cost function over parameter, i.e.
# d J(Theta)/d Theta
# =============================================================================
def computeGradient(theta, data_X, data_y, lambda_reg = 0):
    m = len(data_X) # No of rows
    n = len(data_X[0]) # No of features
    theta = theta.reshape(n,1)
    theta_gradient = np.zeros(theta.shape)
    cost = 0
    #print("==== Inside computeGradient() ====", data_X.shape, data_y.shape)

    cost = computeCost(theta, data_X, data_y, lambda_reg)

    hx = sigmoid(np.dot(data_X, theta))
    error = hx - data_y
    theta_gradient = (1/m) * (np.dot(data_X.T, error))

    # Apply regularization
    theta_reg = (lambda_reg/m) * theta[1:,:]
    theta_gradient[1:,:] = theta_gradient[1:,:] + theta_reg

    #print("==== Inside computeGradient() ====", cost)
    return cost.flatten(), theta_gradient.flatten()

# =============================================================================
# Gradient Descent of Linear Regression with multiple features
# Vectorized implementation
# Input: data_X = mxn matrix, data_y = m-dim vector, theta = n-dim vector
# alpha = learning rate, num_iters = no of iterations/steps for GD
# Output: theta = n-dim vector,
# J_history = cost at each iteration, a num_iters-dim vector
# =============================================================================
def gradientDescent(theta, data_X, data_y, alpha, num_iters, lambda_reg = 0):
    m = len(data_X) # No of rows
    J_history = np.zeros([num_iters, 1])

    for i in range(num_iters):
        hx = np.zeros(data_y.shape)
        error = np.zeros(data_y.shape)
        theta_change = np.zeros(theta.shape)

        hx = sigmoid(np.dot(data_X, theta))
        error = hx - data_y
        theta_change = (alpha/m) * (np.dot(data_X.T, error))

        # Apply regularization
        temp = theta[0,0]
        theta[0,0] = 0
        theta_reg = (lambda_reg/m) * theta
        theta[0,0] = temp;
        theta_change = theta_change + theta_reg

        theta = theta - theta_change

        J_history[i] = computeCost(theta, data_X, data_y, lambda_reg)

    return theta, theta_change, J_history

# =============================================================================
# Predict results based on test input feature and parameter values
# Compare with output results, if already available
# =============================================================================
def predict(theta, data_X, data_y):
    prob = sigmoid(np.dot(data_X, theta))
    pred = prob >= 0.5
    accuracy = np.mean((pred == data_y)) * 100
    print("Predict: Prediction Accuracy % =", accuracy)
    return pred, accuracy

# =============================================================================
# One vs All method of logistic regression
# Used for data with multiple clssification outputs
# =============================================================================
def oneVsAll(data_X, data_y, num_labels, lambda_reg):
    n = data_X.shape[1] # No of features
    all_theta = np.zeros([num_labels, n])
    initial_theta = np.zeros([n, 1])
    print("OneVsAll: Shape of X and y: ", data_X.shape, data_y.shape)

    for label in range(num_labels):
        # Calling advanced optimization alogorith to converge gradient
        theta_optimized = optimize.minimize( \
            computeGradient, \
            initial_theta, \
            args=(data_X, data_y == label, lambda_reg), \
            method = "CG",
            jac=True, options={'disp': True, 'maxiter': 100} \
            )
        print("OneVsAll: Optimization Result =", theta_optimized.message, theta_optimized.success)
        theta = theta_optimized.x.reshape(n, 1)
        all_theta[label,:] = theta.T

    return all_theta


'''
Copyright 2019 Agnese Salutari.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License
'''

__author__ = 'Agnese Salutari'

# Dependencies:
from SalutariDiscreteLogProblemSolver import DiscreteLogProblemSolver as DLPS
from random import randint
import sympy

'''
    This file is a SalutariDiscreteLogProblemSolver tester and example of usage.
    The problems SalutariDiscreteLogProblemSolver can solve are Discrete Logarithms Problems:
        a^(x) = b (mod n)
        We know a, b and n; we have to find x.
        Salutari's algorithm solve the problem, step by step, using the following formula:
            a^(x - stepsNumber) = b * a^(-1) (mod n)
        It finds x when it reaches the final form, that is the following:
            a^(x - stepsNumber) = a^(y) (mod n)
            => x = y + stepsNumber
        It works if n is a prime (n = p) and if n is the product of two primes (n = p1 * p2).

        If n is the product of two primes (n = p1 * p2):
            a^(x) = b (mod n);   n = p1 * p2 = product pf two prime numbers
                if a = p1 * k, where k is an integer
                then we have: (p1 * k)^(x) = b (mod p1 * p2).
                So, for the Chinese Remainder Theorem, this can be written as a system of the following two equations:
                    (p1 * k)^(x) = 0^(x) = 0 = b (mod p1)
                    (p1 * k)^(x) = b (mod p2)
                The first equation is 0 = 0.
                We can solve the second equation modulus p2 and then find the solution to the original problem
                (modulus p1 * p2) with Chinese Remainder Theorem:
                    x = x1 + (j * (p1 - 1)) mod (n)
'''

print('PROBLEM 1: Book Problem (n is a prime)')
a = 7
b = 12
n = 41
x = 13
print('a = ' + str(a))
print('b = ' + str(b))
print('n = ' + str(n))
solver = DLPS(a=a, b=b, n=n)
solver.printProblemOnFile(problemTitle='Problem 1 (x=' + str(x) + ').', overwrite=True)
solver.solve()
solver.printSolutionsOnFile(problemTitle='Problem 1 (x=' + str(x) + ').', overwrite=True)

print('###################################################################')

print('PROBLEM 2: Toy Problem (n is a prime)')
a = 2
x = 8
n = 11
b = a ** x % n
print('a = ' + str(a))
print('x = ' + str(x))
print('b = ' + str(b))
print('n = ' + str(n))
solver = DLPS(a=a, b=b, n=n)
solver.printProblemOnFile(problemTitle='Problema 2 (x=' + str(x) + ').')
solver.solve()
solver.printSolutionsOnFile(problemTitle='Problema 2 (x=' + str(x) + ').')

print('###################################################################')

print('PROBLEM 3: Random Problem (n is a prime)')
a = sympy.randprime(10, 100)
x = sympy.randprime(10, 100)
n = sympy.randprime(100, 1000)
b = a ** x % n
print('a = ' + str(a))
print('x = ' + str(x))
print('b = ' + str(b))
print('n = ' + str(n))
solver = DLPS(a=a, b=b, n=n)
solver.printProblemOnFile(problemTitle='Problema 3 (x=' + str(x) + ').')
solver.solve()
solver.printSolutionsOnFile(problemTitle='Problema 3 (x=' + str(x) + ').')

print('###################################################################')

print('PROBLEM 4: Random Problem (n is a prime)')
a = sympy.randprime(100, 1000)
x = sympy.randprime(1000, 10000)
n = sympy.randprime(10000, 100000)
b = a ** x % n
print('a = ' + str(a))
print('x = ' + str(x))
print('b = ' + str(b))
print('n = ' + str(n))
solver = DLPS(a=a, b=b, n=n)
solver.printProblemOnFile(problemTitle='Problema 4 (x=' + str(x) + ').')
solver.solve()
solver.printSolutionsOnFile(problemTitle='Problema 4 (x=' + str(x) + ').')

print('###################################################################')

print('PROBLEM 5: Random Problem (n is a prime)')
a = sympy.randprime(10000, 100000)
x = sympy.randprime(100000, 1000000)
n = sympy.randprime(1000000, 10000000)
b = a ** x % n
print('a = ' + str(a))
print('x = ' + str(x))
print('b = ' + str(b))
print('n = ' + str(n))
solver = DLPS(a=a, b=b, n=n)
solver.printProblemOnFile(problemTitle='Problema 5 (x=' + str(x) + ').')
solver.solve()
solver.printSolutionsOnFile(problemTitle='Problema 5 (x=' + str(x) + ').')

print('###################################################################')

print('PROBLEM 6: Random Problem where: n=2*7, a=k*2, k is a random integer')
p1 = 2
p2 = 7
n = p1 * p2
k = randint(1, 1000) % n
a = (k * p1) % n
x = sympy.randprime(1, n)
b = a ** x % n
print('a = ' + str(a))
print('k = ' + str(k))
print('x = ' + str(x))
print('b = ' + str(b))
print('n = ' + str(n))
solver = DLPS(a=a, b=b, n=n)
solver.printProblemOnFile(problemTitle='Problem 6 (x=' + str(x) + ', n=2*7, a=k*2, k is a random integer).')
solver.solve()
solver.printSolutionsOnFile(problemTitle='Problem 6 (x=' + str(solver.getSolutions()) +
                                        ', n=2*7, a=k*2, k is a random integer).')

print('###################################################################')

print('PROBLEM 7: Random Problem with: n=p1*p2, a=k*p1, p1 and p2 are primes, k is a random integer')
p1 = sympy.randprime(100, 1000)
p2 = sympy.randprime(100, 1000)
n = p1 * p2
k = randint(1, 100)
a = k * p1
x = sympy.randprime(1, n)
n = p1 * p2
b = a ** x % n
print('a = ' + str(a))
print('k = ' + str(k))
print('x = ' + str(x))
print('b = ' + str(b))
print('n = ' + str(n) + ' = ' + str(p1) + ' * ' + str(p2))
solver = DLPS(a=a, b=b, n=n)
solver.printProblemOnFile(problemTitle='Problem 7 (x=' + str(x) + ', n=' + str(p1) + '*' + str(p2) +
                                       ', a=k*p1, p1 e p2 primi, k is a random integer).')
solver.solve()
solver.printSolutionsOnFile(problemTitle='Problem 7 (x=' + str(x) + ', n=' + str(p1) + '*' + str(p2) +
                                       ', a=k*p1, p1 e p2 are primes, k is a random integer).')


import numpy as np

class PolyFit(object):
    """
    Polynomial data fitting
    """
    def __init__(self, order):
        self.order = order
        self.current_fitting = None
        self._valid = False

        self.poly_data = tuple()

    def getFittedData(self):

        return self.poly_data

    def fit(self, first_coord_data, second_coord_data):

        if first_coord_data.size > 0 and second_coord_data.size > 0:
            self.current_fitting = np.polyfit(first_coord_data, second_coord_data, self.order)
            self._valid = True
        else:
            self._valid = False
            self.current_fitting = np.zeros((1,self.order+1))
        return self.current_fitting

    def fillPolyData(self, data_range):
    # Compute the points belonging to the fitted curve
        if self._valid:
            self.poly_data = tuple(self.compute_fitted_fcn_data(data_range))
        else:
            return

    def compute_fitted_fcn_data(self, data_range_first_coord):

        d_range = data_range_first_coord
        first_ax = np.linspace(d_range[0], d_range[1], d_range[1]-d_range[0]-1)
        second_ax = np.polyval(self.current_fitting, first_ax)

        return second_ax, first_ax

    def eval(self, data):

        return np.polyval(self.current_fitting, data)

    def isValid(self):
        return self._valid

    def invalidate(self):
        self._valid = False

    def getCurrentFit(self):
        return self.current_fitting


import sklearn.preprocessing
import numpy as np

#standard data : mean = 0, standard deviation = 1

# x' = (x - mean(x)) / standard deviation(x)

arr = np.array([[1, 100, 2390], [2, 234, 5432], [0, 323, 5555]])

std = sklearn.preprocessing.scale(arr)

print(std)
# [[ 0.         -1.29834493 -1.41338128]
#  [ 1.22474487  0.16365692  0.66467858]
#  [-1.22474487  1.134688    0.7487027 ]]

print(std.mean(axis=0))
# [0.00000000e+00 0.00000000e+00 3.70074342e-17]

print(std.std(axis=0))
# [1. 1. 1.]


import numpy as np
from scipy.optimize import newton_krylov
import matplotlib.pyplot as plt
from scipy import special # special function
from numpy import cosh, zeros_like, mgrid, zeros, ones
# "linspace" return evenly spaced numbers over a specified interval
# "mgrid" returns a dense multi-dimensional mesh grid
# ”zeros_like” return an array of zeros with the same shape and type as a given array
# "zeros" return a new array of given shape and type, filled with zeros
# "ones" return a new array of given shape and type, filled with ones

global source

# simulation parameters
Lx, Ly = 1, 1
nx, ny = 35, 35
hx, hy = Lx/(nx), Ly/(ny+1)
print("Domain length:", Lx, Ly)
print("Number of vertices:", nx, ny)
print("Increments:", hx, hy)

# boundary condition
P_left, P_right = 0, 0
P_top, P_bottom = 0, 0

# set meshgrid
x = np.linspace(0, Lx, nx)
y = np.linspace(hy, Ly - hy, ny)
xv, yv = np.meshgrid(x, y, indexing = 'ij')
#xv, yv = mgrid[0 : Lx : (nx * 1j), hy : Ly - hy : (ny * 1j)]

def d1nc(N):
    d1x = zeros_like(N)
    d1x[:-1] = np.diff(N, axis = 0)/hx
    d1x[:-1] *= (xv[:-1] + xv[1:])/2.0
    #d1x[-1] = 0
    return d1x

def d1cn(C):
    d1x = zeros_like(C)
    d1x[1:] = np.diff(C, axis = 0)/hx
    d1x[1:] /= xv[1:]
    # Apply Neumann Conditions
    d1x[0] = 0
    return d1x

def d2nn(N,N_right):
    d1x = zeros_like(N)
    d1x[:-1] = np.diff(N, axis = 0)/hx
    d1x[-1] = (N_right - N[-1])/hx
    d1x[:-1] *= (xv[:-1] + xv[1:])/2.0

    d2x = zeros_like(d1x)
    d2x[1:] = np.diff(d1x, axis = 0)/hx
    d2x[1:] /= xv[1:]
    # Apply Axis
    d2x[0] = 4 * (N[1] - N[0])/hx/hx
    return d2x

def residual(P):
    d1x = zeros_like(P)
    d2x = zeros_like(P)
    d2y = zeros_like(P)

    #
    #d2x[1:-1] = (P[2:]   - 2*P[1:-1] + P[:-2]) / hx/hx
    #d2x[0]    = (P[1]    - 2*P[0]    + P_left)/hx/hx
    #d2x[-1]   = (P_right - 2*P[-1]   + P[-2])/hx/hx

    #d1x = d1nc(P)
    #d2x = d1cn(d1x)
    #

    d2x = d2nn(P, P_right)

    d2y[:, 1:-1] = (P[:, 2:] - 2*P[:, 1:-1]  + P[:, :-2])/hy/hy
    d2y[:, 0]    = (P[:, 1]  - 2*P[:, 0]     + P_bottom)/hy/hy
    d2y[:, -1]   = (P_top    - 2*P[:, -1]    + P[:, -2])/hy/hy

    return d2x + d2y  + source

def laplacian(P):
    d1x = zeros_like(P)
    d2x = zeros_like(P)
    d2y = zeros_like(P)

    #
    #d2x[1:-1] = (P[2:]   - 2*P[1:-1] + P[:-2])/hx/hx
    #d2x[0]    = (P[1]    - 2*P[0]    + P_left)/hx/hx
    #d2x[-1]   = (P_right - 2*P[-1]   + P[-2])/hx/hx

    #d1x = d1nc(P)
    #d2x = d1cn(d1x)
    #d2x = d2nn(P)
    #

    d1x[:-1] = np.diff(P, axis = 0)/hx
    d1x[:-1] *= (xv[:-1] + xv[1:])/2.0
    #d1x[-1] = 0
    d2x = zeros_like(d1x)
    d2x[1:] = np.diff(d1x, axis = 0)/hx
    d2x[1:] /= xv[1:]

    # Apply Axis
    d2x[0] = 4 * (P[1] - P[0])/hx/hx
    d2x = d2nn(P)
    d2y[:, 0]    = (P[:, 1]  - 2 * P[:, 0]    + P_bottom)/hy/hy
    d2y[:, -1]   = (P_top    - 2 * P[:, -1]   + P[:, -2])/hy/hy

    return d2x + d2y

# solve
kth_zero = special.jn_zeros(0, 1)[-1]
print("kth_zero:", kth_zero)
Bg = pow(np.pi/Ly, 2) + pow(kth_zero/Lx, 2)
source = np.sin(np.pi * yv/Ly) * special.jv(0, kth_zero * xv/Lx)
guess = zeros((nx, ny), float)
sol = newton_krylov(residual, guess, method='lgmres', verbose=1)

print('Residual: %g' % abs(residual(sol)).max())
print('Bg = ', np.max(source)/Bg, '  Numerical = ', np.max(sol))

# visualize
plt.figure(0)
plt.pcolor(xv, yv, sol)
plt.colorbar()

plt.figure(1)
#plt.plot(source.T/Bg/sol)
plt.pcolor(xv, yv, source/Bg)
plt.colorbar()

#plt.figure(2)
#plt.plot(x, sol)
#plt.figure(3)
#plt.plot(x, source/Bg)

plt.show()


import numpy as np

O = np.zeros((2, 3))

A = np.array([
    [2, -2, 5],
    [0, -1, 7],
])

B = np.array([
    [-1, 3, 7],
    [2, -9, 6],
])

C = np.array([
    [9, 5, 8],
    [-6, -1, 6],
])

print("a) A + B")
print(A + B)
print()

print("b) (A + B) + C")
print((A + B) + C)
print()

print("c) A + (B + C)")
print(A + (B + C))
print()

print("d) B + (C + A)")
print(B + (C + A))
print()

print("e) C + O")
print(C + O)

print("f) B + B + B + B + B")
print(B + B + B + B + B)
print()

print("g) 5B")
print(5 * B)
print()

print("h) C + -C")
print(C + -C)
print()


from numpy import *

def compute_error(b, m, points):
    """Compute MSE by given model

    :param b: scalar
    :param m: intercept
    :param points: dataset list
    :return: mean squared error
    """
    sum_error = 0
    N = len(points)

    # compute the sum of squared residuals
    for i in range(N):
        x = points[i, 0]
        y = points[i, 1]
        sum_error += (y - (m * x + b)) ** 2

    # mean squared error
    return sum_error / N

def step_gradient(current_b, current_m, points, learning_rate=0.0001):
    """The gradient step.

    This function update intercept and scalar by using the partial
    derivative of the cost function wrt to b and m.

    :param current_b: current scalar error
    :param current_m: current intercept
    :param points: dataset list
    :param learning_rate: convergence speed
    :return: updated intercept and updated scalar
    """
    gradient_b = 0
    gradient_m = 0
    N = len(points)

    for i in range(N):
        x = points[i, 0]
        y = points[i, 1]

        # partial derivative of the cost function wrt b and m
        gradient_b += -(2 / N) * (y - (current_m * x + current_b))
        gradient_m += -(2 / N) * x * (y - (current_m * x + current_b))

        new_b = current_b - (learning_rate * gradient_b)
        new_m = current_m - (learning_rate * gradient_m)

    return new_b, new_m

def gradient_decent_runner(points, starting_b=0, starting_m=0,
                           learning_rate=0.0001,
                           num_iteration=10000):
    """The gradient descent calculation process

    Results are calculated by gradient steps
    and should converge to optimal (according to number of iteration).

    :param points: dataset list
    :param starting_b: starting scalar
    :param starting_m: starting intercept
    :param learning_rate: convergence speed
    :param num_iteration: number of gradient descent steps
    :return: result intercept and scalar
    """
    # initialization
    b = starting_b
    m = starting_m

    # gradient descent
    for i in range(num_iteration + 1):
        # update b and m
        if i % 100 == 0:
            print('After {} iteration, b = {}, m = {}'.format(i, b, m))
        b, m = step_gradient(b, m, array(points), learning_rate)

    return [b, m]

def run(path, learning_rate=0.0001, initial_b=0, initial_m=0,
        num_iteration=10000):
    """Run a single linear regression process

    :param path: csv file path
    :param learning_rate: convergence speed
    :param initial_b: initial value of scalar
    :param initial_m: initial value of intercept
    :param num_iteration: number of gradient descent steps
    :return: None
    """
    points = genfromtxt(path, delimiter=',')

    print('Starting gradient descent at b = {}, m = {}, error = {}'.format(
        initial_b, initial_m, compute_error(initial_b, initial_m, points)))
    [b, m] = gradient_decent_runner(points, initial_b, initial_m, learning_rate, num_iteration)

    print('Ending point at b = {}, m = {}, error = {}'.format(b, m, compute_error(b, m, points)))

if __name__ == '__main__':
    data_path = 'data.csv'
    learning_rate = 0.0001
    initial_b = 0
    initial_m = 0
    num_iteration = 10000
    run(data_path, learning_rate, initial_b, initial_m, num_iteration)


"""
Home Work 6
Ankit Khandelwal
Exercise 7
15863
"""

from time import perf_counter

import matplotlib.pyplot as plt
import numpy as np
from scipy.linalg import solve_banded
from scipy.stats import linregress

D = 1
NN = [64, 128, 256, 512, 1024]
ans = []
count = 0

for N in NN:
    dx = 1 / N
    dt = 4 * dx ** 2 / D

    bi = 1 + 2 * D * dt / dx ** 2
    ai = -D * dt / dx ** 2
    ci = -D * dt / dx ** 2

    u = np.zeros((N, 1), float)
    v = np.zeros((N, 1), float)
    v[0][0] = 1
    v[N - 1][0] = -ai / bi
    u[0][0] = -bi
    u[N - 1][0] = ci

    A_banded = np.zeros((3, N), float)
    A_banded[0, 1:] = ci
    A_banded[1, :] = bi
    A_banded[2, :N - 1] = ai

    A_banded[1][0] = 2 * bi
    A_banded[1][N - 1] = ai * ci / bi + bi

    tv = np.linspace(0, 1, 1 / dt)
    xv = np.linspace(0, 1, N)
    f = np.zeros((N, 1), float)
    for i in range(N):
        if xv[i] > 0.4 and xv[i] < 0.6:
            f[i][0] = 1
    y = np.ones((N, 1), float)
    q = np.ones((N, 1), float)
    t1 = perf_counter()
    for t in tv:
        y = solve_banded((1, 1), A_banded, f, overwrite_b=True, check_finite=False)
        q = solve_banded((1, 1), A_banded, u, overwrite_b=False, check_finite=False)
        f = y - q @ ((v.T @ y) / (1 + v.T @ q))
        if count == 0 and t >= 0.025 and N == 256:
            plt.plot(xv, f, label='Time 0.025 sec, N = {}'.format(N))
            plt.legend()
            plt.xlabel('X')
            plt.ylabel('f')
            plt.figure()
            count = 1
    ans.append(f)
    t2 = perf_counter()
xpoints = []
ypoints = []
for i in range(len(NN) - 1):
    error = 0
    for j in range(NN[i]):
        error = error + float(abs(ans[i][j] - ans[i + 1][2 * j]))
    plt.scatter(1 / NN[i], error / NN[i], marker=10)
    xpoints.append(1 / NN[i])
    ypoints.append(error / NN[i])
    plt.xscale('log')
    plt.yscale('log')
    plt.xlabel('dx')
    plt.ylabel('Error')
slope = linregress(xpoints, ypoints)[0]
plt.show()

Ankit Khandelwal_HW6/Exercise 7/exercise 7 banded.py


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

def karatsuba(x, y):
    """ Recursive implementation of Karatsuba's Fast Mulciplication Algoritihm

    :param x: The first integer
    :param y: The second integer
    :return: The product of x * y
    """
    if x < 10 or y < 10:
        return x*y

    m = max(len(str(x)), len(str(y))) // 2

    x_high = x // 10**m
    x_low = x % 10**m
    y_high = y // 10**m
    y_low = y % 10**m

    z0 = karatsuba(x_low, y_low)
    z1 = karatsuba(x_low + x_high, y_low + y_high)
    z2 = karatsuba(x_high, y_high)

    return z2 * 10 ** (2 * m) + (z1 - z2 - z0) * 10 ** m + z0

def karat_compare(max_size, tests):
    samples = []
    test_sizes = np.linspace(1,max_size, tests).astype(int)
    standard_results = []
    karatsuba_results = []
    for test_size in test_sizes:
        x_str = ''
        y_str = ''
        for x in range(test_size):
            x_str += str(random.randint(0,9))
            y_str += str(random.randint(0,9))
        samples.append((int(x_str), int(y_str)))
    print(f"Samples Generated: {len(samples)}, with max size: {max_size}")

    for sample, test_size in zip(samples, test_sizes):
        print(f"Attempting numbers of 10^{test_size}")
        x = sample[0]
        y = sample[1]

        t_start = time.perf_counter()
        r = x * y
        standard_results.append(time.perf_counter() - t_start)

        t_start = time.perf_counter()
        r = karatsuba(x, y)
        karatsuba_results.append(time.perf_counter() - t_start)

    plt.plot(test_size, standard_results, label="python native")
    plt.plot(test_size, karatsuba_results, label="karatsuba")
    plt.xlabel("10^x")
    plt.ylabel("Seconds")
    plt.legend()
    plt.show()

def naive_matrix_multiplication_lists(a, b):
    """
    Uses nested loops to calculate AB
    :param a: An MxN matrix of numbers.
    :param b: An NxP matrix of numbers.
    :return: An MxP matrix of numbers which is the product: AB.
    """
    M = len(a)
    N = len(a[0])
    if len(b) != N:
        raise ValueError("The Matrices Provide are not the proper shape.")
    P = len(b[0])

    c = [[0 for i in range(P)] for j in range(M)]

    for i in range(0,M):
        for j in range(0,P):
            for k in range(0,N):
                c[i][j] += a[i][k] * b[k][j]
    return c

def naive_matrix_multiplication_np(a,b):
    M, N = a.shape
    n, P = b.shape

    if N != n:
        raise ValueError("The Matrices Provide are not the proper shape.")

    c = np.zeros((M,P))

    for i in range(0,M):
        for j in range(0,P):
            for k in range(0,N):
                c[i][j] += a[i][k] * b[k][j]
    return c

if __name__ == "__main__":
    a = [[1, 2, 5],
         [3, 4, 6]]

    b = [[5, 6],
         [7, 8],
         [1, 1]]

    c = naive_matrix_multiplication_lists(a, b)
    print("List Results:\n", c)

    A = np.array(a)
    B = np.array(b)
    C = naive_matrix_multiplication_np(A, B)
    print("NP Array Results:\n", C)

    expected_results = np.array([[24, 27], [49, 56]])
    print("Expected Results:\n", expected_results)


import matplotlib.pyplot as plt

import pandas as pd
import numpy as np
#nbr_items = 200_000_000

nbr_items = 99
yp = np.linspace(0.01, 0.99, nbr_items)
yt = np.ones(nbr_items)
answer = -(yt * np.log(yp) + ((1-yt) * (np.log(1-yp))))

yt0 = np.zeros(nbr_items)
answer0 = -(yt0 * np.log(yp) + ((1-yt0) * (np.log(1-yp))))

df = pd.DataFrame({'yp': yp, 'yt': yt, 'cross_entropy': answer, 'cross_entropy0': answer0})

fig, axs = plt.subplots(ncols=2)
ax = axs[0]
df.plot(x='yp', y='cross_entropy', ax=ax, label='Error for yt==1')
df.plot(x='yp', y='cross_entropy0', ax=ax, label='Error for yt==0', linestyle='--')
ax.set_ylabel('Cross Entropy or Error (smaller is better)')
ax.set_xlabel('Predicted Probability (yp)')
ax.set_title('Cross Entropy error for targets yt 0 and 1')

ax = axs[1]
logs = np.log(yp)
df_log = pd.DataFrame({'yp': yp, 'log_yp': logs})
df_log.plot(x='yp', y='log_yp', ax=ax)
ax.set_title('Natural Log for x==[0, 1]')
ax.set_xlabel('Predicted Probability (yp)')

plt.tight_layout()
plt.savefig('cross_entropy.png')


# Diagonalizing a Tridiagonal Toeplitz matrix
from math import cos, pi, log10
import numpy as np
#Function for initialization of parameters
def initialize():
    RMin = 0.0
    RMax = 1.0
    Dim = 100
    return RMin, RMax, Dim

#Get the boundary and number of integration points
RMin, RMax, Dim = initialize()

#Initialize constants, step size and the constant values of the diagonal and non-diagonal elements
Step    = RMax/(Dim+1)
DiagConst = 2.0 / (Step*Step)
NondiagConst =  -1.0 / (Step*Step)

#Setting up a tridiagonal matrix
Hamiltonian = np.zeros((Dim,Dim))
Hamiltonian[0,0] = DiagConst
Hamiltonian[0,1] = NondiagConst
for i in range(1,Dim-1):
    Hamiltonian[i,i-1]  = NondiagConst
    Hamiltonian[i,i]    = DiagConst
    Hamiltonian[i,i+1]  = NondiagConst
Hamiltonian[Dim-1,Dim-2] = NondiagConst
Hamiltonian[Dim-1,Dim-1] = DiagConst
# diagonalize and obtain eigenvalues, not necessarily sorted
EigValues, EigVectors = np.linalg.eig(Hamiltonian)
# sort eigenvectors and eigenvalues
permute = EigValues.argsort()
EigValues = EigValues[permute]
EigVectors = EigVectors[:,permute]
# compute  the difference between the numerical and exact eigenvalues
for i in range(Dim):
    lambda_i = DiagConst+2*NondiagConst*cos((i+1)*pi*Step)
    print(abs(EigValues[i]-lambda_i))


import numpy as np
import matplotlib.pyplot as plt
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis
from sklearn.neighbors import KNeighborsClassifier
from matplotlib.colors import ListedColormap
from sklearn.naive_bayes import GaussianNB

def toPairs(item1, item2, size):
    pairs = []
    for i in range(size):
        pairs.append([item1[i], item2[i]])
    return pairs

# part 1
mean1 = [37, 37]
cov = [[4, 0], [0, 4]]
size1 = 10
class1_x, class1_y = np.random.multivariate_normal(mean=mean1, cov=cov, size=size1).T

mean2 = [42, 42]
class2_x, class2_y = np.random.multivariate_normal(mean=mean2, cov=cov, size=size1).T

y11 = [1]*size1
y12 = [2]*size1
ys1 = y11 + y12
size2 = 1000
class3_x, class3_y = np.random.multivariate_normal(mean=mean1, cov=cov, size=size2).T
class4_x, class4_y = np.random.multivariate_normal(mean=mean2, cov=cov, size=size2).T

y21 = [1]*size2
y22 = [2]*size2
ys2 = y21 + y22

# part 2
lda = LinearDiscriminantAnalysis()

x1Pairs = toPairs(class1_x, class1_y, size1) + toPairs(class2_x, class2_y, size1)
x2Pairs = toPairs(class3_x, class3_y, size2) + toPairs(class4_x, class4_y, size2)
lda.fit(x1Pairs, ys1)
test1 = lda.predict(x2Pairs)

print("LDA:")
for i in range(len(test1)):
    print(test1[i])

colors = ListedColormap(['#FF0000', '#0000FF'])

X1 = np.array(x1Pairs)
plt.title('LDA for 10 observations')
plt.xlabel("Input 1")
plt.ylabel("Input 2")
plt.scatter(X1[:, 0], X1[:, 1], c=ys1, cmap=colors)
plt.show()

X2 = np.array(x2Pairs)
plt.title('LDA for 1000 observations')
plt.xlabel("Input 1")
plt.ylabel("Input 2")
plt.scatter(X2[:, 0], X2[:, 1], c=ys2, cmap=colors)
plt.show()

knn = KNeighborsClassifier()
knn.fit(x1Pairs, ys1)
test2 = knn.predict(x2Pairs)

print("KNN:")
for i in range(len(test2)):
    print(test2[i])

cmap_light = ListedColormap(['#FFAAAA', '#AAAAFF'])

plt.title('KNN for 1000 observations')
x_min, x_max = X2[:, 0].min() - 1, X2[:, 0].max() + 1
y_min, y_max = X2[:, 1].min() - 1, X2[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, .02), np.arange(y_min, y_max, .02))
Z = knn.predict(np.c_[xx.ravel(), yy.ravel()])

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

# Plot also the training points
plt.scatter(X2[:, 0], X2[:, 1], c=ys2, cmap=colors)
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())

plt.show()

bayes = GaussianNB()
bayes.fit(x2Pairs, ys2)

qda = QuadraticDiscriminantAnalysis()
qda.fit(x2Pairs, ys2)

#Accuracy
print("LDA Accuracy:  ", lda.score(x2Pairs, ys2))
print("QDA Accuracy:  ", qda.score(x2Pairs, ys2))
print("Bayes Accuracy:", bayes.score(x2Pairs, ys2))
print("KNN Accuracy:  ", knn.score(x2Pairs, ys2))


#! /usr/bin/env python

from sympy.ntheory.primetest import isprime
from sympy import sieve
import time

def quadratic_primes(max_coefficient):
  '''Calculate the product of the coefficients that generate the most primes
  for a sequence of n starting with n=0 of the form:

  n^2 + an + b

  for |a| < max_coefficient and |b| < max_coefficient.
  '''

  b_lst = list(sieve.primerange(1, max_coefficient))

  max_n = 0
  for a in range(-max_coefficient + 1, max_coefficient):
    for b in b_lst:
      n = 0
      while isprime(n**2 + a * n + b):
        n += 1
      if n > max_n:
        max_n = n
        max_product = a * b

  return max_product

if __name__ == '__main__':
  START_TIME = time.time()
  MAX_COEFFICIENT = 1000
  print "Max coefficient:", MAX_COEFFICIENT
  print "Solution:", quadratic_primes(MAX_COEFFICIENT)
  print "Running time: %.2g" % (time.time() - START_TIME)


import numpy as np
import matplotlib.pyplot as plt

default_kappa= 2
default_exit_tax = .02

#value function for a given state (R,S)
def invariant(R,S,kappa=default_kappa):
    return (S**kappa)/R

#given a value function (parameterized by kappa)
#and an invariant coeficient V0
#return Supply S as a function of reserve R
def reserve(S, V0, kappa=default_kappa):
    return (S**kappa)/V0

#given a value function (parameterized by kappa)
#and an invariant coeficient V0
#return Supply S as a function of reserve R
def supply(R, V0, kappa=default_kappa):
    return (V0*R)**(1/kappa)

#given a value function (parameterized by kappa)
#and an invariant coeficient V0
#return a spot price P as a function of reserve R
def spot_price(R, V0, kappa=default_kappa):
    return kappa*R**((kappa-1)/kappa)/V0**(1/kappa)

#for a given state (R,S)
#given a value function (parameterized by kappa)
#and an invariant coeficient V0
#deposit deltaR to Mint deltaS
#with realized price deltaR/deltaS
def mint(deltaR, R,S, V0, kappa=default_kappa):
    deltaS = (V0*(R+deltaR))**(1/kappa)-S
    if deltaS ==0:
        realized_price = spot_price(R+deltaR, V0, kappa)
    else:
        realized_price = deltaR/deltaS
    return deltaS, realized_price

#for a given state (R,S)
#given a value function (parameterized by kappa)
#and an invariant coeficient V0
#burn deltaS to Withdraw deltaR
#with realized price deltaR/deltaS
def withdraw(deltaS, R,S, V0, kappa=default_kappa):
    deltaR = R-((S-deltaS)**kappa)/V0
    if deltaS ==0:
        realized_price = spot_price(R+deltaR, V0, kappa)
    else:
        realized_price = deltaR/deltaS
    return deltaR, realized_price

def withdraw_with_tax(deltaS, R,S, V0, exit_tax = default_exit_tax, kappa=default_kappa):
    deltaR = R-((S-deltaS)**kappa)/V0
    #print(deltaR)
    quantity_taxed = exit_tax*deltaR
    quantity_recieved = (1-exit_tax)*deltaR

    realized_price = quantity_recieved/deltaS

    return quantity_recieved, quantity_taxed, realized_price

def response_plot(rdf, title):
    plt.subplots(figsize=(10,6))
    ax1=plt.subplot(2,1,1)
    rdf[["spot_price","price"]].plot(ax=ax1)
    plt.legend(["spot price (output: $P_t$)", "price sample (input: $\hat P_t$)" ])
    plt.ylabel("Price, $\hat P_t$, $P_t$")
    plt.title(title+" Response Dynamics")
    ax2=plt.subplot(2,1,2)
    rdf[["abs_err"]].plot(ax=ax2,logy=True, color='green')
    plt.legend(["$Error: |P_t-\hat P_t|$" ])
    plt.xlabel("transaction count (time)")
    plt.ylabel("Absolute Value of Estimation Error")
    plt.show()


#
# Copyright 2022 Ocean Protocol Foundation
# SPDX-License-Identifier: Apache-2.0
#
import numpy

def branin_mesh(X0, X1):
    # b,c,t = 5.1/(4.*(pi)**2), 5./pi, 1./(8.*pi)
    b, c, t = 0.12918450914398066, 1.5915494309189535, 0.039788735772973836
    u = X1 - b * X0**2 + c * X0 - 6
    r = 10.0 * (1.0 - t) * numpy.cos(X0) + 10
    Z = u**2 + r

    return Z

def create_mesh(npoints):
    X0_vec = numpy.linspace(-5.0, 10.0, npoints)
    X1_vec = numpy.linspace(0.0, 15.0, npoints)
    X0, X1 = numpy.meshgrid(X0_vec, X1_vec)
    Z = branin_mesh(X0, X1)

    return X0, X1, Z