import numpy as np
from numba import njit, int64, float64, prange

@njit(float64[:,:](int64, int64, float64, int64, float64[:]))
def dbfuns(i, n, u, p, U):
    """Evaluates derivatives up to :math:`n` th order of all non-zero
    bspline basis functions :math:`\\frac{\partial^n}{\partial u^n} B_{j,p}(u)`
    at the coordinate :math:`u`, :math:`j=i-p\ldots i`,
    :math:`(n+1) \\times (p+1)` values.

    Parameters:
        i (int) : knot span in which :math:`u` lies
        n (in) : highest derivative order
        u (float) : evaluation point
        p (int)  : basis function degree
        U (np.array(float)) : knot vector

    Returns:
        np.array(float) : scalar values of
        :math:`\\frac{\partial^k}{\partial u^k} B_{j,p}(u)`,
        where dB[k,j] = :math:`\\frac{\partial^k}{\partial u^k} B_{j,p}(u)`.
        :math:`k=0\ldots n`
    """
    m = U.size - 1

    ndu = np.zeros((p+1, p+1))
    a = np.zeros((2,p+1))
    ders = np.zeros((n+1,p+1))
    left = np.zeros(p+1)
    right = np.zeros(p+1)

    ndu[0][0] = 1.
    for j in range(1, p+1):
        left[j] = u - U[i+1-j]
        right[j] = U[i+j] - u
        saved = 0.

        for r in range(0, j):
            ndu[j][r] = right[r+1] + left[j-r]
            temp = ndu[r][j-1] / ndu[j][r]
            ndu[r][j] = saved + right[r+1] * temp
            saved  = left[j-r] * temp

        ndu[j][j] = saved;

    for j in range(0, p+1):
        ders[0][j] = ndu[j][p]

    for r in range(0, p+1):
        s1 = 0
        s2 = 1
        a[0][0] = 1
        for k in range(1, n+1):
            d = 0;
            rk = r - k;
            pk = p - k;
            if r >= k:
                a[s2][0] = a[s1][0] / ndu[pk+1][rk]
                #d += a[s2][0] * ndu[rk][pk] # diff in C# code
                d = a[s2][0] * ndu[rk][pk]

            if rk >= -1:
                j1 = 1
            else:
                j1 = -rk

            if (r-1) <= pk:
                j2 = k - 1
            else:
                j2 = p - r

            for j in range(j1, j2+1):
                a[s2][j] = (a[s1][j] - a[s1][j-1]) / ndu[pk+1][rk+j]
                d += a[s2][j] * ndu[rk+j][pk]

            if r <= pk:
                a[s2][k] = -a[s1][k-1] / ndu[pk+1][r]
                d += a[s2][k] * ndu[r][pk];

            ders[k][r] = d;
            j = s1;
            s1 = s2;
            s2 = j;

    r = float(p);
    for k in range(1, n+1):
        for j in range(0, p+1):
            ders[k][j] *= r
        r *= (p - k)

    return ders

if __name__ == '__main__':
    from tensiga.iga.fspan import fspan
    from tensiga.iga.dbfun import *

    n = 3
    u = 5./2
    p = 2
    U = np.array([0,0,0,1,2,3,4,4,5,5,5], dtype=np.float64)
    i = fspan(u, p, U)

    print('Single call:')
    print(dbfuns(i, n, u, p, U))

    print('  ')
    print('One by one computation:')
    dB22 = dbfun(i-p+0, n, u, p, U)
    dB32 = dbfun(i-p+1, n, u, p, U)
    dB42 = dbfun(i-p+2, n, u, p, U)
    print(np.stack([dB22, dB32, dB42], axis=-1))


import sys
import sympy

def func_1_expr():
    """
    x*sin(x) - 1 = 0
    """
    x = sympy.symbols('x')
    return x*sympy.sin(x)-1.0

def func_2_expr():
    """
    x^2 - 5 = 0
    """
    x = sympy.symbols('x')
    return x**2.0 - 5.0

def func_3_expr():
    """
    x^3 -3x + 2 = 0
    """
    x = sympy.symbols('x')
    return x**3.0 - 3.0*x +2

class _func():
    """
    计算一元函数值及导数值
    """
    def __init__(self, expr, eff=15):
        """
        初始化计算表达式
        expr@表达式
        eff@有效数字位数
        """
        self._expr = expr()
        self._eff = eff
        self._x = list(self._expr.free_symbols)[0]
        self._diff_expr = sympy.diff(self._expr, self._x)

    def value(self, x):
        """
        计算 func 值
        """
        expr = self._expr
        return expr.subs('x', x).evalf(self._eff)

    def diff_value(self, x):
        """
        计算导数值
        """
        expr = self._diff_expr
        return expr.subs('x', x).evalf(self._eff)

def TrailValue(expr, a, b, e):
    """
    试值法
    f@函数
    a@区间下限
    b@区间上限
    e@容忍误差限
    """
    f = _func(expr)
    fa_0 = f.value(a)
    fb_0 = f.value(b)
    res = 0
    count = 0
    if abs(fa_0) < e:
        res = a
    elif abs(fb_0) < e:
        res = b
    elif sympy.sign(fa_0) == sympy.sign(fb_0):
        print('f(a) and f(b) 同号')
        sys.exit()
    else:
        while True:
            count = count + 1
            fa = f.value(a)
            fb = f.value(b)
            c = b - ((b-a)/(fb - fa))*fb
            fc = f.value(c)

            # 更新有根区间
            if sympy.sign(fa) == sympy.sign(fc):
                a = c
            else:
                b = c

            # 判断计算结束
            if abs(f.value(c)) < e:
                res = c
                break

    return res, count

def Newton(expr, a, b, e):
    """
    牛顿法与二分法结合
    f@函数
    a@区间下限
    b@区间上限
    e@容忍误差限
    """
    f = _func(expr)
    fa_0 = f.value(a)
    fb_0 = f.value(b)
    res = 0
    count = 0
    if abs(fa_0) < e:
        res = a
    elif abs(fb_0) < e:
        res = b
    elif sympy.sign(fa_0) == sympy.sign(fb_0):
        print('f(a) and f(b) 同号')
        sys.exit()
    else:
        x = a
        while True:
            count = count + 1
            c = x - f.value(x)/f.diff_value(x)

            # Newton与二分法结合，找下一个点
            if (c > a) and (c < b):
                x = c
            else:
                x = a+(b-a)/2

            # 更新有根区间
            if sympy.sign(f.value(a)) == sympy.sign(f.value(x)):
                a = x
            else:
                b = x

            # 判断计算结束
            if abs(f.value(x)) < e:
                res = x
                break

    return res, count

def main():
    """
    main
    """
    res_t, count_t = TrailValue(func_1_expr, 1, 2, 1.0/sympy.Pow(10, 5))
    print('试值法 func 1 根: %.5f, 迭代次数: %d' % (res_t, count_t))

    res_n, count_n = Newton(func_1_expr, 1, 2, 1.0/sympy.Pow(10, 5))
    print('牛顿法 func 1 根: %.5f, 迭代次数: %d' % (res_n, count_n))

    res_t, count_t = TrailValue(func_2_expr, 2, 3, 1.0/sympy.Pow(10, 5))
    print('试值法 func 2 根: %.5f, 迭代次数: %d' % (res_t, count_t))

    res_n, count_n = Newton(func_2_expr, 2, 3, 1.0/sympy.Pow(10, 5))
    print('牛顿法 func 2 根: %.5f, 迭代次数: %d' % (res_n, count_n))

    res_t, count_t = TrailValue(func_3_expr, -2.5, -1.5, 1.0/sympy.Pow(10, 5))
    print('试值法 func 3 根: %.5f, 迭代次数: %d' % (res_t, count_t))

    res_n, count_n = Newton(func_3_expr, -2.5, -1.5, 1.0/sympy.Pow(10, 5))
    print('牛顿法 func 3 根: %.5f, 迭代次数: %d' % (res_n, count_n))

if __name__ == "__main__":
    main()


import numpy as np
from numpy import linalg as lg
from numpy.linalg import solve
from numpy.linalg import eig
from scipy.integrate import quad

# MAT 350 - Linear Algebra
# Homework 1

# Question 1
'''
x^1 + 2x^2 = 8
x^1 - x^2 = 2

[1 2 | 8]
[1 -1 | 2]

x1 = 4
x2 = 2
'''

# Question 2
'''
x^2 + 3x^3 = 3
x^1 + 2x^2 + 2x^3 = -5
5x^1 + 9x^2 + 7x^3 = 2

Matrix:
[0 1 3 | 3]
[1 2 2 | -5]
[5 9 7 | 2]

Interchange rows 1 & 2:
[1 2 2 | -5]
[0 1 3 | 3]
[5 9 7 | 2]

Row operation to change entry in 3rd row, column 1 to a 0:
(subtract 5 * row 1)
[1 2 2 | -5]
[0 1 3 | 3]
[0 -1 -3 | -23]

Add row 2 to row 3 to zero out the left side of row 3:
[1 2 2 | -5]
[0 1 3 | 3]
[0 0 0 | -20]

This problem has no solution because the 3rd row is the inequality:
0 = 20
'''

# Question 3
'''
[1 h 4]
[5 10 16]

Subtract 5 * row 1 from row 2:
[1 h 4]
[0 10 - 5h | -4]

Rewrite as a system of linear equations:
x^1 + hx^2 = 4
(10 - 5h)x^2 = -4

If h = 2, the equation is undefined, so h != 2
'''

# Question 4
# Multiple Choice

# Question 5
# Multiple Choice

# Question 6
# Multiple Choice

# Question 8
'''
Find the general solution of this system:
[1 0 -7 0 -3 | 4]
[0 1 5 -1 0  | 6]
[0 0 0 0 1   | 0]
[0 0 0 0 0   | 0]

First, add 3*r3 to r1, resulting in reduced row echelon form:
[1 0 -7 0 0 | 4]
[0 1 5 -1 0 | 6]
[0 0 0 0 0  | 1]
[0 0 0 0 0  | 0]

# Write the system of equations:
x1 - 7x3  = 4
  x2 + 5x3 -x4 = 6
x5 = 0
0 = 0


import numpy as np

def affine_forward(x, theta, theta0):
  """
  Computes the forward pass for an affine (fully-connected) layer.

  The input x has shape (m, d_1, ..., d_k) and contains a minibatch of m
  examples, where each example x[i] has shape (d_1, ..., d_k). We will
  reshape each input into a vector of dimension d = d_1 * ... * d_k, and
  then transform it to an output vector of dimension h.

  Inputs:
  - x: A numpy array containing input data, of shape (m, d_1, ..., d_k)
  - theta: A numpy array of weights, of shape (d, h)
  - theta0: A numpy array of biases, of shape (h,)

  Returns a tuple of:
  - out: output, of shape (m, h)
  - cache: (x, theta, theta0)
  """
  out = None
  #############################################################################
  # TODO: Implement the affine forward pass. Store the result in out. You     #
  # will need to reshape the input into rows.                                 #
  #############################################################################
  # 2 lines of code expected
  xmd = x.reshape((x.shape[0], theta.shape[0]))
  out = xmd @ theta + theta0
  #############################################################################
  #                             END OF YOUR CODE                              #
  #############################################################################
  cache = (x, theta, theta0)
  return out, cache

def affine_backward(dout, cache):
  """
  Computes the backward pass for an affine layer.

  Inputs:
  - dout: Upstream derivative, of shape (m, h)
  - cache: Tuple of:
    - x: Input data, of shape (m, d_1, ... d_k)
    - theta: Weights, of shape (d,h)
    - theta0: biases, of shape (h,)

  Returns a tuple of:
  - dx: Gradient with respect to x, of shape (m, d1, ..., d_k)
  - dtheta: Gradient with respect to theta, of shape (d, h)
  - dtheta0: Gradient with respect to theta0, of shape (h,)
  """
  x, theta, theta0 = cache
  dx, dtheta, dtheta0 = None, None, None
  #############################################################################
  # TODO: Implement the affine backward pass.                                 #
  #############################################################################
  # Hint: do not forget to reshape x into (m,d) form
  # 4-5 lines of code expected
  xmd = x.reshape((x.shape[0], theta.shape[0]))
  dx = (dout @ theta.T).reshape(x.shape)
  dtheta = xmd.T @ dout
  dtheta0 = np.sum(dout, axis=0)
  #############################################################################
  #                             END OF YOUR CODE                              #
  #############################################################################
  return dx, dtheta, dtheta0

def relu_forward(x):
  """
  Computes the forward pass for a layer of rectified linear units (ReLUs).

  Input:
  - x: Inputs, of any shape

  Returns a tuple of:
  - out: Output, of the same shape as x
  - cache: x
  """
  out = None
  #############################################################################
  # TODO: Implement the ReLU forward pass.                                    #
  #############################################################################
  # 1 line of code expected
  out = np.where(x > 0, x, 0)
  #############################################################################
  #                             END OF YOUR CODE                              #
  #############################################################################
  cache = x
  return out, cache

def relu_backward(dout, cache):
  """
  Computes the backward pass for a layer of rectified linear units (ReLUs).

  Input:
  - dout: Upstream derivatives, of any shape
  - cache: Input x, of same shape as dout

  Returns:
  - dx: Gradient with respect to x
  """
  dx, x = None, cache
  #############################################################################
  # TODO: Implement the ReLU backward pass.                                   #
  #############################################################################
  # 1 line of code expected. Hint: use np.where
  dx = np.where(x > 0, dout, 0)
  #############################################################################
  #                             END OF YOUR CODE                              #
  #############################################################################
  return dx

def dropout_forward(x, dropout_param):
  """
  Performs the forward pass for (inverted) dropout.

  Inputs:
  - x: Input data, of any shape
  - dropout_param: A dictionary with the following keys:
    - p: Dropout parameter. We drop each neuron output with probability p.
    - mode: 'test' or 'train'. If the mode is train, then perform dropout;
      if the mode is test, then just return the input.
    - seed: Seed for the random number generator. Passing seed makes this
      function deterministic, which is needed for gradient checking but not in
      real networks.

  Outputs:
  - out: Array of the same shape as x.
  - cache: A tuple (dropout_param, mask). In training mode, mask is the dropout
    mask that was used to multiply the input; in test mode, mask is None.
  """
  p, mode = dropout_param['p'], dropout_param['mode']
  if 'seed' in dropout_param:
    np.random.seed(dropout_param['seed'])

  mask = None
  out = None

  if mode == 'train':
    ###########################################################################
    # TODO: Implement the training phase forward pass for inverted dropout.   #
    # Store the dropout mask in the mask variable.                            #
    ###########################################################################
    # 2 lines of code expected
    mask = (np.random.rand(*x.shape) < (1 - p)) / (1 - p)
    out = x * mask
    ###########################################################################
    #                            END OF YOUR CODE                             #
    ###########################################################################
  elif mode == 'test':
    ###########################################################################
    # TODO: Implement the test phase forward pass for inverted dropout.       #
    ###########################################################################
    # 1 line of code expected
    out = x
    ###########################################################################
    #                            END OF YOUR CODE                             #
    ###########################################################################

  cache = (dropout_param, mask)
  out = out.astype(x.dtype, copy=False)

  return out, cache

def dropout_backward(dout, cache):
  """
  Perform the backward pass for (inverted) dropout.

  Inputs:
  - dout: Upstream derivatives, of any shape
  - cache: (dropout_param, mask) from dropout_forward.
  """
  dropout_param, mask = cache
  mode = dropout_param['mode']

  dx = None
  if mode == 'train':
    ###########################################################################
    # TODO: Implement the training phase backward pass for inverted dropout.  #
    ###########################################################################
    # 1 line of code expected
    dx = dout * mask
    ###########################################################################
    #                            END OF YOUR CODE                             #
    ###########################################################################
  elif mode == 'test':
    dx = dout
  return dx

def conv_forward_naive(x, theta, theta0, conv_param):
  """
  A naive implementation of the forward pass for a convolutional layer.

  The input consists of m data points, each with C channels, height H and width
  W. We convolve each input with F different filters, where each filter spans
  all C channels and has height HH and width HH.

  Input:
  - x: Input data of shape (m, C, H, W)
  - theta: Filter weights of shape (F, C, HH, WW)
  - theta0: Biases, of shape (F,)
  - conv_param: A dictionary with the following keys:
    - 'stride': The number of pixels between adjacent receptive fields in the
      horizontal and vertical directions.
    - 'pad': The number of pixels that will be used to zero-pad the input.

  Returns a tuple of:
  - out: Output data, of shape (m, F, H', W') where H' and W' are given by
    H' = 1 + (H + 2 * pad - HH) / stride
    W' = 1 + (W + 2 * pad - WW) / stride
  - cache: (x, theta, theta0, conv_param)
  """
  out = None
  #############################################################################
  # TODO: Implement the convolutional forward pass.                           #
  # Hint: you can use the function np.pad for padding.                        #
  #############################################################################
  m, C, H, W = x.shape
  F, C, HH, WW = theta.shape
  stride, pad = conv_param['stride'], conv_param['pad']
  H1 = int(1 + (H + 2 * pad - HH) / stride)
  W1 = int(1 + (W + 2 * pad - WW) / stride)
  out = np.zeros((m, F, H1, W1))
  xp = np.pad(x, [(0, 0), (0, 0), (pad, pad), (pad, pad)], mode='constant')
  for i in range(m):
    for j in range(F):
      for k in range(H1):
        for l in range(W1):
          conv = xp[i, :, (k * stride):(k * stride + HH), (l * stride):(l * stride + WW)]
          out[i, j, k, l] = np.sum(conv * theta[j]) + theta0[j]
  #############################################################################
  #                             END OF YOUR CODE                              #
  #############################################################################
  cache = (x, theta, theta0, conv_param)
  return out, cache

def conv_backward_naive(dout, cache):
  """
  A naive implementation of the backward pass for a convolutional layer.

  Inputs:
  - dout: Upstream derivatives.
  - cache: A tuple of (x, theta, theta0, conv_param) as in conv_forward_naive

  Returns a tuple of:
  - dx: Gradient with respect to x
  - dtheta: Gradient with respect to theta
  - dtheta0: Gradient with respect to theta0
  """
  dx, dtheta, dtheta0 = None, None, None
  #############################################################################
  # TODO: Implement the convolutional backward pass.                          #
  #############################################################################
  x, theta, theta0, conv_param = cache
  m, C, H, W = x.shape
  F, C, HH, WW = theta.shape
  stride, pad = conv_param['stride'], conv_param['pad']
  H1 = int(1 + (H + 2 * pad - HH) / stride)
  W1 = int(1 + (W + 2 * pad - WW) / stride)
  dx = np.zeros_like(x)
  dtheta = np.zeros_like(theta)
  xp = np.pad(x, [(0, 0), (0, 0), (pad, pad), (pad, pad)], mode='constant')
  dxp = np.pad(dx, [(0, 0), (0, 0), (pad, pad), (pad, pad)], mode='constant')
  for i in range(m):
    for j in range(F):
      for k in range(H1):
        for l in range(W1):
          dxp[i, :, (k * stride):(k * stride + HH), (l * stride):(l * stride + WW)] += dout[i, j, k, l] * theta[j, :, :, :]
          dtheta[j, :, :, :] += dout[i, j, k, l] * xp[i, :, (k * stride):(k * stride + HH),(l * stride):(l * stride + WW)]
  dtheta0 = np.sum(dout, axis=(0, 2, 3))
  dx = dxp[:, :, pad:(pad + H), pad:(pad + W)]
  #############################################################################
  #                             END OF YOUR CODE                              #
  #############################################################################
  return dx, dtheta, dtheta0

def max_pool_forward_naive(x, pool_param):
  """
  A naive implementation of the forward pass for a max pooling layer.

  Inputs:
  - x: Input data, of shape (m, C, H, W)
  - pool_param: dictionary with the following keys:
    - 'pool_height': The height of each pooling region
    - 'pool_width': The width of each pooling region
    - 'stride': The distance between adjacent pooling regions

  Returns a tuple of:
  - out: Output data
  - cache: (x, pool_param)
  """
  out = None
  #############################################################################
  # TODO: Implement the max pooling forward pass                              #
  #############################################################################
  m, C, H, W = x.shape
  pool_height, pool_width, stride = pool_param['pool_height'], pool_param['pool_width'], pool_param['stride']
  H2 = int(1 + (H - pool_height) / stride)
  W2 = int(1 + (W - pool_width) / stride)
  out = np.zeros((m, C, H2, W2))
  for i in range(m):
    for j in range(C):
      for k in range(H2):
        for l in range(W2):
          out[i, j, k, l] = np.max(x[i, j,  (k * stride):(k * stride + pool_height), (l * stride):(l * stride + pool_width)])
  #############################################################################
  #                             END OF YOUR CODE                              #
  #############################################################################
  cache = (x, pool_param)
  return out, cache

def max_pool_backward_naive(dout, cache):
  """
  A naive implementation of the backward pass for a max pooling layer.

  Inputs:
  - dout: Upstream derivatives
  - cache: A tuple of (x, pool_param) as in the forward pass.

  Returns:
  - dx: Gradient with respect to x
  """
  dx = None
  #############################################################################
  # TODO: Implement the max pooling backward pass                             #
  #############################################################################
  x, pool_param = cache
  m, C, H, W = x.shape
  pool_height, pool_width, stride = pool_param['pool_height'], pool_param['pool_width'], pool_param['stride']
  H2 = int(1 + (H - pool_height) / stride)
  W2 = int(1 + (W - pool_width) / stride)
  dx = np.zeros_like(x)
  for i in range(m):
    for j in range(C):
      for k in range(H2):
        for l in range(W2):
          pool = x[i, j,  (k * stride):(k * stride + pool_height), (l * stride):(l * stride + pool_width)]
          maxPool = (np.max(pool) == pool)
          dx[i, j, (k * stride):(k * stride + pool_height), (l * stride):(l * stride + pool_width)] += dout[i, j, k, l] * maxPool
  #############################################################################
  #                             END OF YOUR CODE                              #
  #############################################################################
  return dx

def svm_loss(x, y):
  """
  Computes the loss and gradient using for multiclass SVM classification.

  Inputs:
  - x: Input data, of shape (m, C) where x[i, j] is the score for the jth class
    for the ith input.
  - y: Vector of labels, of shape (m,) where y[i] is the label for x[i] and
    0 <= y[i] < C

  Returns a tuple of:
  - loss: Scalar giving the loss
  - dx: Gradient of the loss with respect to x
  """
  m = x.shape[0]
  correct_class_scores = x[np.arange(m), y]
  margins = np.maximum(0, x - correct_class_scores[:, np.newaxis] + 1.0)
  margins[np.arange(m), y] = 0
  loss = np.sum(margins) / m
  num_pos = np.sum(margins > 0, axis=1)
  dx = np.zeros_like(x)
  dx[margins > 0] = 1
  dx[np.arange(m), y] -= num_pos
  dx /= m
  return loss, dx

def softmax_loss(x, y):
  """
  Computes the loss and gradient for softmax classification.

  Inputs:
  - x: Input data, of shape (m, C) where x[i, j] is the score for the jth class
    for the ith input.
  - y: Vector of labels, of shape (m,) where y[i] is the label for x[i] and
    0 <= y[i] < C

  Returns a tuple of:
  - loss: Scalar giving the loss
  - dx: Gradient of the loss with respect to x
  """
  probs = np.exp(x - np.max(x, axis=1, keepdims=True))
  probs /= np.sum(probs, axis=1, keepdims=True)
  m = x.shape[0]
  loss = -np.sum(np.log(probs[np.arange(m), y])) / m
  dx = probs.copy()
  dx[np.arange(m), y] -= 1
  dx /= m
  return loss, dx


import numpy as np
import math

W = np.array([[ -8, 8, -6, 14, 14, -9, -4],
	[ 2, -11, -2, -11, 14, -2, 14],
	[-13, -2, -5, 3, -8, -4, 13],
	[ 2, 13, -14, -15, -14, -15, 13],
	[ 2, -1, 12, 3, -7, -3, -6]])
Z = np.array([
[ -6, -1, -8, 7, -8],
 [ 7, 4, 0, -10, -10],
 [ 7, -13, 2, 2, -11],
 [ 3, 14, 7, 7, -4],
 [ -1, -3, -8, -4, -14],
 [ 9, -14, 9, 12, -7],
 [ -9, -4, -10, -3, 6]])
X = np.array([0, 15, -9, 7, 12, 3, -21])
Y = np.array([2, 14, -13, 5, 12, 4, -19])
# X = np.array([0, 15, -9, 7, 12, 3, -21]).reshape((7,1))
# Y = np.array([2, 14, -13, 5, 12, 4, -19]).reshape((7,1))
def sum__(x, f):
	acc = 0.
	for item in x:
		acc += f(item)
	return acc
def mean(x):
	n = x.shape[0]
	acc = 0.
	for item in x:
		acc += item
	return acc/n

def	variance(x):
	u = mean(x)
	return sum__(x,lambda x: (x - u)**2) / x.shape[0]

def std(x):
	return math.sqrt(variance(x))

def dot(x, y):
	if (x is None or y is None
	or x.shape[0] != y.shape[0]):
		return None
	return sum__(x * y, lambda x:x)

def mat_vec_prod(x, y):
	if (x.shape[1], 1) != y.shape:
		return None
	res = np.zeros((x.shape[0],1))
	f = 0
	for row in x:
		row = row.reshape((row.shape[0],1))
		res[f] = dot(row, y)
		f += 1
	return res

# print(mat_vec_prod(W, X))
# print(W.dot(X))
# print(mean(X**2))

def mat_mat_prod(x, y):
	if (x.shape[0] != y.shape[1]):
		return None
	res = np.zeros((x.shape[0],y.shape[1]))
	print(x.shape," ",y.shape)
	for i in range(x.shape[0]):
		for j in range(y.shape[1]):
			res[i][j] = dot(x[i],y[:,j])
	return res

def mse(y, y_hat):
	if y.shape != y_hat.shape:
		return None
	acc = 0.
	for elem1,elem2 in zip(y,y_hat):
		acc += (elem1 - elem2)**2
	return acc / y.shape[0]

def vec_mse(y, y_hat):
	y = y.reshape((y.shape[0],1))
	y_hat = y_hat.reshape((y_hat.shape[0],1))
	# print(y.shape)
	return float(dot(y_hat - y,y_hat - y) / y_hat.shape[0])

def linear_mse(x, y, theta):
	return mse(dot(theta, x), y)
# print(X.shape)
# print(X)
# print(X.reshape((1,X.shape[0])))
# print(X)

# print(linear_mse(X, Y))


"""SIR model simulations."""
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

from tqdm import tqdm
from typing import Union, Dict, List

class SIR:
    """Vanilla SIR model."""

    def __init__(
            self,
            param: Dict = {}):
        """Only initialize the model parameters."""
        self.beta = param.get('beta', 0.1)
        self.gamma = param.get('gamma', 0.05)
        self.eta = param.get('eta', 0.01)
        self.X_init = None
        self.X = None
        self.num_steps = 0

    def run(
            self,
            X_init: Union[List, np.ndarray],
            num_steps: int = 365):
        """Run the simulation by solving the SIR ODE numerically."""
        self.X_init = X_init
        self.num_steps = num_steps

        # sanity check for non-negative value
        for x in self.X_init:
            if x < 0:
                print('Invalid value, needs a non-negative number.', x)
        self.X_int = [min(0, x) for x in self.X_init]
        # sanity check, for nomalization
        norm = sum(self.X_init)
        self.X_init = [x / norm for x in self.X_init]

        # we want to simulate S, I and R, plus D (death)
        m = 4
        assert(len(X_init) == m)

        # initialize the X array
        self.X = np.zeros(shape=(m, self.num_steps))
        for i in range(m):
            self.X[i][0] = self.X_init[i]

        # solving the ODE
        for t in tqdm(range(1, self.num_steps)):
            S, I, R, D = self.X[0][t - 1], self.X[1][t - 1], \
                self.X[2][t - 1], self.X[3][t - 1]
            dS = -1. * self.beta * S * I / (S + I + R)
            dI = -1. * dS - self.gamma * I
            dR = (1 - self.eta) * self.gamma * I
            dD = self.eta * self.gamma * I

            self.X[0][t] = S + dS  # update S
            self.X[1][t] = I + dI  # update I
            self.X[2][t] = R + dR  # update R
            self.X[3][t] = D + dD  # update D

    def make_plot(self):
        """Visualize the simulation results."""
        if self.X is None:
            tqdm.write('Run the simulation first.')
            return
        sns.set(font_scale=1.2)
        sns.set_style("whitegrid", {'grid.linestyle': '--'})
        # _ = plt.figure(figsize=(12, 9))

        time_steps = list(range(self.num_steps))

        sns.lineplot(x=time_steps, y=100 * self.X[0, :], label='Susceptible')
        sns.lineplot(x=time_steps, y=100 * self.X[1, :], label='Infectious')
        sns.lineplot(x=time_steps, y=100 * self.X[2, :], label='Recovered')
        sns.lineplot(x=time_steps, y=100 * self.X[3, :], label='Death')

        plt.xlabel('Day')
        plt.ylabel('Proportion of population (%)')
        plt.legend()
        plt.show()


from pennylane import numpy as np
from scipy.linalg import sqrtm
import matplotlib.pyplot as plt

def fidelity(rho, sigma):
    """Computes the fidelity between two density matrices.

    Fidelity has a maximum value of 1 when the two input states are
    the same, and a minimum value of 0 when the two states are
    totally orthogonal. When comparing the output of, e.g.,
    a state obtained through a noisy process to the ideal state,
    higher fidelity is better.

    Args:
        rho (array[complex]): A density matrix.
        sigma (array[complex]): A second density matrix.

    Returns:
        float: The fidelity between rho and sigma.
    """
    sqrt_rho = sqrtm(rho)
    inner_thing = np.linalg.multi_dot([sqrt_rho, sigma, sqrt_rho])
    return np.real(np.trace(sqrtm(inner_thing)) ** 2)

def trace_distance(rho, sigma):
    """Computes the trace distance between two density matrices.

    Trace distance has a maximum value of 1 when the two input states
    are totally orthogonal, and a minimum value of 0 when the two
    states are the same. When comparing the output of, e.g., a state
    obtained through a noisy process to the ideal state, lower
    trace distance is better.

    Args:
        rho (array[complex]): A density matrix.
        sigma (array[complex]): A second density matrix.

    Returns:
        float: The trace distance between rho and sigma.
    """
    rms = rho - sigma
    inner_thing = np.dot(rms.conj().T, rms)
    return np.real(0.5 * np.trace(sqrtm(inner_thing)))

def plot_density_matrix_city(rho):
    """A "city plot" of a density matrices real and imaginary components.

    Code taken from:
      - https://matplotlib.org/stable/gallery/mplot3d/3d_bars.html
      - https://stackoverflow.com/questions/43869751/change-bar-color-in-a-3d-bar-plot-in-matplotlib-based-on-value
    Args:
        rho (array[complex]): A density matrix.
    """

    fig = plt.figure(figsize=(15, 5))
    ax1 = fig.add_subplot(111, projection='3d')
    ax2 = fig.add_subplot(122, projection='3d')

    _x = np.arange(len(rho))
    _y = np.arange(len(rho))
    _xx, _yy = np.meshgrid(_x, _y)
    x, y = _xx.ravel(), _yy.ravel()

    real = rho.flatten().real
    imag = rho.flatten().imag

    colors_real = plt.cm.jet(real/float(real.max()))
    colors_imag = plt.cm.jet(imag/float(imag.max()))

    ax1.bar3d(x, y, np.zeros_like(x), 1, 1, real, color=colors_real, shade=False)
    ax2.bar3d(x, y, np.zeros_like(x), 1, 1, imag, color=colors_imag, shade=False)

    plt.show()


import numpy as np
import time

def hms2dec(h,m,s):
  return 15*(h + (m/60) + (s/3600))

def dms2dec(d,m,s):
  if d>=0:
    return (d + (m/60) + (s/3600))
  return (d - (m/60) - (s/3600))

def angular_dist(r1, d1, r2, d2):   # remove radians, radians mein hi ghusenge
  # r1= np.radians(r1)
  # r2= np.radians(r2)
  # d1= np.radians(d1)
  # d2= np.radians(d2)
  a = (np.sin(np.abs(d1 - d2)/2))**2
  b = np.cos(d1)*np.cos(d2)*np.sin(np.abs(r1 - r2)/2)**2
  d = np.degrees(2*np.arcsin(np.sqrt(a + b)))
  return d

def crossmatch(cat1, cat2, max_dist):
  matches = []
  no_matches = []
  start = time.perf_counter()
  cat1 = np.radians(cat1)
  cat2 = np.radians(cat2)
  id_1 = 0
  for i in cat1:
      best = (0,0,max_dist+1)
      id_2 = 0
      for j in cat2:
        dist = angular_dist(i[0], i[1], j[0], j[1])
        if dist<=best[2]:
          best = (id_1,id_2,dist)
        id_2+=1
      if best[2]<=max_dist:
         matches.append(best)
      else:
         no_matches.append(id_1)
      id_1+=1
  return (matches, no_matches, time.perf_counter() - start)


# Question 06, Lab 05
# AB Satyaprakash - 180123062

# imports ----------------------------------------------------------------------------
from math import cos, log, sin, pi
from sympy.abc import t
import numpy as np
import pandas as pd
import sympy as sp
from scipy.integrate import quad

# global dictionaries ----------------------------------------------------------------
phi = {-1: 0, 0: 1}
alpha = {}
beta = {0: 0}

# functions --------------------------------------------------------------------------

def getFuncVal(x):
    # cosx log(sinx)/(1 + sin^2(x))
    return (cos(x)*log(sin(x))/(1+sin(x)**2))

def getInnerProduct(a, b):
    poly = np.poly1d(np.polyint(np.polymul(a, b)))
    return poly(1) - poly(-1)

def getPhi(n):
    # The value of ϕ(n) = (x-α(n-1))ϕ(n-1) - β(n)ϕ(n-2)
    if n in phi:
        return phi[n]

    a = getAlpha(n-1)
    b = getBeta(n-1)
    phi_n_1 = getPhi(n-1)
    phi_n_2 = getPhi(n-2)

    secondTerm = np.polymul([b], phi_n_2)
    firstTerm = np.polymul(np.polysub([1, 0], a), phi_n_1)
    phi[n] = np.polysub(firstTerm, secondTerm)
    return phi[n]

def getAlpha(n):
    # The value of α(n) = <xϕ(n), ϕ(n)>/<ϕ(n) , ϕ(n)>
    if n in alpha:
        return alpha[n]

    phi_n = getPhi(n)
    xphi_n = np.polymul([1, 0], phi_n)
    num = getInnerProduct(xphi_n, phi_n)
    denom = getInnerProduct(phi_n, phi_n)
    alpha[n] = num/denom

    return alpha[n]

def getBeta(n):
    # The value of β(n) = <ϕ(n), ϕ(n)>/<ϕ(n-1) , ϕ(n-1)>
    if n in beta:
        return beta[n]

    phi_n = getPhi(n)
    phi_n_1 = getPhi(n-1)
    num = getInnerProduct(phi_n, phi_n)
    denom = getInnerProduct(phi_n_1, phi_n_1)
    beta[n] = num/denom

    return beta[n]

def getGaussian(f, roots, W, limits):
    a, b = limits
    I = 0
    for x, w in zip(roots, W):
        I += w*f(x, a, b)
    return I

def f(x, a, b):
    c1, c2 = (b-a)/2, (b+a)/2
    x = c1*x + c2

    return c1*getFuncVal(x)

# program body
table = []
for k in range(1, 6):
    n = k+1
    poly = np.poly1d(getPhi(n))

    roots = poly.r
    roots.sort()

    temp = [[1] + [0]*(i) for i in range(n)]
    output = []
    for P in temp:
        P = (np.polyint(P))
        P = np.poly1d(P)
        I = P(1) - P(-1)
        output.append(I)

    X = []
    for i in range(n):
        temp = [x**i for x in roots]
        X.append(temp)

    X_ = np.linalg.inv(X)
    W = np.dot(X_, output)

    limits = (0, pi/2)
    result = getGaussian(f, roots, W, limits)
    table.append([k, round(result, 2)])

df = pd.DataFrame(
    table, columns=['N', 'Evaluated value using N+1 point Gaussian Quadrature'])
print(df)

ans, _ = quad(getFuncVal, 0, pi/2)
print("The actual value of the integral is", ans)

Semester 6/MA 322 (Scientific Computing Theory)/Labs/Lab 5/Code/q6.py

import numpy,from scipy,import sympy,from sympy


from mpl_toolkits import mplot3d
import numpy as np
import matplotlib.pyplot as plt

def simple_3d():
    fig = plt.figure()
    ax = plt.axes(projection='3d')
    zline = np.linspace(0, 15, 1000)
    xline = np.sin(zline)
    yline = np.cos(zline)
    ax.plot3D(xline, yline, zline, 'gray')

    # Data for three-dimensional scattered points
    zdata = 15 * np.random.random(100)
    xdata = np.sin(zdata) + 0.1 * np.random.randn(100)
    ydata = np.cos(zdata) + 0.1 * np.random.randn(100)
    ax.scatter3D(xdata, ydata, zdata, c=zdata, cmap='Greens');

    plt.show()

def f(x, y):
    return np.sin(np.sqrt(x ** 2 + y ** 2))

def color_3d():
    x = np.linspace(-6, 6, 30)
    y = np.linspace(-6, 6, 30)
    X, Y = np.meshgrid(x, y)
    Z = f(X, Y)
    fig = plt.figure()

    ax = plt.axes(projection='3d')
    ax.contour3D(X, Y, Z, 50, cmap='binary')
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_zlabel('z')
    ax.view_init(60, 35)
    plt.show()

def wireframes():
    x = np.linspace(-6, 6, 30)
    y = np.linspace(-6, 6, 30)
    X, Y = np.meshgrid(x, y)
    Z = f(X, Y)
    fig = plt.figure()
    ax = plt.axes(projection='3d')
    ax.plot_wireframe(X, Y, Z, color='black')
    ax.set_title('wireframe');

    ax = plt.axes(projection='3d')
    ax.plot_surface(X, Y, Z, rstride=1, cstride=1,
                    cmap='viridis', edgecolor='none')
    ax.set_title('surface');
    r = np.linspace(0, 6, 20)
    theta = np.linspace(-0.9 * np.pi, 0.8 * np.pi, 40)
    r, theta = np.meshgrid(r, theta)

    X = r * np.sin(theta)
    Y = r * np.cos(theta)
    Z = f(X, Y)

    ax = plt.axes(projection='3d')
    ax.plot_surface(X, Y, Z, rstride=1, cstride=1,
                    cmap='viridis', edgecolor='none')
    plt.show()

def surface_triangulations():
    theta = 2 * np.pi * np.random.random(1000)
    r = 6 * np.random.random(1000)
    x = np.ravel(r * np.sin(theta))
    y = np.ravel(r * np.cos(theta))
    z = f(x, y)
    ax = plt.axes(projection='3d')
    ax.scatter(x, y, z, c=z, cmap='viridis', linewidth=0.5)
    ax = plt.axes(projection='3d')
    ax.plot_trisurf(x, y, z, cmap='viridis', edgecolor='none')
    plt.show()

def visualize_mobius_strip():
    theta = np.linspace(0, 2 * np.pi, 30)
    w = np.linspace(-0.25, 0.25, 8)
    w, theta = np.meshgrid(w, theta)
    phi = 0.5 * theta
    # radius in x-y plane
    r = 1 + w * np.cos(phi)

    x = np.ravel(r * np.cos(theta))
    y = np.ravel(r * np.sin(theta))
    z = np.ravel(w * np.sin(phi))

    # triangulate in the underlying parametrization
    from matplotlib.tri import Triangulation
    tri = Triangulation(np.ravel(w), np.ravel(theta))

    ax = plt.axes(projection='3d')
    ax.plot_trisurf(x, y, z, triangles=tri.triangles, cmap='viridis', linewidths=0.2);

    ax.set_xlim(-1, 1); ax.set_ylim(-1, 1); ax.set_zlim(-1, 1)
    plt.show()

if __name__ == '__main__':
    print('Numpy Version:', np.__version__)
    # simple_3d()
    # color_3d()
    # wireframes()
    # surface_triangulations()
    visualize_mobius_strip()


import numpy as np

def poly_to_polycr(line_fit, ploty, ym_per_pix, xm_per_pix):
    ### Calc both polynomials using ploty, left_fit and right_fit ###
    if line_fit is None:
        return None

    line_fitx = line_fit[0] * ploty ** 2 + line_fit[1] * ploty + line_fit[2]
    line_fit_cr = np.polyfit(ploty * ym_per_pix, line_fitx * xm_per_pix, 2)
    return line_fit_cr

def measure_real_world_curvature_for_line(line_fit, ploty, ym_per_pix=30 / 720, xm_per_pix=3.7 / 700):
    '''
    Calculates the curvature of polynomial functions in meters.
    '''
    # Define y-value where we want radius of curvature
    # We'll choose the maximum y-value, corresponding to the bottom of the image
    y_eval = np.max(ploty)

    line_fit_cr = poly_to_polycr(line_fit, ploty, ym_per_pix, xm_per_pix)
    if line_fit_cr is None:
        return None
    curvature = (((1 + (2 * line_fit_cr[0] * y_eval * ym_per_pix + line_fit_cr[1]) ** 2) ** 1.5)
                 / np.absolute(2 * line_fit_cr[0]))
    return curvature

def avg_curvature(left_curvature, right_curvature):
    if left_curvature is not None and right_curvature is not None:
        return np.mean([left_curvature, right_curvature])
    elif left_curvature is not None and right_curvature is None:
        return left_curvature
    elif left_curvature is None and right_curvature is not None:
        return right_curvature
    else:
        # print('no curvature found')
        return None

def measure_real_world_curvature_for_road(left_fit, right_fit, ploty, ym_per_pix=30 / 720, xm_per_pix=3.7 / 700):
    '''
    Calculates the curvature of polynomial functions in meters.
    '''
    # Calculation of R_curve (radius of curvature)
    left_curvature, right_curvature = None, None
    if left_fit is not None:
        left_curvature = measure_real_world_curvature_for_line(left_fit, ploty, ym_per_pix, xm_per_pix)
    if right_fit is not None:
        right_curvature = measure_real_world_curvature_for_line(right_fit, ploty, ym_per_pix, xm_per_pix)

    return avg_curvature(left_curvature, right_curvature)

def measure_mid_position(left_fit, right_fit, ploty, std_mid=660, imgsize_x=1200, xm_per_pix=3.7 / 700):
    y_eval = np.max(ploty)
    # find mid point
    leftx = left_fit[0] * y_eval ** 2 + left_fit[1] * y_eval + left_fit[2] if left_fit is not None else 0
    rightx = right_fit[0] * y_eval ** 2 + right_fit[1] * y_eval + right_fit[2] if right_fit is not None else imgsize_x

    current_mid_pix = (leftx + rightx) / 2
    to_mid_of_line = (std_mid - current_mid_pix) * xm_per_pix
    return to_mid_of_line


import math
from functools import partial

import numpy as np
import scipy

import jax
import jax.numpy as jnp
from jax import random
from jax import jit

from .norm import normalize_l2_cw
from .util import promote_arg_dtypes
from .array import hermitian

def gaussian_mtx(key, N, D, normalize_atoms=True):
    """A dictionary/sensing matrix where entries are drawn independently from normal distribution.

    Args:
        key: a PRNG key used as the random key.
        N (int): Number of rows of the sensing matrix
        D (int): Number of columns of the sensing matrix
        normalize_atoms (bool): Whether the columns of sensing matrix are normalized
          (default True)

    Returns:
        (jax.numpy.ndarray): A Gaussian sensing matrix of shape (N, D)

    Example:

        >>> from jax import random
        >>> import cr.nimble as cnb
        >>> m, n = 8, 16
        >>> Phi = cnb.gaussian_mtx(random.PRNGKey(0), m, n)
        >>> print(Phi.shape)
        (8, 16)
        >>> print(cnb.norms_l2_cw(Phi))
        [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
    """
    shape = (N, D)
    dict = random.normal(key, shape)
    if normalize_atoms:
        dict = normalize_l2_cw(dict)
    else:
        sigma = math.sqrt(N)
        dict = dict / sigma
    return dict

def _pascal_lower(n):
    A = jnp.empty((n, n), dtype=jnp.int32)
    A = A.at[0, :].set(0)
    A = A.at[:, 0].set(1)
    for i in range(1, n):
        for j in range(1, i+1):
            A = A.at[i, j].set(A[i-1, j] + A[i-1, j-1])
    return A

def _pascal_sym(n):
    A = jnp.empty((n, n), dtype=jnp.int32)
    A = A.at[0, :].set(1)
    A = A.at[:, 0].set(1)
    for i in range(1, n):
        for j in range(1, n):
            A = A.at[i, j].set(A[i-1, j] + A[i, j-1])
    return A

def pascal(n, symmetric=False):
    """Returns a pascal matrix of size n \times n
    """
    if symmetric:
        return _pascal_sym(n)
    else:
        return _pascal_lower(n)

pascal_jit = jax.jit(pascal, static_argnums=(0, 1))

import numpy,import scipy,import jax,from jax


import numpy as np

def pairwise_distances(p, q):
    first_term = np.einsum('ij->i', p ** 2)  # sum along dimension
    second_term = np.einsum('ij->i', q ** 2)  # sum along dimension
    third_term = np.einsum('ik,jk->ij', p, q)  # pairwise product
    squared_distances = first_term[:, None] + second_term
    squared_distances -= 2 * third_term

    # Ignore numerical error
    squared_distances[squared_distances < 1e-10] = 0

    return np.sqrt(squared_distances)


from time import time
import matplotlib
#this will prevent the figure from popping up
matplotlib.use('Agg')
from matplotlib import pyplot as plt
import numpy as np
import pycuda.autoinit
from pycuda import gpuarray
from pycuda.elementwise import ElementwiseKernel

# first string: the input, pycuda::complex<float> is a special type from pycuda
mandel_ker = ElementwiseKernel(
"pycuda::complex<float> *lattice, float *mandelbrot_graph, int max_iters, float upper_bound",
"""
mandelbrot_graph[i] = 0;

pycuda::complex<float> c = lattice[i];
pycuda::complex<float> z(0,0);

for (int j = 0; j < max_iters; j++)
    {

     z = z*z + c;

     if(abs(z) > 1000)
         {
          mandelbrot_graph[i] = j;
          break;
         }

    }

""",
"mandel_ker")

def gpu_mandelbrot(width, height, real_low, real_high, imag_low, imag_high, max_iters, upper_bound):

    # we set up our complex lattice as such, matrix not supported by pycuda
    real_vals = np.matrix(np.linspace(real_low, real_high, width), dtype=np.complex64)
    imag_vals = np.matrix(np.linspace(imag_high, imag_low, height), dtype=np.complex64) * 1j

    # put them on top of each other
    mandelbrot_lattice = np.array(real_vals + imag_vals.transpose(), dtype=np.complex64)

    # copy complex lattice to the GPU
    mandelbrot_lattice_gpu = gpuarray.to_gpu(mandelbrot_lattice)

    # allocate an empty array on the GPU
    mandelbrot_graph_gpu = gpuarray.empty(shape=mandelbrot_lattice.shape, dtype=np.float32)

    mandel_ker(mandelbrot_lattice_gpu, mandelbrot_graph_gpu, np.int32(max_iters), np.float32(upper_bound))

    mandelbrot_graph = mandelbrot_graph_gpu.get()

    return mandelbrot_graph

if __name__ == '__main__':

    t1 = time()
    mandel = gpu_mandelbrot(4096,4096,-2,2,-2,2,1024, 2)
    t2 = time()

    mandel_time = t2 - t1

    t1 = time()
    fig = plt.figure(1)
    plt.imshow(mandel, vmin=0, vmax=15)
    plt.savefig('mandelbrot.png', dpi=fig.dpi)
    t2 = time()

    dump_time = t2 - t1

    print('It took {} seconds to calculate the Mandelbrot graph.'.format(mandel_time))
    print('It took {} seconds to dump the image.'.format(dump_time))


#!/usr/bin/python
"""
File: fit_pendulum_data

Copyright (c) 2016 Michael Seaman

License: MIT

Gets data about a pendulum and fits it using the numpy
polynomial approximator
"""
import numpy as np
import matplotlib.pyplot as plt

def retrieve_pendulum_data(filename = "pendulum.dat"):
    """
    Gets pendulum data from filename and outputs a 2d list of
    output[0] = L and output[1] = T
    """
    L_list = []
    T_list = []
    with open(filename, 'r') as infile:
        for line in infile:
            data = line.split()
            try:
                L_list.append(float(data[0]))
                T_list.append(float(data[1]))
            except ValueError:
                pass

    infile.close()
    return [L_list, T_list]

def pendulum_fit(L, T, degree):
    """
    Outputs the original list of lengths and a list of period variables as given by the fitted function T(L)
    """
    coeff = np.polyfit(L, T, degree)
    p = np.poly1d(coeff)
    print "Fitted Curve of degree {0}: ".format(degree)
    print p
    return [L,p(L)]


# loss function常用的一种交叉熵函数cross_entropy_error, E = -(for k in range(len(y) np.sum(np.log(y) * t))
import numpy as np

def cross_entropy_error(y, t):
    delta = 1e-7  #定一个非常小的theta主要用于防止np.log(0)变为-inf，导致后面的数据无法正常计算
    return -(np.sum(t * np.log(y + delta)))

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

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

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

'''
cross entropy error
由于t中的数据除了正确标签为1， 其余标签都为0，所以cross entropy error计算的是对应的正确标签的自然对数
由于对数函数log的性质，x = 1时， 由= 0， 随着x靠近0，y逐渐变小，由于cross entropy error带上负号，所以越接近0，误差越大
'''


#  in console run py -m pip install matplotlib
import matplotlib.pyplot as plt
import numpy as np

# x = np.linspace(0, 20, 100)  # Create a list of evenly-spaced numbers over the range
# plt.plot(x, np.sin(x))       # Plot the sine of each x point
# plt.show()                   # Display the plot

print("S")

h  = [1.7, 1.8]
w = [70, 73]

print(h)

np_h  = np.array(h)
np_w = np.array(w)

bmi = np_w / np_h ** 2

print(bmi)
print(bmi[0])
print(bmi[1])

print(bmi[bmi > 23])

print(type(bmi))

print("end")

nn = np.array([0,1,2,3,4,5])
mm = nn[2:4]
print(mm)

print(type(nn))

np_all = np.array([h,w])

print(np_all)

print(np_all[0,0])
print(np_all[:,0])

print("ssssssss")
x = np.array([[1, 2, 3],
              [1, 2, 3]])
y = np.array([[1, 1, 1],
              [1, 2, 3]])

print(x)
print(y)
z = x - y

print(z)

print ("xxxx")
baseball = [[180, 78.4],
            [215, 102.7],
            [210, 98.5],
            [188, 75.2]]

np_baseball = np.array(baseball)

print(np_baseball.shape)


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.spatial.distance import pdist, squareform
from scipy.cluster.hierarchy import linkage, dendrogram
from sklearn.cluster import AgglomerativeClustering

# # Organizing clusters as a hierarchical tree

# ## Grouping clusters in bottom-up fashion

np.random.seed(123)

variables = ['X', 'Y', 'Z']
labels = ['ID_0', 'ID_1', 'ID_2', 'ID_3', 'ID_4']

X = np.random.random_sample([5, 3])*10
df = pd.DataFrame(X, columns=variables, index=labels)
print(df)

# ## Performing hierarchical clustering on a distance matrix

row_dist = pd.DataFrame(squareform(pdist(df, metric='euclidean')),
                        columns=labels,
                        index=labels)
print(row_dist)

# We can either pass a condensed distance matrix (upper triangular) from the `pdist` function, or we can pass the "original" data array and define the `metric='euclidean'` argument in `linkage`. However, we should not pass the squareform distance matrix, which would yield different distance values although the overall clustering could be the same.

# 1. incorrect approach: Squareform distance matrix
#row_clusters = linkage(row_dist, method='complete', metric='euclidean')
#pd.DataFrame(row_clusters,
#             columns=['row label 1', 'row label 2',
#                      'distance', 'no. of items in clust.'],
#             index=['cluster %d' % (i + 1)
#                    for i in range(row_clusters.shape[0])])

# 2. correct approach: Condensed distance matrix
row_clusters = linkage(pdist(df, metric='euclidean'), method='complete')
pd.DataFrame(row_clusters,
             columns=['row label 1', 'row label 2',
                      'distance', 'no. of items in clust.'],
             index=['cluster %d' % (i + 1)
                    for i in range(row_clusters.shape[0])])

# 3. correct approach: Input matrix
row_clusters = linkage(df.values, method='complete', metric='euclidean')
pd.DataFrame(row_clusters,
             columns=['row label 1', 'row label 2',
                      'distance', 'no. of items in clust.'],
             index=['cluster %d' % (i + 1)
                    for i in range(row_clusters.shape[0])])

# make dendrogram
row_dendr = dendrogram(row_clusters,
                       labels=labels,
                       color_threshold=np.inf
                       )
plt.tight_layout()
plt.ylabel('Euclidean distance')
plt.show()

# ## Attaching dendrograms to a heat map

# plot row dendrogram
fig = plt.figure(figsize=(8, 8), facecolor='white')
axd = fig.add_axes([0.09, 0.1, 0.2, 0.6])

# note: for matplotlib < v1.5.1, please use orientation='right'
row_dendr = dendrogram(row_clusters, orientation='left')

# reorder data with respect to clustering
df_rowclust = df.iloc[row_dendr['leaves'][::-1]]

axd.set_xticks([])
axd.set_yticks([])

# remove axes spines from dendrogram
for i in axd.spines.values():
    i.set_visible(False)

# plot heatmap
axm = fig.add_axes([0.23, 0.1, 0.6, 0.6])  # x-pos, y-pos, width, height
cax = axm.matshow(df_rowclust, interpolation='nearest', cmap='hot_r')
fig.colorbar(cax)
axm.set_xticklabels([''] + list(df_rowclust.columns))
axm.set_yticklabels([''] + list(df_rowclust.index))
plt.show()

# ## Applying agglomerative clustering via scikit-learn
ac = AgglomerativeClustering(n_clusters=3,
                             affinity='euclidean',
                             linkage='complete')
labels = ac.fit_predict(X)
print('Cluster labels: %s' % labels)

ac = AgglomerativeClustering(n_clusters=2,
                             affinity='euclidean',
                             linkage='complete')
labels = ac.fit_predict(X)
print('Cluster labels: %s' % labels)

Chapter 11/Organizing clusters as a hierarchical tree/program1.py


import numpy as np

def perceptron(weight, bias, x):
    model = np.add(np.dot(x, weight), bias)
    print('model: {}'.format(model))
    logit = 1/(1+np.exp(-model))
    print('Type: {}'.format(logit))
    return np.round(logit)

def compute(logictype, weightdict, dataset):
    weights = np.array([ weightdict[logictype][w] for w in weightdict[logictype].keys()[::-1]])
    output = np.array([ perceptron(weights, weightdict['bias'][logictype], val) for val in dataset])
    print(logictype)
    return logictype, output

logic = {
    '_and' : {
        'w0': -0.1,
        'w1': 0.2,
        'w2': 0.2
    },
    '_or': {
        'w0': -0.1,
        'w1': 0.7,
        'w2': 0.7
    },
    '_nand': {
        'w0': 0.6,
        'w1': -0.8,
        'w2': -0.8
    },
    '_nor': {
        'w0': 0.5,
        'w1': -0.7,
        'w2': -0.7
    },
    '_not': {
        'w0': 0.5,
        'w1': -0.7
    },
    'bias': {
        '_and': -0.2,
        '_or': -0.1,
        '_nand': 0.3,
        '_nor': 0.1,
        '_not': 0.1
    }
}
dataset = np.array([
    [1,0,0],
    [1,0,1],
    [1,1,0],
    [1,1,1]
])

_and = compute('_and', logic, dataset)
_or = compute('_or', logic, dataset)
_nand = compute('_nand', logic, dataset)
_nor = compute('_nor', logic, dataset)
_not = compute('_not', logic, [[1,0],[1,1]])

def template(dataset, name, data):
    print("\nLogic Function: {}".format(name[1:].upper()))
    if name is "_not":
        print("X\tY")
        toPrint = ["{3}\t{0}".format(output, *datas) for datas, output in zip(dataset, data)]
        for i in toPrint:
            print(i)
    else:
        print("X1\tX2\tY")
        toPrint = ["{2}\t{3}\t{0}".format(output, *datas) for datas, output in zip(dataset, data)]
        for i in toPrint:
            print(i)

gates = [_and, _or, _nand, _nor, _not]

for i in gates:
    template(dataset, *i)


import numpy as np
from collections import defaultdict

def solve(A, b, *args, **kwargs):
    safe_kwargs = defaultdict(lambda: None)
    for key, value in kwargs.items():
        safe_kwargs[key] = value

    methods = {
            "lu" : lu,
            "jacobi": jacobi,
            "gauss seidel": gauss_seidel,
            "sor": successive_overrelaxation
            }

    configs = {
            "tolerance": 1e-10,
            "max_iter": 100,
            "method": "gauss seidel"
            }

    for key, value in configs.items():
        print(key, value)# safe_kwargs[key])
        configs[key] = safe_kwargs[key] or value

    return methods[configs["method"]](A, b, *args, **configs)

def lu(A, b):
    m, n = np.shape(A)
    assert n == m, "Input matrix has dimension {}x{} and isn't square.".format(m,n)

    perm = np.eye(n)
    lower = np.zeros(n)
    upper = A.copy()

    for j in range(n):
        index = np.argmax(np.abs(upper[j:n, j]))
        assert upper[index, j] != 0.0, "This matrix is singular!"
        index += j

        if index > j:
            upper[[index, j]] = upper[[j, index]]
            perm[[index, j]] = perm[[j, index]]
            lower[[index, j]] = lower[[j, index]]

        k = slice(j+1, n)
        js = slice(j, n)
        lower[k, j] = upper[k, j] / upper[j, j]
        upper[k, js] -= lower[k,j] * upper[j, js]
    lower += np.eye(n)

    return perm, lower, upper

def _iteration_submethod(A, b, x, i):
    return 1./A[i,i] * (b[i] + A[i,i] * x[i] - A[i,:] @ x)

def _generic_iteration(A, b, subfunc, *args, tolerance=1e-10, max_iter=100):
    x = np.zeros(A.shape[0])
    iterations = 0

    while iterations < max_iter:
        for i in range(x.size):
            x[i] = subfunc(A, b, x, i, *args)
        err = np.linalg.norm(A @ x - b)
        if err < tolerance:
            break
        iterations += 1

    return x, iterations

def jacobi(A, b, *args, tolerance=1e-10, max_iter=100):
    x = np.zeros(A.shape[0])
    iterations = 0

    while iterations < max_iter:
        xprev = x.copy()
        for i in range(x.size):
            x[i] = _iteration_submethod(A, b, xprev, i)
        err = np.linalg.norm(A @ x - b)
        if err < tolerance:
            break
        iterations += 1

    return x, iterations

def gauss_seidel(A, b, *args, tolerance=1e-10, max_iter=100):
    def gauss_seidel_subfunc(A, b, x, i, *args):
        return _iteration_submethod(A, b, x, i)

    return _generic_iteration(A,b, gauss_seidel_subfunc,
            tolerance=tolerance, max_iter=max_iter)

def successive_overrelaxation(A, b, omega = 1.01, *args, tolerance=1e-10, max_iter=100):
    def sor_subfunc(A, b, x, i, omega):
        return omega * _iteration_submethod(A, b, x, i) + (1 - omega) * x[i]

    return _generic_iteration(A, b, sor_subfunc, omega, tolerance=1e-10, max_iter=100)


# -*- coding: utf-8 -*-
"""
Created on Mon Dec 13 22:05:32 2021

@author: Oliver
"""
import sympy  as sp
import numpy as np
import matplotlib.pyplot as plt
import math

E = 200000 #MPA
I = 300000000 #mm^4
w0 = 250 #N/mm
dx = 125 #mm
y0 = 0
yL = 0
L = 3000
y = np.linspace(0,3000,24000)
x = sp.Symbol('x')
f = sp.Function('f')(x)
f = w0/(120*E*I*L)*(-5*x**4+6*L**2*x**2-L**4)

df = sp.diff(f)
M_x = E*I*df
dMdxV_x = sp.diff(E*I*df)
dVdxw_x = -sp.diff(dMdxV_x)

"E*I*dthetadx = M(x)"
"dMdx = V(x)"
"dVdx = -w(x)"
deflection = sp.integrate(f)
print(deflection)
# deflection_values = []
# for i in y:
#     v = deflection.evalf(subs = {x:i})
#     deflection_values.append(v)

# plt.plot(y,deflection_values)
# plt.xlabel('Length of bar (mm)')
# plt.ylabel('Deflection (mm)')
# plt.show()

print(f'Moment is given by the following equation: {M_x}')
print(f'Shear is given by the following equation: {dMdxV_x}')
print(f'Load is given by the following equation: {dVdxw_x}')

#%% QUESTION 2

t_init = 0
x_final = 100

def model(y,x):
    g = 9.81
    C = 0.55
    h = 2.75
    r = 1.5
    D = 0.03
    A = 3.14*(D/2)**2
    Q = C*A*math.sqrt(2*g*y)
    dQdt = (-Q)/(2*3.14*y*r - 3.14*y**2)
    return dQdt

# ------------------------------------------------------
x0 = t_init
y0 = 2.75
# ------------------------------------------------------
# Euler method
x_final = 10000
# step size
x = 1
# number of steps
n_step = math.ceil(x_final/x)

# Definition of arrays to store the solution
y_eul = np.zeros(n_step+1)
x_eul = np.zeros(n_step+1)

# Initialize first element of solution arrays
# with initial condition
y_eul[0] = 2.75
x_eul[0] = 0

# Populate the x array
for i in range(n_step):
    x_eul[i+1]  = x_eul[i] + x

# Apply Euler method n_step times
for i in range(n_step):
    # compute the slope using the differential equation
    slope = model(y_eul[i],x_eul[i])
    # use the Euler method
    y_eul[i+1] = y_eul[i] + x * slope
    if y_eul[i+1] <0:
        break

plt.plot(x_eul, y_eul , 'b.-',)
plt.xlabel('time (s)')
plt.ylabel('y(x)')
plt.show()

#%% QUESTION 3
print()
print("________________________________________________")
print()
f = 60
L = 30
E = 1.25*10**8
I = 0.05

y = sp.Function('y')
z = sp.Symbol('z')

y = f/(2*E*I)*(L-z)**2
int_y = sp.integrate(y,z)
d_int_y = sp.integrate(int_y)
print(f'The first integral is : {int_y}')
print(f'The second integral is : {d_int_y}')
d_of_mast = d_int_y.evalf(subs = {z:30})
print(f'The deflection of the mast at the peak is : {d_of_mast}m')


#########################
##                     ##
## Irving Gomez Mendez ##
##    March 03, 2021   ##
##                     ##
#########################

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

# m(x) = e_1.T(X_x.T W_x X_x)**(-1) @ (X_x.T W_x Y)

def m(x):
    return (np.sin(2*np.pi*x**3))**3

n = 100
h = 0.024
epsilon = norm.rvs(scale=0.1, size=n)
x_dat = uniform.rvs(size=n)
y = np.array([m(xx) for xx in x_dat])

x_vect = np.linspace(0,1,100)
m_vect =  [m(xx) for xx in x_vect]

y_dat = y+epsilon

plt.figure(figsize=(15,7.5))
plt.scatter(x_dat, y+epsilon)
plt.plot(x_vect, m_vect, 'r--')

def hat_m(x):
    XX = np.vstack([np.ones(n),(x_dat-x)]).T
    W = np.diag(norm.pdf((x_dat-x)/h))
    beta_0 = np.linalg.solve(XX.T @ W @ XX, XX.T @ W @ y_dat)[0]
    return(beta_0)

hat_m_vect = [hat_m(xx) for xx in x_vect]

plt.figure(figsize=(15,7.5))
plt.scatter(x_dat, y+epsilon)
plt.plot(x_vect, m_vect, 'r--')
plt.plot(x_vect, hat_m_vect, 'purple')


'''
Construct a box with the maximum volume from a solid piece of material.
'''

import math
from sympy import Derivative, Symbol, solve

def box_volume( w, h ):
	s = Symbol( 's' )
	# v = b * * w * h
	V = ( h - 2*s ) * ( w - 2*s ) * s
	dV = Derivative( V, s ).doit()

	canidates = solve( dV )

	# Eliminate impossible Values
	for c in canidates:
		l = 2 * c.evalf()

		if( l > w or l > h ):
			canidates.remove( c )

	max_vol = 0

	if( len( canidates ) != 1 ):
		print( 'Invalid number of solutions.' )
	else:
		s0 = canidates[ 0 ].evalf()
		max_vol = V.subs( { s: s0 } )

	return max_vol

if __name__ == '__main__':

	try:
		w = float( input( 'Enter the width of the material piece: ') )
		h = float( input( 'Enter the height of the material piece: ') )
	except ValueError:
		print( 'Error parsing values' )
	else:
		print( 'material dimentions: {0} x {1}'.format( w, h ) )
		print( 'Maximum box volume: {0}'.format( box_volume( w, h ) ) )


import numpy as np
from numpy import vectorize

@vectorize
def relu(x: float) -> float:
    """
    The ReLu activation function

    Args:
        x: The input to the function

    Returns:
        The output of the function
    """
    if x > 0:
        return x
    return 0.1 * x

@vectorize
def relu_d(x: float) -> float:
    """
    The gradient of the ReLu activation function

    Args:
        x: The point at which to take the gradient

    Returns:
        The gradient of the ReLu activation function
    """
    if x > 0:
        return 1
    return 0.1

tanh = np.tanh  # Assigned to this module for code clarity in other files

@vectorize
def tanh_d(x: float) -> float:
    """
    The gradient of the Hyperbolic Tangent activation function

    Args:
        x: The point at which to take the gradient

    Returns:
        The gradient of the tanh activation function
    """
    return 1 - x ** 2


import numpy as np

def softmax(L):
    return np.exp(L) / sum(np.exp(L))

if __name__ == "__main__":
    data = [5, 6, 7]
    print(np.exp(data))
    print(sum(np.exp(data)))
    print(softmax(data))

### Expect output
[ 148.4131591   403.42879349 1096.63315843]
1648.4751110237703
[0.09003057 0.24472847 0.66524096]
###


import numpy as np

a = 9
b = 12
c = 4

print(np.gcd(a, b))
print(np.gcd(b, c))
print(np.gcd(a, c))

arr = np.array([20, 56, 8, 10, 90])

print(np.gcd.reduce(arr))

Tutorial/Code/37. NumPy GCD Greatest Common Denominator.py


# -*- coding: utf-8 -*-

# Práctica 1, Ejercicio BONUS
# David Cabezas Berrido

# Método de Newton para minimizar funciones

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

x, y = sp.symbols('x y')

# Función a minimizar
f_sym=sp.Lambda((x,y), sp.simplify((x-2)**2+2*(y+2)**2+2*sp.sin(2*sp.pi*x)*sp.sin(2*sp.pi*y)))
def f(w):
	return float(f_sym(w[0],w[1]))

# Derivada parcial de f respecto de x
fx_sym=sp.Lambda((x,y), sp.simplify(sp.diff(f_sym(x,y),x)))
def fx(w):
	return float(fx_sym(w[0],w[1]))

# Derivada parcial de f respecto de y
fy_sym=sp.Lambda((x,y), sp.simplify(sp.diff(f_sym(x,y),y)))
def fy(w):
	return float(fy_sym(w[0],w[1]))

# Gradiente de f
def gradf(w):
	return np.array((fx(w), fy(w)),np.float64)

# Derivadas parciales de segundo orden:
fxx_sym=sp.Lambda((x,y), sp.simplify(sp.diff(fx_sym(x,y),x)))
def fxx(w):
	return float(fxx_sym(w[0],w[1]))

fxy_sym=sp.Lambda((x,y), sp.simplify(sp.diff(fx_sym(x,y),y)))
def fxy(w):
	return float(fxy_sym(w[0],w[1]))

fyy_sym=sp.Lambda((x,y), sp.simplify(sp.diff(fy_sym(x,y),y)))
def fyy(w):
	return float(fyy_sym(w[0],w[1]))

# Matriz Hessiana
def hessf(w):
	a=fxy(w) # f es de clase 2, así que fxy = fyx
	return np.array([[fxx(w),a],[a,fyy(w)]])

# Método de Newton para encontrar un 0 en la derivada
def newton(w, grad_fun, hess_fun, fun, max_iters=500):

	graf = []
	graf.append(fun(w))

	for _ in range(max_iters):

		H1=np.linalg.inv(hess_fun(w))
		w = w - np.dot(H1,grad_fun(w))
		graf.append(fun(w))

	return w, graf

# Gradiente descendiente (para compararlo)
def gd(w, lr, grad_fun, fun, max_iters = 1000):

	graf = []
	graf.append(fun(w))

	for _ in range(max_iters):
		grad=grad_fun(w)
		w=w-lr*grad
		graf.append(fun(w))
		#print(w, fun(w))

	graf = np.array(graf,np.float64)

	return w, graf

print('Comparación del método de Newton con el gradiente descendente:\n')

# Número de iteraciones
max_iters=20
# Tasa de aprendizaje para el gradiente descendente
lr=0.01
# Puntos de inicio
condiciones_iniciales=np.array([(2.1, -2.1),(3.0, -3.0),(1.5, 1.5),(1.0, -1.0)])

# Experimentos con resultados (no he puesto pausas porque se pausa sólo hasta que se cierre la gráfica que genera, se puede descomentar la pausa)
for w in condiciones_iniciales:
    wn, grafn = newton(w, gradf, hessf, f, max_iters)
    wg, grafg = gd(w, lr, gradf, f, max_iters)

    # Resultados obtenidos
    print('Punto de inicio:', w)
    print('Solución y valor del método de Newton:')
    print ('(x,y) = (', wn[0], ', ', wn[1],')')
    print ('f(x,y) = ',f(wn))
    print('Solución y valor del gradiente estocástico:')
    print ('(x,y) = (', wg[0], ', ', wg[1],')')
    print ('f(x,y) = ',f(wg))
    print()

    #input("\n--- Pulsar tecla para continuar ---\n")

    # Curva de decrecimiento de la función
    plt.plot(range(0,max_iters+1), grafn, 'bo', alpha=0.6, label='Newton')
    plt.plot(range(0,max_iters+1), grafg, 'ro', alpha=0.4, label='Grad. Desc.')
    plt.xlabel('Iteraciones')
    plt.ylabel('f(x,y)')
    plt.title('Punto de inicio: w = '+str(w))
    plt.legend()
    plt.show()

input("\n--- Pulsar tecla para salir ---\n")


__author__ = 'Justin Niosi'

import numpy as np

def sigmoid(t):
    return 1.0 / (1.0 + np.exp(-t))

def sigmoid_derivative(t):
    # return np.exp(t) / np.square(np.exp(t) + 1)
    return sigmoid(t) * (1 - sigmoid(t))

def quadratic_cost(goal, actual):
    return np.sum(np.square(np.linalg.norm(goal - actual))) / (2 * len(goal))

def quadratic_cost_derivative(goal, actual):
    return actual[:len(goal)] - goal

class NeuralNetwork:

    def __init__(self, layers, max_neurons, rate, out_func=sigmoid, out_derivative=sigmoid_derivative,
                 cost_func=quadratic_cost, cost_derivative=quadratic_cost_derivative):
        self.layers = layers
        self.maxneurons = max_neurons
        self.rate = rate
        self.weights = np.zeros((self.layers, self.maxneurons, self.maxneurons))
        self.biases = np.zeros((self.layers, self.maxneurons))
        self.outfunc = out_func
        self.outderivative = out_derivative
        self.costfunc = cost_func
        self.costderivative = cost_derivative

    def feed_forward(self, inputs):
        values = np.zeros((self.layers, self.maxneurons))
        z_values = np.zeros((self.layers, self.maxneurons))
        values[0, :len(inputs)] = inputs
        for i in xrange(1, self.layers):
            z_values[i] = np.dot(values[i-1], self.weights[i])
            values[i] = self.outfunc(z_values[i] + self.biases[i])
        return np.array([values, z_values])

    def cost(self, goal, actual):
        return self.costfunc(goal, actual)

    def output_error(self, goal, actual, z_values):
        return self.costderivative(goal, actual) * self.outderivative(z_values[:len(goal)])

    def backpropagate(self, goal, feed_forward_output):
        output = np.zeros(self.biases.shape)
        cost_derivative = self.costderivative(goal, feed_forward_output[0][-1])
        output_derivative = self.outderivative(feed_forward_output[1][-1])
        output_error = cost_derivative * output_derivative
        output[-1] = output_error
        for i in xrange(self.layers - 1, 0, -1):
            weight_times_error = np.dot(self.weights[i].transpose(), output[i])
            out_derivative_z = self.outderivative(feed_forward_output[1][i - 1])
            output[i - 1] = np.dot(weight_times_error, out_derivative_z)
        return output

    def update_parameters(self, test_output):
        values, error = test_output
        self.biases -= self.rate * error
        values = np.roll(values, 1, axis=0).repeat(self.maxneurons, axis=0).reshape(self.weights.shape).transpose(0, 2, 1)
        error = error.repeat(self.maxneurons, axis=0).reshape(self.weights.shape)
        self.weights -= self.rate * (error + values)

    def run_test(self, input_values, goal):
        results = self.feed_forward(input_values)
        gradient = self.backpropagate(goal, results)
        return np.array([results, gradient])


import matplotlib.pyplot as plt
import numpy as np
from scipy.fftpack import ifft

Ns = 64
hNs = Ns//2

mY = np.zeros(hNs)
pY = np.zeros(hNs)
Y = np.zeros(Ns)
yw = np.zeros(Ns)
Y = np.zeros(Ns, dtype=complex)

k0 = 5
ph0 = 1.5
A0 = .8
mY[k0] = A0 * Ns
pY[k0] = ph0
Y[:hNs] = .5*mY*np.exp(1j*pY)
Y[hNs+1:] = Y[hNs-1:0:-1].conjugate()

plt.figure(1, figsize=(9, 5))
plt.subplot(3,1,1)
plt.plot(np.arange(hNs), mY, color='r', lw=1.5)
plt.axis([0,hNs-1,-1,Ns])
plt.title('mY; k0 = 5, A0 = .8, N = 64')

plt.subplot(3,1,2)
plt.plot(np.arange(hNs), pY, color='c', lw=1.5)
plt.axis([0,hNs-1,-.3, 2])
plt.title('pY; k0 = 5, theta0 = .1.5, N = 64')

y = np.real(ifft(Y))
yw[:hNs-1] = y[hNs+1:]
yw[hNs-1:] = y[:hNs+1]

plt.subplot(3,1,3)
plt.plot(np.arange(Ns), yw, 'b', lw=1.5)
plt.axis([0, Ns-1,-.9,.9])
plt.title('y; N = 64')

plt.tight_layout()
plt.savefig('sine-synthesis-periodic.png')
plt.show()


import numpy

EARTH_RADIUS = 1.0 # 6371000. # in metres
DEG2RAD = numpy.pi/180.

def lonLat2XYZ(p, radius):
    lam = p[0]*DEG2RAD
    the = p[1]*DEG2RAD
    rho = radius*numpy.cos(the)
    return  numpy.array([rho*numpy.cos(lam),
                         rho*numpy.sin(lam),
                         radius*numpy.sin(the)])

def lonLat2XYZArray(p, radius):
    lam = p[...,0]*DEG2RAD
    the = p[...,1]*DEG2RAD
    rho = radius*numpy.cos(the)
    xyz = numpy.zeros(p.shape, numpy.float64)
    xyz[..., 0] = rho*numpy.cos(lam) # x
    xyz[..., 1] = rho*numpy.sin(lam) # y
    xyz[..., 2] = radius*numpy.sin(the) # z
    return xyz

def getArcLengthArray(xyzA, xyzB, radius=EARTH_RADIUS):
    radiusSquare = radius*radius
    angle = numpy.arccos(  numpy.sum(xyzA*xyzB, axis=-1) / radiusSquare )
    return numpy.fabs(radius * angle)

def getArcLength(xyzA, xyzB, radius=EARTH_RADIUS):
    return abs( radius * numpy.arccos( xyzA.dot(xyzB)/radius**2 ) )

class PoleRotator(object):

    def __init__(self, deltaDeg=(0., 0.)):

        # transformation matrix
        alpha = numpy.pi * deltaDeg[1] / 180.
        beta = numpy.pi * deltaDeg[0] / 180.
        cos_alp = numpy.cos(alpha)
        sin_alp = numpy.sin(alpha)
        cos_bet = numpy.cos(beta)
        sin_bet = numpy.sin(beta)

        # http://gis.stackexchange.com/questions/10808/lon-lat-transformation
        rot_alp = numpy.array([[ cos_alp, 0., sin_alp],
                               [ 0.,      1., 0.     ],
                               [-sin_alp, 0., cos_alp]])
        rot_bet = numpy.array([[ cos_bet, sin_bet, 0.],
                               [-sin_bet, cos_bet, 0.],
                               [ 0.     , 0.,      1.]])
        self.transfMatrix = numpy.dot(rot_bet, rot_alp)

    def apply(self, lons, lats):

        lam = lons * DEG2RAD
        the = lats * DEG2RAD

        cos_the = numpy.cos(the)
        sin_the = numpy.sin(the)
        cos_lam = numpy.cos(lam)
        sin_lam = numpy.sin(lam)

        # to Cartesian
        rho = cos_the
        xx = rho * cos_lam
        yy = rho * sin_lam
        zz = sin_the

        # apply rotation
        xyz = numpy.zeros([3] + list(xx.shape), numpy.float64)
        xyz[0, ...] = xx
        xyz[1, ...] = yy
        xyz[2, ...] = zz
        xyzTransformed = numpy.tensordot(self.transfMatrix, xyz, axes=(0, 0))

        # back to lons and lats
        lonsNew = numpy.arctan2(xyzNew[1,...], xyzNew[0,...]) / DEG2RAD
        latsNew = numpy.arcsin(xyzNew[2,...]) / DEG2RAD

        # NOTE may need to apply dateline fix in some cases

        return lonsNew, latsNew


import numpy as np
from scipy import interpolate

import matplotlib.pyplot as plt

#x = np.arange(0, 2*np.pi+np.pi/4, 2*np.pi/8)
#y = np.sin(x)

ctr =np.array( [(3 , 1, 1), (2.5, 4, 2), (0, 1, 3), (-2.5, 4, 2),
                (-3, 0, 1.5), (-2.5, -4, 2), (0, -1, 4), (2.5, -4, 5), (3, -1, 4)])

x=ctr[:,0]
y=ctr[:,1]
z = ctr[:,2]

#x=np.append(x,x[0])
#y=np.append(y,y[0])

tck,u = interpolate.splprep([x,y],k=3,s=0)
u=np.linspace(0,1,num=50,endpoint=True)
out = interpolate.splev(u,tck)

plt.figure()
plt.plot(x, y, 'ro', out[0], out[1], 'b')
plt.legend(['Points', 'Interpolated B-spline', 'True'],loc='best')
plt.axis([min(x)-1, max(x)+1, min(y)-1, max(y)+1])
plt.title('B-Spline interpolation')
plt.show()

from mpl_toolkits import mplot3d

tck,u = interpolate.splprep([x,y,z],k=3,s=0)
u=np.linspace(0,1,num=50,endpoint=True)
out = interpolate.splev(u,tck)

fig = plt.figure()
ax = plt.axes(projection='3d')
# plt.figure()
plt.plot(x, y, z, 'ro')
plt.plot( out[0], out[1], out[2], 'b')
plt.legend(['Points', 'Interpolated B-spline', 'True'],loc='best')
# plt.axis([min(x)-1, max(x)+1, min(y)-1, max(y)+1])
plt.title('B-Spline interpolation')
plt.show()


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

from metropolis.metropolis import MetropolisAlgorithm

# Random generation according to normal distribution
np.random.seed(568)
x = np.random.normal(loc=0.0, scale=2.0, size=500)
print('Sampled mean and std: mean={:2.2f}, std={:2.2f}'.format(np.mean(x), np.std(x)))

lupost = lambda param: np.sum(stats.norm.logpdf(x, loc=param[0], scale=np.exp(param[1])))
metrop = MetropolisAlgorithm(lupost=lupost,
                             initial=np.array([-2, np.log(7)]),
                             scale=np.array([0.04, 0.04]),
                             burn_cont=100)

# Sample the distribution of parameters
result = metrop.run(batches=1000)

# second parameter requires transform
result.batch[:, 1] = np.exp(result.batch[:, 1])

means = [np.mean(result.batch[:, i]) for i in [0, 1]]
modes = [stats.mode(result.batch[:, i]).mode[0] for i in [0, 1]]

# Print results
print('Mean for parameters: mean={:2.2f}, std={:2.2f}'.format(*means))
print('Mode for parameters: mean={:2.2f}, std={:2.2f}'.format(*modes))
print('Accept rate is {:2.2f}'.format(result.accept))

# Plot simulated markov chains, the parameters
plt.figure()
for i in [0, 1]:
    ax = plt.subplot(1, 2, i + 1)
    ax.plot(result.batch[:, i])
plt.show()

# Plot histograms of the parameters
plt.figure()
for i in [0, 1]:
    ax = plt.subplot(1, 2, i + 1)
    ax.hist(result.batch[:, i])
plt.show()


import numpy as np
import matplotlib.pyplot as pyplot
import scipy.spatial.distance as sd
import sklearn.cluster as skc
import sklearn.metrics as skm
import scipy
import scipy
import sys
import os

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

def build_laplacian(W, laplacian_normalization=""):
    D = np.zeros(W.shape)
    D_inv = np.zeros(W.shape)
    D_invsqrt = np.zeros(W.shape)
    for i in range(W.shape[0]):
        D[i,i] = np.sum(W[i,:])
        D_inv[i,i] = 1./np.sum(W[i,:])
        D_invsqrt[i,i] = np.sqrt(D_inv[i,i])
    if laplacian_normalization == "unn":
        return D - W
    elif laplacian_normalization == "sym":
        return np.eye(W.shape[0]) - D_invsqrt.dot(W).dot(D_invsqrt)
    elif laplacian_normalization == "rw":
        return np.eye(W.shape[0]) - D_inv.dot(W)

def spectral_clustering(L, chosen_eig_indices, num_classes=2):
    [E,U] = np.linalg.eig(L)
    idx = np.argsort(np.real(E))
    E = np.diag(E[idx])
    U = np.real(U[:,idx])
    normalization = np.linalg.norm(U[:,chosen_eig_indices], axis=0)
    Y = U[:,chosen_eig_indices] / normalization
    Y = skc.KMeans(num_classes).fit(Y).labels_
    return Y

def two_blobs_clustering():
    # load the data
    in_data =scipy.io.loadmat(path+'/data/data_2blobs')
    X = in_data['X']
    Y = in_data['Y']
    num_classes = len(np.unique(Y))

    k = 10
    var =  0.5

    laplacian_normalization = 'unn'; #either 'unn'normalized, 'sym'metric normalization or 'rw' random-walk normalization
    chosen_eig_indices =  [0,1]

    # build laplacian
    W, similarities = build_similarity_graph(X, var=var, k=k, eps=0)
    L = build_laplacian(W, laplacian_normalization=laplacian_normalization)
    Y_rec = spectral_clustering(L,chosen_eig_indices)
    plot_clustering_result(X, Y, L, Y_rec, skc.KMeans(num_classes).fit_predict(X), normalized_switch=0)

def choose_eig_function(eigenvalues):
    gap = [eigenvalues[i+1]-eigenvalues[i] for i in range(len(eigenvalues)-1)]
    sortedGapIdx = np.argsort(-abs(np.array(gap)))
    idx = -1
    maxGap = 0
    for i in range(len(sortedGapIdx)):
        if abs(gap[i])>= maxGap:
            idx = i
            maxGap = abs(gap[i])
    return range(idx)

def spectral_clustering_adaptative(L, num_classes=2):
    [E,U] = np.linalg.eig(L)
    idx = np.argsort(np.real(E))
    chosen_eig_indices = choose_eig_function(np.real(E[idx])[:15])
    E = np.diag(np.real(E[idx]))
    U = np.real(U[:,idx])
    Y = U[:,chosen_eig_indices] / np.linalg.norm(U[:,chosen_eig_indices], axis=0)
    Y = skc.KMeans(num_classes).fit(Y).labels_
    return Y

def find_the_bend():
    num_samples = 600

    [X, Y] = blobs(num_samples,4,0.03)

    num_classes = len(np.unique(Y))

    k = 10
    var =  0.5

    laplacian_normalization = 'unn'; #either 'unn'normalized, 'sym'metric normalization or 'rw' random-walk normalization

    # build the laplacian
    W, similarities = build_similarity_graph(X, var, k=k, eps=0)
    L = build_laplacian(W, laplacian_normalization=laplacian_normalization)

    [E,U] = np.linalg.eig(L)
    idx = np.argsort(np.real(E))
    E = E[idx]
    U = np.real(U[:,idx])
    eigenvalues = E[:15]
    chosen_eig_indices = choose_eig_function(eigenvalues) # indices of the ordered eigenvalues to pick
    normalization = np.linalg.norm(U[:,chosen_eig_indices], axis=0)
    Y_rec = U[:,chosen_eig_indices] / normalization
    Y_rec = skc.KMeans(num_classes).fit_predict(Y_rec)

    plot_the_bend(X, Y, L, Y_rec, eigenvalues)

def two_moons_clustering():
    in_data =scipy.io.loadmat(path+'/data/data_2moons')
    X = in_data['X']
    Y = in_data['Y']
    num_classes = len(np.unique(Y))

    k = 5
    eps = 0.5
    var = 0.5

    laplacian_normalization = 'sym'; #either 'unn'normalized, 'sym'metric normalization or 'rw' random-walk normalization
    chosen_eig_indices = [0, 1] # indices of the ordered eigenvalues to pick

    W, similarities = build_similarity_graph(X, var, k=k, eps=eps)
    L = build_laplacian(W, laplacian_normalization=laplacian_normalization)
    Y_rec = spectral_clustering(L, chosen_eig_indices)

    plot_clustering_result(X, Y, L, Y_rec,skc.KMeans(num_classes).fit_predict(X))

def point_and_circle_clustering():
    in_data =scipy.io.loadmat(path+'/data/data_pointandcircle')
    X = in_data['X']
    Y = in_data['Y']
    num_classes = len(np.unique(Y))

    k = 15
    eps = 0.
    var = 0.5; # exponential_euclidean's sigma^2

    laplacian_normalization = 'rw'; #either 'unn'normalized, 'sym'metric normalization or 'rw' random-walk normalization
    chosen_eig_indices = [0, 1] # indices of the ordered eigenvalues to pick

    #  build the laplacian
    W, similarities = build_similarity_graph(X, var, k=k, eps=eps)
    L_unn = build_laplacian(W, laplacian_normalization='unn')
    L_norm = build_laplacian(W, laplacian_normalization='rw')

    # Distribution of nodes' degrees/connections
    plt.hist(np.sum((L_unn!=0).astype(int),axis=0))
    plt.xlabel("Number of edges (connectivity)", fontsize=16)
    plt.ylabel("Number of nodes", fontsize=16)
    plt.show()

    Y_unn = spectral_clustering(L_unn, chosen_eig_indices)
    Y_norm = spectral_clustering(L_norm, chosen_eig_indices)
    plot_clustering_result(X, Y, L_unn, Y_unn, Y_norm, 1);

def parameter_sensitivity(param='k'):
    num_samples = 500;

    var = 0.5

    laplacian_normalization = 'unn'; #either 'unn'normalized, 'sym'metric normalization or 'rw' random-walk normalization
    chosen_eig_indices =  [0, 1]
    if (param == 'k'):
        parameter_candidate = range(1,50,3)   # the number of neighbours for the graph or the epsilon threshold
    else:
        parameter_candidate = np.linspace(0.05,1,20)
    parameter_performance=[]

    for p in parameter_candidate:
        print(param+ " = " + str(p))
        [X, Y] = two_moons(num_samples,1,0.02)
        num_classes = len(np.unique(Y))
        if (param=='k'):
            W, similarities = build_similarity_graph(X, k=p)
        else:
            W, similarities = build_similarity_graph(X, eps=p)
        L =  build_laplacian(W, laplacian_normalization=laplacian_normalization)

        Y_rec = spectral_clustering(L, chosen_eig_indices, num_classes)
        parameter_performance+= [skm.adjusted_rand_score(Y,Y_rec)]

    plt.figure()
    plt.plot(parameter_candidate, parameter_performance)
    plt.title('parameter sensitivity')
    if param=='k':
        plt.xlabel("k", fontsize=16)
    else:
        plt.xlabel("epsilon", fontsize=16)
    plt.ylabel("Performance", fontsize=16)
    plt.show()

two_blobs_clustering()
find_the_bend()
two_moons_clustering()
point_and_circle_clustering()
parameter_sensitivity('k')
parameter_sensitivity('eps')


from numpy import array, random, dot, exp, linalg, zeros
from typing import List

def sigmoid(x):
    return 1.0 / (1.0 + exp(-x))

# Derivative of the sigomid function.
# x is the output of the sigmoid function. You can see it as x = sigmoid(y).
def _dvsigmoid(x: array) -> array:
    return x * (1 - x)

# Derivative of the sigmoid function
def dvsigmoid(x: array) -> array:
    return _dvsigmoid(sigmoid(x))

# Error or cost
def cost(x: array, y: array) -> array:
    return (linalg.norm(y - x) ** 2) / 2

def dvcost(x: array, y: array) -> array:
    return (x - y)

class Network:
    def __init__(self, dims: List[int]):
        random.seed(5)

        self.n_layers = len(dims)
        self.dims = dims
        # randomly initialize biases
        self.B = [2 * random.random((j, 1)) - 1 for j in dims[1:]]
        # randomly initialize weights
        self.W = [
            2 * random.random((j, i)) - 1
            for j, i in zip(dims[1:], dims[:-1])
        ]
        self.lr = 1

    # Return the ouput of the network given x input
    def feedforward(self, x: array) -> List[array]:
        L = [0] * self.n_layers
        L[0] = x
        for i in range(self.n_layers - 1):
            w, b, a = self.W[i], self.B[i], L[i]
            L[i + 1] = sigmoid(dot(w, a) + b)
        return L

    def backprop(self, tx: array, ty: array) -> tuple:
        # Initialize empty lists of n_layers - 1 size
        db = [0] * (self.n_layers - 1)
        dw = [0] * (self.n_layers - 1)

        # Output of each layer
        L = self.feedforward(tx)

        # Direction to move to reduce the cost times
        # the rate of change of the sigmoid function at a certain layer
        l_delta = dvcost(L[-1], ty) * _dvsigmoid(L[-1])

        db[-1] = l_delta
        dw[-1] = dot(l_delta, L[-2].T)

        # Same as - for i in reversed(range(1, self.num_layers)):
        for i in range(self.n_layers - 2, 0, -1):
            # How sensitive the function is to previous weights
            l_delta = dot(self.W[i].T, l_delta) * _dvsigmoid(L[i])

            db[i - 1] = l_delta
            dw[i - 1] = dot(l_delta, L[i - 1].T)

        return dw, db

    """
    Update weights and biases given a batch
    """
    def update_batch(self, batch, batch_size) -> None:
        sdW = [zeros(w.shape) for w in self.W]
        sdB = [zeros(b.shape) for b in self.B]

        """
        sdWB = array([self.backprop(x, y) for x, y in batch])
        """
        # Sum of all the delta weights and biases calculated from the batch
        for tx, ty in batch:
            dW, dB = self.backprop(tx, ty)

            for i in range(self.n_layers - 1):
                sdW[i] += dW[i]
                sdB[i] += dB[i]

        temp_calc = float(self.lr) / float(batch_size)
        # basically -learning rate * mean(delta weight) or
        # W[i] = W[i] - (learning_rate * sum_delta_weights) / n
        for i in range(self.n_layers - 1):
            self.W[i] += -temp_calc * sdW[i]
            self.B[i] += -temp_calc * sdB[i]

    """
    Train the neural network using mini-batch stochastic gradient descent.
    training_data -> List of tuples (x, y)
        x being the training inputs and
        y being the expect outputs
    """
    def SGD(self,
            tdata,
            epochs: int,
            batch_size: int,
            batch_n: int,
            learning_rate: float):
        self.lr = learning_rate

        for j in range(epochs):
            random.shuffle(tdata)

            # array of batch_n x batch_size shape
            batches = (
                tdata[k:k+batch_size]
                for k in range(0, batch_n * batch_size, batch_size)
             )

            for batch in batches:
                self.update_batch(batch, batch_size)

    def accuracy(self, test_data):
        n = len(test_data)
        correct = 0
        for i in range(n):
            tx, ty = test_data[i]

            a = self.feedforward(tx)[-1]
            correct += (a.argmax() == ty.argmax()).all()

        return correct / n

if __name__ == '__main__':
    net_dims = [3, 4, 1]
    net = Network(net_dims)

    tX = [array([[0], [0], [1]]),
          array([[0], [1], [1]]),
          array([[1], [0], [1]]),
          array([[0], [1], [0]]),
          array([[1], [1], [1]])]
    tY = [
        array([[0]]),
        array([[1]]),
        array([[1]]),
        array([[1]]),
        array([[0]])
    ]

    net.SGD(list(zip(tX, tY)), 1000, 5, 1, 6)

    x = array([[1], [0], [1]])
    y = net.feedforward(x)[-1]
    print(y)


import numpy as np
import sys, os
sys.path.append(os.pardir)
from common.activation_functions import sigmoid, identity_function

'''
신경망의 내적
간단한 레이어간의 내적 구현해보기
'''
# X=np.array([1,2])
# print(X.shape)
# W=np.array([[1,3,5],[2,4,6]])
# print(W)
# print(W.shape)
# Y=np.dot(X,W)
# print(Y)

'''
3층 신경망 구현하기
'''
# X=np.array([1.0, 0.5])
#
# W1=np.array([[0.1,0.3,0.5],[0.2,0.4,0.6]])
# B1=np.array([0.1,0.2,0.3])
# print(W1.shape)
# print(X.shape)
# print(B1.shape)
# A1=np.dot(X,W1)+B1
# Z1=sigmoid(A1)
# print(A1)
# print(Z1)
#
# W2=np.array([[.1, .4],[.2,.5],[.3,.6]])
# B2=np.array([.1, .2])
# print(Z1.shape)
# print(W2.shape)
# print(B2.shape)
# A2=np.dot(Z1,W2)+B2
# Z2=sigmoid(A2)
# print(A2)
# print(Z2)
#
# W3=np.array([[.1,.3],[.2,.4]])
# B3=np.array([.1,.2])
# print(Z2.shape)
# print(W3.shape)
# print(B3.shape)
# A3=np.dot(Z2,W3)+B3
# Y=identity_function(A3)
# print(A3)
# print(Y)

'''
구현 정리
'''
def init_network():
    network = {}
    network['W1'] = np.array([[.1,.3,.5],[.2,.4,.6]])
    network['b1'] = np.array([.1, .2, .3])
    network['W2'] = np.array([[.1, .4],[.2,.5],[.3,.6]])
    network['b2'] = np.array([.1,.2])
    network['W3'] = np.array([[.1,.3],[.2,.4]])
    network['b3'] = np.array([.1,.2])

    return network

def forward(network, x):
    W1, W2, W3 = network['W1'], network['W2'], network['W3']
    b1, b2, b3 = network['b1'], network['b2'], network['b3']

    a1 = np.dot(x, W1) + b1
    z1 = sigmoid(a1)
    a2 = np.dot(z1, W2) + b2
    z2 = sigmoid(a2)
    a3 = np.dot(z2, W3) + b3
    y = identity_function(a3)

    return y

network = init_network()
x = np.array([1.0, .5])
y = forward(network, x)
print(y)


"""
Linear algebra functions (matrix multiplication, vector length etc.)
"""

import numpy as np

def gramian(matrix):
    """
    Parameters
    ----------
    matrix : numpy.ndarray
        A matrix

    Returns
    -------
    numpy.ndarray
        The Gramian of `matrix`.
    """

    return np.transpose(matrix).dot(matrix)

def dot_product(vector1, vector2):
    """
    Calculates a dot product of two vectors.

    Parameters
    ----------
    vector1, vector2 : numpy.ndarray
        Two n by 1 matrices.

    Returns
    -------
    float
        The dot product of two matrices
    """

    return np.dot(np.transpose(vector1), vector2)[0, 0]

def matrix_size(matrix):
    """
    Parameters
    ----------
    matrix : numpy.ndarray
        A matrix.

    Returns
    -------
    tuple of two integers
        Size of a matrix. First integer is the number of rows.
    """

    rows = len(matrix)

    if rows > 0:
        columns = len(matrix[0])
    else:
        columns = 0

    return (rows, columns)


from scipy.stats import norm
from scipy.stats import zipf
import sys
sys.path.append ("../tableformula")
from tableformula import *
from tableformulagraph import *

def generate_n_obs_zipf (tail_index, n) :
    return list(zipf.rvs(tail_index, size=n))

def diff_std_deviation (px, py) :
    s = px*(1-px) + py*(1-py)
    return px, py, s**0.5

def pvalue (diff, std, N) :
    theta = abs(diff)
    bn = (2*N)**0.5 * theta / std
    pvalue = (1 - norm.cdf(bn))*2
    return pvalue

def draw_heavy_tail (sample, imagename) :
    table   = TableFormula (["obs"], [ [_] for _ in sample ] )
    avg,std = table.avg_std (lambda v : v["obs"])
    print ("avg,std", avg,std)
    std = 1

    normal  = norm.rvs (size = len(sample))
    normal  = [ x*std  for x in normal ]
    nortbl  = TableFormula (["obs"], [ [_] for _ in normal ] )
    nortbl.addc ("iobs", lambda v : int(v ["obs"] * 10))
    histon  = nortbl.groupby ( lambda v :v["iobs"],
                            [ lambda v : v["iobs"] ],
                            ["value", "nb"],
                            [ len ] )
    histon.sort (lambda v : v["nb"], reverse = True)

    histo   = table.groupby ( lambda v :v["obs"],
                            [ lambda v : v["obs"] ],
                            ["value", "nb"],
                            [ len ] )

    histo.sort (lambda v : v["nb"], reverse = True)
    histo.add_column_index("index", 1)

    vec  = list (histon.select (lambda v : v ["nb"]))
    vec += [0,] * len(histo)
    histo.add_column_vector("nb_normal", vec [:len(histo) ] )

    histo.addc ("log(index)", lambda v : math.log(v ["index"]) / math.log(10) )
    histo.addc ("log(nb)", lambda v : math.log(v ["nb"]) / math.log(10) )
    histo.addc ("log(nb_normal)", lambda v : math.log(v ["nb_normal"]) / math.log(10) if v["nb_normal"] > 0 else 0)
    histo = TableFormulaGraph (histo)
    histo.graph_XY ( [
            [ lambda v: v["log(index)"], lambda v: v["log(nb)"], "Zipf"],
            [ lambda v: v["log(index)"], lambda v: v["log(nb_normal)"], "Gauss"],
                        ],
                     outImage = imagename,
                     marker=False, linkPoint=True)

def draw_variancen (sample, imagename) :
    avg = 0.
    std = 0.
    n   = 0.
    w   = 1.
    add = []
    for i,x in enumerate(sample) :
        x    = float (x)
        avg += x * w
        std += x*x * w
        n   += w
        val  = (std/n - (avg/n)**2)**0.5
        add.append ( [ i, avg/n, val] )

    print add[-1]
    table = TableFormulaGraph ( ["index", "avg(n)", "std(n)"], add)
    table.graph_XY ( [
            [ lambda v: v["index"], lambda v: v["avg(n)"], "avg(n)"],
            [ lambda v: v["index"], lambda v: v["std(n)"], "std(n)"],
                        ],
                     outImage = imagename,
                     marker=False, linkPoint=True)

def hill_estimator (sample) :
    sample = list(sample)
    sample.sort(reverse=True)
    end = len(sample)/10
    end = min(end,100)
    s = 0.
    res = []
    for k in range (0,end) :
        s += math.log(sample[k])
        h = (s - (k+1)*math.log(sample[k+1]))/(k+1)
        h = 1./h
        res.append( [k, h] )
    return res

def draw_hill_estimator (sample, imagename) :
    res = hill_estimator(sample)
    table = TableFormulaGraph (["d", "hill"], res )
    table.graph_XY ( [
            [ lambda v: v["d"], lambda v: v["hill"], "Hill"],
                        ],
                     outImage = imagename,
                     marker=False, linkPoint=True)

def generate_series ( Ndays, tail_index, N) :
    res = [ ]
    total = [ ]
    for i in range(0,Ndays) :
        sample = generate_n_obs_zipf(tail_index, N)
        total.extend(sample)
        dis = { }
        for t in total : dis[t] = 0
        res.append( len(dis) )
    return res

def std (l) :
    m = sum(l)
    v = sum ( [_*_ for _ in l ] )
    m = m*1. / len(l)
    v = v*1. / len(l)
    return (v - m*m)**0.5

if __name__ == "__main__" :
    sys.path.append("../tableformula")
    from tableformula import *
    TableFormula = TableFormulaCore

    # mix
    tail_index  = 3
    N           = 100
    Ndays       = 200

    values = [ ]
    label  = None
    for k in range (0,50) :
        print k
        series      = generate_series( Ndays, tail_index, N)
        if label == None :
            label = [ "d%d" % (k+1) for k in range(0,len(series)) ]
        values.append (series)

    table = TableFormula (label, values)
    table = table.transpose (labelAsRow = False)
    table.addc ("ave", lambda v : sum( v.values() )*1.0 / len(v) )
    table.addc ("dev", lambda v : std( v.values() ) )

    print table

    if False :
        draw_heavy_tail(sample, "distribution_zipf_%d.png" % N)
        draw_variancen(sample, "std deviation after n obs.png")
        draw_hill_estimator(sample, "hill.png")

        TableFormulaGraph.ShowLastGraph()


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

# In[41]:

# Quantile regression
# Step-1. Load libraries
from __future__ import print_function
#get_ipython().run_line_magic('matplotlib', 'inline')
import patsy
import numpy as np
import pandas as pd
import statsmodels.api as sm
import statsmodels.formula.api as smf
import matplotlib.pyplot as plt
from statsmodels.regression.quantile_regression import QuantReg
import seaborn as sns
import os
sns.set_style('whitegrid')

# Step-2. Import data
os.chdir('/Users/pauline/Documents/Python')
data = pd.read_csv("Tab-Morph.csv")

# Step-3. Least Absolute Deviation
mod = smf.quantreg('profile ~ sedim_thick', data)
res = mod.fit(q=.5)
print(res.summary())

# Step-4. Placing the quantile regression results in a Pandas DataFrame, and the OLS results in a dictionary
quantiles = np.arange(.05, .96, .1)
def fit_model(q):
    res = mod.fit(q=q)
    return [q, res.params['Intercept'], res.params['sedim_thick']] +             res.conf_int().loc['sedim_thick'].tolist()

models = [fit_model(x) for x in quantiles]
models = pd.DataFrame(models, columns=['q', 'a', 'b','lb','ub'])

ols = smf.ols('profile ~ sedim_thick', data).fit()
ols_ci = ols.conf_int().loc['sedim_thick'].tolist()
ols = dict(a = ols.params['Intercept'],
           b = ols.params['sedim_thick'],
           lb = ols_ci[0],
           ub = ols_ci[1])

print(models)
print(ols)

# Step-5.
x = np.arange(data.sedim_thick.min(), data.sedim_thick.max(), 5)
get_y = lambda a, b: a + b * x

fig, ax = plt.subplots(figsize=(8, 6))

for i in range(models.shape[0]):
    y = get_y(models.a[i], models.b[i])
    ax.plot(x, y, linestyle='dotted', color='grey')

y = get_y(ols['a'], ols['b'])

ax.plot(x, y, color='red', label='OLS')
ax.scatter(data.sedim_thick, data.profile, alpha=.5, c='#00a381', s=70)
ax.set_xlim((40, 145))
ax.set_ylim((0, 25))
legend = ax.legend()
ax.set_xlabel('Sediment thickness, m', fontsize=14)
ax.set_ylabel('Profile, nr.', fontsize=14);

plt.title("Mariana Trench: Quantile regression for all the data set \nof sediment thickness by 25 bathymetric profiles", fontsize=14)
plt.annotate('E', xy=(-0.01, 1.06), xycoords="axes fraction", fontsize=18,
           bbox=dict(boxstyle='round, pad=0.3', fc='w', edgecolor='grey', linewidth=1, alpha=0.9))
plt.show()

# In[ ]:

import numpy,import statsmodels,from statsmodels


''' Heat equation '''

import numpy as np
import networkx as nx
import pdb
import random

import gds

def heat_grid(n = 10, steady_state=False) -> gds.node_gds:
	G = gds.square_lattice(n, n)
	temp = gds.node_gds(G)
	if steady_state:
		''' Steady-state version (for comparison) '''
		temp.set_evolution(cost=lambda t, y: temp.laplacian(y))
	else:
		temp.set_evolution(dydt=lambda t, y: temp.laplacian(y))
	return temp

def grid_const_boundary(steady_state=False) -> gds.node_gds:
	n = 7
	temp = heat_grid(n=n, steady_state=steady_state)
	temp.set_constraints(dirichlet = lambda x: 1.0 if (0 in x or (n-1) in x) else None)
	return temp

def grid_mixed_boundary(steady_state=False) -> gds.node_gds:
	n = 10
	temp = heat_grid(n=n, steady_state=steady_state)
	def dirichlet(t, x):
		if x[0] == 0 or x[0] == n-1:
			return 0.5
		elif x[1] == 0:
			return 1.0
		return None
	def neumann(t, x):
		if x[1] == n-1 and x[0] not in (0, n-1):
			return -0.1
		return None
	temp.set_constraints(dirichlet=dirichlet, neumann=neumann)
	return temp

def grid_sinus_boundary(steady_state=False, phi=0) -> gds.node_gds:
	n = 10
	temp = heat_grid(n=n, steady_state=steady_state)
	def dirichlet(t, x):
		if x[0] == 0:
			return np.sin(t+x[1]/4+phi)**2
		elif x[0] == n-1:
			return 0.
		return None
	temp.set_constraints(dirichlet=dirichlet)
	return temp

def grid_tv_boundary():
	G = gds.square_lattice(10, 10)
	temperature = gds.node_gds(G)
	temperature.set_evolution(dydt=lambda t, y: temperature.laplacian())
	temperature.set_constraints(dirichlet=gds.combine_bcs(
		lambda x: 0 if x[0] == 9 else None,
		lambda t, x: np.sin(t+x[1]/4)**2 if x[0] == 0 else None
	))
	gds.render(temperature, title='Heat equation with time-varying boundary')

def grid_linear(steady_state=False) -> gds.node_gds:
	n = 10
	temp = heat_grid(n=n, steady_state=steady_state)
	def dirichlet(x):
		if x[0] == 0:
			return 1.0
		elif x[0] == n-1:
			return 0.
		return None
	temp.set_constraints(dirichlet=dirichlet)
	return temp

def heat_test():
	G = gds.grid_graph(10, 10)
	temp1 = gds.node_gds(G)
	x = (5,5)
	i = temp1.X[x]
	B = temp1.incidence.copy().todense()
	B[i][B[i] < 0] = 0
	temp1.set_evolution(dydt=lambda t, y: -B@B.T@y)
	temp1.set_initial(y0=lambda n: 1.0 if n == x else 0.0)
	temp2 = gds.node_gds(G)
	temp2.set_evolution(dydt=lambda t, y: temp2.laplacian(y))
	temp2.set_constraints(dirichlet={x: 1.0})
	return temp1, temp2

def heat_free_lr():
	temp = heat_grid(10)
	temp.set_constraints(dirichlet=gds.combine_bcs(
		lambda x: 0. if x[1] == 9 else None,
		lambda x: 1. if x[1] == 0 else None,
	))
	gds.render(temp)

if __name__ == '__main__':
	# Use coupling to visualize multiple PDEs simultaneously
	# p1 = grid_linear(steady_state=True)
	# p3 = grid_sinus_boundary(steady_state=True)
	# p4 = grid_sinus_boundary(steady_state=True, phi=np.pi/4)

	# t1, t2 = heat_test()

	# sys = gds.couple({
		# 'heat0': p1,
		# 'heat1': t1,
		# 'heat2': t2
	# })

	# G = nx.random_geometric_graph(200, 0.125)
	# p5 = gds.node_gds(G)
	# p5.set_evolution(dydt=lambda t, y: 10*p5.laplacian())
	# p5.set_constraints({random.randint(0, 200): 1.0 for _ in range(10)})

	# gds.render(p5, title='Diffusion on a random geometric graph')
	# gds.render(sys, dynamic_ranges=True)

	heat_free_lr()