Instruction:
Write a Python 3 function that can
compute the quantities and prices for the economy.

Response:
def compute_sequence(self, x0, ts_length=None, Pay=None):
        """
        Simulate quantities and prices for the economy

        Parameters
        ----------
        x0 : array_like(float)
            The initial state

        ts_length : scalar(int)
            Length of the simulation

        Pay : array_like(float)
            Vector to price an asset whose payout is Pay*xt

        """
        lq = LQ(self.Q, self.R, self.A, self.B,
                self.C, N=self.W, beta=self.beta)
        xp, up, wp = lq.compute_sequence(x0, ts_length)
        self.h = self.Sh.dot(xp)
        self.k = self.Sk.dot(xp)
        self.i = self.Si.dot(xp)
        self.b = self.Sb.dot(xp)
        self.d = self.Sd.dot(xp)
        self.c = self.Sc.dot(xp)
        self.g = self.Sg.dot(xp)
        self.s = self.Ss.dot(xp)

        # === Value of J-period risk-free bonds === #
        # === See p.145: Equation (7.11.2) === #
        e1 = np.zeros((1, self.nc))
        e1[0, 0] = 1
        self.R1_Price = np.empty((ts_length + 1, 1))
        self.R2_Price = np.empty((ts_length + 1, 1))
        self.R5_Price = np.empty((ts_length + 1, 1))
        for i in range(ts_length + 1):
            self.R1_Price[i, 0] = self.beta * e1.dot(self.Mc).dot(np.linalg.matrix_power(
                self.A0, 1)).dot(xp[:, i]) / e1.dot(self.Mc).dot(xp[:, i])
            self.R2_Price[i, 0] = self.beta**2 * e1.dot(self.Mc).dot(
                np.linalg.matrix_power(self.A0, 2)).dot(xp[:, i]) / e1.dot(self.Mc).dot(xp[:, i])
            self.R5_Price[i, 0] = self.beta**5 * e1.dot(self.Mc).dot(
                np.linalg.matrix_power(self.A0, 5)).dot(xp[:, i]) / e1.dot(self.Mc).dot(xp[:, i])

        # === Gross rates of return on 1-period risk-free bonds === #
        self.R1_Gross = 1 / self.R1_Price

        # === Net rates of return on J-period risk-free bonds === #
        # === See p.148: log of gross rate of return, divided by j === #
        self.R1_Net = np.log(1 / self.R1_Price) / 1
        self.R2_Net = np.log(1 / self.R2_Price) / 2
        self.R5_Net = np.log(1 / self.R5_Price) / 5

        # === Value of asset whose payout vector is Pay*xt === #
        # See p.145: Equation (7.11.1)
        if isinstance(Pay, np.ndarray) == True:
            self.Za = Pay.T.dot(self.Mc)
            self.Q = solve_discrete_lyapunov(
                self.A0.T * self.beta**0.5, self.Za)
            self.q = self.beta / (1 - self.beta) * \
                np.trace(self.C.T.dot(self.Q).dot(self.C))
            self.Pay_Price = np.empty((ts_length + 1, 1))
            self.Pay_Gross = np.empty((ts_length + 1, 1))
            self.Pay_Gross[0, 0] = np.nan
            for i in range(ts_length + 1):
                self.Pay_Price[i, 0] = (xp[:, i].T.dot(self.Q).dot(
                    xp[:, i]) + self.q) / e1.dot(self.Mc).dot(xp[:, i])
            for i in range(ts_length):
                self.Pay_Gross[i + 1, 0] = self.Pay_Price[i + 1,
                                                          0] / (self.Pay_Price[i, 0] - Pay.dot(xp[:, i]))
        return


Instruction:
Can you generate the documentation for the following Python 3 function
def irf(self, ts_length=100, shock=None):

        if type(shock) != np.ndarray:
            # Default is to select first element of w
            shock = np.vstack((np.ones((1, 1)), np.zeros((self.nw - 1, 1))))

        self.c_irf = np.empty((ts_length, self.nc))
        self.s_irf = np.empty((ts_length, self.nb))
        self.i_irf = np.empty((ts_length, self.ni))
        self.k_irf = np.empty((ts_length, self.nk))
        self.h_irf = np.empty((ts_length, self.nh))
        self.g_irf = np.empty((ts_length, self.ng))
        self.d_irf = np.empty((ts_length, self.nd))
        self.b_irf = np.empty((ts_length, self.nb))

        for i in range(ts_length):
            self.c_irf[i, :] = self.Sc.dot(
                np.linalg.matrix_power(self.A0, i)).dot(self.C).dot(shock).T
            self.s_irf[i, :] = self.Ss.dot(
                np.linalg.matrix_power(self.A0, i)).dot(self.C).dot(shock).T
            self.i_irf[i, :] = self.Si.dot(
                np.linalg.matrix_power(self.A0, i)).dot(self.C).dot(shock).T
            self.k_irf[i, :] = self.Sk.dot(
                np.linalg.matrix_power(self.A0, i)).dot(self.C).dot(shock).T
            self.h_irf[i, :] = self.Sh.dot(
                np.linalg.matrix_power(self.A0, i)).dot(self.C).dot(shock).T
            self.g_irf[i, :] = self.Sg.dot(
                np.linalg.matrix_power(self.A0, i)).dot(self.C).dot(shock).T
            self.d_irf[i, :] = self.Sd.dot(
                np.linalg.matrix_power(self.A0, i)).dot(self.C).dot(shock).T
            self.b_irf[i, :] = self.Sb.dot(
                np.linalg.matrix_power(self.A0, i)).dot(self.C).dot(shock).T

        return

Response: Calculates the IRF of the current set of IAFs for the current set of periods and shocks.


Instruction:
How would you explain what the following Python 3 function does
def canonical(self):
        Ac1 = np.hstack((self.deltah, np.zeros((self.nh, self.nz))))
        Ac2 = np.hstack((np.zeros((self.nz, self.nh)), self.a22))
        Ac = np.vstack((Ac1, Ac2))
        Bc = np.vstack((self.thetah, np.zeros((self.nz, self.nc))))
        Cc = np.vstack((np.zeros((self.nh, self.nw)), self.c2))
        Rc1 = np.hstack((self.llambda.T.dot(self.llambda), -
                         self.llambda.T.dot(self.ub)))
        Rc2 = np.hstack((-self.ub.T.dot(self.llambda), self.ub.T.dot(self.ub)))
        Rc = np.vstack((Rc1, Rc2))
        Qc = self.pih.T.dot(self.pih)
        Nc = np.hstack(
            (self.pih.T.dot(self.llambda), -self.pih.T.dot(self.ub)))

        lq_aux = LQ(Qc, Rc, Ac, Bc, N=Nc, beta=self.beta)

        P1, F1, d1 = lq_aux.stationary_values()

        self.F_b = F1[:, 0:self.nh]
        self.F_f = F1[:, self.nh:]

        self.pihat = np.linalg.cholesky(self.pih.T.dot(
            self.pih) + self.beta.dot(self.thetah.T).dot(P1[0:self.nh, 0:self.nh]).dot(self.thetah)).T
        self.llambdahat = self.pihat.dot(self.F_b)
        self.ubhat = - self.pihat.dot(self.F_f)

        return

Response: Compute the canonical preference representation of the current household technology.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def filtered_to_forecast(self):
        # === simplify notation === #
        A, C = self.ss.A, self.ss.C
        Q = np.dot(C, C.T)

        # === and then update === #
        self.x_hat = dot(A, self.x_hat)
        self.Sigma = dot(A, dot(self.Sigma, A.T)) + Q

Response:
Updates the moments of the time t filtering distribution to the moments of the predictive distribution which becomes the time
        t + 1 prior


Instruction:
Explain what the following Python 3 code does
def stationary_values(self, method='doubling'):

        # === simplify notation === #
        A, C, G, H = self.ss.A, self.ss.C, self.ss.G, self.ss.H
        Q, R = np.dot(C, C.T), np.dot(H, H.T)

        # === solve Riccati equation, obtain Kalman gain === #
        Sigma_infinity = solve_discrete_riccati(A.T, G.T, Q, R, method=method)
        temp1 = dot(dot(A, Sigma_infinity), G.T)
        temp2 = inv(dot(G, dot(Sigma_infinity, G.T)) + R)
        K_infinity = dot(temp1, temp2)

        # == record as attributes and return == #
        self._Sigma_infinity, self._K_infinity = Sigma_infinity, K_infinity
        return Sigma_infinity, K_infinity

Response: Computes the stationary values of the entry - time sets for the current entry - time set.


Instruction:
Implement a function in Python 3 to
find one mixed-action Nash equilibrium of a 2-player normal form game by the Lemke-Howson algorithm [2]_, implemented with "complementary pivoting" (see, e.g., von Stengel [3]_ for details). Parameters ---------- g : NormalFormGame NormalFormGame instance with 2 players. init_pivot : scalar(int), optional(default=0) Initial pivot, an integer k such that 0 <= k < m+n, where integers 0, ..., m-1 and m, ..., m+n-1 correspond to the actions of players 0 and 1, respectively. max_iter : scalar(int), optional(default=10**6) Maximum number of pivoting steps. capping : scalar(int), optional(default=None) If supplied, the routine is executed with the heuristics proposed by Codenotti et al. [1]_; see Notes below for details. full_output : bool, optional(default=False) If False, only the computed Nash equilibrium is returned. If True, the return value is `(NE, res)`, where `NE` is the Nash equilibrium and `res` is a `NashResult` object. Returns ------- NE : tuple(ndarray(float, ndim=1)) Tuple of computed Nash equilibrium mixed actions. res : NashResult Object containing information about the computation. Returned only when `full_output` is True. See `NashResult` for details. Examples -------- Consider the following game from von Stengel [3]_: >>> np.set_printoptions(precision=4) # Reduce the digits printed >>> bimatrix = [[(3, 3), (3, 2)], ... [(2, 2), (5, 6)], ... [(0, 3), (6, 1)]] >>> g = NormalFormGame(bimatrix) Obtain a Nash equilibrium of this game by `lemke_howson` with player 0's action 1 (out of the three actions 0, 1, and 2) as the initial pivot: >>> lemke_howson(g, init_pivot=1) (array([ 0. , 0.3333, 0.6667]), array([ 0.3333, 0.6667])) >>> g.is_nash(_) True Additional information is returned if `full_output` is set True: >>> NE, res = lemke_howson(g, init_pivot=1, full_output=True) >>> res.converged # Whether the routine has converged True >>> res.num_iter # Number of pivoting steps performed 4 Notes ----- * This routine is implemented with floating point arithmetic and thus is subject to numerical instability. * If `capping` is set to a positive integer, the routine is executed with the heuristics proposed by [1]_: * For k = `init_pivot`, `init_pivot` + 1, ..., `init_pivot` + (m+n-2), (modulo m+n), the Lemke-Howson algorithm is executed with k as the initial pivot and `capping` as the maximum number of pivoting steps. If the algorithm converges during this loop, then the Nash equilibrium found is returned. * Otherwise, the Lemke-Howson algorithm is executed with `init_pivot` + (m+n-1) (modulo m+n) as the initial pivot, with a limit `max_iter` on the total number of pivoting steps. Accoding to the simulation results for *uniformly random games*, for medium- to large-size games this heuristics outperforms the basic Lemke-Howson algorithm with a fixed initial pivot, where [1]_ suggests that `capping` be set to 10. References ---------- .. [1] B. Codenotti, S. De Rossi, and M. Pagan, "An Experimental Analysis of Lemke-Howson Algorithm," arXiv:0811.3247, 2008. .. [2] C. E. Lemke and J. T. Howson, "Equilibrium Points of Bimatrix Games," Journal of the Society for Industrial and Applied Mathematics (1964), 413-423. .. [3] B. von Stengel, "Equilibrium Computation for Two-Player Games in Strategic and Extensive Form," Chapter 3, N. Nisan, T. Roughgarden, E. Tardos, and V. Vazirani eds., Algorithmic Game Theory, 2007.

Response:
def lemke_howson(g, init_pivot=0, max_iter=10**6, capping=None,
                 full_output=False):
    """
    Find one mixed-action Nash equilibrium of a 2-player normal form
    game by the Lemke-Howson algorithm [2]_, implemented with
    "complementary pivoting" (see, e.g., von Stengel [3]_ for details).

    Parameters
    ----------
    g : NormalFormGame
        NormalFormGame instance with 2 players.

    init_pivot : scalar(int), optional(default=0)
        Initial pivot, an integer k such that 0 <= k < m+n, where
        integers 0, ..., m-1 and m, ..., m+n-1 correspond to the actions
        of players 0 and 1, respectively.

    max_iter : scalar(int), optional(default=10**6)
        Maximum number of pivoting steps.

    capping : scalar(int), optional(default=None)
        If supplied, the routine is executed with the heuristics
        proposed by Codenotti et al. [1]_; see Notes below for details.

    full_output : bool, optional(default=False)
        If False, only the computed Nash equilibrium is returned. If
        True, the return value is `(NE, res)`, where `NE` is the Nash
        equilibrium and `res` is a `NashResult` object.

    Returns
    -------
    NE : tuple(ndarray(float, ndim=1))
        Tuple of computed Nash equilibrium mixed actions.

    res : NashResult
        Object containing information about the computation. Returned
        only when `full_output` is True. See `NashResult` for details.

    Examples
    --------
    Consider the following game from von Stengel [3]_:

    >>> np.set_printoptions(precision=4)  # Reduce the digits printed
    >>> bimatrix = [[(3, 3), (3, 2)],
    ...             [(2, 2), (5, 6)],
    ...             [(0, 3), (6, 1)]]
    >>> g = NormalFormGame(bimatrix)

    Obtain a Nash equilibrium of this game by `lemke_howson` with player
    0's action 1 (out of the three actions 0, 1, and 2) as the initial
    pivot:

    >>> lemke_howson(g, init_pivot=1)
    (array([ 0.    ,  0.3333,  0.6667]), array([ 0.3333,  0.6667]))
    >>> g.is_nash(_)
    True

    Additional information is returned if `full_output` is set True:

    >>> NE, res = lemke_howson(g, init_pivot=1, full_output=True)
    >>> res.converged  # Whether the routine has converged
    True
    >>> res.num_iter  # Number of pivoting steps performed
    4

    Notes
    -----
    * This routine is implemented with floating point arithmetic and
      thus is subject to numerical instability.

    * If `capping` is set to a positive integer, the routine is executed
      with the heuristics proposed by [1]_:

      * For k = `init_pivot`, `init_pivot` + 1, ..., `init_pivot` +
        (m+n-2), (modulo m+n), the Lemke-Howson algorithm is executed
        with k as the initial pivot and `capping` as the maximum number
        of pivoting steps. If the algorithm converges during this loop,
        then the Nash equilibrium found is returned.

      * Otherwise, the Lemke-Howson algorithm is executed with
        `init_pivot` + (m+n-1) (modulo m+n) as the initial pivot, with a
        limit `max_iter` on the total number of pivoting steps.

      Accoding to the simulation results for *uniformly random games*,
      for medium- to large-size games this heuristics outperforms the
      basic Lemke-Howson algorithm with a fixed initial pivot, where
      [1]_ suggests that `capping` be set to 10.

    References
    ----------
    .. [1] B. Codenotti, S. De Rossi, and M. Pagan, "An Experimental
       Analysis of Lemke-Howson Algorithm," arXiv:0811.3247, 2008.

    .. [2] C. E. Lemke and J. T. Howson, "Equilibrium Points of Bimatrix
       Games," Journal of the Society for Industrial and Applied
       Mathematics (1964), 413-423.

    .. [3] B. von Stengel, "Equilibrium Computation for Two-Player Games
       in Strategic and Extensive Form," Chapter 3, N. Nisan, T.
       Roughgarden, E. Tardos, and V. Vazirani eds., Algorithmic Game
       Theory, 2007.

    """
    try:
        N = g.N
    except:
        raise TypeError('g must be a 2-player NormalFormGame')
    if N != 2:
        raise NotImplementedError('Implemented only for 2-player games')

    payoff_matrices = g.payoff_arrays
    nums_actions = g.nums_actions
    total_num = sum(nums_actions)

    msg = '`init_pivot` must be an integer k' + \
          'such that 0 <= k < {0}'.format(total_num)

    if not isinstance(init_pivot, numbers.Integral):
        raise TypeError(msg)

    if not (0 <= init_pivot < total_num):
        raise ValueError(msg)

    if capping is None:
        capping = max_iter

    tableaux = tuple(
        np.empty((nums_actions[1-i], total_num+1)) for i in range(N)
    )
    bases = tuple(np.empty(nums_actions[1-i], dtype=int) for i in range(N))

    converged, num_iter, init_pivot_used = \
        _lemke_howson_capping(payoff_matrices, tableaux, bases, init_pivot,
                              max_iter, capping)
    NE = _get_mixed_actions(tableaux, bases)

    if not full_output:
        return NE

    res = NashResult(NE=NE,
                     converged=converged,
                     num_iter=num_iter,
                     max_iter=max_iter,
                     init=init_pivot_used)

    return NE, res


Instruction:
Can you generate the documentation for the following Python 3 function
def _lemke_howson_capping(payoff_matrices, tableaux, bases, init_pivot,
                          max_iter, capping):
    """
    Execute the Lemke-Howson algorithm with the heuristics proposed by
    Codenotti et al.

    Parameters
    ----------
    payoff_matrices : tuple(ndarray(ndim=2))
        Tuple of two arrays representing payoff matrices, of shape
        (m, n) and (n, m), respectively.

    tableaux : tuple(ndarray(float, ndim=2))
        Tuple of two arrays to be used to store the tableaux, of shape
        (n, m+n+1) and (m, m+n+1), respectively. Modified in place.

    bases : tuple(ndarray(int, ndim=1))
        Tuple of two arrays to be used to store the bases, of shape (n,)
        and (m,), respectively. Modified in place.

    init_pivot : scalar(int)
        Integer k such that 0 <= k < m+n.

    max_iter : scalar(int)
        Maximum number of pivoting steps.

    capping : scalar(int)
        Value for capping. If set equal to `max_iter`, then the routine
        is equivalent to the standard Lemke-Howson algorithm.

    """
    m, n = tableaux[1].shape[0], tableaux[0].shape[0]
    init_pivot_curr = init_pivot
    max_iter_curr = max_iter
    total_num_iter = 0

    for k in range(m+n-1):
        capping_curr = min(max_iter_curr, capping)

        _initialize_tableaux(payoff_matrices, tableaux, bases)
        converged, num_iter = \
            _lemke_howson_tbl(tableaux, bases, init_pivot_curr, capping_curr)

        total_num_iter += num_iter

        if converged or total_num_iter >= max_iter:
            return converged, total_num_iter, init_pivot_curr

        init_pivot_curr += 1
        if init_pivot_curr >= m + n:
            init_pivot_curr -= m + n
        max_iter_curr -= num_iter

    _initialize_tableaux(payoff_matrices, tableaux, bases)
    converged, num_iter = \
        _lemke_howson_tbl(tableaux, bases, init_pivot_curr, max_iter_curr)
    total_num_iter += num_iter

    return converged, total_num_iter, init_pivot_curr

Response: Execute the Lemke - Howson algorithm with the heuristics proposed by the Codenotti et al.


Instruction:
Can you tell what is the following Python 3 function doing
def _initialize_tableaux(payoff_matrices, tableaux, bases):
    nums_actions = payoff_matrices[0].shape

    consts = np.zeros(2)  # To be added to payoffs if min <= 0
    for pl in range(2):
        min_ = payoff_matrices[pl].min()
        if min_ <= 0:
            consts[pl] = min_ * (-1) + 1

    for pl, (py_start, sl_start) in enumerate(zip((0, nums_actions[0]),
                                                  (nums_actions[0], 0))):
        for i in range(nums_actions[1-pl]):
            for j in range(nums_actions[pl]):
                tableaux[pl][i, py_start+j] = \
                    payoff_matrices[1-pl][i, j] + consts[1-pl]
            for j in range(nums_actions[1-pl]):
                if j == i:
                    tableaux[pl][i, sl_start+j] = 1
                else:
                    tableaux[pl][i, sl_start+j] = 0
            tableaux[pl][i, -1] = 1

        for i in range(nums_actions[1-pl]):
            bases[pl][i] = sl_start + i

    return tableaux, bases

Response: Initialize the basis and tableaux arrays in place.


Instruction:
Write a Python 3 script for
performing a pivoting step. Modify tableau in place.

Response:
def _pivoting(tableau, pivot, pivot_row):
    """
    Perform a pivoting step. Modify `tableau` in place.

    Parameters
    ----------
    tableau : ndarray(float, ndim=2)
        Array containing the tableau.

    pivot : scalar(int)
        Pivot.

    pivot_row : scalar(int)
        Pivot row index.

    Returns
    -------
    tableau : ndarray(float, ndim=2)
        View to `tableau`.

    """
    nrows, ncols = tableau.shape

    pivot_elt = tableau[pivot_row, pivot]
    for j in range(ncols):
        tableau[pivot_row, j] /= pivot_elt

    for i in range(nrows):
        if i == pivot_row:
            continue
        multiplier = tableau[i, pivot]
        if multiplier == 0:
            continue
        for j in range(ncols):
            tableau[i, j] -= tableau[pivot_row, j] * multiplier

    return tableau


Instruction:
How would you code a function in Python 3 to
extract mixed actions from tableaux and bases and return a tuple of the corresponding normalized mixed actions.

Response:
def _get_mixed_actions(tableaux, bases):
    """
    From `tableaux` and `bases`, extract non-slack basic variables and
    return a tuple of the corresponding, normalized mixed actions.

    Parameters
    ----------
    tableaux : tuple(ndarray(float, ndim=2))
        Tuple of two arrays containing the tableaux, of shape (n, m+n+1)
        and (m, m+n+1), respectively.

    bases : tuple(ndarray(int, ndim=1))
        Tuple of two arrays containing the bases, of shape (n,) and
        (m,), respectively.

    Returns
    -------
    tuple(ndarray(float, ndim=1))
        Tuple of mixed actions as given by the non-slack basic variables
        in the tableaux.

    """
    nums_actions = tableaux[1].shape[0], tableaux[0].shape[0]
    num = nums_actions[0] + nums_actions[1]
    out = np.zeros(num)

    for pl, (start, stop) in enumerate(zip((0, nums_actions[0]),
                                           (nums_actions[0], num))):
        sum_ = 0.
        for i in range(nums_actions[1-pl]):
            k = bases[pl][i]
            if start <= k < stop:
                out[k] = tableaux[pl][i, -1]
                sum_ += tableaux[pl][i, -1]
        if sum_ != 0:
            out[start:stop] /= sum_

    return out[:nums_actions[0]], out[nums_actions[0]:]


Instruction:
How would you explain what the following Python 3 function does
def var_quadratic_sum(A, C, H, beta, x0):
    # == Make sure that A, C, H and x0 are array_like == #

    A, C, H = list(map(np.atleast_2d, (A, C, H)))
    x0 = np.atleast_1d(x0)
    # == Start computations == #
    Q = scipy.linalg.solve_discrete_lyapunov(sqrt(beta) * A.T, H)
    cq = dot(dot(C.T, Q), C)
    v = np.trace(cq) * beta / (1 - beta)
    q0 = dot(dot(x0.T, Q), x0) + v

    return q0

Response: r Computes the expected discounted quadratic sum of A C H and x0.


Instruction:
How would you explain what the following Python 3 function does
def m_quadratic_sum(A, B, max_it=50):

    gamma1 = solve_discrete_lyapunov(A, B, max_it)

    return gamma1

Response: r Computes the quadratic sum of A and B.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def tauchen(rho, sigma_u, m=3, n=7):

    # standard deviation of y_t
    std_y = np.sqrt(sigma_u**2 / (1 - rho**2))

    # top of discrete state space
    x_max = m * std_y

    # bottom of discrete state space
    x_min = -x_max

    # discretized state space
    x = np.linspace(x_min, x_max, n)

    step = (x_max - x_min) / (n - 1)
    half_step = 0.5 * step
    P = np.empty((n, n))

    _fill_tauchen(x, P, n, rho, sigma_u, half_step)

    mc = MarkovChain(P, state_values=x)
    return mc

Response: r This function computes a linear Gaussian AR ( 1 ) process and returns a MarkovChain object that stores the transition matrix and state values of the next state.


Instruction:
Make a summary of the following Python 3 code
def nelder_mead(fun, x0, bounds=np.array([[], []]).T, args=(), tol_f=1e-10,
                tol_x=1e-10, max_iter=1000):
    """
    .. highlight:: none

    Maximize a scalar-valued function with one or more variables using the
    Nelder-Mead method.

    This function is JIT-compiled in `nopython` mode using Numba.

    Parameters
    ----------
    fun : callable
        The objective function to be maximized: `fun(x, *args) -> float`
        where x is an 1-D array with shape (n,) and args is a tuple of the
        fixed parameters needed to completely specify the function. This
        function must be JIT-compiled in `nopython` mode using Numba.

    x0 : ndarray(float, ndim=1)
        Initial guess. Array of real elements of size (n,), where ‘n’ is the
        number of independent variables.

    bounds: ndarray(float, ndim=2), optional
        Bounds for each variable for proposed solution, encoded as a sequence
        of (min, max) pairs for each element in x. The default option is used
        to specify no bounds on x.

    args : tuple, optional
        Extra arguments passed to the objective function.

    tol_f : scalar(float), optional(default=1e-10)
        Tolerance to be used for the function value convergence test.

    tol_x : scalar(float), optional(default=1e-10)
        Tolerance to be used for the function domain convergence test.

    max_iter : scalar(float), optional(default=1000)
        The maximum number of allowed iterations.

    Returns
    ----------
    results : namedtuple
        A namedtuple containing the following items:
        ::

            "x" : Approximate local maximizer
            "fun" : Approximate local maximum value
            "success" : 1 if the algorithm successfully terminated, 0 otherwise
            "nit" : Number of iterations
            "final_simplex" : Vertices of the final simplex

    Examples
    --------
    >>> @njit
    ... def rosenbrock(x):
    ...     return -(100 * (x[1] - x[0] ** 2) ** 2 + (1 - x[0])**2)
    ...
    >>> x0 = np.array([-2, 1])
    >>> qe.optimize.nelder_mead(rosenbrock, x0)
    results(x=array([0.99999814, 0.99999756]), fun=-1.6936258239463265e-10,
            success=True, nit=110,
            final_simplex=array([[0.99998652, 0.9999727],
                                 [1.00000218, 1.00000301],
                                 [0.99999814, 0.99999756]]))

    Notes
    --------
    This algorithm has a long history of successful use in applications, but it
    will usually be slower than an algorithm that uses first or second
    derivative information. In practice, it can have poor performance in
    high-dimensional problems and is not robust to minimizing complicated
    functions. Additionally, there currently is no complete theory describing
    when the algorithm will successfully converge to the minimum, or how fast
    it will if it does.

    References
    ----------

    .. [1] J. C. Lagarias, J. A. Reeds, M. H. Wright and P. E. Wright,
           Convergence Properties of the Nelder–Mead Simplex Method in Low
           Dimensions, SIAM. J. Optim. 9, 112–147 (1998).

    .. [2] S. Singer and S. Singer, Efficient implementation of the Nelder–Mead
           search algorithm, Appl. Numer. Anal. Comput. Math., vol. 1, no. 2,
           pp. 524–534, 2004.

    .. [3] J. A. Nelder and R. Mead, A simplex method for function
           minimization, Comput. J. 7, 308–313 (1965).

    .. [4] Gao, F. and Han, L., Implementing the Nelder-Mead simplex algorithm
           with adaptive parameters, Comput Optim Appl (2012) 51: 259.

    .. [5] http://www.scholarpedia.org/article/Nelder-Mead_algorithm

    .. [6] http://www.brnt.eu/phd/node10.html#SECTION00622200000000000000

    .. [7] Chase Coleman's tutorial on Nelder Mead

    .. [8] SciPy's Nelder-Mead implementation

    """
    vertices = _initialize_simplex(x0, bounds)

    results = _nelder_mead_algorithm(fun, vertices, bounds, args=args,
                                     tol_f=tol_f, tol_x=tol_x,
                                     max_iter=max_iter)

    return results

Response: Maximize a scalar - valued function with one or more independent variables using Nelder - Mead method.


Instruction:
Write a Python 3 script for
generating an initial simplex for the Nelder - Mead method using Numba.

Response:
def _initialize_simplex(x0, bounds):
    """
    Generates an initial simplex for the Nelder-Mead method. JIT-compiled in
    `nopython` mode using Numba.

    Parameters
    ----------
    x0 : ndarray(float, ndim=1)
        Initial guess. Array of real elements of size (n,), where ‘n’ is the
        number of independent variables.

    bounds: ndarray(float, ndim=2)
        Sequence of (min, max) pairs for each element in x0.

    Returns
    ----------
    vertices : ndarray(float, ndim=2)
        Initial simplex with shape (n+1, n).

    """
    n = x0.size

    vertices = np.empty((n + 1, n), dtype=np.float64)

    # Broadcast x0 on row dimension
    vertices[:] = x0

    nonzdelt = 0.05
    zdelt = 0.00025

    for i in range(n):
        # Generate candidate coordinate
        if vertices[i + 1, i] != 0.:
            vertices[i + 1, i] *= (1 + nonzdelt)
        else:
            vertices[i + 1, i] = zdelt

    return vertices


Instruction:
Make a summary of the following Python 3 code
def _check_params(ρ, χ, γ, σ, bounds, n):
    if ρ < 0:
        raise ValueError("ρ must be strictly greater than 0.")
    if χ < 1:
        raise ValueError("χ must be strictly greater than 1.")
    if χ < ρ:
        raise ValueError("χ must be strictly greater than ρ.")
    if γ < 0 or γ > 1:
        raise ValueError("γ must be strictly between 0 and 1.")
    if σ < 0 or σ > 1:
        raise ValueError("σ must be strictly between 0 and 1.")

    if not (bounds.shape == (0, 2) or bounds.shape == (n, 2)):
        raise ValueError("The shape of `bounds` is not valid.")
    if (np.atleast_2d(bounds)[:, 0] > np.atleast_2d(bounds)[:, 1]).any():
        raise ValueError("Lower bounds must be greater than upper bounds.")

Response: Checks whether the parameters for the Nelder - Mead algorithm are valid.


Instruction:
Can you write a function in Python 3 where it
checks whether x is within bounds. JIT - compiled in nopython mode uses Numba.

Response:
def _check_bounds(x, bounds):
    """
    Checks whether `x` is within `bounds`. JIT-compiled in `nopython` mode
    using Numba.

    Parameters
    ----------
    x : ndarray(float, ndim=1)
        1-D array with shape (n,) of independent variables.

    bounds: ndarray(float, ndim=2)
        Sequence of (min, max) pairs for each element in x.

    Returns
    ----------
    bool
        `True` if `x` is within `bounds`, `False` otherwise.

    """
    if bounds.shape == (0, 2):
        return True
    else:
        return ((np.atleast_2d(bounds)[:, 0] <= x).all() and
                (x <= np.atleast_2d(bounds)[:, 1]).all())


Instruction:
Can you write a function in Python 3 where it
wraps for bounding and taking the negative of fun for the base Nelder - Mead algorithm.

Response:
def _neg_bounded_fun(fun, bounds, x, args=()):
    """
    Wrapper for bounding and taking the negative of `fun` for the
    Nelder-Mead algorithm. JIT-compiled in `nopython` mode using Numba.

    Parameters
    ----------
    fun : callable
        The objective function to be minimized.
            `fun(x, *args) -> float`
        where x is an 1-D array with shape (n,) and args is a tuple of the
        fixed parameters needed to completely specify the function. This
        function must be JIT-compiled in `nopython` mode using Numba.

    bounds: ndarray(float, ndim=2)
        Sequence of (min, max) pairs for each element in x.

    x : ndarray(float, ndim=1)
        1-D array with shape (n,) of independent variables at which `fun` is
        to be evaluated.

    args : tuple, optional
        Extra arguments passed to the objective function.

    Returns
    ----------
    scalar
        `-fun(x, *args)` if x is within `bounds`, `np.inf` otherwise.

    """
    if _check_bounds(x, bounds):
        return -fun(x, *args)
    else:
        return np.inf