Changelog
Source:NEWS.md
frmtmb.sample 0.27.0
posterior_epred(),posterior_linpred()andposterior_predict()withallow_new_levels = TRUEanswer at ame(gr = )level the fit did not see: each draw takes the level’s latent value fromnormal(x, sdx), as brms does. Before, they refused it, wherefitted()and brms answered. A new level of a group-level term stays refused. Needs frmtmb 0.80.0.The package code does not use the global assignment operator
<<-, which rOpenSci’s pkgcheck refuses. A closure that keeps state between calls writes to an environment that it creates, and a condition handler returns its value. The results do not change. The tmbstan build check keeps its memo inmemo, an environment in its enclosure, and the test helperwith_tmbstan_hpp()resets it there.
frmtmb.sample 0.26.0
Needs frmtmb 0.79.0. The exact gp() field is non-centered in core, so the sampler has nothing to transform. It reads the sampling-API exports gp_tape_scope(), gp_tape_order(), gp_nugget_message(), and the new readers of a me() draw and of a latent residual.
Breaking changes
An exact
gp()is non-centered in core, as brms’szgp, at a nugget of1e-12 * sdgp^2. Sofrm_sample()samples the tapefrm()fits, with the sampler’s priors added, and has nothing to transform. The block no longer has a factor forreparameterize =, and that argument does not reach it: an exact field is non-centered with or without it. Theb[i]columns of its draws are z, over a farthest-first order of the positions, where they were the field.ranef()and every predictive method read the field throughexpand_b(), as before.frm_sample(fit)starts at random where the fit’s noise has reached the nugget of an exactgp(), and says so. Chains started at that mode stay pinned: at truesigma1e-6, n 15, a mediansigmaof 1.83e-8 and Rhat 2.25. These chains do not converge at this noise either:sigmaread 24 and 394 times the truth on two seeds at n 15.laplace = TRUEis the route here.init = "last.par.best"starts at the mode. At ordinary noise the mode stays the start.frm_sample(laplace = TRUE)on an exactgp()takes 3.2 to 3.5 times 0.78.0’s wall clock at 300 positions, 531 to 570 s against 165 s. The dense gradient causes this. Memory holds, 1.91 to 1.95 GB against 1.92 GB.brms’s class
"sds"carries a smooth’s default,student_t(3, 0, <scale>), and a smooth’s prior onfrm_sample(), withcoefthe term as written. Class"sd"no longer reaches a smooth, as in brms. The table lists the rows brms lists.A missing value’s draw is reported under brms’s name,
Ymi_<resp>[k](Ymi[k]with one response,Yl_undermi(sd)), on the response’s own scale. It wasmiss_<k>, on the sampler’s chart:miss_1underGammaranged from -3.05 to 3.01 where brms’sYmi[1]ranges from 0.04 to 15.3. The sampler’s Jacobian does not change.A new row of a
me()term draws a new latent value per posterior draw fromnormal(x, sdx), per row, or per level underme(gr = ). It does so inposterior_epred(),posterior_linpred()andposterior_predict(), as brms 2.23.0 does. Before, they readx: on a model withsdx = 0.3, the sd over draws of the expected value was 0.603 of brms’s. The 95 percent interval was 0.634 wide against 1.036. New data must holdsdx, andcormeis not read, as in brms.One
me()call is one latent value per row and draw, across the responses and dpars one method answers for. This diverges from brms 2.23.0, which draws one per predictor on new data, against its own Stan program, which has oneXme_1: at the training rows the residuals correlate at 0.734, one latent predicts 0.739 and brms’s replicates give -0.001.posterior_linpred()with nodparon an ordinal family with acs()term returns brms’s layout, draws x rows x thresholds, with every margin unnamed. Before, it returned the shared part, the predictor at no threshold of the model.dpar = "mu"andtransform = TRUEread the shared part, as in brms.conditional_effects()of a multivariate model gives one panel set per response withoutresp, and takes several, each named<resp>.<resp>_<effect>, as brms does. A name given twice is refused, where brms repeats the panel. Before, it gave the first response alone and failed on several.A univariate model does not read
resp, as in brms:posterior_epred(),posterior_linpred(),posterior_predict(),fitted(),predict(),residuals(),log_lik(),logLik(),bayes_R2(),loo_R2()and the threeloo_*()predictions give the same answer for an empty vector. They give the same answer for a name given twice, an unknown name,NAand a number. Before, some gave internal errors.update(<draws>, prior = )merges with the first call’s prior, as brms’supdate()does: a new row takes its slot and the other rows stay. A prior with no rows keeps them. Before, the new prior replaced the first call’s: after anupdate()that added a sigma prior,b_xmoved from 9.93 to 2.09. There is one exception: an edited row of adefault_prior()table stays here, where brms loses it because the row’ssourceis still"default":b_xreads 9.52 here and 2.00 in brms.posterior_predict(newdata = )answers underar(),ma(),arma(),cosy()andunstr()withcov = TRUE, through core’s route overnewdata’s own groups and times. Before, it refused.log_lik(newdata = )still refuses where brms answers; its message now namesposterior_predict(newdata = )as a route on these models, and that is all that changes.A new row with no
xorsdxof ame()term readsNAinposterior_epred(),posterior_linpred()andposterior_predict(), with a warning of classfrmtmb_me_missing. The other rows answer.conditional_effects()of ame(gr = )model holds the group atNA, as brms does. Panels are in brms’s order, with the effects outside and the responses inside.
New features
bayes_R2()andloo_R2()read an emptyrespas every response. Before, they stopped with an internal error.pp_mixture()of a multivariate mixture reads the one response named, with brms’s refusal of none or several. Before, it refused every such model, and read the first response whenrespwasNULL.
Bug fixes
frm_sample()onnl = TRUEwithcumulative(),sratio(),cratio(),acat()orhurdle_cumulative()samples the body. Before, it sampled the thresholds alone without a word, asfrm()fitted them, andposterior_epred()on those draws stopped with a refusal.frm_sample()takesbf(..., nl = TRUE, autocor = ~ term), which was refused, andnl = TRUEoncategorical(),multinomial(), the simplex families and amixture(), with one body in every location, as brms.The drawn route for an exact
gp()needs long chains at low noise, and the numbers are stated. At true sigma 1e-3, 15 rows, 4 chains of 12000 read sigma 5.9e-4, 1.05e-3, 2.3e-3 (Rhat 1.025, sdgp Rhat 1.07, 58 minutes). brms’s chains read 5.2e-4, 1.03e-3, 2.4e-3 (1.031, 1.15, 53 minutes, 20000 iterations). Neither reaches Rhat 1.01 at those lengths.frm_sample(laplace = TRUE)serves the outer parameters only: it refusesposterior_epred(),posterior_linpred(),posterior_predict(),fitted(),predict(),log_lik(),loo()andconditional_effects().
Other changes
frm_sample()samplesmi()under every family core takes, and underasym_laplace()andmixture()wherefrm()refuses a value another density reads. From afrm()fit it holds the missing values the fit left out of its objective, through core’s newmi_sampling().frm_sample(formula, laplace = TRUE)takes the route offrm_sample(fit, laplace = TRUE): a missing value no density reads leaves the objective. On anexgaussianwith 200 rows and 60 missing the formula read sigma 0.910 and beta 1.590. It now reads 0.360 and 2.132, the fit 0.355 and 2.146, and the observed rows, fully sampled, 0.359 and 2.139. A value a density reads with no mode to expand about is refused on this route as onfrm().frm_sample()samples core’s latent residuals:ar(),ma(),arma(),cosy()andunstr()on a family with no residualy - mu. Its defaults are brms’s:student_t(3, 0, <scale>)onsderr, flat onarandmaover (-1, 1) and oncosyover (0, 1), andlkj(1)oncortime. On a poissonar(cov = TRUE)with 150 rows, the posterior means of the intercept, slope,ar[1]andsderrread 0.797, 0.478, 0.456 and 0.692. In brms they are 0.796, 0.476, 0.459 and 0.690.variables()listsar[1]andsderr. The latents are the columnslatent_state[k], where brms haszerr[n]anderr[n]. These are the chain’s own states:ma(),arma()andcosy()have one extra state per group, so there are 72 of them for 60 rows in 12 groups. They are noterron a chain withsderrother than 1.frm_sample()fits the forms of a latent residual thatfrm()refuses:cov = FALSEafter the inverse link, and a mean less than 2 marginal sds of the latent from the edge of an identity or inverse link.posterior_epred(),log_lik()andposterior_predict()read each draw’s latents on the fitted rows, andposterior_predict()andposterior_epred()draw new latents on new rows undercov = TRUE. Undercov = FALSEnew rows are refused in brms’s words.
frmtmb.sample 0.25.0
Needs frmtmb 0.78.0. Its set_prior() takes the classes meanme, sdme and corme, and its default_prior() prints the group rows of a sampling-route table as (flat). It exports predict_rescor_draw() and gives rescor_row_loglik() its resp.
Breaking changes
A
default_prior(route = "sample")table passed asprior =applies an edited class row to every group, as brms does: the groups ofsd,corandcorme, and each level ofthres(gr = )for theInterceptanddeltarows. Before, the table’s group rows carried the class row’s default and applied it over the edit: on twome(gr = g)terms, a classcormerow edited tolkj(4)sampledlkj(1). Its Kolmogorov-Smirnov p-value against thelkj(4)correlation was 1.3e-32. The same held forcorandsd.For the brms classes, a bound on one coefficient (
coefwithlborub) is refused with brms’s message: “Prior argument ‘coef’ may not be specified when using boundaries.” brms 2.23.0 refuses it forb,sd,meanmeandsdme. Before, the sampler took the bound and the prior draws ignored it:sdmeof one term atub = 0.5had prior draws up to 10.7. A bound on a class row or on a group’s row is taken, as in brms, andfrm()keeps its box on one coefficient. Three cases are not refused. Classtheta, frmtmb’s own, takes a bound on one internal parameter. A row that restateslb = 0onsd,sdgp,lscaleorsdmebounds nothing. Andset_prior(class = "Intercept", nlpar = "a")on a nonlinear parameter witha ~ 1is brms’s class rowclass = "b", nlpar = "a", so its bound is a class bound. With a bound, that spelling is refused whereahas more than an intercept.That spelling’s bound now reaches its prior draws. Before, it was a bound on one coefficient, and the prior draws ignored it: under
lb = 0ony ~ a * exp(-b * x), the prior draws ofawent down to -1.67. Now they are the prior truncated at the bound, under brms’s namesprior_b_aandprior_b_b.A
me()model is sampled under brms 2.23.0’s default priors on its hyperparameters: flat onsdmeitself, andlkj(1)oncorme. Before, the sampler was flat onlog(sdme)and on the internal chart of the correlation. We sampled twome(gr = g)terms with 10 levels and one row-levelme()term (4 chains of 3000 draws). The posterior means ofsdme_mexgandsdme_mezgwere 12.6 and 13.6 Monte Carlo standard errors from brms’s, and the slopes up to 8.0. Now every mean, sd, 5 and 95 percent quantile of 14 variables is within 2.52 of brms’s.prior = "flat"stays flat onsdme, and is flat on the Cholesky factor ofcorme, which is brms’s(flat).get_prior(route = "sample")andprior_summary()of draws list these defaults in brms’s rows.posterior_predict()of aset_rescor(TRUE)model draws the responses of a row jointly, as brms does: per draw, a multivariate normal with covariancediag(sigma) R diag(sigma), or forstudent()the multivariate t with the sharednu. Before, no call returned that draw: withoutrespthe method returned the first response only. Draws of two responses taken one call each correlated at -0.05 to 0.08, on a fit whose residual correlation was 0.82. On a fit of three responses (200 rows, 2000 draws), the correlations of the predictive residuals are now 0.750, 0.554 and 0.315. They are within 1.3 Monte Carlo standard errors of what the draws imply, and within 0.7 of brms’s own draw from the same parameter draws. Undersigma ~ xand understudent(), the same holds within 1.4 and 0.8. Asigmathat varies by row is drawn at that row’s value.Without
resp,posterior_predict(),posterior_epred(),posterior_linpred()andpredictive_error()of a multivariate model return every response, as brms does: a draws x observations x responses array with brms’s response names.fitted(),predict()andresiduals()summarize it into brms’s observations x 4 x responses array. Before, they returned the first response only. Withoutrescor, each layer is the draw thatresp =gives for its response.resptakes several responses, in the order you name them, in these methods:posterior_predict(),posterior_epred(),posterior_linpred(),predictive_error(),fitted(),predict(),residuals(),log_lik(),loo(),waic(),loo_predict(),loo_epred(),loo_linpred()andloo_predictive_interval(). Each takes brms’s spelling of a name (yafory_a) as well as frmtmb’s. As in brms, each refuses a name given twice and reads an emptyrespas every response. Underset_rescor(TRUE), arespthat is not in the model’s order is answered, with the correlations in the order named. brms 2.23.0 stops there, because it looks up the correlations by the names in the order given.A response can predict more than one value per row: the category probabilities of an ordinal or categorical response. The stacked layout has no place for it.
posterior_epred()andfitted()withoutresprefuse such a model; brms binds the category columns beside the other responses there.predict()withoutresprefuses to summarize it, as brms stops; withsummary = FALSEit returns the draws. Name the response withresp =.predictive_interval()withoutrespis refused, as brms refuses it.log_lik(resp =)of aset_rescor(TRUE)model is brms’s: one response gives its own density, and several give their joint density. Before, everyrespgave the joint density of all the responses, soloo(resp = "y1")on three responses reported -724.7 where the density of y1 gives -280.8.loo(),waic(),loo_predict(),loo_R2()and the otherloo_*()functions read the corrected matrix through theirresp.log_lik(combine = FALSE)returns the joint matrix, as in brms, where it was refused.One response of a
student()model withset_rescor(TRUE)is drawn, and its density taken, as a t with the sharednu. That t is the margin of the multivariate t. brms 2.23.0 readsnu = 1there (its one-response preparation finds nonuof its own), which is not the margin of its own model. This is a deliberate divergence from brms.Where
a ~ 1,set_prior(class = "Intercept", nlpar = "a")and brms’s class rowset_prior(class = "b", nlpar = "a")are one prior slot. With both, theInterceptspelling’s density stands, in either order, asfrm()and brms resolve them. A bound on either row is the class bound, theInterceptspelling’s where both set one. The fit’s own prior and the call’sprior =combine in the same way.prior_summary()of the draws lists both rows as they were written, as brms does.
New features
Priors on brms’s classes
meanme,sdmeandcormeapply when sampling.sample_prior = "yes"draws them under brms’s names:prior_meanme_1,prior_sdme_1andprior_Lme_1, numbered by the group of terms that share agr =. Where a term has a prior of its own, there is one column per term,prior_meanme_1_meanme_mex, as brms’s renaming spells it. With brms’s defaults onlyprior_Lme_1is drawn, as in brms.sample_prior = "only"samples ame()model oncemeanmeandsdmehave proper priors. Before, it refused every such model. With a flat one it is refused with brms’s words, naming'meanme_1'or'sdme_1'.
Bug fixes
The draws of a model with correlated
me(gr = )terms carry brms’scorme_<gr>__<coef1>__<coef2>column. Before, only the ungroupedcorme__column was derived, so the grouped correlation was absent from the draws.The default-prior message prints brms’s
(flat)on a bounded parameter with its bound,delta (flat), lb = 0for the distance of equidistant ordinal thresholds. Before, it printeddelta flat(). The newsdmeline reads(flat), lb = 0too.bayes_R2()andloo_R2()refuse a response named twice inresp, as the other methods do. Before,bayes_R2()gave two identical rows, andloo_R2()gave two rows with different values.
frmtmb.sample 0.24.0
Needs frmtmb 0.77.0. That release reads brms’s (flat) as a prior density and gives build_objective() its prior_only field. Its sigma is the innovation sd under the covariance form of ar(), ma() and arma().
Breaking changes
Under the covariance form of
ar(),ma()andarma(), the draws ofsigmaare of the innovation sd, as brms’s are. Before, they were of the marginal sd. On an AR(1) witharnear 0.92, the posterior mean ofsigmawas 1.154 against brms’s 0.432. It is now 0.433.summary(),posterior_summary(),variables()and the draws read the same parameter as brms’s.The default
student_t(3, 0, s)onsigmaand a prior of your own are densities on the innovation sd itself. Alborubonsigmais taken, as in brms. Undersigma ~ x, the default and a prior of your own on the intercept ofsigmaare read at the log innovation sd, as brms’sIntercept_sigma. Withnormal(-1, 0.5)there, the posterior mean ofarwas 7.95 Monte Carlo standard errors from brms’s and is now 0.55.We compared the draws with brms’s own (4 chains of 4000 on each side):
ar(),ma()andarma()under the defaults,ar()under user priors, andar()undersigma ~ x. Every posterior mean is within 1.8 Monte Carlo standard errors of brms’s. Every sd ratio is within 0.969 to 1.037. The bulk effective sample size ofsigmais 2.0, 0.94 and 1.2 times what it was underar(),ma()andarma().conditional_effects(method = "posterior_predict")on draws draws its band at the draws’sigma. Under these terms that is now the innovation sd. brms does the same, because itsconditional_effects()drops every autocorrelation term. The band is narrower than before bysqrt(1 - ar^2)for an AR(1).Draws saved with frmtmb.sample 0.23.0 for a model with one of these terms still report the old marginal sd as
sigma.summary(),posterior_summary(),as.matrix()andvariables()show it. Theirlog_lik(),loo()andposterior_predict()are refused. Sample such a model again.The message of the default priors no longer marks
sigmawith “on brms’s innovation sd”: it is brms’s sigma.prior = "flat"is brms’s(flat)in every slot: no density on the parameter brms declares, inside the bounds brms declares. That is the model brms fits with""in every row of its prior table; brms has no opt-out of its priors. Until now the opt-out added no density at all, which is flat on frmtmb’s internal parameters: on a log standard deviation, improper atsd = 0, and on a first-order correlation,(1 - rho^2)^(-3/2). A standard deviation,sigmaand the other positive distributional parameters are now flat on their own scale. A correlation matrix (cor,rescor,cortime,lncor) is flat on its Cholesky factor, and the ordered thresholds anddeltaare flat on themselves. The defaults that are already flat on brms’s parameter stay:ar,ma,cosy,lagsar, anddirichlet(1)on a simplex, a mixture’s weights included. Against brms 2.23.0 with""in every slot, 4 chains of 3000 draws each. Ony ~ 1 + (1 | g)with 6 groups the posterior mean ofsd_g__Interceptis 1.458 in brms, 1.455 now and was 1.197. Ony ~ x + (1 + x | g)with 8 groups the correlation’s mean is -0.283 in brms, -0.265 now, and was -1.000 (sd below 0.0001, 529 divergent transitions). Onar(cov = TRUE)with 6 series of 5 the mean ofar[1]is 0.481 in brms, 0.480 now and was 0.541. A random-effect block now non-centers underprior = "flat", since flat on the standard deviation closes the tail atsd = 0, andprior_summary()lists the(flat)rows.A bounds-only specification that replaces a default,
set_prior("", class = "sd", lb = 0.1), is brms’s(flat)on that slot: flat on the standard deviation above 0.1, where it was flat on its log. So isset_prior("", class = ...)with no bound, and a table row with an empty prior: oncorit is flat on the Cholesky factor, on the intercept no density. Theprior_summary()of aprior = "flat"run lists the intercepts as(flat)too. Passed back asprior =, as the object or as its table throughas.brmsprior(), it gives the same density: log density and gradient to 1e-12 relative at 40 points.The named list of prior objects (
prior = list(theta_1 = prior_normal(0, 1))) is refused, as in frmtmb. It took over the internal parameters it named after the class priors. A name inside a correlation block removed the defaultlkj(1)from the whole block:list(theta_4 = prior_normal(0, 1))on(1 + x + z | g)left two correlations with no density. The draws’prior_summary()no longer carries anoverridesattribute.frmtmb.spatial’s
car()dependence parameter is the one parameter brms has a class for that is not yet brms’s(flat): brms declares it on (0, 1) and leaves it flat. Here it carries no density, which is flat on its logit and not integrable at 0. Underprior = "flat"such a posterior is improper; give it a prior with class"theta"on the coefdefault_prior()lists.prior =refuses adefault_prior()orvalidate_prior()table ofroute = "fit", the default route, edited, cut down to some rows or columns, or not. It refuses a priorlist made from one withas.brmsprior(),+orc()too. Its(flat)rows arefrm()’s defaults. Read as brms’s(flat), they replaced brms’s defaults on the intercept, sigma, the standard deviations and the correlations without a word. The message points toroute = "sample", whose table is brms’s defaults, and toprior = "flat".as.data.frame()drops a table’s route. Soas.brmsprior()marks a data frame that holds frmtmb’s printed(flat). The priorlist is refused where its(flat)rows would replace one of brms’s proper defaults. Aroute = "sample"table never does that. A table built by hand in brms’s spelling, with""for(flat), is read as written, and so is brms’s own.delta, the distance between equidistant ordinal thresholds, is flat ondeltaby default, brms’s(flat)withlb = 0. frmtmb holdslog(delta)for an ordered family, and the default was flat on that.prior_summary()and the default-prior message print brms’s(flat)withlbandubforcosy, forlagsarand for a first-ordercov = TRUEarorma. They printeduniform(-1, 1). The density is unchanged.set_prior(class = "theta")on a standard deviation, a correlation orrescoris refused, as in frmtmb (?set_prior). One such prior used to retire the defaultlkj(1)on every correlation of its block.The evidence ratio of a point hypothesis is brms’s.
hypothesis()divides the kernel density of the posterior draws at the point by the kernel density of the prior draws there, as brms’sevidence_ratio()does. It returns the prior draws of each hypothesis asprior_samples. Without prior draws for every parameter a hypothesis names, itsEvid.RatioisNAwith no message, as in brms. Before, the denominator was the prior density read off the prior specification. So draws made without prior draws gave a number where brms givesNA. Andsigma, a standard deviation, a correlation, a nonlinear function and the intercept were refused with a warning. brms gives a ratio for all but the intercept. We compared with brms 2.23.0 ony ~ x + (1 | g)(4 chains of 6000 a side, seed 11). The ratios ofx = 0,x = 0.2,sigma = 1andsd_g__Intercept = 0.5are within 1.7 Monte Carlo standard errors of brms’s.as_draws*(inc_warmup = TRUE)andas.mcmc(inc_warmup = TRUE)return the warmup instead of refusing, andupdate()of draws samples again instead of refusing.
New features
frm_sample()samples amo()term on two values, as brms 2.23.0 does (Jmo = 1). The draws report the weightsimo_<term>1[1]as a constant 1, as brms’s do. On 200 rows,y ~ mo(x) + zwithxin 1 and 2 agrees with brms’s own Stan program (2 chains of 2000 each): every posterior mean within 1.6 Monte Carlo standard errors, every posterior sd within 3.3 percent.frm_sample()refuses amo()term on one value. That term is 0 on every row, so its coefficient has an improper posterior under the default flat prior. brms 2.23.0 cannot sample it either: its Stan program rejectsJmo = 0.-
frm_sample(sample_prior = )takes brms’s"no"(the default),"yes"and"only", andTRUEandFALSE.-
"yes"adds draws from the priors to the draws, under brms’s names, asbrm(sample_prior = "yes")does. That is one column per prior statement of brms’s Stan program for the model:prior_bfor a class-wide prior,prior_b_xfor each coefficient of a vector with a coefficient-specific prior,prior_Intercept,prior_sigma,prior_sd_g,prior_cor_g,prior_simo_mox1[k], and so on. A flat prior has no column. A bounded parameter is drawn truncated to its bounds. We checked 19 models. They cover population-level and monotonic coefficients, intercepts of the location and of a distributional parameter, nonlinear parameters,sigma,nu,phiandhu. They also cover smooth standard deviations in two predictors, group-level standard deviations, correlations,rescorandmo()simplexes. And they cover mixture weights, ordinal thresholds,arof two responses, and multivariate and bounded priors. On each, the names are brms 2.23.0’s, in brms’s order. Each column is drawn directly from its prior, independent of the likelihood, as brms draws it in generated quantities. On 39 columns of 9 models the one-sample Kolmogorov-Smirnov p-value against the exact (truncated) prior is between 0.125 and 0.986. Against brms’s own draws of two models (14 columns, 4000 draws a side), it is between 0.033 and 0.962. An ordinal model with a threshold prior of its own gets brms’sprior_Intercept__1,prior_Intercept__2, …, one per threshold. Agp()term’ssdgpandlscaleget no prior draws, and neither do brms’smeanmeandsdme, which frmtmb has no prior slot for. -
"only"samples the prior of the whole model with the likelihood left out, as brms does. Soposterior_predict(),pp_check()andconditional_effects()give the prior predictive distribution. Every parameter needs a proper prior: a flat one is refused with brms’s message (“Sampling from priors is not possible as some parameters have no proper priors. Error occurred for parameter ‘b’.”). Unlike brms, a vector with some coefficients flat is refused too. So is a model with missing values of anmi()term, which have no density without the likelihood. Ami(sdy)response keeps its measurement density, as in brms. A model withme()terms is refused, naming brms’s classesmeanmeandsdme: brms needs proper priors there, and frmtmb has no prior slot for them yet. We checkedy ~ x + (1 | g)with anormal(0, 1)prior onb(4 chains of 4000). We compared each mean and each 5, 50 and 95 percent quantile ofb_Intercept,b_x,sigma,sd_g__Intercept,r_g[1,Intercept]and of a prior predictive draw. Each is within 3.0 Monte Carlo standard errors of brms’s. At two more seeds every quantile ofb_x,sigmaandsd_g__Interceptis within 1.3 of the exact prior’s (brms’s: 2.4).
-
New
prior_draws(), brms’s, with brms’svariableand its deprecatedpars; brms’s deprecatedprior_samples()reaches it while brms is loaded. A name gets the prior column whose name is the longest match at its start, in random order (b_xreadsprior_b). The overall interceptb_Interceptis left out with brms’s warning.The warmup iterations rstan saves (
save_warmup = TRUE, the default of rstan and of brms) stay in the draws’ stanfit, as in a brmsfit.inc_warmup = TRUEonas_draws(),as_draws_array(),as_draws_df(),as_draws_list(),as_draws_matrix(),as_draws_rvars(),as.mcmc(),as.matrix(),as.array(),as.data.frame(),rhat()andneff_ratio()converts them to the draws’ variables. It puts them before each chain’s draws, as brms does.as.mcmc()refuses it withcombine_chains = TRUEand on thinned draws, with brms’s messages, and every accessor refuses a warmup that no longer fits the draws. Every other method reads the post-warmup draws alone, as before.update()of draws samples the same model again with changed arguments offrm_sample(), as brms’supdate()does forsample_prior,priorand the sampler’s options:update(ds, sample_prior = "yes")adds prior draws. A new formula or new data is refused, as before.
frmtmb.sample 0.23.0
Needs frmtmb 0.76.0, which exports autocor_flat_priors(), autocor_bound_chart(), autocor_innov_sd() and autocor_row_loglik() and codes mo() from its minimum.
Breaking changes
With frmtmb 0.76.0, which codes an integer
mo()variable from its minimum as brms 2.23.0 does,frm_sample()samples brms’s model on such data. On 300 rows with values 1 to 4, the draws have the 3 weightssimo_mok1[1]tosimo_mok1[3], where they had 4. Every posterior mean agrees with brms’s within 2 Monte Carlo standard errors, where the Intercept was 12 of them away. The code of this package did not change; its tests need frmtmb 0.76.0.The default priors of a residual-correlation term are brms’s. Before, an
ar(),ma()orcosy()coefficient was flat on frmtmb’s internal parameter. For a first-ordercov = TRUEarormathat is(1 - rho^2)^(-3/2)onrho, with its mass at -1 and 1. Forcosyit is a density flat on the logit of its whole window. And the default onsigmawas on frmtmb’s marginal sd, where brms’ssigmaunder a first-ordercov = TRUEar(),ma()orarma()is the innovation sd. Now each coefficient is flat on itself, as brms’s(flat)is: on (-1, 1) forarandmaundercov = TRUE, on brms’s [0, 1] forcosy. The defaultstudent_t()onsigmais read on brms’s innovation sd,sigma sqrt(1 - ar^2),sigma / sqrt(1 + ma^2)orsigma sqrt((1 - ar^2) / (1 + ma^2 + 2 ar ma)), with the Jacobian of that factor. The reference is brms 2.23.0’s own draws, 4 chains of 4000 on each side (seed 3). Against them, the means ofar[1]were 42.3 Monte Carlo standard errors apart, on an AR(1) of 0.9 in 8 groups of 6 time points. Forsigmathey were 19.6 apart. An MA(1) of 0.6 had everyma[1]draw at 1. Now every parameter of the ar, ma and arma cases is within 1.6 standard errors of brms’s, the sds within 4 percent. Forcosy(0.03 in 30 groups of 4), 48 percent of the draws were below 0, where brms has none. The mean was 0.011 against brms’s 0.076. Now there are none, and the means are 0.075 to 0.078 against brms’s 0.075 to 0.078 on three seeds. Acov = TRUEterm of order two or more, which brms does not have, is flat on its stationary or invertible region. Itssigmadefault stays on the marginal sd. Thecov = FALSEcoefficients, brms’s default form, are flat as before, as in brms.frm_sample()’s message anddefault_prior(route = "sample")list the new rows.sigmaunder a first-ordercov = TRUEar(),ma()orarma()is the marginal sd. Every prior on classsigmais read at the innovation sd, as brms’s is. The draws’sigmacolumn,summary()andvariables()report frmtmb’s marginal sd: on the AR(1) above, a posterior mean of 1.16. brms’ssigmais the innovation sd (0.43); the model is the same. A prior of your own on class"sigma"is read where the default is, at the innovation sd. So adefault_prior(route = "sample")table passed back asprior =, or the default’s text typed, gives the default’s density exactly. Before, a user prior there was read on the marginal sd. That density was up to 0.72 nats from brms’s with the same text (three points on the AR(1) data).frm()with the same prior is the mode of the densityfrm_sample()samples. Albabove 0 or aubonsigmathere is refused.A prior of your own keeps the bound brms declares for its slot. brms keeps a declared bound under a user prior:
real<lower=1> nu,real<lower=0> sigmaunder an identity link,real<lower=0,upper=min_Y> ndt,real<lower=0,upper=1> cosy. Before, a user prior of the same slot dropped the default’s bound: withset_prior("normal(2, 2)", class = "nu")3.55 percent of the draws were below 1. Now the bound stays on each side the prior leaves unset, and alborubof your own replaces that side, as in brms. Withset_prior("normal(0, 0.1)", class = "cosy")the posterior mean is 0.054 against brms’s 0.053 (z 1.5); it was 0.009, with draws below 0. A bounds-only prior on a residual-correlation class keeps the flat density as well:set_prior("", class = "ar", lb = 0.5)is flat on [0.5, 1] in brms. Here it was flat on frmtmb’s internal parameter (mean 0.946 against brms’s 0.916, z 43.8); now the mean is 0.916 (z 0.5).A prior on
class = "theta", coef = "thetaac_1"is refused where a class reaches that parameter (ar,ma,cosy,cortime); see frmtmb’s NEWS. The message for the retiredlower/upperarguments namescoef = "theta_1"as its example.
New features
-
log_lik()of draws no longer refuses a residual covariance term (ar(cov = TRUE),ma()andarma()withcov = TRUE,cosy(),unstr(),fcor(), frmtmb.spatial’ssar()and other registered terms). A column is brms 2.23.0’s leave-one-out conditional density of the row given the other rows of its group, normal or Student-t. It equals brms’slog_lik()at the same draws to 2.0e-15 relative on 18 cases.loo(),waic(),psis()and theloo_*()functions take these models. The values do not sum to the log-likelihood, as in brms. On a group with a missing time point, the conditional is the fitted model’s. Itsar(),ma()andarma()lags count time levels, where brms’s count positions.
Bug fixes
A bounded residual-correlation parameter is sampled through one logistic onto its interval, as Stan’s own bound is in brms. Stan’s log bound on frmtmb’s internal parameter, stacked on the term’s own map, gave 5 to 9 divergent transitions per 4 chains of 2000. That was on a
cosynear its bound at 0 (seeds 3 to 5, mode and random starts), where brms has none. Now there are none.When the ML estimate of
cosyis below brms’s bound at 0, the warning says that the bound is the default, brms’s declaration. It namesset_prior("", class = "cosy", lb = -1/(d - 1))to sample the whole windowfrm()fits. It said “the requested bound(s) on thetaac_1”.
frmtmb.sample 0.22.0
Needs frmtmb 0.75.0, which exports frmtmb_covstruct_info() and frmtmb_autocor_pars() and gives coefficients brms’s names.
Breaking changes
The draws of a model with an
exp()term carry brms’s names:b_expx,sd_g__expxandcor_g__Intercept__expx, as brms 2.23.0 names them, where they wereb_.frm_expx,sd_g__.frm_expxandcor_g__Intercept__.frm_expx.fixef()of the draws names the rowexpx, andhypothesis(draws, "expx > 0")works. The change is in frmtmb, which builds the names, and the new test of it needs frmtmb 0.75.0. The same holds for a nonlinear parameter of a multivariate model,b_yn_a_Interceptwhere the draws heldb_a_yn_Intercept.fixef()of the draws lists the rows in brms’s order, which is the order offixef()of the fit: every centered intercept first. Forbf(y ~ x, sigma ~ exp(z))brms 2.23.0 givesIntercept,sigma_Intercept,x,sigma_expz. The draws’fixef()listedIntercept,x,sigma_Intercept,sigma_expz, the order of the draws’ columns, which is unchanged.
New features
The draws of a model with frmtmb.spatial’s
sar()carry brms’slagsarorerrorsarcolumn, derived from the sampled internal parameter, asar[1]andcosyare. The names come from core’s registry (frmtmb::frmtmb_autocor_pars()), so a term another package registers gets its own column the same way.The default prior on
lagsaranderrorsaris brms’s: flat onrhoover its interval, whichfrm_sample()announces asuniform(lower, upper), the ends shown to 6 digits. The same holds for a bounded parameter of a term another package registers.set_prior(class = "lagsar")andclass = "errorsar"replace it.
Bug fixes
- The derived
sd_andcor_columns asked core’sfrmtmb_covstruct_info()which structures are fields, where they kept their own list of five names. A field another package registers, beside a block on the same grouping factor, was mapped onto that block’s names. It failed the map’s own check and sent every draw through the slow path: on one model, 0.70 ms a draw against 0.053 ms on the fast path now. The values were right either way. Needs frmtmb 0.75.0, which exportsfrmtmb_covstruct_info().
frmtmb.sample 0.21.1
Needs frmtmb 0.74.0. The package itself loads on frmtmb 0.73.0, but four of its test files need what frmtmb 0.74.0 and frmtmb.latent 0.7.0 add: the covariance structure registry, frmtmb_family(simplex_pars =) and mixture_mvn() in frmtmb.latent.
Bug fixes
- The note of default priors from
frm_sample()names every simplex that a family declares withfrmtmb_family(simplex_pars =), by its brms name. It named only thesbhazsimplex ofcox(), so thedirichlet(1)default on the simplex of another family was not announced. Forcox()the note now reads “sbhaz: dirichlet(1), brms’s default, on the simplex the cox() family declares”.
Other changes
The test of
mixture_mvn()draws reads the family from frmtmb.latent, where it moved, and skips without it. The help ofposterior_predict()andpp_mixture()links it there.frmtmb.survival is a suggested package. The tests of
cox()draws readcox()from it, and skip without it.
frmtmb.sample 0.21.0
Needs frmtmb 0.73.0. It registers its draws methods on the loo_*(), kfold(), reloo(), loo_moment_match() and loo_subsample() generics that frmtmb now defines, and re-exports them. It calls the sampling-API export check_weights_unbounded().
Breaking changes
On a subset of the draws (
ndraws,draw_ids),loo(),psis()and the weights of everyloo_*()function take the relative efficiency on one chain. brms 2.23.0 does the same, and so did theloo_*types ofpp_check(). They usedr_eff = 1. The same draws are now weighted the same way everywhere. On 60-row gaussian and random-intercept models with 4000 draws,loo(ndraws =)at 500, 1000 and 3000 draws moved by at most 0.0065 inelpd_loo. Its standard error was 5.0. On every draw nothing changes, andfrm_sample(thin =)draws keep their chains.posterior_average(weights = "stacking")and"pseudobma"take their weights fromloo_model_weights(): onelog_lik()per model and its relative efficiency, as brms’smodel_weights()does. Before, they read aloocriterion thatadd_criterion()stored, which can come from other draws. Without a stored criterion the weights are identical to the old ones.The
kfold(),reloo(),loo_moment_match()andloo_subsample()generics, and those of the sixloo_*()functions under New features, are frmtmb’s, re-exported here. On a maximum-likelihood fit each refuses, with frmtmb alone attached too: the six namefrm_sample(), the other four what to use instead.loo_moment_match()andloo_subsample()had no method for a fit, even with this package loaded.frm_sample()from a formula refuses a posterior that does not integrate. Suppose that every row with a positive weight has a random effect of its own inmu. The likelihood grows likesigma^-(sum(w) - n)assigmashrinks to 0. A prior that is finite at 0, as brms’s defaultstudent_t(3, 0, s)onsigmais, then leaves the posterior improper oncesum(w) - nreaches 1. Such a run used to return chains that had not mixed (largest Rhat 2.5 on 2 chains of 1000,sigmanear 1e-4). The check is core’s, against the priors the chains sample under. A prior onsigmathat vanishes at 0 fast enough makes the posterior proper but not informative:lognormal(0, 1)gave a posterior mediansigmaof 7.2e-05 and a largest Rhat of 2.83. A usable model has weights that sum to the number of rows or fewer, or no observation-level term.
New features
brms’s leave-one-out functions on draws:
loo_epred(),loo_linpred(),loo_predict(),loo_predictive_interval(),loo_R2()andloo_model_weights(), with brms 2.23.0’s arguments, defaults and output shapes. A multivariate model withoutrespgives one layer per response, named as brms names them, and a category margin stays third. Each computes onelog_lik()and oneloo::psis()per call, on the same draws as the prediction (per response forloo_R2(), per model forloo_model_weights()). The weights are those ofpsis()and ofloo(save_psis = TRUE).psis_object =reuses weights and computes nolog_lik(). On the same posterior draws as a brms 2.23.0 fit, everyloo_epred()andloo_linpred()value is identical to brms’s under R’s reference BLAS. So is everyloo_model_weights()weight (a stacking pair of 0.155 and 0.845). Theloo_R2()bootstrap draws at one seed agree to rounding (largest relative difference 1.1e-14). Under OpenBLAS, where brms’s and frmtmb’s predictors round apart in the last bits, they agree to that rounding.add_criterion(x, "loo_R2")stores theloo_R2()bootstrap draws, as brms stores them, andloo_R2()reads them. It was refused.add_criterion()gives each criterion the arguments it takes, as brms does:add_criterion(x, c("loo", "loo_R2"), seed = 1)seeds the bootstrap and no longer stops inloo().psis()honorsdraw_ids, which it ignored, and refuses an argument it does not read, whichloo::psis()swallowed.loo()and theloo_*()functions accept brms’s default values by name (allow_new_levels = FALSE,sample_new_levels = "uncertainty",newdata = NULL), whichloo()refused, andloo()andloo_model_weights()takedraw_ids.resptakes brms’s spelling (yafor a columny_a) in all six functions, and the layers of a multivariate result carry it.loo_epred(),loo_linpred(),loo_predict(),loo_predictive_interval(),loo_model_weights()andpsis()also take frmtmb’sy_a, whichlog_lik()andposterior_epred()take.loo_R2()takes brms’s spelling only, asbayes_R2()and brms do.brmsfamily("negbinomial2")anddirichlet_multinomial()fits sample under brms 2.23.0’s default priors:sigmaof negbinomial2 getsgamma(0.4, 0.3)from brms’s family hook (where negbinomial’sshapegetsinv_gamma(0.4, 0.3)), andphigetsgamma(0.01, 0.01). On the same data the posterior means agree with brms’s to 0.05 posterior sd, with and without a group term.A
dirichlet_multinomial()fit’s draws take themultinomial()paths:posterior_linpred()with nodparstacks themu<cat>predictors into brms’sdraws x observations x (K - 1)array.posterior_epred()andposterior_predict()returndraws x observations x Karrays that readtrials()fromnewdata.predictive_error()andpp_check(type = "error_binned")refuse the family as polytomous.
Divergences from brms
newdata,re_formulaand the new-level arguments, given a value other than brms’s default, are refused by theloo_*()functions, asloo()refuses them: a weight comes from the observation’s own column oflog_lik(), so it exists only for a row the model was fitted on. brms computes the weights on the new rows’ own response.ndrawsanddraw_idschoose the draws once, for the weights and the prediction. brms draws a separate random subsample for each, so its weights belong to other draws: on a 60-row gaussian model withndraws = 100the two subsamples shared 2 draws.An argument the
loo_*()functions have no use for is an error that names it.loo_linpred(scale = "response"), which brms 2.23.0 reads nowhere (its result is the default’s, on a logit link too), is one.loo_R2()refuses an ordinal or categorical family, asbayes_R2()does. brms refuses the categorical families and computes the ordinal ones with a warning.
frmtmb.sample 0.20.0
Needs frmtmb 0.72.0. It calls the sampling-API export ord_lp_blocks() and writes uniform() and lognormal() priors. It reads the per-response lncor_<resp> names and the per-coefficient sd priors of that release.
Breaking changes
posterior_linpred()with nodparon a family with several location predictors returns brms’sdraws x observations x Parray, every margin unnamed: everymu<cat>ofcategorical(),multinomial()and the simplex families (K - 1layers with a reference category,Kwithout), and every component’smu<k>of a mixture. It returned the first predictor’s matrix. On these familiestransform = TRUEwithout adparis refused in brms’s words, a two-categorycategorical()with its one predictor included.A default steps aside only for a prior on its own slot, as in brms. A narrower prior keeps the defaults on the parameters it does not reach.
set_prior(class = "sd", group = "g")replaces the default on the standard deviations ofg. It keepsstudent_t(3, 0, 2.5)on the other groups. Addingcoef = "x"narrows the prior tosd_g__x. Before, the defaults of the whole class stepped aside, and the other standard deviations were flat.A class-wide prior does not replace a default written per coefficient. For example,
set_prior("inv_gamma(2, 1)", class = "lscale")on agp(x)model keeps brms’s tuned default onlscale_gpx, as brms keeps it. Before, the class-wide prior replaced it. The default-prior message now names a specification that applies to no parameter. That happens for this reason, or when a more specific specification of your own covers its parameters. The message names the coef to write.frm_sample()puts brms 2.23.0’s default prior on every distributional parameter that brms gives one. They were flat on the link scale:shape(gamma(0.01, 0.01), andinv_gamma(0.4, 0.3)for the negative binomials),phi(gamma(0.01, 0.01)),nu(gamma(2, 0.1)) andkappa. So were the exgaussianbeta,alpha,zi,hu,zoi,coiandquantile(beta(1, 1)), and frmtmb.eam’sbs,biasandndt. A parameter with a formula has brms’s default on its intercept, on the link scale. On small data the posteriors move. A betaphinear 300 on 10 rows moved by 30 Monte Carlo standard errors. A negative binomialshapeand a Student-tnuhad no proper posterior before.The ordinal thresholds take brms’s
student_t(3, 0, 2.5), classIntercept, and a mixture’s weights without a formula take brms’sdirichlet(1)on the simplex. Both were flat.sigma ~ 1takes brms’s default on sigma’s intercept. It got a natural-scale default that addressed a slot the model does not have.sigmawithout a formula now reads the response on the identity scale, as brms does. Under a logmulink it read it on the log scale.An
unstr()residual correlation takes brms’slkj(1), classcortime.frm_sample(seed = )fixes every chain. The init jitter of chains 2 and up came from the session’s random stream, so two calls withseed = 3differed unlessset.seed()came first. The jitter is now drawn fromseedand no longer from the session’s stream. rstan’s sampler still advances the session’s stream, as underbrm().A natural-scale default carries brms’s bound on its class where frmtmb’s link does not hold the parameter inside it. A log-linked
ndtis bounded above by the smallest response. An identity- or log-linkednuis bounded below by 1. brms declares them so, and Stan then transforms the draws inside rather than meeting the density’s edge. Where the link holdsndtinside a bound of its own, frmtmb.eam’s, the uniform is over the link’s image and no bound is written:uniform(0, min_Y)for an ungroupedwiener(),lba()orrdm(), anduniform(0, 1)for the fractionndt_group()makes ofndt.posterior_predict(newdata =)reads every addition term from newdata. It read onlytrunc(),rate()andthres(gr = ), and gave the simulator no other term, from the method’s first version on. A binomial withy | trials(N)and newdataN = 1000drew 0 or 1 (column mean 0.595 whereposterior_epred()gave 576.3). A gaussian withse(s)drew at sd 0.033 where newdata hads = 5.predict(),predictive_error()andresiduals()of draws, which call it, change with it. Newdata without thetrials()orse()variable is now refused, naming the term, as brms refuses it.
New features
Draws of a
logistic_normal()response insidemvbf()report its correlations aslncor_<resp>__b__c, with<resp>brms’s Stan name of the response. The sampler’s default puts brms’slkj(1)on each such response.The draws carry brms’s
sd_<group>__<coef>andcor_<group>__<coef1>__<coef2>, and a smooth’ssds_,rescor__,ar[1],cosyandcortime__, as columns of the draws matrix. Soas_draws_df(draws)$sd_g__Interceptworks as on a brms fit. They are derived from each draw’stheta_columns, which stay. The names are core’s, the onesvariables()of the fit lists.
Bug fixes
-
posterior_predict(newdata =)andposterior_predict(re_formula =)hand the simulator each distributional parameter on its natural scale. They handed it the reporting scale, which for a mixture’sthetais already the softmax probability. The simulator applied the softmax again, so the mixing weights were wrong. The defect is in every release from 0.2.0 (frmtmb 0.52.0, whose afd00a43 gave a mixture’s weights their softmax reporting scale). With frmtmb’s fix of the same release, a mixture also draws each class at its own rows’trials().
frmtmb.sample 0.19.0
Needs frmtmb 0.71.0: it reads the sampling-API exports ce_method(), ce_predict_family_check(), ce_sim_one() and pp_check_resp(), ce_plan_eval(one = ), and the gen_extreme_value() chart gev_xi_chart_frame().
Breaking changes
loo()andwaic()of draws take brms’s arguments in brms’s order,(x, ..., compare, resp, ndraws, model_names). Draws given without a name are further models, which are compared as brms compares them. Sondrawsmust be named, as it is in brms.loo()andwaic()of draws refuse by name the arguments they dropped. These arenewdata,re_formulaand the other argumentslog_lik()refuses, which brms reads.loo(newdata = )returned the in-sample elpd in silence (lane remeasure, R2).moment_match = TRUEandreloo = TRUErefit, so they are refused too.pointwiseandk_thresholdchange nothing and are accepted.
New features
The draws of core’s
dirichlet()andlogistic_normal()fits take brms’s shapes.posterior_epred()on adirichlet()fit is thedraws x observations x categoriesarray of category means.posterior_predict()draws rows on the simplex for both families, with layers named by category, as brms’s are.The correlations of a
logistic_normal()fit are the draws columnlncor__b__c, brms’s name. They take brms’slkj(1)default, and eachsigma<k>takes the default that brms givessigma.As in brms,
posterior_epred()refuseslogistic_normal().pp_check()andpredictive_error()refuse both families.frm_sample()samples agen_extreme_value()xiwithout a formula as brms samples it, throughtmp_xi. It mapstmp_xiinto the support that each draw’smuandsigmaleave, and gives it brms’s defaultnormal(0, 2.5). On itslog1pscale the support’s edge was a wall in the sampled space. The review fitted n = 40 data sets atxi-0.45, 0.20 and -0.85 (4 chains x 2000). There 1187, 263 and 3856 of 4000 transitions diverged, with Rhat 2.30 on the last, against 0, 1 and 0 in brms. Throughtmp_xinone diverge, and the posterior mean ofxiis within 0.005 of brms’s at the first two. One difference from brms remains: frmtmb holdsxiabove -1 on every route, where brms’s range goes on (dev/famuni-out/tmpxi.txt,tmpxi-sample.txt). The hold is material where the data put mass there. On the xi -0.85 data brms puts 29 percent of its posterior below -1. Therefrm_sample()’s posterior is brms’s conditioned onxi > -1(median ofxi-0.876 against -0.877; the review’s round 2). A prior on classxiis then a prior ontmp_xi, as in brms. Acens()ortrunc()response, a second GEV response, or GEV components of amixture()keep thelog1pscale, andfrm_sample()warns that they do.frm_sample()puts brms’s defaultnormal(0, 4)on the intercept of a predictedxi,xi ~ 1included (normal(0, 2.5)underlink_xi = "identity").loo()andwaic()of several draws objects return brms’s comparison. It holds the criterion of each model (loos),loo::loo_compare()of them (diffs) and brms’s pairwiseic_diffs__, printed as brms prints itsloolist.compare =andmodel_names =are brms’s. Models with different numbers of observations are refused in brms’s words. Models of different responses get loo’s warning, through brms’syhashattribute.logLik()of draws islog_lik(), the draws by observations matrix, as brms’slogLik()of a fit is. It had no method.bayes_R2()of draws takesnewdataandre_formula, which brms hands toposterior_epred(). Withnewdatait is the R-squared of newdata’s rows, against newdata’s own response column. A newdata without that column is refused in brms’s words.model.frame()of draws is the model frame of their fit. stats’ default rebuilt a frame from the formula’s environment, which holds none of the data. It stopped at “object ‘count’ not found” on brms’s ported rowbrmsfit-methods:120.conditional_effects(method = "predict")on draws (brms’s"posterior_predict") draws one response per grid row and posterior draw, at the parameters of that draw. That is the posterior predictive band brms draws. Under the defaultrobust = TRUE,estimate__is its median andse__its MAD. A category-valued response is refused, as the fit method refuses it.transform =applies to the predicted draws, inconditional_effects(method = "predict")andposterior_predict(), with brms’s warning that the argument is deprecated.frm_sample()of afrm_multiple()result samples the fit of every imputation and combines the draws, as brms’sbrm_multiple()combines its chains.nchains()is the number of imputations timeschains. Aseedgives imputationjthe seedseed + j - 1. Methods that read the data in sample read the first imputed data set, as brms’s do.The diagnostics of combined imputations are brms’s.
summary()leaves outRhat,Bulk_ESSandTail_ESS, as brms’s does for abrm_multiple()fit.loo()takes a relative efficiency of 1, as brms does. Chains of different imputations sample different posteriors, so their R-hat measures the imputations.
Bug fixes
pp_check()of multivariate draws refuses a missing, plural or unknownrespin brms 2.23.0’s words, as the fit method now does. A missing one was “pp_check() is not supported yet for multivariate fits”.summary(draws, waic = TRUE)is refused by name, namingwaic(x). Old brms printed WAIC there, and brms 2.23.0 ignores the argument. It got the generic “has no argumentwaic”.waic = FALSEis accepted.
frmtmb.sample 0.18.0
Needs frmtmb 0.70.0: it reads simplex_frame_terms() and the Dirichlet prior entries frmtmb now resolves, and a cox() fit’s baseline through mo_chart_frame().
Breaking changes
A
cox()baseline is sampled as brms samples it: in softmax coordinates under brms’s defaultdirichlet(1)(classsbhaz), and the draws carry the weights assbhaz[k], brms’s names, in place of thesbhaz_raw_kcoordinates. With no density on the coordinates two of them ran to -3e11 and -9e12 on a right-censored model, with 239 divergences and R-hat 3.07; now the weights’ means and sds agree with brms 2.23.0’s within 2.1 Monte Carlo standard errors on two data sets, with 0 divergences (dev/moparity-cox-sample.R).An exact
gp()field is sampled non-centered, as brms’ssdgp * L zgp, when its sd and length scales have priors (the defaults do). The centered field is a funnel: on lane surface’sy ~ gp(x)the formula route ran 1286 of 2000 transitions into the maximum tree depth with R-hat 1.52 and a bulk ESS of 7; non-centered, none, R-hat at most 1.016, bulk ESS 312 or more, in a third of the time. The factor is a Cholesky factorization of the kernel on the tape,n^3 / 3per gradient fornpositions.reparameterize = FALSEkeeps the centered field.
New features
A
simoorsbhazprior row replacesdirichlet(1)on its simplex, with the softmax’s Jacobian. Withdirichlet(c(5, 1, 1))the draws ofsimo_agree with brms 2.23.0’s on a weakly and a strongly identified simplex: the means within 1.71 Monte Carlo standard errors and the sds within 2.51 (dev/moparity-dir-sample.R).mo()crossed with a factor and group-levelmo()terms sample, with brms’s names (simo_mox:fb1[k],bsp_mox:fb,r_g[, mox]). Onmo(x) * f2, with a two-levelf2, and onmo(x) + (mo(x) | g)the means and sds agree with brms 2.23.0’s within 2.12 Monte Carlo standard errors (dev/moparity-dir-sample.R).as_tmbstan()names only the simplexes with no density on the fit’s tape: a MAP fit with asimorow has its Dirichlet there. The function still samples the fit’s own tape, as documented; it adds no prior.
Bug fixes
-
parnames()on draws warns once whichever generic dispatched it, as on a fit.
frmtmb.sample 0.17.0
Needs frmtmb 0.69.0: it imports and re-exports frmtmb’s stancode(), standata(), pp_mixture() and add_criterion() generics, and it holds a mo() simplex through frmtmb’s mo_simplex(), mo_coords(), mo_chart_frame(), mo_frame_terms() and summary_mo_frame().
Breaking changes
stancode(),standata()andpp_mixture()are frmtmb’s generics, re-exported here; this package keeps its methods for draws. frmtmb defines them because it now has methods for a fit.pp_mixture()’s summary names its componentsP(K = k | Y)and numbers its rows, as brms does and as frmtmb’s method for a fit does. They wereclass1,class2. On draws of a model that is not a mixture it stops in brms’s words, “Method ‘pp_mixture’ can only be applied to mixture models.”, as on a fit.frm_sample()puts brms’s defaultdirichlet(1)on everymo()simplex and reports brms’ssimo_weights. The sampler put no density on a simplex, so the fit’s coordinates were the prior. In frmtmb’s old softmax coordinates that prior is1 / prod(w), and a weakly identified simplex sat at a vertex (44 divergences); in the coordinates frmtmb now fits in it is not integrable at the barycenter, and the draws sat there with sd 0. The simplex is now sampled in softmax coordinates underdirichlet(1), which is the flat density on the simplex (soprior = "flat"keeps it), and the draws carry the weights assimo_<term>1[k], brms’s names, in place of thezeta<j>_kcoordinates. Against brms 2.23.0 on a weakly identified simplex and on brms_monotonic’sfit1(4 chains of 2000 each side), every weight’s mean and sd agree within 1.7 Monte Carlo standard errors, with 0 divergences and R-hat at most 1.0033. Models withoutmo()terms sample exactly as before. Asimorow inprior =is still refused:set_prior()has no Dirichlet density.With more than one
mo()term, each term’s weights are adjacent columns, term by term, as brms orders them.check_laplace()on amo()fit compares each simplex on the weight scale: the ML weights and their delta-method errors (assummary()gives them) against the posterior of thesimo_weights. The coordinates are not comparable, since the fit’s sheet and the draws’ need not be the same. The simplex is sampled underdirichlet(1)there too, the flat density on the simplex, under which the weights’ posterior is the fit’s likelihood; a MAP fit keeps its own prior. A weight at 0 or 1 is reported in a message, with no Wald error.as_tmbstan()says in a message, on a fit withmo()terms, that the simplex has no density on that route (it is sampled flat in the fit’s own coordinates, which a weakly identified simplex collapses in) and thatfrm_sample()samples it underdirichlet(1).
New features
plot()of draws is brms’s display: a histogram and a trace per parameter throughbayesplot::mcmc_combo(),nvariablesto a page, with brms’spars,variable,regex,fixed,combo,bins,theme,plot,askandnewpage, andNas brms’s deprecated alias with brms’s warning. It refused every call before.add_criterion()on draws storesloo,waicandbayes_R2inx$criteriaas brms does, andloo()andwaic()with no further argument return the stored object, brms’suse_stored.overwrite = TRUEclears the stored criterion before it computes, as brms does, so it recomputes.kfold,loo_subsample,loo_R2andmarglikare refused with their own reasons.
Bug fixes
posterior_samples()on draws warns once that it is deprecated. While brms was loaded it warned twice, once from brms’s generic and once from the method.The compatibility pre-flight of
frm_sample()no longer loads R’s base-priority packages to ask whether a name is one of their functions; it reads them without loading. On a headless Linux machine, loading tcltk warned “no DISPLAY variable so Tk is not available” into an unrelated call.check_laplace()leaves a parameter whosez_shiftorsd_ratiois not finite out of its “Laplace/Wald approximation questionable” message. The test passedNAtoif (any(...)), so such a parameter stopped the call (“missing value where TRUE/FALSE needed”) when no other parameter was flagged, and was listed asNAwhen one was. The returned table is unchanged.
frmtmb.sample 0.16.0
Needs frmtmb 0.68.0: for ord_thres_linpred(); for gp_brms_natural(), the prior classes "sdgp" and "lscale" and the kriging draw; and for ordinal mixtures, hurdle_cumulative() with thres(gr = ) and cs(), and the names of the draws of a model with no location column.
Breaking changes
Through frmtmb, a smooth’s null-space draws (
bs_sx_1) are on brms’s scale, and a prior withcoef = "sx_1"is about brms’s parameter: frmtmb now buildss()with brms’sdiagonal.penalty = TRUEbasis.A
gp()term’s draws carry brms’s names on brms’s scales:sdgp_<term>andlscale_<term>where they weretheta_1andtheta_2on the internal log scale, as brms names them (sdgp_gpxfafor levelaofgp(x, by = f)). The lengthscale is on the inputs brms divides by their largest distance.The default priors include brms’s for a GP:
student_t(3, 0, s)on class"sdgp"per prefix, and on class"lscale"an inverse gamma per sub-GP, tuned to that sub-GP’s own distances as brms’sdef_lscale_prior()tunes it.get_prior(route = "sample")lists them; on ninegp()designs every density row equals brmsdefault_prior()’s (63 rows,dev/gpby-priors.R). A Hilbert-spacegp(k = )block, whose lengthscales the defaults left flat, is now non-centered.
New features
posterior_linpred(incl_thres = TRUE)returns brms’s linear predictor with the thresholds included on every ordinal family: a draws by observations by thresholds array with brms’s dimnames, layerkbeingdisc * (thres_k - mu)forcumulative()andsratio()anddisc * (mu - thres_k)forcratio()andacat(), under every threshold structure, withcs()terms, andNApast the thresholds of athres(gr = )level that has fewer. As in brms it is ignored withdpar,nlparortransform = TRUEand on a family that is not ordinal.hurdle_cumulative()is refused, a divergence the user decided on 2026-10-06: brms returns the hurdle probability beside the threshold predictors times1 - huthere, which is the predictor of nothing (dev/upstream-bugs.md, brms-21). An ordinal mixture is refused in brms’s words, “‘incl_thres’ is not supported for mixture models.”Draws of an ordinal mixture carry brms’s names, each component’s thresholds
b_mu1_Intercept[k]andb_mu2_Intercept[k]. Underorder = "mu"both come from the one shared vector, which is read back through the first component that reports it uncentered.posterior_epred()andlog_lik()agree with the theta-weighted sum of brms’s R-side category probabilities at the stored columns to the double epsilon.brms’s default
normal(0, 1)on the intercept of a modeleddisc<k>of an ordinal mixture, as ondisc.Through frmtmb 0.68.0, draws of a
cs()model oncumulative(), as brms samples it: the per-threshold coefficients arebcs_x[k], and a draw’sposterior_epred()equals brms’s own R-side density at that draw to 1.9e-16 (dev/rel068-cs-probe.R). A row whose offsets cross two thresholds hasNaNprobabilities and anNAdraw, as in core.
Bug fixes
A prediction at a position an exact
gp()did not see is a draw of the field there, from its conditional law given the draw’s own values at the fitted positions, as brms’sposterior_epred()draws it. It was that law’s mean, soposterior_epred(newdata = )past the data had no spread from the field itself. At the same 1500 parameter draws of a brms fit, the spread of the predicted field at six new positions is 0.978 to 1.001 of brms’s, where the mean alone reached 0.861 to 1.000 (dev/gpby-brms-epred2.R, final build indev/gpby-p1-nugget-brms-1e-6.txt). The law carries frmtmb’s nugget,1e-6of the variance, as white noise per distinct position, as the fit’s latent values do; two rows at one position take one value exactly.The draw’s factor costs under 1 ms per posterior draw at 300 new positions: a pivoted Cholesky factor that builds only the kernel columns it pivots on (rank 7 to 15 there) and stops where what is left is below
1e-12of the prior variance, which joins the white part (dev/gpby-p1-krigfactor.R). Onposterior_epred()at 300 new positions over 300 draws, CPU time is 0.78 s, against 5.76 s for a dense Cholesky of the same law and 0.63 s for the previous release’s conditional mean, on one machine in one session (dev/gpby-p1-krigdraw.R). # frmtmb.sample 0.15.0
Needs frmtmb 0.67.0: for ord_delta_info(), the ordinal families’ disc and threshold structures and hurdle_cumulative()’s inverse threshold map; for the parnames() generic, which it imports, and the conditional-effects engine that draws crossed and multi-membership new levels; and for arma_cond_fill_dpars(), arma_cond_fill_epred() and response_codes_newdata().
New features
Draws of an ordinal fit with equidistant or sum-to-zero thresholds carry brms’s names: every threshold
b_Intercept[k]and, for equidistant thresholds,delta. The sampler holds fewer parameters than that (two per vector, or one fewer than the thresholds); the columns past them are added after the sampled ones, beforelp__, as a mixture’s last weight is, and dropped again whenever a draw is handed back to the model.brms’s default
normal(0, 1)on the intercept of an ordinal family’sdisc, which is what places that intercept, since the likelihood cannot tell it from the scale of the thresholds. Underlink_disc = "identity"brms useslognormal(0, 1), whichset_prior()does not carry, and the default-prior message names the gap.nsamples(incl_warmup = TRUE)counts the iterations the sampler saved, warmup included, from the stanfit thatfrm_sample()keeps, as brms counts them. It was refused. Draws with no stanfit behind them refuse it by name.nsamples(subset = )takes brms’s check that the subset fits the count.posterior_samples(pars = )returns the coefficients in brms’s order, as brms’svariables()lists them: the intercept of every distributional parameter first (b_Intercept,b_sigma_Intercept,b_x,b_sigma_x), a nonlinear parameter’s intercept staying with its own coefficients (b_a_Intercept,b_a_z,b_b_Intercept). Withoutparsthe columns are those ofvariables(), as before. Aparsthat matches nothing returnsNULL, as in brms.parnames()is frmtmb’s generic, re-exported here. With brms loaded it warns once, as brms’s does; brms’s generic and the method each warned before.conditional_effects()on draws answers crossed(1 | g) + (1 | h) + (1 | g:h)at an unseen combination of observed levels, and a new member of anmm()term with abyvariable.
Bug fixes
A
hurdle_cumulative()fit’s draws are namedb_Intercept[k], as the other ordinal families’ are. They weretau_raw_k.posterior_predict(newdata = )of a model withar(),ma()orarma()andcov = FALSEwas refused as a structured draw, the same refusal as acov = TRUEblock, though core’spredict()answers it. It answers now, and with brms’s treatment of a missing response: a row of newdata whose response isNA, or every row when the column is absent, is filled with a draw at that draw’s parameters before the rows after it read its residual.re_formula =is no longer refused on such a model either.posterior_epred(newdata = )undercov = FALSEfills a missing response with a draw, as brms’sposterior_epred()does, so the expected-response draws on the rows after it carry the spread of the unobserved past. Core’sfitted()on a maximum likelihood fit fills with the expected value instead, because it has no draws to carry the fill through.predictive_error(newdata = )of abernoulli()model codes newdata’s response as the fit coded its own, so a response held as two values other than 0 and 1 (brms’s level-order coding, new in frmtmb) is compared with the draws on the same scale.
frmtmb.sample 0.14.0
Needs frmtmb 0.66.0: for subset_resp_check() and subset_newdata(), for cs_build(), ce_level_plan() and the other engine functions of conditional_smooths() and conditional_effects(), for the ordinal families’ inverse threshold maps that name the draws, and for equated parameters.
Breaking changes
-
An ordinal fit’s draws carry brms’s names. The thresholds are
b_Intercept[1],b_Intercept[2](per group underthres(gr = ), per response in a multivariate model) and hold the thresholds, notcumulative()’s first threshold and log increments; acs()column isbcs_<column>[k]. They weretau_raw_kandbcs<j>_k.variables(ds)now lists whatvariables(fit)lists. A draws object saved with the old names still works. Code that selectedtau_raw_1from the draws must selectb_Intercept[1]now. The names come from each ordinal family’s inverse threshold map, which frmtmb 0.66.0 declares.
Bug fixes
posterior_predict(),posterior_epred()andposterior_linpred()onfrm_sample(laplace = TRUE)draws returned silently wrong numbers. Such draws hold no random effects, and every draws method read them in the layout of full draws:sigmaandthetalanded in the random effects andNApast the last column. Ony ~ x + ar(t, g) + (1 | g)all 4500 cells ofposterior_epred()were NaN; atnewdatathe values were finite and wrong, each group effect read offtheta_1orlp__.fitted(),predict(),residuals()andbayes_R2()returned the same kind of numbers;pp_check(),predictive_interval(),pp_mixture()andhypothesis()onsd_quantities stopped in an internal error fromquantile()or bayesplot. Laplace draws are now read in their own layout. A quantity that reads what was integrated out (the group-level coefficients, a smooth’s coefficients,mi()values) is refused, naming the function you called, aslog_lik()already refused; one that does not, such asre_formula = NAon a model with group-level terms alone, is computed exactly and equals the full draws’ answer bit for bit. The new “Laplace draws” section of?frm_samplelists both, and says why the missing values are not filled in (user decision, 2026-09-29).-
conditional_effects()on draws underre_formula = NULLreads each grid row’s groups by brms’s rule (found by lane sampfix). Withconditions = data.frame(g = <a level>), every draw’s effects for a NEW group were drawn into the first level and predicted there: movingr_g[1,]orr_g[2,]by 10 left the curve where it was, and levels 1 and 2 drew the same curve. The rule is now core’s, per row and per group-level term: a term reads its draws where the row sets every one of its grouping variables to an observed level, inconditionsor as an effect ("x:g"), and draws a new level otherwise, from each draw’s own covariance: an unset variable, an unseen level ("99"), a row of a mixedconditionscolumn, or a nested(1 | g / h)withgset andhunset. At levels 1, 2 and 3 every column and the spaghetti frame equal brms’s at the same five draws, with a difference of 0 (dev/postfit2-celevel-brms.Rin the frmtmb repository), and"x:g"equals brms’s to 1.6e-8.On a
gr(g, by = f)term a row reads only the term of its ownflevel; everyre_formula = NULLdisplay of such a model was refused before, even at an observedg. Anmm(g1, g2)term’s unset members are new levels instead of the first observed one. At the same draws and seed, thegr()band at an unseengand themm()band with members unset equal brms’ssample_new_levels = "gaussian"bands to 8.9e-16 (dev/postfit2-p2-brms.Rin the frmtmb repository). Two different unseen members are two new levels here; brms 2.23.0 draws them once, an artifact of how it numbers unseen values.mm(g1, g2)beside(1 | g1)withg1unset or unseen now draws both new levels, where it was refused. One new level is drawn once per draw and shared by every panel that names it. The core NEWS has the details. predictive_error(),pp_check()andbayes_R2()of draws no longer read a missingmi()response as an observation. The frame holds the placeholder 0 there, and the predictive error was0 - yrep; it isNAnow, as brms’s is,bayes_R2()isNA, as brms’s is, andpp_check()leaves the row out with brms’s warning. App_check()loo type on such a model is refused by name, sincelog_lik()is not defined there; it died inside bayesplot.frm_sample(laplace = TRUE)on a model with nothing to integrate out died in tmbstan with “invalid argument to unary operator”. It now says so and samples the model itself; the draws equal those of the call withoutlaplace. On a REML fit sampled as it stands (prior = "flat") it is refused: that objective integrates the coefficients out too, and the draws carriedb_Interceptover other parameters’ values.frm_sample()on a model with one outer parameter (y ~ 0 + x) died in rstan with “no more scalars to read”: a length-one init was read as a scalar. Each init is now passed as a one-dimensional array.A draws object with
stanfit = NULLworks with every method that reads the chain count (nchains(),summary(),VarCorr(),as_draws_*(),posterior_summary(),mcmc_plot()and more), as one chain.nuts_params()andlog_posterior()refuse it by name.
New features
-
pp_check()’sloo_pit_overlay,loo_pit_qq,loo_intervalsandloo_ribbontypes work. They failed on every model, because nothing built the PSIS weights bayesplot needs. They are built as brms builds them,loo::psis()onlog_lik()of the same draws as the predictions, and match brms 2.23.0 bitwise on brms’s own draws. Wherelog_lik()refuses, these types refuse and say so. A type thatbayesplot::available_ppc()does not list, such as the deprecatedloo_pit, is refused with brms’s message. -
posterior_average(), brms’s model-averaged draws: draws from severalfrm_sample()objects in proportion to their weights, given as numbers or computed by"stacking"(the default),"pseudobma","loo"or"waic"."kfold"and"bma"are refused, askfold()andpost_prob()are. On the same draws, weights and seed its output equals brms’s to 1.4e-17, with the same rows, names and attributes (dev/postfit2-brms-compare.Rin the frmtmb repository). -
conditional_smooths()on draws: brms’s median, MAD and quantiles of each smooth term’s curves, and brms’sspaghetti. On ten draws that afixed_parambrms fit shares, every column and the spaghetti frame equal brms’s to 5.3e-15. -
conditional_effects()on draws takesspaghetti,surface,too_farandselect_points, which it refused before. The spaghetti frame equals brms’s to 5.4e-15 on the same ten draws, for a one- and a two-variable effect. On laplace draws it draws its default curves instead of refusing every model with a group-level term. -
log_lik(),posterior_epred(),posterior_linpred(),posterior_predict()andpredictive_error()on a multivariate model whose responses usesubset()need oneresp =, as brms’s do, and onnewdatakeep the rows where the response’s subset isTRUE.log_lik(resp = )returns one column per row of that response. -
posterior_predict(newdata = )reads the exposure of arate()response fromnewdata. -
nobs()passes brms’sresp =to the fit’s method, which counts that response’s rows. - The draws of a model with an equated parameter,
bf(y ~ x, sigma1 = "sigma2"), carry asigma1column that is a copy ofsigma2, as brms’s draws do, and the default priors skip the equated parameter, which owns no coefficient. -
as.array(),as.matrix()andas.data.frame()of draws take brms’schainanditeration, which brms hands toposterior::subset_draws():as.array(ds, chain = 1)is the first chain. They were refused by name. Any other name is still refused. -
conditional_effects(categorical = FALSE)on ahurdle_cumulative()fit scores the expected category by the category codes, so the hurdle scores 0, as core’s does. Every other ordinal family is unchanged. - The default-prior disclosure names
kappa, which brms gives a gamma prior, besideshape,phiandnu:xbeta()andvon_mises()carry it.
frmtmb.sample 0.13.0
Needs frmtmb 0.65.0, for arma_cond_resp() and arma_cond_dpars(). With an older frmtmb the package installs and loads, and then log_lik(), loo() and posterior_predict() stop at their first call with “could not find function”.
log_lik()andloo()now work on brms’s defaultcov = FALSEform ofar(),ma()andarma(), which was refused before. A row’s log-density is taken at brms’s one-step conditional mean, the regression on the group’s earlier OBSERVED residuals, so a column is an observation and the columns multiply to the whole likelihood. It matchesbrms::log_lik()cell for cell at the same parameter values (gaussianar(1)bitwise; studentarma(1,1)andarma(1,1) + (1 | g)to 4.4e-15 absolute), andloo(),waic()andpsis()follow.loo()’s help says what that makes the estimate: PSIS-LOO over these columns leaves out one CONDITIONAL density, the one-step-ahead density of a row given its observed past, and not the series. Thecov = TRUEcovariance form,cosy()andunstr()stay refused, because there the smallest independent unit is a whole group; the refusal now names the form that does factor.A draws object with no
stanfitbehind it no longer errors inlog_lik():x$stanfit@simis an error and not aNULLon such an object, so the chain identifier could not be read at all.
frmtmb.sample 0.12.0
Needs frmtmb 0.64.0, for rescor_row_loglik() and fit_extras(resp =).
log_lik()on a Student-trescormodel used the gaussian joint density. It now uses the multivariate t through frmtmb’srescor_row_loglik(); on the test fixture the old value was 38.6 log units off. On a multivariate model with an ordinal response, each response reads its own thresholds.Draws of the models frmtmb 0.64.0 adds:
thres(gr = )thresholds per group,gr(g, by = f)blocks merged inranef(),coef()andVarCorr()as brms merges them, andposterior_predict()for brms’scov = FALSEARMA drawn around each row’s one-step mean.An intercept written
0 + Intercept, or underbf(center = FALSE), gets no default prior, as brms leaves class"b"flat.The flat-prior advice no longer reads
class = "Intercept", = ""for a univariate intercept.
frmtmb.sample 0.11.0
The
pp_check(type = "error_binned")refusal on draws of a multinomial fit calls the response a set of counts over categories, not a category, as the fit method now does.Two test files no longer leave
Rplots.pdfin the tests directory:test-draws-methods.R, whose device guard covered one block and not thepairs()call, and the generatedtest-brms-suite-methods.R, whose generator now opens a null device for the file.posterior_predict()on draws now draws acs()term. On ansratio(),cratio()oracat()model with a category-specific effect it drew every row as if the term were absent, in sample and atnewdata, with no warning.predict()andpp_check()on draws go through it and change with it.posterior_epred()andlog_lik()were right and are unchanged. Needs the frmtmb that exportscs_offsets_add().On draws, a
newdatawith a grouping level the fit did not see is refused by the draws methods themselves, with or withoutallow_new_levels, and the refusal says thatallow_new_levels = TRUEis refused too. Without the flag, core’s message reached the caller and recommended “Use allow_new_levels = TRUE”, which the draws methods then refused. The same holds forsample_new_levelsalone and for anewdatawithout the grouping column.re_formula = NAwithallow_new_levels = TRUEand an unseen level now answers, as brms does, instead of being refused: the check asked about the level without there_formulathat drops it.The default priors of a categorical, multinomial, mixture or latent-class model carry the
dparof each location (mub,mu1), as brms writes them. They used to be written without it, which frmtmb now refuses, so this is what keeps those models sampling. The resolved defaults are the same parameters with the same densities. With no prior of your own, a categorical or mixture fit samples exactly as before. With adparprior of your own on a mixture, the default for that slot now steps aside instead of being written and then overridden, which changes the order the priors are applied in: the draws at a fixed seed differ (by up to 8.74 on one measured fit), andprior_summary()no longer lists the overridden defaults. The resp-, dpar- and nlpar-qualified defaults of the other families with several location dpars (lba(),rdm(),hmm(),lca(),mixture_mvn()) follow the same rule.The default-prior announcement names each slot with its
resp,dparandnlpar, so every line is a spellingset_prior()takes. On a multivariate model it used to printInterceptwith no response.hypothesis()’s advice for a coefficient with no proper prior gives a fullset_prior()call, withresp,dpar,nlparandcoefas the model needs them. It used to sayset_prior(class = "b"), which a multivariate model refuses.
frmtmb.sample 0.10.0
The default priors are brms’s on a multivariate model: each response gets its own
Intercept,sigmaandsddefaults, read off that response, andset_rescor(TRUE)getslkj(1)on the residual correlation. Until now a multivariate model was sampled with no default priors at all. This moves the draws of every multivariate model sampled withoutprior = "flat".The default intercept location takes off the mean
offset(), as brms does:y ~ 1 + offset(off)withynear 2 andoff = 10getsstudent_t(3, -8, 2.5), where it gotstudent_t(3, 2, 2.5). A location is now written to 15 significant digits, as brms writes it. This moves the draws of a model with an offset in its location formula.The
sddefault is written once per response, distributional parameter and nonlinear parameter, to follow frmtmb’s brms scoping of class"sd". With noprior =, every standard deviation gets the density it got before. Withprior = set_prior(..., class = "sd"), that prior now replaces the location parameter’s default only, and aphiorsigmablock keeps its own default, as in brms. A SMOOTH’s smoothing standard deviation is keyed the same way, sosigma ~ s(z)gets its own default and its ownsdrow. This moves the draws of a distributional model sampled with a class-widesdprior.BREAKING:
predictive_error()andresiduals()on draws refuse an ordinal, categorical or multinomial model, as brms refuses them.pp_check()on draws refusestype = "error_binned"for a category response in the same words the fit method uses, and ignoresrespon a model with one response, which is what brms does with it. A multivariate model still selects withrespand still refuses a name none of its responses has.A one-sided
re_formulaon draws keeps the terms it names, inposterior_epred(),posterior_linpred(),posterior_predict(),fitted()andpredict(). Each draw is evaluated throughfrmtmb::frm_linpred(), which kept every term for any formula; the fix is in frmtmb’s development version, so it needs that frmtmb. On a(1 + x | g) + (1 | h)fit,re_formula = ~ (1 | g)used to be off the draw’s own intercept-only construction by up to 2.98; it now equals it. A term the fit does not have is an error that names it. The draws already carry each draw’s sampled group effects, so the uncertainty at a known level was in them before and nothing is added.
frmtmb.sample 0.9.0
log_lik()is frmtmb’s generic now, re-exported here, rather than a second generic of the same name defined in this package. frmtmb owns the name because it has a method for it:log_lik(fit)on a maximum-likelihood fit refuses and names the route to draws, asloo()andwaic()do, where it used to be “could not find function”.log_lik(draws)is unchanged, and thefrmtmb_drawsmethod is still registered on rstantools’ generic as well. The method page is?log_lik.frmtmb_draws;?frmtmb::log_likdocuments the generic.posterior_epred()andposterior_predict()on draws refuse every name in...they do not read, where they used to ignore it, as the other methods here already do. The new-level arguments pass through to the refusal described below.Requires frmtmb 0.61.0, for
log_lik(),frm_linpred(),fixef_by_dpar(),brms_fixef_rows()and the brms shape helpers.fitted(),predict()andresiduals()on draws exist (item 2.6f). They are brms’s three summarizing methods, each a summary of the draws method beside it:posterior_epred(),posterior_predict()andpredictive_error(). Before this there was no method at all, sofitted(ds)reachedstats::fitted.default(), readds$fitted.valuesand returnedNULL, a wrong answer with nothing said.summary = FALSEgives the draws,robustandprobsare brms’s, andpredict()on an ordinal or categorical response returns brms’sP(Y = k)proportions.-
BREAKING:
nsamples(),posterior_samples()andparnames()answer instead of refusing. All three were refused as “the deprecated brms spelling”. brms keeps all three live with a deprecation warning, and the refusal stopped a ported script dead where brms’s warning does not. Each now does what brms’s does and warns as brms warns:-
posterior_samples(x)isas.data.frame(x), with brms’spars(a regular expression unlessfixed = TRUE),add_chain,subset,as.matrixandas.array; -
nsamples(x)isndraws(x), with brms’ssubset; -
parnames(x)isvariables(x).
nsamples(incl_warmup = TRUE)is still refused:frm_sample()discards the warmup rather than storing it, so there is nothing to count. -
fixef()on an ordinal draws object reports the thresholds,Intercept[1],Intercept[2], then the coefficients and anycs()terms, in brms’s order and on the model’s own scale, which is what the fit’sfixef()reports. It reported the slopes alone, because the sampler stores the thresholds astau_raw.posterior_epred(),posterior_linpred(),posterior_predict(),fitted(),predict()andresiduals()on draws refuseallow_new_levels = TRUEwhennewdataholds a grouping level the fit did not see, with a message that names the function called and says why. That case used to fail in the design builder with “Use allow_new_levels = TRUE”, which the caller had just done. Predicting an unseen level from draws is not implemented;predict(fit, allow_new_levels = TRUE)on the maximum-likelihood fit does it. Every other use answers as before:allow_new_levels = FALSE, brms’s default, andTRUEwith nonewdataor with levels the fit saw.BREAKING:
hypothesis()on draws no longer returns an object of classbrmshypothesis. The class is"frmtmb_hypothesis"alone; the shape and every element are unchanged, and what stops working isis(x, "brmshypothesis")andinherits(x, "brmshypothesis")in a ported script. frmtmb ownsprint()andplot()for its own class, so neither changes.-
point_estimateandndraws_point_estimateare honored byposterior_epred(),posterior_predict(),posterior_linpred()andlog_lik(). They were accepted and ignored, soposterior_epred(ds, point_estimate = "median", ndraws_point_estimate = 2)returned all 25 draws where brms returns- As in brms it is a PARAMETER-space operation: the draws are collapsed to their mean or median first and the method runs once at that one vector, repeated
ndraws_point_estimatetimes.
- As in brms it is a PARAMETER-space operation: the draws are collapsed to their mean or median first and the method runs once at that one vector, repeated
posterior_epred(),posterior_linpred()andposterior_predict()build each draw’s prediction withfrmtmb::frm_linpred()rather thanpredict(), which is brms’s predictive summary in frmtmb 0.61.0.
frmtmb.sample 0.8.0
Requires frmtmb 0.60.0, for
frm_stop()and the other condition helpers.tmbstan (>= 1.2.1)in Suggests, andcheck_tmbstan_build()now names that version as the remedy. The CI step that pinned a dated snapshot of the Stan trio is removed.Requires the frmtmb release that exports
frm_stop(); thefrmtmb (>= 0.59.0)floor must move to it.BREAKING: every error, warning and message that frmtmb.sample raises is classed. An error has the class
c("frmtmb_sample_error", "frmtmb_error", "error", "condition"), and warnings and messages follow the same pattern, sotryCatch(frmtmb_error = )catches any refusal. The class vector no longer containssimpleError,simpleWarningorsimpleMessage. See?frmtmb::frmtmb-conditions.BREAKING: a value that matches none of the choices of
loo_compare(criterion =),hypothesis(scope =),pp_check(prefix =)andpredictive_error(method =)is refused with afrmtmb_sample_errorthat names the argument, the value and the choices. The old text was'arg' should be one of .... A partial value still matches.posterior_interval(),as.matrix(),rhat(),neff_ratio()and the other accessors refuse an exact variable name that the draws do not carry as afrmtmb_sample_error. The posterior package used to raise it as a plain error. The text keeps posterior’s words,missing in the draws object.
frmtmb.sample 0.7.0
Requires frmtmb 0.59.0, for
brms_par_labels(),brms_coef_table(),brms_stan_name(),expand_b(),varcorr_layout(), thehypothesis()helpers (hyp_eval_in(),hyp_expr_vars()) andcheck_prior_slots()on?frmtmb::frmtmb-sampling-api.BREAKING: the draws carry brms’s names.
b_Intercept,b_x,b_sigma_Interceptfor the coefficients andr_g[1,Intercept]for a group-level coefficient (r_gs[lev.1,Intercept]for a level with a space,r_g:h[1_p,Intercept]for an interaction group), inds$draws,variables(), everyas_draws_*(),as.matrix(),as.array(),as.data.frame(),rhat(),neff_ratio(),summary()andposterior_summary(). They wereIntercept,x,sigma_Interceptandb[1]. A covariance parameter brms does not sample keeps the nameconfint()gives it on the fit,theta_1; a block with no brms counterpart (reduced rank, smooth, GP, CAR, SPDE) keepsb[i]. What stops working:ds$draws[, "x"], and anything that selectedb[columns.-
BREAKING: a distributional parameter nobody wrote a formula for is stored on its natural scale, under brms’s name. The column is
sigma(orshape,nu, andsigma_yafor responsey_aof a multivariate model) and holds sigma, as brms’s does. It used to beb_sigma_Interceptholding log sigma, which brms reports only whensigma ~ 1is written out, sofixef(ds)had a row,coef(ds)$ga slice, andposterior_summary(ds)andas_draws_df(ds)a column that brms does not have. They are gone. What stops working:ds$draws[, "b_sigma_Intercept"]on such a model; usesigma, orlog(ds$draws[, "sigma"])for the old values.A mixture’s weights are stored as brms’s simplex:
theta1 ... theta<K-1>hold the mixing probabilities, and brms’sthetaKis a derived column beforelp__. They used to be the log ratio under the nametheta1_Intercept. Every reader that hands a draw to the model maps allKback to the log ratios together. Draws labels a level repeats are suffixed as brms suffixes them. Levels
lvl 1andlvl.1are bothr_gd[lvl.1,Intercept]in brms, which names the later oner_gd[lvl.1,Intercept]__1. Without the suffix every accessor failed on “Duplicate variable names”.hypothesis()on draws refuses a name that matches two columns instead of reading the first.BREAKING: the accessors return brms’s objects.
as.matrix(),as.array()andas.data.frame()return brms’s unclassed draws objects and take brms’spars,variable,drawandsubset, with brms’s deprecation warnings;as_draws_*()takevariable,regexandinc_warmup;as_draws()is brms’sas_draws_list().posterior_summary(x, pars, variable, probs, robust)andposterior_interval()cover every variable by default, as brms’s do. Compared against brms’s own installed methods on the same draws: 88 of 90 callsidentical(), the other 2rvarsobjects that differ only by a cache environment (dev/brmsnames-findings.md).BREAKING:
fixef(),ranef(),coef()andVarCorr()are brms’s.summary = FALSEreturns the raw draws, as in brms, where it used to return a summary;robust,probs,parsandgroupsare brms’s.coef()broadcasts every population-level coefficient, as brms’s does, andVarCorr()has brms’ssd/cor/cov/residual__structure, with oneresidual__row per response on a multivariate model.ranef()on a model with no group-level effects is refused with brms’s message.ranef()andcoef()on a reduced-rank block, whose draws are factor scores rather than coefficients, compute the coefficients per draw; onfrm_sample(laplace = TRUE)draws, which carry no group-level draws, they are refused by name rather than returned asNA.BREAKING:
hypothesis()returns brms’sbrmshypothesisobject, takesclass = "b"by default and brms’s argument order, supportsrobust,seedandscope = "ranef"or"coef", and reportsEvid.RatioandPost.Probin brms’s columns.evid_ratio,post_prob,z,pandattr(h, "draws")are gone; the draws areh$samples. The string is read with brms’s renaming, sox:feis the interaction coefficient and not R’s:operator, and a stored column such asr_g[1,Intercept]can be named withclass = NULL, as in brms.BREAKING:
bayes_R2()on a multivariate model returns one row per response,R2yaandR2y2, as brms does. It returned the first response alone, namedR2y_a.resptakes brms’s spelling of a response (ya).BREAKING: brms’s positional slots on six more methods.
bayes_R2(ds, NULL, TRUE, TRUE)now asks for brms’srobustsummary; the fourth slot used to beprobsand returned aQ100column.posterior_summary()’s second slot ispars,hypothesis()’s third isclass,pairs()’s second ispars,conditional_effects()’s third isconditionsandpp_check()’s fourth isprefix. The formals audit ofdev/brmsmatch-beyond.Rnow finds 0 of 68 methods diverging, from 6.BREAKING:
summary()has brms’s columns and slots:Estimate,Est.Error,l-95% CI,u-95% CI,Rhat,Bulk_ESS,Tail_ESS, withprob,robustandmc_se.BREAKING:
conditional_effects()defaults to brms’srobust = TRUE:estimate__is the median of the drawn curves andse__their MAD.robust = FALSEgives the mean and SD it used to.pp_check()takes brms’sprefix,group,x,newdata,respanddraw_ids, and brms’s default draw count with brms’s message.log_lik()takes brms’spointwise,combine,add_point_estimateandcores, and refuses an argument it does not have, which it used to accept and ignore.
frmtmb.sample 0.6.0
-
BREAKING, and a published number moves.
rhat()andneff_ratio()now answer brms’s question. They calledbayesplot::rhat()andbayesplot::neff_ratio()on thestanfit, which isrstan::summary()’s classic split-R-hat and rstan’sn_eff. brms computes neither.rhat.brmsfitisposterior::summarise_draws(rhat = posterior::rhat), the rank-normalized split-R-hat, andneff_ratio.brmsfitismin(ess_bulk, ess_tail) / ndraws. Both now do the same, computed on the draws array rather than on thestanfit.Measured on 4 chains of 500 (
dev/brmsmatch-findings.md): the oldrhat()differed from brms’s by 0.00563108 at most, against a whole signal ofmax|rhat - 1| = 0.0100318, so by 1.15 times the entire excess over 1 that the diagnostic reports.neff_ratio()differed by 0.43165, which is 77 times larger and is the number a user reads to decide whether to sample longer.These two no longer agree with
ds$stanfit, which carries a different definition of the same idea.rstan::summary(ds$stanfit)$summarystill has the sampler’s own numbers for anyone who wants them. -
BREAKING.
summary()’s convergence columns move with them. It reported rstan’sn_effand classic split-R-hat; it now reportsRhat,Bulk_ESSandTail_ESSfrom posterior, which is whatbrms:::summary.brmsfit()reports, under brms’s own column names.The
n_effcolumn is gone.summary(ds)[, "Rhat"]is now exactlyrhat(ds)on those rows andneff_ratio(ds)is exactlypmin(Bulk_ESS, Tail_ESS) / ndraws(ds), so the package no longer disagrees with itself. It did: on the fit measured indev/reviews/20260915-brmsmatch.md,sigma_Interceptread 0.99990396 in theRhatcolumn against 1.0037623 fromrhat(ds), BELOW 1 in one place and above it in the other, andxread 1600.37 effective draws against 1028.60, a 55.6 percent overstatement of the number a user reads to decide whether to sample longer. rhat()andneff_ratio()now report frmtmb’s parameter names. They reported Stan’s, because they read thestanfit: 4 of 11 entries on the measured fit (beta[1],beta[2],betad,theta) were not addressable by the namesvariables(ds)lists, sorhat(ds)["x"]wasNA. It is now a number. This falls out of the change above rather than being separate work.Both take brms’s
pars, and it is brms’sparsFOR THESE TWO, which is not theparsthatas.mcmc(),mcmc_plot()andposterior_interval()take.brms:::rhat.brmsfit()passesvariable = parstoas_draws_array()rather than throughextract_pars(), soNULLis the default and means every variable, a string is an EXACT variable name,regex = TRUEmakes it a regular expression, and a name that is not there is an error. The other three keep theextract_parsrule, whereNAmeans every variable and a string is a regular expression.?draws-diagnosticsdocuments both under Two differentparsrules, both brms’s.-
BREAKING. Ten methods take brms’s arguments in brms’s POSITIONS. A positional call ported from brms used to answer a different question, twice without saying so. Every method below now matches brms’s method name for name, as far as this package’s own arguments go, and
tests/testthat/test-draws-spellings.Rasserts that against the installed brms.-
as.mcmc(x, pars, fixed, combine_chains, inc_warmup, ...), was(x, combine_chains, ...).as.mcmc(ds, TRUE)used to return the pooled draws; brms reads that slot asparsand refuses aparsthat is neitherNAnor character, and so does this now. -
posterior_interval(object, pars, variable, prob, regex, fixed, ...), was(object, prob, variable, ...).posterior_interval(ds, 0.9)used to return a 90% interval; it is now the same refusal brms gives. -
log_lik(object, newdata, re_formula, resp, ndraws, draw_ids, ...), was(object, ndraws, resp, ...). -
mcmc_plot(object, pars, type, variable, regex, fixed, ...), was(object, type, variable, ...). -
posterior_epred(object, newdata, re_formula, re.form, resp, dpar, nlpar, ndraws, draw_ids, ...), was(object, newdata, resp, re_formula, re.form, ndraws, ...). -
posterior_linpred(object, transform, newdata, re_formula, re.form, resp, dpar, nlpar, incl_thres, ndraws, draw_ids, ...). -
posterior_predict(object, newdata, re_formula, re.form, transform, resp, negative_rt, ndraws, draw_ids, ...). -
pp_mixture(x, newdata, re_formula, resp, ndraws, draw_ids, log, summary, robust, probs, ...), was(x, summary, ndraws, ...). -
predictive_error(object, newdata, re_formula, re.form, method, resp, ndraws, draw_ids, ...), was(object, resp, re_formula, re.form, ndraws, ...). -
psis(log_ratios, newdata, resp, model_name, ndraws, ...), was(log_ratios, ndraws, resp, ...).
A call that named its arguments is unaffected. A call that passed them positionally must be re-read.
-
New along the way, because brms puts them in those positions:
draw_idson the predictive methods, onlog_lik()and onpp_mixture()names the draws to use by row index;dparonposterior_epred();log,robustandprobsonpp_mixture();methodonpredictive_error(), which also takesnewdatanow and re-evaluates the response term on it.Eight brms arguments are carried in brms’s position and refused, each with the reason and the replacement:
log_lik(newdata =),log_lik(re_formula =),psis(newdata =),pp_mixture(newdata =),pp_mixture(re_formula =),as.mcmc(inc_warmup = TRUE),posterior_linpred(incl_thres = TRUE)andposterior_predict(negative_rt = TRUE).re_formula = NULLis brms’s own default and is refused nowhere: it is the no-op these methods already do.Two spellings of the random-effect switch survive on the five methods where brms itself ACCEPTS both, which is not the same as the four that declare both.
posterior_epred(),posterior_linpred(),posterior_predict()andpredictive_error()declarere_formulaand lme4’sre.formonbrmsfit.predictive_interval()declares neither and honors both anyway, because its whole brms body isposterior_predict(object, ...), so the alias reaches a formal one frame down.tests/testthat/test-draws-spellings.Rderives “brms accepts it” from brms’s own code rather than restating a list.BREAKING, one method.
pp_check()no longer takesre.form. Note that this is the one place the package is knowingly narrower than brms:pp_check.brmsfit()forwards its dots toposterior_predict()throughdo_call(), so brms accepts the alias there too.dev/argspell-brms-accepts.Rin the monorepo has the measurement, and the decision is open rather than settled.BREAKING. An argument that lands in a method’s
...is an error naming it, rather than being swallowed. Every method of this package that took a...it never read now refuses one;dev/argspell-report.Rin the monorepo reports 0 still swallowing. See the frmtmb NEWS entry for why the refusal is the part that prevents the class.
frmtmb.sample 0.5.0
frmtmb.sample no longer breaks brms, rstantools, loo, bridgesampling, bayesplot, posterior, coda or gratia. This package defined its own generic for 28 names those packages own, such as
log_lik(),posterior_epred(),psis(),rhat()andas.mcmc().UseMethod()reads the method table of the namespace where the generic it reached was defined, so afterlibrary(brms); library(frmtmb.sample),log_lik(fit)on abrmsfitfound no method. Measured on the previous release: all 28 lost after brms, all 28 with brms only loaded, all 28 inside a package that imports frmtmb.sample, and every gratia method forposterior_samples()after gratia. It is now 0 in each of those orders. The package now callsfrmtmb::frm_install_generics()from its.onLoad(), so each name resolves to the owner’s generic while the owner is loaded and to this package’s own while it is not.Two methods reached a foreign
.defaultin silence and now reach their own. With posterior loaded after this package,rhat()on draws went to posterior’srhat.default; with gratia loaded after it,posterior_samples()went to gratia’s. Both are now also registered on those owners’ generics.-
BREAKING. Three generics take their owner’s first argument, so a call that NAMED the old one fails:
-
bridge_sampler(samples, ...), was(x, ...), as bridgesampling. -
bayes_factor(x1, x2, log = FALSE, ...), was(x, ...), as bridgesampling. -
rhat(x, ...), was(object, ...). posterior and bayesplot both definerhatwith different first arguments; this follows posterior, which is the one brms uses.
Two only GAIN arguments and break nothing:
post_prob()gainsprior_probandmodel_namesfrom bridgesampling, andposterior_samples()gainsparsfrom brms.posterior_linpred()’s generic gainstransform, which its method already had.If you write an S3 method on any of these names, match the owner’s formals.
-
While brms is loaded,
parnames()andposterior_samples()on draws give brms’s own deprecation warning before this package’s refusal, because the generic that runs is brms’s.gratia (>= 0.9.0)joins Suggests, the first gratia withposterior_samples(), andposteriorgains the floor(>= 1.0.0), whoserhat()this package now registers a method on. As in frmtmb, a partial install of either on the library path that lacks the generic, loaded before this package, stops it loading.The
frmtmbfloor moves to the release that exportsfrm_install_generics().
frmtmb.sample 0.4.2
Requires frmtmb 0.56.0, and the requirement is a hard one.
hypothesis()on afrmtmb_drawsobject now arms the note about a covariate that shadows a distributional parameter itself, throughfrmtmb::hyp_shadow_arm()andhyp_shadow_disarm(), which no earlier frmtmb exports. Before this release the draws method relied on core’s generic to arm that note; once frmtmb 0.56.0 stopped owning thehypothesisgeneric, the note fired on a fitted model and never on draws, in every session and whether or not brms was loaded.The generics this package re-exports from frmtmb no longer break brms’s methods when brms is loaded. With brms loaded but not attached, 26 of 26 re-exports lost their brms method in 0.4.1 and 0 of 26 do now. That repair comes from frmtmb 0.56.0 and reaches this package for free.
Three method signatures now carry their generics’ full formals, because an S3 method must accept every argument its generic declares and the generics are now the owners’ rather than frmtmb’s.
This package still DEFINES 28 generics of its own that break brms’s methods in the same way frmtmb’s did. That is not fixed here.
frmtmb.sample 0.4.1
A broken
tmbstannow skips the sampler tests instead of erroring them, andskip_sampler()asks the package’s own detector rather than only whethertmbstanis installed. 111 test blocks reach a sampler; 47 of them had been using a file-local copy ofskip_sampler(), so searching for the helper’s name looked like coverage. All 111 go through it now.The
\donttestexamples carried the same weak guard. Fifteen topics called a sampler behindrequireNamespace(), which a broken build satisfies. An example cannot skip, so it must not run.A check that does not depend on the marker string. On an affected build
rstan::grad_log_prob()disagrees with-fit$obj$gr(), since the patched log-density overload isrequire_not_st_varand the missed one isrequire_st_var. With infinite bounds the two are the same number bitwise, 0 ulp over four model shapes and five points, so this catches an upstream that renames the placeholder, which the marker cannot.The check workflow pins the Stan trio to a dated snapshot and fails if
model.hppis still unpatched, reporting the state it measured rather than a boolean. Public RSPM rebuilttmbstanthe day after StanHeaders 2.39.1 landed, and four consecutive green runs of this package’s checks sampled a standard normal instead of the model.
frmtmb.sample 0.4.0
BREAKING. frm_sample(control =) is the SAMPLER’s control list now, brms’s spelling and brms’s meaning, passed to tmbstan unchanged. The fit-time options move to fit_control =. as_tmbstan() already meant control that way, so the two entry points agree rather than offering a third convention, and brms code that tightens adapt_delta ports across unchanged.
That closes a silent discard. On the fitted-object route
control = list(adapt_delta = 0.99)was IGNORED:stan_args[[1]]$controlcame back NULL where 0.97 was asked for, and the meanaccept_stat__was 0.9266 against 0.9836 once the setting arrives.fit_control,start,data2,na.actionandREMLwere silently ignored on that route too, and are refused by name. An abbreviation is refused as well:contro =fell into..., reachedrstan::sampling()and partial matched onto ITScontrol, bypassing every check.as_tmbstan()no longer returns an emptystanfitwithout saying so. That was worse than a missing refusal: it bricked the session, and every later model failed withempty_nested() must be true. Both doors share one check, and a run that produced nothing is worded apart from a model that cannot be sampled at all, because those want different fixes.frm_sample()reads the compatibility registry before taping and refuses a fit the sampler cannot run, in about half a second with rstan never loaded, against the roughly three seconds the failure used to take. Where the formula position settles it the match is made on position; where it cannot, the match is made on names, and?frm_samplesays that is the largest set justifiable that way rather than a sound one.frm_sample(control =)is the SAMPLER’s control list now, which is what brms means by the name.frm_sample(fit, control = list(adapt_delta = 0.99, max_treedepth = 12))ports straight from abrm()call and reaches rstan through tmbstan. The fit-time optionsfrm()takes arefit_control =, and they still apply only on the formula route. This is a breaking rename, and the old shape is refused rather than reinterpreted: afrmtmb_control()list arriving incontrolis caught by the field names it carries and the refusal namesfit_control. The two vocabularies share no name, which is what makes the two lists decidable, and a test asserts they stay disjoint. An option rstan does not have is also refused by name, because rstan answers an unknown one by declining to sample and returning an empty fit, which used to be reported as a solver failure. So is an ABBREVIATION of the name:controlfollows...in the formals, so only the exact spelling binds to it, and a shorter one would land in...and then partial-match rstan’s owncontrol, reaching the sampler unchecked.vignette("brms-posterior")carried a row sayingadapt_deltahad no route through this function; it now says the opposite.frm_sample()refuses an assembly argument on a fitted object instead of accepting and discarding it.fit_control,start,data2,na.actionandREMLbuild a model, and a fitted object is already built, so on that route they were read by nothing and said nothing:frm_sample(fit, REML = TRUE)sampled the model it had.dataandfamilywere already refused there; these five now are too, and the message points atcontrolfor the caller who meant the sampler.fit_controlmatters most, because it is the name thecontrolrefusal sends a confused user to.Breaking, and a return-contract change:
as_tmbstan()never hands back an emptystanfitnow. rstan answers some failures by declining to sample, printing its reason to the console and returning the shell of astanfitwith no error at all.frm_sample()has always refused that;as_tmbstan()passed it on, so a failed run looked like a successful one until an accessor came back empty. Both now raise the same message, naming the function that raised it. The wording distinguishes the two ways to get nothing out of this package, because they want different fixes: a model that cannot be sampled at all is refused by the compatibility pre-flight before any chain starts, and this one is a failure of the run in front of you. Nothing in the package or its vignettes relied on the empty object.Fixed: a sampler control list handed to a fitted object was discarded without a word. Up to and including 0.3.2,
frm_sample(fit, control = list(adapt_delta = 0.99))on the fit route ran the chains with rstan’s own defaults and said nothing:controlwas read only where the formula route assembles a model, and the fit route does not go there. A brms user porting a call that raisedadapt_deltatherefore got the untightened sampler. The argument now reaches rstan on both routes, andds$stanfit@stan_args[[1]]$controlrecords what was asked for.-
A pre-flight against the compatibility registry, on
frm_sample()and onas_tmbstan(). Both read the rows that namefrm_samplewith the status"refused"before anything is taped, before the formula route callsfrm(), and before the rstan and tmbstan namespaces are loaded, so a model the sampler cannot run costs the registry read and nothing else: 0.36 s to 0.42 s on the first call of a session against the 2.9 s failure it replaces, and that failure also left rstan unusable for the rest of the session. The refusal repeats the registered note and names the row.frmtmb.oderegisters the first such row.What the check refuses on is deliberately narrow, because what identifies a feature in a model is WHERE its call sits in the formula. It decides three ways. A response FAMILY is matched by name, which is exact; it does not look inside
mixture(). An ADDITION TERM is matched by POSITION, since it is written inside the bar on the left of the response formula and nowhere else, which separatesy | se(v) ~ xfromy ~ a * se(x)with a user’s ownse(). Everything else the vocabulary writes as a call is matched by NAME, outside addition-term position, and only when the name is not also a base R function; that route is justifiable from names but not sound, so a refusal registered onmo(),ma(),cosy()ormm()would also fire on a user’s function of that name. Everything the check cannot decide warns and samples rather than refusing a model that may be correct. A registered refusal cannot be revoked by a later registration: display names are unique, core refuses a second registration of one, and a name the vocabulary writes without parentheses is declared not to be a call at all.
frmtmb.sample 0.3.2
Requires frmtmb 0.55.0, for the hazard-container lint that now runs in this package’s own check.
frmtmb.sample 0.3.1
The sampling articles say why they are unevaluated, and the reason they used to give was false: four chains on the model in question take seconds, not the minutes claimed. They are unevaluated because the samplers are optional dependencies and because that page documents a Stan build which samples the wrong density silently. The two chunks that need no sampler now run, so the page shows output.
loo()on a group-unit matrix says which unit it left out.loo::loo.matrix()never sees the attribute the log-likelihood matrix carries, so the printed estimate was indistinguishable from a per-observation one.
frmtmb.sample 0.3.0
conditional_effects() on draws returns core’s frame, grid and display quantity; hypothesis() reports Savage-Dickey evidence ratios validated against brms; loo() says which unit it leaves out. Requires frmtmb 0.53.0 for the seam exports.
conditional_effects()on a draws object now returns the frame core’s fit method returns, which closes the divergence 0.2.0 recorded. The columns and their order are core’sce_frame(): the varied predictor(s), then every other model variable at the value it is held at, thencond__,cats__,effect1__andeffect2__, then the band.cond__is always present as a factor over every condition level, so brms’s ownplot()has something to facet on; a per-category ordinal display is keyed"x:cats__"rather than"x", so brms’splot()reads the pair back out of the effects attribute; andint_conditions =,categorical =andseed =are formals here as they are on the fit method. A ported script that indexed the returned frame positionally, or that readce$xon an ordinal fit, has to be read again.BUG FIX.
conditional_effects()on draws drew themupredictor where the fit method draws the EXPECTED RESPONSE, on every family whose mean is not the inverse link ofmuand on everytrunc()response. A zero-inflated fit was plotted1 / (1 - zi)times too high, a mixture showed one component’s mean instead of the mixture’s, and a response truncated below at zero reported a NEGATIVE mean and drew it. The column names, the grid and the keys were all correct throughout, which is why the first round’s identity checks passed. The display quantity now comes from core’s ownce_pred_dpar(), so the two surfaces cannot make different choices again. Measured after the fix, largest deviation from the fit curve over a five-point grid: 1.4% zero-inflated, 1.0% truncated, 0.5% mixture, against 21.7% and a sign change before it. An explicitly nameddpar =was always correct and is unchanged.conditional_effects()on draws acceptsallow_new_levelsand lme4’sallow.new.levels, which the fit method has always accepted and this method warned about as unknown. It reads them with core’s ownce_dots(), so the accepted set cannot drift again.hypothesis()refusesabs(x) = 0instead of reporting a Bayes factor twice too large. The affine check probed only non-negative points, whereabs()is the identity; it now probes both signs. The prior of|X|forX ~ N(0, 1)is a half-normal with twice the density at zero, so the denominator was half what it should have been, silently.The
"evid_ratio_mcse"attribute is measured over at least four blocks of draws. With two chains it was the standard deviation of two numbers oversqrt(2)- one degree of freedom - and understated a measured 0.46 gap between two runs of one model as 0.18. Chains are split in half when there are fewer than four, which keeps each block consecutive and so keeps the autocorrelation the estimator exists to respect.A point hypothesis on a natural-scale summary says so.
sigma = 0.9used to refuse with “not a population-level coefficient”, which is true of the name and false of the model:sigmaIS a coefficient here, reported on a scale its prior is not written on. That is now the reason given, for every such quantity.BEHAVIOR CHANGE.
conditional_effects(re_formula = NULL)on draws conditions on a NEW group, as it does on a fit, instead of silently taking the first observed level. The grid’s grouping column reportsNAand each POSTERIOR DRAW gets that group’s effects drawn from its own covariance parameters, which is brms’s construction; the fit method draws them per bootstrap replicate instead. The band is wider than the population band by the amount the new group’s variance adds (1.92 to 3.93 in mean width on the model indev/sample-ce-findings.md).seed =makes the draw reproducible.conditional_effects()on draws reports an argument it cannot use instead of discarding it in silence.hypothesis()on a draws object reportsevid_ratioandpost_prob, brms’sEvid.RatioandPost.Prob. A directional hypothesis gets the posterior odds of the claim, which needs no prior. A POINT hypothesis gets the Savage-Dickey density ratio: the posterior density of the tested quantity at the point, from a kernel density withstats::density()’s defaultnrd0bandwidth over 4096 grid points read by spline, over the PRIOR density there, evaluated from the specification the model was sampled under rather than estimated from prior draws. brms estimates both halves by kernel density fromsample_prior = "yes"draws; the two agree to the accuracy of that estimate, and the numbers are indev/sample-ce-findings.md. The between-chain Monte Carlo error of each ratio rides on the returned object as the"evid_ratio_mcse"attribute, because a density ratio read without one is easy to over-believe.A point hypothesis whose parameter has no proper prior REFUSES BY NAME, with a warning that says which parameter and why, and leaves
evid_ratioNA; the rest of the row is unaffected and the other hypotheses of the same call still report.frm_sample()leaves class"b"flat by default exactly as brms does, so this is the commonest answer until a prior is written. A hypothesis on a variance component, on a nonlinear function of the coefficients, or on the intercept (whose prior is about the intercept at the predictor means, not about the coefficient) refuses for its own stated reason.log_lik(),loo()andwaic()accept a structured family that declares how its likelihood factorizes (frmtmb::frmtmb_structure(loglik_group = )or(loglik_row = )), instead of refusing every family whose likelihood is not rowwise. The columns are the pieces the family declares, at the coarsest granularity it gives, because a family that groups its likelihood is saying its rows are not independently droppable. The matrix carriesattr(x, "unit")naming what a column is when it is not an observation. A family that supplies one number for the whole response is still refused, in the words it already used.
frmtmb.sample 0.2.0
BEHAVIOR CHANGE, following core.
ranef()on afrmtmb_drawsobject is keyed by the GROUPING FACTOR rather than by the block, soranef(draws)[["1 | g"]]returnsNULLwhere it used to return an array andranef(draws)$greturns it instead. The method delegates to core’sranef()once per draw, so it follows core’s re-key exactly; the block label rides along in each array’s"term"attribute, as it does in core. A model with two blocks on ONE factor gives two entries under one name, and the method now assembles them BY POSITION: keyed by name,out[[tn]] <- stwrote the same name twice, so the SECOND block was dropped entirely and the list came back with one entry instead of two.conditional_effects()on a draws object inherits four grid changes from core, because it builds its grids with core’sce_grids_build(): the two-variable grid now varies the FIRST effect slowest (brms’s row order), a numeric moderator is held at the exactmean +/- sdrather than atsignif(mean +/- sd, 3), amo()predictor gets one grid point per level instead of a 100-point continuous grid, and atrials()variable is held at 1 with a message that is new here. What it does NOT yet inherit is core’s frame shape: the returned columns, the always-presentcond__, the"x:cats__"key for a per-category display,int_conditions =,categorical =and the new-group meaning ofre_formula = NULLare core-only for now, so the two surfaces disagree in both directions until the draws method is migrated.frm_sample()refuses parallel chains on Windows when the model’s family comes from a namespace built bypkgload::load_all(), naming the package and the two remedies. A worker process cannot load such a namespace, and R silently substitutes the global environment for it, so the family failed at its first internal call and rstan reported only that the chains returned no draws.The defaults this package registers with
frmtmb::get_prior()now answerroute = "sample"only. Loading this package used to change the tableget_prior()returned for every caller, an author asking aboutfrm()included; it no longer does. Ask forget_prior(..., route = "sample")to see whatfrm_sample()applies, and with this package unloaded that route is refused rather than reported as flat.frm_sample()itself is unchanged: the same defaults under the same call-over-fit-over-defaults precedence.The frmtmb floor rises to 0.51.0. The registration in
.onLoad()now passesfrmtmb_register_compat(expects = ), which frmtmb gained in 0.51.0, and an older frmtmb stops the load outright withunused argument (expects = c("hmm", "lca")). The old floor of 0.46.0 permitted an installation that could not load, so this is a hard requirement rather than a preference.frmtmb.latentjoinsSuggests.hmm()andlca()left frmtmb for that package, so the tests here that sample one of them qualify the call and skip when it is absent. The two compatibility rules this package registers for those pairs are declared infrmtmb_register_compat(expects = ), which says they name a feature another package owns. Before frmtmb checked, those rules were dropped without a word in every session that did not also loadfrmtmb.latent; nowfrm_compat()reports them as unresolved until it is loaded.
frmtmb.sample 0.1.0
First release, extracted from frmtmb 0.46.0.
- NUTS sampling for frmtmb models through tmbstan:
frm_sample()on a fit or a formula, with brms 2.23’s default priors on both routes, priors stacking most-explicit-first, and non-centered sampling of qualifying random-effect blocks. Draws carry frmtmb parameter names. - The full posterior method surface on core’s generics and on the brms, loo, posterior, bayesplot, rstantools, coda and bridgesampling generics:
log_lik(),loo(),waic(),posterior_epred(),posterior_predict(),hypothesis(),conditional_effects()on draws,bayes_R2(),mcmc_plot(), and the rest. -
check_laplace()measures the Laplace and Wald approximations against NUTS on the same objective, centered and with no added priors. - At load, the package registers its sampling default priors with core’s
get_prior()and its feature rows with the compatibility matrix, so both stay truthful whether or not this package is installed. - Refuses a tmbstan built against StanHeaders 2.39 or later, whose code generator leaves one log-density overload unpatched so every chain silently samples a standard normal instead of the model.
- Parallel chains work on every platform, Windows included: tmbstan rebuilds the tape on each socket worker from the serialized objective closure, and frmtmb’s generated closures are self-contained.