\name{fitdistrBayes_model}
\alias{fitdistrBayes_model}
\alias{print.fitdistrBayes_model}
\title{Define a User-Supplied Bayesian Distribution Model}
\usage{
fitdistrBayes_model(density, prior, start, name = "user-defined",
  lower = NULL, upper = NULL, fixed = NULL,
  engine = c("adaptive_metropolis", "slice", "custom"),
  sampler = NULL, independent = FALSE, engine_label = NULL,
  propriety = NULL, moments = NULL, rng = NULL,
  rng_validator = NULL, validate = NULL,
  density_is_log = NULL, prior_is_log = NULL,
  prior_style = c("auto", "scalar", "vector"),
  prior_label = "user-defined",
  prior_kernel = "user-supplied function", reference = NULL)

\method{print}{fitdistrBayes_model}(x, ...)
}
\arguments{
  \item{density}{A density function whose first argument is the observation
  vector. Remaining named arguments are model parameters. An explicit logical
  \code{log} argument is recommended.}
  \item{prior}{A prior-density function accepting either named scalar
  parameters or a named parameter vector.}
  \item{start}{A finite, uniquely named numeric vector of starting values.}
  \item{name}{A nonempty model label used in fitted output.}
  \item{lower, upper}{Optional scalar, complete, or partially named parameter
  bounds. Missing bounds are infinite.}
  \item{fixed}{Optional named list of fixed model quantities.}
  \item{engine}{One of \code{"adaptive_metropolis"}, \code{"slice"}, or
  \code{"custom"}. The slice route requires one unknown parameter.}
  \item{sampler}{For \code{engine = "custom"}, a posterior-sampling function.
  See Details for its input and output contract.}
  \item{independent}{Whether draws returned by a custom sampler are
  independent. If true, MCMC convergence diagnostics are not applicable.}
  \item{engine_label}{Optional descriptive label for a custom sampler.}
  \item{propriety}{Optional user declaration or executable check of posterior
  propriety. It can be \code{NULL}, one logical value, one explanatory string,
  or a function of \code{(x, fixed)}. A function returns a logical value or a
  list with \code{proper} and \code{message}.}
  \item{moments}{Optional data frame, or function of \code{(x, fixed)} returning
  a data frame, with columns \code{parameter}, \code{mean_exists},
  \code{variance_exists}, and optionally \code{note}.}
  \item{rng}{Optional posterior-predictive generator. Its first argument is the
  requested sample size and its remaining arguments are model parameters.}
  \item{rng_validator}{Optional function verifying values generated by
  \code{rng}.}
  \item{validate}{Optional data-support function of \code{(x, fixed)}. It
  returns \code{TRUE} for valid data; \code{FALSE} or an explanatory string
  rejects the data before posterior computation.}
  \item{density_is_log, prior_is_log}{Optional logical declarations for
  functions that do not expose a \code{log} argument.}
  \item{prior_style}{Whether the prior accepts named scalars, one named vector,
  or should be detected automatically.}
  \item{prior_label, prior_kernel}{Prior metadata stored in the fitted object.}
  \item{reference}{Optional bibliographic or methodological note stored with
  the specification.}
  \item{x}{A \code{fitdistrBayes_model} object.}
  \item{...}{Additional arguments, currently ignored by the print method.}
}
\value{
\code{fitdistrBayes_model()} returns an object of class
\code{"fitdistrBayes_model"}. It is a list containing the density and prior
functions; named starting values and parameter bounds; fixed quantities; the
selected posterior engine and optional custom sampler; user-supplied
propriety, moment, support, and prediction components; and descriptive
metadata. It contains no fitted values until passed to
\code{fitdistrBayes(x, distr = model)}.

The print method returns its input invisibly and is called for the side effect
of displaying the model name, parameters, prior, engine, and availability of a
propriety declaration.
}
\description{
Creates a non-stateful model specification for distributions or priors not in
the built-in objective-prior catalogue. The same \code{fitdistrBayes()} output
and methods are used for built-in and user-supplied models.
}
\details{
The adaptive Metropolis and slice engines construct the posterior kernel from
\code{density}, \code{prior}, and the Jacobian implied by \code{lower} and
\code{upper}. The custom engine delegates posterior simulation while retaining
the package's validation, summaries, diagnostics, prediction, and pointwise
log-likelihood interface.

A custom \code{sampler} receives the subset of its formal arguments matching
\code{x}, \code{log_posterior}, \code{log_posterior_unconstrained},
\code{start}, \code{fixed}, \code{lower}, \code{upper},
\code{to_unconstrained}, \code{from_unconstrained}, \code{iter},
\code{warmup}, \code{thin}, \code{chains}, \code{n_save}, \code{control}, and
\code{dots}. It returns either one matrix when a single chain was requested, a
list of chain matrices, or a list containing a \code{chains} component and
optional \code{independent}, \code{engine}, acceptance, and initialization
components. Chain matrices are on the natural parameter scale, have
\code{n_save} rows, and have one named column per parameter.

Propriety and moment declarations supplied through this constructor are
reported explicitly as user-supplied. They are executable metadata, not a
mathematical certification by the package authors. If propriety is omitted,
the fit warns and records it as the user's responsibility. If moment
conditions are omitted, posterior medians and quantiles remain available, but
means, standard deviations, and their Monte Carlo errors are not reported.
}
\examples{
# A new Laplace model with a proper, non-objective prior.
d_laplace <- function(x, location, scale, log = FALSE) {
  value <- -log(2 * scale) - abs(x - location) / scale
  if (log) value else exp(value)
}
p_laplace <- function(location, scale, log = FALSE) {
  value <- dnorm(location, 0, 5, log = TRUE) +
    dlnorm(scale, 0, 0.75, log = TRUE)
  if (log) value else exp(value)
}
r_laplace <- function(n, location, scale) {
  location + scale * ifelse(runif(n) < 0.5, -1, 1) * rexp(n)
}
laplace_model <- fitdistrBayes_model(
  d_laplace, p_laplace, start = c(location = 0, scale = 1),
  lower = c(scale = 0), name = "Laplace",
  propriety = "proper Normal--Lognormal prior for a nonconstant sample",
  moments = data.frame(
    parameter = c("location", "scale"),
    mean_exists = c(TRUE, TRUE), variance_exists = c(TRUE, TRUE),
    note = rep("finite under the stated proper prior", 2)
  ),
  rng = r_laplace,
  validate = function(x) length(x) >= 2 && diff(range(x)) > 0,
  prior_label = "Normal--Lognormal"
)
set.seed(1)
x_laplace <- r_laplace(25, location = 1, scale = 1.5)
fit_laplace <- fitdistrBayes(
  x_laplace, laplace_model, iter = 200, warmup = 80,
  chains = 2, seed = 2,
  control = list(warn_convergence = FALSE)
)
coef(fit_laplace)
}
