Bertini 2 d882924 (2026-10-06 19:56 UTC)
Numerical algebraic geometry library (C++ core)
Loading...
Searching...
No Matches
derive.hpp File Reference

Seed-rooted, fully-specified random derivation (b2rand/1; ADR-0044; the structured-output-directory arc, rung 2). More...

Include dependency graph for derive.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

class  bertini::records::DrawStream
 A deterministic, fully-specified random stream (SHA-256 counter mode). More...

Namespaces

namespace  bertini
namespace  bertini::records

Functions

DrawStream & bertini::records::ThreadDrawStream ()
 This thread's pinned draw stream — the source of every identity-relevant random draw in bertini2.

Variables

constexpr char bertini::records::RandomDerivationVersion [] = "b2rand/1"
 The version tag of the draw-derivation scheme; bump on any algorithm change.

Detailed Description

Seed-rooted, fully-specified random derivation (b2rand/1; ADR-0044; the structured-output-directory arc, rung 2).

"Seed 42" is an identity: the same seed must produce the same draws forever — across runs, platforms, standard libraries, and Boost versions. std/boost random DISTRIBUTIONS carry no such contract (their algorithms are implementation- or release-dependent), so every identity-relevant draw in bertini2 routes through this stream instead: SHA-256 in counter mode (the already-vendored, FIPS-pinned hash), with draw algorithms specified exactly here and versioned as b2rand/1. Any change to a draw algorithm bumps the version — a new keyspace, never silent drift of what a seed means.

Stream keying preserves the existing domain separation (setup / per-path / worker streams; see random.hpp): a stream is keyed by SHA-256 over b2rand/1 || master seed || domain || index, each as 8 big-endian bytes; block i of the stream is SHA-256(key || i as 8 big-endian bytes).

Draw specifications (exact, forever):

  • Uint64: the next 8 unconsumed stream bytes, big-endian.
  • UnitDouble: (Uint64 >> 11) * 2^-53 — uniform on [0,1), exactly 53 bits.
  • SymmetricDouble: 2*UnitDouble() - 1 — uniform on [-1,1] (both ops exact).
  • Bits(n): the next ceil(n/8) stream bytes as a big-endian nonnegative integer, masked to n bits.
  • IntSymmetric(B): rejection sampling — with n = bit-length of 2B, draw v = Bits(n) until v <= 2B; return v - B. Uniform on [-B, B].
  • UnitRealMp(digits): k = ceil(digits * log2(10)) + 1 bits; value = ldexp(M, -k) where M = Bits(k), materialized at digits decimal digits of precision. The mpz→mpfr conversion and the power-of-two scaling are exact/correctly-rounded, so the value is bit-identical everywhere.