Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
""" Randomized tests of GiNaC / PyNaC """
############################################################################### # Sage: Open Source Mathematical Software # Copyright (C) 2008 William Stein <wstein@gmail.com> # Copyright (C) 2008 Burcin Erocal <burcin@erocal.org> # Distributed under the terms of the GNU General Public License (GPL), # version 2 or any later version. The full text of the GPL is available at: # http://www.gnu.org/licenses/ ###############################################################################
catalan, khinchin, twinprime, mertens)
################################################################### ### Generate random expressions for doctests ###################### ###################################################################
r""" A simple function that returns a list of all Pynac functions of known arity, sorted by name.
EXAMPLES::
sage: from sage.symbolic.random_tests import _mk_full_functions sage: [f for (one,f,arity) in _mk_full_functions()] # random [Ei, abs, arccos, arccosh, arccot, arccoth, arccsc, arccsch, arcsec, arcsech, arcsin, arcsinh, arctan, arctan2, arctanh, arg, beta, binomial, ceil, conjugate, cos, cosh, cot, coth, csc, csch, dickman_rho, dilog, dirac_delta, elliptic_e, elliptic_ec, elliptic_eu, elliptic_f, elliptic_kc, elliptic_pi, erf, exp, factorial, floor, heaviside, imag_part, integrate, kronecker_delta, log, polylog, real_part, sec, sech, sgn, sin, sinh, tan, tanh, unit_step, zeta, zetaderiv]
Note that this doctest will fail whenever a Pynac function is added or removed. In that case, it is very likely that the doctests for random_expr will fail as well. That's OK; just fix the doctest to match the new output. """ for (name, f) in items if hasattr(f, 'number_of_arguments') and f.number_of_arguments() > 0 and f != hypergeometric and f != cases]
# For creating simple expressions
# For creating expressions with the full power of Pynac's simple expression # subset (with no quantifiers/operators; that is, no derivatives, integrals, # etc.) [golden_ratio, log2, euler_gamma, catalan, khinchin, twinprime, mertens]] (0.2, full_functions)]
r""" INPUT:
- ``pl`` - A list of tuples, where the first element of each tuple is a floating-point number (representing a relative probability). The second element of each tuple may be a list or any other kind of object.
- ``extra`` - A tuple which is to be appended to every tuple in ``pl``.
This function takes such a list of tuples (a "probability list") and normalizes the probabilities so that they sum to one. If any of the values are lists, then those lists are first normalized; then the probabilities in the list are multiplied by the main probability and the sublist is merged with the main list.
For example, suppose we want to select between group A and group B with 50% probability each. Then within group A, we select A1 or A2 with 50% probability each (so the overall probability of selecting A1 is 25%); and within group B, we select B1, B2, or B3 with probabilities in a 1:2:2 ratio.
EXAMPLES::
sage: from sage.symbolic.random_tests import * sage: A = [(0.5, 'A1'), (0.5, 'A2')] sage: B = [(1, 'B1'), (2, 'B2'), (2, 'B3')] sage: top = [(50, A, 'Group A'), (50, B, 'Group B')] sage: normalize_prob_list(top) [(0.250000000000000, 'A1', 'Group A'), (0.250000000000000, 'A2', 'Group A'), (0.1, 'B1', 'Group B'), (0.2, 'B2', 'Group B'), (0.2, 'B3', 'Group B')] """ return pl else: else:
r""" INPUT:
- ``lst`` - A list of tuples, where the first element of each tuple is a nonnegative float (a probability), and the probabilities sum to one.
OUTPUT:
A tuple randomly selected from the list according to the given probabilities.
EXAMPLES::
sage: from sage.symbolic.random_tests import * sage: v = [(0.1, False), (0.9, True)] sage: choose_from_prob_list(v) (0.900000000000000, True) sage: true_count = 0 sage: for _ in range(10000): ....: if choose_from_prob_list(v)[1]: ....: true_count += 1 sage: true_count 9033 sage: true_count - (10000 * 9/10) 33 """
r""" Give a random list of length *length*, consisting of nonnegative integers that sum to *n*.
This is an approximation to IntegerVectors(n, length).random_element(). That gives values uniformly at random, but might be slow; this routine is not uniform, but should always be fast.
(This routine is uniform if *length* is 1 or 2; for longer vectors, we prefer approximately balanced vectors, where all the values are around `n/{length}`.)
EXAMPLES::
sage: from sage.symbolic.random_tests import * sage: random_integer_vector(100, 2) [11, 89] sage: random_integer_vector(100, 2) [51, 49] sage: random_integer_vector(100, 2) [4, 96] sage: random_integer_vector(10000, 20) [332, 529, 185, 738, 82, 964, 596, 892, 732, 134, 834, 765, 398, 608, 358, 300, 652, 249, 586, 66] """ return [] else:
r""" Produce a random symbolic expression of size *n_nodes* (or slightly larger). Internal nodes are selected from the *internal* probability list; leaves are selected from *leaves*. If *verbose* is True, then a message is printed before creating an internal node.
EXAMPLES::
sage: from sage.symbolic.random_tests import * sage: random_expr_helper(9, [(0.5, operator.add, 2), ....: (0.5, operator.neg, 1)], [(0.5, 1), (0.5, x)], True) About to apply <built-in function add> to [1, x] About to apply <built-in function add> to [x, x + 1] About to apply <built-in function neg> to [1] About to apply <built-in function neg> to [-1] About to apply <built-in function neg> to [1] About to apply <built-in function add> to [2*x + 1, -1] 2*x """ else:
internal=full_internal, nullary=full_nullary, nullary_frac=0.2, coeff_generator=QQ.random_element, verbose=False): r""" Produce a random symbolic expression of the given size. By default, the expression involves (at most) one variable, an arbitrary number of coefficients, and all of the symbolic functions and constants (from the probability lists full_internal and full_nullary). It is possible to adjust the ratio of leaves between symbolic constants, variables, and coefficients (var_frac gives the fraction of variables, and nullary_frac the fraction of symbolic constants; the remaining leaves are coefficients).
The actual mix of symbolic constants and internal nodes can be modified by specifying different probability lists.
To use a different type for coefficients, you can specify coeff_generator, which should be a function that will return a random coefficient every time it is called.
This function will often raise an error because it tries to create an erroneous expression (such as a division by zero).
EXAMPLES::
sage: from sage.symbolic.random_tests import * sage: set_random_seed(53) sage: random_expr(50, nvars=3, coeff_generator=CDF.random_element) # random (v1^(0.97134084277 + 0.195868299334*I)/csc(-pi + v1^2 + v3) + sgn(1/ ((-v3 - 0.760455994772 - 0.554367254855*I)*erf(v3 + 0.982759757946 - 0.0352136502348*I)) + binomial(arccoth(v1^pi), 0.760455994772 + 0.554367254855*I) + arccosh(2*v2 - (v2 + 0.841911550437 - 0.303757179824*I)/sinh_integral(pi) + arccoth(v3 + 0.530133230474 + 0.532140303485*I))))/v2 sage: random_expr(5, verbose=True) # random About to apply <built-in function inv> to [31] About to apply sgn to [v1] About to apply <built-in function add> to [1/31, sgn(v1)] sgn(v1) + 1/31
"""
################################################################### ### Test the ordering of operands ################################# ###################################################################
r""" Check that ``cmp_func`` is a strict weak order on the elements a,b,c.
A strict weak order is a binary relation ``<`` such that
* For all `x`, it is not the case that `x < x` (irreflexivity).
* For all `x\not=y`, if `x < y` then it is not the case that `y < x` (asymmetry).
* For all `x`, `y`, and `z`, if `x < y` and `y < z` then `x < z` (transitivity).
* For all `x`, `y`, and `z`, if x is incomparable with `y`, and `y` is incomparable with `z`, then `x` is incomparable with `z` (transitivity of incomparability).
INPUT:
- ``a``, ``b``, ``c`` -- anything that can be compared by ``cmp_func``.
- ``cmp_func`` -- function of two arguments that returns their comparison (i.e. either ``True`` or ``False``).
OUTPUT:
Does not return anything. Raises a ``ValueError`` if ``cmp_func`` is not a strict weak order on the three given elements.
REFERENCES:
:wikipedia:`Strict_weak_ordering`
EXAMPLES:
The usual ordering of integers is a strict weak order::
sage: from sage.symbolic.random_tests import assert_strict_weak_order sage: a, b, c = [randint(-10, 10) for i in range(3)] sage: assert_strict_weak_order(a, b, c, lambda x, y: x < y)
sage: x = [-SR(oo), SR(0), SR(oo)] sage: cmp_M = matrix(3, 3, 0) sage: for i in range(3): ....: for j in range(3): ....: if x[i] < x[j]: ....: cmp_M[i, j] = -1 ....: elif x[i] > x[j]: ....: cmp_M[i, j] = 1 sage: cmp_M [ 0 -1 -1] [ 1 0 -1] [ 1 1 0] """
# irreflexivity raise ValueError(msg)
# asymmetric raise ValueError(msg)
# transitivity raise ValueError(msg)
# transitivity of incomparability not incomparable(i, k)): raise ValueError(msg)
r""" Tests whether the comparison of random symbolic expressions satisfies the strict weak order axioms.
This is important because the C++ extension class uses ``std::sort()`` which requires a strict weak order. See also :trac:`9880`.
EXAMPLES::
sage: from sage.symbolic.random_tests import test_symbolic_expression_order sage: test_symbolic_expression_order(200) sage: test_symbolic_expression_order(10000) # long time """
rnd_length, nvars=nvars, ncoeffs=ncoeffs, var_frac=var_frac, nullary_frac=nullary_frac, coeff_generator=coeff_generator, internal=fast_nodes) except (ZeroDivisionError, ValueError): pass
|