]> gitweb.michael.orlitzky.com - dunshire.git/blobdiff - test/randomgen.py
Set MAX_COND to 100 in the randomgen module to facilitate random testing.
[dunshire.git] / test / randomgen.py
index afe0dae25304b33e2f01e3fd2cb46ca824cc8771..9fee2f749cbcf8037f2c64d41fe42e17731381a4 100644 (file)
@@ -9,7 +9,7 @@ from dunshire.cones import NonnegativeOrthant, IceCream
 from dunshire.games import SymmetricLinearGame
 from dunshire.matrices import (append_col, append_row, identity)
 
-MAX_COND = 250
+MAX_COND = 100
 """
 The maximum condition number of a randomly-generated game.
 """
@@ -23,12 +23,14 @@ properties within reason.
 
 def random_scalar():
     """
-    Generate a random scalar in ``[-RANDOM_MAX, RANDOM_MAX]``.
+    Generate a random scalar.
 
     Returns
     -------
 
     float
+        A random real number between ``-RANDOM_MAX`` and ``RANDOM_MAX``,
+        inclusive.
 
     Examples
     --------
@@ -42,12 +44,14 @@ def random_scalar():
 
 def random_nn_scalar():
     """
-    Generate a random nonnegative scalar in ``[0, RANDOM_MAX]``.
+    Generate a random nonnegative scalar.
 
     Returns
     -------
 
     float
+        A random nonnegative real number between zero and ``RANDOM_MAX``,
+        inclusive.
 
     Examples
     --------
@@ -61,13 +65,13 @@ def random_nn_scalar():
 
 def random_natural():
     """
-    Generate a random natural number between ``1 and RANDOM_MAX``
-    inclusive.
+    Generate a random natural number.
 
     Returns
     -------
 
     int
+        A random natural number between ``1`` and ``RANDOM_MAX`` inclusive.
 
     Examples
     --------
@@ -98,7 +102,7 @@ def random_matrix(row_count, column_count=None):
 
     matrix
         A new matrix whose entries are random floats chosen uniformly from
-        the interval [-RANDOM_MAX, RANDOM_MAX].
+        the interval ``[-RANDOM_MAX, RANDOM_MAX]``.
 
     Examples
     --------
@@ -263,7 +267,7 @@ def random_lyapunov_like_icecream(dims):
     matrix
         A new matrix, Lyapunov-like on the ice-cream cone in ``dims``
         dimensions, whose free entries are random floats chosen uniformly
-        from the interval [-RANDOM_MAX, RANDOM_MAX].
+        from the interval ``[-RANDOM_MAX, RANDOM_MAX]``.
 
     References
     ----------
@@ -297,17 +301,30 @@ def random_lyapunov_like_icecream(dims):
 
 def random_orthant_game():
     """
-    Generate the ``L``, ``K``, ``e1``, and ``e2`` parameters for a
-    random game over the nonnegative orthant, and return the
-    corresponding :class:`SymmetricLinearGame`.
+    Generate a random game over the nonnegative orthant.
+
+    We generate each of ``L``, ``K``, ``e1``, and ``e2`` randomly within
+    the constraints of the nonnegative orthant, and then construct a
+    game from them. The process is repeated until we generate a game with
+    a condition number under ``MAX_COND``.
+
+    Returns
+    -------
+
+    SymmetricLinearGame
+        A random game over some nonnegative orthant.
+
+    Examples
+    --------
+
+        >>> random_orthant_game()
+        <dunshire.games.SymmetricLinearGame object at 0x...>
 
-    We keep going until we generate a game with a condition number under
-    MAX_COND.
     """
     ambient_dim = random_natural() + 1
     K = NonnegativeOrthant(ambient_dim)
-    e1 = [random_nn_scalar() for _ in range(K.dimension())]
-    e2 = [random_nn_scalar() for _ in range(K.dimension())]
+    e1 = [0.1 + random_nn_scalar() for _ in range(K.dimension())]
+    e2 = [0.1 + random_nn_scalar() for _ in range(K.dimension())]
     L = random_matrix(K.dimension())
     G = SymmetricLinearGame(L, K, e1, e2)
 
@@ -319,12 +336,25 @@ def random_orthant_game():
 
 def random_icecream_game():
     """
-    Generate the ``L``, ``K``, ``e1``, and ``e2`` parameters for a
-    random game over the ice-cream cone, and return the corresponding
-    :class:`SymmetricLinearGame`.
+    Generate a random game over the ice-cream cone.
+
+    We generate each of ``L``, ``K``, ``e1``, and ``e2`` randomly within
+    the constraints of the ice-cream cone, and then construct a game
+    from them. The process is repeated until we generate a game with a
+    condition number under ``MAX_COND``.
+
+    Returns
+    -------
+
+    SymmetricLinearGame
+        A random game over some ice-cream cone.
+
+    Examples
+    --------
+
+        >>> random_icecream_game()
+        <dunshire.games.SymmetricLinearGame object at 0x...>
 
-    We keep going until we generate a game with a condition number under
-    MAX_COND.
     """
     # Use a minimum dimension of two to avoid divide-by-zero in
     # the fudge factor we make up later.
@@ -361,6 +391,20 @@ def random_ll_orthant_game():
     things are Lyapunov-like on the nonnegative orthant. That process is
     repeated until the condition number of the resulting game is within
     ``MAX_COND``.
+
+    Returns
+    -------
+
+    SymmetricLinearGame
+        A random game over some nonnegative orthant whose ``payoff`` method
+        is based on a Lyapunov-like ``L`` operator.
+
+    Examples
+    --------
+
+        >>> random_ll_orthant_game()
+        <dunshire.games.SymmetricLinearGame object at 0x...>
+
     """
     G = random_orthant_game()
     L = random_diagonal_matrix(G._K.dimension())
@@ -385,6 +429,20 @@ def random_ll_icecream_game():
     to have a :func:`random_lyapunov_like_icecream` operator. That
     process is repeated until the condition number of the resulting game
     is within ``MAX_COND``.
+
+    Returns
+    -------
+
+    SymmetricLinearGame
+        A random game over some ice-cream cone whose ``payoff`` method
+        is based on a Lyapunov-like ``L`` operator.
+
+    Examples
+    --------
+
+        >>> random_ll_icecream_game()
+        <dunshire.games.SymmetricLinearGame object at 0x...>
+
     """
     G = random_icecream_game()
     L = random_lyapunov_like_icecream(G._K.dimension())
@@ -410,6 +468,20 @@ def random_positive_orthant_game():
     to have a :func:`random_nonnegative_matrix` as its operator. That
     process is repeated until the condition number of the resulting game
     is within ``MAX_COND``.
+
+    Returns
+    -------
+
+    SymmetricLinearGame
+        A random game over some nonnegative orthant whose ``payoff`` method
+        is based on a positive ``L`` operator.
+
+    Examples
+    --------
+
+        >>> random_positive_orthant_game()
+        <dunshire.games.SymmetricLinearGame object at 0x...>
+
     """
 
     G = random_orthant_game()
@@ -431,17 +503,36 @@ def random_nn_scaling(G):
     """
     Scale the given game by a random nonnegative amount.
 
+    We re-attempt the scaling with a new random number until the
+    resulting scaled game has an acceptable condition number.
+
     Parameters
     ----------
 
-    G : :class:`SymmetricLinearGame`
+    G : SymmetricLinearGame
         The game that you would like to scale.
 
     Returns
     -------
-    (float, :class:`SymmetricLinearGame`)
+    (float, SymmetricLinearGame)
         A pair containing the both the scaling factor and the new scaled game.
 
+    Examples
+    --------
+
+        >>> from dunshire.matrices import norm
+        >>> from dunshire.options import ABS_TOL
+        >>> G = random_orthant_game()
+        >>> (alpha, H) = random_nn_scaling(G)
+        >>> alpha >= 0
+        True
+        >>> G._K == H._K
+        True
+        >>> norm(G._e1 - H._e1) < ABS_TOL
+        True
+        >>> norm(G._e2 - H._e2) < ABS_TOL
+        True
+
     """
     alpha = random_nn_scalar()
     H = SymmetricLinearGame(alpha*G._L.trans(), G._K, G._e1, G._e2)
@@ -458,18 +549,35 @@ def random_translation(G):
     """
     Translate the given game by a random amount.
 
+    We re-attempt the translation with new random scalars until the
+    resulting translated game has an acceptable condition number.
+
     Parameters
     ----------
 
-    G : :class:`SymmetricLinearGame`
+    G : SymmetricLinearGame
         The game that you would like to translate.
 
     Returns
     -------
-    (float, :class:`SymmetricLinearGame`)
+    (float, SymmetricLinearGame)
         A pair containing the both the translation distance and the new
         scaled game.
 
+    Examples
+    --------
+
+        >>> from dunshire.matrices import norm
+        >>> from dunshire.options import ABS_TOL
+        >>> G = random_orthant_game()
+        >>> (alpha, H) = random_translation(G)
+        >>> G._K == H._K
+        True
+        >>> norm(G._e1 - H._e1) < ABS_TOL
+        True
+        >>> norm(G._e2 - H._e2) < ABS_TOL
+        True
+
     """
     alpha = random_scalar()
     tensor_prod = G._e1 * G._e2.trans()