Skip to content

pblischak/zprob

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

77 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

zprob

A Zig Module for Probability Distributions

The zprob module implements functionality for working with probability distributions in Zig, including generating random samples and calculating probabilities using mass/density functions.

CI Status pages-build-deployment


Discrete Probability Distributions

Bernoulli :: Binomial :: Geometric :: Multinomial :: Negative Binomial :: Poisson

Continuous Probability Distributions

Beta :: Chi-squared :: Dirichlet :: Exponential :: Gamma :: Multivariate Normal (sampling only) :: Normal

Note zprob was developed and tested using v0.11.0 of Zig and is still a work in progress. Using a version of Zig other than 0.11.0 may lead to the code not compiling.

TODO:

A Fresh Start

To use zprob in a nice, fresh new Zig project, you can include it as a git submodule within a dedicated subfolder in you main project folder (e.g., libs/). Below is a simple example for how you could start such a project:

# Make new project folder with libs/ subfolder inside
mkdir -p my_zig_proj/libs

# Change into new project folder and initialize as a git repo
cd my_zig_proj/ && git init

# Initialize a new Zig command line application
zig init-exe

# Add zprob as a git submodule in the libs/ folder
git submodule add https://github.com/pblischak/zprob.git libs/zprob

To include zprob as a module to your new project, you'll only need to add two lines to the default build script:

const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    // ** 1. Here we define the zprob module and the path to the main file
    const zprob_module = b.addModule(
        "zprob",
        .{ .source_file = .{ .path = "libs/zprob/src/zprob.zig" } }
    );

    const exe = b.addExecutable(.{
        .name = "zprob_demo",
        .root_source_file = .{ .path = "src/main.zig" },
        .target = target,
        .optimize = optimize,
    });

    // ** 2. Here we add the zprob module to our executable
    exe.addModule("zprob", zprob_module);

    exe.install();
    const run_cmd = exe.run();

    run_cmd.step.dependOn(b.getInstallStep());

    if (b.args) |args| {
        run_cmd.addArgs(args);
    }

    const run_step = b.step("run", "Run the app");
    run_step.dependOn(&run_cmd.step);

    const exe_tests = b.addTest(.{
        .root_source_file = .{ .path = "src/main.zig" },
        .target = target,
        .optimize = optimize,
    });

    const test_step = b.step("test", "Run unit tests");
    test_step.dependOn(&exe_tests.step);
}

Now, inside the src/main.zig file in your project, you can import zprob like any other module:

const zprob = @import("zprob");

Examples

This repo contains a few simple examples of how to use the random sampling functionality implemented in zprob. To build the examples, clone the repo and run zig build examples:

git clone https://github.compblischak/zprob.git
cd zprob/
zig build examples

Each example file should compile into a binary executable with the same name in the zig-out/bin folder.

Pseudo-Random Number Generators

Using the current time in microseconds

  • How to use the random number generator in Zig
const std = @import("std");

const seed = @intCast(u64, std.time.microTimestamp());
var prng = std.rand.Xoshiro256.init(seed);
const rand = prng.random();

Using /dev/urandom

const std = @import("std");

var prng = std.rand.Xoshiro256.init(blk: {
    var seed: u64 = undefined;
    try std.os.getrandom(std.mem.asBytes(&seed));
    break :blk seed;
});

const rand = prng.random();

Acknowledgements

Code from the following repositories helped guide the development of zprob: