% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/kl_optim.R
\name{make_kl_fun}
\alias{make_kl_fun}
\title{Build a KL-divergence point function for use with opt_des()}
\usage{
make_kl_fun(
  family1,
  model1,
  params1,
  par_values1,
  family2 = family1,
  model2 = model1,
  params2 = params1,
  phi1 = 1,
  phi2 = phi1
)
}
\arguments{
\item{family1}{character; reference distribution (\code{"Normal"},
\code{"Poisson"}, \code{"Binomial"} or \code{"Gamma"}).}

\item{model1}{formula; reference model mean function.}

\item{params1}{character vector; parameter names in \code{model1}.}

\item{par_values1}{numeric vector; nominal values for the reference parameters.}

\item{family2}{character; rival distribution (default: same as \code{family1}).}

\item{model2}{formula; rival model mean function (default: same as \code{model1}).}

\item{params2}{character vector; rival parameter names (optimised internally).
Default: same as \code{params1}.}

\item{phi1}{positive numeric; dispersion of the reference
(\code{Normal}: variance; \code{Gamma}: \eqn{1/\text{shape}}).}

\item{phi2}{positive numeric; dispersion of the rival (default: same as \code{phi1}).}
}
\value{
A function \code{function(x, beta2)} giving the point KL divergence.
Works for both 1-D (\code{x} scalar) and multi-factor designs (\code{x}
named numeric vector).
}
\description{
Returns a \code{function(x, beta2)} computing the point KL divergence at
design point \code{x} given rival parameters \code{beta2}.  The result is
passed to \code{\link{opt_des}} via the \code{kl_fun} argument, allowing
discrimination between models with different family, dispersion, or mean
structure without having to derive the formula manually.

Supported family pairs:
\itemize{
\item Same family and same \code{phi}: any of
\code{"Normal"}, \code{"Poisson"}, \code{"Binomial"}, \code{"Gamma"}.
Uses the standard exponential-family cumulant formula.
\item \code{"Normal"} vs \code{"Normal"} with \code{phi1 != phi2}:
\eqn{KL = \frac{1}{2}\bigl[\log(\phi_2/\phi_1) + \phi_1/\phi_2 + (\mu_1-\mu_2)^2/\phi_2 - 1\bigr]}.
\item \code{"Gamma"} vs \code{"Gamma"} with different shape
(\eqn{k_i = 1/\phi_i}): closed form involving \code{digamma} and
\code{lgamma}.
}
For other cross-family pairs provide \code{kl_fun} directly.
}
\examples{
# Same family (Normal), different model structures
kl_fn <- make_kl_fun(
  "Normal",
  model1 = y ~ Vmax * x / (Km + x), params1 = c("Vmax", "Km"),
  par_values1 = c(2, 1),
  model2 = y ~ a * x, params2 = "a"
)
kl_fn(x = 1, beta2 = 0.5)

\donttest{
# Normal vs Normal with different variance (phi2 = 4)
kl_fn2 <- make_kl_fun(
  "Normal",
  model1 = y ~ a * exp(-b * x), params1 = c("a", "b"),
  par_values1 = c(1, 0.5), phi1 = 1,
  family2 = "Normal",
  model2 = y ~ c * exp(-d * x), params2 = c("c", "d"), phi2 = 4
)
opt_des("KL-Optimality",
        model = y ~ a * exp(-b * x), parameters = c("a", "b"),
        par_values = c(1, 0.5), design_space = c(0, 4),
        kl_fun = kl_fn2, rival_pars = c(1, 1),
        rival_lower = c(0.5, 0.8), rival_upper = c(2, 1.5))
}
}
