R/stream.R

Defines functions create_seedseq0 create_seedseq ironseed_stream

Documented in create_seedseq ironseed_stream

# MIT License
#
# Copyright (c) 2025 Reed A. Cartwright <racartwright@gmail.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

#' Ironseed output seed sequences
#'
#' @description
#'
#' Output sequences of 32-bit seeds are generated from an ironseed using
#' multilinear hashes. The coefficients for these hashes are generated by a
#' different Weyl sequence from the input hashes. A hash finalizer is also used
#' to mix bits and improve observed randomness.
#'
#' - `create_seedseq()` uses an ironseed to generate a sequence of 32-bit seeds.
#'
#' - `ironseed_stream()` returns a function that can be used to generate
#'   a seed sequence iteratively.
#'
#' @inheritParams ironseed
#' @param n a scalar integer specifying the number of seeds to generate
#' @param fe an ironseed
#'
#' @returns an integer vector containing 32-bit output seeds. If `n` is missing,
#' `ironseed_stream()` returns the underlying ironseed.
#'
#' @seealso [ironseed]
#'
#' @examples
#' # Generate 20 seeds from an ironseed
#' fe <- ironseed("Experiment", 20251031, 1, set_seed = FALSE)
#' create_seedseq(fe, 20)
#'
#' # Create a function that can be called multiple times to produce seeds
#' get_seeds <- ironseed_stream("Experiment", 20251031, 1)
#'
#' # generate 10 seeds
#' get_seeds(10)
#'
#' # generate 10 more seeds
#' get_seeds(10)
#'
#' # output the ironseed used for the stream
#' get_seeds()
#'
#' @export
ironseed_stream <- function(
  ...,
  methods = c("dots", "args", "env", "auto", "null")
) {
  fe <- ironseed(..., set_seed = NA, quiet = TRUE, methods = methods)
  k <- NULL
  function(n) {
    if (missing(n)) {
      return(fe)
    }
    n <- as.integer(n)
    z <- create_seedseq0(fe, n, k)
    k <<- attr(z, "k", exact = TRUE)
    c(z) # strip attributes
  }
}

#' @export
#' @rdname ironseed_stream
create_seedseq <- function(fe, n) {
  c(create_seedseq0(fe, n, NULL)) # strip attributes
}

create_seedseq0 <- function(fe, n, k = NULL) {
  fe <- as_ironseed(fe)
  n <- as.integer(n)
  stopifnot(length(unclass(fe)) == 8L)
  .Call(R_create_seedseq, fe, n, k)
}

Try the ironseed package in your browser

Any scripts or data that you put into this service are public.

ironseed documentation built on Aug. 21, 2025, 5:49 p.m.