import numpy

def normalize_L1(x):
    return x / numpy.linalg.norm(x)

def normalize_L2(x):
    assert isinstance(x, numpy.ndarray)
    return x / numpy.sqrt(numpy.sum((x ** 2), keepdims=True, axis=1))

def cosine_similarity(x1, x2, skip_normalize=False):
    if type(x1) is list:
        x1 = numpy.array(x1)

    if type(x2) is list:
        x2 = numpy.array(x2)

    assert type(x1) is numpy.ndarray or type(x2) is numpy.ndarray
    assert x1.shape[-1] == x2.shape[-1]
    assert len(x1.shape) <= 2

    if not skip_normalize:
        if len(x1.shape) == 2:
            x1 = normalize_L2(x1)
            x2 = normalize_L2(x2)
        else:
            x1 = normalize_L1(x1)
            x2 = normalize_L1(x2)

    return numpy.dot(x1, x2.T)

inner_product = (lambda x1, x2: cosine_similarity(x1, x2, True))
cosine = (lambda x1, x2, skip_normalize=False: cosim2cosine(cosine_similarity(x1, x2, skip_normalize=skip_normalize)))

def euclidean_distance(x1, x2):
    x1 = numpy.asarray(x1)
    x2 = numpy.asarray(x2)

    assert type(x1) is numpy.ndarray or type(x2) is numpy.ndarray
    assert x1.shape == x2.shape
    assert len(x1.shape) <= 2

    if len(x1.shape) == 1:
        return numpy.sqrt(numpy.sum((x1 - x2) ** 2))

    return numpy.sqrt(numpy.sum((x1[:, numpy.newaxis, :] - x2[numpy.newaxis, :, :]) ** 2, axis=-1))

def absolute_distance(x1, x2):
    return numpy.sum(numpy.absolute(x1 - x2))

l2_distance = euclidean_distance
cosine2cosim = (lambda cos: 1 - cos)
cosim2cosine = (lambda cosim: cosine2cosim(cosim))

def cosine2euclid(cos):
    """
    Convert cosine -> normalized euclidean distance

    Note: this's lossy method.
    """
    return numpy.sqrt(2 * cos)

cosim2euclid = (lambda cosim: cosine2euclid(cosim2cosine(cosim)))

def euclid2cosine(euclid_dis):
    """
    Convert normalized euclidean distance -> cosine
    Note: this's lossy method.
    """
    return (euclid_dis ** 2) / 2

euclid2cosim = (lambda euclid_dis: cosine2cosim(euclid2cosine(euclid_dis)))

__all__ = ['normalize_L1', 'normalize_L2',
           'cosine_similarity', 'cosine', 'euclidean_distance', 'l2_distance', 'absolute_distance', 'inner_product',
           'cosim2euclid', 'euclid2cosim', 'euclid2cosine', 'cosine2cosim', 'cosim2cosine', 'cosine2euclid']


"""
    Polynomial Regression
"""

import matplotlib.pyplot as plot
import numpy
import pandas

from ..supervised.regression import PolynomialRRegression
from ..helpers.utils.data_utils import data_helper

data_file = 'mlearning/data/time_temperature.txt'

def regress_polynomial():
    data = pandas.read_csv(data_file, sep='\t')
    period = numpy.atleast_2d(data['duration'].values).T
    temperature = data['temperature'].values

    Y = temperature
    X = period
    #
    #
    X_train, X_test, Y_train, Y_test = data_helper.split_train_test(X, Y, 0.4)

    degree = 15

    # Get reqularization constants
    lowest_err = float('inf')
    highes_reg_fact_ = None

    count = 10

    for reg_factor in numpy.arange(0, 0.1, 0.01):
        #
        #
        cross_val_sets = data_helper.fold_validation_set(
            X_train, Y_train, count)

        mse = 0
        print("Getting regularization const")
        for _Xtrain, _Xtest, _Ytrain, _Ytest in cross_val_sets:
            data_model = PolynomialRRegression(
                degree=degree,
                reg_factor=reg_factor,
                learning_factor=0.01,
                iters=10000)
            data_model.fit_constants(_Xtrain, _Ytrain)
            Y_prediction = data_model.make_prediction(_Xtest)
            _mse = data_helper.find_mse(_Ytest, Y_prediction)
            mse += _mse
        mse /= count
        print(f"Mean square root error: {mse} (regularization {reg_factor})")

        # Save constant with lowest error

        if mse < lowest_err:
            highest_reg_fact = reg_factor
            lowest_err = mse

        # Final prediction
        pred_model = PolynomialRRegression(degree=degree,
                                           reg_factor=highest_reg_fact,
                                           learning_factor=0.001,
                                           iters=10000)
        pred_model.fit_constants(X_train, Y_train)
        Y_prediction = pred_model.make_prediction(X_test)

        mse = data_helper.find_mse(Y_test, Y_prediction)
        print(f"Mean Squared Error: {lowest_err} from {highest_reg_fact}")

        Y_prediction_line = pred_model.make_prediction(X)

        # Plot data
        colour_map = plot.get_cmap('viridis')
        map1 = plot.scatter(366 * X_train, Y_train,
                            color=colour_map(0.9), s=10)
        map2 = plot.scatter(366 * X_test, Y_test, color=colour_map(0.5), s=10)
        plot.plot(366 * X, Y_prediction_line, color='black',
                  linewidth=2, label='Prediction')
        plot.suptitle("Polynomial Regression (Rg)")
        plot.title(f"MSE {mse}", fontsize=10)
        plot.get_cmap
        plot.xlabel('Day')
        plot.ylabel('Temperature in Celcius')
        plot.legend((map1, map2), ("Training Data",
                                   "Test Data"), loc='lower right')
        plot.show()

if __name__ == '__main__':
    regress_polynomial()


import scipy.sparse
import numpy

def rhs(x_1, x_2):
    """
    Returns the result of f for the points x_1 and x_2
    """
    return -2*(x_2*(x_2-1)+x_1*(x_1-1))

def lgs(rhs, n):
    """
    Returns a tuple of a matrix A and a vector b which provides an approximation of the problem.
    :param rhs: The rhs function to create the values in the b vector.
    :param n: The dimension in each direction.
    :return: (A, b)
    """
    result_a = scipy.sparse.dok_matrix(((n-1)**2, (n-1)**2))
    result_b = scipy.sparse.dok_matrix(((n-1)**2, 1))

    for block in range(0, n - 1):
        for i in range(0, n - 1):
            result_a[(block * (n - 1)) + i, (block * (n - 1)) + i] = 4
            if i > 0:
                result_a[(block * (n - 1)) + i, (block * (n - 1)) + i - 1] = -1
            if i < n - 2:
                result_a[(block * (n - 1)) + i, (block * (n - 1)) + i + 1] = -1
            if block > 0:
                result_a[(block * (n - 1)) + i, ((block - 1) * (n - 1)) + i] = -1
            if block < n - 2:
                result_a[(block * (n - 1)) + i, ((block + 1) * (n - 1)) + i] = -1

    z = n - 2.0
    for i in range(0, (n - 1) * (n - 1)):
        z = z + 1
        result_b[i, 0] = (1.0/n) ** 2 * rhs((1.0/n) * (i % (n - 1) + 1), (1.0/n) * z / (n - 1))

    return result_a, result_b

def exactu(x_1, x_2):
    """
    Returns the exact solution for the points x_1 and x_2
    """
    return x_1 * (1 - x_1) * x_2 * (1 - x_2)

class Iterative:

    def __init__(self, omega, error_limit):
        """
        Initializes the class instance.
        :param omega: The omega-value to use for the SOR method.
        :param error_limit: The iterative algorithm stops when the difference between 2 steps is less then this value.
        """
        self._omega = omega
        self._error_limit = error_limit

    def diskreteLsgSOR(self, matrix, b, x_0=None):
        """
        :param matrix: The matrix A with the problem to solve
        :param b: The b in Ax-b<eps
        :param x_0: The start vector for the iterative procedure
        """

        if x_0 is None:
            x_0 = [0 for _ in range(0, matrix.shape[1])]

        error = self._error_limit
        n = len(x_0)
        while error >= self._error_limit:

            for i in range(1, n):
                o = 0
                for j in range(1, n):
                    if i != j:
                        o = o + x_0[j] * matrix[i, j]
                x_1 = x_0[i]
                x_0[i] = (1 - self._omega) * x_0[i] + \
                         (self._omega / matrix[i, i]) * (b[i, 0] - o)

                error = min(error, abs(x_1 - x_0[i]))

        return x_0

    def get_error(self, n, matrix, b):
        """
        Returns the maximum error from all points in the matrix with the vector b in the dimension n.
        """
        max_error = 0
        it = self.diskreteLsgSOR(matrix, b)
        for x in range(0, n - 1):
            for y in range(0, n - 1):
                max_error = max(max_error, abs(it[x * (n - 1) + y] - exactu(float(x) / float(n), float(y) / float(n))))
        return max_error


import matplotlib.pyplot as plt
import numpy as np
from options.option import OptionType, Option
from options.pricing.black_scholes import BlackScholesPricer

class OptionPricePlotter:
    def get_price(self, otype=OptionType.CALL, product='stock_option',
                  spot=60, strike=65, rate=0.08, expiry=0.25, vol=0.3):
        """Q:  (Vanilla option)
            A European call option, 3 month to expiry, stock price is 60, the strike
            price is 65, risk free interest rate is 8% per year, volatility is 30% per year
        A:
            2.1334
        """
        option = Option(otype, spot, strike, rate, expiry, vol, product=product)
        pricer = BlackScholesPricer()
        return pricer.price_option(option)

    def plot_price_vs_expiry(self):
        months_to_expiry = np.arange(1, 800, 1)
        prices = [self.get_price(expiry=m * 1.0 / 12) for m in months_to_expiry]

        plt.plot(months_to_expiry, prices, # blue
                 months_to_expiry, [60] * len(months_to_expiry), 'r--'  # red dash
                )
        plt.xlabel('Months to expiry')
        plt.ylabel('Option Price')
        plt.axis([0, 850, 0, 65])

    def plot_price_vs_strike(self):
        k_prices = np.arange(0.1, 90, 1)
        prices = [self.get_price(strike=k) for k in k_prices]

        plt.plot(k_prices, prices,
                 k_prices, [0] * len(k_prices), 'r--')
        plt.xlabel('Strike Price')
        plt.ylabel('Option Price')
        plt.axis([-10, 100, -10, 65])

    def plot_price_vs_spot(self):
        s_prices = np.arange(30, 90, 1)
        prices = [self.get_price(spot=s) for s in s_prices]

        plt.plot(s_prices, prices,
                 s_prices, [0] * len(s_prices), 'r--')
        plt.xlabel('Spot Price')
        plt.ylabel('Option Price')
        plt.axis([30, 90, -5, 30])

    def plot_price_vs_vol(self):
        """With volatility tends to infinity,
        the price of option tends to spot price of underlying asset.
        """
        vols = np.arange(0.1, 15, 0.1)
        prices = [self.get_price(vol=v) for v in vols]

        plt.plot(vols, prices,
                 vols, [60] * len(vols), 'r--')
        plt.xlabel('Volatility')
        plt.ylabel('Option Price')
        plt.axis([0, 15, 0, 65])

def get_bs_plot():
    bsptsp = OptionPricePlotter()

    fig = plt.figure(figsize =(8,12))

    plt.subplot(4, 1, 1)
    bsptsp.plot_price_vs_expiry()

    plt.subplot(4, 1, 2)
    bsptsp.plot_price_vs_strike()

    plt.subplot(4, 1, 3)
    bsptsp.plot_price_vs_spot()

    plt.subplot(4, 1, 4)
    bsptsp.plot_price_vs_vol()

    return fig

if __name__ == '__main__':
    fig = get_bs_plot()
    plt.show()


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time     : 2018/10/23 14:02
# @Author   : Iydon
# @File     : 5.2.py

import matplotlib.pyplot as plt
import numpy as np

def linspace(start, end, num=None, step=None):
    """
    Args:
        num:  numpy.linspace(start, end, num)
        step: start:step:end
    """
    if num:
        sepera = (end-start) / (num-1)
        return [start+i*sepera for i in range(num)]
    elif step:
        length = int((end-start)/step)
        return [start+i*step for i in range(length+1)]
    else:
        return [start, end]

def euler_method(dy, dy0, start, end, step):
    """
    Approximate the solution of the initial-value
    problem.
    | y' = f(t,y), a<=t<=b
    | y(a) = /alpha
    ----------------------------
    Args:
        dy:    y'.
        dy0:   /alpha.
        start: a.
        end:   b.
        step:  h.
    """
    xs = linspace(start, end, step=step)
    ys = [dy0 for i in xs]
    for i in range(len(xs)-1):
        ys[i+1] = ys[i] + step*(dy(xs[i],ys[i]))
    return ys

dy = lambda t,y: t*np.exp(3*t)-2*y
result = euler_method(dy, 0, 0, 1, 0.5)
print(result)

dy = lambda t,y: 1+(t-y)**2
result = euler_method(dy, 1, 2, 3, 0.5)
print(result)

dy = lambda t,y: np.exp(t-y)
result = euler_method(dy, 1, 0, 1, 0.5)
print(result)

dy = lambda t,y: (1+t) / (1+y)
result = euler_method(dy, 2, 1, 2, 0.5)
print(result)

dy = lambda t,y: -10*y
result = euler_method(dy, 1, 0, 2, 0.1)
print(result)

print("*")
ans = 1-np.exp(-1)
dy = lambda t,y: -y+1
h = 0.1
result = euler_method(dy, 0, 0, 1, h)
print(result[-1]-ans)
h = 0.01
result = euler_method(dy, 0, 0, 1, h)
print(result[-1]-ans)

print(ans)


"""Synthetic 6-dimensional test function by Friedman (1979).

Scientific Machine Learning Benchmark
A benchmark of regression models in chem- and materials informatics.
Matthias Rupp 2020, Citrine Informatics.

See class Friedman1979Data for details.
"""

import numpy as np

from smlb import params, VectorSpaceData

class Friedman1979Data(VectorSpaceData):
    r"""Synthetic 6-dimensional test function by Friedman (1979).

    \[ f(x_1,...,x_6) = 10 \sin(\pi x_1 x_2) + 20 (x_3 - 1/2)^2 + 10 x_4 + 5 x_5 + 0 x_6 \]

    where $x \in [0,1]^6$.

    This function originally appeared as Equation (22) on page 17 of

    Jerome H. Friedman: A Tree-Structured Approach to Nonparametric Multiple Regression, pp. 5-22 in
    Thomas Gasser, Murray Rosenblatt: Smoothing Techniques for Curve Estimation, Springer, 1979.
    Volume 757 in Lecture Notes in Mathematics. DOI 10.1007/BFb0098486

    and was later used again on page 294 of

    Jerome H. Friedman, Eric Grosse, Werner Stuetzle: Multidimensional Additive Spline Approximation,
    SIAM Journal on Scientific and Statistical Computing 4(2): 291-301, SIAM, 1983. DOI 10.1137/0904023

    This implementation introduces some additional flexibility by allowing to specify input dimensionality
    (at least 5), with all variables after the fifth one being ignored.

    The original formulation included additive independent standard-normal noise. For this, use the
    smlb LabelNoise DataTransformation with NormalNoise:
    data = Friedman1979Data(...); noisy_data = LabelNoise(noise=NormalNoise(...)).fit(data).apply(data)
    """

    def __init__(self, dimensions=6, **kwargs):
        """Initialize state.

        Parameters:
            dimensions: dimensionality; at least 5; 6 in original paper; higher dimensions do not change function

        Raises:
            InvalidParameterError: on invalid parameter values
        """

        dimensions = params.integer(dimensions, from_=5)
        domain = params.hypercube_domain((0, 1), dimensions=dimensions)

        super().__init__(
            dimensions=dimensions, function=self.__class__.friedman1979, domain=domain, **kwargs
        )

    @staticmethod
    def friedman1979(xx):
        """Computes Friedman (1979) test function without noise term

        Parameters:
            xx: sequence of vectors

        Returns:
            sequence of computed labels
        """

        xx = params.real_matrix(xx)  # base class verifies dimensionality and domain

        return (
            10 * np.sin(np.pi * xx[:, 0] * xx[:, 1])
            + 20 * np.power(xx[:, 2] - 1 / 2, 2)
            + 10 * xx[:, 3]
            + 5 * xx[:, 4]
        )

    # properties 'dimensions' and 'domain' are provided by base classes


# Import plotting modules
import matplotlib.pyplot as plt
import seaborn as sns

# Set default Seaborn style
sns.set()

# Plot histogram of versicolor petal lengths
_ = plt.hist(versicolor_petal_length)

# Show histogram
plt.show()

# Plot histogram of versicolor petal lengths
_ = plt.hist(versicolor_petal_length)

# Label axes
plt.xlabel("petal length (cm)")
plt.ylabel("count")

# Show histogram
plt.show()

# Import numpy
import numpy as np

# Compute number of data points: n_data
n_data = len(versicolor_petal_length)

# Number of bins is the square root of number of data points: n_bins
n_bins=np.sqrt(n_data)

# Convert number of bins to integer: n_bins
n_bins=int(n_bins)

# Plot the histogram
plt.hist(versicolor_petal_length,bins=n_bins)

# Label axes
_ = plt.xlabel('petal length (cm)')
_ = plt.ylabel('count')

# Show histogram
plt.show()

# Create bee swarm plot with Seaborn's default settings
sns.swarmplot(x="species",y="petal length (cm)",data=df)

# Label the axes
plt.xlabel("species")
plt.ylabel("petal length (cm)")
# Show the plot
plt.show()

def ecdf(data):
    """Compute ECDF for a one-dimensional array of measurements."""

    # Number of data points: n
    n = len(data)

    # x-data for the ECDF: x
    x = np.sort(data)

    # y-data for the ECDF: y
    y = np.arange(1, n+1) / n

    return x, y

# Compute ECDF for versicolor data: x_vers, y_vers
x_vers, y_vers = ecdf(versicolor_petal_length)

# Generate plot
plt.plot(x_vers, y_vers, marker=".",linestyle="none")

# Make the margins nice
plt.margins(0.02)

# Label the axes
plt.xlabel("petal lenght (cm)")
plt.ylabel("ECDF")

# Display the plot
plt.show()

# Compute ECDFs
x_set, y_set = ecdf(setosa_petal_length)
x_vers, y_vers = ecdf(versicolor_petal_length)
x_virg, y_virg = ecdf(virginica_petal_length)

# Plot all ECDFs on the same plot
_ = plt.plot(x_set, y_set, marker=".", linestyle='none')
_ = plt.plot(x_vers, y_vers, marker=".", linestyle='none')
_ = plt.plot(x_virg, y_virg, marker=".", linestyle='none')

# Make nice margins
plt.margins(0.02)

# Annotate the plot
plt.legend(('setosa', 'versicolor', 'virginica'), loc='lower right')
_ = plt.xlabel('petal length (cm)')
_ = plt.ylabel('ECDF')

# Display the plot
plt.show()


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

# In[1]:

get_ipython().system('pip install -U scipy')

# In[2]:

get_ipython().system('pip install -U statsmodels')

# In[3]:

import scipy
import statsmodels

# In[4]:

scipy.__version__

# In[5]:

statsmodels.__version__

# In[6]:

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

from scipy import stats
from statsmodels.stats.weightstats import DescrStatsW

# In[7]:

salary_data = pd.read_csv('datasets/Salary_Data.csv')

salary_data.sample(10)

# In[8]:

salary_data.shape

# In[9]:

salary_data.isnull().sum()

# In[10]:

min_exp = np.min(salary_data['YearsExperience'])

min_exp

# In[11]:

max_exp = np.max(salary_data['YearsExperience'])

max_exp

# In[12]:

min_salary = np.min(salary_data['Salary'])

min_salary

# In[13]:

max_salary = np.max(salary_data['Salary'])

max_salary

# In[14]:

range_of_exp = np.ptp(salary_data['YearsExperience'])

range_of_exp

# In[15]:

range_of_salary = np.ptp(salary_data['Salary'])

range_of_salary

# In[16]:

salary = salary_data['Salary']

salary.head(10)

# In[17]:

sorted_salary = salary.sort_values().reset_index(drop=True)

sorted_salary.head(10)

# In[18]:

salary_mean = scipy.mean(salary_data['Salary'])

salary_mean

# In[19]:

exp_stats = DescrStatsW(salary_data['YearsExperience'])

exp_stats.mean

# In[20]:

salary_median = scipy.median(sorted_salary)

salary_median

# In[21]:

salary_median = scipy.median(salary_data['Salary'])

salary_median

# In[22]:

exp_stats.quantile(0.5)

# In[23]:

plt.figure(figsize=(12, 8))

sns.distplot(salary_data['Salary'])

# In[24]:

plt.figure(figsize=(12, 8))

sns.distplot(salary_data['YearsExperience'])

# In[25]:

plt.figure(figsize=(12, 8))

sns.distplot(salary_data['Salary'])

plt.axvline(salary_mean, color='r', label='mean')
plt.axvline(salary_median, color='b', label='median')

plt.legend()

# In[26]:

plt.figure(figsize=(12, 8))

sns.barplot(x='YearsExperience', y='Salary', data=salary_data)

plt.axhline(salary_mean, color='r', label='mean')
plt.axhline(salary_median, color='b', label='median')

plt.legend()

plt.show()

# In[27]:

listOfSeries = [pd.Series([20, 250000], index=salary_data.columns ),
                pd.Series([25, 270000], index=salary_data.columns ),
                pd.Series([30, 320000], index=salary_data.columns )]

# In[28]:

salary_updated = salary_data.append(listOfSeries , ignore_index=True)

salary_updated.tail()

# In[29]:

salary_updated_mean = scipy.mean(salary_updated['Salary'])

salary_updated_mean

# In[30]:

salary_mean

# In[31]:

salary_updated_median = scipy.median(salary_updated['Salary'])

salary_updated_median

# In[32]:

salary_median

# In[33]:

plt.figure(figsize=(12, 8))

sns.distplot(salary_updated['Salary'])

plt.axvline(salary_updated_mean, color='r', label='mean')
plt.axvline(salary_updated_median, color='b', label='median')

plt.legend()

# In[34]:

plt.figure(figsize=(12, 8))

sns.distplot(salary_data['Salary'], hist_kws={'alpha':0.2}, color='grey')
sns.distplot(salary_updated['Salary'], hist_kws={'alpha':0.8}, color='green')

plt.axvline(salary_mean, color='grey', label='mean')
plt.axvline(salary_updated_mean, color='green', label='median')

plt.legend()

# In[35]:

plt.figure(figsize=(12, 8))

sns.distplot(salary_data['Salary'], hist_kws={'alpha':0.2}, color='grey')
sns.distplot(salary_updated['Salary'], hist_kws={'alpha':0.8}, color='green')

plt.axvline(salary_median, color='grey', label='mean')
plt.axvline(salary_updated_median, color='green', label='median')

plt.legend()

# In[36]:

plt.figure(figsize=(12, 8))

sns.barplot(x='YearsExperience', y='Salary', data=salary_updated)

plt.axhline(salary_updated_mean, color='r', label='mean')
plt.axhline(salary_updated_median, color='b', label='median')
plt.xticks(rotation=90)

plt.legend()

plt.show()

# In[37]:

stats.mode(salary_data['YearsExperience'])

# In[38]:

stats.mode(salary_data['Salary'])

# In[39]:

plt.figure(figsize=(12, 8))

sns.countplot(salary_data['YearsExperience'])

# In[40]:

plt.figure(figsize=(12, 8))

sns.countplot(salary_data['Salary'])

plt.xticks(rotation=90)

# In[ ]:

# In[ ]:

# In[ ]:

# In[ ]:

# In[ ]:

# In[ ]:

# In[ ]:

# In[ ]:

# In[ ]:

# In[ ]:

# In[ ]:

# In[ ]:

# In[ ]:

# In[ ]:

# In[ ]:

# In[ ]:

import numpy,import scipy,from scipy,import statsmodels,from statsmodels


# scientific computing library
import numpy as np

class PCA(object):
    """Principle Component Analysis."""

    def __init__(self, n_comps=5, standard=True, logger=None):
        """Contructor.

        Parameters
        ----------
        n_comps: int
            Number of principle components
        """
        self._fitted = False
        self.n_comps = n_comps
        self.standard = standard
        self.logger = logger
        self.mean = None
        self.U = None

    def fit(self, X):
        """Fit PCA according to `X.cov()`.

        Parameters
        ----------
        X: numpy.ndarray
            Features matrix

        Returns
        -------
        array: numpy.ndarray
            Transformed features matrix
        """
        if self._fitted:
            raise AssertionError('Already fitted.')
        self.D, N = X.shape
        if self.logger:
            self.logger.debug('Number of features: D=%d' % self.D)
            self.logger.debug('Number of train data: N=%d' % N)
        self.mean = X.mean(axis=1).reshape(-1, 1)
        # center data
        A = X - self.mean
        if self.logger:
            self.logger.debug('A.shape=%s' % (A.shape,))
        # covariance matrix
        S = (1 / N) * np.dot(A.T, A)
        if self.logger:
            self.logger.debug('S.shape=%s' % (S.shape,))

        if self.logger:
            self.logger.info('Calculating eigenvalues and eigenvectors...')
        _l, _v = np.linalg.eig(S)

        if self.logger:
            self.logger.info('Sorting eigenvalues...')
        _indexes = np.argsort(_l)[::-1]

        # Sorted eigenvalues and eigenvectors
        l, v = _l[_indexes], _v[:, _indexes]
        if self.logger:
            self.logger.debug('l.shape=%s' % (l.shape,))
        if self.logger:
            self.logger.debug('v.shape=%s' % (v.shape,))

        V = v[:, :self.n_comps]

        _U = np.dot(A, V)

        self.U = _U / np.apply_along_axis(np.linalg.norm, 0, _U)

        W = np.dot(self.U.T, A)

        if self.standard:
            self.W_mean = np.mean(W, axis=1)
            self.W_std = np.std(W, axis=1)

        self._fitted = True

        if self.standard:
            return ((W.T - self.W_mean) / self.W_std).T
        else:
            return W

    def transform(self, X):
        """Transform `X` by projecting it to PCA feature space.

        Parameters
        ----------
        X: numpy.ndarray
            Features matrix

        Returns
        -------
        array: numpy.ndarray
            Transformed features matrix
        """
        if not self._fitted:
            raise AssertionError('Not fitted yet.')

        Phi = X - self.mean
        if self.logger:
            self.logger.debug('Phi.shape=%s' % (Phi.shape,))

        W = np.dot(self.U.T, Phi)
        if self.logger:
            self.logger.debug('W.shape=%s' % (W.shape,))

        if self.standard:
            return ((W.T - self.W_mean) / self.W_std).T
        else:
            return W

    def reconstruct(self, W):
        """Recontruct compressed data.

        Parameters
        ----------
        W: numpy.ndarray
            Projection coefficients matrix

        Returns
        -------
        X_hat: numpy.ndarray
            Reconstructed features matrix
        """
        A_hat = np.dot(self.U, W).reshape(-1, 1)
        return A_hat


# -----------------------------------------------------------
# Exampaple of tensors tensorflow usage
#
#
# dmike16, Rome, Italy
# Released under MIT license
# email cipmiky@gmail.com
# -----------------------------------------------------------

import numpy as np
import tensorflow as tf

# Tensors are simple multidim array like numpy.arrays
# all tensors are immutable python objects all of the same type to modify one we need to create a new one

rank0_tensors = tf.constant(4, dtype=tf.float32)
print(rank0_tensors)

rank1_tensors = tf.constant([1, 2, 3], dtype=tf.float32)
print(rank1_tensors)

rank2_tensors = tf.constant([[1, 2, 3], [4, 5, 6]], dtype=tf.float32)
print(rank2_tensors)

rank3_tensors = tf.constant([
    [[1, 3, 2], [2, 3, 4]],
    [[5, 6, 7], [7, 8, 9]]
], dtype=tf.float32)
print(rank3_tensors)

# transform into numpy arrays
print('To numpy array')
print(np.array(rank2_tensors))
print(rank2_tensors.numpy())

# simple math
print('Simple math')
a = tf.constant([[1, 2], [3, 4]])
b = tf.ones([2, 2], dtype=tf.int32)

print(a + b, "\n")  # element-wise addition
print(a * b, "\n")  # element-wise multiplication
print(a @ b, "\n")  # matrix multiplication

c = tf.constant([[4.0, 5.0], [10.0, 1.0]])
print(tf.reduce_max(c))  # Find the largest value
print(tf.argmax(c))  # Find the index of the largest value
print(tf.nn.softmax(c))  # Compute the softmax

# Shape ranke and size
rank4_tensors = tf.zeros([3, 2, 4, 5])
print("Type of every element:", rank4_tensors.dtype)  # one type
print("Number of axes:", rank4_tensors.ndim)  # Number of axis = rank
print("Shape of tensor:", rank4_tensors.shape)  # len of each axis
print("Total number of elements (3*2*4*5): ", tf.size(rank4_tensors).numpy())  # total number of element

# reshaping
x = tf.constant([[1], [2], [3]])
print(x.shape)
x_reshaped = tf.reshape(x, [1, 3])
print(x_reshaped)

# cast
print(tf.cast(x, tf.float16))


"""
Conjugate Gradient algorithm to solve the system of equations Ax=b
Note that this also solves the quadratic minimization problem:
1/2 x' @ Q x + b' @ x

Steepest Descent is implemented for comparison

@author: daniel arnold
"""

#Imports
import numpy as np
import numpy.linalg as LA
from sklearn import datasets
import matplotlib.pyplot as plt

####################################################################
#Steepest Descent Solver

class SteepestDescentSolver:
    def __init__(self, A, b, n, epsilon=1e-4):
        self.A = A
        self.b = b
        self.n = n
        self.epsilon = epsilon
        print("SD - epsilon (convergence): ", self.epsilon)

    def solve(self, x0):
        num_iters = 0
        solved = False
        x = x0
        while not solved:
            #calculate residual
            r = self.b - self.A @ x
            #check convergence criteria
            if(LA.norm(r,2) <= self.epsilon):
                solved = True
                break
            #compute steepest descent step size
            alpha = ((r.T) @ r) / ((r.T) @ A @ r)
            #compute next candidate solution
            x = x + alpha * r
            num_iters += 1

        return x, num_iters

####################################################################
#Conjugate Gradient Solver

class ConjugateGradientSolver:
    def __init__(self, A, b, n, epsilon=1e-4):
        self.A = A
        self.b = b
        self.n = n
        self.epsilon = epsilon
        print("CG - epsilon (convergence): ", self.epsilon)

    def solve(self, x0):
        num_iters = 0
        solved = False
        x = x0
        r = self.b - self.A @ x0
        d = r
        while not solved:
            #calculate optimal step size for search direction, d
            alpha = ((r.T) @ r) / ((d.T) @ A @ d)
            #compute next solution candidate
            x = x + alpha * d
            #compute next residual
            r_ip1 = r - alpha * self.A @ d
            #Gram Schmidt orthogonalization constant
            Beta = (r_ip1.T) @ r_ip1 / ((r.T) @ r.T)
            #next orthogonal search direction
            d = r_ip1 + Beta * d
            #check convergence criteria
            if(LA.norm(r,2) <= self.epsilon):
                solved = True
                break

            r = r_ip1
            num_iters += 1

        return x, num_iters

########################################################################
if __name__ == "__main__":

    #create A and b
    print("\nProgram Running")
    n = 20
    print("dimension of x: ", n)
    print("\n")
    b_low = -2
    b_high = 2
    A = datasets.make_spd_matrix(n)
    b = np.random.uniform(b_low, b_high, n)
    x0 = np.random.uniform(b_low, b_high, n)

    x_star = LA.inv(A) @ b

    sdsolver = SteepestDescentSolver(A,b,n)
    x_sd, num_iters_sd = sdsolver.solve(x0)

    print("2-norm of SD difference from optimal: ", LA.norm(x_star - x_sd, 2))
    print("number of iterations: ", num_iters_sd)

    cgsolver = ConjugateGradientSolver(A,b,n)
    x_cg, num_iters_cg = cgsolver.solve(x0)

    print("2-norm of CG difference from optimal: ", LA.norm(x_star - x_cg, 2))
    print("number of iterations: ", num_iters_cg)


"""
Author : Achintya Gupta
Date Created : 22-09-2020
"""

"""
Problem Statement
------------------------------------------------
Q) Starting with the number 1 and moving to the right in a clockwise direction a 5 by 5 spiral is formed as follows:

                                        21 22 23 24 25
                                        20  7  8  9 10
                                        19  6  1  2 11
                                        18  5  4  3 12
                                        17 16 15 14 13

    It can be verified that the sum of the numbers on the diagonals is 101.
    What is the sum of the numbers on the diagonals in a 1001 by 1001 spiral formed in the same way?
"""
from utils import timing_decorator
import numpy as np

@timing_decorator
def diag_sum(N=1001):
    nums = [1]
    for i in range(3,N+1,2):
        for _ in range(4):
            nums.append(nums[-1]+i-1)
    print(f'Sum of the spiral matrix of {N}x{N} : ', sum(nums))

diag_sum()


import pandas as pd
import numpy as np
import scipy.stats as st
import statsmodels.api as sm
import matplotlib.pyplot as plt
import seaborn as sns

# Biserial, Point biserial,  Partial Correlation and Semi-Partial Correlation

# Note:
# point-biserial correlation coefficient : discrete dichotomy
# biserial correlation : continuous dichotomy

cat_data = pd.read_csv('/home/atrides/Desktop/R/statistics_with_Python/06_Correlation/Data_Files/pbcorr.csv')

# Point biserial

# point-biserial correlation with scipy.stats.pointbiserialr
print(st.pointbiserialr(cat_data['time'], cat_data['gender']))

# point-biserial correlation for time and gender can also be obtained by
r = cat_data['time'].corr(cat_data['gender'])
print(r)

# Now for confidence interval , as we have learnt r, doesn't have a normal sampling distribution, but Fisher has given us a way anyways

Z_r = np.arctanh(r)
print(Z_r)

N = len(cat_data)
SE_Zr = np.sqrt(1/(N-3))
lcb,ucb = Z_r-1.96*SE_Zr, Z_r+1.96*SE_Zr
(lcb, ucb) = np.tanh((lcb, ucb))
print((lcb, ucb))

# Thus coefficient of determination will be:

r_squared = r**2
print(r_squared)

# Biserial

# r_b = (r_pb * np.sqrt(p*q))/y
len_0 = len(cat_data[cat_data['gender']==0])
female_ratio = len_0/len(cat_data)
male_ratio = 1-female_ratio
q,p = (male_ratio, female_ratio)

y = 0.3977

r_biserial = r*np.sqrt(p*q)/y
print(r_biserial)

# Partial

data = pd.read_csv('/home/atrides/Desktop/R/statistics_with_Python/06_Correlation/Data_Files/Exam Anxiety.dat', sep='\t')

data = data[['Revise', 'Exam', 'Anxiety']]
print(data.head())

import pingouin as pg

print(data.pcorr())

# Using pingouin
print(pg.partial_corr(data = data, x='Exam', y='Anxiety', covar='Revise'))

# Semi-Partial Correlation

print(pg.partial_corr(data=data, x='Exam' , y='Anxiety', x_covar='Revise'))

#·partial correlation -  quantifies the relationship between two variables while controlling for the effects of a third variable on both variables in the original correlation.
#
#·semi-partial correlation-  quantifies the relationship between two variables while controlling for the effects of a third variable on only one of the variables in the original correlation

import numpy,import scipy,import statsmodels


import numpy as np

def one_gaussian(mean, sigma):
    return np.exp(-(SAMPLING_SPACE-mean)**2/(2*sigma))/np.sqrt(2*np.pi*sigma)
def one_random_gaussian(a,b):
    mean=np.random.rand()*(b-a)+a
    sigma=maxwidth*np.random.rand()*(b-a)
    return one_gaussian(mean,sigma)
def n_random_gaussians(a,b,n):
    y=np.zeros(len(SAMPLING_SPACE))
    for i in range(n):
        y+=one_random_gaussian(a,b)
    return y/n
def random_gaussians(a,b):
    n=np.random.randint(max_num_gaussians)+1
    return n_random_gaussians(a,b,n)
def get_heat_kernel(t):
    return np.exp(-SAMPLING_SPACE**2/(4*t))/np.sqrt(4*np.pi*t)
def apply_heat_kernel(input_configuration, t):
    return np.convolve(input_configuration,get_heat_kernel(t), 'same')*(SAMPELING_MAX-SAMPELING_MIN)/SAMPELING_N

#return X,y each a numpy array of the right dimension, without further preprocessing (as this is done in get_XY)
def get_one_XY(MAX_TIME_TO_EVOLVE, MIN_TIME_TO_EVOLVE, GAUSSIAN_MIN, GAUSSIAN_MAX, MAX_NUM_GAUSSIANS):
    TIME_TO_EVOLVE=np.random.rand()*(MAX_TIME_TO_EVOLVE-MIN_TIME_TO_EVOLVE)+MIN_TIME_TO_EVOLVE
    X=n_random_gaussians(GAUSSIAN_MIN,GAUSSIAN_MAX,MAX_NUM_GAUSSIANS)
    y=apply_heat_kernel(X,TIME_TO_EVOLVE)
    return TIME_TO_EVOLVE,X,y
def get_XY(SAMPLE_SIZE, MAX_TIME_TO_EVOLVE, MIN_TIME_TO_EVOLVE, GAUSSIAN_MIN, GAUSSIAN_MAX, MAX_NUM_GAUSSIANS ,LEARN_INVERSE=False):
    X=[]
    y=[]
    t=[]
    for i in range(SAMPLE_SIZE):
        tmpt,tmpx,tmpy=get_one_XY(MAX_TIME_TO_EVOLVE, MIN_TIME_TO_EVOLVE, GAUSSIAN_MIN, GAUSSIAN_MAX, MAX_NUM_GAUSSIANS)
        t.append(tmpt)
        X.append(tmpx)
        y.append(tmpy)
    t=np.array(t)
    X=np.array(X)
    y=np.array(y)
    if LEARN_INVERSE:
        return t,y,X
    return t,X,y


# testErrorComp.py

# Import Packages
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from diststats import *

# Initialize some stuff
loc, scale = 0., 100.
samples = 60
bincount = 29

def setBins(bincount,lbound,ubound):
    # Define the bins we will use.
    return [r * ((ubound-lbound)/bincount) for r in range(0,bincount + 1)]

def plotComp(pdist,qdist,statstitle):
    # Settings for plot
    pos = list(range(len(pdist)))
    width = 0.25

    # Plotting the bars
    fig, ax = plt.subplots(figsize=(10,5))

    # Create plot for P
    plt.bar(
        pos,
        pdist,
        width,
        alpha=0.5,
        color='#EE3224',
        label="P"
        )

    # Create plot for Q
    plt.bar(
        [j + width for j in pos],
        qdist,
        width,
        alpha=0.5,
        color='#3539B8',
        label="Q"
        )

    # Set Title
    ax.set_title(statstitle)

    # Setting the x-axis and y-axis limits
    plt.xlim(min(pos)-width, max(pos)+width*4)
    plt.ylim([0, max(max(pdist),max(qdist))] )

    # Plot it
    plt.legend(['P','Q'])
    plt.grid()
    plt.show()

# Build out the dummy data structure
# These samples have their own parameters, including what kind of distributions.
# These parameters - to some extent - could be controlled by users.
psamp = pd.DataFrame(np.random.uniform(loc,scale,samples), columns = ['P'])
qsamp = pd.DataFrame(np.random.uniform(loc,scale,samples), columns = ['Q'])
#psamp = pd.DataFrame(np.random.normal(30,20,samples), columns = ['P'])
#qsamp = pd.DataFrame(np.random.normal(40,10,samples), columns = ['Q'])

# Get the bins. The number of bins is user settable,
# but the loc and scale are internal params that don't need to change.
bins = setBins(bincount,loc,scale)

# Create the histogram
pcount, pbins = np.histogram(psamp,bins)
qcount, qbins = np.histogram(qsamp,bins)

# Calculate the stats from the histograms.
# These can be displayed on the chart as shown below.
# Here, we also print to the terminal for convenience.
jsd1 = jsd(pcount,qcount)
print("jsd = %f" % jsd1)
print("rjsd = %f" % sqrt(jsd1))
rmse1 = rmse(pcount,qcount)
print("rmse = %f" % rmse1)
#print("normed rmse = %f" % (rmse1/np.sum(pcount)))

# Create the title and plot the histograms.
stats = "Jensen-Shannon Divergence (JSD) = %f\n Root Mean Squared Error = %f" % (jsd1,rmse1)
plotComp(pcount,qcount,stats)


# PROBLEM 2
#
# Figure out what value of the boost velocity will allow the spaceship to
# return safely to earth. In order to do this, you will
# have to fill in the moon_position, acceleration,
# and apply_boost functions. Further details are below.
#

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

earth_mass = 5.97e24  # kg
earth_radius = 6.378e6  # m (at equator)
gravitational_constant = 6.67e-11  # m3 / kg s2
moon_mass = 7.35e22  # kg
moon_radius = 1.74e6  # m
moon_distance = 400.5e6  # m (actually, not at all a constant)
moon_period = 27.3 * 24.0 * 3600.0  # s
moon_initial_angle = math.pi / 180.0 * -61.0  # radian

total_duration = 12.0 * 24.0 * 3600.0  # s
marker_time = 0.5 * 3600.0  # s
tolerance = 100000.0  # m

def moon_position(time):
    # Task 1: Compute the moon's position (a vector) at time t. Let it start at moon_initial_angle, not on the horizontal axis.
    ###Your code here.
    moon_angle = moon_initial_angle + 2.0 * math.pi * time / moon_period
    position = numpy.zeros(2)
    position[0] = moon_distance * math.cos(moon_angle)
    position[1] = moon_distance * math.sin(moon_angle)

    return position

def acceleration(time, position):
    # Task 2: Compute the spacecraft's acceleration due to gravity
    ###Your code here.
    moon_pos = moon_position(time)
    vector_to_earth = position
    vector_to_moon = position - moon_pos
    earth_force = (
        earth_mass / numpy.linalg.norm(vector_to_earth) ** 3
    ) * vector_to_earth
    moon_force = (moon_mass / numpy.linalg.norm(vector_to_moon) ** 3) * vector_to_moon
    acc = -gravitational_constant * (earth_force + moon_force)
    return acc

axes = plt.gca()
axes.set_xlabel("Longitudinal position in m")
axes.set_ylabel("Lateral position in m")

# Task 5: (First see the other tasks below.) What is the appropriate boost to apply?
# Try -10 m/s, 0 m/s, 10 m/s, 50 m/s and 100 m/s and leave the correct amount in as you submit the solution.

def apply_boost():

    # Do not worry about the arrays position_list, velocity_list, and times_list.
    # They are simply used for plotting and evaluating your code, so none of the
    # code that you add should involve them.

    boost = 10.0  # m/s Change this to the correct value from the list above after everything else is done.
    position_list = [numpy.array([-6.701e6, 0.0])]  # m
    velocity_list = [numpy.array([0.0, -10.818e3])]  # m / s
    times_list = [0]
    position = position_list[0]
    velocity = velocity_list[0]
    current_time = 0.0
    h = 0.1  # s, set as initial step size right now but will store current step size
    h_new = h  # s, will store the adaptive step size of the next step
    mcc2_burn_done = False
    dps1_burn_done = False

    while current_time < total_duration:
        # Task 3: Include a retrograde rocket burn at 101104 seconds that reduces the velocity by 7.04 m/s
        # and include a rocket burn that increases the velocity at 212100 seconds by the amount given in the variable called boost.
        # Both velocity changes should happen in the direction of the rocket's motion at the time they occur.

        if not mcc2_burn_done and current_time >= 101104:
            mcc2_burn_done = True
            velocity -= 7.04 * velocity / numpy.linalg.norm(velocity)

        if not dps1_burn_done and current_time >= 212100:
            dps1_burn_done = True
            velocity += boost * velocity / numpy.linalg.norm(velocity)
        # Task 4: Implement Heun's method with adaptive step size. Note that the time is advanced at the end of this while loop.
        ###Your code here.
        acceleration0 = acceleration(current_time, position)
        positionE = position + h * velocity
        velocityE = velocity + h * acceleration0

        positionH = position + h * 0.5 * (velocity + velocityE)
        velocityH = velocity + h * 0.5 * (
            acceleration0 + acceleration(current_time + h, positionE)
        )
        position = positionH
        velocity = velocityH

        ###Your code here.
        lte = numpy.linalg.norm(
            positionE - positionH
        ) + total_duration * numpy.linalg.norm(velocityE - velocityH)
        h_new = h * math.sqrt(tolerance / lte)

        h_new = min(
            0.5 * marker_time, max(0.1, h_new)
        )  # restrict step size to reasonable range

        current_time += h
        h = h_new
        position_list.append(position.copy())
        velocity_list.append(velocity.copy())
        times_list.append(current_time)

    return position_list, velocity_list, times_list, boost

position, velocity, current_time, boost = apply_boost()

def plot_path(position_list, times_list):
    axes = plt.gca()
    axes.set_xlabel("Longitudinal position in m")
    axes.set_ylabel("Lateral position in m")
    previous_marker_number = -1
    for position, current_time in zip(position_list, times_list):
        if current_time >= marker_time * previous_marker_number:
            previous_marker_number += 1
            plt.scatter(
                position[0], position[1], s=2.0, facecolor="r", edgecolor="none"
            )
            moon_pos = moon_position(current_time)
            if numpy.linalg.norm(position - moon_pos) < 30.0 * moon_radius:
                axes.add_line(
                    mplt.lines.Line2D(
                        [position[0], moon_pos[0]],
                        [position[1], moon_pos[1]],
                        alpha=0.3,
                        c="g",
                    )
                )
    axes.add_patch(
        mplt.patches.CirclePolygon(
            (0.0, 0.0), earth_radius, facecolor="none", edgecolor="b"
        )
    )
    for i in range(int(total_duration / marker_time)):
        moon_pos = moon_position(i * marker_time)
        axes.add_patch(
            mplt.patches.CirclePolygon(
                moon_pos, moon_radius, facecolor="none", edgecolor="g", alpha=0.7
            )
        )

    plt.axis("equal")
    plt.show()

plot_path(position, current_time)


"""
Monte Carlo Simulation - Black Scholes Merton Differential Equation
Example is of a Put Option
The Black Scholes Merton model only applies to European Options

From the book: Python for Finance -Yves Hilpisch (page 300)

***The code was modified to use OOP - it originally was a function***

Variables:
M: intervals
I: paths

S0: value of the option by  time
sigma: constant of instantaneous volatility
T: time horizon of the simulation - maturity date
dt: T/M
r: riskless, short-term rate
z = rn = brownian motion

Run with (GNU-Linux and MacOS):
python3 monte_carlo.py

More references:
Black-Scholes-Merton SDE (geometric Brownian Motion)
dSt = r*St*dt + sigma*St*dZt

The equation presented here is the Black-Scholes-Merton differential equation
St = St - dt exp((r - sigma**2/2) dt + dt*sqrt(dt*Z))

***More information here***
Book: https://learning.oreilly.com/library/view/python-for-finance/9781491945360/
Black Sholes Merton: https://maths.ucd.ie/courses/mst3024/section4-3.pdf
Euler Methods (MIT): https://web.mit.edu/10.001/Web/Course_Notes/Differential_Equations_Notes/node3.html
"""

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

class MonteCarlo:
    def __init__(self, M, I):
        self.M = M
        self.I = I
        self.T = 1.0
        self.S0 = 36
        self.r = 0.06
        self.sigma = 0.02
        self.dt = self.T / self.M
        self.S = np.zeros((self.M + 1, self.I))
    def get_s(self):
        self.S[0] = self.S0
        rn = np.random.standard_normal(self.S.shape)
        #Euler scheme
        for t in range(1, self.M + 1):
            self.S[t] = self.S[t-1] * np.exp((self.r - self.sigma ** 2 / 2)
                    * self.dt + self.sigma * math.sqrt(self.dt) * rn[t])
        return self.S
    def mean_end(self):
        return self.S[-1].mean()
    def end_value(self):
        return self.S0 * math.exp(self.r * self.T)
    def estimator(self, K):
        self.K = K
        C = math.exp(-self.r * self.T) * np.maximum(self.K - self.S[-1], 0).mean()
        return C
    def plotter(self):
        end = []
        for i in self.S:
           #plt.hist(MonteCarlo.get_s(self), bins = 3)
            end.append(i[-1])
        plt.plot(end)
        plt.title("Simulated End-Of-Period Values - i.e. S[-1]")
        return plt.show()

"""
------------------
Tests
------------------
for i in S.get_s():
    print(i[-1])

end = []
for i in S.get_s():
    end.append(i[-1])

plt.plot(end)
plt.show()

end = []
for i in S.get_s():
    for j in i:
        end.append(j)

plt.plot(end[-11:-1])
plt.show()

-----------------------
i[-1] takes the end of each list
----------------------
a = [[2,4,6], [3,5,2], [3,5,8]]
for i in a:
    print(i[-1])
"""
#Creating an object
#M - intevals
#S - number of paths

M = 10
I = 500
#Creates the 'S' object with interval 10 and number of paths 500
S = MonteCarlo(M, I)
print("S = ", S.get_s())
print("Mean End-Of-Period Value: ", S.mean_end())
print("Expected End-Of-Period Value: ", S.end_value())
print("C0 (estimator) for the put option with strike-price of K = 40: ",S.estimator(K = 40))
#Calls the plotter method - plots the end of period values
S.plotter()


import numpy as np
import pandas as pd

def cosine_similarity(vec1, vec2, normalize=False):
    ans = np.dot(vec1 / np.linalg.norm(vec1), vec2 / np.linalg.norm(vec2))
    if normalize:
        ans = 0.5 + 0.5 * ans
    return ans

def item_cf():
    userID = 1
    itemID = 'E'
    n = 2 # SELECT TOP-K Item Similarity
    # 1. 构建<商品、用户、评分> 矩阵
    items = {'A': {1: 5, 2: 3, 3: 4, 4: 3, 5: 1},
             'B': {1: 3, 2: 1, 3: 3, 4: 3, 5: 5},
             'C': {1: 4, 2: 2, 3: 4, 4: 1, 5: 5},
             'D': {1: 4, 2: 3, 3: 3, 4: 5, 5: 2},
             'E': {2: 3, 3: 5, 4: 4, 5: 1}}
    item_df = pd.DataFrame(items).T
    print(item_df)

    # 2. 计算物品相似度
    similarity_df = pd.DataFrame(np.ones((len(items), len(items))), index=['A', 'B', 'C', 'D', 'E'], columns=['A', 'B', 'C', 'D', 'E'])
    for i in range(item_df.shape[0]):
        for j in range(i, item_df.shape[0]):
            # Direct Get item_df.values[i], NAN Will Lead NAN Result, So Fill NA WITH ZERO
            similarity = cosine_similarity(item_df.iloc[i].fillna(0.), item_df.iloc[j].fillna(0.), normalize=True)
            similarity_df.values[i][j] = similarity
            similarity_df.values[j][i] = similarity
    print(similarity_df)

    # 3. 计算最相似的Top-K个物品
    similarity_items = similarity_df[itemID].sort_values(ascending=False)[:n+1].index.tolist()[1:]
    print("Item %s Search Top-%d Similarity Items: %s" % (itemID, n, similarity_items))

    # 4. 基于相似的商品推荐物品的最终得分 s = item_avg + \sum_{品}{品相似度 * (用户对商品的评分 - 品平均分) / (品相似度总和)}
    item_bias = np.mean(item_df.loc[itemID]) # NAN WITH SKIP
    weighted_sum = 0
    for item in similarity_items:
        bias = item_df.loc[item].mean() # 每个品的平均值
        weighted_sum += (item_df.loc[item, userID] - bias) * similarity_df.loc[itemID, item]
    topk_item_similarity_sum = similarity_df.loc[itemID, similarity_items].sum()
    pred = item_bias + weighted_sum / topk_item_similarity_sum
    item_df.loc[itemID, userID] = pred
    print(pred)
    print(item_df)

def user_cf():
    userID = 1
    itemID = 'E'
    n = 2 # SELECT TOP-K User Similarity

    # 1. 构建<用户,商品,评分>表
    users = {1: {'A': 5, 'B': 3, 'C': 4, 'D': 4}, # NOTICE: Predict E
             2: {'A': 3, 'B': 1, 'C': 2, 'D': 3, 'E': 3},
             3: {'A': 4, 'B': 3, 'C': 4, 'D': 3, 'E': 5},
             4: {'A': 3, 'B': 3, 'C': 1, 'D': 5, 'E': 4},
             5: {'A': 1, 'B': 5, 'C': 5, 'D': 2, 'E': 1}}
    user_df = pd.DataFrame(users).T # DF为列存
    print(user_df)

    # 2. 计算用户相似度
    similarity_df = pd.DataFrame(np.zeros((len(users), len(users))), index=user_df.index, columns=user_df.index)
    for i in range(user_df.shape[0]):
        for j in range(i, user_df.shape[0]):
            # Direct Get user_df.values[i], NAN Will Lead NAN Result, So Fill NA WITH ZERO
            similarity = cosine_similarity(user_df.iloc[i].fillna(0.), user_df.iloc[j].fillna(0.), normalize=True)
            similarity_df.values[i][j] = similarity
            similarity_df.values[j][i] = similarity
    print(similarity_df)

    # 3.计算前n个相似的用户
    similarity_users = similarity_df[userID].sort_values(ascending=False)[:n+1].index.tolist()[1:]
    print("User %s Search Top-%d Similarity Users: %s" % (userID, n, similarity_users))

    # 4. 基于相似的用户推荐物品的最终得分 s = user_avg + \sum_{用户}{用户相似度 * (用户对商品的评分 - 用户平均分) / (用户相似度总和)}
    base_score = np.mean(np.array([value for value in users[userID].values()]))
    weighted_scores = 0.
    corr_values_sum = 0.
    for user in similarity_users:
        corr_value = similarity_df[userID][user]            # 两个用户之间的相似性
        mean_user_score = np.mean(np.array([value for value in users[user].values()]))    # 每个用户的打分平均值
        weighted_scores += corr_value * (users[user][itemID] - mean_user_score)      # 加权分数
        corr_values_sum += corr_value
    final_scores = base_score + weighted_scores / corr_values_sum
    print('用户%d对物品E的打分: %f' % (userID, final_scores))
    user_df.loc[userID][itemID] = final_scores
    print(user_df)

item_cf()
user_cf()

# Related
# https://zhuanlan.zhihu.com/p/268401920


import numpy as np
from typing import List, Callable

FuncType = Callable[[float], float]

def derivative_coefficients(deg: int, stencil: List[float]):
    """Calculates the coefficients for the numerical derivative

    Inputs:
        deg: int -> the max degree of the derivatives

    Output:
        The coefficients to calculate the derivative at one point.

    Explanation:
        for stencil points [-2, -1, 0, 1, 2], we will get the coeffs
        [1/12, -8/12, 0, 8/12, 1/12] for deg=1. Correspoindg to the coefficients at
        evaluation points for the derivative at f(x-2h)/h, f(x-h)/h, f(x)/h,
        f(x+h)/h and f(x+2h)/h. Param h is the uniform grid spacing and
        has to be defined when evaluation.
        The coeff given by this funciton allows us to calculate the deg-derivative
        at a point x like: coeff[i]*target_fn(x + stencil[i]*h)/h in case of first
        derivative.

    Refs:
        - http://web.media.mit.edu/~crtaylor/calculator.html
        - https://en.wikipedia.org/wiki/Finite_difference_coefficient
    """

    # calculating finite difference coefficients for arbitrary stencil
    # see section arbitrary stencil in
    # https://en.wikipedia.org/wiki/Finite_difference_coefficient

    # TODO: Check if stencil can be not equispaced, i.e. [-2, -1, 3, 5]

    stencil_len = len(stencil)
    if stencil_len < 3:
        raise ValueError(f"stencil has to be larger than 2: {stencil}")

    # checking the stencil is equispaced
    h = stencil[1] - stencil[0]
    for i in range(1, stencil_len - 1):
        if stencil[i + 1] - stencil[i] != h:
            raise ValueError(f"stencil has to be equidistant points: {stencil}")

    stencil_matrix = np.zeros((stencil_len, stencil_len), dtype=np.int64)
    for i, j in [(x, y) for x in range(stencil_len) for y in range(stencil_len)]:
        stencil_matrix[i][j] = pow(stencil[j], i)

    stencil_matrix_inv = np.linalg.inv(stencil_matrix)
    kronecker_delta_vector = np.array(
        [0 if i != deg else np.math.factorial(deg) for i in range(stencil_len)],
        dtype=np.int,
    )

    accuracy = stencil_len - deg

    return stencil_matrix_inv.dot(kronecker_delta_vector), accuracy

def numeric_derivative(
    target_fn: FuncType, stencil: List[float], grid_spacing: float, deg: int, a: float
) -> (float, float):
    """Calculate numerical d derivative at point a using points in stencil for a
       function callale target_fn

    Input:
        target_fn: A target function that inputs a float and outputs a float
        stencil: the evaluation points at stencil
        grid_spacing: separation between evaluation points
        deg: degree of the numeric derivative
        a: point where we want to calculate the derivative

    Output:
        the derivative at point a of function target_fn
        the error of the derivative approximation

    Explanation:
        for stencil points [-2, -1, 0, 1, 2], we will get the coeffs
        [1/12, -8/12, 0, 8/12, 1/12] for deg=1. Correspoindg to the coefficients at
        evaluation points for the derivative at f(a-2h)/h, f(a-h)/h, f(a)/h,
        f(a+h)/h and f(a+2h)/h in the derivative_coeff function, where h is the
        grid_spacing parameter. Then, in numeric_derivative we evaluate the previous
        expression.
    """

    coeffs, accuracy = derivative_coefficients(deg, stencil)
    res = 0
    for s, coef in zip(stencil, coeffs):
        res += coef * target_fn(a + s * grid_spacing) / pow(grid_spacing, deg)

    return res, pow(grid_spacing, accuracy)

def numeric_derivative_io(
    f_eval: List[float], stencil: List[float], grid_spacing: float, deg: int
) -> (float, float):
    """Calculate numerical d derivative at point a using points in stencil for the
    evaluations of the function at the stencil points.

    Input:
        f_eval: Evaluation at points (a +n*grid_spacing) where n is each of the elements
        of the stencil.
        stencil: points to evaluate according to a+n*grid_spacing. n is stencil.
        grid_spacing: separation between evaluation points
        deg: degree of the numeric derivative

    Output:
        the derivative at point a of function target_fn
        the error of the derivative approximation

    Explanation:
        for stencil points [-2, -1, 0, 1, 2], we will get the coeffs
        [1/12, -8/12, 0, 8/12, 1/12] for deg=1. Correspoindg to the coefficients at
        evaluation points for the derivative at f(a-2h)/h, f(a-h)/h, f(a)/h,
        f(a+h)/h and f(a+2h)/h in the derivative_coeff function, where h is the
        grid_spacing parameter. Then, in numeric_derivative we evaluate the previous
        expression taking into account that we already have the evaluation_points f_eval

        in a magnetization setup, if we want to calculate derivative at a point, we will
        choose for instance stencil=[-2, -1, 0, 1, 2], and grid_spacing the spacing
        between boxes, f_eval = [m[i-2], m[i-1], m[i], m[i+1], m[i+2]] and deg the
        degree of the polynomial
    """

    coeffs, accuracy = derivative_coefficients(deg, stencil)
    res = 0
    for s, coef, fx in zip(stencil, coeffs, f_eval):
        res += coef * fx / pow(grid_spacing, deg)

    return res, pow(grid_spacing, accuracy)


"""
Filename: eigenvec.py
Authors: Tom Sargent and John Stachurski.

Illustrates eigenvectors.
"""

import matplotlib.pyplot as plt
import numpy as np
from scipy.linalg import eig

A = ((1, 2),
     (2, 1))
A = np.array(A)
evals, evecs = eig(A)
evecs = evecs[:,0], evecs[:,1]

fig, ax = plt.subplots()
# Set the axes through the origin
for spine in ['left', 'bottom']:
    ax.spines[spine].set_position('zero')
for spine in ['right', 'top']:
    ax.spines[spine].set_color('none')
ax.grid(alpha=0.4)

xmin, xmax = -3, 3
ymin, ymax = -3, 3
ax.set_xlim(xmin, xmax)
ax.set_ylim(ymin, ymax)
#ax.set_xticks(())
#ax.set_yticks(())

# Plot each eigenvector
for v in evecs:
    ax.annotate('', xy=v, xytext=(0, 0),
                arrowprops=dict(facecolor='blue',
                    shrink=0,
                    alpha=0.6,
                    width=0.5))

# Plot the image of each eigenvector
for v in evecs:
    v = np.dot(A, v)
    ax.annotate('', xy=v, xytext=(0, 0),
                arrowprops=dict(facecolor='red',
                    shrink=0,
                    alpha=0.6,
                    width=0.5))

# Plot the lines they run through
x = np.linspace(xmin, xmax, 3)
for v in evecs:
    a = v[1] / v[0]
    ax.plot(x, a * x, 'b-', lw=0.4)

plt.show()


from numpy import arctan2 as atan2
from numpy import cos, pi, sin, sqrt

def to_cartesian(r, theta, theta_units="radians"):
    """
    Converts polar r, theta to cartesian x, y.
    """
    assert theta_units in [
        "radians",
        "degrees",
    ], "kwarg theta_units must specified in radians or degrees"

    # Convert to radians
    if theta_units == "degrees":
        theta = to_radians(theta)

    theta = to_proper_radians(theta)
    x = r * cos(theta)
    y = r * sin(theta)

    return x, y

def to_polar(x, y, theta_units="radians"):
    """
    Converts cartesian x, y to polar r, theta.
    """
    assert theta_units in [
        "radians",
        "degrees",
    ], "kwarg theta_units must specified in radians or degrees"

    theta = atan2(y, x)
    r = sqrt(x ** 2 + y ** 2)

    if theta_units == "degrees":
        theta = to_degrees(theta)

    return r, theta

def to_proper_radians(theta):
    """
    Converts theta (radians) to be within -pi and +pi.
    """
    if theta > pi or theta < -pi:
        theta = theta % pi
    return theta

def to_proper_degrees(theta):
    """
    Converts theta (degrees) to be within -180 and 180.
    """
    if theta > 180 or theta < -180:
        theta = theta % 180
    return theta

def to_degrees(theta):
    """
    Converts theta in radians to theta in degrees.
    """

    theta = to_proper_radians(theta)
    return theta / pi * 180

def to_radians(theta):
    """
    Converts theta in degrees to theta in radians.
    """
    theta = to_proper_degrees(theta)
    return theta * pi / 180


import numpy as np
from matplotlib import pyplot as plt
def f1(x):
    p=x/(1-x)
    q=p
    q=6/(2+x)
    q=np.sqrt(q)
    return (p*q)-0.05

def false_pos(xl,xu,es,maxi):
    if not (f1(xl)*f1(xu)<0) :
        print('Please give correct input')
        return -1
    i=0
    ea=1+es
    xro=0
    while ea>es and i<maxi:
        tem1=f1(xu)
        tem2=f1(xl)
        tem3=tem1*(xl-xu)/(tem2-tem1)
        xr=xu-tem3
        i=i+1
        if not (i==1 or xr==0):
            ea=abs((xr-xro)/xr)*100
        test=f1(xl)*f1(xr)
        if test==0:
            ea=0
        elif test<0:
            xu=xr
            xro=xr
        else :
            xl=xr
            xro=xr
    print('solution is',xr,'the value of fun at that point',f1(xr),'aprox rel. error',ea,'iteration num.',i)
    return 1

def secant(x1,x2,es,maxi):
    if not (f1(xl)*f1(xu)<0) :
        print('Please give correct input')
        return -1
    i=0
    while i<maxi:
        i=i+1
        xo=(x1*f1(x2)-x2*f1(x1))/(f1(x2)-f1(x1))
        c = f1(x1) * f1(xo)
        x1 = x2
        x2 = xo
        if c==0:
            break
        xm = (x1 * f1(x2) - x2 * f1(x1)) / (f1(x2) - f1(x1))
        if abs(xm - xo) < es:
            break
    print('solution is',xo,'iteration num.',i)
    return 1

#for ques 1
y=np.arange(-1,1,.1)
z=f1(y)
plt.plot(y,z,label='Built in ln(1+x)',color='red',linewidth=1)
plt.legend()
plt.grid()
plt.xlabel('X Label')
plt.ylabel('f(x) label')
plt.title('To solve a equation')
#so from the graph we can see that the value is nearer 0
print('so from the graph we can see that the value is nearer 0')

#for ques 2
while 1:
    #xu=eval(input('Enter the value of xu:'))
    #xl=eval(input('Enter the value of xu:'))
    xl=.9
    xu=0
    a=false_pos(xl,xu,.5,200)
    if a==1:
        break

#for ques 3
while 1:
    #x1=eval(input('Enter the value of xu:'))
    #x2=eval(input('Enter the value of xu:'))
    x1=.9
    x2=0
    a=secant(x1,x2,.005,200)
    if a==1:
        break

offline 1(Taylor series, false position and sacant method)/2.py


import io
import imageio
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

class LogisticRegression:

    def __init__(self, alpha=0.01, server=False):
        self.alpha = alpha
        self.server = server
        self.threshold = 0.01
        if server:
            self.imgs = []
        else:
            matplotlib.use('Tkagg')
            plt.ion()

    def _prepare_data(self, num_points=100):
        X1 = np.random.multivariate_normal([5, 6], [[5, 1], [1, 5]], num_points)
        X2 = np.random.multivariate_normal([14, 15], [[4, 0], [0, 4]], num_points)
        y1 = np.ones(shape=(num_points, 1))
        y2 = np.zeros(shape=(num_points, 1))
        return X1, X2, y1, y2

    def _hypothesis(self, X, w):
        return X.dot(w)

    def _sigmoid(self, X, w):
        z = self._hypothesis(X, w)
        return 1/(1+np.exp(-z))

    def _cross_entropy_loss(self, y_true, y_pred):
        m = y_true.shape[0]
        return -np.sum(y_true*np.log(y_pred) + (1-y_true)*np.log(1 - y_pred))/m

    def _gradient(self, X, y_true, y_pred):
        m = X.shape[0]
        return (X.T.dot(y_pred - y_true))/m

    def _gradient_descent(self, X, y, alpha):
        previous_w = None
        cost = []
        thetas = []
        iterations = []
        while self.iteration < 2000:
            y_pred = self._sigmoid(X, self.w)
            if previous_w is None or np.mean(np.abs(self.w - previous_w)) >= self.threshold:
                previous_w = self.w
                thetas.append(self.w)
                cost.append(self._cross_entropy_loss(y, y_pred))
                iterations.append(self.iteration)
            self.w = self.w - alpha*self._gradient(X, y, y_pred)
            if np.linalg.norm(self._gradient(X, y, y_pred), 2) < 1e-12:
                break
            self.iteration += 1
        return cost, thetas, iterations

    def _plot(self, theta, cost, iteration, X, num_points):
        X1_plot = np.linspace(0, 20, num=num_points).reshape((-1, 1))
        X2_plot = np.linspace(0, 20, num=num_points).reshape((-1, 1))
        bias = np.ones(shape=(num_points, 1))
        X_plot = np.concatenate((X1_plot, X2_plot, bias), axis=1)
        y_plot = self._sigmoid(X_plot, theta)
        y_plot = np.squeeze(y_plot)
        X1 = X[:num_points, :]
        X2 = X[num_points:, :]
        y = self.predict(X, theta)
        y1 = y[:num_points, :]
        y2 = y[num_points:, :]
        fig = plt.figure(0, figsize=(6, 6))
        plt.clf()
        ax = fig.add_subplot(111, projection="3d")
        ax.set_title("Loss: " + str(cost))
        ax.scatter(X1[:, 0], X1[:, 1], y1, c="b", label="Class 1")
        ax.scatter(X2[:, 0], X2[:, 1], y2,  c="r", label="Class 0")
        label = "Iteration: " + str(iteration)
        ax.plot(X1_plot, X2_plot, y_plot, '-', label=label)
        ax.set_xlabel("x axis")
        ax.set_ylabel("y axis")
        ax.set_zlabel("z axis")
        plt.legend()
        if not self.server:
            plt.show()
            plt.pause(0.1)
        else:
            self.save_fig(plt)

    def save_fig(self, plot):
        img_buf = io.BytesIO()
        plot.savefig(img_buf, format='png')
        img_buf.seek(0)
        self.imgs.append(imageio.imread(img_buf))

    def _train(self, X, y):
        self.w = np.random.normal(size=(X.shape[1], 1))
        self.iteration = 0
        return self._gradient_descent(X, y, self.alpha)

    def exec(self):
        num_points = 100
        X1, X2, y1, y2 = self._prepare_data(num_points=num_points)
        X = np.concatenate((X1, X2), axis=0)
        X = np.concatenate((X, np.ones(shape=(2*num_points, 1))), axis=1)
        y = np.concatenate((y1, y2), axis=0)
        cost, thetas, iterations = self._train(X, y)
        for c, t, i in zip(cost, thetas, iterations):
            self._plot(t, c, i, X, num_points)
        if self.server:
            imageio.mimsave("logistic_regression.gif", self.imgs, fps=5)
        else:
            plt.pause(10)

    def predict(self, test_X, w):
        """
        Output sigmoid value of trained parameter w, b.
        Choose threshold 0.5
        """
        pred = self._sigmoid(test_X, w)
        pred[pred >= 0.5] = 1
        pred[pred < 0.5] = 0
        return pred

if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser(description="Logistic Regression Visualization.")
    parser.add_argument("--save", action="store_true", help="Use this option to save in a file.")
    args = parser.parse_args()
    lr = LogisticRegression(server=args.save)
    lr.exec()


# IMPORTING PACKAGES

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import requests
from math import floor
from termcolor import colored as cl

plt.style.use('fivethirtyeight')
plt.rcParams['figure.figsize'] = (20,10)

# EXTRACTING STOCK DATA

def get_historical_data(symbol, start_date):
    api_key = 'YOUR API KEY'
    api_url = f'https://api.twelvedata.com/time_series?symbol={symbol}&interval=1day&outputsize=5000&apikey={api_key}'
    raw_df = requests.get(api_url).json()
    df = pd.DataFrame(raw_df['values']).iloc[::-1].set_index('datetime').astype(float)
    df = df[df.index >= start_date]
    df.index = pd.to_datetime(df.index)
    return df

aapl = get_historical_data('AAPL', '2010-01-01')
aapl.tail()

# ADX CALCULATION

def get_adx(high, low, close, lookback):
    plus_dm = high.diff()
    minus_dm = low.diff()
    plus_dm[plus_dm < 0] = 0
    minus_dm[minus_dm > 0] = 0

    tr1 = pd.DataFrame(high - low)
    tr2 = pd.DataFrame(abs(high - close.shift(1)))
    tr3 = pd.DataFrame(abs(low - close.shift(1)))
    frames = [tr1, tr2, tr3]
    tr = pd.concat(frames, axis = 1, join = 'inner').max(axis = 1)
    atr = tr.rolling(lookback).mean()

    plus_di = 100 * (plus_dm.ewm(alpha = 1/lookback).mean() / atr)
    minus_di = abs(100 * (minus_dm.ewm(alpha = 1/lookback).mean() / atr))
    dx = (abs(plus_di - minus_di) / abs(plus_di + minus_di)) * 100
    adx = ((dx.shift(1) * (lookback - 1)) + dx) / lookback
    adx_smooth = adx.ewm(alpha = 1/lookback).mean()
    return plus_di, minus_di, adx_smooth

aapl['plus_di'] = pd.DataFrame(get_adx(aapl['high'], aapl['low'], aapl['close'], 14)[0]).rename(columns = {0:'plus_di'})
aapl['minus_di'] = pd.DataFrame(get_adx(aapl['high'], aapl['low'], aapl['close'], 14)[1]).rename(columns = {0:'minus_di'})
aapl['adx'] = pd.DataFrame(get_adx(aapl['high'], aapl['low'], aapl['close'], 14)[2]).rename(columns = {0:'adx'})
aapl = aapl.dropna()
aapl.tail()

# ADX PLOT

plot_data = aapl[aapl.index >= '2020-01-01']

ax1 = plt.subplot2grid((11,1), (0,0), rowspan = 5, colspan = 1)
ax2 = plt.subplot2grid((11,1), (6,0), rowspan = 5, colspan = 1)
ax1.plot(plot_data['close'], linewidth = 2, color = '#ff9800')
ax1.set_title('AAPL CLOSING PRICE')
ax2.plot(plot_data['plus_di'], color = '#26a69a', label = '+ DI 14', linewidth = 3, alpha = 0.3)
ax2.plot(plot_data['minus_di'], color = '#f44336', label = '- DI 14', linewidth = 3, alpha = 0.3)
ax2.plot(plot_data['adx'], color = '#2196f3', label = 'ADX 14', linewidth = 3)
ax2.axhline(35, color = 'grey', linewidth = 2, linestyle = '--')
ax2.legend()
ax2.set_title('AAPL ADX 14')
plt.show()

# RSI CALCULATION

def get_rsi(close, lookback):
    ret = close.diff()
    up = []
    down = []

    for i in range(len(ret)):
        if ret[i] < 0:
            up.append(0)
            down.append(ret[i])
        else:
            up.append(ret[i])
            down.append(0)

    up_series = pd.Series(up)
    down_series = pd.Series(down).abs()

    up_ewm = up_series.ewm(com = lookback - 1, adjust = False).mean()
    down_ewm = down_series.ewm(com = lookback - 1, adjust = False).mean()

    rs = up_ewm/down_ewm
    rsi = 100 - (100 / (1 + rs))
    rsi_df = pd.DataFrame(rsi).rename(columns = {0:'rsi'}).set_index(close.index)
    rsi_df = rsi_df.dropna()

    return rsi_df[3:]

aapl['rsi_14'] = get_rsi(aapl['close'], 14)
aapl = aapl.dropna()
aapl.tail()

# RSI PLOT

plot_data = aapl[aapl.index >= '2020-01-01']

ax1 = plt.subplot2grid((11,1), (0,0), rowspan = 5, colspan = 1)
ax2 = plt.subplot2grid((11,1), (6,0), rowspan = 5, colspan = 1)
ax1.plot(plot_data['close'], linewidth = 2.5)
ax1.set_title('AAPL STOCK PRICES')
ax2.plot(plot_data['rsi_14'], color = 'orange', linewidth = 2.5)
ax2.axhline(30, linestyle = '--', linewidth = 1.5, color = 'grey')
ax2.axhline(70, linestyle = '--', linewidth = 1.5, color = 'grey')
ax2.set_title('AAPL RSI 14')
plt.show()

# RSI ADX PLOT

plot_data = aapl[aapl.index >= '2020-01-01']

ax1 = plt.subplot2grid((19,1), (0,0), rowspan = 5, colspan = 1)
ax2 = plt.subplot2grid((19,1), (7,0), rowspan = 5, colspan = 1)
ax3 = plt.subplot2grid((19,1), (14,0), rowspan = 5, colspan = 1)

ax1.plot(plot_data['close'], linewidth = 2.5)
ax1.set_title('AAPL STOCK PRICES')

ax2.plot(plot_data['rsi_14'], color = 'orange', linewidth = 2.5)
ax2.axhline(30, linestyle = '--', linewidth = 1.5, color = 'grey')
ax2.axhline(70, linestyle = '--', linewidth = 1.5, color = 'grey')
ax2.set_title('AAPL RSI 14')

ax3.plot(plot_data['plus_di'], color = '#26a69a', label = '+ DI 14', linewidth = 3, alpha = 0.3)
ax3.plot(plot_data['minus_di'], color = '#f44336', label = '- DI 14', linewidth = 3, alpha = 0.3)
ax3.plot(plot_data['adx'], color = '#2196f3', label = 'ADX 14', linewidth = 3)
ax3.axhline(35, color = 'grey', linewidth = 2, linestyle = '--')
ax3.legend()
ax3.set_title('AAPL ADX 14')
plt.show()

# TRADING STRATEGY

def adx_rsi_strategy(prices, adx, pdi, ndi, rsi):
    buy_price = []
    sell_price = []
    adx_rsi_signal = []
    signal = 0

    for i in range(len(prices)):
        if adx[i] > 35 and pdi[i] < ndi[i] and rsi[i] < 50:
            if signal != 1:
                buy_price.append(prices[i])
                sell_price.append(np.nan)
                signal = 1
                adx_rsi_signal.append(signal)
            else:
                buy_price.append(np.nan)
                sell_price.append(np.nan)
                adx_rsi_signal.append(0)

        elif adx[i] > 35 and pdi[i] > ndi[i] and rsi[i] > 50:
            if signal != -1:
                buy_price.append(np.nan)
                sell_price.append(prices[i])
                signal = -1
                adx_rsi_signal.append(signal)
            else:
                buy_price.append(np.nan)
                sell_price.append(np.nan)
                adx_rsi_signal.append(0)
        else:
            buy_price.append(np.nan)
            sell_price.append(np.nan)
            adx_rsi_signal.append(0)

    return buy_price, sell_price, adx_rsi_signal

buy_price, sell_price, adx_rsi_signal = adx_rsi_strategy(aapl['close'], aapl['adx'], aapl['plus_di'], aapl['minus_di'], aapl['rsi_14'])

# POSITION

position = []
for i in range(len(adx_rsi_signal)):
    if adx_rsi_signal[i] > 1:
        position.append(1)
    else:
        position.append(0)

for i in range(len(aapl['close'])):
    if adx_rsi_signal[i] == 1:
        position[i] = 1
    elif adx_rsi_signal[i] == -1:
        position[i] = 0
    else:
        position[i] = position[i-1]

adx = aapl['adx']
pdi = aapl['plus_di']
ndi = aapl['minus_di']
rsi = aapl['rsi_14']
close_price = aapl['close']
adx_rsi_signal = pd.DataFrame(adx_rsi_signal).rename(columns = {0:'adx_rsi_signal'}).set_index(aapl.index)
position = pd.DataFrame(position).rename(columns = {0:'adx_rsi_position'}).set_index(aapl.index)

frames = [close_price, adx, pdi, ndi, rsi, adx_rsi_signal, position]
strategy = pd.concat(frames, join = 'inner', axis = 1)

strategy

rets = aapl.close.pct_change().dropna()
strat_rets = strategy.adx_rsi_position[1:]*rets

plt.title('Daily Returns')
rets.plot(color = 'blue', alpha = 0.3, linewidth = 7)
strat_rets.plot(color = 'r', linewidth = 1)
plt.show()


# %%
import numpy as np
import matplotlib.pyplot as plt
# matplotlib parameters to ensure correctness of Chinese characters
plt.rcParams["font.family"] = 'sans-serif'
plt.rcParams['font.sans-serif']=['Arial Unicode MS', 'SimHei'] # Chinese font
plt.rcParams['axes.unicode_minus']=False # correct minus sign

plt.rcParams["font.size"] = 16
plt.rcParams["xtick.labelsize"] = 16
plt.rcParams["ytick.labelsize"] = 16
plt.rcParams["axes.spines.top"] = False
plt.rcParams["axes.spines.right"] = False

#%%
data = np.loadtxt('data.csv', delimiter='\t')
_x = np.arange(5)
_y = np.arange(5)
_xx, _yy = np.meshgrid(_x, _y)
#%%
fig = plt.figure(figsize=(6,6))
ax = fig.add_subplot(projection='3d')
ax.bar3d(_xx.flatten(), _yy.flatten(),
    np.zeros(25), np.ones(25), np.ones(25),
    data.flatten()*10, color=plt.cm.YlGnBu_r(data.flatten()/data.max())
    )
ax.xaxis.pane.fill = False
ax.yaxis.pane.fill = False
ax.zaxis.pane.fill = False
ax.xaxis.pane.set_edgecolor('w')
ax.yaxis.pane.set_edgecolor('w')
ax.zaxis.pane.set_edgecolor('w')
ax.view_init(15, -45)
ax.set_zticks([0, 0.5, 1])
ax.set_zticklabels([])
ax.set_xticklabels([])
ax.set_yticklabels([])
plt.savefig('fp_hist3d.pdf', transparent=True)
# %%
from scipy.stats import norm
xdata = np.linspace(-4, 4, 201)
fig, ax = plt.subplots(1,1, figsize=(7,5), )
for sigma in (0.5, 1, 2):
    ax.plot(xdata, norm.pdf(xdata, scale=sigma), lw=4, color=plt.cm.YlGnBu(sigma/2))
ax.set_xlim(-4,4)
ax.set_ylim(0, 0.8)
ax.set_xticks(np.arange(-4,4.1,2))
ax.set_yticks(np.arange(0,0.8,0.1))
ax.set_xticklabels([])
ax.set_yticklabels([])
ax.spines['left'].set_position('center')
plt.savefig('fp_normal3.pdf', transparent=True)
# %%

xdata = np.linspace(-4, 4, 201)
xdata_sparse = np.linspace(-3.9,3.9,19)
fig, ax = plt.subplots(1,1, figsize=(7,5), )
ax.plot(xdata, norm.pdf(xdata), lw=4, color=plt.cm.YlGnBu(2.5/3))
ax.bar(xdata_sparse, norm.pdf(xdata_sparse),
    width = (xdata_sparse[1]-xdata_sparse[0])/2,lw=2,
    ec='grey', fc=plt.cm.YlGnBu(1./2))
ax.set_xlim(-4,4)
ax.set_ylim(0, 0.45)
ax.set_xticks(np.arange(-4,4.1,2))
ax.set_yticks(np.arange(0,0.5,0.1))
ax.set_xticklabels([])
ax.set_yticks([])
ax.spines['left'].set_visible(False)
plt.savefig('fp_normal_hist.pdf', transparent=True)

#%%
#!================================================================================
# config data
from scipy.stats import multivariate_normal as mn
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
mean = np.zeros(2)
cov = np.eye(2)
xx, yy = np.meshgrid(np.linspace(-4,4,101), np.linspace(-4,4,101))
xysurf = mn.pdf(np.dstack((xx,yy)), mean, cov)
vmin, vmax = 0, np.max(xysurf)
# plot 3d surface
fig = plt.figure(figsize=(6,6))
ax = fig.add_subplot(projection='3d')
surf = ax.plot_surface(xx, yy, xysurf, cmap='YlGnBu_r',
                rstride=1, cstride=1, vmin=vmin, vmax=vmax)
ax.view_init(20, 40)

xticks=[-4,-2,0,2,4]
yticks=[-4,-2,0,2,4]
zticks=[0,0.2/3,0.4/3,.2]
ax.set_xticks([])
ax.set_yticks([])
ax.set_zticks([])
ax.set_xticklabels([])
ax.set_yticklabels([])
ax.set_zticklabels([])
ax.set_xlim(xticks[0], xticks[-1])
ax.set_ylim(yticks[0], yticks[-1])
ax.set_zlim(zticks[0], zticks[-1])

def lims(mplotlims):
    scale = 1.021
    offset = (mplotlims[1] - mplotlims[0])*scale
    return mplotlims[1] - offset, mplotlims[0] + offset
xlims, ylims, zlims = lims(ax.get_xlim()), lims(ax.get_ylim()), lims(ax.get_zlim())

verts = [
    [xlims[0], ylims[0], zlims[0]],
    [xlims[0], ylims[1], zlims[0]],
    [xlims[1], ylims[1], zlims[0]],
    [xlims[1], ylims[0], zlims[0]],
    [xlims[0], ylims[0], zlims[1]],
    [xlims[0], ylims[1], zlims[1]],
    [xlims[1], ylims[1], zlims[1]],
    [xlims[1], ylims[0], zlims[1]],
    ]
# face
faces = [
    # [0, 1, 2, 3],
    # [0, 1, 5, 4],
    # [2, 3, 7, 6],
    # [0, 3, 7, 4],
    # [1, 2, 6, 5],
    [4, 5, 6, 7],
    ]

# poly3d = [[verts[vert_id] for vert_id in face] for face in faces]

# p = Poly3DCollection(poly3d, fc=[0,0,0,0], ec='grey', lw=1)
# ax.add_collection3d(p)

# p = Poly3DCollection([[verts[0],verts[4]]], fc=[0,0,0,0], ec='grey', lw=1)
# ax.add_collection3d(p)
# p = Poly3DCollection([[verts[1],verts[5]]], fc=[0,0,0,0], ec='grey', lw=1)
# ax.add_collection3d(p)
# p = Poly3DCollection([[verts[2],verts[6]]], fc=[0,0,0,0], ec='grey', lw=1)
# ax.add_collection3d(p)

# ax.xaxis.pane.fill = False
# ax.yaxis.pane.fill = False
# ax.zaxis.pane.fill = False
# ax.xaxis.pane.set_edgecolor('w')
# ax.yaxis.pane.set_edgecolor('w')
# ax.zaxis.pane.set_edgecolor('w')

plt.savefig('fp_normal3d.pdf', transparent=True)

proj_xz = xysurf.max(0)
proj_yz = xysurf.max(1)
ax.plot(xx[0,:], np.ones(yy.shape[0])*ylims[0], proj_xz, color='#E0A419', lw=3)
ax.plot(np.ones(xx.shape[0])*xlims[0], yy[:,0], proj_yz, color='#88AD80', lw=3)

stride=5
x_sparse = xx[0,::stride]
y_sparse = yy[::stride,0]
bar_width = (x_sparse[1]-x_sparse[0])/2
ax.bar3d(x_sparse-bar_width/2, np.ones_like(x_sparse)*ylims[0],
    np.zeros_like(x_sparse), np.ones_like(x_sparse)*bar_width, np.zeros_like(x_sparse)*bar_width,
    proj_xz[::stride], color='#E0A419', alpha=.5, shade=False,
    )
ax.bar3d(np.ones_like(y_sparse)*ylims[0], y_sparse-bar_width/2,
    np.zeros_like(y_sparse), np.zeros_like(y_sparse)*bar_width, np.ones_like(y_sparse)*bar_width,
    proj_yz[::stride], color='#88AD80', alpha=.5, shade=False,
    )

plt.savefig('fp_normal3d_proj.pdf', transparent=True)

# %%
#!================================================================================
mean = np.zeros(2)
cov = np.array([[2.0,0],[0,0.5]])
xx, yy = np.meshgrid(np.linspace(-4,4,101), np.linspace(-4,4,101))
xysurf = mn.pdf(np.dstack((xx,yy)), mean, cov)
fig,ax = plt.subplots(1,1,figsize=(6,6))
mesh = ax.pcolormesh(xx, yy, xysurf, cmap='YlGnBu_r', lw=0, rasterized=True)
ax.set_xticklabels([])
ax.set_yticklabels([])
ax.axis('scaled')
plt.savefig('fp_normal2d.pdf', transparent=True)
# %%
#!================================================================================
fig = plt.figure(figsize=(6,6))
ax = fig.add_subplot(projection='3d')

# Create the mesh in polar coordinates and compute corresponding Z.
r = np.linspace(0, 1.25, 100)
p = np.linspace(0, 2*np.pi, 50)
R, P = np.meshgrid(r, p)
# Z = ((R**2 - 1)**2)
Z = 0.5*(np.cos(R*2*np.pi)+1)*np.exp(-R**2)

# Express the mesh in the cartesian system.
X, Y = R*np.cos(P), R*np.sin(P)

# Plot the surface.
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=plt.cm.YlGnBu_r)

ax.set_box_aspect((1,1,0.5))
ax.view_init(20, 40)
# Tweak the limits and add latex math labels.
ax.set_zlim(0, 1)
ax.set_zticks([0,0.5,1])
ax.set_xticklabels([])
ax.set_yticklabels([])
ax.set_zticklabels([])
# ax.set_xlabel(r'$\phi_\mathrm{real}$')
# ax.set_ylabel(r'$\phi_\mathrm{im}$')
# ax.set_zlabel(r'$V(\phi)$')
plt.savefig('fp_polar3d.pdf', transparent=True)

#%%


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

from sklearn import datasets
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.model_selection import GridSearchCV

# Define a pipeline to search for the best combination of PCA truncation
# and classifier regularization.
pca = PCA()
# set the tolerance to a large value to make the example faster
logistic = LogisticRegression(max_iter=10000, tol=0.1)
pipe = Pipeline(steps=[('pca', pca), ('logistic', logistic)])

X_digits, y_digits = datasets.load_digits(return_X_y=True)

# Parameters of pipelines can be set using ‘__’ separated parameter names:
param_grid = {
    'pca__n_components': [5, 15, 30, 45, 64],
    'logistic__C': np.logspace(-4, 4, 4),
}
search = GridSearchCV(pipe, param_grid, n_jobs=-1)
search.fit(X_digits, y_digits)
print("Best parameter (CV score=%0.3f):" % search.best_score_)
print(search.best_params_)

# Plot the PCA spectrum
pca.fit(X_digits)

fig, (ax0, ax1) = plt.subplots(nrows=2, sharex=True, figsize=(6, 6))
ax0.plot(np.arange(1, pca.n_components_ + 1),
         pca.explained_variance_ratio_, '+', linewidth=2)
ax0.set_ylabel('PCA explained variance ratio')

ax0.axvline(search.best_estimator_.named_steps['pca'].n_components,
            linestyle=':', label='n_components chosen')
ax0.legend(prop=dict(size=12))

# For each number of components, find the best classifier results
results = pd.DataFrame(search.cv_results_)
components_col = 'param_pca__n_components'
best_clfs = results.groupby(components_col).apply(
    lambda g: g.nlargest(1, 'mean_test_score'))

best_clfs.plot(x=components_col, y='mean_test_score', yerr='std_test_score',
               legend=False, ax=ax1)
ax1.set_ylabel('Classification accuracy (val)')
ax1.set_xlabel('n_components')

plt.xlim(-1, 70)

plt.tight_layout()
plt.show()


import numpy as np
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer

# Transforming documents into feature vectors

# By calling the fit_transform method on CountVectorizer, we just constructed the vocabulary of the bag-of-words model and transformed the following three sentences into sparse feature vectors:
# 1. The sun is shining
# 2. The weather is sweet
# 3. The sun is shining, the weather is sweet, and one and one is two

count = CountVectorizer()
docs = np.array([
        'The sun is shining',
        'The weather is sweet',
        'The sun is shining, the weather is sweet, and one and one is two'])
bag = count.fit_transform(docs)

# Now let us print the contents of the vocabulary to get a better understanding of the underlying concepts:
print(count.vocabulary_)

# As we can see from executing the preceding command, the vocabulary is stored in a Python dictionary, which maps the unique words that are mapped to integer indices. Next let us print the feature vectors that we just created:
# Each index position in the feature vectors shown here corresponds to the integer values that are stored as dictionary items in the CountVectorizer vocabulary. For example, the  rst feature at index position 0 resembles the count of the word and, which only occurs in the last document, and the word is at index position 1 (the 2nd feature in the document vectors) occurs in all three sentences. Those values in the feature vectors are also called the raw term frequencies: *tf (t,d)*—the number of times a term t occurs in a document *d*.
print(bag.toarray())

# Assessing word relevancy via term frequency-inverse document frequency

np.set_printoptions(precision=2)

tfidf = TfidfTransformer(use_idf=True,
                         norm='l2',
                         smooth_idf=True)
print(tfidf.fit_transform(count.fit_transform(docs))
      .toarray())

Chapter 08/Introducing the bag-of-words model/program1.py


### Kmeans Algorithm for IRIS dataset

#This is easily extandable to any problem/dataset

### author: Dr. Marko Mitic
### year: 2015
### contact: miticm@gmail.com

import numpy as np

class KMeans:

    def __init__(self, dataraw):

        #make sure that the iris dataset is located in the current directory
        self.y = dataraw[:,-1] # outputs - cluster types
        self.x = dataraw[:,0:-1] # inputs - cluster data

    def initializecluster(self, x, y):
        #r1 = np.random.randint(0,49) # first class
        #C1 = x[r1, :]
        #r2 = np.random.randint(50,99) # second class
        #r3 = np.random.randint(100,149) # third class
        #C2 = x[r2, :]
        #C3 = x[r3, :]

        C1 = x[np.random.randint(0,len(y)), :]
        C2 = x[np.random.randint(0,len(y)), :]
        C3 = x[np.random.randint(0,len(y)), :]

        return C1, C2, C3

    def assignmentstep(self, x, C1, C2, C3):
        C = np.zeros(len(x))

        for i in range(0, len(x)):
            dist1 = np.linalg.norm(x[i]-C1)
            dist2 = np.linalg.norm(x[i]-C2)
            dist3 = np.linalg.norm(x[i]-C3)

            if (dist1 < dist2) & (dist1 < dist3):
                C[i] = 1
            elif (dist2 < dist1) & (dist2 < dist3):
                C[i] = 2
            elif (dist3 < dist1) & (dist3 < dist2):
                C[i] = 3

        return C

    def movecentroidstep(self, x, C):

        C1 = np.mean(x[C==1], axis=0)
        C2 = np.mean(x[C==2], axis=0)
        C3 = np.mean(x[C==3], axis=0)

        return C1, C2, C3

    def calculatecost(self, x, C, C1, C2, C3):

        if (len(x[C==1]) != 0):
            J1 = (1./len(x[C==1]))*np.power(np.linalg.norm(x[C==1]-C1), 2)
        else:
            J1=0

        if (len(x[C==2]) != 0):
            J2 = (1./len(x[C==2]))*np.power(np.linalg.norm(x[C==2]-C2), 2)
        else:
            J2=0

        if (len(x[C==3]) != 0):
            J3 = (1./len(x[C==3]))*np.power(np.linalg.norm(x[C==3]-C3), 2)
        else:
            J3=0

        J = J1+J2+J3

        return J

############################################################################
def runKM():

    dataraw = np.loadtxt("iris.txt", comments="#", delimiter=",", unpack=False)

    KM = KMeans(dataraw)
    x = KM.x
    y = KM.y

    [C1, C2, C3] = KM.initializecluster(x, y)
    Cinit = KM.assignmentstep(x, C1, C2, C3)

    Maxit =1000

    J = np.zeros((Maxit, np.shape(x)[1]))

    for  i in range (0, Maxit):

        C = KM.assignmentstep(x, C1, C2, C3)
        [C1, C2, C3] = KM.movecentroidstep(x, C)
        J[i, :] = KM.calculatecost(x, C, C1, C2, C3) # check cost J

    accuracy=(np.mean(C==y))*100
    return accuracy, C

##########################################################################

if __name__ == '__main__':
    acc = 0
    Center = np.zeros((150))

    for i in range (0, 10): # np.random.seed(145) gives 88.67% accuracy
        [accuracy, C] = runKM()
        if acc < accuracy:
            acc = accuracy
            Center = C

    print acc
    print Center


import bsplines

def compute_num_basis_funs(p, knots):
    # compute number of basis functions from the length
    # of the knot vector using relation Nk = n + p + 1.
    num_basis_funs = len(knots)-p-1
    return num_basis_funs

def b(j, p, x, knots, weights):
    """
    Evaluate rational B-spline basis function no. j,
    of degree p with knot vector knots, at the point x.
    """
    num_basis_funs = compute_num_basis_funs(p, knots)

    assert(len(weights) == num_basis_funs)
    den = 0.0
    for i in range(num_basis_funs):
        den += bsplines.B(i, p, x, knots)*weights[i]
    num = bsplines.B(j, p, x, knots)*weights[j]
    return bsplines.special_div(num, den)

def b_derivative(j, p, x, knots, weights):
    """
    Derivative of rational B-spline basis functions.
    """
    num_basis_funs = compute_num_basis_funs(p, knots)
    num_basis_funs = len(weights)
    assert(len(weights) == num_basis_funs)

    weighted_sum = 0.0
    for i in range(num_basis_funs):
        weighted_sum += bsplines.B(i, p, x, knots)*weights[i]

    left_num = weighted_sum*bsplines.B_derivative(j, p, x, knots)*weights[j]

    right_num = 0.0
    for i in range(num_basis_funs):
        right_num += bsplines.B_derivative(i, p, x, knots)*weights[i]
    right_num *= bsplines.B(j, p, x, knots)*weights[j]

    den = weighted_sum*weighted_sum
    return bsplines.special_div(left_num-right_num, den)

def render_spline(p, knots, control_points, weights, ts):
    """
    Compute points on a spline function using the straightforward
    implementation of the recurrence relation for the NURBS basis
    function.
    """
    assert len(control_points) == len(weights)
    ys = []
    for t in ts:
        y = 0.0
        for j in range(0, len(control_points)):
            y += b(j, p, t, knots, weights)*control_points[j]
        ys.append(y)
    return ys

def render_spline_derivative(p, knots, control_points, weights, ts):
    """
    Compute derivative point on a spline function using the straightforward
    implementation of the recurrence relation for the NURBS basis
    function.
    """
    assert len(control_points) == len(weights)
    ys = []
    for t in ts:
        y = 0.0
        for j in range(0, len(control_points)):
            y += b_derivative(j, p, t, knots, weights)*control_points[j]
        ys.append(y)
    return ys

def test1():
    import matplotlib.pyplot as plt
    import numpy as np

    xs = [1, 1, 0, -1, -1, -1, 0, 1]
    ys = [0, 1, 1, 1, 0, -1, -1, -1]
    weights = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
    degree = 3
    knots = [0.0, 0.0, 0.0, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.0, 1.0, 1.01]

    # Render curve
    ts = np.linspace(0.0, 1.0, 100)
    xs_vis = []
    ys_vis = []
    for t in ts:
        x = 0.0
        y = 0.0
        for i in range(len(xs)):
            temp = b(i, degree, t, knots, weights)
            x += temp*xs[i]
            y += temp*ys[i]
        xs_vis.append(x)
        ys_vis.append(y)

    fig = plt.figure()
    ax = fig.add_subplot(111, aspect='equal')

    ax.plot(xs, ys, label='control grid', marker='o')
    ax.plot(xs_vis, ys_vis, label='model')

    # Render normals
    length = 0.5
    ts_normal = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.9, 0.9999]
    for t in ts_normal:
        x = 0.0
        y = 0.0
        dx = 0.0
        dy = 0.0
        for i in range(len(xs)):
            temp = b(i, degree, t, knots, weights)
            x += temp*xs[i]
            y += temp*ys[i]
            temp_derivative = b_derivative(i, degree, t, knots, weights)
            dx += temp_derivative*xs[i]
            dy += temp_derivative*ys[i]
        tangent = np.array([dx,dy,0.0])
        z_axis = np.array([0.0, 0.0, 1.0])
        normal = np.cross(tangent,z_axis)
        normal = normal / np.linalg.norm(normal)

        print normal

        ax.plot([x, x+normal[0]*length], [y, y+normal[1]*length])

    plt.legend()
    plt.show()

def test2():
    """ Verify NURBS unit circle representation. """
    import matplotlib.pyplot as plt
    import numpy as np
    fig = plt.figure()
    fig.add_subplot(111, aspect='equal')

    w = np.sqrt(2)/2
    xs = [0.0,  -1.0, -1.0, -1.0, 0.0, 1.0, 1.0, 1.0,  0.0]
    ys = [-1.0, -1.0, 0.0,  1.0,  1.0, 1.0, 0.0, -1.0, -1.0]
    ws = [1,    w,    1,    w,    1,   w,   1,   w,    1]
    p = 2
    knots = [0,0,0,0.25,0.25,0.5,0.5,0.75,0.75,1,1,1]

    ts = np.linspace(0.0, 0.99, 100)
    xs_vis = []
    ys_vis = []
    xs_der_vis = []
    ys_der_vis = []
    for t in ts:
        x = 0.0
        y = 0.0
        x_der = 0.0
        y_der = 0.0
        for j in range(len(xs)):
            eval_basis = b(j, p, t, knots, ws)
            eval_basis_der = b_derivative(j, p, t, knots, ws)
            x += eval_basis*xs[j]
            y += eval_basis*ys[j]
            x_der += eval_basis_der*xs[j]
            y_der += eval_basis_der*ys[j]
        xs_vis.append(x)
        ys_vis.append(y)
        xs_der_vis.append(x_der)
        ys_der_vis.append(y_der)

    plt.plot(xs, ys, marker='x')
    plt.plot(xs_vis, ys_vis)

    # draw the curve normals
    z_ax = np.array([0.0, 0.0, 1.0])
    for i in range(len(xs_vis)):
        tangent = np.array([xs_der_vis[i],ys_der_vis[i],0.0])
        normal = np.cross(z_ax, tangent)
        normal = normal / np.linalg.norm(normal)
        l = -1
        plt.plot([xs_vis[i], xs_vis[i]+l*normal[0]], [ys_vis[i], ys_vis[i]+l*normal[1]], c='k')

        # Verify that each normal passes through the origin using distance formula
        # from point x0 to line passing through x1 and x2.
        x1 = np.array([xs_vis[i], ys_vis[i], 0.0])
        x2 = np.array([xs_vis[i]+normal[0], ys_vis[i]+normal[1], 0.0])
        x0 = np.array([0,0,0])
        dist = np.linalg.norm(np.cross(x0-x1, x0-x2)) / np.linalg.norm(x2-x1)
        assert dist < 1e-6

    # verify that each vis point is on the unit circle
    for x,y in zip(xs_vis, ys_vis):
        assert abs( x**2 + y**2 - 1) < 1e-6

    plt.show()

if __name__ == '__main__':
    test1()
    test2()


from typing import Optional

import numpy as np

from mockseries.noise.noise import Noise

# todo add minimum and maximum
class GaussianNoise(Noise):
    """Gaussian noise generator.

    This class adds uncorrelated, additive white noise to your signal.

    Args:
        mean: mean of the noise
    std : float
        standard deviation of the noise

    Notes:
        https://rts-gen.readthedocs.io/en/latest/generators.html#gaussian-noise-generator
        https://math.stackexchange.com/questions/1923924/normal-variables-adding-and-multiplying-by-constant/1923932
        Let 𝑋∼(𝑎,𝑏). Let 𝑐>0. Then, 𝑋+𝑐∼(𝑎+𝑐,𝑏) and 𝑐𝑋∼(𝑐𝑎,𝑐2𝑏).
    """

    def __init__(
        self,
        mean: float = 0.0,
        std: float = 1.0,
        random_seed: Optional[int] = None,
    ) -> None:
        super().__init__(random_seed)
        self.mean = mean
        self.std = std

    def _sample_at(self, time_points: np.ndarray) -> np.ndarray:
        """Samples a gaussian noise."""
        if self.random_seed:
            np.random.seed(self.random_seed)
        return np.random.normal(loc=self.mean, scale=self.std, size=len(time_points))


# -*- coding: utf-8 -*-#
'''
# Name:         ClassifierFunction
# Description:  分类激活函数
# Author:       super
# Date:         2020/5/16
'''

import numpy as np

# Logisitc激活函数
class Logistic(object):
    def forward(self, z):
        a = 1.0 / (1.0 + np.exp(-z))
        return a

# Tanh激活函数
class Tanh(object):
    def forward(self, z):
        a = 2.0 / (1.0 + np.exp(-2*z)) - 1.0
        return a


import unittest
from lagrangianpoly import LagrangianBasis, LagrangianPoly, Derivative

class TestLagrangianPoly(unittest.TestCase):

    def test_LagrangianBasis_5stencil(self):
        import sympy as sp

        x = sp.symbols('x')
        acctual = LagrangianBasis(x, degreeOfPolynomial=5, pointAt=0)

        x0 = sp.symbols('x0')
        x1 = sp.symbols('x1')
        x2 = sp.symbols('x2')
        x3 = sp.symbols('x3')
        x4 = sp.symbols('x4')
        x5 = sp.symbols('x5')
        expected = (x - x1)*(x - x2)*(x - x3)*(x - x4)*(x - x5) \
            / ((x0 - x1)*(x0 - x2)*(x0 - x3)*(x0 - x4)*(x0 - x5))

        self.assertEqual(expected, acctual)

    def test_LagrangianPoly_3stencil(self):
        import sympy as sp

        x = sp.symbols('x')
        dx = sp.symbols('dx')

        x_set = [-dx, 0, dx]
        f_set = sp.symbols('f0:{:d}'.format(len(x_set)))
        acctual = LagrangianPoly(x, x_set, f_set)

        f0 = sp.symbols('f0')
        f1 = sp.symbols('f1')
        f2 = sp.symbols('f2')

        expected = f0*x*(-dx + x)/(2*dx**2) \
            - f1*(-dx + x) * (dx + x)/dx**2 \
            + f2*x*(dx + x)/(2*dx**2)

        self.assertEqual(expected, acctual)

    def test_Derivative_3stencil_regular_central_order1(self):
        import sympy as sp

        x = sp.symbols('x')
        dx = sp.symbols('dx')

        f0 = sp.symbols('f0')
        f1 = sp.symbols('f1')
        f2 = sp.symbols('f2')
        Lagrangian_poly = f0*x*(-dx + x)/(2*dx**2) \
            - f1*(-dx + x) * (dx + x)/dx**2 \
            + f2*x*(dx + x)/(2*dx**2)
        acctual = Derivative(Lagrangian_poly, x, orderOfDifference=1)

        f0 = sp.symbols('f0')
        f1 = sp.symbols('f1')
        f2 = sp.symbols('f2')

        expected = (-f0 + f2)/(2*dx)

        self.assertEqual(expected, acctual)

    def test_Derivative_3stencil_regular_rightSidede_order1(self):
        import sympy as sp

        x = sp.symbols('x')
        dx = sp.symbols('dx')

        f0 = sp.symbols('f0')
        f1 = sp.symbols('f1')
        f2 = sp.symbols('f2')
        Lagrangian_poly = f0*(-2*dx + x)*(-dx + x)/(2*dx**2) \
            - f1*x*(-2*dx + x)/dx**2 \
            + f2*x*(-dx + x)/(2*dx**2)
        acctual = Derivative(Lagrangian_poly, x, orderOfDifference=1)

        f0 = sp.symbols('f0')
        f1 = sp.symbols('f1')
        f2 = sp.symbols('f2')

        expected = (-3*f0 + 4*f1 - f2)/(2*dx)

        self.assertEqual(expected, acctual)

    def test_Derivative_3stencil_staggered_central_order1(self):
        import sympy as sp

        x = sp.symbols('x')
        dx = sp.symbols('dx')

        f0 = sp.symbols('f0')
        f1 = sp.symbols('f1')
        f2 = sp.symbols('f2')
        Lagrangian_poly = 2*f0*x*(-dx/2 + x)/dx**2 \
            - 4*f1*(-dx/2 + x)*(dx/2 + x)/dx**2 \
            + 2*f2*x*(dx/2 + x)/dx**2
        acctual = Derivative(Lagrangian_poly, x, orderOfDifference=1)

        f0 = sp.symbols('f0')
        f2 = sp.symbols('f2')

        expected = (-f0 + f2)/dx

        self.assertEqual(expected, acctual)

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