Source code for bertini.random

import numpy as _np

from bertini._pybertini import random as _pybrand
from bertini._pybertini.random import *


[docs] def random_real(symbolic=False): """A random real number of bounded modulus, at the current default precision. Box-uniform in ``[-1, 1]`` and pulled away from 0 -- the Bertini genericity draw. Reproducible via :func:`set_random_seed`. Parameters ---------- symbolic : bool, default False When False (default) return a numeric ``multiprec.real_mp`` value. When True return a constant function-tree *node* (a real :class:`~bertini.symbolics.Complex` leaf, imaginary part 0) ready to drop straight into an expression -- the spelling to reach for when you want a random coefficient rather than a random value. ``bertini.symbolics.random_real`` is the always-symbolic shortcut. Notes ----- The node carries exactly the digits drawn, i.e. the current default precision -- set ``bertini.default_precision(1000)`` first for a 1000-digit constant. (A random float can be no more precise than its draw; for a *precision-independent* exact random constant use ``bertini.symbolics.Rational.rand_real`` instead.) """ v = _pybrand.random_real() if symbolic: from bertini._coefficients import coefficient return coefficient(v) return v
[docs] def random_complex(symbolic=False): """A random complex number of bounded modulus, at the current default precision. Modulus pulled toward 1 (away from 0 and infinity) -- the Bertini genericity draw. Reproducible via :func:`set_random_seed`. Parameters ---------- symbolic : bool, default False When False (default) return a numeric ``multiprec.complex_mp`` value. When True return a constant function-tree *node* (a :class:`~bertini.symbolics.Complex` leaf) ready to drop straight into an expression. ``bertini.symbolics.random_complex`` is the always-symbolic shortcut. Notes ----- The node carries exactly the digits drawn, i.e. the current default precision -- set ``bertini.default_precision(1000)`` first for a 1000-digit constant. For a *precision-independent* exact random constant use ``bertini.symbolics.Rational.rand`` instead. """ v = _pybrand.random_complex() if symbolic: from bertini._coefficients import coefficient return coefficient(v) return v
[docs] def random_vector(size, real=False, symbolic=False): """A random length-``size`` vector of bounded-modulus numbers, at the current default precision. The natural random projection / linear-functional coefficient vector (generic and seed-reproducible, unlike the quantized orthonormal :func:`random_matrix`). Parameters ---------- size : int The length of the vector. real : bool, default False When True the entries are real (``real_mp``); otherwise complex (``complex_mp``). symbolic : bool, default False When True return a numpy object array of constant coefficient *nodes* (via :func:`bertini.coefficients`) rather than numeric multiprecision values -- each entry a :class:`~bertini.symbolics.Complex` leaf. Notes ----- As for :func:`random_real`, a symbolic entry carries the current default precision's worth of digits; set ``bertini.default_precision`` first if you need more. """ v = _pybrand.random_vector(size, real) if symbolic: from bertini._coefficients import coefficients return coefficients(v) return v
[docs] def random_matrix(rows, cols, real=False, units=False, orthonormal=True, symbolic=False): """A ``rows`` x ``cols`` random matrix, at the current default precision. The building block for a random linear form / projection / slice / patch -- they are all just linear functions, and "what you use them for is up to you." Returns a numpy array of arbitrary-precision values (``bertini.multiprec.Complex``); pass ``symbolic=True`` to instead get coefficient *nodes* ready to drop straight into function-tree expressions. Parameters ---------- rows, cols : int The shape of the matrix. real : bool, default False When True the entries are real (zero imaginary part); otherwise complex. units : bool, default False When True (and not ``orthonormal``) each entry has modulus 1 (a ``real`` unit is +/-1); otherwise each entry is drawn with bounded modulus (box-uniform in [-1,1] per component). orthonormal : bool, default True When True the rows are conjugate-orthonormal (QR-factored from a square matrix of units, then truncated -- perfectly conditioned). ``real=True`` gives a real orthogonal matrix. ``orthonormal`` takes precedence over ``units`` (orthonormal rows are already normalized). symbolic : bool, default False When True, return a numpy object array of coefficient *nodes* (via :func:`bertini.coefficients`); otherwise numeric ``multiprec.complex_mp``. Notes ----- Reproducible via :func:`bertini.random.set_random_seed`. A projection is just a linear functional with zero constant term, so its gradient row is exactly ``random_matrix(1, n)``. For a **generic real** direction (e.g. a real projection), prefer :func:`bertini.random_vector` with ``real=True``: a real *orthonormal* matrix is QR-factored from a matrix of real units (+/-1), so its entries are **quantized** (a real ``random_matrix(3, 1)`` has entries +/-1/sqrt(3)) and look seed-independent -- fine for conditioning, but not a generic direction. ``random_vector`` draws continuous bounded-modulus reals instead (generic and seed-reproducible). """ if orthonormal: M = _np.array(_pybrand.conjugate_orthonormal_matrix(rows, cols, real)) else: if units: draw = _pybrand.real_unit if real else _pybrand.complex_unit else: draw = _pybrand.real_bounded_modulus if real else _pybrand.complex_bounded_modulus M = _np.array([[draw() for _ in range(cols)] for _ in range(rows)], dtype=object) # eigenpy collapses a single-row matrix to 1-D; keep the (rows, cols) shape predictable. M = M.reshape(rows, cols) if symbolic: from bertini._coefficients import coefficients return coefficients(M) return M
__all__ = dir(_pybrand) + ['random_matrix']