## ----setup, include = FALSE--------------------------------------------------- knitr::opts_chunk$set(collapse = TRUE, comment = "#>") library(rzig) compiler <- find_zig(required = FALSE) has_zig <- isTRUE(compiler$supported) ## ----create------------------------------------------------------------------- path <- file.path(tempdir(), "exportspkg") create_rzig_package(path, tests = FALSE) main_zig <- file.path(path, "src", "rzig", "src", "main.zig") ## ----options, comment = ""---------------------------------------------------- cat( "", "/// Shrink values towards zero.", "/// @param x A numeric vector.", "/// @param amount The amount to subtract from each absolute value.", "/// @default amount 0.5", "/// @return The shrunk values, invisibly.", "/// @export name=shrink invisible", "pub fn shrink_zig(ctx: *rzig.Ctx, x: []const f64, amount: f64) rzig.Error![]f64 {", " const out = try ctx.alloc(f64, x.len);", " for (x, out) |value, *slot| {", " const size = @max(@abs(value) - amount, 0);", " slot.* = if (value < 0) -size else size;", " }", " return out;", "}", sep = "\n", file = main_zig, append = TRUE ) ## ----internal, comment = ""--------------------------------------------------- cat( "", "/// The weighted mean, for weighted_mean().", "/// @export internal", "pub fn weighted_mean_zig(x: []const f64, w: []const f64) rzig.Error!f64 {", " if (x.len != w.len) return rzig.raise(\"x and w differ in length\", .{});", " var total: f64 = 0;", " var weights: f64 = 0;", " for (x, w) |value, weight| {", " total += value * weight;", " weights += weight;", " }", " return total / weights;", "}", sep = "\n", file = main_zig, append = TRUE ) writeLines(c( "#' The weighted mean", "#'", "#' @param x A numeric vector.", "#' @param w Non-negative weights of the same length.", "#' @return A number.", "#' @export", "weighted_mean <- function(x, w = rep(1, length(x))) {", " stopifnot(is.numeric(x), is.numeric(w), all(w >= 0))", " weighted_mean_zig(as.double(x), as.double(w))", "}" ), file.path(path, "R", "weighted.R")) ## ----class, comment = ""------------------------------------------------------ cat( "", "/// A running mean.", "/// @class", "pub const RunningMean = struct {", " total: f64 = 0,", " count: usize = 0,", "", " /// Create an empty running mean.", " pub fn init() RunningMean {", " return .{};", " }", "", " /// Add values.", " pub fn add(self: *RunningMean, values: []const f64) void {", " for (values) |value| self.total += value;", " self.count += values.len;", " }", "", " /// The mean of the values added so far.", " pub fn mean(self: *const RunningMean) f64 {", " return self.total / @as(f64, @floatFromInt(self.count));", " }", "};", sep = "\n", file = main_zig, append = TRUE ) ## ----scan--------------------------------------------------------------------- scan_exports(path) ## ----document----------------------------------------------------------------- bindings <- document(path) cat(bindings$wrappers) ## ----namespace---------------------------------------------------------------- cat("export(weighted_mean)\n", file = file.path(path, "NAMESPACE"), append = TRUE) cat(readLines(file.path(path, "NAMESPACE")), sep = "\n") ## ----build, eval = has_zig---------------------------------------------------- build <- build_zig(path) library(build$package, character.only = TRUE, lib.loc = build$library) shrink(c(-2, 0.2, 3)) print(shrink(c(-2, 0.2, 3), amount = 1)) weighted_mean(c(1, 2, 3), c(1, 1, 2)) exists("weighted_mean_zig", envir = asNamespace("exportspkg")) "weighted_mean_zig" %in% getNamespaceExports("exportspkg") m <- RunningMean() m$add(c(1, 2, 3)) m$add(10) m$mean() m ## ----cleanup, include = FALSE------------------------------------------------- if (has_zig) unloadNamespace("exportspkg") unlink(path, recursive = TRUE)