SlicTranspilerStanBlocks → Stan
Spotlight
StanBlocks.jl ↗

SLIC Library

Runnable starter sources, documentation examples, and stable links in one place.

✓ ok 63 runnable now✓ ok all linked bundles classified• ready 16 pinned source references
Model spotlightfrom a first regression to a population PK model

Six models in order of ambition — open any rung to edit it and watch it transpile to Stan.

  1. Linear regression✓ ok runnable

    The whole shape of a SLIC model in four lines: priors, a linear predictor, one Gaussian likelihood.

  2. Hierarchical radon✓ ok runnable

    Partial pooling — an index vector and a group-level prior tie many small groups into one model.

  3. A Gaussian process via Hilbert-space basis functions, with the observation noise its own second GP. Based on a model by Aki Vehtari.

  4. The full gpbf8rhs model: trend and periodic GPs, time-varying weekday effects, 366 horseshoe-shrunk day effects, and holiday overrides. Based on a model by Aki Vehtari.

  5. A nonlinear population model: an eight-state two-compartment PK/neutropenia ODE, correlated PK and PD variability, solver dispatch, and proportional concentration/neutrophil likelihoods. Based on a model by Casey Davis (stanpmx).

  6. The final rung: the full structured SLIC port of n-kall/sealIPM. One year-recursive state process feeds eight observation streams through Form-A submodels, custom likelihood families with explicit predictive totals, and ODE hunting dynamics.

Case studies

9 runnable · 11 linked
Birthdays (HSGP + regularized horseshoe)Bundle
✓ ok runnable

The largest Birthday model, assembled from reusable submodels: an exponentiated-quadratic Hilbert-space GP (hsgp_eq, reused for the long-term trend and the GP-modulated weekday effect), a periodic HSGP (hsgp_periodic) for the seasonal term, and a regularized-horseshoe prior (reg_horseshoe) for the 366 day effects, plus holiday overrides and compiler-generated predictive draws with pointwise log likelihood. The earlier additive HSGP remains as a stepping-stone model in this bundle.

Population PK/PD (two-compartment Friberg)Bundle
✓ ok runnable

The StanPMX two-compartment Friberg model adapted to native Stan ODEs: full-covariance PK and PD variability, proportional truncated likelihoods, an eight-state PK/neutropenia system, and a solver supplied as a compile-time data function. Population prediction should rebind this same source through CV taint rather than duplicate the subject model; that workspace control is planned. The earlier analytic PK model remains as a stepping stone.

Grey-seal integrated population modelBundle
✓ ok runnable

Runnable structured SLIC port: one compute-once state process, ODE hunting dynamics, and eight observation streams. Multinomial predictive totals are explicit family inputs; the ODE calls use the reference package's literal solver defaults.

Starter sources

Curated runnable models and functions. Public saving is disabled.

Models (4)

linear_regression@e49a88Load ▸
View complete source
K = dims(X)[2]
alpha ~ normal(0, 10)
beta::vector[K] ~ normal(0, 5)
sigma ~ exponential(1)
y ~ normal(alpha + X * beta, sigma)
varying_intercept@00dd73Load ▸
View complete source
mu_a ~ normal(0, 5)
sigma_a ~ exponential(1)
sigma_y ~ exponential(1)
alpha::vector[J] ~ normal(mu_a, sigma_a)
y ~ normal(alpha[county], sigma_y)
poisson_glm@c6c1d5Load ▸
View complete source
beta ~ normal(0, 1)
alpha ~ normal(0, 5)
y ~ poisson_log(alpha + beta * x)
l2_scaled_prior@3de720Load ▸
View complete source
sigma ~ exponential(1)
scale = l2_norm(y)
mu ~ normal(0, scale)
y ~ normal(mu, sigma)

Functions (5)

sq@df8507Load ▸
View complete source
sq(x::vector[n]) = begin
  out = rep_vector(0., n)
  for i in 1:n
    out[i] = x[i]^2
  end
  out
end
cube@1d028bLoad ▸
View complete source
cube(x::real) = x^3
l2_norm@335e9cLoad ▸
View complete source
l2_norm(x::vector[n])::real = sqrt(sum(x .* x))
standardize@6a47aeLoad ▸
View complete source
standardize(x::vector[n]) = (x - mean(x)) / sd(x)
softplus@9ef256Load ▸
View complete source
softplus(x::real)::real = log1p(exp(x))

Worked examples

2 runnable · 7 linked
Disk constraintsBundle
✓ ok runnable

The historical zero-density transform is preserved with explicit structured distribution metadata; StanBlocks’ built-in dummy family keeps the prior live.

Simplex constraintsReference

∅ unavailable — source excerpt only

Reference only: the generated family combines signature-only stubs, same-name overloads and compile-time function tokens that reusable public cards cannot import or disambiguate.

Crowdsource model familyReference

∅ unavailable — source excerpt only

Reference only: the nineteen-model family depends on higher-order function tokens, overload groups and generated Base.merge variants that reusable public cards cannot import or disambiguate.

Historical SLIC overviewReference

∅ unavailable — source excerpt only

Historical source includes intentionally superseded syntax.

StanCon 2026

7 runnable · 9 linked
Named random-slope submodelBundle
✓ ok runnable

A named SLIC submodel and its parent model share one isolated tracing module.

Wide-prior model variantBundle
✓ ok runnable

The slide's Base.merge rewrite is resolved into wide-prior and base-model entrypoints so both remain plain editable SLIC.

Parameter-generating plate cellReference

∅ unavailable — source excerpt only

The slide intentionally shows a fragment whose captured sigma is declared outside the excerpt.

Composed observation semanticsReference

∅ unavailable — source excerpt only

The slide is a compact fragment. Open authoring/observation-combinators for the complete runnable model.

Main guide

7 runnable · 11 linked
Multi-stratum Cholesky priorReference

∅ unavailable — source excerpt only

The excerpt depends on caller-provided n_strata and n_terms.

GARCH(1,1)Reference

∅ unavailable — source excerpt only

Reference only: the linked excerpt defines only garch11_lpdf; a runnable local distribution also needs explicit pointwise/RNG bodies and trusted @lhs/@lpxf registration (snag compile-slic-bun-4bc9aa10).

BRM-style composition patternsReference

∅ unavailable — source excerpt only

Reference only: this bibliography excerpt points into the separate BRM DSL and demonstrates anonymous submodels plus trusted custom-distribution macros.

Authoring guide

6 runnable · 7 linked

Feature atlas

32 runnable · 34 linked
Data rebinding Bernoulli modelModel
✓ ok runnable

The editor opens the final data shape; the docs also demonstrate rebinding a traced model.

Cross-validation taintModel
✓ ok runnable

The runnable editor shows the base model. The docs additionally rebind person with maybecv.

Anonymous submodelBundle
✓ ok runnable

The anonymous dependency keeps its exact free-name keyword capture and hygienic per-LHS parameters.

Named submodel dispatchBundle
✓ ok runnable

Two typed named submodels and their parent compile in one isolated tracing module.

Post-hoc model variantsBundle
✓ ok runnable

Base.merge results are resolved into three plain-SLIC entrypoints: wide prior, base prior and a fixed-beta likelihood.

Iteration function suiteBundle
✓ ok runnable

Four deterministic UDFs exercise value iteration, enumerate, zip and a two-axis comprehension.

Defaults and keyword argumentsBundle
✓ ok runnable

Positional defaults and required/optional keyword arguments are resolved at the call site.

Variadic and function-typed dispatchReference

∅ unavailable — source excerpt only

Reference only: the exact example imports compile-time function tokens and defines same-name overloads/varargs, while reusable public workspace cards currently have unique names and no import surface.

Caller macro expansionReference

∅ unavailable — source excerpt only

Public authoring rejects macros by design; a curated trusted bundle could pre-expand it.

Inline mutation helpersBundle
✓ ok runnable

The macro-free marker comment is validated and lowered to StanBlocks’ trusted inline metadata inside the worker.

Runtime assertion helperBundle
✓ ok runnable

The macro-free assertion comment becomes validated structured metadata; no user macro reaches expansion.

Transpile-time return type queryBundle
✓ ok runnable

The workspace-local return_type_of binding resolves the registered element helper while preserving the exact pinned source spelling.

Dual Julia and Stan emissionBundle
✓ ok runnable

The same deterministic affine definition has a bounded Julia method and emits into Stan when the model calls it.

Custom distribution triadBundle
✓ ok runnable

The density marker comment lowers to validated :lhs/:lpxf metadata; pointwise density and RNG remain ordinary dependency cards.

PK ODE function and modelBundle
✓ ok runnable

A typed ODE right-hand side and the consuming one-compartment model compile together.

Immutable, provenance-bearing Stan utility collection

Helpful Stan Functions Library

28 functions are ready to load and transpile. Every one is pinned to upstream revision 583d31de52e8, keeps its source credit, and is distributed under BSD-3-Clause.

The full 66-callable audit stays visible below: support gaps and unsuitable test helpers are recorded rather than omitted.

Upstream repository ↗

Array operations (1)

in_order@6c7333Load ▸

int in_order(array[] real theta)

Credit: Ben Goodrich, 2020

SLIC adaptation: Uses SLIC vector[K], Stan's compact representation of array[] real.

Pinned upstream source ↗
View complete source
in_order(theta::vector[K])::int = begin
    if theta[1] == negative_infinity()
        reject("first element must be finite")
    end
    for k in 2:K
        if theta[k] <= theta[k - 1]
            reject("bounds and quantiles are not in the right order")
        end
    end
    1
end

Copulas (7)

clayton_copula_lpdf@df940dLoad ▸

real clayton_copula_lpdf(real u, real v, real theta)

Credit: Andre Pfeuffer and Sean Pinkney

Pinned upstream source ↗
View complete source
clayton_copula_lpdf(u::real, v::real, theta::real)::real = begin
    if theta <= 0.0
        reject("clayton_copula: theta must > 0")
    end
    log1p(theta) - (theta + 1) * (log(u) + log(v)) -
        (1 + 2 * theta) / theta * log(u^(-theta) + v^(-theta) - 1)
end
frank_copula_lpdf@f2e750Load ▸

real frank_copula_lpdf(vector u, vector v, real theta)

Credit: Sean Pinkney

Pinned upstream source ↗
View complete source
frank_copula_lpdf(u::vector[N], v::vector[N], theta::real)::real = begin
    log_lik = 0.0
    if theta < 0
        log_lik = N * log(theta * (1 - exp(-theta))) - theta * sum(append_col(u, v)) -
            sum(log((-expm1(-theta) .- expm1(-theta .* u) .* expm1(-theta .* v)) .^ 2))
    else
        log_lik = N * (log(theta) + log1m_exp(-theta)) - theta * sum(append_col(u, v)) -
            2 * sum(log(-expm1(-theta) .- expm1(-theta .* u) .* expm1(-theta .* v)))
    end
    log_lik
end
gumbel_copula_lpdf@5f5d24Load ▸

real gumbel_copula_lpdf(real u, real v, real theta)

Credit: Ben Goodrich

Pinned upstream source ↗
View complete source
gumbel_copula_lpdf(u::real, v::real, theta::real)::real = begin
    neg_log_u = -log(u)
    log_neg_log_u = log(neg_log_u)
    neg_log_v = -log(v)
    log_neg_log_v = log(neg_log_v)
    log_temp = log_sum_exp(theta * log_neg_log_u, theta * log_neg_log_v)
    theta_m1 = theta - 1
    if theta < 1
        reject("theta must be >= 1")
    end
    out = 0.0
    if is_inf(theta)
        out = u == v ? 0.0 : negative_infinity()
    else
        out = theta_m1 * log_neg_log_u + theta_m1 * log_neg_log_v + neg_log_u + neg_log_v -
            exp(log_temp / theta) + log_sum_exp(2 * theta_m1 / -theta * log_temp,
                log(theta_m1) + (1 - 2 * theta) / theta * log_temp)
    end
    out
end
normal_copula_lpdf@ebba68Load ▸

real normal_copula_lpdf(real u, real v, real rho)

Credit: Andre Pfeuffer and Sean Pinkney

Pinned upstream source ↗
View complete source
normal_copula_lpdf(u::real, v::real, rho::real)::real = begin
    rho_sq = square(rho)
    (0.5 * rho * (-2.0 * u * v + square(u) * rho + square(v) * rho)) /
        (-1.0 + rho_sq) - 0.5 * log1m(rho_sq)
end
normal_copula_vector_lpdf@fd2cdcLoad ▸

real normal_copula_vector_lpdf(vector u, vector v, real rho)

Credit: Sean Pinkney

SLIC adaptation: Uses dot_product(u, v), equivalent to the upstream u' * v expression.

Pinned upstream source ↗
View complete source
normal_copula_vector_lpdf(u::vector[N], v::vector[N], rho::real)::real = begin
    rho_sq = square(rho)
    a1 = 0.5 * rho
    a2 = rho_sq - 1
    a3 = 0.5 * log1m(rho_sq)
    x = -2 * dot_product(u, v) + rho * (dot_self(u) + dot_self(v))
    a1 * x / a2 - N * a3
end
bivariate_normal_copula_cdf@883982Load ▸

real bivariate_normal_copula_cdf(real u, real v, real rho)

Credit: Sean Pinkney, 2021

SLIC adaptation: Uses (u + v) / 2 for upstream mean([u, v]) and comma-separated recursive arguments.

Pinned upstream source ↗
View complete source
bivariate_normal_copula_cdf(u::real, v::real, rho::real)::real = begin
    a = 1 / sqrt(1 - square(rho))
    avg_uv = (u + v) / 2
    pu = inv_Phi(u)
    pv = inv_Phi(v)
    alpha_u = a * (pv / pu - rho)
    alpha_v = a * (pu / pv - rho)
    d = 0.0
    if v == 0.5 || (u == 0.5 && v != u)
        x = u == 0.5 ? v : u
        if rho < 0
            return 0.5 * bivariate_normal_copula_cdf(x, x, 1 - 2 * rho^2)
        else
            return u - 0.5 * bivariate_normal_copula_cdf(x, x, 1 - 2 * rho^2)
        end
    end
    if v == u
        return u - 2 * owens_t(inv_Phi(u), sqrt((1 - rho) / (1 + rho)))
    end
    if (u < 0.5 && v >= 0.5) || (u >= 0.5 && v < 0.5)
        d = 0.5
    end
    avg_uv - owens_t(pu, alpha_u) - owens_t(pv, alpha_v) - d
end
multi_normal_cholesky_copula_lpdf@c859b3Load ▸

real multi_normal_cholesky_copula_lpdf(matrix U, matrix L)

Credit: Ethan Alt and Sean Pinkney

Pinned upstream source ↗
View complete source
multi_normal_cholesky_copula_lpdf(U::matrix[N,J], L::matrix[J,J])::real = begin
    Gammainv = chol2inv(L)
    -N * sum(log(diagonal(L))) - 0.5 * sum(add_diag(Gammainv, -1.0) .* crossprod(U))
end

Distributions (12)

gpareto_lpdf@a53459Load ▸

real gpareto_lpdf(vector y, real ymin, real k, real sigma)

Credit: Aki Vehtari

Pinned upstream source ↗
View complete source
gpareto_lpdf(y::vector[N], ymin::real, k::real, sigma::real)::real = begin
    inv_k = inv(k)
    if k < 0 && max(y .- ymin) / sigma > -inv_k
        reject("k < 0 and max(y - ymin) / sigma > -1 / k; found k, sigma = ", k, sigma)
    end
    if sigma <= 0
        reject("sigma <= 0; found sigma = ", sigma)
    end
    abs(k) > 1e-15 ? -(1 + inv_k) * sum(log1p((y .- ymin) .* (k / sigma))) -
        N * log(sigma) : -sum(y .- ymin) / sigma - N * log(sigma)
end
gpareto_cdf@02d70eLoad ▸

real gpareto_cdf(vector y, real ymin, real k, real sigma)

Credit: Aki Vehtari

Pinned upstream source ↗
View complete source
gpareto_cdf(y::vector[N], ymin::real, k::real, sigma::real)::real = begin
    inv_k = inv(k)
    if k < 0 && max(y .- ymin) / sigma > -inv_k
        reject("k < 0 and max(y - ymin) / sigma > -1 / k; found k, sigma = ", k, sigma)
    end
    if sigma <= 0
        reject("sigma <= 0; found sigma = ", sigma)
    end
    abs(k) > 1e-15 ? exp(sum(log1m_exp((-inv_k) .* log1p((y .- ymin) .* (k / sigma))))) :
        exp(sum(log1m_exp(-(y .- ymin) ./ sigma)))
end
gpareto_lcdf@3ac210Load ▸

real gpareto_lcdf(vector y, real ymin, real k, real sigma)

Credit: Aki Vehtari

Pinned upstream source ↗
View complete source
gpareto_lcdf(y::vector[N], ymin::real, k::real, sigma::real)::real = begin
    inv_k = inv(k)
    if k < 0 && max(y .- ymin) / sigma > -inv_k
        reject("k < 0 and max(y - ymin) / sigma > -1 / k; found k, sigma = ", k, sigma)
    end
    if sigma <= 0
        reject("sigma <= 0; found sigma = ", sigma)
    end
    abs(k) > 1e-15 ? sum(log1m_exp((-inv_k) .* log1p((y .- ymin) .* (k / sigma)))) :
        sum(log1m_exp(-(y .- ymin) ./ sigma))
end
gpareto_lccdf@0e7976Load ▸

real gpareto_lccdf(vector y, real ymin, real k, real sigma)

Credit: Aki Vehtari

Pinned upstream source ↗
View complete source
gpareto_lccdf(y::vector[N], ymin::real, k::real, sigma::real)::real = begin
    inv_k = inv(k)
    if k < 0 && max(y .- ymin) / sigma > -inv_k
        reject("k < 0 and max(y - ymin) / sigma > -1 / k; found k, sigma = ", k, sigma)
    end
    if sigma <= 0
        reject("sigma <= 0; found sigma = ", sigma)
    end
    abs(k) > 1e-15 ? (-inv_k) * sum(log1p((y .- ymin) .* (k / sigma))) :
        -sum(y .- ymin) / sigma
end
gpareto_rng@e13adeLoad ▸

real gpareto_rng(real ymin, real k, real sigma)

Credit: Aki Vehtari

Pinned upstream source ↗
View complete source
gpareto_rng(ymin::real, k::real, sigma::real)::real = begin
    if sigma <= 0
        reject("sigma <= 0; found sigma = ", sigma)
    end
    u = uniform_rng(0.0, 1.0)
    abs(k) > 1e-15 ? ymin + (u^(-k) - 1) * sigma / k : ymin - sigma * log(u)
end
student_t_lcdf_stan@e842adLoad ▸

real student_t_lcdf_stan(real x, real df)

Credit: Helpful Stan Functions contributors named in the pinned source header

Pinned upstream source ↗
View complete source
student_t_lcdf_stan(x::real, df::real)::real = begin
    if df <= 0
        reject("df must be > 0. Found df = ", df)
    end
    lval = 0.0
    if is_inf(x)
        lval = not_a_number()
    elseif is_inf(df)
        lval = normal_lcdf(x, 0.0, 1.0)
    else
        nx = 1 + (x / df) * x
        lval = nx > 1e100 ? -0.5 * df * (2 * log(abs(x)) - log(df)) -
            lbeta(0.5 * df, 0.5) - log(0.5 * df) :
            (df > x * x ? beta_lccdf(x * x / (df + x * x), 0.5, df / 2) :
                beta_lcdf(1 / nx, df / 2, 0.5))
        lval = x <= 0 ? lval - log2() : log1m(0.5 * exp(lval))
    end
    lval
end
student_t_lccdf_stan@abe45cLoad ▸

real student_t_lccdf_stan(real x, real df)

Credit: Helpful Stan Functions contributors named in the pinned source header

Pinned upstream source ↗
View complete source
student_t_lccdf_stan(x::real, df::real)::real = begin
    if df <= 0
        reject("df must be > 0. Found df = ", df)
    end
    lval = 0.0
    if is_inf(x)
        lval = not_a_number()
    elseif is_inf(df)
        lval = normal_lccdf(x, 0.0, 1.0)
    else
        nx = 1 + (x / df) * x
        lval = nx > 1e100 ? -0.5 * df * (2 * log(abs(x)) - log(df)) -
            lbeta(0.5 * df, 0.5) - log(0.5 * df) :
            (df > x * x ? beta_lccdf(x * x / (df + x * x), 0.5, df / 2) :
                beta_lcdf(1 / nx, df / 2, 0.5))
        lval = x < 0 ? log1m(0.5 * exp(lval)) : lval - log2()
    end
    lval
end
unit_johnson_lpdf@c2139aLoad ▸

real unit_johnson_lpdf(vector x, real mu, real sigma)

Credit: Sean Pinkney, 2021

Pinned upstream source ↗
View complete source
unit_johnson_lpdf(x::vector[N], mu::real, sigma::real)::real = begin
    N * log(sigma) - sum(log(x) + log1m(x) + 0.5 * log1p(square(logit(x)))) +
        std_normal_lpdf(mu + sigma * asinh(logit(x)))
end
unit_johnson_cdf@635c05Load ▸

real unit_johnson_cdf(real x, real mu, real sigma)

Credit: Sean Pinkney, 2021

Pinned upstream source ↗
View complete source
unit_johnson_cdf(x::real, mu::real, sigma::real)::real = std_normal_cdf(mu + sigma * asinh(logit(x)))
unit_johnson_lcdf@1af108Load ▸

real unit_johnson_lcdf(real x, real mu, real sigma)

Credit: Sean Pinkney, 2021

Pinned upstream source ↗
View complete source
unit_johnson_lcdf(x::real, mu::real, sigma::real)::real = std_normal_lcdf(mu + sigma * asinh(logit(x)))
unit_johnson_lccdf@8bf6e7Load ▸

real unit_johnson_lccdf(real x, real mu, real sigma)

Credit: Sean Pinkney, 2021

Pinned upstream source ↗
View complete source
unit_johnson_lccdf(x::real, mu::real, sigma::real)::real = std_normal_lccdf(mu + sigma * asinh(logit(x)))
unit_johnson_rng@97bb7cLoad ▸

real unit_johnson_rng(real mu, real sigma)

Credit: Sean Pinkney, 2021

Pinned upstream source ↗
View complete source
unit_johnson_rng(mu::real, sigma::real)::real = inv_logit(sinh((inv_Phi(uniform_rng(0.0, 1.0)) - mu) / sigma))

Linear algebra (4)

chol_kronecker_prod@20e36cLoad ▸

matrix chol_kronecker_prod(matrix A, matrix B)

Credit: Sean Pinkney, 2022

Pinned upstream source ↗
View complete source
chol_kronecker_prod(A::matrix[m,m], B::matrix[p,p])::matrix[m*p,m*p] = begin
    C = rep_matrix(0.0, m * p, m * p)
    for i in 1:m
        for j in 1:i
            if abs(A[i, j]) > 1e-12
                row_start = (i - 1) * p + 1
                row_end = i * p
                col_start = (j - 1) * p + 1
                col_end = j * p
                C[row_start:row_end, col_start:col_end] = A[i, j] * B
            end
        end
    end
    C
end
angle2chol@2088eeLoad ▸

matrix angle2chol(matrix angle_mat)

Credit: Sean Pinkney, 2021

Pinned upstream source ↗
View complete source
angle2chol(angle_mat::matrix[N,N])::matrix[N,N] = begin
    inv_mat = identity_matrix(N)
    inv_mat[:, 1] = cos(angle_mat[:, 1])
    for i in 2:N
        inv_mat[i, i] = prod(sin(angle_mat[i, 1:(i - 1)]))
        if i > 2
            for j in 2:(i - 1)
                inv_mat[i, j] = cos(angle_mat[i, j]) * prod(sin(angle_mat[i, 1:(j - 1)]))
            end
        end
    end
    inv_mat
end
angle_vec2angle_mat@b28f31Load ▸

matrix angle_vec2angle_mat(vector angle, int K)

Credit: Sean Pinkney, 2021

Pinned upstream source ↗
View complete source
angle_vec2angle_mat(angle::vector[N], K::int)::matrix[K,K] = begin
    mat = add_diag(identity_matrix(K), rep_vector(-1.0, K))
    count = K - 1
    pos = 1
    for k in 1:(K - 1)
        mat[(k + 1):K, k] = segment(angle, pos, count)
        pos += count
        count -= 1
    end
    mat
end
lower_elements@bf87aaLoad ▸

vector lower_elements(matrix mat)

Credit: Sean Pinkney, 2025

Pinned upstream source ↗
View complete source
lower_elements(mat::matrix[N,N])::vector[(N*(N-1))÷2] = begin
    out = rep_vector(0.0, (N * (N - 1)) ÷ 2)
    count = N
    pos = 1
    for k in 1:(N - 1)
        count -= 1
        out[pos:(pos + count - 1)] = sub_col(mat, k + 1, k, count)
        pos += count
    end
    out
end

Quantile functions (2)

lognormal_qf@5347b6Load ▸

real lognormal_qf(real p, real mu, real sigma)

Credit: Sean Pinkney

Pinned upstream source ↗
View complete source
lognormal_qf(p::real, mu::real, sigma::real)::real = begin
    if is_nan(p) || p < 0 || p > 1
        reject("lognormal_icdf: p must be between 0 and 1; found p = ", p)
    end
    if is_nan(mu) || is_inf(mu)
        reject("lognormal_icdf: mu must be finite; found mu = ", mu)
    end
    if is_nan(sigma) || is_inf(sigma) || sigma <= 0
        reject("lognormal_icdf: sigma must be finite and > 0; found sigma = ", sigma)
    end
    exp(mu + sigma * inv_Phi(p))
end
unit_johnson_qf@624dc0Load ▸

real unit_johnson_qf(real p, real mu, real sigma)

Credit: Sean Pinkney

Pinned upstream source ↗
View complete source
unit_johnson_qf(p::real, mu::real, sigma::real)::real = begin
    if is_nan(p) || p < 0 || p > 1
        reject("unit_johnson_icdf: p must be between 0 and 1; found p = ", p)
    end
    if is_nan(mu) || is_inf(mu)
        reject("unit_johnson_icdf: mu must be finite; found mu = ", mu)
    end
    if is_nan(sigma) || is_inf(sigma) || sigma <= 0
        reject("unit_johnson_icdf: sigma must be finite and > 0; found sigma = ", sigma)
    end
    inv_logit(sinh((inv_Phi(p) - mu) / sigma))
end

Special functions (2)

inv_erf@f216cdLoad ▸

real inv_erf(real x)

Credit: Sean Pinkney, 2021

Pinned upstream source ↗
View complete source
inv_erf(x::real)::real = begin
    if is_nan(x) || is_inf(x) || x < 0 || x > 1
        reject("inv_erf: x must be finite and between 0 and 1; found x = ", x)
    end
    w = -log1m(square(x))
    s = sqrt(w)
    p = 0.0
    if w < 5.0
        w -= 2.5
        p = 2.81022636e-08
        p = fma(p, w, 3.43273939e-07)
        p = fma(p, w, -3.5233877e-06)
        p = fma(p, w, -4.39150654e-06)
        p = fma(p, w, 0.00021858087)
        p = fma(p, w, -0.00125372503)
        p = fma(p, w, -0.00417768164)
        p = fma(p, w, 0.246640727)
        p = fma(p, w, 1.50140941)
    else
        w = s - 3.0
        p = -0.000200214257
        p = fma(p, w, 0.000100950558)
        p = fma(p, w, 0.00134934322)
        p = fma(p, w, -0.00367342844)
        p = fma(p, w, 0.00573950773)
        p = fma(p, w, -0.0076224613)
        p = fma(p, w, 0.00943887047)
        p = fma(p, w, 1.00167406)
        p = fma(p, w, 2.83297682)
    end
    p * x
end
inv_erf_nsqrt@65a4e1Load ▸

real inv_erf_nsqrt(real x)

Credit: njuffa and Sean Pinkney, 2021

Pinned upstream source ↗
View complete source
inv_erf_nsqrt(x::real)::real = begin
    if is_nan(x) || is_inf(x) || x < 0 || x > 1
        reject("inv_erf_nsqrt: x must be finite and between 0 and 1; found x = ", x)
    end
    t = log(fma(x, -x, 1.0))
    p = 0.0
    if abs(t) > 6.125
        p = 3.03697567e-10
        p = fma(p, t, 2.93243101e-8)
        p = fma(p, t, 1.22150334e-6)
        p = fma(p, t, 2.84108955e-5)
        p = fma(p, t, 3.93552968e-4)
        p = fma(p, t, 3.02698812e-3)
        p = fma(p, t, 4.83185798e-3)
        p = fma(p, t, -2.64646143e-1)
        p = fma(p, t, 8.40016484e-1)
    else
        p = 5.43877832e-9
        p = fma(p, t, 1.43285448e-7)
        p = fma(p, t, 1.22774793e-6)
        p = fma(p, t, 1.12963626e-7)
        p = fma(p, t, -5.61530760e-5)
        p = fma(p, t, -1.47697632e-4)
        p = fma(p, t, 2.31468678e-3)
        p = fma(p, t, 1.15392581e-2)
        p = fma(p, t, -2.32015476e-1)
        p = fma(p, t, 8.86226892e-1)
    end
    p * x
end

Portable after SLIC / StanBlocks support (36)

normal_marginalneeds SlicTranspiler

array[] matrix normal_marginal(matrix y, matrix mu_glm, vector sigma)

StanBlocks now emits this nested array-of-matrix signature, but the app demo wrapper cannot instantiate its return container.

Pinned upstream source ↗
bernoulli_marginalneeds SlicTranspiler

array[] matrix bernoulli_marginal(array[,] int y, matrix mu_glm, matrix u_raw)

StanBlocks supports the signature; the app demo wrapper cannot instantiate nested matrix outputs or two-dimensional integer-array inputs.

Pinned upstream source ↗
binomial_marginalneeds SlicTranspiler

array[] matrix binomial_marginal(array[,] int y, array[,] int num, matrix mu_glm, matrix u_raw)

StanBlocks supports the signature; the app demo wrapper cannot instantiate nested matrix outputs or two-dimensional integer-array inputs.

Pinned upstream source ↗
poisson_marginalneeds SlicTranspiler

array[] matrix poisson_marginal(array[,] int y, matrix mu_glm, matrix u_raw)

StanBlocks supports the signature; the app demo wrapper cannot instantiate nested matrix outputs or two-dimensional integer-array inputs.

Pinned upstream source ↗
centered_gaussian_copula_cholesky_lpdfneeds SlicTranspiler

real centered_gaussian_copula_cholesky_lpdf(array[,] matrix marginals, matrix L)

StanBlocks supports the signature; the app demo wrapper cannot instantiate its two-dimensional array-of-matrices input.

Pinned upstream source ↗
bivariate_t_copula_lpdfneeds SlicTranspiler

real bivariate_t_copula_lpdf(vector u, vector v, real rho, real nu)

Depends on the vector overload of student_t_qf; immutable Library entries currently carry one overload per name.

Pinned upstream source ↗
multi_normal_cholesky_truncated_lpdfneeds SlicTranspiler

real multi_normal_cholesky_truncated_lpdf(vector u, vector mu, matrix L, vector lb, vector ub, vector lb_ind, vector ub_ind)

The source is portable after the Library demo wrapper can provide domain-valid truncation indicators and bounds.

Pinned upstream source ↗
multi_normal_cholesky_truncated_rngneeds SlicTranspiler

vector multi_normal_cholesky_truncated_rng(vector u, vector mu, matrix L, vector lb, vector ub, vector lb_ind, vector ub_ind)

The source is portable after the Library demo wrapper can provide domain-valid truncation indicators and bounds.

Pinned upstream source ↗
multi_normal_cholesky_truncated_lpneeds StanBlocks

void multi_normal_cholesky_truncated_lp(vector u, vector mu, matrix L, vector lb, vector ub, vector lb_ind, vector ub_ind)

Uses target += inside a user-defined _lp function, which StanBlocks deliberately rejects today.

Pinned upstream source ↗
multi_wallenius_integralneeds SlicTranspiler

real multi_wallenius_integral(real t, real xc, array[] real theta, array[] real d, array[] int x_i)

Requires mixed scalar arrays and a companion integrate_1d callback bundle, which the Library does not yet instantiate.

Pinned upstream source ↗
multi_wallenius_lpmfneeds SlicTranspiler

real multi_wallenius_lpmf(array[] int k, vector m, vector p, array[] real x_r, array[] int x_i, real tol)

Requires a dependency bundle plus integrate_1d callback and mixed scalar-array demo inputs.

Pinned upstream source ↗
variance_adjusted_sgtneeds StanBlocks

real variance_adjusted_sgt(real sigma, real lambda, real p, real q)

StanBlocks support for inv_sqrt has landed; the remaining legal beta(real, real) call is still inferred as anything.

Pinned upstream source ↗
mean_centered_sgtneeds StanBlocks

vector mean_centered_sgt(vector x, real sigma, real lambda, real p, real q)

Uses the legal Stan builtin beta(real, real), whose return type is currently inferred as anything by StanBlocks.

Pinned upstream source ↗
mean_centered_sgtneeds SlicTranspiler

real mean_centered_sgt(real x, real sigma, real lambda, real p, real q)

Name is overloaded upstream; Library entries currently carry one definition per name.

Pinned upstream source ↗
mean_centered_sgtneeds SlicTranspiler

real mean_centered_sgt(real x, real sigma, real lambda, real q)

Name is overloaded upstream; Library entries currently carry one definition per name.

Pinned upstream source ↗
skew_generalized_t_lpdfneeds SlicTranspiler

real skew_generalized_t_lpdf(vector x, real mu, real sigma, real lambda, real p, real q)

Depends on an overload bundle not yet representable as one immutable Library entry.

Pinned upstream source ↗
skew_t_lpdfneeds SlicTranspiler

real skew_t_lpdf(vector x, real mu, real sigma, real lambda, real q)

Depends on the skew-generalized-t overload bundle.

Pinned upstream source ↗
generalized_t_lpdfneeds SlicTranspiler

real generalized_t_lpdf(vector x, real mu, real sigma, real p, real q)

Depends on the skew-generalized-t overload bundle.

Pinned upstream source ↗
skew_generalized_t_lcdfneeds SlicTranspiler

real skew_generalized_t_lcdf(real x, real mu, real sigma, real lambda, real p, real q)

Depends on the skew-generalized-t overload bundle.

Pinned upstream source ↗
build_b_splineneeds SlicTranspiler

vector build_b_spline(array[] real t, array[] real ext_knots, int ind, int order)

Short-circuit guards and recursion now compile, but the app demo wrapper maps real[N] to vector and cannot instantiate this array[] real recursive signature.

Pinned upstream source ↗
interp_1d_cubicneeds SlicTranspiler

array[] vector interp_1d_cubic(array[] vector y, array[] real x, array[] real x_out, array[] int a0, vector theta)

Requires a caller-supplied derivative_fun callback plus array-of-vector demo inputs and output.

Pinned upstream source ↗
interp_1d_linearneeds SlicTranspiler

array[] vector interp_1d_linear(array[] vector y, array[] real x, array[] real x_out)

Requires array-of-vector demo inputs and output in the Library wrapper.

Pinned upstream source ↗
corr_constrain_lpneeds StanBlocks

vector corr_constrain_lp(vector x)

Uses target += inside a user-defined _lp function, which StanBlocks deliberately rejects today.

Pinned upstream source ↗
cholesky_corr_constrain_lpneeds StanBlocks

matrix cholesky_corr_constrain_lp(vector y, int K)

Depends on a target-mutating _lp helper unsupported by StanBlocks.

Pinned upstream source ↗
odeint_eulerneeds SlicTranspiler

array[] vector odeint_euler(real t0, array[] real ts, vector y0, int num_steps, array[] int a0, vector theta)

Hard-codes a caller-supplied derivative_fun callback and returns an array of vectors.

Pinned upstream source ↗
odeint_midpointneeds SlicTranspiler

array[] vector odeint_midpoint(real t0, array[] real ts, vector y0, int num_steps, array[] int a0, vector theta)

Hard-codes a caller-supplied derivative_fun callback and returns an array of vectors.

Pinned upstream source ↗
odeint_rk4needs SlicTranspiler

array[] vector odeint_rk4(real t0, array[] real ts, vector y0, int num_steps, array[] int a0, vector theta)

Hard-codes a caller-supplied derivative_fun callback and returns an array of vectors.

Pinned upstream source ↗
JQPDS_qfneeds SlicTranspiler

real JQPDS_qf(real p, real lower_bound, real alpha, vector quantiles)

Uses literal scalar arrays and a dependency call shape not yet instantiated by the Library wrapper.

Pinned upstream source ↗
JQPDS2_qfneeds SlicTranspiler

real JQPDS2_qf(real p, real lower_bound, real alpha, vector quantiles)

Uses literal scalar arrays and a dependency call shape not yet instantiated by the Library wrapper.

Pinned upstream source ↗
JQPDB_qfneeds SlicTranspiler

real JQPDB_qf(real p, row_vector bounds, real alpha, vector quantiles)

Requires row-vector demo values and dependency-aware Johnson-QF installation.

Pinned upstream source ↗
skew_generalized_t_qfneeds SlicTranspiler

real skew_generalized_t_qf(real x, real mu, real sigma, real lambda, real p, real q)

Depends on the skew-generalized-t overload bundle.

Pinned upstream source ↗
student_t_qfneeds SlicTranspiler

real student_t_qf(real p, real ndf)

Shares an upstream name with a vector overload; Library entries need overload-aware installation.

Pinned upstream source ↗
student_t_qfneeds SlicTranspiler

vector student_t_qf(vector u, real nu)

Recursive overload dispatch cannot be represented by the current one-definition-per-name Library entry.

Pinned upstream source ↗
student_t_log_qfneeds SlicTranspiler

real student_t_log_qf(real log_p, real ndf)

Shares an upstream name with a vector overload; Library entries need overload-aware installation.

Pinned upstream source ↗
student_t_log_qfneeds SlicTranspiler

vector student_t_log_qf(vector u, real nu)

Recursive overload dispatch cannot be represented by the current one-definition-per-name Library entry.

Pinned upstream source ↗
inc_beta_inverseneeds StanBlocks

real inc_beta_inverse(real x, real p, real q)

Uses unbounded while(1) loops with break/continue-heavy control flow; the current SLIC UDF lowering does not preserve this shape.

Pinned upstream source ↗

Audited but unsuitable for the modeling Library (2)

expect_equal_realnot included

void expect_equal_real(real expected, real actual, real tol)

Test-only assertion helper with no modeling return value; retained in the audit but omitted from the end-user function Library.

Pinned upstream source ↗
expect_equal_vectornot included

void expect_equal_vector(vector expected, vector actual, real tol)

Test-only assertion helper with no modeling return value; retained in the audit but omitted from the end-user function Library.

Pinned upstream source ↗

Using SlicTranspiler

StanBlocks (SLIC) → Stan, in the browser

What this does

SlicTranspiler turns editable Julia/StanBlocks source into Stan, checks the generated program with stanc, and keeps source and output side by side. Most prepared Library examples transpile as soon as you open them; large workspaces and shared links stay review-first until you choose Transpile.

The workbench

  • Compose data, functions, anonymous submodels and endpoint models in one copyable Julia script. Section summaries keep their global line ranges visible while collapsed; Data starts collapsed.
  • Arrange the source and generated-code panes with the center divider. Drag it, focus it and use the arrow keys, or use its edge buttons to collapse either pane completely; your layout stays in this browser.
  • Edit the bluish-outlined code in place. Binding names live in the code itself, so there is no second label to drift out of sync.
  • Transpile an endpoint with its button or ⌘/Ctrl + Enter; the Stan program and its stanc result appear on the right and that endpoint is highlighted.
  • The Function tab transpiles a single @deffun into its emitted Stan function.
  • The Library collects runnable examples and a guided Model spotlight; call any Library function by name.
  • Share builds a link that reopens the editor with your source.

SLIC in a nutshell

y ~ normal(mu, sigma)
A ~ statement — a prior on a parameter, or a likelihood when the left side is data.
mu = alpha + beta * x
An = assignment — a deterministic transform.
beta::vector[k] ~ normal(0, 1)
A typed declaration. Left bare (beta::vector[k]) it becomes a flat-prior parameter.
No loops or if in a model body
Control flow lives in a @deffun Stan function (the Function tab); the model calls it straight-line.
theta ~ plate(y; outer=N) do yi … end
The one sampling loop — a fresh parameter and observation per group.
Submodels
Name a reusable fragment and pass its inputs by keyword: eta ~ regression(; x).
Observations
weighted, truncated, censored and interval_censored wrap a family; missing outcomes are imputed automatically.

Try a Spotlight model

These prepared examples open editable and already transpiled:

Browse every prepared source in the Library.

StanBlocks documentation ↗

Send feedback

Tell me what worked, or what broke
Your workspace source — every editor's contents — is attached so I can reproduce exactly what you saw. Uncheck to send only your message.