import numpy as np

class PCA:
    """
    This class implements PCA.

    Args:
        k(int): Number of principle components. If None, k will be set equal to the original dimension.
        whiten(boolean): When True (False by default) the components are multiplied by the square root of (numbers of
                         data - 1) and then divided by the singular values to ensure uncorrelated outputs with
                        unit variances.

    Attributes:
        k(int): Number of principle components. If None, k will be set equal to the original dimension.
        whiten(boolean): whiten or not.
        x: Array of data.
        mean: Array of mean of data.
        components: Array of principle components.
        singular_values: Array of singular values of input data array. Variances after PCA is equals to
                        singular_values ** 2 / (numbers of data - 1).

    Methods:
        PCA.fit: Fit the model with data.
        PCA.transform: Apply PCA model to data.
        PCA.fit_transform: Fit and apply.
        PCA.inverse_transform: Transform data back to its original space.
        PCA.factor_loading: Return the factor loading for all principle components to all dimension.
        PCA.explained_variance: Return the amount/ratio of variance explained by each of the selected components.
    """

    def __init__(self, k = None, whiten = False):
        """
        Constructor method.
        """

        self.k = k
        self.whiten = whiten
        self.x = None
        self.mean = None
        self.components = None
        self.singular_values = None

    def fit(self, x):
        """
        Fit the model with data.

        Args:
            x: array of data.
        """

        self.x = x.copy()
        self.x = self.__check_x(self.x)
        self.mean = np.average(self.x, axis = 0)
        self.x -= self.mean
        self.k = self.x.shape[1] if self.k == None else self.k
        U, S, V = np.linalg.svd(self.x)
        self.singular_values = S[:self.k]
        self.components = V[:self.k, :]
        self.__original_singular_values = S
        self.__original_components = V

    def transform(self, x):

        """
        Apply PCA model to data.

        Args:
            x: array of data.

        Return:
            array of data represented bt the principal components.
        """

        x = self.__check_x(x) - self.mean
        res = np.dot(x, self.components.T) if self.whiten == False \
            else (self.x.shape[0]-1)**0.5 * np.dot(x, self.components.T) / self.singular_values
        return res

    def fit_transform(self, x):
        """
        Fit and apply.

        Args:
            x: array of data.

        Return:
            array of data represented bt the principal components.
        """

        self.fit(x)
        return self.transform(x)

    def inverse_transform(self, x):

        """
        Transform data back to its original space.

        Args:
            x: array of data.

        Returns:
            data in original space.
        """
        x *= self.singular_values / (self.x.shape[0] - 1) ** 0.5 if self.whiten else 1
        return np.dot(x, self.components) + self.mean

    def factor_loading(self):
        """
        Return the factor loading for all principle components to all dimension.

        Return:
            Array-like, shape(number_of_principle_components, number_of_original_dimensions)
        """

        fl = self.components * np.reshape(self.singular_values, [self.k,1])
        fl /= np.diag(np.dot(self.x.T, self.x)) ** 0.5
        return fl

    def explained_variance(self, ratio = True):
        """
        Return the amount/ratio of variance explained by each of the selected components.

        Args:
            ratio: If True, return ratio of variance. If False, returnthe value of variance. Default True.

        Return:
            Array of variance (value/ratio).
        """

        var = self.singular_values ** 2
        all_var = self.__original_singular_values ** 2
        return var / (self.x.shape[0]-1) if not ratio else var / np.sum(all_var)

    def __check_x(self, x):

        """
        Check if x is 2D array. If not, convert.
        Check if dimension matches. If not, raise error.

        Return:
            x in 2D array.
        """

        if x.ndim == 1: x = np.reshape(x, [1, x.shape[0]])
        if x.ndim == 0: x = np.reshape(x, [1, 1])
        if self.k != None and x.shape[1] < self.k: raise ValueError("Dimension should not be smaller than k.")
        if self.x.shape[1] != x.shape[1]: raise  ValueError("Dimension not match.")
        return x


import numpy as np
import scipy as sp
from dml.SVM import SVMC
import matplotlib.pyplot as plt
X=[
[10.75,14.95],
[11.35,14.05],
[12,13.65],
[12.75,13.75],
[14.2,14.85],
[13.2,15.8],
[12.1,16.55],
[11.3,15.8],
[12.7,14.7],
[12.8,14.55],
[12.35,15.75],
[8.55,17.2],
[8.15,15.4],
[8.7,13.95],
[9.75,12.25],
[11.9,11.1],
[14.45,11.3],
[16.7,12.9],
[16.9,14.45],
[16.4,15.95],
[15,17.7],
[12.2,18.8],
[9.85,18.45],
[8.2,17.5],
[7.4,15.85],
[7.8,13.6],
[9.6,12.1],
[12.3,11.2],
[14.95,12.2],
[15.2,13.05],
[15.55,13.65],
[15.9,14.6],
[15.5,16.45],
[14.75,17.9],
[13.1,18.5],
[10.8,19.4],
[11.05,18.7]]

y=[
[0],
[0],
[0],
[0],
[0],
[0],
[0],
[0],
[0],
[0],
[0],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
[1],
[1]]
X=np.array(X).transpose()
print X.shape

y=np.array(y).flatten(1)
y[y==0]=-1
print y.shape
def Gauss_kernel(x,z,sigma=1):
		return np.exp(-np.sum((x-z)**2)/(2*sigma**2))
svms=SVMC(X,y,kernel=Gauss_kernel)
svms.train()
print len(svms.supportVec),"SupportVectors:"

for i in range(len(svms.supportVec)):
	t=svms.supportVec[i]
	print svms.X[:,t]
svms.error(X,y)
for i in range(svms.M):
			if  svms.y[i]==-1:
				plt.plot(svms.X[0,i],svms.X[1,i],'or')
			elif  svms.y[i]==1:
				plt.plot(svms.X[0,i],svms.X[1,i],'ob')
for i in svms.supportVec:
			plt.plot(svms.X[0,i],svms.X[1,i],'oy')
plt.show()


##============================ opti_config_ex_4.py ================================

# Config file for the minimization of f1(x) and f2(x) of the TNK function:
# f1(x) = x_1
# f2(x) = x_2
# Subjected to the following constraints:
# x_1^2 - x_2^2 + 1 + 0.1cos(16arctan(x_1/x_2)) < 0
# (x_1 - 0.5)^2 + (x_2 - 0.5)^2 - 0.5 < 0
# Both x_1 and x_2 in the range (0, pi]

print('Minimizing both f1(x) and f2(x) of the TNK function\n')

var_range = [[0, 3.1415926535]]*2
project_name = 'ex_4'
var_names = ['x', 'y']
lim_range_orig = [('lower', 0.0)]*2
max_min = ['min', 'min']
analytical_funcs = True
working_directory = '.'
plotting = True
true_pareto = True

def getFunctionsAnalytical():
    import numpy as np
    def of1(*vars):
        return vars[0]

    def of2(*vars):
        return vars[1]

    def l1(*vars):
        if vars[1] < 1e-9: # to avoid possible division by zero
            return 1
        else:
            return -vars[0] ** 2 - vars[1] ** 2 + 1 + 0.1 * np.cos(16 * np.arctan(vars[0] / vars[1]))

    def l2(*vars):
        return (vars[0] - 0.5) ** 2 + (vars[1] - 0.5) ** 2 - 0.5

    return [[of1, of2], [l1, l2]]


import numpy as np
import gym
from functools import partial

def discretize_val(val, min_val, max_val, num_states):
	"""
	Discretizes a single float
	if val < min_val, it gets a discrete value of 0
	if val >= max_val, it gets a discrete value of num_states-1

	Args:
	    val (float): value to discretize
	    min_val (float): lower bound of discretization
	    max_val (float): upper bound of discretization
	    num_states (int): number of discrete states

	Returns:
	    float: discrete value
	"""
	state = int(num_states * (val - min_val) / (max_val - min_val))
	if state >= num_states:
		state = num_states - 1
	if state < 0:
		state = 0
	return state

def obs_to_state(num_states, lower_bounds, upper_bounds, obs):
	"""
	Turns an observation in R^N, into a discrete state

	Args:
	    num_states (list): list of number of states for each dimension of observation
	    lower_bounds (list): list of lowerbounds for discretization
	    upper_bounds (list): list of upperbounds for discretization
	    obs (list): observation in R^N to discretize

	Returns:
	    int: discrete state
	"""
	state_idx = []
	for ob, lower, upper, num in zip(obs, lower_bounds, upper_bounds, num_states):
		state_idx.append(discretize_val(ob, lower, upper, num))

	return np.ravel_multi_index(state_idx, num_states)

env = gym.make('CartPole-v0')
num_actions = env.action_space.n
num_states = [1, 8, 8, 8]
lower_bounds = [-4.8, -3, -0.418, -2]
upper_bounds = [4.8, 3, 0.418, 2]

get_state = partial(obs_to_state, num_states, lower_bounds, upper_bounds)


import math
import numpy as np
import random
import sys

def KMeansClustering(data, k, seed_init=12345, large_output = False):
    """Clustering using K-Means algorithm

    Arguments:
        data {np.ndarray} -- (N * D) matrix where each entry is a D-vector
        k {int} -- Number of desired clusters

    Keyword Arguments:
        seed_init {int} -- Seed for random initialization of centroids (default: {12345})
        large_output {bool} -- If True, will return cluster and centroids objects (default: {False})

    Returns:
        np.ndarray -- (N * (D+1)) matrix where each entry has an additional column indicating the assigned cluster
    """

    random.seed(seed_init)
    D = len(data)
    centroids = []
    clusters = [[] for i in range(k)]
    point_cluster_mask = [0] * D
    n_changes = D

    # Select intial centroids
    centroid_numbers = set()
    while len(centroid_numbers) < k:
        r = random.randint(1,D-1)
        centroid_numbers.add(r)
    for i in centroid_numbers:
        centroids.append(data[i])

    while n_changes:
        # Reset clusters
        clusters = [[] for i in range(k)]

        # Calculate distances from centroids and assign to clusters
        n_changes = D
        distances = np.zeros((D, k))
        for d in range(D):
            for c in range(k):
                distances[d][c] = _point_distance(data[d], centroids[c])
            old_assignment = point_cluster_mask[d]
            assignment = np.argmin(distances[d])
            clusters[assignment].append(data[d])
            point_cluster_mask[d] = assignment
            if old_assignment == assignment:
                n_changes -= 1

        # Calculate new centroids
        for c in range(k):
            centroids[c] = np.sum(clusters[c], axis=0) / len(clusters[c])

    # Annotate data with cluster
    result = np.empty((D,3))
    for d in range(D):
        result[d] = np.append(data[d], point_cluster_mask[d])

    if large_output:
        return result, clusters, centroids, point_cluster_mask
    else:
        return result

def AggHierClustering(data, k, similarity_measure):
    """Agglomerative Hierarchical Clustering Algorithm

    Arguments:
        data {np.ndarray} -- (N * D) matrix where each entry is a D-vector
        k {int} -- number of desired clusters
        similarity_measure {str} -- The metric by which to compare similarity of clusters. See below for more detail.

    Returns:
        np.ndarray -- (N * (D+1)) matrix where each entry has an additional column indicating the assigned cluster)

    Similarity Measures:
        "min" - The distance between clusters is the distance between the two closest points in each cluster
        "max" - The distance between clusters is the distance between the two furthest points in each cluster
        "average" - The distance between clusters is the average of all distances (i,j) where i is in C1 and j is in C2
        "centroids" - The distance between clusters is the distance between the centroid of each cluster
    """

    D = len(data)
    clusters = [[d] for d in data]

    while len(clusters) > k:

        # Calculate distances between all clusters
        C = len(clusters)
        distances = np.ndarray((C, C))
        for i in range(C):
            for j in range(C):
                dist = _cluster_distance(clusters[i], clusters[j], similarity_measure)
                distances[i][j] = dist if (not i == j) else np.Infinity
        min_distance_locus = np.unravel_index(np.argmin(distances, axis=None), distances.shape)

        # Merge two smallest clusters
        updated_clusters = []
        new_cluster = []
        for i in range(C):
            if (i == min_distance_locus[0] or i == min_distance_locus[1]):
                for d in clusters[i]:
                    new_cluster.append(d)
            else:
                updated_clusters.append(clusters[i])

        updated_clusters.append(new_cluster)
        clusters = updated_clusters

    # Annotate data with cluster
    result = np.empty((D,3))
    d = 0
    assert(len(clusters) == k)
    for i in range(k):
        for j in range(len(clusters[i])):
            annotated_point = np.append(clusters[i][j], i)
            result[d] = annotated_point
            d += 1

    return result

def DivHierClustering(data, k):
    #mst = get_MST(data)
    n_clusters = 1
    while n_clusters < k:
        pass

####################
# Helper Functions #
####################

def calculate_sse(clusters, centroids):
    k = len(centroids)
    sse = 0

    # Calculate SSE
    for c in range(k):
        centroid = centroids[c]
        for d in clusters[c]:
            sse += _point_distance(d, centroid)**2

    return sse

def _point_distance(X1, X2):

    return np.linalg.norm(X1-X2)

def _cluster_distance(C1, C2, similarity_measure):

    if similarity_measure == "min":
        min_dist = np.Infinity
        for i in C1:
            for j in C2:
                dist = _point_distance(i, j)
                if (dist < min_dist):
                    min_dist = dist
        return min_dist

    elif similarity_measure == "max":
        max_dist = 0
        for i in C1:
            for j in C2:
                dist = _point_distance(i, j)
                if (dist > max_dist):
                    min_dist = dist
        return max_dist

    elif similarity_measure == "average":
        I = len(C1)
        J = len(C2)
        d_mat = np.ndarray((I, J))
        for i in range(I):
            for j in range(J):
                d_mat[i][j] = _point_distance(C1[i], C2[j])
        return d_mat.sum() / (I*J)

    elif similarity_measure == "centroids":
        c1_centroid = np.sum(C1, axis=0) / len(C1)
        c2_centroid = np.sum(C2, axis=0) / len(C2)
        return _point_distance(c1_centroid, c2_centroid)

    else:
        print("Invalid similarity measurement.")
        sys.exit(1)
    return _point_distance(C1[0], C2[0])

def get_MST(points):
    return 1


import numpy as np
import pandas as pd
import time, gc
import GV_Runtime as gv_r
import Star_Image_Generation as sig

pi = np.pi
cos = np.cos
sin = np.sin
acos = np.arccos
degrees = np.degrees
radians = np.radians

def cartesianVector_x(row, col_names):
    '''
    Returns the (x) component of the cartesian vector generated from right-ascension and declination of a star

    <Reference> - http://fmwriters.com/Visionback/Issue14/wbputtingstars.htm

    Parameters
    ----------
    row : pd.Dataframe - series
        Input the values of right-ascension and declination

    col_name : string
        The name of the column on which the function will be applied

    Returns
    -------
    x : floating-point number
        The (x) component of the cartesian vector
    '''
    c1, c2 = col_names

    # Converting right-ascension into degrees format
    ra, dec = 15*row[c1], row[c2]

    # Given Formula
    x = cos(radians(dec))*cos(radians(ra))
    y = cos(radians(dec))*sin(radians(ra))
    z = sin(radians(dec))

    # Normalize vector
    temp = np.array([x,y,z])
    temp = temp/np.linalg.norm(temp)

    # Return (x) component
    return temp[0]

def cartesianVector_y(row, col_names):
    '''
    Returns the (y) component of the cartesian vector generated from right-ascension and declination of a star

    <Reference> - http://fmwriters.com/Visionback/Issue14/wbputtingstars.htm

    Parameters
    ----------
    row : pd.Dataframe - series
        Input the values of right-ascension and declination

    col_name : string
        The name of the column on which the function will be applied

    Returns
    -------
    y : floating-point number
        The (y) component of the cartesian vector
    '''
    c1, c2 = col_names

    # Converting right-ascension into degrees format
    ra, dec = 15*row[c1], row[c2]

    # Given Formula
    x = cos(radians(dec))*cos(radians(ra))
    y = cos(radians(dec))*sin(radians(ra))
    z = sin(radians(dec))

    # Normalize vector
    temp = np.array([x,y,z])
    temp = temp/np.linalg.norm(temp)

    # Return (y) component
    return temp[1]

def cartesianVector_z(row, col_names):
    '''
    Returns the (z) component of the cartesian vector generated from right-ascension and declination of a star

    <Reference> - http://fmwriters.com/Visionback/Issue14/wbputtingstars.htm

    Parameters
    ----------
    row : pd.Dataframe - series
        Input the values of right-ascension and declination

    col_name : string
        The name of the column on which the function will be applied

    Returns
    -------
    z : floating-point number
        The (z) component of the cartesian vector
    '''
    c1, c2 = col_names

    # Converting right-ascension into degrees format
    ra, dec = 15*row[c1], row[c2]

    # Given Formula
    x = cos(radians(dec))*cos(radians(ra))
    y = cos(radians(dec))*sin(radians(ra))
    z = sin(radians(dec))

    # Normalize vector
    temp = np.array([x,y,z])
    temp = temp/np.linalg.norm(temp)

    # Return (y) component
    return temp[2]

def norm(row, col_names):
    '''
    Returns the L2 - norm of the cartesian vectors of each star

    Parameters
    ----------
    row : pd.Dataframe - series
        Input the values of vector components

    col_name : string
        The name of the column on which the function will be applied

    Returns
    -------
    y : floating-point number
        The norm of the vector
    '''
    c1, c2, c3 = col_names

    # Extracts (x,y,z) vector components
    x, y, z = row[c1], row[c2], row[c3]

    # Return norm
    return np.sqrt(x*x + y*y + z*z)

def test_gvAlgorithm():
    '''
    Funtion to test <gvAlgorithm>
    '''
    # Initialize main and processed star - catalogues
    CATALOGUE = pd.read_csv(r"F:\IIT Bombay\SatLab\Star Tracker\Programs\Catalogues\Modified Star Catalogue.csv")
    REFERENCE= pd.read_csv(r'F:\IIT Bombay\SatLab\Star Tracker\Programs\Catalogues\Reduced_Catalogue.csv', usecols=['Star_ID1', 'Star_ID2', 'Ang_Distance'])

    # Converts reference catalogue to numpy array for faster implementation
    ref_array = REFERENCE.to_numpy()

    # Generate array of stars using <generateImageDataframe> about a given point, with a specified right-ascension & declination value,
    # with a max circular-FOV and maximum magnitude limit value
    # >>>The given RA/Dec value is centered about Orion's belt
    result = sig.generateImageDataframe(CATALOGUE, ref_ra=5.60355904, ref_dec=-1.20191725, ref_ang_dist=5, mag_limit=5, ra_hrs=True)

    # Generate <temp> dataframe which has following columns: Star_ID, RA/Dec
    temp = result
    temp = temp.drop(['Ref_RA', 'Ref_Dec', 'Mag'], axis = 1)
    temp.index = list(range(temp.shape[0]))

    # Generate the (x,y,z)-vect components for each star
    cols = ['RA', 'Dec']
    temp['x_vect'] = temp.apply(cartesianVector_x, axis = 1, col_names=cols)
    temp['y_vect'] = temp.apply(cartesianVector_y, axis = 1, col_names=cols)
    temp['z_vect'] = temp.apply(cartesianVector_z, axis = 1, col_names=cols)

    #  Generate the norm of the cartesian vector for each star
    cols = ['x_vect', 'y_vect', 'z_vect']
    temp['norm'] = temp.apply(norm, axis = 1, col_names = cols )

    # Generate <test_df> dataframe which has following columns: Star_ID, RA/Dec, (x,y,z)-vect components, norm of vector
    test_df = temp

    # Generate array of Star_IDs alone
    true_stars = temp.Star_ID.to_numpy()

    # Generate <temp1> dataframe which has following columns: (x,y,z)-vect components
    temp1 = temp.drop(['Star_ID', 'RA', 'Dec', 'norm','Ang_Dist'], axis = 1)

    # Generate np.arrays of the star vectors
    st_vect = temp1.to_numpy()
    # Generate np.array of uncertainty values for each vector
    # >>> Generating uncertainty using a continuous-uniform random function around [-eps, eps)
    eps = 0.01
    st_uncert = np.random.random(st_vect.shape[0]) * (2*eps) - eps

    # Running Geometric Voting Algorithm on generated star-vectors and star uncertainty values
    final_result = gv_r.gvAlgorithm(ref_array, st_vect, st_uncert, return_VoteList_1=False)

    print(final_result)
    print(true_stars)

    check_arr = list(final_result[:, 1]==true_stars)
    print(check_arr)
    count_true = check_arr.count(True)
    count_false = check_arr.count(False)
    print('True = ', count_true)
    print('False = ', count_false)

def main():
    test_gvAlgorithm()

if __name__ == "__main__":
    main()


import numpy as np
def gauss_high_pass_filter(source, center, radius=5):
    """
    create gaussian high pass filter
    param: source: input, source image
    param: center: input, the center of the filter, where is the lowest value, (0, 0) is top left corner, source.shape[:2] is
                   center of the source image
    param: radius: input, the radius of the lowest value, greater value, bigger blocker out range, if the radius is 0, then all
                   value is 1
    return a [0, 1] value filter
    """
    M, N = source.shape[1], source.shape[0]

    u = np.arange(M)
    v = np.arange(N)

    u, v = np.meshgrid(u, v)

    D = np.sqrt((u - center[1]//2)**2 + (v - center[0]//2)**2)
    D0 = radius

    if D0 == 0:
        kernel = np.ones(source.shape[:2], dtype=np.float)
    else:
        kernel = 1 - np.exp(- (D**2)/(D0**2))
    return kernel

# 使用高能滤波和阈值处理增强图像
import cv2
import numpy as np
import matplotlib.pyplot as plt

img_finger = cv2.imread('8_blur.jpeg', 0) #直接读为灰度图像

plt.figure(figsize=(15, 12))
plt.subplot(221),plt.imshow(img_finger,'gray'),plt.title('origial')

#--------------------------------
fft = np.fft.fft2(img_finger)
fft_shift = np.fft.fftshift(fft)
amp_img = np.abs(np.log(1 + np.abs(fft_shift)))
plt.subplot(222),plt.imshow(amp_img,'gray'),plt.title('FFT')

#--------------------------------
BHPF = gauss_high_pass_filter(img_finger, img_finger.shape, radius=30)
plt.subplot(223),plt.imshow(BHPF,'gray'),plt.title('BHPF')

#--------------------------------
f1shift = fft_shift * BHPF
f2shift = np.fft.ifftshift(f1shift) #对新的进行平移
img_back = np.fft.ifft2(f2shift)

# 出来的是复数，无法显示
img_new = np.abs(img_back)

# 调整大小范围便于显示
img_new = (img_new-np.amin(img_new))/(np.amax(img_new)-np.amin(img_new))
plt.subplot(224),plt.imshow(img_new,'gray'),plt.title('After BHPF')

plt.tight_layout()
plt.show()

# import  cv2
# def bi_demo(image):#高斯双边滤波
#     dst = cv2.bilateralFilter(src=image, d=0, sigmaColor=100, sigmaSpace=15)
#     cv2.namedWindow('bi_demo',0)
#     cv2.resizeWindow('bi_demo',600,800)
#     cv2.imshow("bi_demo", dst)

# src = cv2.imread('8.jpeg')
# bi_demo(src)
# cv2.namedWindow('src', 0)
# cv2.resizeWindow('src', 600, 800)
# cv2.imshow('src',src)
# plt.show()
# cv2.waitKey(0)


import math

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

import helper_functions
import loaddata

separator = '---------------------------------------------------------------'
tab: str = "\t"

def stat_analysis(stat_name, stat_values, z_stat_values, stat_value_stats, z_stat_value_stats, modifier=''):
    # ----------------------------------------------------------------------------------
    print(f'{separator + separator}\n')
    print(f'{tab * 10}- - - Pokemon Data Analysis - {stat_name} Stat Analysis - - -')
    print(f'{tab * 12}Group 18')
    print(f'{separator + separator}\n')
    print(f'{tab * 7}Relevant data about the figures will be printed to the console to\n'
          f'{tab * 6}conserve space, please refer to the console using the figure numbers provided.\n'
          f'{tab * 14}Thank you!\n')
    print(f'{separator + separator}')
    # ----------------------------------------------------------------------------------

    # ----------------------------------------------------------------------------------
    # plotting bell curve for pokemon stat distribution
    curr_fig = "1"
    print(f'{separator + separator}\n')
    print(f'{tab * 3}- - - Figure {curr_fig}: {stat_name} Stat Distribution {modifier} - - -\n')
    print(helper_functions.basic_stats_string(stat_value_stats, stat_name))
    helper_functions.plot_hist(stat_values, f"Figure {curr_fig}: {stat_name} Stat Distribution {modifier}", stat_name,
                               'frequency', 'blue', 'red', False)
    plt.show()
    print(f'{separator + separator}\n')
    # ----------------------------------------------------------------------------------

    # ----------------------------------------------------------------------------------
    # plotting stat dist. (standardized)
    curr_fig = "1b"
    print(f'{separator + separator}\n')
    print(f'{tab * 3}- - - Figure {curr_fig}: {stat_name} Stat Distribution (standardized) {modifier} - - -\n')
    print(helper_functions.basic_stats_string(z_stat_value_stats, f"Z {stat_name}"))
    helper_functions.plot_hist(z_stat_values, f"Figure {curr_fig}: {stat_name} Stat Distribution (standardized) {modifier}",
                               F'Z {stat_name}', 'frequency', 'blue', 'red', True)
    plt.show()
    print(f'{separator + separator}\n')
    # ----------------------------------------------------------------------------------

    # ----------------------------------------------------------------------------------
    # Population Stat distribution standardized plot
    curr_fig = "2"
    print(f'{separator + separator}\n')
    print(f'{tab * 3}- - - Figure {curr_fig}: Population raw {stat_name} value against standardized score {modifier} - - -\n')
    print(helper_functions.corr_compute(stat_values, z_stat_values, f"{stat_name}", f"Z {stat_name}"))
    plt.xlabel(f'{stat_name}')
    plt.ylabel('Z-score (unit-less)')
    plt.title(f'Figure 2: Population raw {stat_name} value against standardized score')
    plt.scatter(stat_values, z_stat_values)
    plt.show()
    print(f'{separator + separator}\n')
    # ----------------------------------------------------------------------------------

    # --- three groups of pokemon attack stats ----------------------------------------------
    stat_measures = pd.DataFrame(np.random.choice(stat_values, (300, 3), replace=True))

    g1_stats = stat_measures[0].describe()
    g2_stats = stat_measures[1].describe()
    g3_stats = stat_measures[2].describe()

    # --- SEM for 3 groups of pokemon stats  ->  std / sqrt(len(group))
    stat_sem = np.std(stat_measures, 0) / math.sqrt(stat_measures.shape[0])
    # --- 95% Confidence Interval ----------------------------------------------------------
    stat_ci95 = stat_sem * 1.96
    # ---------------------------------------------------------------------------------------

    # --- samples --------------------------------------------------------------------------------------
    stat_sample = np.random.choice(stat_values, (loaddata.sample_size, loaddata.repeat_n), replace=True)
    stat_sample_mean = pd.DataFrame(stat_sample).describe().loc['mean']  # getting mean of each col
    # ---------------------------------------------------------------------------------------------------

    # --- samples stats -----------------------------------
    stat_sample_stats = stat_sample_mean.describe()
    # sample zscore and stats
    z_stat_sample = helper_functions.z_score(stat_sample_mean)
    z_stat_sample_stats = z_stat_sample.describe()
    # ------------------------------------------------------

    # ----------------------------------------------------------------------------------
    # plotting sample Pokemon attack distribution
    curr_fig = "3"
    print(f'{separator + separator}\n')
    print(f'{tab * 3}- - - Figure {curr_fig}: Sample Pokemon {stat_name} Distribution {modifier} - - -\n')
    print(f'{tab * 4}Sample size = {loaddata.sample_size}, Repeated {loaddata.repeat_n}x\n')
    print(helper_functions.basic_stats_string(stat_sample_stats, stat_name))
    helper_functions.plot_hist(stat_sample_mean, f'Figure {curr_fig}: Sample Pokemon {stat_name} Distribution {modifier}',
                               f'{stat_name}', 'frequency', 'blue', 'red', False)
    plt.show()
    print(f'{separator + separator}\n')
    # ----------------------------------------------------------------------------------

    # ----------------------------------------------------------------------------------
    # Plotting sample attack distribution (standardized)
    curr_fig = "3b"
    print(f'{separator + separator}\n')
    print(f'{tab * 3}- - - Figure {curr_fig}: Sample Pokemon {stat_name} Distribution (standardized) {modifier} - - -\n')
    print(f'{tab * 4}Sample Size = {loaddata.sample_size}, Repeated {loaddata.repeat_n}x\n')
    print(helper_functions.basic_stats_string(z_stat_sample_stats, f"Z {stat_name}"))

    helper_functions.plot_hist(z_stat_sample, x_label=f'Z {stat_name}', y_label='frequency',
                               title=f"Figure {curr_fig}: Sample {stat_name} Distribution (standardized) {modifier}",
                               c='blue', tc='red', is_z_score=True)
    plt.show()
    print(f'{separator + separator}\n')
    # ----------------------------------------------------------------------------------

    # ----------------------------------------------------------------------------------
    # Sample Attack against standardized plot
    curr_fig = "4"
    print(f'{separator + separator}\n')
    print(f'{tab * 3}- - - Figure {curr_fig}: Sample Raw {stat_name} value against standardized score {modifier} - - -\n')
    print(f'{tab * 4}Sample Size = {loaddata.sample_size}, Repeated {loaddata.repeat_n}x\n')
    print(helper_functions.corr_compute(stat_sample_mean, z_stat_sample, f"{stat_name}", f"Z {stat_name}"))
    plt.xlabel(f'{stat_name}')
    plt.ylabel('Z-score (unit-less)')
    plt.title(f'Figure {curr_fig}: Sample Raw {stat_name} value against standardized score {modifier}')
    plt.scatter(stat_sample_mean, z_stat_sample)
    plt.show()
    print(f'{separator + separator}\n')
    # ----------------------------------------------------------------------------------

    # ----------------------------------------------------------------------------------
    # Mean and standard error of the mean of Atk stat for three groups of data
    curr_fig = "5"
    sem_str = ""
    for x in range(len(stat_sem)):
        sem_str += f"{tab * 2}Group #{x + 1}: {round(stat_sem[x], 2)}\n"
    print(f'{separator + separator}\n')
    print(f'{tab * 3}- - - Figure {curr_fig}: Mean and SEM {stat_name} stat for three groups of Pokemon {modifier} - - -\n')
    print(f'{tab * 4}Sample size per group = {stat_measures.shape[0]}\n')
    print(f'{tab * 4}Standard Error of the Mean:')
    print(sem_str)
    print(f"{tab * 9}- - - {stat_name} Stats By Group - - -\n")
    print(helper_functions.basic_stats_string(g1_stats, f"{stat_name} (group 1)"))
    print(helper_functions.basic_stats_string(g2_stats, f"{stat_name} (group 2)"))
    print(helper_functions.basic_stats_string(g3_stats, f"{stat_name} (group 3)"))
    plt.xlabel('Sample group')
    plt.ylabel(f'Mean $\pm$ SEM ({stat_name.lower()})')
    plt.title(f'Figure {curr_fig}: Mean & SEM {stat_name} for 3 groups. {modifier}')
    plt.errorbar([1, 2, 3], np.mean(stat_measures, 0), stat_sem)
    plt.xticks([1, 2, 3])
    plt.show()
    print(f'{separator + separator}\n')
    # ----------------------------------------------------------------------------------

    # ----------------------------------------------------------------------------------
    # calculating 95% Confidence interval for mean selected stats
    curr_fig = "5b"
    ci_95_str = ""
    for x in range(len(stat_sem)):
        ci_95_str += f"{tab * 2}Group #{x + 1}: {round(stat_ci95[x], 2)}\n"
    print(f'{separator + separator}\n')
    print(f'{tab * 3}- - - Figure {curr_fig}: 95% Confidence Interval {stat_name} stat in mean '
          f'of 3 groups of Pokemon {modifier} - - -\n')
    print(f'{tab * 4}Sample size per group = {stat_measures.shape[0]}\n')
    print(f'{tab * 4}95% Confidence Interval {stat_name} stat for mean of 3 groups:')
    print(ci_95_str)
    plt.xlabel('Sample Groups')
    plt.ylabel(f'Mean, SEM, & 95% CI ({stat_name})')
    plt.title(f"Figure {curr_fig}: 95% Confidence Interval of {stat_name}. {modifier}")
    plt.errorbar([1.05, 2.05, 3.05], np.mean(stat_measures, 0), stat_sem)
    plt.errorbar([1, 2, 3], np.mean(stat_measures, 0), stat_ci95)
    plt.legend(('SEM', '95% CI'), loc=2)
    plt.xticks([1, 2, 3])
    plt.show()
    print(f'{separator + separator}\n')
    # ----------------------------------------------------------------------------------
    return


import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial import KDTree, Delaunay

# Original code provided by George Killick

def cartesian_to_polar(coordinates):

    x = coordinates[:, 0]
    y = coordinates[:, 1]
    rho = np.sqrt(x**2 + y**2)
    theta = np.arctan2(y, x)

    return np.stack([theta, rho], 1)

def polar_to_cartesian(coordinates):

    theta = coordinates[:, 0]
    rho = coordinates[:, 1]
    x = rho*np.cos(theta)
    y = rho*np.sin(theta)

    return np.stack([x, y], 1)

def display_tessellation(points, figsize=(15, 15), s=1):

    plt.figure(figsize=figsize)
    plt.scatter(points[:, 0], points[:, 1], s=s, c='black')
    plt.show()

    return

def display_stats(points, figsize=(15, 8), k=7):

    nbs = KDTree(points)

    distance, index = nbs.query(points, k=k)

    eccentricity = np.linalg.norm(points, axis=1)
    distance = 1/np.mean(distance[:, 1:], axis=1)

    distance = distance[np.argsort(eccentricity)]
    eccentricity = np.sort(eccentricity)

    plt.figure(figsize=figsize)
    plt.plot(eccentricity, distance)
    plt.xlabel("Eccentricity")
    plt.ylabel("1/mean distance to neighbours")
    plt.show()

    return

def normalize(points):

    points = cartesian_to_polar(points)
    points[:, 1] /= np.max(points[:, 1])
    points = polar_to_cartesian(points)

    return points

def randomize(points, alpha=0.25):

    x = np.copy(points)
    nbs = KDTree(x)

    distance, index = nbs.query(x, k=5)
    distance = np.mean(distance[:, 1:], axis=1)

    delta_rho = distance*np.sqrt(np.random.uniform())
    delta_theta = 2*np.random.uniform(size=distance.shape[0])*np.pi
    delta_x = delta_rho*np.cos(delta_theta)
    delta_y = delta_rho*np.sin(delta_theta)

    x[:, 0] += (delta_x*alpha)
    x[:, 1] += (delta_y*alpha)

    return normalize(x)

def point_generation(points, mode='sierpinski', concatenate=True):

    # Generates points using delaunay triangulation
    # and barycentre or sierpinski methods for generating
    # points.

    points = points
    triangulation = Delaunay(points)
    d_tri = points[triangulation.simplices]

    if(mode == 'barycentre'):
        new_points = np.sum(d_tri, axis=1)/3

    elif(mode == 'sierpinski'):

        a = (d_tri[:, 0] + d_tri[:, 1])/2
        b = (d_tri[:, 1] + d_tri[:, 2])/2
        c = (d_tri[:, 2] + d_tri[:, 0])/2

        new_points = np.concatenate((a, b, c), axis=0)
        new_points = np.unique(new_points, axis=0)

    else:
        print("Unknown mode; Choose from 'barycentre' or 'sierpinski'.")
        return None

    if(concatenate):
        new_points = np.concatenate((points, new_points), axis=0)

    return normalize(new_points)


import matplotlib.pyplot as plt
import numpy as np

u = np.linspace(0, 1, 100)
v = np.linspace(0, np.pi, 360)
uu, vv = np.meshgrid(u, v)
z0 = uu * np.exp(1j * vv)
z = z0 ** 2
T = np.arctan2(uu, vv)

plt.figure(figsize=(14, 6))
plt.subplot(1, 2, 1)
plt.scatter(np.real(z0), np.imag(z0), c=T, s=10, lw=0, cmap='hsv')
plt.title('real points')
plt.grid(True)
plt.axis('equal')
plt.xlabel('Re(z)')
plt.ylabel('Im(z)')
plt.xlim(-1.5, 1.5)
plt.ylim(-1.5, 1.5)

plt.subplot(1, 2, 2)
plt.scatter(np.real(z), np.imag(z), c=T, s=10, lw=0, cmap='hsv')
plt.title('f(z)=z**2')
plt.grid(True)
plt.axis('equal')
plt.xlabel('Re(z)')
plt.ylabel('Im(z)')
plt.xlim(-1.5, 1.5)
plt.ylim(-1.5, 1.5)

plt.show()


import numpy as np

''' Kirill Zakharov
    Cobb-Douglas production function'''

#data
listY = np.array([83278,90884,83743,91530,101313,116415,127434,136274,146470,\
145052,140288,142022,149895,147122,163620])
listL = np.array([234236,254890,217606,221746,228757,250238,266469,266154,\
269520,263098,252357,262536,285700,277522,307946])
listK = np.array([73426,77568,70460,75131,79694,89276,97056,101633,100124,\
94920,96671,100072,101304,96784,100352])

#linearization with Ln
lnY = np.log(listY)
lnK = np.log(listK)
lnL = np.log(listL)

#add additional parameters
lnK2 = lnK*lnK
lnL2 = lnL*lnL
lnKlnL = lnK*lnL
lnYlnK = lnY*lnK
lnYlnL = lnY*lnL

#calculate the sums
sumY = np.sum(lnY)
sumK = np.sum(lnK)
sumL = np.sum(lnL)
sumK2 = np.sum(lnK2)
sumL2 = np.sum(lnL2)
sumYK = np.sum(lnYlnK)
sumYL = np.sum(lnYlnL)
sumKL = np.sum(lnKlnL)

#preparing the data
coef_matrix = np.array([[len(listY), sumK, sumL],
                        [sumK, sumK2, sumKL],
                        [sumL, sumKL, sumL2]])

vector = np.array([sumY, sumYK, sumYL]).T

#solve the system
inv_matrix = np.linalg.inv(coef_matrix)

solution = np.dot(inv_matrix, vector)

print(f'A: {np.exp(solution[0])}\nalpha: {solution[1]}\nbeta: {solution[2]}')


"""
This script demonstrates how to calculate the regression line for paired X/Y data.
"""

import matplotlib.pyplot as plt
import scipy.stats
import numpy as np
import os
thisFolder = os.path.abspath(os.path.dirname(__file__))

# start with sample data
xs = [5, 15, 25, 35, 45, 55]
ys = [5, 20, 14, 32, 22, 38]

# calculate the regression
slope, intercept, r, p, stdErr = scipy.stats.linregress(xs, ys)

# create X/Y data to display as a line on the plot
fittedXs = np.linspace(0, 60)
fittedYs = fittedXs * slope + intercept

# plot the sample data and the regression line
plt.figure(figsize=(6, 3))
plt.plot(xs, ys, '.', alpha=.5, ms=20, label="data")
plt.plot(fittedXs, fittedYs, '--', label="fit")
plt.legend()
plt.title(f"Y={slope:.03f}*X + {intercept:.03f}")
imageFilePath = os.path.join(thisFolder, "regression.png")
plt.savefig(imageFilePath)
print("Saved:", imageFilePath)
plt.show()


import numpy as np

def relu(z):
    return np.maximum(z, 0)

def relu_d(z):
    return np.sign(np.maximum(z, 0))

if __name__ == "__main__":
    print('ReLU Tests')
    testVector = np.matrix("5 1 0 -1 -2")

    print(testVector)
    print(relu(testVector))
    print(relu_d(testVector))


import numpy as np
import matplotlib.pyplot as plt
x = np.random.uniform(-3, 3, size=100)
X = x.reshape(-1, 1)
# 一元二次方程
y = 0.5 * x**2 + x + 2 + np.random.normal(0, 1, 100)
plt.scatter(x, y)
plt.show()

#线性回归
from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(X, y)
y_predict = lin_reg.predict(X)
plt.scatter(x, y)
plt.plot(x, y_predict, color='r')
plt.show()

# 原来所有的数据都在X中，现在对X中每一个数据都进行平方，
# 再将得到的数据集与原数据集进行拼接， 在用新的数据集进行线性回归
from sklearn.linear_model import LinearRegression
X2 = np.hstack([X, X**2])
lin_reg2 = LinearRegression()
lin_reg2.fit(X2, y)
y_predict2 = lin_reg2.predict(X2)
plt.scatter(x, y)
# 由于x是乱的，所以应该进行排序
plt.plot(np.sort(x), y_predict2[np.argsort(x)], color='r')
plt.show()

机器学习/多项式回归/简单实现.py

机器学习/多项式回归/简单实现.py

机器学习/多项式回归/简单实现.py


import numpy as np
import math

def rescale(data):
    # second-dimension are different images

    # reshape
    data = np.swapaxes(data, 0, 1)
    permuted_shape = data.shape
    data = data.reshape(data.shape[0], -1)

    # rescale each image between 0 and 1
    min_data = data.min(axis=1).reshape(-1, 1)
    max_data = data.max(axis=1).reshape(-1, 1)
    data = (data - min_data) / (max_data - min_data)

    # reshape
    data = data.reshape(permuted_shape)
    data = np.swapaxes(data, 0, 1)
    return data

def normalize(data):
    # adpated from https://github.com/XtractOpen/Meganet.m/blob/master/utils/normalizeData.m

    # rescale
    numel_features = data.size // data.shape[1]

    # make the mean of voxels in each image 0 with standard deviation of 1
    data = data - data.mean(axis=(0, 1))
    data = data / np.maximum(data.std(axis=(0, 1)), 1 / math.sqrt(numel_features))

    return data


import numpy as np

def actualizar(funcion_de_valor, politica, longitud_del_mundo, recompensa,
               descuento=1):
    nueva_funcion_de_valor = np.zeros((longitud_del_mundo, longitud_del_mundo))
    #se genera una matriz con ceros, la cual remplazara a la funcion de valor
    # existente
    for posicion_en_el_mundo, valor in np.ndenumerate(funcion_de_valor):
        posicion_en_el_mundo = np.asarray(posicion_en_el_mundo)
        if not es_estado_terminal(posicion_en_el_mundo, longitud_del_mundo):
            #se confirma si el estado es terminal o no
            nuevo_valor = 0
            for _, accion_individual in politica.items():
                #se iterara por cada una de las acciones de nuestra politica
                nueva_posicion = (posicion_en_el_mundo +
                                  accion_individual['accion'])
                x, y = nueva_posicion.T
                if (x < 0 or x >= longitud_del_mundo or y < 0 or y >=
                    longitud_del_mundo):
                    #nos fijamos si esta dentro del mundo, si no se le devuelve
                    #a la misma posicion
                    nueva_posicion = posicion_en_el_mundo
                nuevo_valor += (accion_individual['probabilidad'] *
                                (recompensa + descuento *
                                 funcion_de_valor[tuple(nueva_posicion)]))
                    #se genera el nuevo valor que remplazara ese estado
            nueva_funcion_de_valor[tuple(posicion_en_el_mundo)] = nuevo_valor
    return nueva_funcion_de_valor

def es_estado_terminal(posicion_en_el_mundo, longitud_del_mundo):
    '''esta funcion hara que la funcion de valor no sufra ningun cambio cuando
    se encuentre en los estados terminales'''
    inicio = np.array([0,0])
    final = np.array([longitud_del_mundo-1, longitud_del_mundo-1])
    return (np.array_equal(posicion_en_el_mundo, inicio) or
            np.array_equal(posicion_en_el_mundo, final))

def mundo_cuadricula(longitud_del_mundo, politica, recompensa, k=1000):
    funcion_de_valor = np.zeros((longitud_del_mundo, longitud_del_mundo))
    #la funcion inicial arbitraria inicializa con una matriz de ceros
    for iteracion in range(k):
        #se va a actualizar la funcion de valor basado en el valor de k
        funcion_de_valor_nueva = actualizar(funcion_de_valor, politica,
                                            longitud_del_mundo, recompensa)
        if np.array_equal(funcion_de_valor_nueva, funcion_de_valor):
            #si la politica deja de cambiar significa que se habra
            #encontrado una solucion
            print("convergio! a la iteracion:", iteracion)
            break
        else:
            funcion_de_valor = funcion_de_valor_nueva
        print(funcion_de_valor)

if __name__ == '__main__':
    recompensa = -1
    longitud_del_mundo = 4 #el tamaño del mundo sera una cuadricula 4 x 4
    politica = {           #la politica es la misma que se explico en el post
        'derecha' : {
            'probabilidad': 0.25,
            'accion': np.array([0, 1])
        },
        'izquierda' : {
            'probabilidad': 0.25,
            'accion': np.array([0, -1])
        },
        'arriba' : {
            'probabilidad': 0.25,
            'accion': np.array([1, 0])
        },
        'abajo' : {
            'probabilidad': 0.25,
            'accion': np.array([-1, 0])
        }
    }
    mundo_cuadricula(longitud_del_mundo, politica, recompensa)


import numpy as np
from lazydiff.vars import Var

def sin(var):
    """
    Returns variable representing sin applied to the input variable var
    """
    result = Var(np.sin(var.val))
    result.parents[var] = var.children[result] = np.cos(var.val)
    return result

def cos(var):
    """
    Returns variable representing cos applied to the input variable var
    """
    result = Var(np.cos(var.val))
    result.parents[var] = var.children[result] = -np.sin(var.val)
    return result

def tan(var):
    """
    Returns variable representing tan applied to the input variable var
    """
    result = Var(np.tan(var.val))
    result.parents[var] = var.children[result] = 1 / np.cos(var.val) ** 2
    return result

def asin(var):
    """
    Returns variable representing asin applied to the input variable var
    """
    result = Var(np.arcsin(var.val))
    result.parents[var] = var.children[result] = 1 / np.sqrt(1 - var.val ** 2)
    return result

def acos(var):
    """
    Returns variable representing acos applied to the input variable var
    """
    result = Var(np.arccos(var.val))
    result.parents[var] = var.children[result] = -1 / np.sqrt(1 - var.val ** 2)
    return result

def atan(var):
    """
    Returns variable representing atan applied to the input variable var
    """
    result = Var(np.arctan(var.val))
    result.parents[var] = var.children[result] = 1 / (var.val ** 2 + 1)
    return result

def arcsin(var):
    """
    Wrapper function for asin
    """
    return asin(var)

def arccos(var):
    """
    Wrapper function for asin
    """
    return acos(var)

def arctan(var):
    """
    Wrapper function for atan
    """
    return atan(var)

def sinh(var):
    """
    Returns variable representing sinh applied to the input variable var
    """
    result = Var(np.sinh(var.val))
    result.parents[var] = var.children[result] = np.cosh(var.val)
    return result

def cosh(var):
    """
    Returns variable representing cosh applied to the input variable var
    """
    result = Var(np.cosh(var.val))
    result.parents[var] = var.children[result] = np.sinh(var.val)
    return result

def tanh(var):
    """
    Returns variable representing tanh applied to the input variable var
    """
    result = Var(np.tanh(var.val))
    result.parents[var] = var.children[result] = 1 / (np.cosh(var.val) ** 2)
    return result

def asinh(var):
    """
    Returns variable representing asinh applied to the input variable var
    """
    result = Var(np.arcsinh(var.val))
    result.parents[var] = var.children[result] = 1 / np.sqrt(var.val ** 2 + 1)
    return result

def acosh(var):
    """
    Returns variable representing acosh applied to the input variable var
    """
    result = Var(np.arccosh(var.val))
    result.parents[var] = var.children[result] = 1 / np.sqrt(var.val ** 2 - 1)
    return result

def atanh(var):
    """
    Returns variable representing atanh applied to the input variable var
    """
    result = Var(np.arctanh(var.val))
    result.parents[var] = var.children[result] = 1 / (1 - var.val ** 2)
    return result

def arcsinh(var):
    """
    Wrapper function for asinh
    """
    return asinh(var)

def arccosh(var):
    """
    Wrapper function for acosh
    """
    return acosh(var)

def arctanh(var):
    """
    Wrapper function for atanh
    """
    return atanh(var)

def exp(var):
    """
    Returns variable representing exp applied to the input variable var
    """
    result = Var(np.exp(var.val))
    result.parents[var] = var.children[result] = np.exp(var.val)
    return result

def log(var, base=np.e):
    """
    Returns variable representing log applied to the input variable var.
    Base of log is optional with default base e
    """
    result = Var(np.log(var.val) / np.log(base))
    result.parents[var] = var.children[result] = 1 / (var.val * np.log(base))
    return result

def logistic(var):
    """
    Returns variable representing sigmoid applied to input variable var
    """
    return (1 + exp(-var)) ** -1

def sqrt(var):
    """
    Returns variable representing square root applied to input variable var
    """
    return var ** 0.5

def sum(var):
    """
    Returns variable representing the sum of the components of input variable var
    """
    result = Var(np.sum(var.val))
    result.parents[var] = var.children[result] = np.ones_like(var.val)
    return result

def norm(var, p=1):
    """
    Returns variable representing L-p norm of input variable var
    """
    return sum(abs(var) ** p) ** (1 / p)

def neg(var):
    """
    Wrapper function for __neg__
    """
    return -var

def add(var1, var2):
    """
    Wrapper function for __add__ and __radd__
    """
    return var1 + var2

def sub(var1, var2):
    """
    Wrapper function for __sub__ and __rsub__
    """
    return var1 - var2

def mul(var1, var2):
    """
    Wrapper function for __mul__ and __rmul__
    """
    return var1 * var2

def div(var1, var2):
    """
    Wrapper function for __truediv__ and __rtruediv__
    """
    return var1 / var2

def pow(var1, var2):
    """
    Wrapper function for __pow__
    """
    return var1 ** var2

def abs(var):
    """
    Wrapper function for __abs__
    """
    return var.__abs__()


"""
Distance heuristics
"""

import numpy as np

def l1_norm(p1, p2):
    """
    Computes the L1 norm distance between two n-dimensional points

    Args:
        p1: first point
        p2: second point

    Returns:
        L1 norm distance value
    """
    return np.sum(np.abs(np.asarray(p1) - np.asarray(p2)))

def l2_norm(p1, p2):
    """
    Computes the L2 norm distance between two n-dimensional points

    Args:
        p1: first point
        p2: second point

    Returns:
        L2 norm distance value
    """
    return np.linalg.norm((np.asarray(p1), np.asarray(p2)))

def chebyshev(p1, p2):
    """
    Computes the Chebyshev distance, between two n-dimensional points

    Args:
        p1: first point
        p2: second point

    Returns:
        Chebyshev distance value
    """
    return np.max(np.abs(np.asarray(p1) - np.asarray(p2)))


# Copyright (c) Microsoft. All rights reserved.
# Licensed under the MIT license. See LICENSE file in the project root for full license information.

import numpy as np

def target_function(w,b):
    x = 2*w+3*b
    y=2*b+1
    z=x*y
    return x,y,z

def single_variable(w,b,t):
    print("\nsingle variable: b ----- ")
    error = 1e-5
    while(True):
        x,y,z = target_function(w,b)
        delta_z = z - t
        print("w=%f,b=%f,z=%f,delta_z=%f"%(w,b,z,delta_z))
        if abs(delta_z) < error:
            break
        delta_b = delta_z /63
        print("delta_b=%f"%delta_b)
        b = b - delta_b

    print("done!")
    print("final b=%f"%b)

def single_variable_new(w,b,t):
    print("\nsingle variable new: b ----- ")
    error = 1e-5
    while(True):
        x,y,z = target_function(w,b)
        delta_z = z - t
        print("w=%f,b=%f,z=%f,delta_z=%f"%(w,b,z,delta_z))
        if abs(delta_z) < error:
            break
        factor_b = 2*x+3*y
        delta_b = delta_z/factor_b
        print("factor_b=%f, delta_b=%f"%(factor_b, delta_b))
        b = b - delta_b

    print("done!")
    print("final b=%f"%b)

# this version has a bug
def double_variable(w,b,t):
    print("\ndouble variable: w, b -----")
    error = 1e-5
    while(True):
        x,y,z = target_function(w,b)
        delta_z = z - t
        print("w=%f,b=%f,z=%f,delta_z=%f"%(w,b,z,delta_z))
        if abs(delta_z) < error:
            break
        delta_b = delta_z/63/2
        delta_w = delta_z/18/2
        print("delta_b=%f, delta_w=%f"%(delta_b,delta_w))
        b = b - delta_b
        w = w - delta_w
    print("done!")
    print("final b=%f"%b)
    print("final w=%f"%w)

# this is correct version
def double_variable_new(w,b,t):
    print("\ndouble variable new: w, b -----")
    error = 1e-5
    while(True):
        x,y,z = target_function(w,b)
        delta_z = z - t
        print("w=%f,b=%f,z=%f,delta_z=%f"%(w,b,z,delta_z))
        if abs(delta_z) < error:
            break

        factor_b, factor_w = calculate_wb_factor(x,y)
        delta_b = delta_z/factor_b/2
        delta_w = delta_z/factor_w/2
        print("factor_b=%f, factor_w=%f, delta_b=%f, delta_w=%f"%(factor_b, factor_w, delta_b,delta_w))
        b = b - delta_b
        w = w - delta_w
    print("done!")
    print("final b=%f"%b)
    print("final w=%f"%w)

def calculate_wb_factor(x,y):
    factor_b = 2*x+3*y
    factor_w = 2*y
    return factor_b, factor_w

if __name__ == '__main__':
    w = 3
    b = 4
    t = 150
    single_variable(w,b,t)
    single_variable_new(w,b,t)
    double_variable(w,b,t)
    double_variable_new(w,b,t)


from sympy import *
import math
from numpy import arange

class BracketingMethod:

    num_of_iteration = 0
    root

    # pass a function to me
    def __init__(self, function_formula, upper_bound, lower_bound, max_iterations, precision, x=Symbol('x')):
        self.function_formula = function_formula
        self.upper_bound = upper_bound
        self.lower_bound = lower_bound
        self.X = x
        self.max_iterations = max_iterations
        if max_iterations == 0:
            self.max_iterations = 50
        self.precision = precision
        if precision == 0:
            self.precision = 0.0001

    def verify_there_is_a_root(self):
        try:
            function_value_at_upper_bound = self.function_formula.evalf(subs={self.X: self.upper_bound})
            function_value_at_lower_bound = self.function_formula.evalf(subs={self.X: self.lower_bound})
            print(function_value_at_upper_bound)
            print(function_value_at_lower_bound)

            if int(function_value_at_lower_bound) * int(function_value_at_upper_bound) > 0:
                return false
            else:
                return true
        except:
            return false

    def determine_number_of_iterations(self):
        BracketingMethod.num_of_iteration = math.ceil(((math.log10(math.fabs(self.upper_bound - self.lower_bound))
                                                        - math.log10(self.precision)) / math.log10(2)))
        return BracketingMethod.num_of_iteration

    def compute_root(self):

        try:
            xr = (self.upper_bound + self.lower_bound) / 2.0
            fxr = float(self.function_formula.evalf(subs={self.X: ((self.upper_bound + self.lower_bound) / 2.0)}))

            # create the table
            table = [['Xu', 'Xl', 'Xr', 'F(Xr)', 'relative_error']]
            row = [self.upper_bound, self.lower_bound, (self.upper_bound + self.lower_bound) / 2.0, fxr, None]

            # if the initial guess is the root
            if self.function_formula.evalf(subs={self.X: self.upper_bound}) < 1e-10 \
                    and self.function_formula.evalf(subs={self.X: self.upper_bound}) > -1e-10:
                row = [self.upper_bound, self.lower_bound, self.upper_bound, 0.0, None]
                table.append(row)
                BracketingMethod.root = self.upper_bound
                return [table], self.upper_bound, true
            elif self.function_formula.evalf(subs={self.X: self.lower_bound}) < 1e-10 \
                    and self.function_formula.evalf(subs={self.X: self.lower_bound}) > -1e-10:
                row = [self.upper_bound, self.lower_bound, self.lower_bound, 0.0, None]
                table.append(row)
                BracketingMethod.root = self.lower_bound
                return [table], self.lower_bound, true

            table.append(row)

            i = 0
            while i < BracketingMethod.num_of_iteration:
                xr = (self.upper_bound + self.lower_bound) / 2.0
                function_value_at_xr = self.function_formula.evalf(subs={self.X: xr})

                if i > 0:

                    # if the root is zero
                    if xr == 0.0:
                        if  self.function_formula.evalf(subs={self.X: xr}) < 1e-10 \
                                and  self.function_formula.evalf(subs={self.X: xr}) > -1e-10:

                            return [table], xr, true

                        else:
                            eps = 1.0
                    else:
                        eps = (xr - xr_old) / xr

                    fxr = self.function_formula.evalf(subs={self.X: xr})

                    # add new row
                    row = [self.upper_bound, self.lower_bound, xr, fxr, math.fabs(eps)]
                    table.append(row)

                    if math.fabs(eps) <= self.precision:
                        break

                if function_value_at_xr < 1e-10 and function_value_at_xr > -1e-10:
                    break

                if (function_value_at_xr * self.function_formula.evalf(subs={self.X: self.upper_bound})) < 0:
                    self.lower_bound = xr
                else:
                    self.upper_bound = xr

                xr_old = xr
                i = i + 1

                if i >= self.max_iterations:
                    break

            final_table = [table]
            BracketingMethod.root = xr
            return final_table, xr, true
        except:
            return [[[]]], 0.0, false

    # to do call to check if root
    def is_root(self):
        try:
            if self.function_formula.evalf(subs={self.X: BracketingMethod.root}) < 1e-1 \
                    and self.function_formula.evalf(subs={self.X: BracketingMethod.root}) > -1e-1:
                return true
            else:
                return false
        except:
            return false

    def get_x_y(self):

        a = []
        b = []

        for x in range(-50, 50, 1):
            y = self.function_formula.evalf(subs={self.X: x})
            a.append(x)
            b.append(y)
        return a, b


from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

X, y = make_blobs(n_samples=150,
                  n_features=2,
                  centers=3,
                  cluster_std=0.5,
                  shuffle=True,
                  random_state=0)

plt.scatter(X[:, 0], X[:, 1], c='white', marker='o', edgecolor='black', s=50)
plt.grid()
plt.tight_layout()
plt.show()

km = KMeans(n_clusters=3, init='random', n_init=10, max_iter=300, tol=1e-04, random_state=0)

y_km = km.fit_predict(X)

plt.scatter(X[y_km == 0, 0],
            X[y_km == 0, 1],
            s=50, c='lightgreen',
            marker='s', edgecolor='black',
            label='cluster 1')
plt.scatter(X[y_km == 1, 0],
            X[y_km == 1, 1],
            s=50, c='orange',
            marker='o', edgecolor='black',
            label='cluster 2')
plt.scatter(X[y_km == 2, 0],
            X[y_km == 2, 1],
            s=50, c='lightblue',
            marker='v', edgecolor='black',
            label='cluster 3')
plt.scatter(km.cluster_centers_[:, 0],
            km.cluster_centers_[:, 1],
            s=250, marker='*',
            c='red', edgecolor='black',
            label='centroids')
plt.legend(scatterpoints=1)
plt.grid()
plt.tight_layout()
plt.show()

print('Distortion: %.2f' % km.inertia_)

# elbow method

distortions = []
for i in range(1, 11):
    km = KMeans(n_clusters=i,
                init='k-means++',
                n_init=10,
                max_iter=300,
                random_state=0)
    km.fit(X)
    distortions.append(km.inertia_)
plt.plot(range(1, 11), distortions, marker='o')
plt.xlabel('Number of clusters')
plt.ylabel('Distortion')
plt.tight_layout()
plt.show()

# Quantifying the quality of clustering  via silhouette plots
import numpy as np
from matplotlib import cm
from sklearn.metrics import silhouette_samples

km = KMeans(n_clusters=3,
            init='k-means++',
            n_init=10,
            max_iter=300,
            tol=1e-04,
            random_state=0)
y_km = km.fit_predict(X)

cluster_labels = np.unique(y_km)
n_clusters = cluster_labels.shape[0]
silhouette_vals = silhouette_samples(X, y_km, metric='euclidean')
y_ax_lower, y_ax_upper = 0, 0
yticks = []
for i, c in enumerate(cluster_labels):
    c_silhouette_vals = silhouette_vals[y_km == c]
    c_silhouette_vals.sort()
    y_ax_upper += len(c_silhouette_vals)
    color = cm.jet(float(i) / n_clusters)
    plt.barh(range(y_ax_lower, y_ax_upper), c_silhouette_vals, height=1.0,
             edgecolor='none', color=color)

    yticks.append((y_ax_lower + y_ax_upper) / 2.)
    y_ax_lower += len(c_silhouette_vals)

silhouette_avg = np.mean(silhouette_vals)
plt.axvline(silhouette_avg, color="red", linestyle="--")

plt.yticks(yticks, cluster_labels + 1)
plt.ylabel('Cluster')
plt.xlabel('Silhouette coefficient')

plt.tight_layout()
plt.show()

# Comparison to "bad" clustering:

km = KMeans(n_clusters=2,
            init='k-means++',
            n_init=10,
            max_iter=300,
            tol=1e-04,
            random_state=0)
y_km = km.fit_predict(X)

plt.scatter(X[y_km == 0, 0],
            X[y_km == 0, 1],
            s=50,
            c='lightgreen',
            edgecolor='black',
            marker='s',
            label='cluster 1')
plt.scatter(X[y_km == 1, 0],
            X[y_km == 1, 1],
            s=50,
            c='orange',
            edgecolor='black',
            marker='o',
            label='cluster 2')

plt.scatter(km.cluster_centers_[:, 0], km.cluster_centers_[:, 1],
            s=250, marker='*', c='red', label='centroids')
plt.legend()
plt.grid()
plt.tight_layout()
plt.show()

cluster_labels = np.unique(y_km)
n_clusters = cluster_labels.shape[0]
silhouette_vals = silhouette_samples(X, y_km, metric='euclidean')
y_ax_lower, y_ax_upper = 0, 0
yticks = []
for i, c in enumerate(cluster_labels):
    c_silhouette_vals = silhouette_vals[y_km == c]
    c_silhouette_vals.sort()
    y_ax_upper += len(c_silhouette_vals)
    color = cm.jet(float(i) / n_clusters)
    plt.barh(range(y_ax_lower, y_ax_upper), c_silhouette_vals, height=1.0,
             edgecolor='none', color=color)

    yticks.append((y_ax_lower + y_ax_upper) / 2.)
    y_ax_lower += len(c_silhouette_vals)

silhouette_avg = np.mean(silhouette_vals)
plt.axvline(silhouette_avg, color="red", linestyle="--")

plt.yticks(yticks, cluster_labels + 1)
plt.ylabel('Cluster')
plt.xlabel('Silhouette coefficient')

plt.tight_layout()
plt.show()

# Organizing clusters as a hierarchical tree
# Grouping clusters in bottom-up fashion


from itertools import product

from objects.grtensors.riccitensor import RicciTensor
from sympy import simplify

class RicciScalar(RicciTensor):
    def __init__(self, metric_tensor, coord_sys):
        """
        Creating the ricci scalar object

        Args:
            metric_tensor [list]: The metric tensor, provided by the user
            coord_sys [list]: The coordinate system given as a list (e.g., [t,x,y,z])

        Returns:
            self.ricciscalar_obj [int/symbol]: The ricci scalar, R
        """
        RicciTensor.__init__(self, metric_tensor, coord_sys)
        ricci_scalar = 0
        for i, k in product(range(self.ndim), repeat=2):
            ricci_scalar += self.inverse_metric_obj[i,
                                                    k] * self.riccitensor_obj[i, k]
        self.ricciscalar_obj = ricci_scalar

    def get_ricciscalar(self):
        """
        Returns the ricci scalar object
        """
        return simplify(self.ricciscalar_obj)


"""
---
title: Fixed Positional Encodings
summary: >
  Implementation with explanation of fixed positional encodings as
  described in paper Attention is All You Need.
---

# Fixed Positional Encodings

The positional encoding encodes the position along the sequence into
 a vector of size `d_model`.

\begin{align}
PE_{p,2i} &= sin\Bigg(\frac{p}{10000^{\frac{2i}{d_{model}}}}\Bigg) \\
PE_{p,2i + 1} &= cos\Bigg(\frac{p}{10000^{\frac{2i}{d_{model}}}}\Bigg)
\end{align}

Where $1 \leq 2i, 2i + 1 \leq d_{model}$
 are the feature indexes in the encoding, and $p$ is the position.
"""

import math

import numpy as np
import torch
import torch.nn as nn

from labml_helpers.module import Module

class PositionalEncoding(Module):
    def __init__(self, d_model: int, dropout_prob: float, max_len: int = 5000):
        super().__init__()
        self.dropout = nn.Dropout(dropout_prob)

        self.register_buffer('positional_encodings', get_positional_encoding(d_model, max_len), False)

    def __call__(self, x: torch.Tensor):
        pe = self.positional_encodings[:x.shape[0]].detach().requires_grad_(False)
        x = x + pe
        x = self.dropout(x)
        return x

def get_positional_encoding(d_model: int, max_len: int = 5000):
    # Empty encodings vectors
    encodings = torch.zeros(max_len, d_model)
    # Position indexes
    position = torch.arange(0, max_len, dtype=torch.float32).unsqueeze(1)
    # $2 * i$
    two_i = torch.arange(0, d_model, 2, dtype=torch.float32)
    # $10000^{\frac{2i}{d_{model}}$
    div_term = torch.exp(two_i * -(math.log(10000.0) / d_model))
    # $PE_{p,2i} = sin\Bigg(\frac{p}{10000^{\frac{2i}{d_{model}}}}\Bigg)$
    encodings[:, 0::2] = torch.sin(position * div_term)
    # $PE_{p,2i + 1} = cos\Bigg(\frac{p}{10000^{\frac{2i}{d_{model}}}}\Bigg)$
    encodings[:, 1::2] = torch.cos(position * div_term)

    # Add batch dimension
    encodings = encodings.unsqueeze(1).requires_grad_(False)

    return encodings

def _test_positional_encoding():
    import matplotlib.pyplot as plt

    plt.figure(figsize=(15, 5))
    pe = get_positional_encoding(20, 100)
    plt.plot(np.arange(100), pe[:, 0, 4:8].numpy())
    plt.legend(["dim %d" % p for p in [4, 5, 6, 7]])
    plt.title("Positional encoding")
    plt.show()

if __name__ == '__main__':
    _test_positional_encoding()


'''
@author: Sergio Rojas
@contact: rr.sergio@gmail.com
--------------------------
Contenido bajo
 Atribución-NoComercial-CompartirIgual 3.0 Venezuela (CC BY-NC-SA 3.0 VE)
 http://creativecommons.org/licenses/by-nc-sa/3.0/ve/

Creado en abril 21, 2016
'''

$ ipython --pylab
Python 2.7.10 | 64-bit | (default, Oct 21 2015, 12:08:08)
Type "copyright", "credits" or "license" for more information.

IPython 2.4.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.
Using matplotlib backend: Qt4Agg

In [1]: import numpy as np

In [2]: a = 1.0

In [3]: b = 4.0

In [4]: c = - 4.0

In [5]: x1 = (-b + np. sqrt (b**2 -4*a*c ))/(2* a)

In [6]: print (x1)
0.828427124746

In [7]: test_x1 = a*x1 **2 + b*x1 + c

In [8]: print ( test_x1 )
8.881784197e-16

In [9]: x2 = (-b - np. sqrt (b**2 -4*a*c ))/(2* a)

In [10]: print (x2)
-4.82842712475

In [11]: test_x2 = a*x2 **2 + b*x2 + c

In [12]: print ( test_x2 )
0.0

In [13]: sumaX1X2ybSobrea = (x1+x2) + b/a

In [14]: print ( sumaX1X2ybSobrea )
4.4408920985e-16

In [15]: ProductoRaicesMenosCsobreA = x1*x2 - c/a

In [16]: print ( ProductoRaicesMenosCsobreA )
-8.881784197e-16

In [17]: %save prueba.py 1-16
The following commands were written to file `prueba.py`:
import numpy as np
a = 1.0
b = 4.0
c = - 4.0
x1 = (-b + np. sqrt (b**2 -4*a*c ))/(2* a)
print (x1)
test_x1 = a*x1 **2 + b*x1 + c
print ( test_x1 )
x2 = (-b - np. sqrt (b**2 -4*a*c ))/(2* a)
print (x2)
test_x2 = a*x2 **2 + b*x2 + c
print ( test_x2 )
sumaX1X2ybSobrea = (x1+x2) + b/a
print ( sumaX1X2ybSobrea )
ProductoRaicesMenosCsobreA = x1*x2 - c/a
print ( ProductoRaicesMenosCsobreA )

In [18]: %ls -l prueba.py
-rw-rw-r-- 1 srojas srojas 403 Apr 21 15:34 prueba.py

In [19]: %cat prueba.py
# coding: utf-8
import numpy as np
a = 1.0
b = 4.0
c = - 4.0
x1 = (-b + np. sqrt (b**2 -4*a*c ))/(2* a)
print (x1)
test_x1 = a*x1 **2 + b*x1 + c
print ( test_x1 )
x2 = (-b - np. sqrt (b**2 -4*a*c ))/(2* a)
print (x2)
test_x2 = a*x2 **2 + b*x2 + c
print ( test_x2 )
sumaX1X2ybSobrea = (x1+x2) + b/a
print ( sumaX1X2ybSobrea )
ProductoRaicesMenosCsobreA = x1*x2 - c/a
print ( ProductoRaicesMenosCsobreA )

In [20]: %who
ProductoRaicesMenosCsobreA	 a	 b	 c	 sumaX1X2ybSobrea	 test_x1	 test_x2	 x1	 x2

In [21]: %reset -f

In [22]: %who
Interactive namespace is empty.

In [23]: print(a)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-23-c5a4f3535135> in <module>()
----> 1 print(a)

NameError: name 'a' is not defined

In [24]: %run prueba.py
0.828427124746
8.881784197e-16
-4.82842712475
0.0
4.4408920985e-16
-8.881784197e-16

In [25]: %who
ProductoRaicesMenosCsobreA	 a	 b	 c	 np	 sumaX1X2ybSobrea	 test_x1	 test_x2	 x1
x2

In [26]: ProductoRaicesMenosCsobreA
Out[26]: -8.8817841970012523e-16

In [27]: quit

$ python prueba.py
0.828427124746
8.881784197e-16
-4.82842712475
0.0
4.4408920985e-16
-8.881784197e-16


"""
Basic power method for computing the dominant eigenvalue
and an associated eigenvector of a symmetric matrix

>>> A = array([[ 1.56260001,  0.22898325,  1.04332261,  0.4558478 ,  0.89455427],
...            [ 0.22898325,  0.54532437,  1.51480666,  0.96986641,  1.5202461 ],
...            [ 1.04332261,  1.51480666,  0.53536642,  0.77569108,  1.23270255],
...            [ 0.4558478 ,  0.96986641,  0.77569108,  1.6110797 ,  1.32133154],
...            [ 0.89455427,  1.5202461 ,  1.23270255,  1.32133154,  0.27904888]])

>>> lam, v, iters, err = power(A,True)
>>> iters < 30
True

>>> err < 1.0e-15
True
"""

from numpy import *

def power(A, details=False):
    n,_ = shape(A)
    v = random.rand(n)
    iters = 0
    err = 1.0
    while err > 1.0e-15 and iters < 1000:
        w = A.dot(v)
        v = w / linalg.norm(w)
        lam = v.dot(A).dot(v) / v.dot(v)
        err = linalg.norm(A.dot(v) - lam*v)
        iters += 1
    if details:
        return lam, v, iters, err
    else:
        return lam, v

if __name__ == "__main__":
    import doctest
    doctest.testmod()


# -*- coding: utf-8 -*-
"""
Created on Wed Sep  8 10:44:14 2021

@author: User
"""
# Arreglos n-dimensionales
import numpy as np

#%%
a = np.array([1, 2, 3, 4, 5, 6])
print(a)
#%%
a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
print(a)
#%%
print(a[0])
print(a[2])
print(a[2][3])
#%%
print(np.zeros(2)) # Crea un arreglo con dos elementos tipo cero
print(np.ones(2)) # Crea un arreglo con dos elementos tipo 1
print(np.empty(2)) # Crea un arreglo con dos elementos vacio
#%% También podés crear vectores a partir de un rango de valores:
print(np.arange(4))
#%% Vector que contiene elementos equiespaciados, especificando
# el primer número, el límite, y el paso.
print(np.arange(2, 9, 2)) # o np.arange(2, 10, 2)
#%% crear un vector de valores equiespaciados especificando
# el primer número, el último número, y la cantidad de elementos
print(np.linspace(0, 10, num=5))

#%%

#Ejercicio 5.7: arange() y linspace()
''' Generá un vector que tenga los números impares entre el 1 y el 19 inclusive
 usando arange(). Repetí el ejercicio usando linspace().
  ¿Qué diferencia hay en el resultado? '''

#%%
# podés explicitar otro tipo de datos usando la palabra clave dtype.
x = np.ones(2, dtype=np.int64)
print(x)

#%%
# Agregar, borrar y ordenar elementos
#Ordenar un vector es sencillo usando np.sort()

arr = np.array([2, 1, 5, 3, 7, 4, 6, 8])
print( arr )
print(np.sort(arr))

#%%
a = np.array([1, 2, 3, 4])
b = np.array([5, 6, 7, 8])
# los podés concatenar usado np.concatenate()
print(np.concatenate((a, b)))
#%% mas complejo
x = np.array([[1, 2], [3, 4]])
y = np.array([[5, 6]])
print(np.concatenate((x, y), axis=0))
#%% Conocer el tamaño, dimensiones y forma de un arreglo
array_ejemplo = np.array([[[0, 1, 2, 3], [4, 5, 6, 7]], [[0, 1, 2, 3], [4, 5, 6, 7]], [[0 ,1 ,2, 3], [4, 5, 6, 7]]])
#
print(array_ejemplo.ndim) # cantidad de dimensiones
#%%
print(array_ejemplo.shape ) # cantidad de elementos en cada eje
#%%
print(array_ejemplo.size ) # total de elementos 3*2*4
#%% Cambiar la forma de un arreglo
a = np.arange(6)
print(a)
#%%
b = a.reshape(3, 2)
print(b)
#%%
# Agregar un nuevo eje a un arreglo
a = np.array([1, 2, 3, 4, 5, 6])
print(a)
print(a.shape)
#%%
vec_fila = a[np.newaxis, :]
print(vec_fila.shape)
#%%
vec_col = a[:, np.newaxis]
#%% Índices y rebanadas
data = np.array([1, 2, 3])
print(data)
print(data[1])
#%% Podés imprimir todos los valores menores que cinco.
a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
print(a[a < 8])

#%%
five_up = (a >= 5)
print(five_up)
#%% Podés seleccionar los elementos pares:
pares = a[a%2==0]
print(pares)
#%%
a = np.array([1,  2,  3,  4,  5,  6,  7,  8,  9, 10])
arr1 = a[3:8]
print(arr1)
#%%
arr1[0] = 44
print(arr1)

#%%
a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
# Ahora creamos b1 a partir de una rebanada de a y modificamos su primer elemento. ¡Esto va a modificar el elemento correspondiente de a también!
b1 = a[0, :]
print(b1)
#%%

b1[0] = 99
print(b1)
print(a)
#%%
b2 = a[1, :].copy()
print(b2)


# coding=utf-8
import numpy as np
"""
def numpy.histogram(a, bins=10, range=None, weights=None, density=None)
    '''
    将 a 的各个数值按 bins 分类。

    :param:
      > a     : Input data.
                DataType : flattend array
      > bins  : 直方图的柱子.
                DataType : int or sequence of scalars.
                if bins is an integer, it defines the number of equal width bins in the given range.
                It defines a monotonically increasing array of bin edges,
                including the rightmost edge, allowing for non-uniform bin widths.
      > range : 数据范围.
                DataType : (float, float)
                The lower and upper range of bins.
                If not provided, range is simply (a.min(), a.max())
      > density: DataType bool.
                If False, the result will contain the number of samples in each bin.
                If True, the result is the value of probability density function at the bin.

    :return:
      > hist      : DataType array, The values of histogram.
      > bin_edges : DataType array, the bin edges.

    :Tips:
      len(bin_edges) = len(hist) + 1
    '''
"""

print(np.histogram([1, 2, 1], bins=[0, 1, 2, 3]))
# (array([0, 2, 1]), array([0, 1, 2, 3]))

print(np.histogram(np.arange(4), bins=np.arange(5), density=True))
# (array([ 0.25,  0.25,  0.25,  0.25]), array([0, 1, 2, 3, 4]))

print(np.histogram([[1, 2, 1], [1, 0, 1]], bins=[0,1,2,3]))
# (array([1, 4, 1]), array([0, 1, 2, 3]))


import numpy as np
from copy import copy
#import rbdl
cos=np.cos; sin=np.sin; pi=np.pi

def dh(d, theta, a, alpha):
    """
    Matriz de transformacion homogenea asociada a los parametros DH.
    Retorna una matriz 4x4
    """
    sth = np.sin(theta)
    cth = np.cos(theta)
    sa  = np.sin(alpha)
    ca  = np.cos(alpha)
    T = np.array([[cth, -ca*sth,  sa*sth, a*cth],
                   [sth,  ca*cth, -sa*cth, a*sth],
                   [0.0,      sa,      ca,     d],
                   [0.0,     0.0,     0.0,   1.0]])
    return T

def fkine_BRT(q):
    """
    Calcular la cinematica directa del robot UR5 dados sus valores articulares.
    q es un vector numpy de la forma [q1, q2, q3, q4, q5, q6]
    """
    # Longitudes (en metros)
    # Matrices DH (completar), emplear la funcion dh con los parametros DH para cada articulacion
    m=100
    l1=(7.5/m)
    l2=(12.5/m)
    l3=(12.5/m)
    l4=(6.5/m)
    l5=(13/m)
    # Matrices DH
    T1=dh(l1 ,-q[0]-pi/2 ,0,-pi/2)#listo
    T2=dh(0,q[1]+pi,l2,0)
    T3=dh(0,q[2]-pi/2,l3,0)
    T4=dh(0,q[3],0 ,pi/2) #listo
    T5=dh(l4+l5,-q[4] ,0 ,0     )#listo
    # Efector final con respecto a la base
    T = T1.dot(T2).dot(T3).dot(T4).dot(T5)
    return T

def jacobian_BRT(q, delta=0.0001):
    # Crear una matriz 3x5
    J = np.zeros((3,5))
    # Transformacion homogenea inicial (usando q)
    T = fkine_BRT(q)
    # Iteracion para la derivada de cada columna
    for i in range(5):
        # Copiar la configuracion articular inicial
        dq = copy(q)
        # Incrementar la articulacion i-esima usando un delta
        dq[i]=dq[i]+delta
        # Transformacion homogenea luego del incremento (q+delta)
        Ti=fkine_BRT(dq)
        # Aproximacion del Jacobiano de posicion usando diferencias finitas
        J[:,i]= 1/delta*(Ti[0:3,3]-T[0:3,3])
    return J

def ikine_BRT(xdes, q0):
    """
    Calcular la cinematica inversa de UR5 numericamente a partir de la configuracion articular inicial de q0.
    """
    epsilon  = 0.0001
    max_iter = 1000
    delta=0.0001

    q  = copy(q0)
    for i in range(max_iter):
            # Main loop
            J=jacobian_BRT(q,delta)
            f=fkine_BRT(q)
            e=xdes-f[0:3,3]
            q=q+np.dot(np.linalg.pinv(J), e)
            #Condicion de final
            if (np.linalg.norm(e)<epsilon):
                break
            pass
    return q

def ik_gradient_BRT(xdes, q0):

    """
    Calcular la cinematica inversa de UR5 numericamente a partir de la configuracion articular inicial de q0.
    Emplear el metodo gradiente
    """
    epsilon  = 0.001
    max_iter = 1000
    delta    = 0.00001
    alpha    = 0.5
    q  = copy(q0)

    for i in range(max_iter):
        # Main loop
        #Matriz Jacobiana
        J=jacobian_BRT(q,delta)
        #Matriz Actual
        Td=fkine_BRT(q)
        #Posicion Actual
        xact=Td[0:3,3]
        # Error entre pos deseada y pos actual
        e=xdes-xact
        # Metodo de Newton
        q=q+alpha*np.dot(J.T,e)
        #Condicion de termino
        if(np.linalg.norm(e)<epsilon):
            break
        pass
    return q


# Import the necessary modules
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# In this script we will plot the analytical solution of the process of
# one-dimensional diffusion as a function of time. In class, we derived that
# the concentration of molecules at position x at time t can be written as
#
#         p(x, t) = 1 / sqrt(4 * pi * D * t) * exp(-x^2 / 4 * D * t)
#
# where D is the diffuision constant of the molecule,  molecules, and t is the
# time. Assuming we have a large spike of molecules positioned at the origin at
# time 0, let's see how the concentration profile canges with time.
D = 10  # Diffusion constant in square microns per second

time_steps = [1, 5, 10, 50]
x = np.linspace(-100, 100, 1000)  # Diffusion distance in units of microns.

# Now we can loop through each time step to and evaluate our equation.
plt.figure()
for t in time_steps:
    c_t = 1 / np.sqrt(4 * np.pi * D * t) * np.exp(-x**2 / (4 * D * t))

    # Plot the profile as a funxiton of x position
    plt.plot(x, c_t, '-', label='time = ' + str(t) + ' seconds')

plt.xlabel(r'x position ($\mu$m)')
plt.ylabel(r'$c (x, t)$ (number of molecules)')
plt.legend()
plt.show()

# We see that the profile is gaussian and widens with a longer period of time.


from math import pi, sin, cos, tan, log10, log, e, asin, acos, atan
from math import factorial as f
from pathlib import Path
import os
import colorama
import sympy as sp

# *Additional variables
# Radian constant
RAD = pi / 180
RAD2 = sp.pi / 180  # Using sympy syntax
# Path
CWD = Path.cwd()
# Physic
ke = 9e9  # K constant (electric)
qe = -1.6e-19  # Electron charge (coulomb)
qp = 1.6e-19  # Proton charge (coulomb)
G = 6.67e-11  # Gravity constant (m^3/(kg.s^2))

# *Additional function
# Trigonometry
def rada(x):
    return x * RAD  # Radian to Angle #! Will be deprecated

def deg2rad(x):
    return rada(x)

def rad2deg(x):
    return x / RAD

def sina(x):
    return sin(rada(x))  # Sin of angle

def cosa(x):
    return cos(rada(x))  # Cos of angle

def tana(x):
    return tan(rada(x))  # Tan of angle

def csca(x):
    return 1 / sina(x)  # Csc of angle

def seca(x):
    return 1 / cosa(x)  # Sec of angle

def cota(x):
    return 1 / tana(x)  # Cot of angle

def asina(x):  # Arcsin (return angle)
    return rad2deg(asin(x))

def acosa(x):  # Arccos (return angle)
    return rad2deg(acos(x))

def atana(x):  # Arctan (return angle)
    return rad2deg(atan(x))

# TODO: Add Arccosec Arcsec Arccot

# Probability and etc.
def c(n, k):
    return f(n) / (f(k) * f(n - k))  # Choose

# List accumulator
def acc(x):
    sum_value_accumulate = []
    sum_value = 0
    for value in x:
        sum_value += value
        sum_value_accumulate.append(sum_value)
    return sum_value_accumulate

# Quick map convertion
def lm(*x):
    return list(map(*x))  # List of Map

def sm(*x):
    return set(map(*x))  # Set of Map

# Quick sum
def suml(*x):
    return sum(list(*x))  # Sum of List

def sumlm(*x):
    return suml(map(*x))  # Sum of List of Map

# Chemistry
# For calculate: pH pOH
def p(x):
    return -log10(x)

# Chemical rate
def c_rate(concentration_start, concentration_stop, duration):
    return (concentration_start - concentration_stop) / duration

def root(x):
    return x ** (1 / 2)

# Distance
def dis2(x1, y1, x2, y2):
    dx = x1 - x2
    dy = y1 - y2
    return (dx**2 + dy**2) ** (1 / 2)

def dis3(x1, y1, z1, x2, y2, z2):
    dx = x1 - x2
    dy = y1 - y2
    dz = z1 - z2
    return (dx**2 + dy**2 + dz**2) ** (1 / 2)

# Natural log
def ln(x):
    return log(x, e)

# *Special function
# CMD
def cmd(x):
    os.system(x)

# Clear
def cls():
    cmd("cls")

# Score calculator
def scalc(countmode: str = "wrong"):
    print("Enter a max score for the test")
    max_score = int(input("Max score: "))
    match countmode:
        case "wrong" | 0:
            print("Each character represent a zero mark.")
            wrong_character = input("Enter character: ")
            wrong_score = len(wrong_character)
            score = max_score - wrong_score
        case "right" | 1:
            print("Each character represent 1 mark.")
            correct_character = input("Enter character: ")
            score = len(correct_character)
        case _:
            raise TypeError("Not support")

    score_percentage = score * 100 / max_score

    print(f"{colorama.Fore.RED}Score: {score}/{max_score}")
    print(f"{colorama.Fore.GREEN}Percent: {score_percentage:.2f}%")


import numpy as np
from scipy.stats import sem
from scipy.stats import t

def ttest_1d(data1, data2, alpha):
    """
    Function for calculating the t-test for two independent samples
    """

    # calculate means
    mean1 = np.mean(data1)
    mean2 = np.mean(data2)

    # calculate standard errors
    se1 = sem(data1)
    se2 = sem(data2)

    # standard error on the difference between the samples
    sed = np.sqrt(se1**2.0 + se2**2.0)

    # calculate the t statistic
    t_stat = (mean1 - mean2) / sed

    # degrees of freedom
    df = len(data1) + len(data2) - 2

    # calculate the critical value
    cv = t.ppf(1.0 - alpha, df)

    # calculate the p-value
    p = (1.0 - t.cdf(abs(t_stat), df)) * 2.0

    return t_stat, df, cv, p


from numpy import array, sin, exp, sqrt, pi
from benchmarks.benchmark import Benchmark

class Crossit(Benchmark):
    """dim: 2"""
    def __init__(self, lower=-10, upper=10, dimension=2):
        super(Crossit, self).__init__(lower, upper, dimension)

    def get_optimum(self):
        return array([[1.3491, -1.3491], [1.3491, 1.3491], [-1.3491, 1.3491], [-1.3491, -1.3491]]), -2.0626118504479614

    @staticmethod
    def eval(sol):
        term1 = sin(sol[0]) * sin(sol[1])
        term2 = exp(abs(100 - sqrt(sol[0] ** 2 + sol[1] ** 2) / pi))

        return -0.0001 * (abs(term1 * term2) + 1) ** 0.1


from scipy import integrate
def integrand(y, x):
    return x * y**2
x_lower_lim, x_upper_lim = 0.0, 0.5
y_lower_lim, y_upper_lim = lambda x:0.0, lambda x:1.0-2.0*x
# int_{x=0}^{0.5} int_{y=0}^{1-2x} x y dx dy
integral,error = integrate.dblquad(integrand,
                                   x_lower_lim, x_upper_lim,
                                   y_lower_lim, y_upper_lim)
print(integral, error)

example_snippets/multimenus_snippets/Snippets/SciPy/Integration and ODE solvers/Integrate given function object/General purpose double integration.py


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

# # My lesson 2

# In[8]:

import numpy
get_ipython().run_line_magic('matplotlib', 'notebook')
from matplotlib import pyplot
import sys
sys.path.append('../scripts/')

# Our helper with the functions
# plot_vector, plot_linear_transformation, plot_linear_transformations
# import plot_config
# plot_config.use_notebook = True
from plot_helper import *

# In[9]:

A = numpy.array([[1, 1], [-1, 1]])
print(A)

# In[4]:

plot_linear_transformation(A)

# In[15]:

i = numpy.array([1, 0])
j = numpy.array([0, 1])

# In[16]:

a = numpy.array([1, -1])
b = numpy.array([1, 1])

# In[17]:

vectors = [i, a] # where i landed
plot_vector(vectors)

# In[18]:

numpy.linalg.norm(i)

# In[19]:

numpy.linalg.norm(a)

# In[20]:

numpy.sqrt(2)

# In[21]:

plot_linear_transformation(A)

# In[22]:

A_inv = numpy.linalg.inv(A)

# In[23]:

plot_linear_transformation(A)
plot_linear_transformation(A_inv)

# In[24]:

plot_linear_transformations(A, A_inv)

# In[27]:

B = numpy.array([[1, 1], [0, -1]])
print(B)

# In[28]:

B_inv = numpy.linalg.inv(B)
print(B_inv)

# In[29]:

plot_linear_transformation(B)
plot_linear_transformation(B_inv)

# In[30]:

plot_linear_transformations(B, B_inv)

# In[32]:

C = numpy.array([[2, 1], [1, 2]])
print(C)
plot_linear_transformation(C)

# In[33]:

alpha = numpy.linspace(0, 2*numpy.pi, 41)

# In[34]:

vectors = list(zip(numpy.cos(alpha), numpy.sin(alpha)))

# In[35]:

plot_vector(vectors)

# In[36]:

vectors[0]

# In[38]:

C.dot(numpy.array(vectors[0]))

# In[41]:

newvectors = []
for i in range(len(vectors)):
    newvectors.append(C.dot(numpy.array(vectors[i])))

# In[42]:

plot_vector(newvectors)

# In[43]:

lengths = []
for i in range(len(newvectors)):
    lengths.append(numpy.linalg.norm(newvectors[i]))

# In[44]:

semi_major = max(lengths)
print(semi_major)

# In[45]:

semi_minor = min(lengths)
print(semi_minor)

# In[49]:

# semi major longest lies at 45 degrees which means that x and y equally contribute to it. therefore we can take the
# length of the semi_major (norm) and find it's components by dividing it by the squareroot of 2
s = semi_major/numpy.sqrt(2)

# In[50]:

u1 = numpy.array([s, s])
print(u1)

# In[51]:

C_inv = numpy.linalg.inv(C)
v1 = C_inv.dot(u1)

# In[52]:

plot_vector([u1, v1])

# The vector that landed on the semi-axis was only scaled by the effect of ${C}$.

# semi-minor

# In[54]:

u2 = numpy.array([semi_minor/numpy.sqrt(2), -semi_minor/numpy.sqrt(2)])
print(u2)

# In[75]:

v2 = C_inv.dot(u2)
print(v2)

# In[76]:

plot_vector([u2, v2])

# In[77]:

numpy.linalg.norm(u2)

# -----
#
# ## System of equations

# In[78]:

A

# In[80]:

c = numpy.array([1, 5])
print(c)

# In[82]:

x = A_inv.dot(c) # is the vector that lands in c after the transformation
print(x)

# Row by row the system represents two lines:
#
# $$ y = 1-x $$
# $$ y = 5+x $$

# In[88]:

xvalues = numpy.linspace(-4,2)
m1, b1, m2, b2 = -1, 1, 1, 5

pyplot.figure(figsize=(2,2))
pyplot.plot(xvalues, m1*xvalues+b1)
pyplot.plot(xvalues, m2*xvalues+b2)
pyplot.scatter(x[0], x[1])

# In[90]:

# numpy also has builtin support for solving for a transform A with the given vector C
x = numpy.linalg.solve(A, c)
print(x)

# In[91]:

# made from prev 2 vectors a and d, which are colinear
D = numpy.array([[-2, -1], [1, 0.5]])
print(D)

# In[92]:

plot_linear_transformation(D)

# In[93]:

# D doesn't have an inverse, it's a singular matrix that smashes the whole 2D space into a line.
# It cannot be unpacked back into the entire 2D space

# In[ ]:

xvalues = numpy.linspace(y)


'''
Este script resuelve la ecuacion (1) del documento enunciado.pdf. La idea es
buscar el valor de a para el cual la integral toma un valor de 0.05.
'''

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import quad
from scipy.optimize import newton

def gausiana(x):
    """Funcion argumento de la integral de la ec. 1 del P1 de la tarea."""
    output = np.exp(-x**2/2) / np.sqrt(2*np.pi)
    return output

plt.figure(1, figsize=(6, 4))
plt.clf()

x_to_plot = np.linspace(-5, 5, 100)
plt.plot(x_to_plot, gausiana(x_to_plot))

plt.xlabel("$x$", fontsize=12)
plt.ylabel(r"$\exp(x^2/2)/\sqrt{2\pi}$", fontsize=12)
plt.subplots_adjust(top=0.95, right=0.95, left=0.15, bottom=0.15)
plt.show()

# Notese que esta funcion y el grafico no estan en el informe, sin embargo fue
# parte del proceso exploratorio para resolver el problema.

def gausiana_cv(u):
    """La funcion a integrar luego del cambio de variable u=1/y.
    """
    output = np.exp(-1/(2 * u**2)) / u**2 / np.sqrt(2*np.pi)
    return output

plt.figure(1, figsize=(6, 4))
plt.clf()

u_to_plot = np.linspace(1e-5, 10, 500)
plt.plot(u_to_plot, gausiana_cv(u_to_plot))

plt.xlabel("$u$", fontsize=12)
plt.ylabel(r"$\frac{1}{\sqrt{2\pi}u^2}\exp\left(\frac{-1}{2u^2}\right)$",
           fontsize=12)
plt.subplots_adjust(top=0.95, right=0.95, left=0.15, bottom=0.15)

plt.savefig("integral.pdf")
plt.show()

def integral_cv(a):
    """Calcula la integral de la funcion gaussiana_cv entre 0 y 1/a.
    """
    if type(a) == np.ndarray:
        output = [quad(gausiana_cv, 0, 1/a_i)[0] for a_i in a]
        output = np.array(output)
    else:
        output = quad(gausiana_cv, 0, 1/a)[0]
    return output

# A continuacion, una prueba de que la funcion integral_cv entrega resultados
# razonables
print("integral_cv(a=inf) = {:.5f}".format(integral_cv(1e4)))  # deberia dar ~0
print("integral_cv(a=0) = {:.5f}".format(integral_cv(1e-4)))  # deberia dar ~.5

print(integral_cv(np.array([1e4, 1e-4])))  # testing that it works for arrays

# Ahora hay que implementar la búsqueda del punto de interseccion entre la
# integral_cv y el valor 0.05

def func_zero(a):
    return integral_cv(a) - 0.05

a_star, result = newton(func_zero, 1, full_output=True)
print("El valor buscado es {:.3f}".format(a_star))
print("Numero de iteraciones: {}".format(result.iterations))

plt.figure(2, figsize=(6, 4))
plt.clf()

a_to_plot = np.linspace(0.5, 5, 100)
plt.plot(a_to_plot, integral_cv(a_to_plot))

plt.xlabel("$a$", fontsize=12)
plt.ylabel(r"$\int_0^{1/a} f(u) du $", fontsize=12)
plt.subplots_adjust(top=0.95, right=0.95, left=0.15, bottom=0.15)

plt.axhline(0.05, ls='--')
plt.axvline(a_star, ls='--', color='r', label="$a^*={:.2f}$".format(a_star))

plt.legend()
plt.savefig("solucion.pdf")
plt.show()

print("=====\n")
a_star, result = newton(func_zero, 0.5, full_output=True)
print("El valor buscado es {:.3f}".format(a_star))
print("Numero de iteraciones: {}".format(result.iterations))


#!/usr/bin/env python
# coding: utf-8
# # Hedging
# Make sure to refer to the video for full explanations!
import numpy as np
from statsmodels import regression
import statsmodels.api as sm
import matplotlib.pyplot as plt
# Get data for the specified period and stocks
start = '2016-01-01'
end = '2017-01-01'
asset = get_pricing('AAPL', fields='price', start_date=start, end_date=end)
benchmark = get_pricing('SPY', fields='price', start_date=start, end_date=end)
# In[165]:
asset_ret = asset.pct_change()[1:]
bench_ret = benchmark.pct_change()[1:]
# In[166]:
asset_ret.plot()
bench_ret.plot()
plt.legend()
# ## Regression for Alpha and Beta Values
plt.scatter(bench_ret,asset_ret,alpha=0.6,s=50)
plt.xlabel('SPY Ret')
plt.ylabel('AAPL Ret')
# In[168]:
AAPL = asset_ret.values
spy = bench_ret.values
# Add a constant (column of 1s for intercept)
spy_constant = sm.add_constant(spy)
# Fit regression to data
model = regression.linear_model.OLS(AAPL,spy_constant).fit()
model.params
alpha , beta = model.params
alpha
# In[173]:
beta
# ### Plot Alpha and Beta
# Scatter Returns
plt.scatter(bench_ret,asset_ret,alpha=0.6,s=50)
# Fit Line
min_spy = bench_ret.values.min()
max_spy = bench_ret.values.max()
spy_line = np.linspace(min_spy,max_spy,100)
y = spy_line * beta + alpha
plt.plot(spy_line,y,'r')
plt.xlabel('SPY Ret')
plt.ylabel('AAPL Ret')
# ## Implementing the Hedge
hedged = -1*beta*bench_ret + asset_ret
hedged.plot(label='AAPL with Hedge')
bench_ret.plot(alpha=0.5)
asset_ret.plot(alpha=0.5)
plt.legend()
# #### What happens if there is a big market drop?
hedged.plot(label='AAPL with Hedge')
bench_ret.plot()
asset_ret.plot()
plt.xlim(['2016-06-01','2016-08-01'])
plt.legend()
# ### Effects of Hedging
def alpha_beta(benchmark_ret,stock):
    benchmark = sm.add_constant(benchmark_ret)
    model = regression.linear_model.OLS(stock,benchmark).fit()
    return model.params[0], model.params[1]
# ** 2016-2017 Alpha and Beta **
# Get the alpha and beta estimates over the last year
start = '2016-01-01'
end = '2017-01-01'
asset2016 = get_pricing('AAPL', fields='price', start_date=start, end_date=end)
benchmark2016 = get_pricing('SPY', fields='price', start_date=start, end_date=end)
asset_ret2016 = asset2016.pct_change()[1:]
benchmark_ret2016 = benchmark2016.pct_change()[1:]
aret_val = asset_ret2016.values
bret_val = benchmark_ret2016.values
alpha2016, beta2016 = alpha_beta(bret_val,aret_val)
print('2016 Based Figures')
print('alpha: ' + str(alpha2016))
print('beta: ' + str(beta2016))
# ** Creating a Portfolio **
# Create hedged portfolio and compute alpha and beta
portfolio = -1*beta2016*benchmark_ret2016 + asset_ret2016
alpha, beta = alpha_beta(benchmark_ret2016,portfolio)
print('Portfolio with Alphas and Betas:')
print('alpha: ' + str(alpha))
print('beta: ' + str(beta))
# Plot the returns of the portfolio as well as the asset by itself
portfolio.plot(alpha=0.9,label='AAPL with Hedge')
asset_ret2016.plot(alpha=0.5);
benchmark_ret2016.plot(alpha=0.5)
plt.ylabel("Daily Return")
plt.legend();
# In[182]:
portfolio.mean()
# In[183]:
asset_ret2016.mean()
# In[184]:
portfolio.std()
# In[185]:
asset_ret2016.std()
# ** 2017 Based Figures **
# Get data for a different time frame:
start = '2017-01-01'
end = '2017-08-01'
asset2017 = get_pricing('AAPL', fields='price', start_date=start, end_date=end)
benchmark2017 = get_pricing('SPY', fields='price', start_date=start, end_date=end)
asset_ret2017 = asset2017.pct_change()[1:]
benchmark_ret2017 = benchmark2017.pct_change()[1:]
aret_val = asset_ret2017.values
bret_val = benchmark_ret2017.values
alpha2017, beta2017 = alpha_beta(bret_val,aret_val)
print('2016 Based Figures')
print('alpha: ' + str(alpha2017))
print('beta: ' + str(beta2017))
# ** Creating a Portfolio based off 2016 Beta estimate **
# Create hedged portfolio and compute alpha and beta
portfolio = -1*beta2016*benchmark_ret2017 + asset_ret2017
alpha, beta = alpha_beta(benchmark_ret2017,portfolio)
print 'Portfolio with Alphas and Betas Out of Sample:'
print 'alpha: ' + str(alpha)
print 'beta: ' + str(beta)
# Plot the returns of the portfolio as well as the asset by itself
portfolio.plot(alpha=0.9,label='AAPL with Hedge')
asset_ret2017.plot(alpha=0.5);
benchmark_ret2017.plot(alpha=0.5)
plt.ylabel("Daily Return")
plt.legend();
# What are the actual effects? Typically sacrificing average returns for less volatility, but this is also highly dependent on the security:
# In[189]:
portfolio.mean()
# In[190]:
asset_ret2017.mean()
# In[191]:
portfolio.std()
# In[192]:
asset_ret2017.std()
# # Great Job!

import numpy,import statsmodels,from statsmodels


# A Pair of hyperhels, brought to you by PharaohCola13

import mpl_toolkits.mplot3d.axes3d as p3
import matplotlib.pyplot as plt
from matplotlib import *
from numpy import *
from mpl_toolkits.mplot3d.art3d import *
from matplotlib.animation import *

name = "Hyperbolic Helicoid"

def shape(fig, alpha, color, edge_c, edge_w, grid, sides, edges, figcolor, rotation, rotmagt, rotmagp, save):
	plt.clf()

	# Definition of x
	def x_(u,v):
		x = (sinh(v) * cos(t * u))/(1 + cosh(u) * cosh(v))
		return x

	# Definition of y
	def y_(u,v):
		y = (sinh(v) * sin(t * u))/(1 + cosh(u) * cosh(v))
		return y

	# Definition of z
	def z_(u,v):
		z = (cosh(v) * sinh(u))/(1 + cosh(u) * cosh(v))
		return z

	# Value of the angles
	t = 3
	u = linspace(-2 * pi, 2 * pi, sides + 1)
	v = linspace(-2 * pi, 2 * pi, edges)

	u, v = np.meshgrid(u, v)

	# Symbolic representation
	x = x_(u,v)
	y = y_(u,v)
	z = z_(u,v)

	# Figure Properties
	ax = p3.Axes3D(fig)
	ax.set_facecolor(figcolor) # Figure background turns black

	# Axis Properties
	plt.axis(grid) # Turns off the axis grid
	plt.axis('equal')

	# Surface Plot
	hyperhel = ax.plot_surface(x, y, z)

	hyperhel.set_alpha(alpha) # Transparency of figure
	hyperhel.set_edgecolor(edge_c) # Edge color of the lines on the figure
	hyperhel.set_linewidth(edge_w) # Line width of the edges
	hyperhel.set_facecolor(color) # General color of the figure

	def rot_on():
		def animate(i):
			ax.view_init(azim=rotmagt * i, elev=rotmagp * i)

		if save == "MP4":
			# Animate
			ani = FuncAnimation(fig, animate, frames=500,
								interval=100, save_count=50)  # frames=100)#, repeat=True)

			Writer = writers['ffmpeg']
			writer = Writer(fps=30, bitrate=1800)
			ani.save('{}.mp4'.format(name), writer=writer)
		else:
			#save = None
			# Animate
			ani = FuncAnimation(fig, animate,
								interval=1, save_count=50)  # frames=100)#, repeat=True)
			pass

		plt.ion()
		plt.show()
		time.sleep(0)
		plt.close()

	if rotation == "On":
		rot_on()
	elif rotation == "Off":
		pass