<commit_before>"""
Tools for repeated game.

"""

import numpy as np
from scipy.spatial import ConvexHull
from numba import jit, njit

class RepeatedGame:
    """
    Class representing an N-player repeated game.

    Parameters
    ----------
    stage_game : NormalFormGame
                 The stage game used to create the repeated game.

    delta : scalar(float)
            The common discount rate at which all players discount the future.

    """
    def __init__(self, stage_game, delta):
        self.sg = stage_game
        self.delta = delta
        self.N = stage_game.N
        self.nums_actions = stage_game.nums_actions

    def AS(self, tol=1e-12, max_iter=500, u=np.zeros(2)):
        """
        Using AS algorithm to compute the set of payoff pairs of all
        pure-strategy subgame-perfect equilibria with public randomization
        for any repeated two-player games with perfect monitoring and
        discounting, following Abreu and Sannikov (2014).

        Parameters
        ----------
        rpd : RepeatedGame
            Two player repeated game.

        tol : scalar(float), optional(default=1e-12)
            Tolerance for convergence checkinsg.

        max_iter : scalar(int), optional(default=500)
            Maximum number of iterations.

        u : ndarray(float, ndim=1), optional(default=np.zeros(2))
            The initial threat points.

        Returns
        -------
        hull : scipy.spatial.ConvexHull
            The convex hull of feasible payoff pairs.
        """
        sg, delta = self.sg, self.delta
        best_dev_gains = _best_dev_gains(sg, delta)
        C = np.empty((4, 2))
        IC = np.empty(2)
        action_profile_payoff = np.empty(2)
        # array for checking if payoff is inside the polytope or not
        # the last entry is set to be 1
        extended_payoff = np.ones(3)
        # array to store new points of C in each intersection
        # at most 4 new points will be generated
        new_pts = np.empty((4, 2))
        # array to store the points of W
        # the length of v is limited by |A1|*|A2|*4
        W_new = np.empty((np.prod(sg.nums_actions)*4, 2))
        W_old = np.empty((np.prod(sg.nums_actions)*4, 2))
        # count the new points generated in each iteration
        n_new_pt = 0

        # initialization
        payoff_pts = \
            sg.payoff_profile_array.reshape(np.prod(sg.nums_actions), 2)
        W_new[:np.prod(sg.nums_actions)] = payoff_pts
        n_new_pt = np.prod(sg.nums_actions)

        n_iter = 0
        while True:
            W_old[:n_new_pt] = W_new[:n_new_pt]
            n_old_pt = n_new_pt<commit_msg>FIX: solve the bug of cached keyword `u`.<commit_after>"""
Tools for repeated game.

"""

import numpy as np
from scipy.spatial import ConvexHull
from numba import jit, njit

class RepeatedGame:
    """
    Class representing an N-player repeated game.

    Parameters
    ----------
    stage_game : NormalFormGame
                 The stage game used to create the repeated game.

    delta : scalar(float)
            The common discount rate at which all players discount the future.

    """
    def __init__(self, stage_game, delta):
        self.sg = stage_game
        self.delta = delta
        self.N = stage_game.N
        self.nums_actions = stage_game.nums_actions

    def AS(self, tol=1e-12, max_iter=500, u_init=np.zeros(2)):
        """
        Using AS algorithm to compute the set of payoff pairs of all
        pure-strategy subgame-perfect equilibria with public randomization
        for any repeated two-player games with perfect monitoring and
        discounting, following Abreu and Sannikov (2014).

        Parameters
        ----------
        rpd : RepeatedGame
            Two player repeated game.

        tol : scalar(float), optional(default=1e-12)
            Tolerance for convergence checkinsg.

        max_iter : scalar(int), optional(default=500)
            Maximum number of iterations.

        u_init : ndarray(float, ndim=1), optional(default=np.zeros(2))
            The initial threat points.

        Returns
        -------
        hull : scipy.spatial.ConvexHull
            The convex hull of feasible payoff pairs.
        """
        sg, delta = self.sg, self.delta
        best_dev_gains = _best_dev_gains(sg, delta)
        C = np.empty((4, 2))
        IC = np.empty(2)
        action_profile_payoff = np.empty(2)
        # array for checking if payoff is inside the polytope or not
        # the last entry is set to be 1
        extended_payoff = np.ones(3)
        # array to store new points of C in each intersection
        # at most 4 new points will be generated
        new_pts = np.empty((4, 2))
        # array to store the points of W
        # the length of v is limited by |A1|*|A2|*4
        W_new = np.empty((np.prod(sg.nums_actions)*4, 2))
        W_old = np.empty((np.prod(sg.nums_actions)*4, 2))
        # count the new points generated in each iteration
        n_new_pt = 0

        # copy the threat points
        u = np.copy(u_init)

        # initialization
        payoff_pts = \
            sg.payoff_profile_array.reshape(np.prod(sg.nums_actions), 2)
        W_new[:np.prod(sg.nums_actions)] = payoff_pts
        n_new_pt = np.prod(sg.nums_actions)

        n_iter = 0
        while True:
            W_old[:n_new_pt] = W_new[:n_new_pt]
            n_old_pt = n_new_pt
{'fraction_non_alphanumeric': 0.09011843079200592, 'fraction_numerical': 0.014063656550703183, 'mean_word_length': 2.0348119034250423, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3297425', 'n_tokens_mistral': 1701, 'n_tokens_neox': 1613, 'n_words': 498}