R/RcppExports.R

Defines functions calculatePartialResiduals calculateModifiedDevianceResiduals calculateScoreResiduals calculateCoxSnellResiduals calculateQuantileResiduals calculateDevianceResiduals calculatePearsonResiduals calculateResponseResiduals calculateQuantiles calculateProbabilities calculateDensities calculateMeans calculateParameters nrgkw hsbeta grbeta llbeta rbeta_ qbeta_ pbeta_ dbeta_ hskw grkw llkw rkw qkw pkw dkw hsmc grmc llmc rmc qmc pmc dmc hsekw grekw llekw rekw qekw pekw dekw hsbkw grbkw llbkw rbkw qbkw pbkw dbkw hskkw grkkw llkkw rkkw qkkw pkkw dkkw hsgkw grgkw llgkw rgkw qgkw pgkw dgkw gkwgetstartvalues

Documented in calculateCoxSnellResiduals calculateDensities calculateDevianceResiduals calculateMeans calculateModifiedDevianceResiduals calculateParameters calculatePartialResiduals calculatePearsonResiduals calculateProbabilities calculateQuantileResiduals calculateQuantiles calculateResponseResiduals calculateScoreResiduals dbeta_ dbkw dekw dgkw dkkw dkw dmc gkwgetstartvalues grbeta grbkw grekw grgkw grkkw grkw grmc hsbeta hsbkw hsekw hsgkw hskkw hskw hsmc llbeta llbkw llekw llgkw llkkw llkw llmc nrgkw pbeta_ pbkw pekw pgkw pkkw pkw pmc qbeta_ qbkw qekw qgkw qkkw qkw qmc rbeta_ rbkw rekw rgkw rkkw rkw rmc

# Generated by using Rcpp::compileAttributes() -> do not edit by hand
# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393

#' Main function to estimate GKw distribution parameters using the method of moments.
#' This implementation is optimized for numerical stability and computational efficiency.
#'
#' @param x Data vector (must be in (0,1))
#' @param n_starts Number of starting points for optimization
#' @return Vector of estimated parameters \eqn{\alpha, \beta, \gamma, \delta, \lambda}
#'
#' @export
gkwgetstartvalues <- function(x, n_starts = 5L) {
    .Call(`_gkwreg_gkwgetstartvalues`, x, n_starts)
}

#' @title Generate Regularized Positive Definite Approximation of a Hessian
#' @description Creates a positive definite approximation of a Hessian matrix
#' using eigendecomposition and selective eigenvalue adjustment with enhanced
#' numerical stability.
#'
#' @param H Input Hessian matrix (arma::mat)
#' @param min_eigenval Minimum eigenvalue threshold (default: 1e-6)
#' @return Positive definite approximation of H
#' @noRd
NULL

#' @title Calculate Numerical Hessian with Advanced Adaptive Step Size
#' @description Computes a robust numerical approximation of the Hessian matrix
#' using adaptive finite difference methods with cross-validation.
#'
#' @param params Parameter vector
#' @param data Data vector
#' @param ll_func Log-likelihood function
#' @param gr_func Gradient function (used for validation)
#' @param min_step Minimum step size (default: 1e-8)
#' @param base_step Base step size (default: 1e-5)
#' @return Numerical approximation of the Hessian matrix
#' @noRd
NULL

#' @title Calculate Adaptive Parameter Scaling Factors
#' @description Computes intelligent scaling factors for parameters to improve
#' numerical stability in optimization, with automatic detection of parameter
#' patterns and adaptive thresholds.
#'
#' @param params Parameter vector
#' @return Vector of scaling factors
#' @noRd
NULL

#' @title Enhanced Line Search with Wolfe Conditions
#' @description Performs a robust line search that satisfies Wolfe conditions to
#' ensure sufficient decrease and curvature conditions, with improved numerical
#' stability and adaptive bracketing strategies.
#'
#' @param params Current parameter vector
#' @param search_dir Search direction
#' @param data Data vector
#' @param ll_func Log-likelihood function
#' @param gr_func Gradient function
#' @param alpha_init Initial step size (default: 1.0)
#' @param c1 Parameter for sufficient decrease condition (default: 1e-4)
#' @param c2 Parameter for curvature condition (default: 0.9)
#' @param max_iter Maximum line search iterations (default: 20)
#' @return Step size satisfying Wolfe conditions
#' @noRd
NULL

#' @title Force Matrix Symmetry
#' @description Ensures perfect matrix symmetry for numerical stability
#' @param M Input matrix to symmetrize
#' @return Symmetrized matrix
#' @noRd
NULL

#' @title Enhanced Trust Region Update Using Levenberg-Marquardt
#' @description Performs robust parameter updates using an advanced trust region method
#' with Levenberg-Marquardt implementation, incorporating numerical safeguards and
#' adaptive strategies for improved convergence.
#'
#' @param params Current parameter vector
#' @param data Data vector
#' @param ll_func Log-likelihood function
#' @param gr_func Gradient function
#' @param hs_func Hessian function
#' @param trust_radius Current trust region radius (default: 1.0)
#' @param eta Acceptance threshold for step ratio (default: 0.1)
#' @param enforce_bounds Whether to enforce parameter bounds (default: true)
#' @param min_param_val Minimum parameter value (default: 1e-5)
#' @param max_param_val Maximum parameter value (default: 1e5)
#' @return List containing new parameters and trust region information
#' @noRd
NULL

#' @title Advanced Initialization for GKw Family Parameters
#' @description Generates intelligent initial parameter estimates for GKw
#' family distributions based on theoretical moment relationships and
#' distribution properties from Carrasco et al. (2010).
#'
#' @param data Data vector in (0,1)
#' @param family Distribution family (default: "gkw")
#' @param robust Logical; if TRUE, uses robust statistics for initialization (default: TRUE)
#' @return Vector of initial parameter estimates
#' @noRd
NULL

#' @title Density of the Generalized Kumaraswamy Distribution
#' @author Lopes, J. E.
#' @keywords distribution density
#'
#' @description
#' Computes the probability density function (PDF) for the five-parameter
#' Generalized Kumaraswamy (GKw) distribution, defined on the interval (0, 1).
#'
#' @param x Vector of quantiles (values between 0 and 1).
#' @param alpha Shape parameter \code{alpha} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param beta Shape parameter \code{beta} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param gamma Shape parameter \code{gamma} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param delta Shape parameter \code{delta} >= 0. Can be a scalar or a vector.
#'   Default: 0.0.
#' @param lambda Shape parameter \code{lambda} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param log_prob Logical; if \code{TRUE}, the logarithm of the density is
#'   returned. Default: \code{FALSE}.
#'
#' @return A vector of density values (\eqn{f(x)}) or log-density values
#'   (\eqn{\log(f(x))}). The length of the result is determined by the recycling
#'   rule applied to the arguments (\code{x}, \code{alpha}, \code{beta},
#'   \code{gamma}, \code{delta}, \code{lambda}). Returns \code{0} (or \code{-Inf}
#'   if \code{log_prob = TRUE}) for \code{x} outside the interval (0, 1), or
#'   \code{NaN} if parameters are invalid.
#'
#' @details
#' The probability density function of the Generalized Kumaraswamy (GKw)
#' distribution with parameters \code{alpha} (\eqn{\alpha}), \code{beta}
#' (\eqn{\beta}), \code{gamma} (\eqn{\gamma}), \code{delta} (\eqn{\delta}), and
#' \code{lambda} (\eqn{\lambda}) is given by:
#' \deqn{
#' f(x; \alpha, \beta, \gamma, \delta, \lambda) =
#'   \frac{\lambda \alpha \beta x^{\alpha-1}(1-x^{\alpha})^{\beta-1}}
#'        {B(\gamma, \delta+1)}
#'   [1-(1-x^{\alpha})^{\beta}]^{\gamma\lambda-1}
#'   [1-[1-(1-x^{\alpha})^{\beta}]^{\lambda}]^{\delta}
#' }
#' for \eqn{x \in (0,1)}, where \eqn{B(a, b)} is the Beta function
#' \code{\link[base]{beta}}.
#'
#' This distribution was proposed by Cordeiro & de Castro (2011) and includes
#' several other distributions as special cases:
#' \itemize{
#'   \item Kumaraswamy (Kw): \code{gamma = 1}, \code{delta = 0}, \code{lambda = 1}
#'   \item Exponentiated Kumaraswamy (EKw): \code{gamma = 1}, \code{delta = 0}
#'   \item Beta-Kumaraswamy (BKw): \code{lambda = 1}
#'   \item Generalized Beta type 1 (GB1 - implies McDonald): \code{alpha = 1}, \code{beta = 1}
#'   \item Beta distribution: \code{alpha = 1}, \code{beta = 1}, \code{lambda = 1}
#' }
#' The function includes checks for valid parameters and input values \code{x}.
#' It uses numerical stabilization for \code{x} close to 0 or 1.
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#' *81*(7), 883-898.
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#' @seealso
#' \code{\link{pgkw}}, \code{\link{qgkw}}, \code{\link{rgkw}} (if these exist),
#' \code{\link[stats]{dbeta}}, \code{\link[stats]{integrate}}
#'
#' @examples
#' \donttest{
#' # Simple density evaluation at a point
#' dgkw(0.5, alpha = 2, beta = 3, gamma = 1, delta = 0, lambda = 1) # Kw case
#'
#' # Plot the PDF for various parameter sets
#' x_vals <- seq(0.01, 0.99, by = 0.01)
#'
#' # Standard Kumaraswamy (gamma=1, delta=0, lambda=1)
#' pdf_kw <- dgkw(x_vals, alpha = 2, beta = 3, gamma = 1, delta = 0, lambda = 1)
#'
#' # Beta equivalent (alpha=1, beta=1, lambda=1) - Beta(gamma, delta+1)
#' pdf_beta <- dgkw(x_vals, alpha = 1, beta = 1, gamma = 2, delta = 3, lambda = 1)
#' # Compare with stats::dbeta
#' pdf_beta_check <- stats::dbeta(x_vals, shape1 = 2, shape2 = 3 + 1)
#' # max(abs(pdf_beta - pdf_beta_check)) # Should be close to zero
#'
#' # Exponentiated Kumaraswamy (gamma=1, delta=0)
#' pdf_ekw <- dgkw(x_vals, alpha = 2, beta = 3, gamma = 1, delta = 0, lambda = 2)
#'
#' plot(x_vals, pdf_kw, type = "l", ylim = range(c(pdf_kw, pdf_beta, pdf_ekw)),
#'      main = "GKw Densities Examples", ylab = "f(x)", xlab="x", col = "blue")
#' lines(x_vals, pdf_beta, col = "red")
#' lines(x_vals, pdf_ekw, col = "green")
#' legend("topright", legend = c("Kw(2,3)", "Beta(2,4) equivalent", "EKw(2,3, lambda=2)"),
#'        col = c("blue", "red", "green"), lty = 1, bty = "n")
#'
#' # Log-density
#' log_pdf_val <- dgkw(0.5, 2, 3, 1, 0, 1, log_prob = TRUE)
#' print(log_pdf_val)
#' print(log(dgkw(0.5, 2, 3, 1, 0, 1))) # Should match
#'
#' }
#'
#' @export
dgkw <- function(x, alpha, beta, gamma, delta, lambda, log_prob = FALSE) {
    .Call(`_gkwreg_dgkw`, x, alpha, beta, gamma, delta, lambda, log_prob)
}

#' @title Generalized Kumaraswamy Distribution CDF
#' @author Lopes, J. E.
#' @keywords distribution cumulative
#'
#' @description
#' Computes the cumulative distribution function (CDF) for the five-parameter
#' Generalized Kumaraswamy (GKw) distribution, defined on the interval (0, 1).
#' Calculates \eqn{P(X \le q)}.
#'
#' @param q Vector of quantiles (values generally between 0 and 1).
#' @param alpha Shape parameter \code{alpha} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param beta Shape parameter \code{beta} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param gamma Shape parameter \code{gamma} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param delta Shape parameter \code{delta} >= 0. Can be a scalar or a vector.
#'   Default: 0.0.
#' @param lambda Shape parameter \code{lambda} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param lower_tail Logical; if \code{TRUE} (default), probabilities are
#'   \eqn{P(X \le q)}, otherwise, \eqn{P(X > q)}.
#' @param log_p Logical; if \code{TRUE}, probabilities \eqn{p} are given as
#'   \eqn{\log(p)}. Default: \code{FALSE}.
#'
#' @return A vector of probabilities, \eqn{F(q)}, or their logarithms if
#'   \code{log_p = TRUE}. The length of the result is determined by the recycling
#'   rule applied to the arguments (\code{q}, \code{alpha}, \code{beta},
#'   \code{gamma}, \code{delta}, \code{lambda}). Returns \code{0} (or \code{-Inf}
#'   if \code{log_p = TRUE}) for \code{q <= 0} and \code{1} (or \code{0} if
#'   \code{log_p = TRUE}) for \code{q >= 1}. Returns \code{NaN} for invalid
#'   parameters.
#'
#' @details
#' The cumulative distribution function (CDF) of the Generalized Kumaraswamy (GKw)
#' distribution with parameters \code{alpha} (\eqn{\alpha}), \code{beta}
#' (\eqn{\beta}), \code{gamma} (\eqn{\gamma}), \code{delta} (\eqn{\delta}), and
#' \code{lambda} (\eqn{\lambda}) is given by:
#' \deqn{
#' F(q; \alpha, \beta, \gamma, \delta, \lambda) =
#'   I_{x(q)}(\gamma, \delta+1)
#' }
#' where \eqn{x(q) = [1-(1-q^{\alpha})^{\beta}]^{\lambda}} and \eqn{I_x(a, b)}
#' is the regularized incomplete beta function, defined as:
#' \deqn{
#' I_x(a, b) = \frac{B_x(a, b)}{B(a, b)} = \frac{\int_0^x t^{a-1}(1-t)^{b-1} dt}{\int_0^1 t^{a-1}(1-t)^{b-1} dt}
#' }
#' This corresponds to the \code{\link[stats]{pbeta}} function in R, such that
#' \eqn{F(q; \alpha, \beta, \gamma, \delta, \lambda) = \code{pbeta}(x(q), \code{shape1} = \gamma, \code{shape2} = \delta+1)}.
#'
#' The GKw distribution includes several special cases, such as the Kumaraswamy,
#' Beta, and Exponentiated Kumaraswamy distributions (see \code{\link{dgkw}} for details).
#' The function utilizes numerical algorithms for computing the regularized
#' incomplete beta function accurately, especially near the boundaries.
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#' @seealso
#' \code{\link{dgkw}}, \code{\link{qgkw}}, \code{\link{rgkw}},
#' \code{\link[stats]{pbeta}}
#'
#' @examples
#' \donttest{
#' # Simple CDF evaluation
#' prob <- pgkw(0.5, alpha = 2, beta = 3, gamma = 1, delta = 0, lambda = 1) # Kw case
#' print(prob)
#'
#' # Upper tail probability P(X > q)
#' prob_upper <- pgkw(0.5, alpha = 2, beta = 3, gamma = 1, delta = 0, lambda = 1,
#'                  lower_tail = FALSE)
#' print(prob_upper)
#' # Check: prob + prob_upper should be 1
#' print(prob + prob_upper)
#'
#' # Log probability
#' log_prob <- pgkw(0.5, alpha = 2, beta = 3, gamma = 1, delta = 0, lambda = 1,
#'                  log_p = TRUE)
#' print(log_prob)
#' # Check: exp(log_prob) should be prob
#' print(exp(log_prob))
#'
#' # Use of vectorized parameters
#' q_vals <- c(0.2, 0.5, 0.8)
#' alphas_vec <- c(0.5, 1.0, 2.0)
#' betas_vec <- c(1.0, 2.0, 3.0)
#' # Vectorizes over q, alpha, beta
#' pgkw(q_vals, alpha = alphas_vec, beta = betas_vec, gamma = 1, delta = 0.5, lambda = 0.5)
#'
#' # Plotting the CDF for special cases
#' x_seq <- seq(0.01, 0.99, by = 0.01)
#' # Standard Kumaraswamy CDF
#' cdf_kw <- pgkw(x_seq, alpha = 2, beta = 3, gamma = 1, delta = 0, lambda = 1)
#' # Beta distribution CDF equivalent (Beta(gamma, delta+1))
#' cdf_beta_equiv <- pgkw(x_seq, alpha = 1, beta = 1, gamma = 2, delta = 3, lambda = 1)
#' # Compare with stats::pbeta
#' cdf_beta_check <- stats::pbeta(x_seq, shape1 = 2, shape2 = 3 + 1)
#' # max(abs(cdf_beta_equiv - cdf_beta_check)) # Should be close to zero
#'
#' plot(x_seq, cdf_kw, type = "l", ylim = c(0, 1),
#'      main = "GKw CDF Examples", ylab = "F(x)", xlab = "x", col = "blue")
#' lines(x_seq, cdf_beta_equiv, col = "red", lty = 2)
#' legend("bottomright", legend = c("Kw(2,3)", "Beta(2,4) equivalent"),
#'        col = c("blue", "red"), lty = c(1, 2), bty = "n")
#'}
#' @export
pgkw <- function(q, alpha, beta, gamma, delta, lambda, lower_tail = TRUE, log_p = FALSE) {
    .Call(`_gkwreg_pgkw`, q, alpha, beta, gamma, delta, lambda, lower_tail, log_p)
}

#' @title Generalized Kumaraswamy Distribution Quantile Function
#' @author Lopes, J. E.
#' @keywords distribution quantile
#'
#' @description
#' Computes the quantile function (inverse CDF) for the five-parameter
#' Generalized Kumaraswamy (GKw) distribution. Finds the value \code{x} such
#' that \eqn{P(X \le x) = p}, where \code{X} follows the GKw distribution.
#'
#' @param p Vector of probabilities (values between 0 and 1).
#' @param alpha Shape parameter \code{alpha} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param beta Shape parameter \code{beta} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param gamma Shape parameter \code{gamma} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param delta Shape parameter \code{delta} >= 0. Can be a scalar or a vector.
#'   Default: 0.0.
#' @param lambda Shape parameter \code{lambda} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param lower_tail Logical; if \code{TRUE} (default), probabilities are
#'   \eqn{P(X \le x)}, otherwise, \eqn{P(X > x)}.
#' @param log_p Logical; if \code{TRUE}, probabilities \code{p} are given as
#'   \eqn{\log(p)}. Default: \code{FALSE}.
#'
#' @return A vector of quantiles corresponding to the given probabilities \code{p}.
#'   The length of the result is determined by the recycling rule applied to
#'   the arguments (\code{p}, \code{alpha}, \code{beta}, \code{gamma},
#'   \code{delta}, \code{lambda}). Returns:
#'   \itemize{
#'     \item \code{0} for \code{p = 0} (or \code{p = -Inf} if \code{log_p = TRUE}).
#'     \item \code{1} for \code{p = 1} (or \code{p = 0} if \code{log_p = TRUE}).
#'     \item \code{NaN} for \code{p < 0} or \code{p > 1} (or corresponding log scale).
#'     \item \code{NaN} for invalid parameters (e.g., \code{alpha <= 0},
#'           \code{beta <= 0}, \code{gamma <= 0}, \code{delta < 0},
#'           \code{lambda <= 0}).
#'   }
#'
#' @details
#' The quantile function \eqn{Q(p)} is the inverse of the CDF \eqn{F(x)}.
#' Given \eqn{F(x) = I_{y(x)}(\gamma, \delta+1)} where
#' \eqn{y(x) = [1-(1-x^{\alpha})^{\beta}]^{\lambda}}, the quantile function is:
#' \deqn{
#' Q(p) = x = \left\{ 1 - \left[ 1 - \left( I^{-1}_{p}(\gamma, \delta+1) \right)^{1/\lambda} \right]^{1/\beta} \right\}^{1/\alpha}
#' }
#' where \eqn{I^{-1}_{p}(a, b)} is the inverse of the regularized incomplete beta
#' function, which corresponds to the quantile function of the Beta distribution,
#' \code{\link[stats]{qbeta}}.
#'
#' The computation proceeds as follows:
#' \enumerate{
#'   \item Calculate \code{y = stats::qbeta(p, shape1 = gamma, shape2 = delta + 1, lower.tail = lower_tail, log.p = log_p)}.
#'   \item Calculate \eqn{v = y^{1/\lambda}}.
#'   \item Calculate \eqn{w = (1 - v)^{1/\beta}}. Note: Requires \eqn{v \le 1}.
#'   \item Calculate \eqn{q = (1 - w)^{1/\alpha}}. Note: Requires \eqn{w \le 1}.
#' }
#' Numerical stability is maintained by handling boundary cases (\code{p = 0},
#' \code{p = 1}) directly and checking intermediate results (e.g., ensuring
#' arguments to powers are non-negative).
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#' @seealso
#' \code{\link{dgkw}}, \code{\link{pgkw}}, \code{\link{rgkw}},
#' \code{\link[stats]{qbeta}}
#'
#' @examples
#' \donttest{
#' # Basic quantile calculation (median)
#' median_val <- qgkw(0.5, alpha = 2, beta = 3, gamma = 1, delta = 0, lambda = 1)
#' print(median_val)
#'
#' # Computing multiple quantiles
#' probs <- c(0.01, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99)
#' quantiles <- qgkw(probs, alpha = 2, beta = 3, gamma = 1, delta = 0, lambda = 1)
#' print(quantiles)
#'
#' # Upper tail quantile (e.g., find x such that P(X > x) = 0.1, which is 90th percentile)
#' q90 <- qgkw(0.1, alpha = 2, beta = 3, gamma = 1, delta = 0, lambda = 1,
#'             lower_tail = FALSE)
#' print(q90)
#' # Check: should match quantile for p = 0.9 with lower_tail = TRUE
#' print(qgkw(0.9, alpha = 2, beta = 3, gamma = 1, delta = 0, lambda = 1))
#'
#' # Log probabilities
#' median_logp <- qgkw(log(0.5), alpha = 2, beta = 3, gamma = 1, delta = 0, lambda = 1,
#'                     log_p = TRUE)
#' print(median_logp) # Should match median_val
#'
#' # Vectorized parameters
#' alphas_vec <- c(0.5, 1.0, 2.0)
#' betas_vec <- c(1.0, 2.0, 3.0)
#' # Get median for 3 different GKw distributions
#' medians_vec <- qgkw(0.5, alpha = alphas_vec, beta = betas_vec, gamma = 1, delta = 0, lambda = 1)
#' print(medians_vec)
#'
#' # Verify inverse relationship with pgkw
#' p_val <- 0.75
#' x_val <- qgkw(p_val, alpha = 2, beta = 3, gamma = 1, delta = 0, lambda = 1)
#' p_check <- pgkw(x_val, alpha = 2, beta = 3, gamma = 1, delta = 0, lambda = 1)
#' print(paste("Calculated p:", p_check, " (Expected:", p_val, ")"))
#'}
#' @export
qgkw <- function(p, alpha, beta, gamma, delta, lambda, lower_tail = TRUE, log_p = FALSE) {
    .Call(`_gkwreg_qgkw`, p, alpha, beta, gamma, delta, lambda, lower_tail, log_p)
}

#' @title Generalized Kumaraswamy Distribution Random Generation
#' @author Lopes, J. E.
#' @keywords distribution random
#'
#' @description
#' Generates random deviates from the five-parameter Generalized Kumaraswamy (GKw)
#' distribution defined on the interval (0, 1).
#'
#' @param n Number of observations. If \code{length(n) > 1}, the length is
#'   taken to be the number required. Must be a non-negative integer.
#' @param alpha Shape parameter \code{alpha} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param beta Shape parameter \code{beta} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param gamma Shape parameter \code{gamma} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param delta Shape parameter \code{delta} >= 0. Can be a scalar or a vector.
#'   Default: 0.0.
#' @param lambda Shape parameter \code{lambda} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#'
#' @return A vector of length \code{n} containing random deviates from the GKw
#'   distribution. The length of the result is determined by \code{n} and the
#'   recycling rule applied to the parameters (\code{alpha}, \code{beta},
#'   \code{gamma}, \code{delta}, \code{lambda}). Returns \code{NaN} if parameters
#'   are invalid (e.g., \code{alpha <= 0}, \code{beta <= 0}, \code{gamma <= 0},
#'   \code{delta < 0}, \code{lambda <= 0}).
#'
#' @details
#' The generation method relies on the transformation property: if
#' \eqn{V \sim \mathrm{Beta}(\gamma, \delta+1)}, then the random variable \code{X}
#' defined as
#' \deqn{
#' X = \left\{ 1 - \left[ 1 - V^{1/\lambda} \right]^{1/\beta} \right\}^{1/\alpha}
#' }
#' follows the GKw(\eqn{\alpha, \beta, \gamma, \delta, \lambda}) distribution.
#'
#' The algorithm proceeds as follows:
#' \enumerate{
#'   \item Generate \code{V} from \code{stats::rbeta(n, shape1 = gamma, shape2 = delta + 1)}.
#'   \item Calculate \eqn{v = V^{1/\lambda}}.
#'   \item Calculate \eqn{w = (1 - v)^{1/\beta}}.
#'   \item Calculate \eqn{x = (1 - w)^{1/\alpha}}.
#' }
#' Parameters (\code{alpha}, \code{beta}, \code{gamma}, \code{delta}, \code{lambda})
#' are recycled to match the length required by \code{n}. Numerical stability is
#' maintained by handling potential edge cases during the transformations.
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#' @seealso
#' \code{\link{dgkw}}, \code{\link{pgkw}}, \code{\link{qgkw}},
#' \code{\link[stats]{rbeta}}, \code{\link[base]{set.seed}}
#'
#' @examples
#' \donttest{
#' set.seed(1234) # for reproducibility
#'
#' # Generate 1000 random values from a specific GKw distribution (Kw case)
#' x_sample <- rgkw(1000, alpha = 2, beta = 3, gamma = 1, delta = 0, lambda = 1)
#' summary(x_sample)
#'
#' # Histogram of generated values compared to theoretical density
#' hist(x_sample, breaks = 30, freq = FALSE, # freq=FALSE for density scale
#'      main = "Histogram of GKw(2,3,1,0,1) Sample", xlab = "x", ylim = c(0, 2.5))
#' curve(dgkw(x, alpha = 2, beta = 3, gamma = 1, delta = 0, lambda = 1),
#'       add = TRUE, col = "red", lwd = 2, n = 201)
#' legend("topright", legend = "Theoretical PDF", col = "red", lwd = 2, bty = "n")
#'
#' # Comparing empirical and theoretical quantiles (Q-Q plot)
#' prob_points <- seq(0.01, 0.99, by = 0.01)
#' theo_quantiles <- qgkw(prob_points, alpha = 2, beta = 3, gamma = 1, delta = 0, lambda = 1)
#' emp_quantiles <- quantile(x_sample, prob_points)
#'
#' plot(theo_quantiles, emp_quantiles, pch = 16, cex = 0.8,
#'      main = "Q-Q Plot for GKw(2,3,1,0,1)",
#'      xlab = "Theoretical Quantiles", ylab = "Empirical Quantiles (n=1000)")
#' abline(a = 0, b = 1, col = "blue", lty = 2)
#'
#' # Using vectorized parameters: generate 1 value for each alpha
#' alphas_vec <- c(0.5, 1.0, 2.0)
#' n_param <- length(alphas_vec)
#' samples_vec <- rgkw(n_param, alpha = alphas_vec, beta = 2, gamma = 1, delta = 0, lambda = 1)
#' print(samples_vec) # One sample for each alpha value
#' # Result length matches n=3, parameters alpha recycled accordingly
#'
#' # Example with invalid parameters (should produce NaN)
#' invalid_sample <- rgkw(1, alpha = -1, beta = 2, gamma = 1, delta = 0, lambda = 1)
#' print(invalid_sample)
#'}
#' @export
rgkw <- function(n, alpha, beta, gamma, delta, lambda) {
    .Call(`_gkwreg_rgkw`, n, alpha, beta, gamma, delta, lambda)
}

#' @title Negative Log-Likelihood for the Generalized Kumaraswamy Distribution
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize
#'
#' @description
#' Computes the negative log-likelihood function for the five-parameter
#' Generalized Kumaraswamy (GKw) distribution given a vector of observations.
#' This function is designed for use in optimization routines (e.g., maximum
#' likelihood estimation).
#'
#' @param par A numeric vector of length 5 containing the distribution parameters
#'   in the order: \code{alpha} (\eqn{\alpha > 0}), \code{beta} (\eqn{\beta > 0}),
#'   \code{gamma} (\eqn{\gamma > 0}), \code{delta} (\eqn{\delta \ge 0}),
#'   \code{lambda} (\eqn{\lambda > 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a single \code{double} value representing the negative
#'   log-likelihood (\eqn{-\ell(\theta|\mathbf{x})}). Returns a large positive
#'   value (e.g., \code{Inf}) if any parameter values in \code{par} are invalid
#'   according to their constraints, or if any value in \code{data} is not in
#'   the interval (0, 1).
#'
#' @details
#' The probability density function (PDF) of the GKw distribution is given in
#' \code{\link{dgkw}}. The log-likelihood function \eqn{\ell(\theta)} for a sample
#' \eqn{\mathbf{x} = (x_1, \dots, x_n)} is:
#' \deqn{
#' \ell(\theta | \mathbf{x}) = n\ln(\lambda\alpha\beta) - n\ln B(\gamma,\delta+1) +
#'   \sum_{i=1}^{n} [(\alpha-1)\ln(x_i) + (\beta-1)\ln(v_i) + (\gamma\lambda-1)\ln(w_i) + \delta\ln(z_i)]
#' }
#' where \eqn{\theta = (\alpha, \beta, \gamma, \delta, \lambda)}, \eqn{B(a,b)}
#' is the Beta function (\code{\link[base]{beta}}), and:
#' \itemize{
#'   \item \eqn{v_i = 1 - x_i^{\alpha}}
#'   \item \eqn{w_i = 1 - v_i^{\beta} = 1 - (1-x_i^{\alpha})^{\beta}}
#'   \item \eqn{z_i = 1 - w_i^{\lambda} = 1 - [1-(1-x_i^{\alpha})^{\beta}]^{\lambda}}
#' }
#' This function computes \eqn{-\ell(\theta|\mathbf{x})}.
#'
#' Numerical stability is prioritized using:
#' \itemize{
#'   \item \code{\link[base]{lbeta}} function for the log-Beta term.
#'   \item Log-transformations of intermediate terms (\eqn{v_i, w_i, z_i}) and
#'         use of \code{\link[base]{log1p}} where appropriate to handle values
#'         close to 0 or 1 accurately.
#'   \item Checks for invalid parameters and data.
#' }
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#' @seealso
#' \code{\link{dgkw}}, \code{\link{pgkw}}, \code{\link{qgkw}}, \code{\link{rgkw}},
#' \code{\link{grgkw}}, \code{\link{hsgkw}} (gradient and Hessian functions, if available),
#' \code{\link[stats]{optim}}, \code{\link[base]{lbeta}}, \code{\link[base]{log1p}}
#'
#' @examples
#' \donttest{
#' # Generate sample data from a known GKw distribution
#' set.seed(123)
#' true_par <- c(alpha = 2, beta = 3, gamma = 1.0, delta = 0.5, lambda = 0.5)
#' sample_data <- rgkw(100, alpha = true_par[1], beta = true_par[2],
#'                    gamma = true_par[3], delta = true_par[4], lambda = true_par[5])
#' hist(sample_data, breaks = 20, main = "Sample GKw Data")
#'
#' # --- Maximum Likelihood Estimation using optim ---
#' # Initial parameter guess (can be crucial)
#' start_par <- c(1.5, 2.5, 1.2, 0.3, 0.6)
#'
#' # Perform optimization (minimizing negative log-likelihood)
#' # Ensure data is passed correctly to llgkw
#' mle_result <- stats::optim(par = start_par,
#'                            fn = llgkw,
#'                            method = "BFGS", # Method supporting bounds might be safer
#'                            hessian = TRUE,
#'                            data = sample_data)
#'
#' # Check convergence and results
#' if (mle_result$convergence == 0) {
#'   print("Optimization converged successfully.")
#'   mle_par <- mle_result$par
#'   print("Estimated parameters:")
#'   print(mle_par)
#'   print("True parameters:")
#'   print(true_par)
#'
#'   # Standard errors from Hessian (optional)
#'   # fisher_info <- solve(mle_result$hessian) # Need positive definite Hessian
#'   # std_errors <- sqrt(diag(fisher_info))
#'   # print("Approximate Standard Errors:")
#'   # print(std_errors)
#'
#' } else {
#'   warning("Optimization did not converge!")
#'   print(mle_result$message)
#' }
#'
#' # --- Compare numerical and analytical derivatives (if available) ---
#' # Requires the 'numDeriv' package and analytical functions 'grgkw', 'hsgkw'
#' if (requireNamespace("numDeriv", quietly = TRUE) &&
#'     exists("grgkw") && exists("hsgkw") && mle_result$convergence == 0) {
#'
#'   cat("\nComparing Derivatives at MLE estimates:\n")
#'
#'   # Numerical derivatives
#'   num_grad <- numDeriv::grad(func = llgkw, x = mle_par, data = sample_data)
#'   num_hess <- numDeriv::hessian(func = llgkw, x = mle_par, data = sample_data)
#'
#'   # Analytical derivatives (assuming they exist)
#'   # Note: grgkw/hsgkw might compute derivatives of log-likelihood,
#'   # while llgkw is negative log-likelihood. Adjust signs if needed.
#'   # Assuming grgkw/hsgkw compute derivatives of NEGATIVE log-likelihood here:
#'   ana_grad <- grgkw(par = mle_par, data = sample_data)
#'   ana_hess <- hsgkw(par = mle_par, data = sample_data)
#'
#'   # Check differences (should be small if analytical functions are correct)
#'   cat("Difference between numerical and analytical gradient:\n")
#'   print(summary(abs(num_grad - ana_grad)))
#'
#'   cat("Difference between numerical and analytical Hessian:\n")
#'   print(summary(abs(num_hess - ana_hess)))
#'
#' } else {
#'    cat("\nSkipping derivative comparison.\n")
#'    cat("Requires 'numDeriv' package and functions 'grgkw', 'hsgkw'.\n")
#' }
#'
#' }
#'
#' @export
llgkw <- function(par, data) {
    .Call(`_gkwreg_llgkw`, par, data)
}

#' @title Gradient of the Negative Log-Likelihood for the GKw Distribution
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize gradient
#'
#' @description
#' Computes the gradient vector (vector of partial derivatives) of the negative
#' log-likelihood function for the five-parameter Generalized Kumaraswamy (GKw)
#' distribution. This provides the analytical gradient, often used for efficient
#' optimization via maximum likelihood estimation.
#'
#' @param par A numeric vector of length 5 containing the distribution parameters
#'   in the order: \code{alpha} (\eqn{\alpha > 0}), \code{beta} (\eqn{\beta > 0}),
#'   \code{gamma} (\eqn{\gamma > 0}), \code{delta} (\eqn{\delta \ge 0}),
#'   \code{lambda} (\eqn{\lambda > 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a numeric vector of length 5 containing the partial derivatives
#'   of the negative log-likelihood function \eqn{-\ell(\theta | \mathbf{x})} with
#'   respect to each parameter:
#'   \eqn{(-\partial \ell/\partial \alpha, -\partial \ell/\partial \beta, -\partial \ell/\partial \gamma, -\partial \ell/\partial \delta, -\partial \ell/\partial \lambda)}.
#'   Returns a vector of \code{NaN} if any parameter values are invalid according
#'   to their constraints, or if any value in \code{data} is not in the
#'   interval (0, 1).
#'
#' @details
#' The components of the gradient vector of the negative log-likelihood
#' (\eqn{-\nabla \ell(\theta | \mathbf{x})}) are:
#'
#' \deqn{
#' -\frac{\partial \ell}{\partial \alpha} = -\frac{n}{\alpha} - \sum_{i=1}^{n}\ln(x_i) +
#' \sum_{i=1}^{n}\left[x_i^{\alpha} \ln(x_i) \left(\frac{\beta-1}{v_i} -
#' \frac{(\gamma\lambda-1) \beta v_i^{\beta-1}}{w_i} +
#' \frac{\delta \lambda \beta v_i^{\beta-1} w_i^{\lambda-1}}{z_i}\right)\right]
#' }
#' \deqn{
#' -\frac{\partial \ell}{\partial \beta} = -\frac{n}{\beta} - \sum_{i=1}^{n}\ln(v_i) +
#' \sum_{i=1}^{n}\left[v_i^{\beta} \ln(v_i) \left(\frac{\gamma\lambda-1}{w_i} -
#' \frac{\delta \lambda w_i^{\lambda-1}}{z_i}\right)\right]
#' }
#' \deqn{
#' -\frac{\partial \ell}{\partial \gamma} = n[\psi(\gamma) - \psi(\gamma+\delta+1)] -
#' \lambda\sum_{i=1}^{n}\ln(w_i)
#' }
#' \deqn{
#' -\frac{\partial \ell}{\partial \delta} = n[\psi(\delta+1) - \psi(\gamma+\delta+1)] -
#' \sum_{i=1}^{n}\ln(z_i)
#' }
#' \deqn{
#' -\frac{\partial \ell}{\partial \lambda} = -\frac{n}{\lambda} -
#' \gamma\sum_{i=1}^{n}\ln(w_i) + \delta\sum_{i=1}^{n}\frac{w_i^{\lambda}\ln(w_i)}{z_i}
#' }
#'
#' where:
#' \itemize{
#'   \item \eqn{v_i = 1 - x_i^{\alpha}}
#'   \item \eqn{w_i = 1 - v_i^{\beta} = 1 - (1-x_i^{\alpha})^{\beta}}
#'   \item \eqn{z_i = 1 - w_i^{\lambda} = 1 - [1-(1-x_i^{\alpha})^{\beta}]^{\lambda}}
#'   \item \eqn{\psi(\cdot)} is the digamma function (\code{\link[base]{digamma}}).
#' }
#'
#' Numerical stability is ensured through careful implementation, including checks
#' for valid inputs and handling of intermediate calculations involving potentially
#' small or large numbers, often leveraging the Armadillo C++ library for efficiency.
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#' @seealso
#' \code{\link{llgkw}} (negative log-likelihood),
#' \code{\link{hsgkw}} (Hessian matrix),
#' \code{\link{dgkw}} (density),
#' \code{\link[stats]{optim}},
#' \code{\link[numDeriv]{grad}} (for numerical gradient comparison),
#' \code{\link[base]{digamma}}
#'
#' @examples
#' \donttest{
#' # Generate sample data from a known GKw distribution
#' set.seed(123)
#' true_par <- c(alpha = 2, beta = 3, gamma = 1.0, delta = 0.5, lambda = 0.5)
#' sample_data <- rgkw(100, alpha = true_par[1], beta = true_par[2],
#'                    gamma = true_par[3], delta = true_par[4], lambda = true_par[5])
#'
#' # --- Use in Optimization (e.g., with optim using analytical gradient) ---
#' start_par <- c(1.5, 2.5, 1.2, 0.3, 0.6) # Initial guess
#'
#' # Optimization using analytical gradient
#' mle_result_gr <- stats::optim(par = start_par,
#'                               fn = llgkw,  # Objective function (Negative LL)
#'                               gr = grgkw,  # Gradient function
#'                               method = "BFGS", # Method using gradient
#'                               hessian = TRUE,
#'                               data = sample_data)
#'
#' if (mle_result_gr$convergence == 0) {
#'   print("Optimization with analytical gradient converged.")
#'   mle_par_gr <- mle_result_gr$par
#'   print("Estimated parameters:")
#'   print(mle_par_gr)
#' } else {
#'   warning("Optimization with analytical gradient failed!")
#' }
#'
#' # --- Compare analytical gradient to numerical gradient ---
#' # Requires the 'numDeriv' package
#' if (requireNamespace("numDeriv", quietly = TRUE) && mle_result_gr$convergence == 0) {
#'
#'   cat("\nComparing Gradients at MLE estimates:\n")
#'
#'   # Numerical gradient of the negative log-likelihood function
#'   num_grad <- numDeriv::grad(func = llgkw, x = mle_par_gr, data = sample_data)
#'
#'   # Analytical gradient (output of grgkw)
#'   ana_grad <- grgkw(par = mle_par_gr, data = sample_data)
#'
#'   cat("Numerical Gradient:\n")
#'   print(num_grad)
#'   cat("Analytical Gradient:\n")
#'   print(ana_grad)
#'
#'   # Check differences (should be small)
#'   cat("Max absolute difference between gradients:\n")
#'   print(max(abs(num_grad - ana_grad)))
#'
#' } else {
#'   cat("\nSkipping gradient comparison (requires 'numDeriv' package or convergence).\n")
#' }
#'
#' }
#'
#' @export
grgkw <- function(par, data) {
    .Call(`_gkwreg_grgkw`, par, data)
}

#' @title Hessian Matrix of the Negative Log-Likelihood for the GKw Distribution
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize hessian
#'
#' @description
#' Computes the analytic Hessian matrix (matrix of second partial derivatives)
#' of the negative log-likelihood function for the five-parameter Generalized
#' Kumaraswamy (GKw) distribution. This is typically used to estimate standard
#' errors of maximum likelihood estimates or in optimization algorithms.
#'
#' @param par A numeric vector of length 5 containing the distribution parameters
#'   in the order: \code{alpha} (\eqn{\alpha > 0}), \code{beta} (\eqn{\beta > 0}),
#'   \code{gamma} (\eqn{\gamma > 0}), \code{delta} (\eqn{\delta \ge 0}),
#'   \code{lambda} (\eqn{\lambda > 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a 5x5 numeric matrix representing the Hessian matrix of the
#'   negative log-likelihood function, i.e., the matrix of second partial
#'   derivatives \eqn{-\partial^2 \ell / (\partial \theta_i \partial \theta_j)}.
#'   Returns a 5x5 matrix populated with \code{NaN} if any parameter values are
#'   invalid according to their constraints, or if any value in \code{data} is
#'   not in the interval (0, 1).
#'
#' @details
#' This function calculates the analytic second partial derivatives of the
#' negative log-likelihood function based on the GKw PDF (see \code{\link{dgkw}}).
#' The log-likelihood function \eqn{\ell(\theta | \mathbf{x})} is given by:
#' \deqn{
#' \ell(\theta) = n \ln(\lambda\alpha\beta) - n \ln B(\gamma, \delta+1)
#' + \sum_{i=1}^{n} [(\alpha-1) \ln(x_i)
#' + (\beta-1) \ln(v_i)
#' + (\gamma\lambda - 1) \ln(w_i)
#' + \delta \ln(z_i)]
#' }
#' where \eqn{\theta = (\alpha, \beta, \gamma, \delta, \lambda)}, \eqn{B(a,b)}
#' is the Beta function (\code{\link[base]{beta}}), and intermediate terms are:
#' \itemize{
#'   \item \eqn{v_i = 1 - x_i^{\alpha}}
#'   \item \eqn{w_i = 1 - v_i^{\beta} = 1 - (1-x_i^{\alpha})^{\beta}}
#'   \item \eqn{z_i = 1 - w_i^{\lambda} = 1 - [1-(1-x_i^{\alpha})^{\beta}]^{\lambda}}
#' }
#' The Hessian matrix returned contains the elements \eqn{- \frac{\partial^2 \ell(\theta | \mathbf{x})}{\partial \theta_i \partial \theta_j}}.
#'
#' Key properties of the returned matrix:
#' \itemize{
#'   \item Dimensions: 5x5.
#'   \item Symmetry: The matrix is symmetric.
#'   \item Ordering: Rows and columns correspond to the parameters in the order
#'     \eqn{\alpha, \beta, \gamma, \delta, \lambda}.
#'   \item Content: Analytic second derivatives of the *negative* log-likelihood.
#' }
#' The exact analytical formulas for the second derivatives are implemented
#' directly (often derived using symbolic differentiation) for accuracy and
#' efficiency, typically using C++.
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#' @seealso
#' \code{\link{llgkw}} (negative log-likelihood function),
#' \code{\link{grgkw}} (gradient vector),
#' \code{\link{dgkw}} (density function),
#' \code{\link{gkwreg}} (if provides regression fitting),
#' \code{\link[stats]{optim}},
#' \code{\link[numDeriv]{hessian}} (for numerical Hessian comparison).
#'
#' @examples
#' \donttest{
#' # Generate sample data from a known GKw distribution
#' set.seed(123)
#' true_par <- c(alpha = 2, beta = 3, gamma = 1.0, delta = 0.5, lambda = 0.5)
#' sample_data <- rgkw(100, alpha = true_par[1], beta = true_par[2],
#'                    gamma = true_par[3], delta = true_par[4], lambda = true_par[5])
#'
#' # --- Find MLE estimates (e.g., using optim) ---
#' start_par <- c(1.5, 2.5, 1.2, 0.3, 0.6) # Initial guess
#' mle_result <- stats::optim(par = start_par,
#'                            fn = llgkw,
#'                            method = "BFGS",
#'                            hessian = TRUE, # Ask optim for numerical Hessian
#'                            data = sample_data)
#'
#' if (mle_result$convergence == 0) {
#'   mle_par <- mle_result$par
#'   print("MLE parameters found:")
#'   print(mle_par)
#'
#'   # --- Compare analytical Hessian to numerical Hessian ---
#'   # Requires the 'numDeriv' package
#'   if (requireNamespace("numDeriv", quietly = TRUE)) {
#'
#'     cat("\nComparing Hessians at MLE estimates:\n")
#'
#'     # Numerical Hessian from numDeriv applied to negative LL function
#'     num_hess <- numDeriv::hessian(func = llgkw, x = mle_par, data = sample_data)
#'
#'     # Analytical Hessian (output of hsgkw)
#'     ana_hess <- hsgkw(par = mle_par, data = sample_data)
#'
#'     cat("Numerical Hessian (from numDeriv):\n")
#'     print(round(num_hess, 4))
#'     cat("Analytical Hessian (from hsgkw):\n")
#'     print(round(ana_hess, 4))
#'
#'     # Check differences (should be small)
#'     cat("Max absolute difference between Hessians:\n")
#'     print(max(abs(num_hess - ana_hess)))
#'
#'     # Optional: Use analytical Hessian to estimate standard errors
#'     # Ensure Hessian is positive definite before inverting
#'     # fisher_info_analytic <- ana_hess # Hessian of negative LL
#'     # tryCatch({
#'     #   cov_matrix <- solve(fisher_info_analytic)
#'     #   std_errors <- sqrt(diag(cov_matrix))
#'     #   cat("Std. Errors from Analytical Hessian:\n")
#'     #   print(std_errors)
#'     # }, error = function(e) {
#'     #   warning("Could not invert analytical Hessian to get standard errors: ", e$message)
#'     # })
#'
#'   } else {
#'     cat("\nSkipping Hessian comparison (requires 'numDeriv' package).\n")
#'   }
#' } else {
#'   warning("Optimization did not converge. Hessian comparison skipped.")
#' }
#'
#' }
#'
#' @export
hsgkw <- function(par, data) {
    .Call(`_gkwreg_hsgkw`, par, data)
}

#' @title Density of the Kumaraswamy-Kumaraswamy (kkw) Distribution
#' @author Lopes, J. E.
#' @keywords distribution density
#'
#' @description
#' Computes the probability density function (PDF) for the Kumaraswamy-Kumaraswamy
#' (kkw) distribution with parameters \code{alpha} (\eqn{\alpha}), \code{beta}
#' (\eqn{\beta}), \code{delta} (\eqn{\delta}), and \code{lambda} (\eqn{\lambda}).
#' This distribution is defined on the interval (0, 1).
#'
#' @param x Vector of quantiles (values between 0 and 1).
#' @param alpha Shape parameter \code{alpha} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param beta Shape parameter \code{beta} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param delta Shape parameter \code{delta} >= 0. Can be a scalar or a vector.
#'   Default: 0.0.
#' @param lambda Shape parameter \code{lambda} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param log_prob Logical; if \code{TRUE}, the logarithm of the density is
#'   returned (\eqn{\log(f(x))}). Default: \code{FALSE}.
#'
#' @return A vector of density values (\eqn{f(x)}) or log-density values
#'   (\eqn{\log(f(x))}). The length of the result is determined by the recycling
#'   rule applied to the arguments (\code{x}, \code{alpha}, \code{beta},
#'   \code{delta}, \code{lambda}). Returns \code{0} (or \code{-Inf} if
#'   \code{log_prob = TRUE}) for \code{x} outside the interval (0, 1), or
#'   \code{NaN} if parameters are invalid (e.g., \code{alpha <= 0}, \code{beta <= 0},
#'   \code{delta < 0}, \code{lambda <= 0}).
#'
#' @details
#' The Kumaraswamy-Kumaraswamy (kkw) distribution is a special case of the
#' five-parameter Generalized Kumaraswamy distribution (\code{\link{dgkw}})
#' obtained by setting the parameter \eqn{\gamma = 1}.
#'
#' The probability density function is given by:
#' \deqn{
#' f(x; \alpha, \beta, \delta, \lambda) = (\delta + 1) \lambda \alpha \beta x^{\alpha - 1} (1 - x^\alpha)^{\beta - 1} \bigl[1 - (1 - x^\alpha)^\beta\bigr]^{\lambda - 1} \bigl\{1 - \bigl[1 - (1 - x^\alpha)^\beta\bigr]^\lambda\bigr\}^{\delta}
#' }
#' for \eqn{0 < x < 1}. Note that \eqn{1/(\delta+1)} corresponds to the Beta function
#' term \eqn{B(1, \delta+1)} when \eqn{\gamma=1}.
#'
#' Numerical evaluation follows similar stability considerations as \code{\link{dgkw}}.
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#' @seealso
#' \code{\link{dgkw}} (parent distribution density),
#' \code{\link{pkkw}}, \code{\link{qkkw}}, \code{\link{rkkw}} (if they exist),
#' \code{\link[stats]{dbeta}}
#'
#' @examples
#' \donttest{
#' # Example values
#' x_vals <- c(0.2, 0.5, 0.8)
#' alpha_par <- 2.0
#' beta_par <- 3.0
#' delta_par <- 0.5
#' lambda_par <- 1.5
#'
#' # Calculate density
#' densities <- dkkw(x_vals, alpha_par, beta_par, delta_par, lambda_par)
#' print(densities)
#'
#' # Calculate log-density
#' log_densities <- dkkw(x_vals, alpha_par, beta_par, delta_par, lambda_par,
#'                        log_prob = TRUE)
#' print(log_densities)
#' # Check: should match log(densities)
#' print(log(densities))
#'
#' # Compare with dgkw setting gamma = 1
#' densities_gkw <- dgkw(x_vals, alpha_par, beta_par, gamma = 1.0,
#'                       delta_par, lambda_par)
#' print(paste("Max difference:", max(abs(densities - densities_gkw)))) # Should be near zero
#'
#' # Plot the density
#' curve_x <- seq(0.01, 0.99, length.out = 200)
#' curve_y <- dkkw(curve_x, alpha_par, beta_par, delta_par, lambda_par)
#' plot(curve_x, curve_y, type = "l", main = "kkw Density Example",
#'      xlab = "x", ylab = "f(x)", col = "blue")
#'
#' }
#'
#' @export
dkkw <- function(x, alpha, beta, delta, lambda, log_prob = FALSE) {
    .Call(`_gkwreg_dkkw`, x, alpha, beta, delta, lambda, log_prob)
}

#' @title Cumulative Distribution Function (CDF) of the kkw Distribution
#' @author Lopes, J. E.
#' @keywords distribution cumulative
#'
#' @description
#' Computes the cumulative distribution function (CDF), \eqn{P(X \le q)}, for the
#' Kumaraswamy-Kumaraswamy (kkw) distribution with parameters \code{alpha}
#' (\eqn{\alpha}), \code{beta} (\eqn{\beta}), \code{delta} (\eqn{\delta}),
#' and \code{lambda} (\eqn{\lambda}). This distribution is defined on the
#' interval (0, 1).
#'
#' @param q Vector of quantiles (values generally between 0 and 1).
#' @param alpha Shape parameter \code{alpha} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param beta Shape parameter \code{beta} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param delta Shape parameter \code{delta} >= 0. Can be a scalar or a vector.
#'   Default: 0.0.
#' @param lambda Shape parameter \code{lambda} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param lower_tail Logical; if \code{TRUE} (default), probabilities are
#'   \eqn{P(X \le q)}, otherwise, \eqn{P(X > q)}.
#' @param log_p Logical; if \code{TRUE}, probabilities \eqn{p} are given as
#'   \eqn{\log(p)}. Default: \code{FALSE}.
#'
#' @return A vector of probabilities, \eqn{F(q)}, or their logarithms/complements
#'   depending on \code{lower_tail} and \code{log_p}. The length of the result
#'   is determined by the recycling rule applied to the arguments (\code{q},
#'   \code{alpha}, \code{beta}, \code{delta}, \code{lambda}). Returns \code{0}
#'   (or \code{-Inf} if \code{log_p = TRUE}) for \code{q <= 0} and \code{1}
#'   (or \code{0} if \code{log_p = TRUE}) for \code{q >= 1}. Returns \code{NaN}
#'   for invalid parameters.
#'
#' @details
#' The Kumaraswamy-Kumaraswamy (kkw) distribution is a special case of the
#' five-parameter Generalized Kumaraswamy distribution (\code{\link{pgkw}})
#' obtained by setting the shape parameter \eqn{\gamma = 1}.
#'
#' The CDF of the GKw distribution is \eqn{F_{GKw}(q) = I_{y(q)}(\gamma, \delta+1)},
#' where \eqn{y(q) = [1-(1-q^{\alpha})^{\beta}]^{\lambda}} and \eqn{I_x(a,b)}
#' is the regularized incomplete beta function (\code{\link[stats]{pbeta}}).
#' Setting \eqn{\gamma=1} utilizes the property \eqn{I_x(1, b) = 1 - (1-x)^b},
#' yielding the kkw CDF:
#' \deqn{
#' F(q; \alpha, \beta, \delta, \lambda) = 1 - \bigl\{1 - \bigl[1 - (1 - q^\alpha)^\beta\bigr]^\lambda\bigr\}^{\delta + 1}
#' }
#' for \eqn{0 < q < 1}.
#'
#' The implementation uses this closed-form expression for efficiency and handles
#' \code{lower_tail} and \code{log_p} arguments appropriately.
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#' @seealso
#' \code{\link{pgkw}} (parent distribution CDF),
#' \code{\link{dkkw}}, \code{\link{qkkw}}, \code{\link{rkkw}},
#' \code{\link[stats]{pbeta}}
#'
#' @examples
#' \donttest{
#' # Example values
#' q_vals <- c(0.2, 0.5, 0.8)
#' alpha_par <- 2.0
#' beta_par <- 3.0
#' delta_par <- 0.5
#' lambda_par <- 1.5
#'
#' # Calculate CDF P(X <= q)
#' probs <- pkkw(q_vals, alpha_par, beta_par, delta_par, lambda_par)
#' print(probs)
#'
#' # Calculate upper tail P(X > q)
#' probs_upper <- pkkw(q_vals, alpha_par, beta_par, delta_par, lambda_par,
#'                      lower_tail = FALSE)
#' print(probs_upper)
#' # Check: probs + probs_upper should be 1
#' print(probs + probs_upper)
#'
#' # Calculate log CDF
#' log_probs <- pkkw(q_vals, alpha_par, beta_par, delta_par, lambda_par,
#'                    log_p = TRUE)
#' print(log_probs)
#' # Check: should match log(probs)
#' print(log(probs))
#'
#' # Compare with pgkw setting gamma = 1
#' probs_gkw <- pgkw(q_vals, alpha_par, beta_par, gamma = 1.0,
#'                   delta_par, lambda_par)
#' print(paste("Max difference:", max(abs(probs - probs_gkw)))) # Should be near zero
#'
#' # Plot the CDF
#' curve_q <- seq(0.01, 0.99, length.out = 200)
#' curve_p <- pkkw(curve_q, alpha_par, beta_par, delta_par, lambda_par)
#' plot(curve_q, curve_p, type = "l", main = "kkw CDF Example",
#'      xlab = "q", ylab = "F(q)", col = "blue", ylim = c(0, 1))
#'
#' }
#'
#' @export
pkkw <- function(q, alpha, beta, delta, lambda, lower_tail = TRUE, log_p = FALSE) {
    .Call(`_gkwreg_pkkw`, q, alpha, beta, delta, lambda, lower_tail, log_p)
}

#' @title Quantile Function of the Kumaraswamy-Kumaraswamy (kkw) Distribution
#' @author Lopes, J. E.
#' @keywords distribution quantile
#'
#' @description
#' Computes the quantile function (inverse CDF) for the Kumaraswamy-Kumaraswamy
#' (kkw) distribution with parameters \code{alpha} (\eqn{\alpha}), \code{beta}
#' (\eqn{\beta}), \code{delta} (\eqn{\delta}), and \code{lambda} (\eqn{\lambda}).
#' It finds the value \code{q} such that \eqn{P(X \le q) = p}. This distribution
#' is a special case of the Generalized Kumaraswamy (GKw) distribution where
#' the parameter \eqn{\gamma = 1}.
#'
#' @param p Vector of probabilities (values between 0 and 1).
#' @param alpha Shape parameter \code{alpha} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param beta Shape parameter \code{beta} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param delta Shape parameter \code{delta} >= 0. Can be a scalar or a vector.
#'   Default: 0.0.
#' @param lambda Shape parameter \code{lambda} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param lower_tail Logical; if \code{TRUE} (default), probabilities are \eqn{p = P(X \le q)},
#'   otherwise, probabilities are \eqn{p = P(X > q)}.
#' @param log_p Logical; if \code{TRUE}, probabilities \code{p} are given as
#'   \eqn{\log(p)}. Default: \code{FALSE}.
#'
#' @return A vector of quantiles corresponding to the given probabilities \code{p}.
#'   The length of the result is determined by the recycling rule applied to
#'   the arguments (\code{p}, \code{alpha}, \code{beta}, \code{delta},
#'   \code{lambda}). Returns:
#'   \itemize{
#'     \item \code{0} for \code{p = 0} (or \code{p = -Inf} if \code{log_p = TRUE},
#'           when \code{lower_tail = TRUE}).
#'     \item \code{1} for \code{p = 1} (or \code{p = 0} if \code{log_p = TRUE},
#'           when \code{lower_tail = TRUE}).
#'     \item \code{NaN} for \code{p < 0} or \code{p > 1} (or corresponding log scale).
#'     \item \code{NaN} for invalid parameters (e.g., \code{alpha <= 0},
#'           \code{beta <= 0}, \code{delta < 0}, \code{lambda <= 0}).
#'   }
#'   Boundary return values are adjusted accordingly for \code{lower_tail = FALSE}.
#'
#' @details
#' The quantile function \eqn{Q(p)} is the inverse of the CDF \eqn{F(q)}. The CDF
#' for the kkw (\eqn{\gamma=1}) distribution is (see \code{\link{pkkw}}):
#' \deqn{
#' F(q) = 1 - \bigl\{1 - \bigl[1 - (1 - q^\alpha)^\beta\bigr]^\lambda\bigr\}^{\delta + 1}
#' }
#' Inverting this equation for \eqn{q} yields the quantile function:
#' \deqn{
#' Q(p) = \left[ 1 - \left\{ 1 - \left[ 1 - (1 - p)^{1/(\delta+1)} \right]^{1/\lambda} \right\}^{1/\beta} \right]^{1/\alpha}
#' }
#' The function uses this closed-form expression and correctly handles the
#' \code{lower_tail} and \code{log_p} arguments by transforming \code{p}
#' appropriately before applying the formula.
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#' @seealso
#' \code{\link{qgkw}} (parent distribution quantile function),
#' \code{\link{dkkw}}, \code{\link{pkkw}}, \code{\link{rkkw}},
#' \code{\link[stats]{qbeta}}
#'
#' @examples
#' \donttest{
#' # Example values
#' p_vals <- c(0.1, 0.5, 0.9)
#' alpha_par <- 2.0
#' beta_par <- 3.0
#' delta_par <- 0.5
#' lambda_par <- 1.5
#'
#' # Calculate quantiles
#' quantiles <- qkkw(p_vals, alpha_par, beta_par, delta_par, lambda_par)
#' print(quantiles)
#'
#' # Calculate quantiles for upper tail probabilities P(X > q) = p
#' # e.g., for p=0.1, find q such that P(X > q) = 0.1 (90th percentile)
#' quantiles_upper <- qkkw(p_vals, alpha_par, beta_par, delta_par, lambda_par,
#'                          lower_tail = FALSE)
#' print(quantiles_upper)
#' # Check: qkkw(p, ..., lt=F) == qkkw(1-p, ..., lt=T)
#' print(qkkw(1 - p_vals, alpha_par, beta_par, delta_par, lambda_par))
#'
#' # Calculate quantiles from log probabilities
#' log_p_vals <- log(p_vals)
#' quantiles_logp <- qkkw(log_p_vals, alpha_par, beta_par, delta_par, lambda_par,
#'                         log_p = TRUE)
#' print(quantiles_logp)
#' # Check: should match original quantiles
#' print(quantiles)
#'
#' # Compare with qgkw setting gamma = 1
#' quantiles_gkw <- qgkw(p_vals, alpha_par, beta_par, gamma = 1.0,
#'                       delta_par, lambda_par)
#' print(paste("Max difference:", max(abs(quantiles - quantiles_gkw)))) # Should be near zero
#'
#' # Verify inverse relationship with pkkw
#' p_check <- 0.75
#' q_calc <- qkkw(p_check, alpha_par, beta_par, delta_par, lambda_par)
#' p_recalc <- pkkw(q_calc, alpha_par, beta_par, delta_par, lambda_par)
#' print(paste("Original p:", p_check, " Recalculated p:", p_recalc))
#' # abs(p_check - p_recalc) < 1e-9 # Should be TRUE
#'
#' # Boundary conditions
#' print(qkkw(c(0, 1), alpha_par, beta_par, delta_par, lambda_par)) # Should be 0, 1
#' print(qkkw(c(-Inf, 0), alpha_par, beta_par, delta_par, lambda_par, log_p = TRUE)) # Should be 0, 1
#'
#' }
#'
#' @export
qkkw <- function(p, alpha, beta, delta, lambda, lower_tail = TRUE, log_p = FALSE) {
    .Call(`_gkwreg_qkkw`, p, alpha, beta, delta, lambda, lower_tail, log_p)
}

#' @title Random Number Generation for the kkw Distribution
#' @author Lopes, J. E.
#' @keywords distribution random
#'
#' @description
#' Generates random deviates from the Kumaraswamy-Kumaraswamy (kkw)
#' distribution with parameters \code{alpha} (\eqn{\alpha}), \code{beta}
#' (\eqn{\beta}), \code{delta} (\eqn{\delta}), and \code{lambda} (\eqn{\lambda}).
#' This distribution is a special case of the Generalized Kumaraswamy (GKw)
#' distribution where the parameter \eqn{\gamma = 1}.
#'
#' @param n Number of observations. If \code{length(n) > 1}, the length is
#'   taken to be the number required. Must be a non-negative integer.
#' @param alpha Shape parameter \code{alpha} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param beta Shape parameter \code{beta} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param delta Shape parameter \code{delta} >= 0. Can be a scalar or a vector.
#'   Default: 0.0.
#' @param lambda Shape parameter \code{lambda} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#'
#' @return A vector of length \code{n} containing random deviates from the kkw
#'   distribution. The length of the result is determined by \code{n} and the
#'   recycling rule applied to the parameters (\code{alpha}, \code{beta},
#'   \code{delta}, \code{lambda}). Returns \code{NaN} if parameters
#'   are invalid (e.g., \code{alpha <= 0}, \code{beta <= 0}, \code{delta < 0},
#'   \code{lambda <= 0}).
#'
#' @details
#' The generation method uses the inverse transform method based on the quantile
#' function (\code{\link{qkkw}}). The kkw quantile function is:
#' \deqn{
#' Q(p) = \left[ 1 - \left\{ 1 - \left[ 1 - (1 - p)^{1/(\delta+1)} \right]^{1/\lambda} \right\}^{1/\beta} \right]^{1/\alpha}
#' }
#' Random deviates are generated by evaluating \eqn{Q(p)} where \eqn{p} is a
#' random variable following the standard Uniform distribution on (0, 1)
#' (\code{\link[stats]{runif}}).
#'
#' This is equivalent to the general method for the GKw distribution
#' (\code{\link{rgkw}}) specialized for \eqn{\gamma=1}. The GKw method generates
#' \eqn{W \sim \mathrm{Beta}(\gamma, \delta+1)} and then applies transformations.
#' When \eqn{\gamma=1}, \eqn{W \sim \mathrm{Beta}(1, \delta+1)}, which can be
#' generated via \eqn{W = 1 - V^{1/(\delta+1)}} where \eqn{V \sim \mathrm{Unif}(0,1)}.
#' Substituting this \eqn{W} into the GKw transformation yields the same result
#' as evaluating \eqn{Q(1-V)} above (noting \eqn{p = 1-V} is also Uniform).
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#' Devroye, L. (1986). *Non-Uniform Random Variate Generation*. Springer-Verlag.
#' (General methods for random variate generation).
#'
#' @seealso
#' \code{\link{rgkw}} (parent distribution random generation),
#' \code{\link{dkkw}}, \code{\link{pkkw}}, \code{\link{qkkw}},
#' \code{\link[stats]{runif}}, \code{\link[stats]{rbeta}}
#'
#' @examples
#' \donttest{
#' set.seed(2025) # for reproducibility
#'
#' # Generate 1000 random values from a specific kkw distribution
#' alpha_par <- 2.0
#' beta_par <- 3.0
#' delta_par <- 0.5
#' lambda_par <- 1.5
#'
#' x_sample_kkw <- rkkw(1000, alpha = alpha_par, beta = beta_par,
#'                        delta = delta_par, lambda = lambda_par)
#' summary(x_sample_kkw)
#'
#' # Histogram of generated values compared to theoretical density
#' hist(x_sample_kkw, breaks = 30, freq = FALSE, # freq=FALSE for density
#'      main = "Histogram of kkw Sample", xlab = "x", ylim = c(0, 3.5))
#' curve(dkkw(x, alpha = alpha_par, beta = beta_par, delta = delta_par,
#'             lambda = lambda_par),
#'       add = TRUE, col = "red", lwd = 2, n = 201)
#' legend("topright", legend = "Theoretical PDF", col = "red", lwd = 2, bty = "n")
#'
#' # Comparing empirical and theoretical quantiles (Q-Q plot)
#' prob_points <- seq(0.01, 0.99, by = 0.01)
#' theo_quantiles <- qkkw(prob_points, alpha = alpha_par, beta = beta_par,
#'                         delta = delta_par, lambda = lambda_par)
#' emp_quantiles <- quantile(x_sample_kkw, prob_points, type = 7) # type 7 is default
#'
#' plot(theo_quantiles, emp_quantiles, pch = 16, cex = 0.8,
#'      main = "Q-Q Plot for kkw Distribution",
#'      xlab = "Theoretical Quantiles", ylab = "Empirical Quantiles (n=1000)")
#' abline(a = 0, b = 1, col = "blue", lty = 2)
#'
#' # Compare summary stats with rgkw(..., gamma=1, ...)
#' # Note: individual values will differ due to randomness
#' x_sample_gkw <- rgkw(1000, alpha = alpha_par, beta = beta_par, gamma = 1.0,
#'                      delta = delta_par, lambda = lambda_par)
#' print("Summary stats for rkkw sample:")
#' print(summary(x_sample_kkw))
#' print("Summary stats for rgkw(gamma=1) sample:")
#' print(summary(x_sample_gkw)) # Should be similar
#' }
#'
#' @export
rkkw <- function(n, alpha, beta, delta, lambda) {
    .Call(`_gkwreg_rkkw`, n, alpha, beta, delta, lambda)
}

#' @title Negative Log-Likelihood for the kkw Distribution
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize
#'
#' @description
#' Computes the negative log-likelihood function for the Kumaraswamy-Kumaraswamy
#' (kkw) distribution with parameters \code{alpha} (\eqn{\alpha}), \code{beta}
#' (\eqn{\beta}), \code{delta} (\eqn{\delta}), and \code{lambda} (\eqn{\lambda}),
#' given a vector of observations. This distribution is a special case of the
#' Generalized Kumaraswamy (GKw) distribution where \eqn{\gamma = 1}.
#'
#' @param par A numeric vector of length 4 containing the distribution parameters
#'   in the order: \code{alpha} (\eqn{\alpha > 0}), \code{beta} (\eqn{\beta > 0}),
#'   \code{delta} (\eqn{\delta \ge 0}), \code{lambda} (\eqn{\lambda > 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a single \code{double} value representing the negative
#'   log-likelihood (\eqn{-\ell(\theta|\mathbf{x})}). Returns \code{Inf}
#'   if any parameter values in \code{par} are invalid according to their
#'   constraints, or if any value in \code{data} is not in the interval (0, 1).
#'
#' @details
#' The kkw distribution is the GKw distribution (\code{\link{dgkw}}) with \eqn{\gamma=1}.
#' Its probability density function (PDF) is:
#' \deqn{
#' f(x | \theta) = (\delta + 1) \lambda \alpha \beta x^{\alpha - 1} (1 - x^\alpha)^{\beta - 1} \bigl[1 - (1 - x^\alpha)^\beta\bigr]^{\lambda - 1} \bigl\{1 - \bigl[1 - (1 - x^\alpha)^\beta\bigr]^\lambda\bigr\}^{\delta}
#' }
#' for \eqn{0 < x < 1} and \eqn{\theta = (\alpha, \beta, \delta, \lambda)}.
#' The log-likelihood function \eqn{\ell(\theta | \mathbf{x})} for a sample
#' \eqn{\mathbf{x} = (x_1, \dots, x_n)} is \eqn{\sum_{i=1}^n \ln f(x_i | \theta)}:
#' \deqn{
#' \ell(\theta | \mathbf{x}) = n[\ln(\delta+1) + \ln(\lambda) + \ln(\alpha) + \ln(\beta)]
#' + \sum_{i=1}^{n} [(\alpha-1)\ln(x_i) + (\beta-1)\ln(v_i) + (\lambda-1)\ln(w_i) + \delta\ln(z_i)]
#' }
#' where:
#' \itemize{
#'   \item \eqn{v_i = 1 - x_i^{\alpha}}
#'   \item \eqn{w_i = 1 - v_i^{\beta} = 1 - (1-x_i^{\alpha})^{\beta}}
#'   \item \eqn{z_i = 1 - w_i^{\lambda} = 1 - [1-(1-x_i^{\alpha})^{\beta}]^{\lambda}}
#' }
#' This function computes and returns the *negative* log-likelihood, \eqn{-\ell(\theta|\mathbf{x})},
#' suitable for minimization using optimization routines like \code{\link[stats]{optim}}.
#' Numerical stability is maintained similarly to \code{\link{llgkw}}.
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#' @seealso
#' \code{\link{llgkw}} (parent distribution negative log-likelihood),
#' \code{\link{dkkw}}, \code{\link{pkkw}}, \code{\link{qkkw}}, \code{\link{rkkw}},
#' \code{\link{grkkw}} (gradient, if available),
#' \code{\link{hskkw}} (Hessian, if available),
#' \code{\link[stats]{optim}}
#'
#' @examples
#' \donttest{
#' # Assuming existence of rkkw, grkkw, hskkw functions for kkw distribution
#'
#' # Generate sample data from a known kkw distribution
#' set.seed(123)
#' true_par_kkw <- c(alpha = 2, beta = 3, delta = 1.5, lambda = 0.5)
#' # Use rkkw if it exists, otherwise use rgkw with gamma=1
#' if (exists("rkkw")) {
#'   sample_data_kkw <- rkkw(100, alpha = true_par_kkw[1], beta = true_par_kkw[2],
#'                          delta = true_par_kkw[3], lambda = true_par_kkw[4])
#' } else {
#'   sample_data_kkw <- rgkw(100, alpha = true_par_kkw[1], beta = true_par_kkw[2],
#'                          gamma = 1, delta = true_par_kkw[3], lambda = true_par_kkw[4])
#' }
#' hist(sample_data_kkw, breaks = 20, main = "kkw(2, 3, 1.5, 0.5) Sample")
#'
#' # --- Maximum Likelihood Estimation using optim ---
#' # Initial parameter guess
#' start_par_kkw <- c(1.5, 2.5, 1.0, 0.6)
#'
#' # Perform optimization (minimizing negative log-likelihood)
#' mle_result_kkw <- stats::optim(par = start_par_kkw,
#'                                fn = llkkw, # Use the kkw neg-log-likelihood
#'                                method = "BFGS",
#'                                hessian = TRUE,
#'                                data = sample_data_kkw)
#'
#' # Check convergence and results
#' if (mle_result_kkw$convergence == 0) {
#'   print("Optimization converged successfully.")
#'   mle_par_kkw <- mle_result_kkw$par
#'   print("Estimated kkw parameters:")
#'   print(mle_par_kkw)
#'   print("True kkw parameters:")
#'   print(true_par_kkw)
#' } else {
#'   warning("Optimization did not converge!")
#'   print(mle_result_kkw$message)
#' }
#'
#' # --- Compare numerical and analytical derivatives (if available) ---
#' # Requires 'numDeriv' package and analytical functions 'grkkw', 'hskkw'
#' if (mle_result_kkw$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE) &&
#'     exists("grkkw") && exists("hskkw")) {
#'
#'   cat("\nComparing Derivatives at kkw MLE estimates:\n")
#'
#'   # Numerical derivatives of llkkw
#'   num_grad_kkw <- numDeriv::grad(func = llkkw, x = mle_par_kkw, data = sample_data_kkw)
#'   num_hess_kkw <- numDeriv::hessian(func = llkkw, x = mle_par_kkw, data = sample_data_kkw)
#'
#'   # Analytical derivatives (assuming they return derivatives of negative LL)
#'   ana_grad_kkw <- grkkw(par = mle_par_kkw, data = sample_data_kkw)
#'   ana_hess_kkw <- hskkw(par = mle_par_kkw, data = sample_data_kkw)
#'
#'   # Check differences
#'   cat("Max absolute difference between gradients:\n")
#'   print(max(abs(num_grad_kkw - ana_grad_kkw)))
#'   cat("Max absolute difference between Hessians:\n")
#'   print(max(abs(num_hess_kkw - ana_hess_kkw)))
#'
#' } else {
#'    cat("\nSkipping derivative comparison for kkw.\n")
#'    cat("Requires convergence, 'numDeriv' package and functions 'grkkw', 'hskkw'.\n")
#' }
#'
#' }
#'
#' @export
llkkw <- function(par, data) {
    .Call(`_gkwreg_llkkw`, par, data)
}

#' @title Gradient of the Negative Log-Likelihood for the kkw Distribution
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize gradient
#'
#' @description
#' Computes the gradient vector (vector of first partial derivatives) of the
#' negative log-likelihood function for the Kumaraswamy-Kumaraswamy (kkw)
#' distribution with parameters \code{alpha} (\eqn{\alpha}), \code{beta}
#' (\eqn{\beta}), \code{delta} (\eqn{\delta}), and \code{lambda} (\eqn{\lambda}).
#' This distribution is the special case of the Generalized Kumaraswamy (GKw)
#' distribution where \eqn{\gamma = 1}. The gradient is typically used in
#' optimization algorithms for maximum likelihood estimation.
#'
#' @param par A numeric vector of length 4 containing the distribution parameters
#'   in the order: \code{alpha} (\eqn{\alpha > 0}), \code{beta} (\eqn{\beta > 0}),
#'   \code{delta} (\eqn{\delta \ge 0}), \code{lambda} (\eqn{\lambda > 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a numeric vector of length 4 containing the partial derivatives
#'   of the negative log-likelihood function \eqn{-\ell(\theta | \mathbf{x})} with
#'   respect to each parameter:
#'   \eqn{(-\partial \ell/\partial \alpha, -\partial \ell/\partial \beta, -\partial \ell/\partial \delta, -\partial \ell/\partial \lambda)}.
#'   Returns a vector of \code{NaN} if any parameter values are invalid according
#'   to their constraints, or if any value in \code{data} is not in the
#'   interval (0, 1).
#'
#' @details
#' The components of the gradient vector of the negative log-likelihood
#' (\eqn{-\nabla \ell(\theta | \mathbf{x})}) for the kkw (\eqn{\gamma=1}) model are:
#'
#' \deqn{
#' -\frac{\partial \ell}{\partial \alpha} = -\frac{n}{\alpha} - \sum_{i=1}^{n}\ln(x_i)
#' + (\beta-1)\sum_{i=1}^{n}\frac{x_i^{\alpha}\ln(x_i)}{v_i}
#' - (\lambda-1)\sum_{i=1}^{n}\frac{\beta v_i^{\beta-1} x_i^{\alpha}\ln(x_i)}{w_i}
#' + \delta\sum_{i=1}^{n}\frac{\lambda w_i^{\lambda-1} \beta v_i^{\beta-1} x_i^{\alpha}\ln(x_i)}{z_i}
#' }
#' \deqn{
#' -\frac{\partial \ell}{\partial \beta} = -\frac{n}{\beta} - \sum_{i=1}^{n}\ln(v_i)
#' + (\lambda-1)\sum_{i=1}^{n}\frac{v_i^{\beta}\ln(v_i)}{w_i}
#' - \delta\sum_{i=1}^{n}\frac{\lambda w_i^{\lambda-1} v_i^{\beta}\ln(v_i)}{z_i}
#' }
#' \deqn{
#' -\frac{\partial \ell}{\partial \delta} = -\frac{n}{\delta+1} - \sum_{i=1}^{n}\ln(z_i)
#' }
#' \deqn{
#' -\frac{\partial \ell}{\partial \lambda} = -\frac{n}{\lambda} - \sum_{i=1}^{n}\ln(w_i)
#' + \delta\sum_{i=1}^{n}\frac{w_i^{\lambda}\ln(w_i)}{z_i}
#' }
#'
#' where:
#' \itemize{
#'   \item \eqn{v_i = 1 - x_i^{\alpha}}
#'   \item \eqn{w_i = 1 - v_i^{\beta} = 1 - (1-x_i^{\alpha})^{\beta}}
#'   \item \eqn{z_i = 1 - w_i^{\lambda} = 1 - [1-(1-x_i^{\alpha})^{\beta}]^{\lambda}}
#' }
#' These formulas represent the derivatives of \eqn{-\ell(\theta)}, consistent with
#' minimizing the negative log-likelihood. They correspond to the general GKw
#' gradient (\code{\link{grgkw}}) components for \eqn{\alpha, \beta, \delta, \lambda}
#' evaluated at \eqn{\gamma=1}. Note that the component for \eqn{\gamma} is omitted.
#' Numerical stability is maintained through careful implementation.
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#' @seealso
#' \code{\link{grgkw}} (parent distribution gradient),
#' \code{\link{llkkw}} (negative log-likelihood for kkw),
#' \code{\link{hskkw}} (Hessian for kkw),
#' \code{\link{dkkw}} (density for kkw),
#' \code{\link[stats]{optim}},
#' \code{\link[numDeriv]{grad}} (for numerical gradient comparison).
#'
#' @examples
#' \donttest{
#' # Assuming existence of rkkw, llkkw, grkkw, hskkw functions for kkw
#'
#' # Generate sample data
#' set.seed(123)
#' true_par_kkw <- c(alpha = 2, beta = 3, delta = 1.5, lambda = 0.5)
#' if (exists("rkkw")) {
#'   sample_data_kkw <- rkkw(100, alpha = true_par_kkw[1], beta = true_par_kkw[2],
#'                          delta = true_par_kkw[3], lambda = true_par_kkw[4])
#' } else {
#'   sample_data_kkw <- rgkw(100, alpha = true_par_kkw[1], beta = true_par_kkw[2],
#'                          gamma = 1, delta = true_par_kkw[3], lambda = true_par_kkw[4])
#' }
#'
#' # --- Find MLE estimates ---
#' start_par_kkw <- c(1.5, 2.5, 1.0, 0.6)
#' mle_result_kkw <- stats::optim(par = start_par_kkw,
#'                                fn = llkkw,
#'                                gr = grkkw, # Use analytical gradient for kkw
#'                                method = "BFGS",
#'                                hessian = TRUE,
#'                                data = sample_data_kkw)
#'
#' # --- Compare analytical gradient to numerical gradient ---
#' if (mle_result_kkw$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE)) {
#'
#'   mle_par_kkw <- mle_result_kkw$par
#'   cat("\nComparing Gradients for kkw at MLE estimates:\n")
#'
#'   # Numerical gradient of llkkw
#'   num_grad_kkw <- numDeriv::grad(func = llkkw, x = mle_par_kkw, data = sample_data_kkw)
#'
#'   # Analytical gradient from grkkw
#'   ana_grad_kkw <- grkkw(par = mle_par_kkw, data = sample_data_kkw)
#'
#'   cat("Numerical Gradient (kkw):\n")
#'   print(num_grad_kkw)
#'   cat("Analytical Gradient (kkw):\n")
#'   print(ana_grad_kkw)
#'
#'   # Check differences
#'   cat("Max absolute difference between kkw gradients:\n")
#'   print(max(abs(num_grad_kkw - ana_grad_kkw)))
#'
#' } else {
#'   cat("\nSkipping kkw gradient comparison.\n")
#' }
#'
#' # --- Optional: Compare with relevant components of GKw gradient ---
#' # Requires grgkw function
#' if (mle_result_kkw$convergence == 0 && exists("grgkw")) {
#'   # Create 5-param vector for grgkw (insert gamma=1)
#'   mle_par_gkw_equiv <- c(mle_par_kkw[1:2], gamma = 1.0, mle_par_kkw[3:4])
#'   ana_grad_gkw <- grgkw(par = mle_par_gkw_equiv, data = sample_data_kkw)
#'   # Extract components corresponding to alpha, beta, delta, lambda
#'   ana_grad_gkw_subset <- ana_grad_gkw[c(1, 2, 4, 5)]
#'
#'   cat("\nComparison with relevant components of GKw gradient:\n")
#'   cat("Max absolute difference:\n")
#'   print(max(abs(ana_grad_kkw - ana_grad_gkw_subset))) # Should be very small
#' }
#'
#' }
#'
#' @export
grkkw <- function(par, data) {
    .Call(`_gkwreg_grkkw`, par, data)
}

#' @title Hessian Matrix of the Negative Log-Likelihood for the kkw Distribution
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize hessian
#'
#' @description
#' Computes the analytic 4x4 Hessian matrix (matrix of second partial derivatives)
#' of the negative log-likelihood function for the Kumaraswamy-Kumaraswamy (kkw)
#' distribution with parameters \code{alpha} (\eqn{\alpha}), \code{beta}
#' (\eqn{\beta}), \code{delta} (\eqn{\delta}), and \code{lambda} (\eqn{\lambda}).
#' This distribution is the special case of the Generalized Kumaraswamy (GKw)
#' distribution where \eqn{\gamma = 1}. The Hessian is useful for estimating
#' standard errors and in optimization algorithms.
#'
#' @param par A numeric vector of length 4 containing the distribution parameters
#'   in the order: \code{alpha} (\eqn{\alpha > 0}), \code{beta} (\eqn{\beta > 0}),
#'   \code{delta} (\eqn{\delta \ge 0}), \code{lambda} (\eqn{\lambda > 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a 4x4 numeric matrix representing the Hessian matrix of the
#'   negative log-likelihood function, \eqn{-\partial^2 \ell / (\partial \theta_i \partial \theta_j)},
#'   where \eqn{\theta = (\alpha, \beta, \delta, \lambda)}.
#'   Returns a 4x4 matrix populated with \code{NaN} if any parameter values are
#'   invalid according to their constraints, or if any value in \code{data} is
#'   not in the interval (0, 1).
#'
#' @details
#' This function calculates the analytic second partial derivatives of the
#' negative log-likelihood function based on the kkw log-likelihood
#' (\eqn{\gamma=1} case of GKw, see \code{\link{llkkw}}):
#' \deqn{
#' \ell(\theta | \mathbf{x}) = n[\ln(\delta+1) + \ln(\lambda) + \ln(\alpha) + \ln(\beta)]
#' + \sum_{i=1}^{n} [(\alpha-1)\ln(x_i) + (\beta-1)\ln(v_i) + (\lambda-1)\ln(w_i) + \delta\ln(z_i)]
#' }
#' where \eqn{\theta = (\alpha, \beta, \delta, \lambda)} and intermediate terms are:
#' \itemize{
#'   \item \eqn{v_i = 1 - x_i^{\alpha}}
#'   \item \eqn{w_i = 1 - v_i^{\beta} = 1 - (1-x_i^{\alpha})^{\beta}}
#'   \item \eqn{z_i = 1 - w_i^{\lambda} = 1 - [1-(1-x_i^{\alpha})^{\beta}]^{\lambda}}
#' }
#' The Hessian matrix returned contains the elements \eqn{- \frac{\partial^2 \ell(\theta | \mathbf{x})}{\partial \theta_i \partial \theta_j}}
#' for \eqn{\theta_i, \theta_j \in \{\alpha, \beta, \delta, \lambda\}}.
#'
#' Key properties of the returned matrix:
#' \itemize{
#'   \item Dimensions: 4x4.
#'   \item Symmetry: The matrix is symmetric.
#'   \item Ordering: Rows and columns correspond to the parameters in the order
#'     \eqn{\alpha, \beta, \delta, \lambda}.
#'   \item Content: Analytic second derivatives of the *negative* log-likelihood.
#' }
#' This corresponds to the relevant submatrix of the 5x5 GKw Hessian (\code{\link{hsgkw}})
#' evaluated at \eqn{\gamma=1}. The exact analytical formulas are implemented directly.
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#' @seealso
#' \code{\link{hsgkw}} (parent distribution Hessian),
#' \code{\link{llkkw}} (negative log-likelihood for kkw),
#' \code{\link{grkkw}} (gradient for kkw),
#' \code{\link{dkkw}} (density for kkw),
#' \code{\link[stats]{optim}},
#' \code{\link[numDeriv]{hessian}} (for numerical Hessian comparison).
#'
#' @examples
#' \donttest{
#' # Assuming existence of rkkw, llkkw, grkkw, hskkw functions for kkw
#'
#' # Generate sample data
#' set.seed(123)
#' true_par_kkw <- c(alpha = 2, beta = 3, delta = 1.5, lambda = 0.5)
#' if (exists("rkkw")) {
#'   sample_data_kkw <- rkkw(100, alpha = true_par_kkw[1], beta = true_par_kkw[2],
#'                          delta = true_par_kkw[3], lambda = true_par_kkw[4])
#' } else {
#'   sample_data_kkw <- rgkw(100, alpha = true_par_kkw[1], beta = true_par_kkw[2],
#'                          gamma = 1, delta = true_par_kkw[3], lambda = true_par_kkw[4])
#' }
#'
#' # --- Find MLE estimates ---
#' start_par_kkw <- c(1.5, 2.5, 1.0, 0.6)
#' mle_result_kkw <- stats::optim(par = start_par_kkw,
#'                                fn = llkkw,
#'                                gr = if (exists("grkkw")) grkkw else NULL,
#'                                method = "BFGS",
#'                                hessian = TRUE,
#'                                data = sample_data_kkw)
#'
#' # --- Compare analytical Hessian to numerical Hessian ---
#' if (mle_result_kkw$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE) &&
#'     exists("hskkw")) {
#'
#'   mle_par_kkw <- mle_result_kkw$par
#'   cat("\nComparing Hessians for kkw at MLE estimates:\n")
#'
#'   # Numerical Hessian of llkkw
#'   num_hess_kkw <- numDeriv::hessian(func = llkkw, x = mle_par_kkw, data = sample_data_kkw)
#'
#'   # Analytical Hessian from hskkw
#'   ana_hess_kkw <- hskkw(par = mle_par_kkw, data = sample_data_kkw)
#'
#'   cat("Numerical Hessian (kkw):\n")
#'   print(round(num_hess_kkw, 4))
#'   cat("Analytical Hessian (kkw):\n")
#'   print(round(ana_hess_kkw, 4))
#'
#'   # Check differences
#'   cat("Max absolute difference between kkw Hessians:\n")
#'   print(max(abs(num_hess_kkw - ana_hess_kkw)))
#'
#'   # Optional: Use analytical Hessian for Standard Errors
#'   # tryCatch({
#'   #   cov_matrix_kkw <- solve(ana_hess_kkw)
#'   #   std_errors_kkw <- sqrt(diag(cov_matrix_kkw))
#'   #   cat("Std. Errors from Analytical kkw Hessian:\n")
#'   #   print(std_errors_kkw)
#'   # }, error = function(e) {
#'   #   warning("Could not invert analytical kkw Hessian: ", e$message)
#'   # })
#'
#' } else {
#'   cat("\nSkipping kkw Hessian comparison.\n")
#'   cat("Requires convergence, 'numDeriv' package, and function 'hskkw'.\n")
#' }
#'
#' }
#'
#' @export
hskkw <- function(par, data) {
    .Call(`_gkwreg_hskkw`, par, data)
}

#' @title Density of the Beta-Kumaraswamy (BKw) Distribution
#' @author Lopes, J. E.
#' @keywords distribution density
#'
#' @description
#' Computes the probability density function (PDF) for the Beta-Kumaraswamy
#' (BKw) distribution with parameters \code{alpha} (\eqn{\alpha}), \code{beta}
#' (\eqn{\beta}), \code{gamma} (\eqn{\gamma}), and \code{delta} (\eqn{\delta}).
#' This distribution is defined on the interval (0, 1).
#'
#' @param x Vector of quantiles (values between 0 and 1).
#' @param alpha Shape parameter \code{alpha} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param beta Shape parameter \code{beta} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param gamma Shape parameter \code{gamma} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param delta Shape parameter \code{delta} >= 0. Can be a scalar or a vector.
#'   Default: 0.0.
#' @param log_prob Logical; if \code{TRUE}, the logarithm of the density is
#'   returned (\eqn{\log(f(x))}). Default: \code{FALSE}.
#'
#' @return A vector of density values (\eqn{f(x)}) or log-density values
#'   (\eqn{\log(f(x))}). The length of the result is determined by the recycling
#'   rule applied to the arguments (\code{x}, \code{alpha}, \code{beta},
#'   \code{gamma}, \code{delta}). Returns \code{0} (or \code{-Inf} if
#'   \code{log_prob = TRUE}) for \code{x} outside the interval (0, 1), or
#'   \code{NaN} if parameters are invalid (e.g., \code{alpha <= 0}, \code{beta <= 0},
#'   \code{gamma <= 0}, \code{delta < 0}).
#'
#' @details
#' The probability density function (PDF) of the Beta-Kumaraswamy (BKw)
#' distribution is given by:
#' \deqn{
#' f(x; \alpha, \beta, \gamma, \delta) = \frac{\alpha \beta}{B(\gamma, \delta+1)} x^{\alpha - 1} \bigl(1 - x^\alpha\bigr)^{\beta(\delta+1) - 1} \bigl[1 - \bigl(1 - x^\alpha\bigr)^\beta\bigr]^{\gamma - 1}
#' }
#' for \eqn{0 < x < 1}, where \eqn{B(a,b)} is the Beta function
#' (\code{\link[base]{beta}}).
#'
#' The BKw distribution is a special case of the five-parameter
#' Generalized Kumaraswamy (GKw) distribution (\code{\link{dgkw}}) obtained
#' by setting the parameter \eqn{\lambda = 1}.
#' Numerical evaluation is performed using algorithms similar to those for `dgkw`,
#' ensuring stability.
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#' @seealso
#' \code{\link{dgkw}} (parent distribution density),
#' \code{\link{pbkw}}, \code{\link{qbkw}}, \code{\link{rbkw}} (other BKw functions),
#'
#' @examples
#' \donttest{
#' # Example values
#' x_vals <- c(0.2, 0.5, 0.8)
#' alpha_par <- 2.0
#' beta_par <- 1.5
#' gamma_par <- 1.0 # Equivalent to Kw when gamma=1
#' delta_par <- 0.5
#'
#' # Calculate density
#' densities <- dbkw(x_vals, alpha_par, beta_par, gamma_par, delta_par)
#' print(densities)
#'
#' # Calculate log-density
#' log_densities <- dbkw(x_vals, alpha_par, beta_par, gamma_par, delta_par,
#'                       log_prob = TRUE)
#' print(log_densities)
#' # Check: should match log(densities)
#' print(log(densities))
#'
#' # Compare with dgkw setting lambda = 1
#' densities_gkw <- dgkw(x_vals, alpha_par, beta_par, gamma = gamma_par,
#'                       delta = delta_par, lambda = 1.0)
#' print(paste("Max difference:", max(abs(densities - densities_gkw)))) # Should be near zero
#'
#' # Plot the density for different gamma values
#' curve_x <- seq(0.01, 0.99, length.out = 200)
#' curve_y1 <- dbkw(curve_x, alpha = 2, beta = 3, gamma = 0.5, delta = 1)
#' curve_y2 <- dbkw(curve_x, alpha = 2, beta = 3, gamma = 1.0, delta = 1)
#' curve_y3 <- dbkw(curve_x, alpha = 2, beta = 3, gamma = 2.0, delta = 1)
#'
#' plot(curve_x, curve_y1, type = "l", main = "BKw Density Examples (alpha=2, beta=3, delta=1)",
#'      xlab = "x", ylab = "f(x)", col = "blue", ylim = range(0, curve_y1, curve_y2, curve_y3))
#' lines(curve_x, curve_y2, col = "red")
#' lines(curve_x, curve_y3, col = "green")
#' legend("topright", legend = c("gamma=0.5", "gamma=1.0", "gamma=2.0"),
#'        col = c("blue", "red", "green"), lty = 1, bty = "n")
#' }
#'
#' @export
dbkw <- function(x, alpha, beta, gamma, delta, log_prob = FALSE) {
    .Call(`_gkwreg_dbkw`, x, alpha, beta, gamma, delta, log_prob)
}

#' @title Cumulative Distribution Function (CDF) of the Beta-Kumaraswamy (BKw) Distribution
#' @author Lopes, J. E.
#' @keywords distribution cumulative
#'
#' @description
#' Computes the cumulative distribution function (CDF), \eqn{P(X \le q)}, for the
#' Beta-Kumaraswamy (BKw) distribution with parameters \code{alpha} (\eqn{\alpha}),
#' \code{beta} (\eqn{\beta}), \code{gamma} (\eqn{\gamma}), and \code{delta}
#' (\eqn{\delta}). This distribution is defined on the interval (0, 1) and is
#' a special case of the Generalized Kumaraswamy (GKw) distribution where
#' \eqn{\lambda = 1}.
#'
#' @param q Vector of quantiles (values generally between 0 and 1).
#' @param alpha Shape parameter \code{alpha} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param beta Shape parameter \code{beta} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param gamma Shape parameter \code{gamma} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param delta Shape parameter \code{delta} >= 0. Can be a scalar or a vector.
#'   Default: 0.0.
#' @param lower_tail Logical; if \code{TRUE} (default), probabilities are
#'   \eqn{P(X \le q)}, otherwise, \eqn{P(X > q)}.
#' @param log_p Logical; if \code{TRUE}, probabilities \eqn{p} are given as
#'   \eqn{\log(p)}. Default: \code{FALSE}.
#'
#' @return A vector of probabilities, \eqn{F(q)}, or their logarithms/complements
#'   depending on \code{lower_tail} and \code{log_p}. The length of the result
#'   is determined by the recycling rule applied to the arguments (\code{q},
#'   \code{alpha}, \code{beta}, \code{gamma}, \code{delta}). Returns \code{0}
#'   (or \code{-Inf} if \code{log_p = TRUE}) for \code{q <= 0} and \code{1}
#'   (or \code{0} if \code{log_p = TRUE}) for \code{q >= 1}. Returns \code{NaN}
#'   for invalid parameters.
#'
#' @details
#' The Beta-Kumaraswamy (BKw) distribution is a special case of the
#' five-parameter Generalized Kumaraswamy distribution (\code{\link{pgkw}})
#' obtained by setting the shape parameter \eqn{\lambda = 1}.
#'
#' The CDF of the GKw distribution is \eqn{F_{GKw}(q) = I_{y(q)}(\gamma, \delta+1)},
#' where \eqn{y(q) = [1-(1-q^{\alpha})^{\beta}]^{\lambda}} and \eqn{I_x(a,b)}
#' is the regularized incomplete beta function (\code{\link[stats]{pbeta}}).
#' Setting \eqn{\lambda=1} simplifies \eqn{y(q)} to \eqn{1 - (1 - q^\alpha)^\beta},
#' yielding the BKw CDF:
#' \deqn{
#' F(q; \alpha, \beta, \gamma, \delta) = I_{1 - (1 - q^\alpha)^\beta}(\gamma, \delta+1)
#' }
#' This is evaluated using the \code{\link[stats]{pbeta}} function.
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#' @seealso
#' \code{\link{pgkw}} (parent distribution CDF),
#' \code{\link{dbkw}}, \code{\link{qbkw}}, \code{\link{rbkw}} (other BKw functions),
#' \code{\link[stats]{pbeta}}
#'
#' @examples
#' \donttest{
#' # Example values
#' q_vals <- c(0.2, 0.5, 0.8)
#' alpha_par <- 2.0
#' beta_par <- 1.5
#' gamma_par <- 1.0
#' delta_par <- 0.5
#'
#' # Calculate CDF P(X <= q)
#' probs <- pbkw(q_vals, alpha_par, beta_par, gamma_par, delta_par)
#' print(probs)
#'
#' # Calculate upper tail P(X > q)
#' probs_upper <- pbkw(q_vals, alpha_par, beta_par, gamma_par, delta_par,
#'                     lower_tail = FALSE)
#' print(probs_upper)
#' # Check: probs + probs_upper should be 1
#' print(probs + probs_upper)
#'
#' # Calculate log CDF
#' log_probs <- pbkw(q_vals, alpha_par, beta_par, gamma_par, delta_par,
#'                   log_p = TRUE)
#' print(log_probs)
#' # Check: should match log(probs)
#' print(log(probs))
#'
#' # Compare with pgkw setting lambda = 1
#' probs_gkw <- pgkw(q_vals, alpha_par, beta_par, gamma = gamma_par,
#'                  delta = delta_par, lambda = 1.0)
#' print(paste("Max difference:", max(abs(probs - probs_gkw)))) # Should be near zero
#'
#' # Plot the CDF
#' curve_q <- seq(0.01, 0.99, length.out = 200)
#' curve_p <- pbkw(curve_q, alpha = 2, beta = 3, gamma = 0.5, delta = 1)
#' plot(curve_q, curve_p, type = "l", main = "BKw CDF Example",
#'      xlab = "q", ylab = "F(q)", col = "blue", ylim = c(0, 1))
#' }
#'
#' @export
pbkw <- function(q, alpha, beta, gamma, delta, lower_tail = TRUE, log_p = FALSE) {
    .Call(`_gkwreg_pbkw`, q, alpha, beta, gamma, delta, lower_tail, log_p)
}

#' @title Quantile Function of the Beta-Kumaraswamy (BKw) Distribution
#' @author Lopes, J. E.
#' @keywords distribution quantile
#'
#' @description
#' Computes the quantile function (inverse CDF) for the Beta-Kumaraswamy (BKw)
#' distribution with parameters \code{alpha} (\eqn{\alpha}), \code{beta}
#' (\eqn{\beta}), \code{gamma} (\eqn{\gamma}), and \code{delta} (\eqn{\delta}).
#' It finds the value \code{q} such that \eqn{P(X \le q) = p}. This distribution
#' is a special case of the Generalized Kumaraswamy (GKw) distribution where
#' the parameter \eqn{\lambda = 1}.
#'
#' @param p Vector of probabilities (values between 0 and 1).
#' @param alpha Shape parameter \code{alpha} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param beta Shape parameter \code{beta} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param gamma Shape parameter \code{gamma} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param delta Shape parameter \code{delta} >= 0. Can be a scalar or a vector.
#'   Default: 0.0.
#' @param lower_tail Logical; if \code{TRUE} (default), probabilities are \eqn{p = P(X \le q)},
#'   otherwise, probabilities are \eqn{p = P(X > q)}.
#' @param log_p Logical; if \code{TRUE}, probabilities \code{p} are given as
#'   \eqn{\log(p)}. Default: \code{FALSE}.
#'
#' @return A vector of quantiles corresponding to the given probabilities \code{p}.
#'   The length of the result is determined by the recycling rule applied to
#'   the arguments (\code{p}, \code{alpha}, \code{beta}, \code{gamma}, \code{delta}).
#'   Returns:
#'   \itemize{
#'     \item \code{0} for \code{p = 0} (or \code{p = -Inf} if \code{log_p = TRUE},
#'           when \code{lower_tail = TRUE}).
#'     \item \code{1} for \code{p = 1} (or \code{p = 0} if \code{log_p = TRUE},
#'           when \code{lower_tail = TRUE}).
#'     \item \code{NaN} for \code{p < 0} or \code{p > 1} (or corresponding log scale).
#'     \item \code{NaN} for invalid parameters (e.g., \code{alpha <= 0},
#'           \code{beta <= 0}, \code{gamma <= 0}, \code{delta < 0}).
#'   }
#'   Boundary return values are adjusted accordingly for \code{lower_tail = FALSE}.
#'
#' @details
#' The quantile function \eqn{Q(p)} is the inverse of the CDF \eqn{F(q)}. The CDF
#' for the BKw (\eqn{\lambda=1}) distribution is \eqn{F(q) = I_{y(q)}(\gamma, \delta+1)},
#' where \eqn{y(q) = 1 - (1 - q^\alpha)^\beta} and \eqn{I_z(a,b)} is the
#' regularized incomplete beta function (see \code{\link{pbkw}}).
#'
#' To find the quantile \eqn{q}, we first invert the outer Beta part: let
#' \eqn{y = I^{-1}_{p}(\gamma, \delta+1)}, where \eqn{I^{-1}_p(a,b)} is the
#' inverse of the regularized incomplete beta function, computed via
#' \code{\link[stats]{qbeta}}. Then, we invert the inner Kumaraswamy part:
#' \eqn{y = 1 - (1 - q^\alpha)^\beta}, which leads to \eqn{q = \{1 - (1-y)^{1/\beta}\}^{1/\alpha}}.
#' Substituting \eqn{y} gives the quantile function:
#' \deqn{
#' Q(p) = \left\{ 1 - \left[ 1 - I^{-1}_{p}(\gamma, \delta+1) \right]^{1/\beta} \right\}^{1/\alpha}
#' }
#' The function uses this formula, calculating \eqn{I^{-1}_{p}(\gamma, \delta+1)}
#' via \code{qbeta(p, gamma, delta + 1, ...)} while respecting the
#' \code{lower_tail} and \code{log_p} arguments.
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#' @seealso
#' \code{\link{qgkw}} (parent distribution quantile function),
#' \code{\link{dbkw}}, \code{\link{pbkw}}, \code{\link{rbkw}} (other BKw functions),
#' \code{\link[stats]{qbeta}}
#'
#' @examples
#' \donttest{
#' # Example values
#' p_vals <- c(0.1, 0.5, 0.9)
#' alpha_par <- 2.0
#' beta_par <- 1.5
#' gamma_par <- 1.0
#' delta_par <- 0.5
#'
#' # Calculate quantiles
#' quantiles <- qbkw(p_vals, alpha_par, beta_par, gamma_par, delta_par)
#' print(quantiles)
#'
#' # Calculate quantiles for upper tail probabilities P(X > q) = p
#' quantiles_upper <- qbkw(p_vals, alpha_par, beta_par, gamma_par, delta_par,
#'                         lower_tail = FALSE)
#' print(quantiles_upper)
#' # Check: qbkw(p, ..., lt=F) == qbkw(1-p, ..., lt=T)
#' print(qbkw(1 - p_vals, alpha_par, beta_par, gamma_par, delta_par))
#'
#' # Calculate quantiles from log probabilities
#' log_p_vals <- log(p_vals)
#' quantiles_logp <- qbkw(log_p_vals, alpha_par, beta_par, gamma_par, delta_par,
#'                        log_p = TRUE)
#' print(quantiles_logp)
#' # Check: should match original quantiles
#' print(quantiles)
#'
#' # Compare with qgkw setting lambda = 1
#' quantiles_gkw <- qgkw(p_vals, alpha_par, beta_par, gamma = gamma_par,
#'                      delta = delta_par, lambda = 1.0)
#' print(paste("Max difference:", max(abs(quantiles - quantiles_gkw)))) # Should be near zero
#'
#' # Verify inverse relationship with pbkw
#' p_check <- 0.75
#' q_calc <- qbkw(p_check, alpha_par, beta_par, gamma_par, delta_par)
#' p_recalc <- pbkw(q_calc, alpha_par, beta_par, gamma_par, delta_par)
#' print(paste("Original p:", p_check, " Recalculated p:", p_recalc))
#' # abs(p_check - p_recalc) < 1e-9 # Should be TRUE
#'
#' # Boundary conditions
#' print(qbkw(c(0, 1), alpha_par, beta_par, gamma_par, delta_par)) # Should be 0, 1
#' print(qbkw(c(-Inf, 0), alpha_par, beta_par, gamma_par, delta_par, log_p = TRUE)) # Should be 0, 1
#'
#' }
#'
#' @export
qbkw <- function(p, alpha, beta, gamma, delta, lower_tail = TRUE, log_p = FALSE) {
    .Call(`_gkwreg_qbkw`, p, alpha, beta, gamma, delta, lower_tail, log_p)
}

#' @title Random Number Generation for the Beta-Kumaraswamy (BKw) Distribution
#' @author Lopes, J. E.
#' @keywords distribution random
#'
#' @description
#' Generates random deviates from the Beta-Kumaraswamy (BKw) distribution
#' with parameters \code{alpha} (\eqn{\alpha}), \code{beta} (\eqn{\beta}),
#' \code{gamma} (\eqn{\gamma}), and \code{delta} (\eqn{\delta}). This distribution
#' is a special case of the Generalized Kumaraswamy (GKw) distribution where
#' the parameter \eqn{\lambda = 1}.
#'
#' @param n Number of observations. If \code{length(n) > 1}, the length is
#'   taken to be the number required. Must be a non-negative integer.
#' @param alpha Shape parameter \code{alpha} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param beta Shape parameter \code{beta} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param gamma Shape parameter \code{gamma} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param delta Shape parameter \code{delta} >= 0. Can be a scalar or a vector.
#'   Default: 0.0.
#'
#' @return A vector of length \code{n} containing random deviates from the BKw
#'   distribution. The length of the result is determined by \code{n} and the
#'   recycling rule applied to the parameters (\code{alpha}, \code{beta},
#'   \code{gamma}, \code{delta}). Returns \code{NaN} if parameters
#'   are invalid (e.g., \code{alpha <= 0}, \code{beta <= 0}, \code{gamma <= 0},
#'   \code{delta < 0}).
#'
#' @details
#' The generation method uses the relationship between the GKw distribution and the
#' Beta distribution. The general procedure for GKw (\code{\link{rgkw}}) is:
#' If \eqn{W \sim \mathrm{Beta}(\gamma, \delta+1)}, then
#' \eqn{X = \{1 - [1 - W^{1/\lambda}]^{1/\beta}\}^{1/\alpha}} follows the
#' GKw(\eqn{\alpha, \beta, \gamma, \delta, \lambda}) distribution.
#'
#' For the BKw distribution, \eqn{\lambda=1}. Therefore, the algorithm simplifies to:
#' \enumerate{
#'   \item Generate \eqn{V \sim \mathrm{Beta}(\gamma, \delta+1)} using
#'         \code{\link[stats]{rbeta}}.
#'   \item Compute the BKw variate \eqn{X = \{1 - (1 - V)^{1/\beta}\}^{1/\alpha}}.
#' }
#' This procedure is implemented efficiently, handling parameter recycling as needed.
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#'
#' Devroye, L. (1986). *Non-Uniform Random Variate Generation*. Springer-Verlag.
#' (General methods for random variate generation).
#'
#' @seealso
#' \code{\link{rgkw}} (parent distribution random generation),
#' \code{\link{dbkw}}, \code{\link{pbkw}}, \code{\link{qbkw}} (other BKw functions),
#' \code{\link[stats]{rbeta}}
#'
#' @examples
#' \donttest{
#' set.seed(2026) # for reproducibility
#'
#' # Generate 1000 random values from a specific BKw distribution
#' alpha_par <- 2.0
#' beta_par <- 1.5
#' gamma_par <- 1.0
#' delta_par <- 0.5
#'
#' x_sample_bkw <- rbkw(1000, alpha = alpha_par, beta = beta_par,
#'                      gamma = gamma_par, delta = delta_par)
#' summary(x_sample_bkw)
#'
#' # Histogram of generated values compared to theoretical density
#' hist(x_sample_bkw, breaks = 30, freq = FALSE, # freq=FALSE for density
#'      main = "Histogram of BKw Sample", xlab = "x", ylim = c(0, 2.5))
#' curve(dbkw(x, alpha = alpha_par, beta = beta_par, gamma = gamma_par,
#'            delta = delta_par),
#'       add = TRUE, col = "red", lwd = 2, n = 201)
#' legend("topright", legend = "Theoretical PDF", col = "red", lwd = 2, bty = "n")
#'
#' # Comparing empirical and theoretical quantiles (Q-Q plot)
#' prob_points <- seq(0.01, 0.99, by = 0.01)
#' theo_quantiles <- qbkw(prob_points, alpha = alpha_par, beta = beta_par,
#'                        gamma = gamma_par, delta = delta_par)
#' emp_quantiles <- quantile(x_sample_bkw, prob_points, type = 7)
#'
#' plot(theo_quantiles, emp_quantiles, pch = 16, cex = 0.8,
#'      main = "Q-Q Plot for BKw Distribution",
#'      xlab = "Theoretical Quantiles", ylab = "Empirical Quantiles (n=1000)")
#' abline(a = 0, b = 1, col = "blue", lty = 2)
#'
#' # Compare summary stats with rgkw(..., lambda=1, ...)
#' # Note: individual values will differ due to randomness
#' x_sample_gkw <- rgkw(1000, alpha = alpha_par, beta = beta_par, gamma = gamma_par,
#'                      delta = delta_par, lambda = 1.0)
#' print("Summary stats for rbkw sample:")
#' print(summary(x_sample_bkw))
#' print("Summary stats for rgkw(lambda=1) sample:")
#' print(summary(x_sample_gkw)) # Should be similar
#'
#' }
#'
#' @export
rbkw <- function(n, alpha, beta, gamma, delta) {
    .Call(`_gkwreg_rbkw`, n, alpha, beta, gamma, delta)
}

#' @title Negative Log-Likelihood for Beta-Kumaraswamy (BKw) Distribution
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize
#'
#' @description
#' Computes the negative log-likelihood function for the Beta-Kumaraswamy (BKw)
#' distribution with parameters \code{alpha} (\eqn{\alpha}), \code{beta}
#' (\eqn{\beta}), \code{gamma} (\eqn{\gamma}), and \code{delta} (\eqn{\delta}),
#' given a vector of observations. This distribution is the special case of the
#' Generalized Kumaraswamy (GKw) distribution where \eqn{\lambda = 1}. This function
#' is typically used for maximum likelihood estimation via numerical optimization.
#'
#' @param par A numeric vector of length 4 containing the distribution parameters
#'   in the order: \code{alpha} (\eqn{\alpha > 0}), \code{beta} (\eqn{\beta > 0}),
#'   \code{gamma} (\eqn{\gamma > 0}), \code{delta} (\eqn{\delta \ge 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a single \code{double} value representing the negative
#'   log-likelihood (\eqn{-\ell(\theta|\mathbf{x})}). Returns \code{Inf}
#'   if any parameter values in \code{par} are invalid according to their
#'   constraints, or if any value in \code{data} is not in the interval (0, 1).
#'
#' @details
#' The Beta-Kumaraswamy (BKw) distribution is the GKw distribution (\code{\link{dgkw}})
#' with \eqn{\lambda=1}. Its probability density function (PDF) is:
#' \deqn{
#' f(x | \theta) = \frac{\alpha \beta}{B(\gamma, \delta+1)} x^{\alpha - 1} \bigl(1 - x^\alpha\bigr)^{\beta(\delta+1) - 1} \bigl[1 - \bigl(1 - x^\alpha\bigr)^\beta\bigr]^{\gamma - 1}
#' }
#' for \eqn{0 < x < 1}, \eqn{\theta = (\alpha, \beta, \gamma, \delta)}, and \eqn{B(a,b)}
#' is the Beta function (\code{\link[base]{beta}}).
#' The log-likelihood function \eqn{\ell(\theta | \mathbf{x})} for a sample
#' \eqn{\mathbf{x} = (x_1, \dots, x_n)} is \eqn{\sum_{i=1}^n \ln f(x_i | \theta)}:
#' \deqn{
#' \ell(\theta | \mathbf{x}) = n[\ln(\alpha) + \ln(\beta) - \ln B(\gamma, \delta+1)]
#' + \sum_{i=1}^{n} [(\alpha-1)\ln(x_i) + (\beta(\delta+1)-1)\ln(v_i) + (\gamma-1)\ln(w_i)]
#' }
#' where:
#' \itemize{
#'   \item \eqn{v_i = 1 - x_i^{\alpha}}
#'   \item \eqn{w_i = 1 - v_i^{\beta} = 1 - (1-x_i^{\alpha})^{\beta}}
#' }
#' This function computes and returns the *negative* log-likelihood, \eqn{-\ell(\theta|\mathbf{x})},
#' suitable for minimization using optimization routines like \code{\link[stats]{optim}}.
#' Numerical stability is maintained similarly to \code{\link{llgkw}}.
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#'
#' @seealso
#' \code{\link{llgkw}} (parent distribution negative log-likelihood),
#' \code{\link{dbkw}}, \code{\link{pbkw}}, \code{\link{qbkw}}, \code{\link{rbkw}},
#' \code{grbkw} (gradient, if available),
#' \code{hsbkw} (Hessian, if available),
#' \code{\link[stats]{optim}}, \code{\link[base]{lbeta}}
#'
#' @examples
#' \donttest{
#'
#' # Generate sample data from a known BKw distribution
#' set.seed(2203)
#' true_par_bkw <- c(alpha = 2.0, beta = 1.5, gamma = 1.5, delta = 0.5)
#' sample_data_bkw <- rbkw(1000, alpha = true_par_bkw[1], beta = true_par_bkw[2],
#'                          gamma = true_par_bkw[3], delta = true_par_bkw[4])
#' hist(sample_data_bkw, breaks = 20, main = "BKw(2, 1.5, 1.5, 0.5) Sample")
#'
#' # --- Maximum Likelihood Estimation using optim ---
#' # Initial parameter guess
#' start_par_bkw <- c(1.8, 1.2, 1.1, 0.3)
#'
#' # Perform optimization (minimizing negative log-likelihood)
#' mle_result_bkw <- stats::optim(par = start_par_bkw,
#'                                fn = llbkw, # Use the BKw neg-log-likelihood
#'                                method = "BFGS", # Needs parameters > 0, consider L-BFGS-B
#'                                hessian = TRUE,
#'                                data = sample_data_bkw)
#'
#' # Check convergence and results
#' if (mle_result_bkw$convergence == 0) {
#'   print("Optimization converged successfully.")
#'   mle_par_bkw <- mle_result_bkw$par
#'   print("Estimated BKw parameters:")
#'   print(mle_par_bkw)
#'   print("True BKw parameters:")
#'   print(true_par_bkw)
#' } else {
#'   warning("Optimization did not converge!")
#'   print(mle_result_bkw$message)
#' }
#'
#' # --- Compare numerical and analytical derivatives (if available) ---
#' # Requires 'numDeriv' package and analytical functions 'grbkw', 'hsbkw'
#' if (mle_result_bkw$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE) &&
#'     exists("grbkw") && exists("hsbkw")) {
#'
#'   cat("\nComparing Derivatives at BKw MLE estimates:\n")
#'
#'   # Numerical derivatives of llbkw
#'   num_grad_bkw <- numDeriv::grad(func = llbkw, x = mle_par_bkw, data = sample_data_bkw)
#'   num_hess_bkw <- numDeriv::hessian(func = llbkw, x = mle_par_bkw, data = sample_data_bkw)
#'
#'   # Analytical derivatives (assuming they return derivatives of negative LL)
#'   ana_grad_bkw <- grbkw(par = mle_par_bkw, data = sample_data_bkw)
#'   ana_hess_bkw <- hsbkw(par = mle_par_bkw, data = sample_data_bkw)
#'
#'   # Check differences
#'   cat("Max absolute difference between gradients:\n")
#'   print(max(abs(num_grad_bkw - ana_grad_bkw)))
#'   cat("Max absolute difference between Hessians:\n")
#'   print(max(abs(num_hess_bkw - ana_hess_bkw)))
#'
#' } else {
#'    cat("\nSkipping derivative comparison for BKw.\n")
#'    cat("Requires convergence, 'numDeriv' package and functions 'grbkw', 'hsbkw'.\n")
#' }
#'
#' }
#'
#' @export
llbkw <- function(par, data) {
    .Call(`_gkwreg_llbkw`, par, data)
}

#' @title Gradient of the Negative Log-Likelihood for the BKw Distribution
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize gradient
#'
#' @description
#' Computes the gradient vector (vector of first partial derivatives) of the
#' negative log-likelihood function for the Beta-Kumaraswamy (BKw) distribution
#' with parameters \code{alpha} (\eqn{\alpha}), \code{beta} (\eqn{\beta}),
#' \code{gamma} (\eqn{\gamma}), and \code{delta} (\eqn{\delta}). This distribution
#' is the special case of the Generalized Kumaraswamy (GKw) distribution where
#' \eqn{\lambda = 1}. The gradient is typically used in optimization algorithms
#' for maximum likelihood estimation.
#'
#' @param par A numeric vector of length 4 containing the distribution parameters
#'   in the order: \code{alpha} (\eqn{\alpha > 0}), \code{beta} (\eqn{\beta > 0}),
#'   \code{gamma} (\eqn{\gamma > 0}), \code{delta} (\eqn{\delta \ge 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a numeric vector of length 4 containing the partial derivatives
#'   of the negative log-likelihood function \eqn{-\ell(\theta | \mathbf{x})} with
#'   respect to each parameter:
#'   \eqn{(-\partial \ell/\partial \alpha, -\partial \ell/\partial \beta, -\partial \ell/\partial \gamma, -\partial \ell/\partial \delta)}.
#'   Returns a vector of \code{NaN} if any parameter values are invalid according
#'   to their constraints, or if any value in \code{data} is not in the
#'   interval (0, 1).
#'
#' @details
#' The components of the gradient vector of the negative log-likelihood
#' (\eqn{-\nabla \ell(\theta | \mathbf{x})}) for the BKw (\eqn{\lambda=1}) model are:
#'
#' \deqn{
#' -\frac{\partial \ell}{\partial \alpha} = -\frac{n}{\alpha} - \sum_{i=1}^{n}\ln(x_i)
#' + \sum_{i=1}^{n}\left[x_i^{\alpha} \ln(x_i) \left(\frac{\beta(\delta+1)-1}{v_i} -
#' \frac{(\gamma-1) \beta v_i^{\beta-1}}{w_i}\right)\right]
#' }
#' \deqn{
#' -\frac{\partial \ell}{\partial \beta} = -\frac{n}{\beta} - (\delta+1)\sum_{i=1}^{n}\ln(v_i)
#' + \sum_{i=1}^{n}\left[\frac{(\gamma-1) v_i^{\beta} \ln(v_i)}{w_i}\right]
#' }
#' \deqn{
#' -\frac{\partial \ell}{\partial \gamma} = n[\psi(\gamma) - \psi(\gamma+\delta+1)] -
#' \sum_{i=1}^{n}\ln(w_i)
#' }
#' \deqn{
#' -\frac{\partial \ell}{\partial \delta} = n[\psi(\delta+1) - \psi(\gamma+\delta+1)] -
#' \beta\sum_{i=1}^{n}\ln(v_i)
#' }
#'
#' where:
#' \itemize{
#'   \item \eqn{v_i = 1 - x_i^{\alpha}}
#'   \item \eqn{w_i = 1 - v_i^{\beta} = 1 - (1-x_i^{\alpha})^{\beta}}
#'   \item \eqn{\psi(\cdot)} is the digamma function (\code{\link[base]{digamma}}).
#' }
#' These formulas represent the derivatives of \eqn{-\ell(\theta)}, consistent with
#' minimizing the negative log-likelihood. They correspond to the general GKw
#' gradient (\code{\link{grgkw}}) components for \eqn{\alpha, \beta, \gamma, \delta}
#' evaluated at \eqn{\lambda=1}. Note that the component for \eqn{\lambda} is omitted.
#' Numerical stability is maintained through careful implementation.
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#' (Note: Specific gradient formulas might be derived or sourced from additional references).
#'
#' @seealso
#' \code{\link{grgkw}} (parent distribution gradient),
#' \code{\link{llbkw}} (negative log-likelihood for BKw),
#' \code{\link{hsbkw}} (Hessian for BKw, if available),
#' \code{\link{dbkw}} (density for BKw),
#' \code{\link[stats]{optim}},
#' \code{\link[numDeriv]{grad}} (for numerical gradient comparison),
#' \code{\link[base]{digamma}}.
#'
#' @examples
#' \donttest{
#' # Assuming existence of rbkw, llbkw, grbkw, hsbkw functions for BKw
#'
#' # Generate sample data
#' set.seed(123)
#' true_par_bkw <- c(alpha = 2, beta = 3, gamma = 1, delta = 0.5)
#' if (exists("rbkw")) {
#'   sample_data_bkw <- rbkw(100, alpha = true_par_bkw[1], beta = true_par_bkw[2],
#'                          gamma = true_par_bkw[3], delta = true_par_bkw[4])
#' } else {
#'   sample_data_bkw <- rgkw(100, alpha = true_par_bkw[1], beta = true_par_bkw[2],
#'                          gamma = true_par_bkw[3], delta = true_par_bkw[4], lambda = 1)
#' }
#' hist(sample_data_bkw, breaks = 20, main = "BKw(2, 3, 1, 0.5) Sample")
#'
#' # --- Find MLE estimates ---
#' start_par_bkw <- c(1.5, 2.5, 0.8, 0.3)
#' mle_result_bkw <- stats::optim(par = start_par_bkw,
#'                                fn = llbkw,
#'                                gr = grbkw, # Use analytical gradient for BKw
#'                                method = "BFGS",
#'                                hessian = TRUE,
#'                                data = sample_data_bkw)
#'
#' # --- Compare analytical gradient to numerical gradient ---
#' if (mle_result_bkw$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE)) {
#'
#'   mle_par_bkw <- mle_result_bkw$par
#'   cat("\nComparing Gradients for BKw at MLE estimates:\n")
#'
#'   # Numerical gradient of llbkw
#'   num_grad_bkw <- numDeriv::grad(func = llbkw, x = mle_par_bkw, data = sample_data_bkw)
#'
#'   # Analytical gradient from grbkw
#'   ana_grad_bkw <- grbkw(par = mle_par_bkw, data = sample_data_bkw)
#'
#'   cat("Numerical Gradient (BKw):\n")
#'   print(num_grad_bkw)
#'   cat("Analytical Gradient (BKw):\n")
#'   print(ana_grad_bkw)
#'
#'   # Check differences
#'   cat("Max absolute difference between BKw gradients:\n")
#'   print(max(abs(num_grad_bkw - ana_grad_bkw)))
#'
#' } else {
#'   cat("\nSkipping BKw gradient comparison.\n")
#' }
#'
#' # --- Optional: Compare with relevant components of GKw gradient ---
#' # Requires grgkw function
#' if (mle_result_bkw$convergence == 0 && exists("grgkw")) {
#'   # Create 5-param vector for grgkw (insert lambda=1)
#'   mle_par_gkw_equiv <- c(mle_par_bkw[1:4], lambda = 1.0)
#'   ana_grad_gkw <- grgkw(par = mle_par_gkw_equiv, data = sample_data_bkw)
#'   # Extract components corresponding to alpha, beta, gamma, delta
#'   ana_grad_gkw_subset <- ana_grad_gkw[c(1, 2, 3, 4)]
#'
#'   cat("\nComparison with relevant components of GKw gradient:\n")
#'   cat("Max absolute difference:\n")
#'   print(max(abs(ana_grad_bkw - ana_grad_gkw_subset))) # Should be very small
#' }
#'
#' }
#'
#' @export
#' @title Gradient of the Negative Log-Likelihood for the BKw Distribution
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize gradient
#'
#' @description
#' Computes the gradient vector (vector of first partial derivatives) of the
#' negative log-likelihood function for the Beta-Kumaraswamy (BKw) distribution
#' with parameters \code{alpha} (\eqn{\alpha}), \code{beta} (\eqn{\beta}),
#' \code{gamma} (\eqn{\gamma}), and \code{delta} (\eqn{\delta}). This distribution
#' is the special case of the Generalized Kumaraswamy (GKw) distribution where
#' \eqn{\lambda = 1}. The gradient is typically used in optimization algorithms
#' for maximum likelihood estimation.
#'
#' @param par A numeric vector of length 4 containing the distribution parameters
#'   in the order: \code{alpha} (\eqn{\alpha > 0}), \code{beta} (\eqn{\beta > 0}),
#'   \code{gamma} (\eqn{\gamma > 0}), \code{delta} (\eqn{\delta \ge 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a numeric vector of length 4 containing the partial derivatives
#'   of the negative log-likelihood function \eqn{-\ell(\theta | \mathbf{x})} with
#'   respect to each parameter:
#'   \eqn{(-\partial \ell/\partial \alpha, -\partial \ell/\partial \beta, -\partial \ell/\partial \gamma, -\partial \ell/\partial \delta)}.
#'   Returns a vector of \code{NaN} if any parameter values are invalid according
#'   to their constraints, or if any value in \code{data} is not in the
#'   interval (0, 1).
#'
#' @details
#' The components of the gradient vector of the negative log-likelihood
#' (\eqn{-\nabla \ell(\theta | \mathbf{x})}) for the BKw (\eqn{\lambda=1}) model are:
#'
#' \deqn{
#' -\frac{\partial \ell}{\partial \alpha} = -\frac{n}{\alpha} - \sum_{i=1}^{n}\ln(x_i)
#' + \sum_{i=1}^{n}\left[x_i^{\alpha} \ln(x_i) \left(\frac{\beta(\delta+1)-1}{v_i} -
#' \frac{(\gamma-1) \beta v_i^{\beta-1}}{w_i}\right)\right]
#' }
#' \deqn{
#' -\frac{\partial \ell}{\partial \beta} = -\frac{n}{\beta} - (\delta+1)\sum_{i=1}^{n}\ln(v_i)
#' + \sum_{i=1}^{n}\left[\frac{(\gamma-1) v_i^{\beta} \ln(v_i)}{w_i}\right]
#' }
#' \deqn{
#' -\frac{\partial \ell}{\partial \gamma} = n[\psi(\gamma) - \psi(\gamma+\delta+1)] -
#' \sum_{i=1}^{n}\ln(w_i)
#' }
#' \deqn{
#' -\frac{\partial \ell}{\partial \delta} = n[\psi(\delta+1) - \psi(\gamma+\delta+1)] -
#' \beta\sum_{i=1}^{n}\ln(v_i)
#' }
#'
#' where:
#' \itemize{
#'   \item \eqn{v_i = 1 - x_i^{\alpha}}
#'   \item \eqn{w_i = 1 - v_i^{\beta} = 1 - (1-x_i^{\alpha})^{\beta}}
#'   \item \eqn{\psi(\cdot)} is the digamma function (\code{\link[base]{digamma}}).
#' }
#' These formulas represent the derivatives of \eqn{-\ell(\theta)}, consistent with
#' minimizing the negative log-likelihood. They correspond to the general GKw
#' gradient (\code{\link{grgkw}}) components for \eqn{\alpha, \beta, \gamma, \delta}
#' evaluated at \eqn{\lambda=1}. Note that the component for \eqn{\lambda} is omitted.
#' Numerical stability is maintained through careful implementation.
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#' (Note: Specific gradient formulas might be derived or sourced from additional references).
#'
#' @seealso
#' \code{\link{grgkw}} (parent distribution gradient),
#' \code{\link{llbkw}} (negative log-likelihood for BKw),
#' \code{\link{hsbkw}} (Hessian for BKw, if available),
#' \code{\link{dbkw}} (density for BKw),
#' \code{\link[stats]{optim}},
#' \code{\link[numDeriv]{grad}} (for numerical gradient comparison),
#' \code{\link[base]{digamma}}.
#'
#' @examples
#' \donttest{
#' # Assuming existence of rbkw, llbkw, grbkw, hsbkw functions for BKw
#'
#' # Generate sample data
#' set.seed(123)
#' true_par_bkw <- c(alpha = 2, beta = 3, gamma = 1, delta = 0.5)
#' if (exists("rbkw")) {
#'   sample_data_bkw <- rbkw(100, alpha = true_par_bkw[1], beta = true_par_bkw[2],
#'                          gamma = true_par_bkw[3], delta = true_par_bkw[4])
#' } else {
#'   sample_data_bkw <- rgkw(100, alpha = true_par_bkw[1], beta = true_par_bkw[2],
#'                          gamma = true_par_bkw[3], delta = true_par_bkw[4], lambda = 1)
#' }
#' hist(sample_data_bkw, breaks = 20, main = "BKw(2, 3, 1, 0.5) Sample")
#'
#' # --- Find MLE estimates ---
#' start_par_bkw <- c(1.5, 2.5, 0.8, 0.3)
#' mle_result_bkw <- stats::optim(par = start_par_bkw,
#'                                fn = llbkw,
#'                                gr = grbkw, # Use analytical gradient for BKw
#'                                method = "BFGS",
#'                                hessian = TRUE,
#'                                data = sample_data_bkw)
#'
#' # --- Compare analytical gradient to numerical gradient ---
#' if (mle_result_bkw$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE)) {
#'
#'   mle_par_bkw <- mle_result_bkw$par
#'   cat("\nComparing Gradients for BKw at MLE estimates:\n")
#'
#'   # Numerical gradient of llbkw
#'   num_grad_bkw <- numDeriv::grad(func = llbkw, x = mle_par_bkw, data = sample_data_bkw)
#'
#'   # Analytical gradient from grbkw
#'   ana_grad_bkw <- grbkw(par = mle_par_bkw, data = sample_data_bkw)
#'
#'   cat("Numerical Gradient (BKw):\n")
#'   print(num_grad_bkw)
#'   cat("Analytical Gradient (BKw):\n")
#'   print(ana_grad_bkw)
#'
#'   # Check differences
#'   cat("Max absolute difference between BKw gradients:\n")
#'   print(max(abs(num_grad_bkw - ana_grad_bkw)))
#'
#' } else {
#'   cat("\nSkipping BKw gradient comparison.\n")
#' }
#'
#' # --- Optional: Compare with relevant components of GKw gradient ---
#' # Requires grgkw function
#' if (mle_result_bkw$convergence == 0 && exists("grgkw")) {
#'   # Create 5-param vector for grgkw (insert lambda=1)
#'   mle_par_gkw_equiv <- c(mle_par_bkw[1:4], lambda = 1.0)
#'   ana_grad_gkw <- grgkw(par = mle_par_gkw_equiv, data = sample_data_bkw)
#'   # Extract components corresponding to alpha, beta, gamma, delta
#'   ana_grad_gkw_subset <- ana_grad_gkw[c(1, 2, 3, 4)]
#'
#'   cat("\nComparison with relevant components of GKw gradient:\n")
#'   cat("Max absolute difference:\n")
#'   print(max(abs(ana_grad_bkw - ana_grad_gkw_subset))) # Should be very small
#' }
#'
#' }
#'
#' @export
grbkw <- function(par, data) {
    .Call(`_gkwreg_grbkw`, par, data)
}

#' @title Hessian Matrix of the Negative Log-Likelihood for the BKw Distribution
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize hessian
#'
#' @description
#' Computes the analytic 4x4 Hessian matrix (matrix of second partial derivatives)
#' of the negative log-likelihood function for the Beta-Kumaraswamy (BKw)
#' distribution with parameters \code{alpha} (\eqn{\alpha}), \code{beta}
#' (\eqn{\beta}), \code{gamma} (\eqn{\gamma}), and \code{delta} (\eqn{\delta}).
#' This distribution is the special case of the Generalized Kumaraswamy (GKw)
#' distribution where \eqn{\lambda = 1}. The Hessian is useful for estimating
#' standard errors and in optimization algorithms.
#'
#' @param par A numeric vector of length 4 containing the distribution parameters
#'   in the order: \code{alpha} (\eqn{\alpha > 0}), \code{beta} (\eqn{\beta > 0}),
#'   \code{gamma} (\eqn{\gamma > 0}), \code{delta} (\eqn{\delta \ge 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a 4x4 numeric matrix representing the Hessian matrix of the
#'   negative log-likelihood function, \eqn{-\partial^2 \ell / (\partial \theta_i \partial \theta_j)},
#'   where \eqn{\theta = (\alpha, \beta, \gamma, \delta)}.
#'   Returns a 4x4 matrix populated with \code{NaN} if any parameter values are
#'   invalid according to their constraints, or if any value in \code{data} is
#'   not in the interval (0, 1).
#'
#' @details
#' This function calculates the analytic second partial derivatives of the
#' negative log-likelihood function based on the BKw log-likelihood
#' (\eqn{\lambda=1} case of GKw, see \code{\link{llbkw}}):
#' \deqn{
#' \ell(\theta | \mathbf{x}) = n[\ln(\alpha) + \ln(\beta) - \ln B(\gamma, \delta+1)]
#' + \sum_{i=1}^{n} [(\alpha-1)\ln(x_i) + (\beta(\delta+1)-1)\ln(v_i) + (\gamma-1)\ln(w_i)]
#' }
#' where \eqn{\theta = (\alpha, \beta, \gamma, \delta)}, \eqn{B(a,b)}
#' is the Beta function (\code{\link[base]{beta}}), and intermediate terms are:
#' \itemize{
#'   \item \eqn{v_i = 1 - x_i^{\alpha}}
#'   \item \eqn{w_i = 1 - v_i^{\beta} = 1 - (1-x_i^{\alpha})^{\beta}}
#' }
#' The Hessian matrix returned contains the elements \eqn{- \frac{\partial^2 \ell(\theta | \mathbf{x})}{\partial \theta_i \partial \theta_j}}
#' for \eqn{\theta_i, \theta_j \in \{\alpha, \beta, \gamma, \delta\}}.
#'
#' Key properties of the returned matrix:
#' \itemize{
#'   \item Dimensions: 4x4.
#'   \item Symmetry: The matrix is symmetric.
#'   \item Ordering: Rows and columns correspond to the parameters in the order
#'     \eqn{\alpha, \beta, \gamma, \delta}.
#'   \item Content: Analytic second derivatives of the *negative* log-likelihood.
#' }
#' This corresponds to the relevant 4x4 submatrix of the 5x5 GKw Hessian (\code{\link{hsgkw}})
#' evaluated at \eqn{\lambda=1}. The exact analytical formulas are implemented directly.
#'
#' @references
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#' (Note: Specific Hessian formulas might be derived or sourced from additional references).
#'
#' @seealso
#' \code{\link{hsgkw}} (parent distribution Hessian),
#' \code{\link{llbkw}} (negative log-likelihood for BKw),
#' \code{\link{grbkw}} (gradient for BKw, if available),
#' \code{\link{dbkw}} (density for BKw),
#' \code{\link[stats]{optim}},
#' \code{\link[numDeriv]{hessian}} (for numerical Hessian comparison).
#'
#' @examples
#' \donttest{
#' # Assuming existence of rbkw, llbkw, grbkw, hsbkw functions for BKw
#'
#' # Generate sample data
#' set.seed(123)
#' true_par_bkw <- c(alpha = 2, beta = 3, gamma = 1, delta = 0.5)
#' if (exists("rbkw")) {
#'   sample_data_bkw <- rbkw(100, alpha = true_par_bkw[1], beta = true_par_bkw[2],
#'                          gamma = true_par_bkw[3], delta = true_par_bkw[4])
#' } else {
#'   sample_data_bkw <- rgkw(100, alpha = true_par_bkw[1], beta = true_par_bkw[2],
#'                          gamma = true_par_bkw[3], delta = true_par_bkw[4], lambda = 1)
#' }
#' hist(sample_data_bkw, breaks = 20, main = "BKw(2, 3, 1, 0.5) Sample")
#'
#' # --- Find MLE estimates ---
#' start_par_bkw <- c(1.5, 2.5, 0.8, 0.3)
#' mle_result_bkw <- stats::optim(par = start_par_bkw,
#'                                fn = llbkw,
#'                                gr = if (exists("grbkw")) grbkw else NULL,
#'                                method = "BFGS",
#'                                hessian = TRUE, # Ask optim for numerical Hessian
#'                                data = sample_data_bkw)
#'
#' # --- Compare analytical Hessian to numerical Hessian ---
#' if (mle_result_bkw$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE) &&
#'     exists("hsbkw")) {
#'
#'   mle_par_bkw <- mle_result_bkw$par
#'   cat("\nComparing Hessians for BKw at MLE estimates:\n")
#'
#'   # Numerical Hessian of llbkw
#'   num_hess_bkw <- numDeriv::hessian(func = llbkw, x = mle_par_bkw, data = sample_data_bkw)
#'
#'   # Analytical Hessian from hsbkw
#'   ana_hess_bkw <- hsbkw(par = mle_par_bkw, data = sample_data_bkw)
#'
#'   cat("Numerical Hessian (BKw):\n")
#'   print(round(num_hess_bkw, 4))
#'   cat("Analytical Hessian (BKw):\n")
#'   print(round(ana_hess_bkw, 4))
#'
#'   # Check differences
#'   cat("Max absolute difference between BKw Hessians:\n")
#'   print(max(abs(num_hess_bkw - ana_hess_bkw)))
#'
#'   # Optional: Use analytical Hessian for Standard Errors
#'   # tryCatch({
#'   #   cov_matrix_bkw <- solve(ana_hess_bkw)
#'   #   std_errors_bkw <- sqrt(diag(cov_matrix_bkw))
#'   #   cat("Std. Errors from Analytical BKw Hessian:\n")
#'   #   print(std_errors_bkw)
#'   # }, error = function(e) {
#'   #   warning("Could not invert analytical BKw Hessian: ", e$message)
#'   # })
#'
#' } else {
#'   cat("\nSkipping BKw Hessian comparison.\n")
#'   cat("Requires convergence, 'numDeriv' package, and function 'hsbkw'.\n")
#' }
#'
#' }
#'
#' @export
hsbkw <- function(par, data) {
    .Call(`_gkwreg_hsbkw`, par, data)
}

#' @title Density of the Exponentiated Kumaraswamy (EKw) Distribution
#'
#' @author Lopes, J. E.
#' @keywords distribution density
#'
#' @description
#' Computes the probability density function (PDF) for the Exponentiated
#' Kumaraswamy (EKw) distribution with parameters \code{alpha} (\eqn{\alpha}),
#' \code{beta} (\eqn{\beta}), and \code{lambda} (\eqn{\lambda}).
#' This distribution is defined on the interval (0, 1).
#'
#' @param x Vector of quantiles (values between 0 and 1).
#' @param alpha Shape parameter \code{alpha} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param beta Shape parameter \code{beta} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param lambda Shape parameter \code{lambda} > 0 (exponent parameter).
#'   Can be a scalar or a vector. Default: 1.0.
#' @param log_prob Logical; if \code{TRUE}, the logarithm of the density is
#'   returned (\eqn{\log(f(x))}). Default: \code{FALSE}.
#'
#' @return A vector of density values (\eqn{f(x)}) or log-density values
#'   (\eqn{\log(f(x))}). The length of the result is determined by the recycling
#'   rule applied to the arguments (\code{x}, \code{alpha}, \code{beta},
#'   \code{lambda}). Returns \code{0} (or \code{-Inf} if
#'   \code{log_prob = TRUE}) for \code{x} outside the interval (0, 1), or
#'   \code{NaN} if parameters are invalid (e.g., \code{alpha <= 0},
#'   \code{beta <= 0}, \code{lambda <= 0}).
#'
#' @details
#' The probability density function (PDF) of the Exponentiated Kumaraswamy (EKw)
#' distribution is given by:
#' \deqn{
#' f(x; \alpha, \beta, \lambda) = \lambda \alpha \beta x^{\alpha-1} (1 - x^\alpha)^{\beta-1} \bigl[1 - (1 - x^\alpha)^\beta \bigr]^{\lambda - 1}
#' }
#' for \eqn{0 < x < 1}.
#'
#' The EKw distribution is a special case of the five-parameter
#' Generalized Kumaraswamy (GKw) distribution (\code{\link{dgkw}}) obtained
#' by setting the parameters \eqn{\gamma = 1} and \eqn{\delta = 0}.
#' When \eqn{\lambda = 1}, the EKw distribution reduces to the standard
#' Kumaraswamy distribution.
#'
#' @references
#' Nadarajah, S., Cordeiro, G. M., & Ortega, E. M. (2012). The exponentiated
#' Kumaraswamy distribution. *Journal of the Franklin Institute*, *349*(3),
#'
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#'
#' @seealso
#' \code{\link{dgkw}} (parent distribution density),
#' \code{\link{pekw}}, \code{\link{qekw}}, \code{\link{rekw}} (other EKw functions),
#'
#' @examples
#' \donttest{
#' # Example values
#' x_vals <- c(0.2, 0.5, 0.8)
#' alpha_par <- 2.0
#' beta_par <- 3.0
#' lambda_par <- 1.5 # Exponent parameter
#'
#' # Calculate density
#' densities <- dekw(x_vals, alpha_par, beta_par, lambda_par)
#' print(densities)
#'
#' # Calculate log-density
#' log_densities <- dekw(x_vals, alpha_par, beta_par, lambda_par, log_prob = TRUE)
#' print(log_densities)
#' # Check: should match log(densities)
#' print(log(densities))
#'
#' # Compare with dgkw setting gamma = 1, delta = 0
#' densities_gkw <- dgkw(x_vals, alpha_par, beta_par, gamma = 1.0, delta = 0.0,
#'                       lambda = lambda_par)
#' print(paste("Max difference:", max(abs(densities - densities_gkw)))) # Should be near zero
#'
#' # Plot the density for different lambda values
#' curve_x <- seq(0.01, 0.99, length.out = 200)
#' curve_y1 <- dekw(curve_x, alpha = 2, beta = 3, lambda = 0.5) # less peaked
#' curve_y2 <- dekw(curve_x, alpha = 2, beta = 3, lambda = 1.0) # standard Kw
#' curve_y3 <- dekw(curve_x, alpha = 2, beta = 3, lambda = 2.0) # more peaked
#'
#' plot(curve_x, curve_y2, type = "l", main = "EKw Density Examples (alpha=2, beta=3)",
#'      xlab = "x", ylab = "f(x)", col = "red", ylim = range(0, curve_y1, curve_y2, curve_y3))
#' lines(curve_x, curve_y1, col = "blue")
#' lines(curve_x, curve_y3, col = "green")
#' legend("topright", legend = c("lambda=0.5", "lambda=1.0 (Kw)", "lambda=2.0"),
#'        col = c("blue", "red", "green"), lty = 1, bty = "n")
#' }
#'
#' @export
dekw <- function(x, alpha, beta, lambda, log_prob = FALSE) {
    .Call(`_gkwreg_dekw`, x, alpha, beta, lambda, log_prob)
}

#' @title Cumulative Distribution Function (CDF) of the EKw Distribution
#' @author Lopes, J. E.
#' @keywords distribution cumulative
#'
#' @description
#' Computes the cumulative distribution function (CDF), \eqn{P(X \le q)}, for the
#' Exponentiated Kumaraswamy (EKw) distribution with parameters \code{alpha}
#' (\eqn{\alpha}), \code{beta} (\eqn{\beta}), and \code{lambda} (\eqn{\lambda}).
#' This distribution is defined on the interval (0, 1) and is a special case
#' of the Generalized Kumaraswamy (GKw) distribution where \eqn{\gamma = 1}
#' and \eqn{\delta = 0}.
#'
#' @param q Vector of quantiles (values generally between 0 and 1).
#' @param alpha Shape parameter \code{alpha} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param beta Shape parameter \code{beta} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param lambda Shape parameter \code{lambda} > 0 (exponent parameter).
#'   Can be a scalar or a vector. Default: 1.0.
#' @param lower_tail Logical; if \code{TRUE} (default), probabilities are
#'   \eqn{P(X \le q)}, otherwise, \eqn{P(X > q)}.
#' @param log_p Logical; if \code{TRUE}, probabilities \eqn{p} are given as
#'   \eqn{\log(p)}. Default: \code{FALSE}.
#'
#' @return A vector of probabilities, \eqn{F(q)}, or their logarithms/complements
#'   depending on \code{lower_tail} and \code{log_p}. The length of the result
#'   is determined by the recycling rule applied to the arguments (\code{q},
#'   \code{alpha}, \code{beta}, \code{lambda}). Returns \code{0} (or \code{-Inf}
#'   if \code{log_p = TRUE}) for \code{q <= 0} and \code{1} (or \code{0} if
#'   \code{log_p = TRUE}) for \code{q >= 1}. Returns \code{NaN} for invalid
#'   parameters.
#'
#' @details
#' The Exponentiated Kumaraswamy (EKw) distribution is a special case of the
#' five-parameter Generalized Kumaraswamy distribution (\code{\link{pgkw}})
#' obtained by setting parameters \eqn{\gamma = 1} and \eqn{\delta = 0}.
#'
#' The CDF of the GKw distribution is \eqn{F_{GKw}(q) = I_{y(q)}(\gamma, \delta+1)},
#' where \eqn{y(q) = [1-(1-q^{\alpha})^{\beta}]^{\lambda}} and \eqn{I_x(a,b)}
#' is the regularized incomplete beta function (\code{\link[stats]{pbeta}}).
#' Setting \eqn{\gamma=1} and \eqn{\delta=0} gives \eqn{I_{y(q)}(1, 1)}. Since
#' \eqn{I_x(1, 1) = x}, the CDF simplifies to \eqn{y(q)}:
#' \deqn{
#' F(q; \alpha, \beta, \lambda) = \bigl[1 - (1 - q^\alpha)^\beta \bigr]^\lambda
#' }
#' for \eqn{0 < q < 1}.
#' The implementation uses this closed-form expression for efficiency and handles
#' \code{lower_tail} and \code{log_p} arguments appropriately.
#'
#' @references
#' Nadarajah, S., Cordeiro, G. M., & Ortega, E. M. (2012). The exponentiated
#' Kumaraswamy distribution. *Journal of the Franklin Institute*, *349*(3),
#'
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#'
#' @seealso
#' \code{\link{pgkw}} (parent distribution CDF),
#' \code{\link{dekw}}, \code{\link{qekw}}, \code{\link{rekw}} (other EKw functions),
#'
#' @examples
#' \donttest{
#' # Example values
#' q_vals <- c(0.2, 0.5, 0.8)
#' alpha_par <- 2.0
#' beta_par <- 3.0
#' lambda_par <- 1.5
#'
#' # Calculate CDF P(X <= q)
#' probs <- pekw(q_vals, alpha_par, beta_par, lambda_par)
#' print(probs)
#'
#' # Calculate upper tail P(X > q)
#' probs_upper <- pekw(q_vals, alpha_par, beta_par, lambda_par,
#'                     lower_tail = FALSE)
#' print(probs_upper)
#' # Check: probs + probs_upper should be 1
#' print(probs + probs_upper)
#'
#' # Calculate log CDF
#' log_probs <- pekw(q_vals, alpha_par, beta_par, lambda_par, log_p = TRUE)
#' print(log_probs)
#' # Check: should match log(probs)
#' print(log(probs))
#'
#' # Compare with pgkw setting gamma = 1, delta = 0
#' probs_gkw <- pgkw(q_vals, alpha_par, beta_par, gamma = 1.0, delta = 0.0,
#'                  lambda = lambda_par)
#' print(paste("Max difference:", max(abs(probs - probs_gkw)))) # Should be near zero
#'
#' # Plot the CDF for different lambda values
#' curve_q <- seq(0.01, 0.99, length.out = 200)
#' curve_p1 <- pekw(curve_q, alpha = 2, beta = 3, lambda = 0.5)
#' curve_p2 <- pekw(curve_q, alpha = 2, beta = 3, lambda = 1.0) # standard Kw
#' curve_p3 <- pekw(curve_q, alpha = 2, beta = 3, lambda = 2.0)
#'
#' plot(curve_q, curve_p2, type = "l", main = "EKw CDF Examples (alpha=2, beta=3)",
#'      xlab = "q", ylab = "F(q)", col = "red", ylim = c(0, 1))
#' lines(curve_q, curve_p1, col = "blue")
#' lines(curve_q, curve_p3, col = "green")
#' legend("bottomright", legend = c("lambda=0.5", "lambda=1.0 (Kw)", "lambda=2.0"),
#'        col = c("blue", "red", "green"), lty = 1, bty = "n")
#' }
#'
#' @export
pekw <- function(q, alpha, beta, lambda, lower_tail = TRUE, log_p = FALSE) {
    .Call(`_gkwreg_pekw`, q, alpha, beta, lambda, lower_tail, log_p)
}

#' @title Quantile Function of the Exponentiated Kumaraswamy (EKw) Distribution
#' @author Lopes, J. E.
#' @keywords distribution quantile
#'
#' @description
#' Computes the quantile function (inverse CDF) for the Exponentiated
#' Kumaraswamy (EKw) distribution with parameters \code{alpha} (\eqn{\alpha}),
#' \code{beta} (\eqn{\beta}), and \code{lambda} (\eqn{\lambda}).
#' It finds the value \code{q} such that \eqn{P(X \le q) = p}. This distribution
#' is a special case of the Generalized Kumaraswamy (GKw) distribution where
#' \eqn{\gamma = 1} and \eqn{\delta = 0}.
#'
#' @param p Vector of probabilities (values between 0 and 1).
#' @param alpha Shape parameter \code{alpha} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param beta Shape parameter \code{beta} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param lambda Shape parameter \code{lambda} > 0 (exponent parameter).
#'   Can be a scalar or a vector. Default: 1.0.
#' @param lower_tail Logical; if \code{TRUE} (default), probabilities are \eqn{p = P(X \le q)},
#'   otherwise, probabilities are \eqn{p = P(X > q)}.
#' @param log_p Logical; if \code{TRUE}, probabilities \code{p} are given as
#'   \eqn{\log(p)}. Default: \code{FALSE}.
#'
#' @return A vector of quantiles corresponding to the given probabilities \code{p}.
#'   The length of the result is determined by the recycling rule applied to
#'   the arguments (\code{p}, \code{alpha}, \code{beta}, \code{lambda}).
#'   Returns:
#'   \itemize{
#'     \item \code{0} for \code{p = 0} (or \code{p = -Inf} if \code{log_p = TRUE},
#'           when \code{lower_tail = TRUE}).
#'     \item \code{1} for \code{p = 1} (or \code{p = 0} if \code{log_p = TRUE},
#'           when \code{lower_tail = TRUE}).
#'     \item \code{NaN} for \code{p < 0} or \code{p > 1} (or corresponding log scale).
#'     \item \code{NaN} for invalid parameters (e.g., \code{alpha <= 0},
#'           \code{beta <= 0}, \code{lambda <= 0}).
#'   }
#'   Boundary return values are adjusted accordingly for \code{lower_tail = FALSE}.
#'
#' @details
#' The quantile function \eqn{Q(p)} is the inverse of the CDF \eqn{F(q)}. The CDF
#' for the EKw (\eqn{\gamma=1, \delta=0}) distribution is \eqn{F(q) = [1 - (1 - q^\alpha)^\beta ]^\lambda}
#' (see \code{\link{pekw}}). Inverting this equation for \eqn{q} yields the
#' quantile function:
#' \deqn{
#' Q(p) = \left\{ 1 - \left[ 1 - p^{1/\lambda} \right]^{1/\beta} \right\}^{1/\alpha}
#' }
#' The function uses this closed-form expression and correctly handles the
#' \code{lower_tail} and \code{log_p} arguments by transforming \code{p}
#' appropriately before applying the formula. This is equivalent to the general
#' GKw quantile function (\code{\link{qgkw}}) evaluated with \eqn{\gamma=1, \delta=0}.
#'
#' @references
#' Nadarajah, S., Cordeiro, G. M., & Ortega, E. M. (2012). The exponentiated
#' Kumaraswamy distribution. *Journal of the Franklin Institute*, *349*(3),
#'
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#'
#' @seealso
#' \code{\link{qgkw}} (parent distribution quantile function),
#' \code{\link{dekw}}, \code{\link{pekw}}, \code{\link{rekw}} (other EKw functions),
#' \code{\link[stats]{qunif}}
#'
#' @examples
#' \donttest{
#' # Example values
#' p_vals <- c(0.1, 0.5, 0.9)
#' alpha_par <- 2.0
#' beta_par <- 3.0
#' lambda_par <- 1.5
#'
#' # Calculate quantiles
#' quantiles <- qekw(p_vals, alpha_par, beta_par, lambda_par)
#' print(quantiles)
#'
#' # Calculate quantiles for upper tail probabilities P(X > q) = p
#' quantiles_upper <- qekw(p_vals, alpha_par, beta_par, lambda_par,
#'                         lower_tail = FALSE)
#' print(quantiles_upper)
#' # Check: qekw(p, ..., lt=F) == qekw(1-p, ..., lt=T)
#' print(qekw(1 - p_vals, alpha_par, beta_par, lambda_par))
#'
#' # Calculate quantiles from log probabilities
#' log_p_vals <- log(p_vals)
#' quantiles_logp <- qekw(log_p_vals, alpha_par, beta_par, lambda_par,
#'                        log_p = TRUE)
#' print(quantiles_logp)
#' # Check: should match original quantiles
#' print(quantiles)
#'
#' # Compare with qgkw setting gamma = 1, delta = 0
#' quantiles_gkw <- qgkw(p_vals, alpha = alpha_par, beta = beta_par,
#'                      gamma = 1.0, delta = 0.0, lambda = lambda_par)
#' print(paste("Max difference:", max(abs(quantiles - quantiles_gkw)))) # Should be near zero
#'
#' # Verify inverse relationship with pekw
#' p_check <- 0.75
#' q_calc <- qekw(p_check, alpha_par, beta_par, lambda_par)
#' p_recalc <- pekw(q_calc, alpha_par, beta_par, lambda_par)
#' print(paste("Original p:", p_check, " Recalculated p:", p_recalc))
#' # abs(p_check - p_recalc) < 1e-9 # Should be TRUE
#'
#' # Boundary conditions
#' print(qekw(c(0, 1), alpha_par, beta_par, lambda_par)) # Should be 0, 1
#' print(qekw(c(-Inf, 0), alpha_par, beta_par, lambda_par, log_p = TRUE)) # Should be 0, 1
#' }
#'
#' @export
qekw <- function(p, alpha, beta, lambda, lower_tail = TRUE, log_p = FALSE) {
    .Call(`_gkwreg_qekw`, p, alpha, beta, lambda, lower_tail, log_p)
}

#' @title Random Number Generation for the Exponentiated Kumaraswamy (EKw) Distribution
#' @author Lopes, J. E.
#' @keywords distribution random
#'
#' @description
#' Generates random deviates from the Exponentiated Kumaraswamy (EKw)
#' distribution with parameters \code{alpha} (\eqn{\alpha}), \code{beta}
#' (\eqn{\beta}), and \code{lambda} (\eqn{\lambda}). This distribution is a
#' special case of the Generalized Kumaraswamy (GKw) distribution where
#' \eqn{\gamma = 1} and \eqn{\delta = 0}.
#'
#' @param n Number of observations. If \code{length(n) > 1}, the length is
#'   taken to be the number required. Must be a non-negative integer.
#' @param alpha Shape parameter \code{alpha} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param beta Shape parameter \code{beta} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param lambda Shape parameter \code{lambda} > 0 (exponent parameter).
#'   Can be a scalar or a vector. Default: 1.0.
#'
#' @return A vector of length \code{n} containing random deviates from the EKw
#'   distribution. The length of the result is determined by \code{n} and the
#'   recycling rule applied to the parameters (\code{alpha}, \code{beta},
#'   \code{lambda}). Returns \code{NaN} if parameters
#'   are invalid (e.g., \code{alpha <= 0}, \code{beta <= 0}, \code{lambda <= 0}).
#'
#' @details
#' The generation method uses the inverse transform (quantile) method.
#' That is, if \eqn{U} is a random variable following a standard Uniform
#' distribution on (0, 1), then \eqn{X = Q(U)} follows the EKw distribution,
#' where \eqn{Q(u)} is the EKw quantile function (\code{\link{qekw}}):
#' \deqn{
#' Q(u) = \left\{ 1 - \left[ 1 - u^{1/\lambda} \right]^{1/\beta} \right\}^{1/\alpha}
#' }
#' This is computationally equivalent to the general GKw generation method
#' (\code{\link{rgkw}}) when specialized for \eqn{\gamma=1, \delta=0}, as the
#' required Beta(1, 1) random variate is equivalent to a standard Uniform(0, 1)
#' variate. The implementation generates \eqn{U} using \code{\link[stats]{runif}}
#' and applies the transformation above.
#'
#' @references
#' Nadarajah, S., Cordeiro, G. M., & Ortega, E. M. (2012). The exponentiated
#' Kumaraswamy distribution. *Journal of the Franklin Institute*, *349*(3),
#'
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#'
#' Devroye, L. (1986). *Non-Uniform Random Variate Generation*. Springer-Verlag.
#' (General methods for random variate generation).
#'
#' @seealso
#' \code{\link{rgkw}} (parent distribution random generation),
#' \code{\link{dekw}}, \code{\link{pekw}}, \code{\link{qekw}} (other EKw functions),
#' \code{\link[stats]{runif}}
#'
#' @examples
#' \donttest{
#' set.seed(2027) # for reproducibility
#'
#' # Generate 1000 random values from a specific EKw distribution
#' alpha_par <- 2.0
#' beta_par <- 3.0
#' lambda_par <- 1.5
#'
#' x_sample_ekw <- rekw(1000, alpha = alpha_par, beta = beta_par, lambda = lambda_par)
#' summary(x_sample_ekw)
#'
#' # Histogram of generated values compared to theoretical density
#' hist(x_sample_ekw, breaks = 30, freq = FALSE, # freq=FALSE for density
#'      main = "Histogram of EKw Sample", xlab = "x", ylim = c(0, 3.0))
#' curve(dekw(x, alpha = alpha_par, beta = beta_par, lambda = lambda_par),
#'       add = TRUE, col = "red", lwd = 2, n = 201)
#' legend("topright", legend = "Theoretical PDF", col = "red", lwd = 2, bty = "n")
#'
#' # Comparing empirical and theoretical quantiles (Q-Q plot)
#' prob_points <- seq(0.01, 0.99, by = 0.01)
#' theo_quantiles <- qekw(prob_points, alpha = alpha_par, beta = beta_par,
#'                        lambda = lambda_par)
#' emp_quantiles <- quantile(x_sample_ekw, prob_points, type = 7)
#'
#' plot(theo_quantiles, emp_quantiles, pch = 16, cex = 0.8,
#'      main = "Q-Q Plot for EKw Distribution",
#'      xlab = "Theoretical Quantiles", ylab = "Empirical Quantiles (n=1000)")
#' abline(a = 0, b = 1, col = "blue", lty = 2)
#'
#' # Compare summary stats with rgkw(..., gamma=1, delta=0, ...)
#' # Note: individual values will differ due to randomness
#' x_sample_gkw <- rgkw(1000, alpha = alpha_par, beta = beta_par, gamma = 1.0,
#'                      delta = 0.0, lambda = lambda_par)
#' print("Summary stats for rekw sample:")
#' print(summary(x_sample_ekw))
#' print("Summary stats for rgkw(gamma=1, delta=0) sample:")
#' print(summary(x_sample_gkw)) # Should be similar
#'
#' }
#'
#' @export
rekw <- function(n, alpha, beta, lambda) {
    .Call(`_gkwreg_rekw`, n, alpha, beta, lambda)
}

#' @title Negative Log-Likelihood for the Exponentiated Kumaraswamy (EKw) Distribution
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize
#'
#' @description
#' Computes the negative log-likelihood function for the Exponentiated
#' Kumaraswamy (EKw) distribution with parameters \code{alpha} (\eqn{\alpha}),
#' \code{beta} (\eqn{\beta}), and \code{lambda} (\eqn{\lambda}), given a vector
#' of observations. This distribution is the special case of the Generalized
#' Kumaraswamy (GKw) distribution where \eqn{\gamma = 1} and \eqn{\delta = 0}.
#' This function is suitable for maximum likelihood estimation.
#'
#' @param par A numeric vector of length 3 containing the distribution parameters
#'   in the order: \code{alpha} (\eqn{\alpha > 0}), \code{beta} (\eqn{\beta > 0}),
#'   \code{lambda} (\eqn{\lambda > 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a single \code{double} value representing the negative
#'   log-likelihood (\eqn{-\ell(\theta|\mathbf{x})}). Returns \code{Inf}
#'   if any parameter values in \code{par} are invalid according to their
#'   constraints, or if any value in \code{data} is not in the interval (0, 1).
#'
#' @details
#' The Exponentiated Kumaraswamy (EKw) distribution is the GKw distribution
#' (\code{\link{dekw}}) with \eqn{\gamma=1} and \eqn{\delta=0}. Its probability
#' density function (PDF) is:
#' \deqn{
#' f(x | \theta) = \lambda \alpha \beta x^{\alpha-1} (1 - x^\alpha)^{\beta-1} \bigl[1 - (1 - x^\alpha)^\beta \bigr]^{\lambda - 1}
#' }
#' for \eqn{0 < x < 1} and \eqn{\theta = (\alpha, \beta, \lambda)}.
#' The log-likelihood function \eqn{\ell(\theta | \mathbf{x})} for a sample
#' \eqn{\mathbf{x} = (x_1, \dots, x_n)} is \eqn{\sum_{i=1}^n \ln f(x_i | \theta)}:
#' \deqn{
#' \ell(\theta | \mathbf{x}) = n[\ln(\lambda) + \ln(\alpha) + \ln(\beta)]
#' + \sum_{i=1}^{n} [(\alpha-1)\ln(x_i) + (\beta-1)\ln(v_i) + (\lambda-1)\ln(w_i)]
#' }
#' where:
#' \itemize{
#'   \item \eqn{v_i = 1 - x_i^{\alpha}}
#'   \item \eqn{w_i = 1 - v_i^{\beta} = 1 - (1-x_i^{\alpha})^{\beta}}
#' }
#' This function computes and returns the *negative* log-likelihood, \eqn{-\ell(\theta|\mathbf{x})},
#' suitable for minimization using optimization routines like \code{\link[stats]{optim}}.
#' Numerical stability is maintained similarly to \code{\link{llgkw}}.
#'
#' @references
#' Nadarajah, S., Cordeiro, G. M., & Ortega, E. M. (2012). The exponentiated
#' Kumaraswamy distribution. *Journal of the Franklin Institute*, *349*(3),
#'
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#'
#' @seealso
#' \code{\link{llgkw}} (parent distribution negative log-likelihood),
#' \code{\link{dekw}}, \code{\link{pekw}}, \code{\link{qekw}}, \code{\link{rekw}},
#' \code{grekw} (gradient, if available),
#' \code{hsekw} (Hessian, if available),
#' \code{\link[stats]{optim}}
#'
#' @examples
#' \donttest{
#' # Assuming existence of rekw, grekw, hsekw functions for EKw distribution
#'
#' # Generate sample data from a known EKw distribution
#' set.seed(123)
#' true_par_ekw <- c(alpha = 2, beta = 3, lambda = 0.5)
#' # Use rekw if it exists, otherwise use rgkw with gamma=1, delta=0
#' if (exists("rekw")) {
#'   sample_data_ekw <- rekw(100, alpha = true_par_ekw[1], beta = true_par_ekw[2],
#'                           lambda = true_par_ekw[3])
#' } else {
#'   sample_data_ekw <- rgkw(100, alpha = true_par_ekw[1], beta = true_par_ekw[2],
#'                          gamma = 1, delta = 0, lambda = true_par_ekw[3])
#' }
#' hist(sample_data_ekw, breaks = 20, main = "EKw(2, 3, 0.5) Sample")
#'
#' # --- Maximum Likelihood Estimation using optim ---
#' # Initial parameter guess
#' start_par_ekw <- c(1.5, 2.5, 0.8)
#'
#' # Perform optimization (minimizing negative log-likelihood)
#' # Use method="L-BFGS-B" for box constraints if needed (all params > 0)
#' mle_result_ekw <- stats::optim(par = start_par_ekw,
#'                                fn = llekw, # Use the EKw neg-log-likelihood
#'                                method = "BFGS", # Or "L-BFGS-B" with lower=1e-6
#'                                hessian = TRUE,
#'                                data = sample_data_ekw)
#'
#' # Check convergence and results
#' if (mle_result_ekw$convergence == 0) {
#'   print("Optimization converged successfully.")
#'   mle_par_ekw <- mle_result_ekw$par
#'   print("Estimated EKw parameters:")
#'   print(mle_par_ekw)
#'   print("True EKw parameters:")
#'   print(true_par_ekw)
#' } else {
#'   warning("Optimization did not converge!")
#'   print(mle_result_ekw$message)
#' }
#'
#' # --- Compare numerical and analytical derivatives (if available) ---
#' # Requires 'numDeriv' package and analytical functions 'grekw', 'hsekw'
#' if (mle_result_ekw$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE) &&
#'     exists("grekw") && exists("hsekw")) {
#'
#'   cat("\nComparing Derivatives at EKw MLE estimates:\n")
#'
#'   # Numerical derivatives of llekw
#'   num_grad_ekw <- numDeriv::grad(func = llekw, x = mle_par_ekw, data = sample_data_ekw)
#'   num_hess_ekw <- numDeriv::hessian(func = llekw, x = mle_par_ekw, data = sample_data_ekw)
#'
#'   # Analytical derivatives (assuming they return derivatives of negative LL)
#'   ana_grad_ekw <- grekw(par = mle_par_ekw, data = sample_data_ekw)
#'   ana_hess_ekw <- hsekw(par = mle_par_ekw, data = sample_data_ekw)
#'
#'   # Check differences
#'   cat("Max absolute difference between gradients:\n")
#'   print(max(abs(num_grad_ekw - ana_grad_ekw)))
#'   cat("Max absolute difference between Hessians:\n")
#'   print(max(abs(num_hess_ekw - ana_hess_ekw)))
#'
#' } else {
#'    cat("\nSkipping derivative comparison for EKw.\n")
#'    cat("Requires convergence, 'numDeriv' package and functions 'grekw', 'hsekw'.\n")
#' }
#'
#' }
#'
#' @export
llekw <- function(par, data) {
    .Call(`_gkwreg_llekw`, par, data)
}

#' @title Gradient of the Negative Log-Likelihood for the EKw Distribution
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize gradient
#'
#' @description
#' Computes the gradient vector (vector of first partial derivatives) of the
#' negative log-likelihood function for the Exponentiated Kumaraswamy (EKw)
#' distribution with parameters \code{alpha} (\eqn{\alpha}), \code{beta}
#' (\eqn{\beta}), and \code{lambda} (\eqn{\lambda}). This distribution is the
#' special case of the Generalized Kumaraswamy (GKw) distribution where
#' \eqn{\gamma = 1} and \eqn{\delta = 0}. The gradient is useful for optimization.
#'
#' @param par A numeric vector of length 3 containing the distribution parameters
#'   in the order: \code{alpha} (\eqn{\alpha > 0}), \code{beta} (\eqn{\beta > 0}),
#'   \code{lambda} (\eqn{\lambda > 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a numeric vector of length 3 containing the partial derivatives
#'   of the negative log-likelihood function \eqn{-\ell(\theta | \mathbf{x})} with
#'   respect to each parameter: \eqn{(-\partial \ell/\partial \alpha, -\partial \ell/\partial \beta, -\partial \ell/\partial \lambda)}.
#'   Returns a vector of \code{NaN} if any parameter values are invalid according
#'   to their constraints, or if any value in \code{data} is not in the
#'   interval (0, 1).
#'
#' @details
#' The components of the gradient vector of the negative log-likelihood
#' (\eqn{-\nabla \ell(\theta | \mathbf{x})}) for the EKw (\eqn{\gamma=1, \delta=0})
#' model are:
#'
#' \deqn{
#' -\frac{\partial \ell}{\partial \alpha} = -\frac{n}{\alpha} - \sum_{i=1}^{n}\ln(x_i)
#' + \sum_{i=1}^{n}\left[x_i^{\alpha} \ln(x_i) \left(\frac{\beta-1}{v_i} -
#' \frac{(\lambda-1) \beta v_i^{\beta-1}}{w_i}\right)\right]
#' }
#' \deqn{
#' -\frac{\partial \ell}{\partial \beta} = -\frac{n}{\beta} - \sum_{i=1}^{n}\ln(v_i)
#' + \sum_{i=1}^{n}\left[\frac{(\lambda-1) v_i^{\beta} \ln(v_i)}{w_i}\right]
#' }
#' \deqn{
#' -\frac{\partial \ell}{\partial \lambda} = -\frac{n}{\lambda} - \sum_{i=1}^{n}\ln(w_i)
#' }
#'
#' where:
#' \itemize{
#'   \item \eqn{v_i = 1 - x_i^{\alpha}}
#'   \item \eqn{w_i = 1 - v_i^{\beta} = 1 - (1-x_i^{\alpha})^{\beta}}
#' }
#' These formulas represent the derivatives of \eqn{-\ell(\theta)}, consistent with
#' minimizing the negative log-likelihood. They correspond to the relevant components
#' of the general GKw gradient (\code{\link{grgkw}}) evaluated at \eqn{\gamma=1, \delta=0}.
#'
#' @references
#' Nadarajah, S., Cordeiro, G. M., & Ortega, E. M. (2012). The exponentiated
#' Kumaraswamy distribution. *Journal of the Franklin Institute*, *349*(3),
#'
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#' (Note: Specific gradient formulas might be derived or sourced from additional references).
#'
#' @seealso
#' \code{\link{grgkw}} (parent distribution gradient),
#' \code{\link{llekw}} (negative log-likelihood for EKw),
#' \code{hsekw} (Hessian for EKw, if available),
#' \code{\link{dekw}} (density for EKw),
#' \code{\link[stats]{optim}},
#' \code{\link[numDeriv]{grad}} (for numerical gradient comparison).
#'
#' @examples
#' \donttest{
#' # Assuming existence of rekw, llekw, grekw, hsekw functions for EKw
#'
#' # Generate sample data
#' set.seed(123)
#' true_par_ekw <- c(alpha = 2, beta = 3, lambda = 0.5)
#' if (exists("rekw")) {
#'   sample_data_ekw <- rekw(100, alpha = true_par_ekw[1], beta = true_par_ekw[2],
#'                           lambda = true_par_ekw[3])
#' } else {
#'   sample_data_ekw <- rgkw(100, alpha = true_par_ekw[1], beta = true_par_ekw[2],
#'                           gamma = 1, delta = 0, lambda = true_par_ekw[3])
#' }
#' hist(sample_data_ekw, breaks = 20, main = "EKw(2, 3, 0.5) Sample")
#'
#' # --- Find MLE estimates ---
#' start_par_ekw <- c(1.5, 2.5, 0.8)
#' mle_result_ekw <- stats::optim(par = start_par_ekw,
#'                                fn = llekw,
#'                                gr = grekw, # Use analytical gradient for EKw
#'                                method = "BFGS",
#'                                hessian = TRUE,
#'                                data = sample_data_ekw)
#'
#' # --- Compare analytical gradient to numerical gradient ---
#' if (mle_result_ekw$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE)) {
#'
#'   mle_par_ekw <- mle_result_ekw$par
#'   cat("\nComparing Gradients for EKw at MLE estimates:\n")
#'
#'   # Numerical gradient of llekw
#'   num_grad_ekw <- numDeriv::grad(func = llekw, x = mle_par_ekw, data = sample_data_ekw)
#'
#'   # Analytical gradient from grekw
#'   ana_grad_ekw <- grekw(par = mle_par_ekw, data = sample_data_ekw)
#'
#'   cat("Numerical Gradient (EKw):\n")
#'   print(num_grad_ekw)
#'   cat("Analytical Gradient (EKw):\n")
#'   print(ana_grad_ekw)
#'
#'   # Check differences
#'   cat("Max absolute difference between EKw gradients:\n")
#'   print(max(abs(num_grad_ekw - ana_grad_ekw)))
#'
#' } else {
#'   cat("\nSkipping EKw gradient comparison.\n")
#' }
#'
#' # Example with Hessian comparison (if hsekw exists)
#' if (mle_result_ekw$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE) && exists("hsekw")) {
#'
#'   num_hess_ekw <- numDeriv::hessian(func = llekw, x = mle_par_ekw, data = sample_data_ekw)
#'   ana_hess_ekw <- hsekw(par = mle_par_ekw, data = sample_data_ekw)
#'   cat("\nMax absolute difference between EKw Hessians:\n")
#'   print(max(abs(num_hess_ekw - ana_hess_ekw)))
#'
#' }
#'
#' }
#'
#' @export
grekw <- function(par, data) {
    .Call(`_gkwreg_grekw`, par, data)
}

#' @title Hessian Matrix of the Negative Log-Likelihood for the EKw Distribution
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize hessian
#'
#' @description
#' Computes the analytic 3x3 Hessian matrix (matrix of second partial derivatives)
#' of the negative log-likelihood function for the Exponentiated Kumaraswamy (EKw)
#' distribution with parameters \code{alpha} (\eqn{\alpha}), \code{beta}
#' (\eqn{\beta}), and \code{lambda} (\eqn{\lambda}). This distribution is the
#' special case of the Generalized Kumaraswamy (GKw) distribution where
#' \eqn{\gamma = 1} and \eqn{\delta = 0}. The Hessian is useful for estimating
#' standard errors and in optimization algorithms.
#'
#' @param par A numeric vector of length 3 containing the distribution parameters
#'   in the order: \code{alpha} (\eqn{\alpha > 0}), \code{beta} (\eqn{\beta > 0}),
#'   \code{lambda} (\eqn{\lambda > 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a 3x3 numeric matrix representing the Hessian matrix of the
#'   negative log-likelihood function, \eqn{-\partial^2 \ell / (\partial \theta_i \partial \theta_j)},
#'   where \eqn{\theta = (\alpha, \beta, \lambda)}.
#'   Returns a 3x3 matrix populated with \code{NaN} if any parameter values are
#'   invalid according to their constraints, or if any value in \code{data} is
#'   not in the interval (0, 1).
#'
#' @details
#' This function calculates the analytic second partial derivatives of the
#' negative log-likelihood function based on the EKw log-likelihood
#' (\eqn{\gamma=1, \delta=0} case of GKw, see \code{\link{llekw}}):
#' \deqn{
#' \ell(\theta | \mathbf{x}) = n[\ln(\lambda) + \ln(\alpha) + \ln(\beta)]
#' + \sum_{i=1}^{n} [(\alpha-1)\ln(x_i) + (\beta-1)\ln(v_i) + (\lambda-1)\ln(w_i)]
#' }
#' where \eqn{\theta = (\alpha, \beta, \lambda)} and intermediate terms are:
#' \itemize{
#'   \item \eqn{v_i = 1 - x_i^{\alpha}}
#'   \item \eqn{w_i = 1 - v_i^{\beta} = 1 - (1-x_i^{\alpha})^{\beta}}
#' }
#' The Hessian matrix returned contains the elements \eqn{- \frac{\partial^2 \ell(\theta | \mathbf{x})}{\partial \theta_i \partial \theta_j}}
#' for \eqn{\theta_i, \theta_j \in \{\alpha, \beta, \lambda\}}.
#'
#' Key properties of the returned matrix:
#' \itemize{
#'   \item Dimensions: 3x3.
#'   \item Symmetry: The matrix is symmetric.
#'   \item Ordering: Rows and columns correspond to the parameters in the order
#'     \eqn{\alpha, \beta, \lambda}.
#'   \item Content: Analytic second derivatives of the *negative* log-likelihood.
#' }
#' This corresponds to the relevant 3x3 submatrix of the 5x5 GKw Hessian (\code{\link{hsgkw}})
#' evaluated at \eqn{\gamma=1, \delta=0}. The exact analytical formulas are implemented directly.
#'
#' @references
#' Nadarajah, S., Cordeiro, G. M., & Ortega, E. M. (2012). The exponentiated
#' Kumaraswamy distribution. *Journal of the Franklin Institute*, *349*(3),
#'
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#' (Note: Specific Hessian formulas might be derived or sourced from additional references).
#'
#' @seealso
#' \code{\link{hsgkw}} (parent distribution Hessian),
#' \code{\link{llekw}} (negative log-likelihood for EKw),
#' \code{grekw} (gradient for EKw, if available),
#' \code{\link{dekw}} (density for EKw),
#' \code{\link[stats]{optim}},
#' \code{\link[numDeriv]{hessian}} (for numerical Hessian comparison).
#'
#' @examples
#' \donttest{
#' # Assuming existence of rekw, llekw, grekw, hsekw functions for EKw
#'
#' # Generate sample data
#' set.seed(123)
#' true_par_ekw <- c(alpha = 2, beta = 3, lambda = 0.5)
#' if (exists("rekw")) {
#'   sample_data_ekw <- rekw(100, alpha = true_par_ekw[1], beta = true_par_ekw[2],
#'                           lambda = true_par_ekw[3])
#' } else {
#'   sample_data_ekw <- rgkw(100, alpha = true_par_ekw[1], beta = true_par_ekw[2],
#'                          gamma = 1, delta = 0, lambda = true_par_ekw[3])
#' }
#' hist(sample_data_ekw, breaks = 20, main = "EKw(2, 3, 0.5) Sample")
#'
#' # --- Find MLE estimates ---
#' start_par_ekw <- c(1.5, 2.5, 0.8)
#' mle_result_ekw <- stats::optim(par = start_par_ekw,
#'                                fn = llekw,
#'                                gr = if (exists("grekw")) grekw else NULL,
#'                                method = "BFGS",
#'                                hessian = TRUE, # Ask optim for numerical Hessian
#'                                data = sample_data_ekw)
#'
#' # --- Compare analytical Hessian to numerical Hessian ---
#' if (mle_result_ekw$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE) &&
#'     exists("hsekw")) {
#'
#'   mle_par_ekw <- mle_result_ekw$par
#'   cat("\nComparing Hessians for EKw at MLE estimates:\n")
#'
#'   # Numerical Hessian of llekw
#'   num_hess_ekw <- numDeriv::hessian(func = llekw, x = mle_par_ekw, data = sample_data_ekw)
#'
#'   # Analytical Hessian from hsekw
#'   ana_hess_ekw <- hsekw(par = mle_par_ekw, data = sample_data_ekw)
#'
#'   cat("Numerical Hessian (EKw):\n")
#'   print(round(num_hess_ekw, 4))
#'   cat("Analytical Hessian (EKw):\n")
#'   print(round(ana_hess_ekw, 4))
#'
#'   # Check differences
#'   cat("Max absolute difference between EKw Hessians:\n")
#'   print(max(abs(num_hess_ekw - ana_hess_ekw)))
#'
#'   # Optional: Use analytical Hessian for Standard Errors
#'   # tryCatch({
#'   #   cov_matrix_ekw <- solve(ana_hess_ekw)
#'   #   std_errors_ekw <- sqrt(diag(cov_matrix_ekw))
#'   #   cat("Std. Errors from Analytical EKw Hessian:\n")
#'   #   print(std_errors_ekw)
#'   # }, error = function(e) {
#'   #   warning("Could not invert analytical EKw Hessian: ", e$message)
#'   # })
#'
#' } else {
#'   cat("\nSkipping EKw Hessian comparison.\n")
#'   cat("Requires convergence, 'numDeriv' package, and function 'hsekw'.\n")
#' }
#'
#' }
#'
#' @export
hsekw <- function(par, data) {
    .Call(`_gkwreg_hsekw`, par, data)
}

#' @title Density of the McDonald (Mc)/Beta Power Distribution Distribution
#' @author Lopes, J. E.
#' @keywords distribution density mcdonald
#'
#' @description
#' Computes the probability density function (PDF) for the McDonald (Mc)
#' distribution (also previously referred to as Beta Power) with parameters
#' \code{gamma} (\eqn{\gamma}), \code{delta} (\eqn{\delta}), and \code{lambda}
#' (\eqn{\lambda}). This distribution is defined on the interval (0, 1).
#'
#' @param x Vector of quantiles (values between 0 and 1).
#' @param gamma Shape parameter \code{gamma} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param delta Shape parameter \code{delta} >= 0. Can be a scalar or a vector.
#'   Default: 0.0.
#' @param lambda Shape parameter \code{lambda} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param log_prob Logical; if \code{TRUE}, the logarithm of the density is
#'   returned (\eqn{\log(f(x))}). Default: \code{FALSE}.
#'
#' @return A vector of density values (\eqn{f(x)}) or log-density values
#'   (\eqn{\log(f(x))}). The length of the result is determined by the recycling
#'   rule applied to the arguments (\code{x}, \code{gamma}, \code{delta},
#'   \code{lambda}). Returns \code{0} (or \code{-Inf} if
#'   \code{log_prob = TRUE}) for \code{x} outside the interval (0, 1), or
#'   \code{NaN} if parameters are invalid (e.g., \code{gamma <= 0},
#'   \code{delta < 0}, \code{lambda <= 0}).
#'
#' @details
#' The probability density function (PDF) of the McDonald (Mc) distribution
#' is given by:
#' \deqn{
#' f(x; \gamma, \delta, \lambda) = \frac{\lambda}{B(\gamma,\delta+1)} x^{\gamma \lambda - 1} (1 - x^\lambda)^\delta
#' }
#' for \eqn{0 < x < 1}, where \eqn{B(a,b)} is the Beta function
#' (\code{\link[base]{beta}}).
#'
#' The Mc distribution is a special case of the five-parameter
#' Generalized Kumaraswamy (GKw) distribution (\code{\link{dgkw}}) obtained
#' by setting the parameters \eqn{\alpha = 1} and \eqn{\beta = 1}.
#' It was introduced by McDonald (1984) and is related to the Generalized Beta
#' distribution of the first kind (GB1). When \eqn{\lambda=1}, it simplifies
#' to the standard Beta distribution with parameters \eqn{\gamma} and
#' \eqn{\delta+1}.
#'
#' @references
#' McDonald, J. B. (1984). Some generalized functions for the size distribution
#' of income. *Econometrica*, 52(3), 647-663.
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#'
#' @seealso
#' \code{\link{dgkw}} (parent distribution density),
#' \code{\link{pmc}}, \code{\link{qmc}}, \code{\link{rmc}} (other Mc functions),
#' \code{\link[stats]{dbeta}}
#'
#' @examples
#' \donttest{
#' # Example values
#' x_vals <- c(0.2, 0.5, 0.8)
#' gamma_par <- 2.0
#' delta_par <- 1.5
#' lambda_par <- 1.0 # Equivalent to Beta(gamma, delta+1)
#'
#' # Calculate density using dmc
#' densities <- dmc(x_vals, gamma_par, delta_par, lambda_par)
#' print(densities)
#' # Compare with Beta density
#' print(stats::dbeta(x_vals, shape1 = gamma_par, shape2 = delta_par + 1))
#'
#' # Calculate log-density
#' log_densities <- dmc(x_vals, gamma_par, delta_par, lambda_par, log_prob = TRUE)
#' print(log_densities)
#'
#' # Compare with dgkw setting alpha = 1, beta = 1
#' densities_gkw <- dgkw(x_vals, alpha = 1.0, beta = 1.0, gamma = gamma_par,
#'                       delta = delta_par, lambda = lambda_par)
#' print(paste("Max difference:", max(abs(densities - densities_gkw)))) # Should be near zero
#'
#' # Plot the density for different lambda values
#' curve_x <- seq(0.01, 0.99, length.out = 200)
#' curve_y1 <- dmc(curve_x, gamma = 2, delta = 3, lambda = 0.5)
#' curve_y2 <- dmc(curve_x, gamma = 2, delta = 3, lambda = 1.0) # Beta(2, 4)
#' curve_y3 <- dmc(curve_x, gamma = 2, delta = 3, lambda = 2.0)
#'
#' plot(curve_x, curve_y2, type = "l", main = "McDonald (Mc) Density (gamma=2, delta=3)",
#'      xlab = "x", ylab = "f(x)", col = "red", ylim = range(0, curve_y1, curve_y2, curve_y3))
#' lines(curve_x, curve_y1, col = "blue")
#' lines(curve_x, curve_y3, col = "green")
#' legend("topright", legend = c("lambda=0.5", "lambda=1.0 (Beta)", "lambda=2.0"),
#'        col = c("blue", "red", "green"), lty = 1, bty = "n")
#' }
#'
#' @export
dmc <- function(x, gamma, delta, lambda, log_prob = FALSE) {
    .Call(`_gkwreg_dmc`, x, gamma, delta, lambda, log_prob)
}

#' @title CDF of the McDonald (Mc)/Beta Power Distribution
#' @author Lopes, J. E.
#' @keywords distribution cumulative mcdonald
#'
#' @description
#' Computes the cumulative distribution function (CDF), \eqn{F(q) = P(X \le q)},
#' for the McDonald (Mc) distribution (also known as Beta Power) with
#' parameters \code{gamma} (\eqn{\gamma}), \code{delta} (\eqn{\delta}), and
#' \code{lambda} (\eqn{\lambda}). This distribution is defined on the interval
#' (0, 1) and is a special case of the Generalized Kumaraswamy (GKw)
#' distribution where \eqn{\alpha = 1} and \eqn{\beta = 1}.
#'
#' @param q Vector of quantiles (values generally between 0 and 1).
#' @param gamma Shape parameter \code{gamma} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param delta Shape parameter \code{delta} >= 0. Can be a scalar or a vector.
#'   Default: 0.0.
#' @param lambda Shape parameter \code{lambda} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param lower_tail Logical; if \code{TRUE} (default), probabilities are
#'   \eqn{P(X \le q)}, otherwise, \eqn{P(X > q)}.
#' @param log_p Logical; if \code{TRUE}, probabilities \eqn{p} are given as
#'   \eqn{\log(p)}. Default: \code{FALSE}.
#'
#' @return A vector of probabilities, \eqn{F(q)}, or their logarithms/complements
#'   depending on \code{lower_tail} and \code{log_p}. The length of the result
#'   is determined by the recycling rule applied to the arguments (\code{q},
#'   \code{gamma}, \code{delta}, \code{lambda}). Returns \code{0} (or \code{-Inf}
#'   if \code{log_p = TRUE}) for \code{q <= 0} and \code{1} (or \code{0} if
#'   \code{log_p = TRUE}) for \code{q >= 1}. Returns \code{NaN} for invalid
#'   parameters.
#'
#' @details
#' The McDonald (Mc) distribution is a special case of the five-parameter
#' Generalized Kumaraswamy (GKw) distribution (\code{\link{pgkw}}) obtained
#' by setting parameters \eqn{\alpha = 1} and \eqn{\beta = 1}.
#'
#' The CDF of the GKw distribution is \eqn{F_{GKw}(q) = I_{y(q)}(\gamma, \delta+1)},
#' where \eqn{y(q) = [1-(1-q^{\alpha})^{\beta}]^{\lambda}} and \eqn{I_x(a,b)}
#' is the regularized incomplete beta function (\code{\link[stats]{pbeta}}).
#' Setting \eqn{\alpha=1} and \eqn{\beta=1} simplifies \eqn{y(q)} to \eqn{q^\lambda},
#' yielding the Mc CDF:
#' \deqn{
#' F(q; \gamma, \delta, \lambda) = I_{q^\lambda}(\gamma, \delta+1)
#' }
#' This is evaluated using the \code{\link[stats]{pbeta}} function as
#' \code{pbeta(q^lambda, shape1 = gamma, shape2 = delta + 1)}.
#'
#' @references
#' McDonald, J. B. (1984). Some generalized functions for the size distribution
#' of income. *Econometrica*, 52(3), 647-663.
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#'
#' @seealso
#' \code{\link{pgkw}} (parent distribution CDF),
#' \code{\link{dmc}}, \code{\link{qmc}}, \code{\link{rmc}} (other Mc functions),
#' \code{\link[stats]{pbeta}}
#'
#' @examples
#' \donttest{
#' # Example values
#' q_vals <- c(0.2, 0.5, 0.8)
#' gamma_par <- 2.0
#' delta_par <- 1.5
#' lambda_par <- 1.0 # Equivalent to Beta(gamma, delta+1)
#'
#' # Calculate CDF P(X <= q) using pmc
#' probs <- pmc(q_vals, gamma_par, delta_par, lambda_par)
#' print(probs)
#' # Compare with Beta CDF
#' print(stats::pbeta(q_vals, shape1 = gamma_par, shape2 = delta_par + 1))
#'
#' # Calculate upper tail P(X > q)
#' probs_upper <- pmc(q_vals, gamma_par, delta_par, lambda_par,
#'                    lower_tail = FALSE)
#' print(probs_upper)
#' # Check: probs + probs_upper should be 1
#' print(probs + probs_upper)
#'
#' # Calculate log CDF
#' log_probs <- pmc(q_vals, gamma_par, delta_par, lambda_par, log_p = TRUE)
#' print(log_probs)
#' # Check: should match log(probs)
#' print(log(probs))
#'
#' # Compare with pgkw setting alpha = 1, beta = 1
#' probs_gkw <- pgkw(q_vals, alpha = 1.0, beta = 1.0, gamma = gamma_par,
#'                   delta = delta_par, lambda = lambda_par)
#' print(paste("Max difference:", max(abs(probs - probs_gkw)))) # Should be near zero
#'
#' # Plot the CDF for different lambda values
#' curve_q <- seq(0.01, 0.99, length.out = 200)
#' curve_p1 <- pmc(curve_q, gamma = 2, delta = 3, lambda = 0.5)
#' curve_p2 <- pmc(curve_q, gamma = 2, delta = 3, lambda = 1.0) # Beta(2, 4)
#' curve_p3 <- pmc(curve_q, gamma = 2, delta = 3, lambda = 2.0)
#'
#' plot(curve_q, curve_p2, type = "l", main = "Mc/Beta Power CDF (gamma=2, delta=3)",
#'      xlab = "q", ylab = "F(q)", col = "red", ylim = c(0, 1))
#' lines(curve_q, curve_p1, col = "blue")
#' lines(curve_q, curve_p3, col = "green")
#' legend("bottomright", legend = c("lambda=0.5", "lambda=1.0 (Beta)", "lambda=2.0"),
#'        col = c("blue", "red", "green"), lty = 1, bty = "n")
#' }
#'
#' @export
pmc <- function(q, gamma, delta, lambda, lower_tail = TRUE, log_p = FALSE) {
    .Call(`_gkwreg_pmc`, q, gamma, delta, lambda, lower_tail, log_p)
}

#' @title Quantile Function of the McDonald (Mc)/Beta Power Distribution
#' @author Lopes, J. E.
#' @keywords distribution quantile mcdonald
#'
#' @description
#' Computes the quantile function (inverse CDF) for the McDonald (Mc) distribution
#' (also known as Beta Power) with parameters \code{gamma} (\eqn{\gamma}),
#' \code{delta} (\eqn{\delta}), and \code{lambda} (\eqn{\lambda}). It finds the
#' value \code{q} such that \eqn{P(X \le q) = p}. This distribution is a special
#' case of the Generalized Kumaraswamy (GKw) distribution where \eqn{\alpha = 1}
#' and \eqn{\beta = 1}.
#'
#' @param p Vector of probabilities (values between 0 and 1).
#' @param gamma Shape parameter \code{gamma} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param delta Shape parameter \code{delta} >= 0. Can be a scalar or a vector.
#'   Default: 0.0.
#' @param lambda Shape parameter \code{lambda} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param lower_tail Logical; if \code{TRUE} (default), probabilities are \eqn{p = P(X \le q)},
#'   otherwise, probabilities are \eqn{p = P(X > q)}.
#' @param log_p Logical; if \code{TRUE}, probabilities \code{p} are given as
#'   \eqn{\log(p)}. Default: \code{FALSE}.
#'
#' @return A vector of quantiles corresponding to the given probabilities \code{p}.
#'   The length of the result is determined by the recycling rule applied to
#'   the arguments (\code{p}, \code{gamma}, \code{delta}, \code{lambda}).
#'   Returns:
#'   \itemize{
#'     \item \code{0} for \code{p = 0} (or \code{p = -Inf} if \code{log_p = TRUE},
#'           when \code{lower_tail = TRUE}).
#'     \item \code{1} for \code{p = 1} (or \code{p = 0} if \code{log_p = TRUE},
#'           when \code{lower_tail = TRUE}).
#'     \item \code{NaN} for \code{p < 0} or \code{p > 1} (or corresponding log scale).
#'     \item \code{NaN} for invalid parameters (e.g., \code{gamma <= 0},
#'           \code{delta < 0}, \code{lambda <= 0}).
#'   }
#'   Boundary return values are adjusted accordingly for \code{lower_tail = FALSE}.
#'
#' @details
#' The quantile function \eqn{Q(p)} is the inverse of the CDF \eqn{F(q)}. The CDF
#' for the Mc (\eqn{\alpha=1, \beta=1}) distribution is \eqn{F(q) = I_{q^\lambda}(\gamma, \delta+1)},
#' where \eqn{I_z(a,b)} is the regularized incomplete beta function (see \code{\link{pmc}}).
#'
#' To find the quantile \eqn{q}, we first invert the Beta function part: let
#' \eqn{y = I^{-1}_{p}(\gamma, \delta+1)}, where \eqn{I^{-1}_p(a,b)} is the
#' inverse computed via \code{\link[stats]{qbeta}}. We then solve \eqn{q^\lambda = y}
#' for \eqn{q}, yielding the quantile function:
#' \deqn{
#' Q(p) = \left[ I^{-1}_{p}(\gamma, \delta+1) \right]^{1/\lambda}
#' }
#' The function uses this formula, calculating \eqn{I^{-1}_{p}(\gamma, \delta+1)}
#' via \code{qbeta(p, gamma, delta + 1, ...)} while respecting the
#' \code{lower_tail} and \code{log_p} arguments. This is equivalent to the general
#' GKw quantile function (\code{\link{qgkw}}) evaluated with \eqn{\alpha=1, \beta=1}.
#'
#' @references
#' McDonald, J. B. (1984). Some generalized functions for the size distribution
#' of income. *Econometrica*, 52(3), 647-663.
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#'
#' @seealso
#' \code{\link{qgkw}} (parent distribution quantile function),
#' \code{\link{dmc}}, \code{\link{pmc}}, \code{\link{rmc}} (other Mc functions),
#' \code{\link[stats]{qbeta}}
#'
#' @examples
#' \donttest{
#' # Example values
#' p_vals <- c(0.1, 0.5, 0.9)
#' gamma_par <- 2.0
#' delta_par <- 1.5
#' lambda_par <- 1.0 # Equivalent to Beta(gamma, delta+1)
#'
#' # Calculate quantiles using qmc
#' quantiles <- qmc(p_vals, gamma_par, delta_par, lambda_par)
#' print(quantiles)
#' # Compare with Beta quantiles
#' print(stats::qbeta(p_vals, shape1 = gamma_par, shape2 = delta_par + 1))
#'
#' # Calculate quantiles for upper tail probabilities P(X > q) = p
#' quantiles_upper <- qmc(p_vals, gamma_par, delta_par, lambda_par,
#'                        lower_tail = FALSE)
#' print(quantiles_upper)
#' # Check: qmc(p, ..., lt=F) == qmc(1-p, ..., lt=T)
#' print(qmc(1 - p_vals, gamma_par, delta_par, lambda_par))
#'
#' # Calculate quantiles from log probabilities
#' log_p_vals <- log(p_vals)
#' quantiles_logp <- qmc(log_p_vals, gamma_par, delta_par, lambda_par, log_p = TRUE)
#' print(quantiles_logp)
#' # Check: should match original quantiles
#' print(quantiles)
#'
#' # Compare with qgkw setting alpha = 1, beta = 1
#' quantiles_gkw <- qgkw(p_vals, alpha = 1.0, beta = 1.0, gamma = gamma_par,
#'                       delta = delta_par, lambda = lambda_par)
#' print(paste("Max difference:", max(abs(quantiles - quantiles_gkw)))) # Should be near zero
#'
#' # Verify inverse relationship with pmc
#' p_check <- 0.75
#' q_calc <- qmc(p_check, gamma_par, delta_par, lambda_par) # Use lambda != 1
#' p_recalc <- pmc(q_calc, gamma_par, delta_par, lambda_par)
#' print(paste("Original p:", p_check, " Recalculated p:", p_recalc))
#' # abs(p_check - p_recalc) < 1e-9 # Should be TRUE
#'
#' # Boundary conditions
#' print(qmc(c(0, 1), gamma_par, delta_par, lambda_par)) # Should be 0, 1
#' print(qmc(c(-Inf, 0), gamma_par, delta_par, lambda_par, log_p = TRUE)) # Should be 0, 1
#'
#' }
#'
#' @export
qmc <- function(p, gamma, delta, lambda, lower_tail = TRUE, log_p = FALSE) {
    .Call(`_gkwreg_qmc`, p, gamma, delta, lambda, lower_tail, log_p)
}

#' @title Random Number Generation for the McDonald (Mc)/Beta Power Distribution
#' @author Lopes, J. E.
#' @keywords distribution random mcdonald
#'
#' @description
#' Generates random deviates from the McDonald (Mc) distribution (also known as
#' Beta Power) with parameters \code{gamma} (\eqn{\gamma}), \code{delta}
#' (\eqn{\delta}), and \code{lambda} (\eqn{\lambda}). This distribution is a
#' special case of the Generalized Kumaraswamy (GKw) distribution where
#' \eqn{\alpha = 1} and \eqn{\beta = 1}.
#'
#' @param n Number of observations. If \code{length(n) > 1}, the length is
#'   taken to be the number required. Must be a non-negative integer.
#' @param gamma Shape parameter \code{gamma} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param delta Shape parameter \code{delta} >= 0. Can be a scalar or a vector.
#'   Default: 0.0.
#' @param lambda Shape parameter \code{lambda} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#'
#' @return A vector of length \code{n} containing random deviates from the Mc
#'   distribution, with values in (0, 1). The length of the result is determined
#'   by \code{n} and the recycling rule applied to the parameters (\code{gamma},
#'   \code{delta}, \code{lambda}). Returns \code{NaN} if parameters
#'   are invalid (e.g., \code{gamma <= 0}, \code{delta < 0}, \code{lambda <= 0}).
#'
#' @details
#' The generation method uses the relationship between the GKw distribution and the
#' Beta distribution. The general procedure for GKw (\code{\link{rgkw}}) is:
#' If \eqn{W \sim \mathrm{Beta}(\gamma, \delta+1)}, then
#' \eqn{X = \{1 - [1 - W^{1/\lambda}]^{1/\beta}\}^{1/\alpha}} follows the
#' GKw(\eqn{\alpha, \beta, \gamma, \delta, \lambda}) distribution.
#'
#' For the Mc distribution, \eqn{\alpha=1} and \eqn{\beta=1}. Therefore, the
#' algorithm simplifies significantly:
#' \enumerate{
#'   \item Generate \eqn{U \sim \mathrm{Beta}(\gamma, \delta+1)} using
#'         \code{\link[stats]{rbeta}}.
#'   \item Compute the Mc variate \eqn{X = U^{1/\lambda}}.
#' }
#' This procedure is implemented efficiently, handling parameter recycling as needed.
#'
#' @references
#' McDonald, J. B. (1984). Some generalized functions for the size distribution
#' of income. *Econometrica*, 52(3), 647-663.
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#'
#' Devroye, L. (1986). *Non-Uniform Random Variate Generation*. Springer-Verlag.
#' (General methods for random variate generation).
#'
#' @seealso
#' \code{\link{rgkw}} (parent distribution random generation),
#' \code{\link{dmc}}, \code{\link{pmc}}, \code{\link{qmc}} (other Mc functions),
#' \code{\link[stats]{rbeta}}
#'
#' @examples
#' \donttest{
#' set.seed(2028) # for reproducibility
#'
#' # Generate 1000 random values from a specific Mc distribution
#' gamma_par <- 2.0
#' delta_par <- 1.5
#' lambda_par <- 1.0 # Equivalent to Beta(gamma, delta+1)
#'
#' x_sample_mc <- rmc(1000, gamma = gamma_par, delta = delta_par,
#'                    lambda = lambda_par)
#' summary(x_sample_mc)
#'
#' # Histogram of generated values compared to theoretical density
#' hist(x_sample_mc, breaks = 30, freq = FALSE, # freq=FALSE for density
#'      main = "Histogram of Mc Sample (Beta Case)", xlab = "x")
#' curve(dmc(x, gamma = gamma_par, delta = delta_par, lambda = lambda_par),
#'       add = TRUE, col = "red", lwd = 2, n = 201)
#' curve(stats::dbeta(x, gamma_par, delta_par + 1), add=TRUE, col="blue", lty=2)
#' legend("topright", legend = c("Theoretical Mc PDF", "Theoretical Beta PDF"),
#'        col = c("red", "blue"), lwd = c(2,1), lty=c(1,2), bty = "n")
#'
#' # Comparing empirical and theoretical quantiles (Q-Q plot)
#' lambda_par_qq <- 0.7 # Use lambda != 1 for non-Beta case
#' x_sample_mc_qq <- rmc(1000, gamma = gamma_par, delta = delta_par,
#'                       lambda = lambda_par_qq)
#' prob_points <- seq(0.01, 0.99, by = 0.01)
#' theo_quantiles <- qmc(prob_points, gamma = gamma_par, delta = delta_par,
#'                       lambda = lambda_par_qq)
#' emp_quantiles <- quantile(x_sample_mc_qq, prob_points, type = 7)
#'
#' plot(theo_quantiles, emp_quantiles, pch = 16, cex = 0.8,
#'      main = "Q-Q Plot for Mc Distribution",
#'      xlab = "Theoretical Quantiles", ylab = "Empirical Quantiles (n=1000)")
#' abline(a = 0, b = 1, col = "blue", lty = 2)
#'
#' # Compare summary stats with rgkw(..., alpha=1, beta=1, ...)
#' # Note: individual values will differ due to randomness
#' x_sample_gkw <- rgkw(1000, alpha = 1.0, beta = 1.0, gamma = gamma_par,
#'                      delta = delta_par, lambda = lambda_par_qq)
#' print("Summary stats for rmc sample:")
#' print(summary(x_sample_mc_qq))
#' print("Summary stats for rgkw(alpha=1, beta=1) sample:")
#' print(summary(x_sample_gkw)) # Should be similar
#'
#' }
#'
#' @export
rmc <- function(n, gamma, delta, lambda) {
    .Call(`_gkwreg_rmc`, n, gamma, delta, lambda)
}

#' @title Negative Log-Likelihood for the McDonald (Mc)/Beta Power Distribution
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize mcdonald
#'
#' @description
#' Computes the negative log-likelihood function for the McDonald (Mc)
#' distribution (also known as Beta Power) with parameters \code{gamma}
#' (\eqn{\gamma}), \code{delta} (\eqn{\delta}), and \code{lambda} (\eqn{\lambda}),
#' given a vector of observations. This distribution is the special case of the
#' Generalized Kumaraswamy (GKw) distribution where \eqn{\alpha = 1} and
#' \eqn{\beta = 1}. This function is suitable for maximum likelihood estimation.
#'
#' @param par A numeric vector of length 3 containing the distribution parameters
#'   in the order: \code{gamma} (\eqn{\gamma > 0}), \code{delta} (\eqn{\delta \ge 0}),
#'   \code{lambda} (\eqn{\lambda > 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a single \code{double} value representing the negative
#'   log-likelihood (\eqn{-\ell(\theta|\mathbf{x})}). Returns \code{Inf}
#'   if any parameter values in \code{par} are invalid according to their
#'   constraints, or if any value in \code{data} is not in the interval (0, 1).
#'
#' @details
#' The McDonald (Mc) distribution is the GKw distribution (\code{\link{dmc}})
#' with \eqn{\alpha=1} and \eqn{\beta=1}. Its probability density function (PDF) is:
#' \deqn{
#' f(x | \theta) = \frac{\lambda}{B(\gamma,\delta+1)} x^{\gamma \lambda - 1} (1 - x^\lambda)^\delta
#' }
#' for \eqn{0 < x < 1}, \eqn{\theta = (\gamma, \delta, \lambda)}, and \eqn{B(a,b)}
#' is the Beta function (\code{\link[base]{beta}}).
#' The log-likelihood function \eqn{\ell(\theta | \mathbf{x})} for a sample
#' \eqn{\mathbf{x} = (x_1, \dots, x_n)} is \eqn{\sum_{i=1}^n \ln f(x_i | \theta)}:
#' \deqn{
#' \ell(\theta | \mathbf{x}) = n[\ln(\lambda) - \ln B(\gamma, \delta+1)]
#' + \sum_{i=1}^{n} [(\gamma\lambda - 1)\ln(x_i) + \delta\ln(1 - x_i^\lambda)]
#' }
#' This function computes and returns the *negative* log-likelihood, \eqn{-\ell(\theta|\mathbf{x})},
#' suitable for minimization using optimization routines like \code{\link[stats]{optim}}.
#' Numerical stability is maintained, including using the log-gamma function
#' (\code{\link[base]{lgamma}}) for the Beta function term.
#'
#' @references
#' McDonald, J. B. (1984). Some generalized functions for the size distribution
#' of income. *Econometrica*, 52(3), 647-663.
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#'
#' @seealso
#' \code{\link{llgkw}} (parent distribution negative log-likelihood),
#' \code{\link{dmc}}, \code{\link{pmc}}, \code{\link{qmc}}, \code{\link{rmc}},
#' \code{grmc} (gradient, if available),
#' \code{hsmc} (Hessian, if available),
#' \code{\link[stats]{optim}}, \code{\link[base]{lbeta}}
#'
#' @examples
#' \donttest{
#' # Assuming existence of rmc, grmc, hsmc functions for Mc distribution
#'
#' # Generate sample data from a known Mc distribution
#' set.seed(123)
#' true_par_mc <- c(gamma = 2, delta = 3, lambda = 0.5)
#' # Use rmc for data generation
#' sample_data_mc <- rmc(100, gamma = true_par_mc[1], delta = true_par_mc[2],
#'                       lambda = true_par_mc[3])
#' hist(sample_data_mc, breaks = 20, main = "Mc(2, 3, 0.5) Sample")
#'
#' # --- Maximum Likelihood Estimation using optim ---
#' # Initial parameter guess
#' start_par_mc <- c(1.5, 2.5, 0.8)
#'
#' # Perform optimization (minimizing negative log-likelihood)
#' mle_result_mc <- stats::optim(par = start_par_mc,
#'                               fn = llmc, # Use the Mc neg-log-likelihood
#'                               method = "BFGS", # Or "L-BFGS-B" with lower=1e-6
#'                               hessian = TRUE,
#'                               data = sample_data_mc)
#'
#' # Check convergence and results
#' if (mle_result_mc$convergence == 0) {
#'   print("Optimization converged successfully.")
#'   mle_par_mc <- mle_result_mc$par
#'   print("Estimated Mc parameters:")
#'   print(mle_par_mc)
#'   print("True Mc parameters:")
#'   print(true_par_mc)
#' } else {
#'   warning("Optimization did not converge!")
#'   print(mle_result_mc$message)
#' }
#'
#' # --- Compare numerical and analytical derivatives (if available) ---
#' # Requires 'numDeriv' package and analytical functions 'grmc', 'hsmc'
#' if (mle_result_mc$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE) &&
#'     exists("grmc") && exists("hsmc")) {
#'
#'   cat("\nComparing Derivatives at Mc MLE estimates:\n")
#'
#'   # Numerical derivatives of llmc
#'   num_grad_mc <- numDeriv::grad(func = llmc, x = mle_par_mc, data = sample_data_mc)
#'   num_hess_mc <- numDeriv::hessian(func = llmc, x = mle_par_mc, data = sample_data_mc)
#'
#'   # Analytical derivatives (assuming they return derivatives of negative LL)
#'   ana_grad_mc <- grmc(par = mle_par_mc, data = sample_data_mc)
#'   ana_hess_mc <- hsmc(par = mle_par_mc, data = sample_data_mc)
#'
#'   # Check differences
#'   cat("Max absolute difference between gradients:\n")
#'   print(max(abs(num_grad_mc - ana_grad_mc)))
#'   cat("Max absolute difference between Hessians:\n")
#'   print(max(abs(num_hess_mc - ana_hess_mc)))
#'
#' } else {
#'    cat("\nSkipping derivative comparison for Mc.\n")
#'    cat("Requires convergence, 'numDeriv' package and functions 'grmc', 'hsmc'.\n")
#' }
#'
#' }
#'
#' @export
llmc <- function(par, data) {
    .Call(`_gkwreg_llmc`, par, data)
}

#' @title Gradient of the Negative Log-Likelihood for the McDonald (Mc)/Beta Power Distribution
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize gradient mcdonald
#'
#' @description
#' Computes the gradient vector (vector of first partial derivatives) of the
#' negative log-likelihood function for the McDonald (Mc) distribution (also
#' known as Beta Power) with parameters \code{gamma} (\eqn{\gamma}), \code{delta}
#' (\eqn{\delta}), and \code{lambda} (\eqn{\lambda}). This distribution is the
#' special case of the Generalized Kumaraswamy (GKw) distribution where
#' \eqn{\alpha = 1} and \eqn{\beta = 1}. The gradient is useful for optimization.
#'
#' @param par A numeric vector of length 3 containing the distribution parameters
#'   in the order: \code{gamma} (\eqn{\gamma > 0}), \code{delta} (\eqn{\delta \ge 0}),
#'   \code{lambda} (\eqn{\lambda > 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a numeric vector of length 3 containing the partial derivatives
#'   of the negative log-likelihood function \eqn{-\ell(\theta | \mathbf{x})} with
#'   respect to each parameter:
#'   \eqn{(-\partial \ell/\partial \gamma, -\partial \ell/\partial \delta, -\partial \ell/\partial \lambda)}.
#'   Returns a vector of \code{NaN} if any parameter values are invalid according
#'   to their constraints, or if any value in \code{data} is not in the
#'   interval (0, 1).
#'
#' @details
#' The components of the gradient vector of the negative log-likelihood
#' (\eqn{-\nabla \ell(\theta | \mathbf{x})}) for the Mc (\eqn{\alpha=1, \beta=1})
#' model are:
#'
#' \deqn{
#' -\frac{\partial \ell}{\partial \gamma} = n[\psi(\gamma+\delta+1) - \psi(\gamma)] -
#' \lambda\sum_{i=1}^{n}\ln(x_i)
#' }
#' \deqn{
#' -\frac{\partial \ell}{\partial \delta} = n[\psi(\gamma+\delta+1) - \psi(\delta+1)] -
#' \sum_{i=1}^{n}\ln(1-x_i^{\lambda})
#' }
#' \deqn{
#' -\frac{\partial \ell}{\partial \lambda} = -\frac{n}{\lambda} - \gamma\sum_{i=1}^{n}\ln(x_i) +
#' \delta\sum_{i=1}^{n}\frac{x_i^{\lambda}\ln(x_i)}{1-x_i^{\lambda}}
#' }
#'
#' where \eqn{\psi(\cdot)} is the digamma function (\code{\link[base]{digamma}}).
#' These formulas represent the derivatives of \eqn{-\ell(\theta)}, consistent with
#' minimizing the negative log-likelihood. They correspond to the relevant components
#' of the general GKw gradient (\code{\link{grgkw}}) evaluated at \eqn{\alpha=1, \beta=1}.
#'
#' @references
#' McDonald, J. B. (1984). Some generalized functions for the size distribution
#' of income. *Econometrica*, 52(3), 647-663.
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#' (Note: Specific gradient formulas might be derived or sourced from additional references).
#'
#' @seealso
#' \code{\link{grgkw}} (parent distribution gradient),
#' \code{\link{llmc}} (negative log-likelihood for Mc),
#' \code{hsmc} (Hessian for Mc, if available),
#' \code{\link{dmc}} (density for Mc),
#' \code{\link[stats]{optim}},
#' \code{\link[numDeriv]{grad}} (for numerical gradient comparison),
#' \code{\link[base]{digamma}}.
#'
#' @examples
#' \donttest{
#' # Assuming existence of rmc, llmc, grmc, hsmc functions for Mc distribution
#'
#' # Generate sample data
#' set.seed(123)
#' true_par_mc <- c(gamma = 2, delta = 3, lambda = 0.5)
#' sample_data_mc <- rmc(100, gamma = true_par_mc[1], delta = true_par_mc[2],
#'                       lambda = true_par_mc[3])
#' hist(sample_data_mc, breaks = 20, main = "Mc(2, 3, 0.5) Sample")
#'
#' # --- Find MLE estimates ---
#' start_par_mc <- c(1.5, 2.5, 0.8)
#' mle_result_mc <- stats::optim(par = start_par_mc,
#'                               fn = llmc,
#'                               gr = grmc, # Use analytical gradient for Mc
#'                               method = "BFGS",
#'                               hessian = TRUE,
#'                               data = sample_data_mc)
#'
#' # --- Compare analytical gradient to numerical gradient ---
#' if (mle_result_mc$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE)) {
#'
#'   mle_par_mc <- mle_result_mc$par
#'   cat("\nComparing Gradients for Mc at MLE estimates:\n")
#'
#'   # Numerical gradient of llmc
#'   num_grad_mc <- numDeriv::grad(func = llmc, x = mle_par_mc, data = sample_data_mc)
#'
#'   # Analytical gradient from grmc
#'   ana_grad_mc <- grmc(par = mle_par_mc, data = sample_data_mc)
#'
#'   cat("Numerical Gradient (Mc):\n")
#'   print(num_grad_mc)
#'   cat("Analytical Gradient (Mc):\n")
#'   print(ana_grad_mc)
#'
#'   # Check differences
#'   cat("Max absolute difference between Mc gradients:\n")
#'   print(max(abs(num_grad_mc - ana_grad_mc)))
#'
#' } else {
#'   cat("\nSkipping Mc gradient comparison.\n")
#' }
#'
#' # Example with Hessian comparison (if hsmc exists)
#' if (mle_result_mc$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE) && exists("hsmc")) {
#'
#'   num_hess_mc <- numDeriv::hessian(func = llmc, x = mle_par_mc, data = sample_data_mc)
#'   ana_hess_mc <- hsmc(par = mle_par_mc, data = sample_data_mc)
#'   cat("\nMax absolute difference between Mc Hessians:\n")
#'   print(max(abs(num_hess_mc - ana_hess_mc)))
#'
#' }
#'
#' }
#'
#' @export
grmc <- function(par, data) {
    .Call(`_gkwreg_grmc`, par, data)
}

#' @title Hessian Matrix of the Negative Log-Likelihood for the McDonald (Mc)/Beta Power Distribution
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize hessian mcdonald
#'
#' @description
#' Computes the analytic 3x3 Hessian matrix (matrix of second partial derivatives)
#' of the negative log-likelihood function for the McDonald (Mc) distribution
#' (also known as Beta Power) with parameters \code{gamma} (\eqn{\gamma}),
#' \code{delta} (\eqn{\delta}), and \code{lambda} (\eqn{\lambda}). This distribution
#' is the special case of the Generalized Kumaraswamy (GKw) distribution where
#' \eqn{\alpha = 1} and \eqn{\beta = 1}. The Hessian is useful for estimating
#' standard errors and in optimization algorithms.
#'
#' @param par A numeric vector of length 3 containing the distribution parameters
#'   in the order: \code{gamma} (\eqn{\gamma > 0}), \code{delta} (\eqn{\delta \ge 0}),
#'   \code{lambda} (\eqn{\lambda > 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a 3x3 numeric matrix representing the Hessian matrix of the
#'   negative log-likelihood function, \eqn{-\partial^2 \ell / (\partial \theta_i \partial \theta_j)},
#'   where \eqn{\theta = (\gamma, \delta, \lambda)}.
#'   Returns a 3x3 matrix populated with \code{NaN} if any parameter values are
#'   invalid according to their constraints, or if any value in \code{data} is
#'   not in the interval (0, 1).
#'
#' @details
#' This function calculates the analytic second partial derivatives of the
#' negative log-likelihood function (\eqn{-\ell(\theta|\mathbf{x})}).
#' The components are based on the second derivatives of the log-likelihood \eqn{\ell}
#' (derived from the PDF in \code{\link{dmc}}).
#'
#' **Note:** The formulas below represent the second derivatives of the positive
#' log-likelihood (\eqn{\ell}). The function returns the **negative** of these values.
#' Users should verify these formulas independently if using for critical applications.
#'
#' \deqn{
#' \frac{\partial^2 \ell}{\partial \gamma^2} = -n[\psi'(\gamma) - \psi'(\gamma+\delta+1)]
#' }
#' \deqn{
#' \frac{\partial^2 \ell}{\partial \gamma \partial \delta} = -n\psi'(\gamma+\delta+1)
#' }
#' \deqn{
#' \frac{\partial^2 \ell}{\partial \gamma \partial \lambda} = \sum_{i=1}^{n}\ln(x_i)
#' }
#' \deqn{
#' \frac{\partial^2 \ell}{\partial \delta^2} = -n[\psi'(\delta+1) - \psi'(\gamma+\delta+1)]
#' }
#' \deqn{
#' \frac{\partial^2 \ell}{\partial \delta \partial \lambda} = -\sum_{i=1}^{n}\frac{x_i^{\lambda}\ln(x_i)}{1-x_i^{\lambda}}
#' }
#' \deqn{
#' \frac{\partial^2 \ell}{\partial \lambda^2} = -\frac{n}{\lambda^2} -
#' \delta\sum_{i=1}^{n}\frac{x_i^{\lambda}[\ln(x_i)]^2}{(1-x_i^{\lambda})^2}
#' }
#'
#' where \eqn{\psi'(\cdot)} is the trigamma function (\code{\link[base]{trigamma}}).
#' (*Note: The formula for \eqn{\partial^2 \ell / \partial \lambda^2} provided in the source
#' comment was different and potentially related to the expected information matrix;
#' the formula shown here is derived from the gradient provided earlier. Verification
#' is recommended.*)
#'
#' The returned matrix is symmetric, with rows/columns corresponding to
#' \eqn{\gamma, \delta, \lambda}.
#'
#' @references
#' McDonald, J. B. (1984). Some generalized functions for the size distribution
#' of income. *Econometrica*, 52(3), 647-663.
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#' (Note: Specific Hessian formulas might be derived or sourced from additional references).
#'
#' @seealso
#' \code{\link{hsgkw}} (parent distribution Hessian),
#' \code{\link{llmc}} (negative log-likelihood for Mc),
#' \code{\link{grmc}} (gradient for Mc, if available),
#' \code{\link{dmc}} (density for Mc),
#' \code{\link[stats]{optim}},
#' \code{\link[numDeriv]{hessian}} (for numerical Hessian comparison),
#' \code{\link[base]{trigamma}}.
#'
#' @examples
#' \donttest{
#' # Assuming existence of rmc, llmc, grmc, hsmc functions for Mc distribution
#'
#' # Generate sample data
#' set.seed(123)
#' true_par_mc <- c(gamma = 2, delta = 3, lambda = 0.5)
#' sample_data_mc <- rmc(100, gamma = true_par_mc[1], delta = true_par_mc[2],
#'                       lambda = true_par_mc[3])
#' hist(sample_data_mc, breaks = 20, main = "Mc(2, 3, 0.5) Sample")
#'
#' # --- Find MLE estimates ---
#' start_par_mc <- c(1.5, 2.5, 0.8)
#' mle_result_mc <- stats::optim(par = start_par_mc,
#'                               fn = llmc,
#'                               gr = if (exists("grmc")) grmc else NULL,
#'                               method = "BFGS",
#'                               hessian = TRUE, # Ask optim for numerical Hessian
#'                               data = sample_data_mc)
#'
#' # --- Compare analytical Hessian to numerical Hessian ---
#' if (mle_result_mc$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE) &&
#'     exists("hsmc")) {
#'
#'   mle_par_mc <- mle_result_mc$par
#'   cat("\nComparing Hessians for Mc at MLE estimates:\n")
#'
#'   # Numerical Hessian of llmc
#'   num_hess_mc <- numDeriv::hessian(func = llmc, x = mle_par_mc, data = sample_data_mc)
#'
#'   # Analytical Hessian from hsmc
#'   ana_hess_mc <- hsmc(par = mle_par_mc, data = sample_data_mc)
#'
#'   cat("Numerical Hessian (Mc):\n")
#'   print(round(num_hess_mc, 4))
#'   cat("Analytical Hessian (Mc):\n")
#'   print(round(ana_hess_mc, 4))
#'
#'   # Check differences (monitor sign consistency)
#'   cat("Max absolute difference between Mc Hessians:\n")
#'   print(max(abs(num_hess_mc - ana_hess_mc)))
#'
#'   # Optional: Use analytical Hessian for Standard Errors
#'   # tryCatch({
#'   #   cov_matrix_mc <- solve(ana_hess_mc) # ana_hess_mc is already Hessian of negative LL
#'   #   std_errors_mc <- sqrt(diag(cov_matrix_mc))
#'   #   cat("Std. Errors from Analytical Mc Hessian:\n")
#'   #   print(std_errors_mc)
#'   # }, error = function(e) {
#'   #   warning("Could not invert analytical Mc Hessian: ", e$message)
#'   # })
#'
#' } else {
#'   cat("\nSkipping Mc Hessian comparison.\n")
#'   cat("Requires convergence, 'numDeriv' package, and function 'hsmc'.\n")
#' }
#'
#' }
#'
#' @export
hsmc <- function(par, data) {
    .Call(`_gkwreg_hsmc`, par, data)
}

#' @title Density of the Kumaraswamy (Kw) Distribution
#' @author Lopes, J. E.
#' @keywords distribution density kumaraswamy
#'
#' @description
#' Computes the probability density function (PDF) for the two-parameter
#' Kumaraswamy (Kw) distribution with shape parameters \code{alpha} (\eqn{\alpha})
#' and \code{beta} (\eqn{\beta}). This distribution is defined on the interval (0, 1).
#'
#' @param x Vector of quantiles (values between 0 and 1).
#' @param alpha Shape parameter \code{alpha} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param beta Shape parameter \code{beta} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param log_prob Logical; if \code{TRUE}, the logarithm of the density is
#'   returned (\eqn{\log(f(x))}). Default: \code{FALSE}.
#'
#' @return A vector of density values (\eqn{f(x)}) or log-density values
#'   (\eqn{\log(f(x))}). The length of the result is determined by the recycling
#'   rule applied to the arguments (\code{x}, \code{alpha}, \code{beta}).
#'   Returns \code{0} (or \code{-Inf} if \code{log_prob = TRUE}) for \code{x}
#'   outside the interval (0, 1), or \code{NaN} if parameters are invalid
#'   (e.g., \code{alpha <= 0}, \code{beta <= 0}).
#'
#' @details
#' The probability density function (PDF) of the Kumaraswamy (Kw) distribution
#' is given by:
#' \deqn{
#' f(x; \alpha, \beta) = \alpha \beta x^{\alpha-1} (1 - x^\alpha)^{\beta-1}
#' }
#' for \eqn{0 < x < 1}, \eqn{\alpha > 0}, and \eqn{\beta > 0}.
#'
#' The Kumaraswamy distribution is identical to the Generalized Kumaraswamy (GKw)
#' distribution (\code{\link{dgkw}}) with parameters \eqn{\gamma = 1},
#' \eqn{\delta = 0}, and \eqn{\lambda = 1}. It is also a special case of the
#' Exponentiated Kumaraswamy (\code{\link{dekw}}) with \eqn{\lambda = 1}, and
#' the Kumaraswamy-Kumaraswamy (\code{\link{dkkw}}) with \eqn{\delta = 0}
#' and \eqn{\lambda = 1}.
#'
#' @references
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#'
#' Jones, M. C. (2009). Kumaraswamy's distribution: A beta-type distribution
#' with some tractability advantages. *Statistical Methodology*, *6*(1), 70-81.
#'
#'
#' @seealso
#' \code{\link{dgkw}} (parent distribution density),
#' \code{\link{dekw}}, \code{\link{dkkw}},
#' \code{\link{pkw}}, \code{\link{qkw}}, \code{\link{rkw}} (other Kw functions),
#' \code{\link[stats]{dbeta}}
#'
#' @examples
#' \donttest{
#' # Example values
#' x_vals <- c(0.2, 0.5, 0.8)
#' alpha_par <- 2.0
#' beta_par <- 3.0
#'
#' # Calculate density using dkw
#' densities <- dkw(x_vals, alpha_par, beta_par)
#' print(densities)
#'
#' # Calculate log-density
#' log_densities <- dkw(x_vals, alpha_par, beta_par, log_prob = TRUE)
#' print(log_densities)
#' # Check: should match log(densities)
#' print(log(densities))
#'
#' # Compare with dgkw setting gamma = 1, delta = 0, lambda = 1
#' densities_gkw <- dgkw(x_vals, alpha_par, beta_par, gamma = 1.0, delta = 0.0,
#'                       lambda = 1.0)
#' print(paste("Max difference:", max(abs(densities - densities_gkw)))) # Should be near zero
#'
#' # Plot the density for different shape parameter combinations
#' curve_x <- seq(0.001, 0.999, length.out = 200)
#' plot(curve_x, dkw(curve_x, alpha = 2, beta = 3), type = "l",
#'      main = "Kumaraswamy Density Examples", xlab = "x", ylab = "f(x)",
#'      col = "blue", ylim = c(0, 4))
#' lines(curve_x, dkw(curve_x, alpha = 3, beta = 2), col = "red")
#' lines(curve_x, dkw(curve_x, alpha = 0.5, beta = 0.5), col = "green") # U-shaped
#' lines(curve_x, dkw(curve_x, alpha = 5, beta = 1), col = "purple") # J-shaped
#' lines(curve_x, dkw(curve_x, alpha = 1, beta = 3), col = "orange") # J-shaped (reversed)
#' legend("top", legend = c("a=2, b=3", "a=3, b=2", "a=0.5, b=0.5", "a=5, b=1", "a=1, b=3"),
#'        col = c("blue", "red", "green", "purple", "orange"), lty = 1, bty = "n", ncol = 2)
#' }
#'
#' @export
dkw <- function(x, alpha, beta, log_prob = FALSE) {
    .Call(`_gkwreg_dkw`, x, alpha, beta, log_prob)
}

#' @title Cumulative Distribution Function (CDF) of the Kumaraswamy (Kw) Distribution
#' @author Lopes, J. E.
#' @keywords distribution cumulative kumaraswamy
#'
#' @description
#' Computes the cumulative distribution function (CDF), \eqn{P(X \le q)}, for the
#' two-parameter Kumaraswamy (Kw) distribution with shape parameters \code{alpha}
#' (\eqn{\alpha}) and \code{beta} (\eqn{\beta}). This distribution is defined
#' on the interval (0, 1).
#'
#' @param q Vector of quantiles (values generally between 0 and 1).
#' @param alpha Shape parameter \code{alpha} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param beta Shape parameter \code{beta} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param lower_tail Logical; if \code{TRUE} (default), probabilities are
#'   \eqn{P(X \le q)}, otherwise, \eqn{P(X > q)}.
#' @param log_p Logical; if \code{TRUE}, probabilities \eqn{p} are given as
#'   \eqn{\log(p)}. Default: \code{FALSE}.
#'
#' @return A vector of probabilities, \eqn{F(q)}, or their logarithms/complements
#'   depending on \code{lower_tail} and \code{log_p}. The length of the result
#'   is determined by the recycling rule applied to the arguments (\code{q},
#'   \code{alpha}, \code{beta}). Returns \code{0} (or \code{-Inf} if
#'   \code{log_p = TRUE}) for \code{q <= 0} and \code{1} (or \code{0} if
#'   \code{log_p = TRUE}) for \code{q >= 1}. Returns \code{NaN} for invalid
#'   parameters.
#'
#' @details
#' The cumulative distribution function (CDF) of the Kumaraswamy (Kw)
#' distribution is given by:
#' \deqn{
#' F(x; \alpha, \beta) = 1 - (1 - x^\alpha)^\beta
#' }
#' for \eqn{0 < x < 1}, \eqn{\alpha > 0}, and \eqn{\beta > 0}.
#'
#' The Kw distribution is a special case of several generalized distributions:
#' \itemize{
#'  \item Generalized Kumaraswamy (\code{\link{pgkw}}) with \eqn{\gamma=1, \delta=0, \lambda=1}.
#'  \item Exponentiated Kumaraswamy (\code{\link{pekw}}) with \eqn{\lambda=1}.
#'  \item Kumaraswamy-Kumaraswamy (\code{\link{pkkw}}) with \eqn{\delta=0, \lambda=1}.
#' }
#' The implementation uses the closed-form expression for efficiency.
#'
#' @references
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#'
#' Jones, M. C. (2009). Kumaraswamy's distribution: A beta-type distribution
#' with some tractability advantages. *Statistical Methodology*, *6*(1), 70-81.
#'
#'
#' @seealso
#' \code{\link{pgkw}}, \code{\link{pekw}}, \code{\link{pkkw}} (related generalized CDFs),
#' \code{\link{dkw}}, \code{\link{qkw}}, \code{\link{rkw}} (other Kw functions),
#' \code{\link[stats]{pbeta}}
#'
#' @examples
#' \donttest{
#' # Example values
#' q_vals <- c(0.2, 0.5, 0.8)
#' alpha_par <- 2.0
#' beta_par <- 3.0
#'
#' # Calculate CDF P(X <= q) using pkw
#' probs <- pkw(q_vals, alpha_par, beta_par)
#' print(probs)
#'
#' # Calculate upper tail P(X > q)
#' probs_upper <- pkw(q_vals, alpha_par, beta_par, lower_tail = FALSE)
#' print(probs_upper)
#' # Check: probs + probs_upper should be 1
#' print(probs + probs_upper)
#'
#' # Calculate log CDF
#' log_probs <- pkw(q_vals, alpha_par, beta_par, log_p = TRUE)
#' print(log_probs)
#' # Check: should match log(probs)
#' print(log(probs))
#'
#' # Compare with pgkw setting gamma = 1, delta = 0, lambda = 1
#' probs_gkw <- pgkw(q_vals, alpha_par, beta_par, gamma = 1.0, delta = 0.0,
#'                   lambda = 1.0)
#' print(paste("Max difference:", max(abs(probs - probs_gkw)))) # Should be near zero
#'
#' # Plot the CDF for different shape parameter combinations
#' curve_q <- seq(0.001, 0.999, length.out = 200)
#' plot(curve_q, pkw(curve_q, alpha = 2, beta = 3), type = "l",
#'      main = "Kumaraswamy CDF Examples", xlab = "q", ylab = "F(q)",
#'      col = "blue", ylim = c(0, 1))
#' lines(curve_q, pkw(curve_q, alpha = 3, beta = 2), col = "red")
#' lines(curve_q, pkw(curve_q, alpha = 0.5, beta = 0.5), col = "green")
#' lines(curve_q, pkw(curve_q, alpha = 5, beta = 1), col = "purple")
#' lines(curve_q, pkw(curve_q, alpha = 1, beta = 3), col = "orange")
#' legend("bottomright", legend = c("a=2, b=3", "a=3, b=2", "a=0.5, b=0.5", "a=5, b=1", "a=1, b=3"),
#'        col = c("blue", "red", "green", "purple", "orange"), lty = 1, bty = "n", ncol = 2)
#'
#' }
#'
#' @export
pkw <- function(q, alpha, beta, lower_tail = TRUE, log_p = FALSE) {
    .Call(`_gkwreg_pkw`, q, alpha, beta, lower_tail, log_p)
}

#' @title Quantile Function of the Kumaraswamy (Kw) Distribution
#' @author Lopes, J. E.
#' @keywords distribution quantile kumaraswamy
#'
#' @description
#' Computes the quantile function (inverse CDF) for the two-parameter
#' Kumaraswamy (Kw) distribution with shape parameters \code{alpha} (\eqn{\alpha})
#' and \code{beta} (\eqn{\beta}). It finds the value \code{q} such that
#' \eqn{P(X \le q) = p}.
#'
#' @param p Vector of probabilities (values between 0 and 1).
#' @param alpha Shape parameter \code{alpha} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param beta Shape parameter \code{beta} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param lower_tail Logical; if \code{TRUE} (default), probabilities are \eqn{p = P(X \le q)},
#'   otherwise, probabilities are \eqn{p = P(X > q)}.
#' @param log_p Logical; if \code{TRUE}, probabilities \code{p} are given as
#'   \eqn{\log(p)}. Default: \code{FALSE}.
#'
#' @return A vector of quantiles corresponding to the given probabilities \code{p}.
#'   The length of the result is determined by the recycling rule applied to
#'   the arguments (\code{p}, \code{alpha}, \code{beta}).
#'   Returns:
#'   \itemize{
#'     \item \code{0} for \code{p = 0} (or \code{p = -Inf} if \code{log_p = TRUE},
#'           when \code{lower_tail = TRUE}).
#'     \item \code{1} for \code{p = 1} (or \code{p = 0} if \code{log_p = TRUE},
#'           when \code{lower_tail = TRUE}).
#'     \item \code{NaN} for \code{p < 0} or \code{p > 1} (or corresponding log scale).
#'     \item \code{NaN} for invalid parameters (e.g., \code{alpha <= 0},
#'           \code{beta <= 0}).
#'   }
#'   Boundary return values are adjusted accordingly for \code{lower_tail = FALSE}.
#'
#' @details
#' The quantile function \eqn{Q(p)} is the inverse of the CDF \eqn{F(q)}. The CDF
#' for the Kumaraswamy distribution is \eqn{F(q) = 1 - (1 - q^\alpha)^\beta}
#' (see \code{\link{pkw}}). Inverting this equation for \eqn{q} yields the
#' quantile function:
#' \deqn{
#' Q(p) = \left\{ 1 - (1 - p)^{1/\beta} \right\}^{1/\alpha}
#' }
#' The function uses this closed-form expression and correctly handles the
#' \code{lower_tail} and \code{log_p} arguments by transforming \code{p}
#' appropriately before applying the formula. This is equivalent to the general
#' GKw quantile function (\code{\link{qgkw}}) evaluated with \eqn{\gamma=1, \delta=0, \lambda=1}.
#'
#' @references
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#'
#' Jones, M. C. (2009). Kumaraswamy's distribution: A beta-type distribution
#' with some tractability advantages. *Statistical Methodology*, *6*(1), 70-81.
#'
#'
#' @seealso
#' \code{\link{qgkw}} (parent distribution quantile function),
#' \code{\link{dkw}}, \code{\link{pkw}}, \code{\link{rkw}} (other Kw functions),
#' \code{\link[stats]{qbeta}}, \code{\link[stats]{qunif}}
#'
#' @examples
#' \donttest{
#' # Example values
#' p_vals <- c(0.1, 0.5, 0.9)
#' alpha_par <- 2.0
#' beta_par <- 3.0
#'
#' # Calculate quantiles using qkw
#' quantiles <- qkw(p_vals, alpha_par, beta_par)
#' print(quantiles)
#'
#' # Calculate quantiles for upper tail probabilities P(X > q) = p
#' quantiles_upper <- qkw(p_vals, alpha_par, beta_par, lower_tail = FALSE)
#' print(quantiles_upper)
#' # Check: qkw(p, ..., lt=F) == qkw(1-p, ..., lt=T)
#' print(qkw(1 - p_vals, alpha_par, beta_par))
#'
#' # Calculate quantiles from log probabilities
#' log_p_vals <- log(p_vals)
#' quantiles_logp <- qkw(log_p_vals, alpha_par, beta_par, log_p = TRUE)
#' print(quantiles_logp)
#' # Check: should match original quantiles
#' print(quantiles)
#'
#' # Compare with qgkw setting gamma = 1, delta = 0, lambda = 1
#' quantiles_gkw <- qgkw(p_vals, alpha = alpha_par, beta = beta_par,
#'                      gamma = 1.0, delta = 0.0, lambda = 1.0)
#' print(paste("Max difference:", max(abs(quantiles - quantiles_gkw)))) # Should be near zero
#'
#' # Verify inverse relationship with pkw
#' p_check <- 0.75
#' q_calc <- qkw(p_check, alpha_par, beta_par)
#' p_recalc <- pkw(q_calc, alpha_par, beta_par)
#' print(paste("Original p:", p_check, " Recalculated p:", p_recalc))
#' # abs(p_check - p_recalc) < 1e-9 # Should be TRUE
#'
#' # Boundary conditions
#' print(qkw(c(0, 1), alpha_par, beta_par)) # Should be 0, 1
#' print(qkw(c(-Inf, 0), alpha_par, beta_par, log_p = TRUE)) # Should be 0, 1
#'
#' }
#'
#' @export
qkw <- function(p, alpha, beta, lower_tail = TRUE, log_p = FALSE) {
    .Call(`_gkwreg_qkw`, p, alpha, beta, lower_tail, log_p)
}

#' @title Random Number Generation for the Kumaraswamy (Kw) Distribution
#' @author Lopes, J. E.
#' @keywords distribution random kumaraswamy
#'
#' @description
#' Generates random deviates from the two-parameter Kumaraswamy (Kw)
#' distribution with shape parameters \code{alpha} (\eqn{\alpha}) and
#' \code{beta} (\eqn{\beta}).
#'
#' @param n Number of observations. If \code{length(n) > 1}, the length is
#'   taken to be the number required. Must be a non-negative integer.
#' @param alpha Shape parameter \code{alpha} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#' @param beta Shape parameter \code{beta} > 0. Can be a scalar or a vector.
#'   Default: 1.0.
#'
#' @return A vector of length \code{n} containing random deviates from the Kw
#'   distribution, with values in (0, 1). The length of the result is determined
#'   by \code{n} and the recycling rule applied to the parameters (\code{alpha},
#'   \code{beta}). Returns \code{NaN} if parameters are invalid (e.g.,
#'   \code{alpha <= 0}, \code{beta <= 0}).
#'
#' @details
#' The generation method uses the inverse transform (quantile) method.
#' That is, if \eqn{U} is a random variable following a standard Uniform
#' distribution on (0, 1), then \eqn{X = Q(U)} follows the Kw distribution,
#' where \eqn{Q(p)} is the Kw quantile function (\code{\link{qkw}}):
#' \deqn{
#' Q(p) = \left\{ 1 - (1 - p)^{1/\beta} \right\}^{1/\alpha}
#' }
#' The implementation generates \eqn{U} using \code{\link[stats]{runif}}
#' and applies this transformation. This is equivalent to the general GKw
#' generation method (\code{\link{rgkw}}) evaluated at \eqn{\gamma=1, \delta=0, \lambda=1}.
#'
#' @references
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#'
#' Jones, M. C. (2009). Kumaraswamy's distribution: A beta-type distribution
#' with some tractability advantages. *Statistical Methodology*, *6*(1), 70-81.
#'
#'
#' Devroye, L. (1986). *Non-Uniform Random Variate Generation*. Springer-Verlag.
#' (General methods for random variate generation).
#'
#' @seealso
#' \code{\link{rgkw}} (parent distribution random generation),
#' \code{\link{dkw}}, \code{\link{pkw}}, \code{\link{qkw}} (other Kw functions),
#' \code{\link[stats]{runif}}
#'
#' @examples
#' \donttest{
#' set.seed(2029) # for reproducibility
#'
#' # Generate 1000 random values from a specific Kw distribution
#' alpha_par <- 2.0
#' beta_par <- 3.0
#'
#' x_sample_kw <- rkw(1000, alpha = alpha_par, beta = beta_par)
#' summary(x_sample_kw)
#'
#' # Histogram of generated values compared to theoretical density
#' hist(x_sample_kw, breaks = 30, freq = FALSE, # freq=FALSE for density
#'      main = "Histogram of Kw Sample", xlab = "x", ylim = c(0, 2.5))
#' curve(dkw(x, alpha = alpha_par, beta = beta_par),
#'       add = TRUE, col = "red", lwd = 2, n = 201)
#' legend("top", legend = "Theoretical PDF", col = "red", lwd = 2, bty = "n")
#'
#' # Comparing empirical and theoretical quantiles (Q-Q plot)
#' prob_points <- seq(0.01, 0.99, by = 0.01)
#' theo_quantiles <- qkw(prob_points, alpha = alpha_par, beta = beta_par)
#' emp_quantiles <- quantile(x_sample_kw, prob_points, type = 7)
#'
#' plot(theo_quantiles, emp_quantiles, pch = 16, cex = 0.8,
#'      main = "Q-Q Plot for Kw Distribution",
#'      xlab = "Theoretical Quantiles", ylab = "Empirical Quantiles (n=1000)")
#' abline(a = 0, b = 1, col = "blue", lty = 2)
#'
#' # Compare summary stats with rgkw(..., gamma=1, delta=0, lambda=1)
#' # Note: individual values will differ due to randomness
#' x_sample_gkw <- rgkw(1000, alpha = alpha_par, beta = beta_par, gamma = 1.0,
#'                      delta = 0.0, lambda = 1.0)
#' print("Summary stats for rkw sample:")
#' print(summary(x_sample_kw))
#' print("Summary stats for rgkw(gamma=1, delta=0, lambda=1) sample:")
#' print(summary(x_sample_gkw)) # Should be similar
#'
#' }
#'
#' @export
rkw <- function(n, alpha, beta) {
    .Call(`_gkwreg_rkw`, n, alpha, beta)
}

#' @title Negative Log-Likelihood of the Kumaraswamy (Kw) Distribution
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize kumaraswamy
#'
#' @description
#' Computes the negative log-likelihood function for the two-parameter
#' Kumaraswamy (Kw) distribution with parameters \code{alpha} (\eqn{\alpha})
#' and \code{beta} (\eqn{\beta}), given a vector of observations. This function
#' is suitable for maximum likelihood estimation.
#'
#' @param par A numeric vector of length 2 containing the distribution parameters
#'   in the order: \code{alpha} (\eqn{\alpha > 0}), \code{beta} (\eqn{\beta > 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a single \code{double} value representing the negative
#'   log-likelihood (\eqn{-\ell(\theta|\mathbf{x})}). Returns \code{Inf}
#'   if any parameter values in \code{par} are invalid according to their
#'   constraints, or if any value in \code{data} is not in the interval (0, 1).
#'
#' @details
#' The Kumaraswamy (Kw) distribution's probability density function (PDF) is
#' (see \code{\link{dkw}}):
#' \deqn{
#' f(x | \theta) = \alpha \beta x^{\alpha-1} (1 - x^\alpha)^{\beta-1}
#' }
#' for \eqn{0 < x < 1} and \eqn{\theta = (\alpha, \beta)}.
#' The log-likelihood function \eqn{\ell(\theta | \mathbf{x})} for a sample
#' \eqn{\mathbf{x} = (x_1, \dots, x_n)} is \eqn{\sum_{i=1}^n \ln f(x_i | \theta)}:
#' \deqn{
#' \ell(\theta | \mathbf{x}) = n[\ln(\alpha) + \ln(\beta)]
#' + \sum_{i=1}^{n} [(\alpha-1)\ln(x_i) + (\beta-1)\ln(v_i)]
#' }
#' where \eqn{v_i = 1 - x_i^{\alpha}}.
#' This function computes and returns the *negative* log-likelihood, \eqn{-\ell(\theta|\mathbf{x})},
#' suitable for minimization using optimization routines like \code{\link[stats]{optim}}.
#' It is equivalent to the negative log-likelihood of the GKw distribution
#' (\code{\link{llgkw}}) evaluated at \eqn{\gamma=1, \delta=0, \lambda=1}.
#'
#' @references
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#'
#' Jones, M. C. (2009). Kumaraswamy's distribution: A beta-type distribution
#' with some tractability advantages. *Statistical Methodology*, *6*(1), 70-81.
#'
#'
#' @seealso
#' \code{\link{llgkw}} (parent distribution negative log-likelihood),
#' \code{\link{dkw}}, \code{\link{pkw}}, \code{\link{qkw}}, \code{\link{rkw}},
#' \code{grkw} (gradient, if available),
#' \code{hskw} (Hessian, if available),
#' \code{\link[stats]{optim}}
#'
#' @examples
#' \donttest{
#' # Assuming existence of rkw, grkw, hskw functions for Kw distribution
#'
#' # Generate sample data from a known Kw distribution
#' set.seed(123)
#' true_par_kw <- c(alpha = 2, beta = 3)
#' sample_data_kw <- rkw(100, alpha = true_par_kw[1], beta = true_par_kw[2])
#' hist(sample_data_kw, breaks = 20, main = "Kw(2, 3) Sample")
#'
#' # --- Maximum Likelihood Estimation using optim ---
#' # Initial parameter guess
#' start_par_kw <- c(1.5, 2.5)
#'
#' # Perform optimization (minimizing negative log-likelihood)
#' # Use method="L-BFGS-B" for box constraints (params > 0)
#' mle_result_kw <- stats::optim(par = start_par_kw,
#'                               fn = llkw, # Use the Kw neg-log-likelihood
#'                               method = "L-BFGS-B",
#'                               lower = c(1e-6, 1e-6), # Lower bounds > 0
#'                               hessian = TRUE,
#'                               data = sample_data_kw)
#'
#' # Check convergence and results
#' if (mle_result_kw$convergence == 0) {
#'   print("Optimization converged successfully.")
#'   mle_par_kw <- mle_result_kw$par
#'   print("Estimated Kw parameters:")
#'   print(mle_par_kw)
#'   print("True Kw parameters:")
#'   print(true_par_kw)
#' } else {
#'   warning("Optimization did not converge!")
#'   print(mle_result_kw$message)
#' }
#'
#' # --- Compare numerical and analytical derivatives (if available) ---
#' # Requires 'numDeriv' package and analytical functions 'grkw', 'hskw'
#' if (mle_result_kw$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE) &&
#'     exists("grkw") && exists("hskw")) {
#'
#'   cat("\nComparing Derivatives at Kw MLE estimates:\n")
#'
#'   # Numerical derivatives of llkw
#'   num_grad_kw <- numDeriv::grad(func = llkw, x = mle_par_kw, data = sample_data_kw)
#'   num_hess_kw <- numDeriv::hessian(func = llkw, x = mle_par_kw, data = sample_data_kw)
#'
#'   # Analytical derivatives (assuming they return derivatives of negative LL)
#'   ana_grad_kw <- grkw(par = mle_par_kw, data = sample_data_kw)
#'   ana_hess_kw <- hskw(par = mle_par_kw, data = sample_data_kw)
#'
#'   # Check differences
#'   cat("Max absolute difference between gradients:\n")
#'   print(max(abs(num_grad_kw - ana_grad_kw)))
#'   cat("Max absolute difference between Hessians:\n")
#'   print(max(abs(num_hess_kw - ana_hess_kw)))
#'
#' } else {
#'    cat("\nSkipping derivative comparison for Kw.\n")
#'    cat("Requires convergence, 'numDeriv' package and functions 'grkw', 'hskw'.\n")
#' }
#'
#' }
#'
#' @export
llkw <- function(par, data) {
    .Call(`_gkwreg_llkw`, par, data)
}

#' @title Gradient of the Negative Log-Likelihood for the Kumaraswamy (Kw) Distribution
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize gradient kumaraswamy
#'
#' @description
#' Computes the gradient vector (vector of first partial derivatives) of the
#' negative log-likelihood function for the two-parameter Kumaraswamy (Kw)
#' distribution with parameters \code{alpha} (\eqn{\alpha}) and \code{beta}
#' (\eqn{\beta}). This provides the analytical gradient often used for efficient
#' optimization via maximum likelihood estimation.
#'
#' @param par A numeric vector of length 2 containing the distribution parameters
#'   in the order: \code{alpha} (\eqn{\alpha > 0}), \code{beta} (\eqn{\beta > 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a numeric vector of length 2 containing the partial derivatives
#'   of the negative log-likelihood function \eqn{-\ell(\theta | \mathbf{x})} with
#'   respect to each parameter: \eqn{(-\partial \ell/\partial \alpha, -\partial \ell/\partial \beta)}.
#'   Returns a vector of \code{NaN} if any parameter values are invalid according
#'   to their constraints, or if any value in \code{data} is not in the
#'   interval (0, 1).
#'
#' @details
#' The components of the gradient vector of the negative log-likelihood
#' (\eqn{-\nabla \ell(\theta | \mathbf{x})}) for the Kw model are:
#'
#' \deqn{
#' -\frac{\partial \ell}{\partial \alpha} = -\frac{n}{\alpha} - \sum_{i=1}^{n}\ln(x_i)
#' + (\beta-1)\sum_{i=1}^{n}\frac{x_i^{\alpha}\ln(x_i)}{v_i}
#' }
#' \deqn{
#' -\frac{\partial \ell}{\partial \beta} = -\frac{n}{\beta} - \sum_{i=1}^{n}\ln(v_i)
#' }
#'
#' where \eqn{v_i = 1 - x_i^{\alpha}}.
#' These formulas represent the derivatives of \eqn{-\ell(\theta)}, consistent with
#' minimizing the negative log-likelihood. They correspond to the relevant components
#' of the general GKw gradient (\code{\link{grgkw}}) evaluated at \eqn{\gamma=1, \delta=0, \lambda=1}.
#'
#' @references
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#'
#' Jones, M. C. (2009). Kumaraswamy's distribution: A beta-type distribution
#' with some tractability advantages. *Statistical Methodology*, *6*(1), 70-81.
#'
#' (Note: Specific gradient formulas might be derived or sourced from additional references).
#'
#' @seealso
#' \code{\link{grgkw}} (parent distribution gradient),
#' \code{\link{llkw}} (negative log-likelihood for Kw),
#' \code{hskw} (Hessian for Kw, if available),
#' \code{\link{dkw}} (density for Kw),
#' \code{\link[stats]{optim}},
#' \code{\link[numDeriv]{grad}} (for numerical gradient comparison).
#'
#' @examples
#' \donttest{
#' # Assuming existence of rkw, llkw, grkw, hskw functions for Kw
#'
#' # Generate sample data
#' set.seed(123)
#' true_par_kw <- c(alpha = 2, beta = 3)
#' sample_data_kw <- rkw(100, alpha = true_par_kw[1], beta = true_par_kw[2])
#' hist(sample_data_kw, breaks = 20, main = "Kw(2, 3) Sample")
#'
#' # --- Find MLE estimates ---
#' start_par_kw <- c(1.5, 2.5)
#' mle_result_kw <- stats::optim(par = start_par_kw,
#'                               fn = llkw,
#'                               gr = grkw, # Use analytical gradient for Kw
#'                               method = "L-BFGS-B", # Recommended for bounds
#'                               lower = c(1e-6, 1e-6),
#'                               hessian = TRUE,
#'                               data = sample_data_kw)
#'
#' # --- Compare analytical gradient to numerical gradient ---
#' if (mle_result_kw$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE)) {
#'
#'   mle_par_kw <- mle_result_kw$par
#'   cat("\nComparing Gradients for Kw at MLE estimates:\n")
#'
#'   # Numerical gradient of llkw
#'   num_grad_kw <- numDeriv::grad(func = llkw, x = mle_par_kw, data = sample_data_kw)
#'
#'   # Analytical gradient from grkw
#'   ana_grad_kw <- grkw(par = mle_par_kw, data = sample_data_kw)
#'
#'   cat("Numerical Gradient (Kw):\n")
#'   print(num_grad_kw)
#'   cat("Analytical Gradient (Kw):\n")
#'   print(ana_grad_kw)
#'
#'   # Check differences
#'   cat("Max absolute difference between Kw gradients:\n")
#'   print(max(abs(num_grad_kw - ana_grad_kw)))
#'
#' } else {
#'   cat("\nSkipping Kw gradient comparison.\n")
#' }
#'
#' # Example with Hessian comparison (if hskw exists)
#' if (mle_result_kw$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE) && exists("hskw")) {
#'
#'   num_hess_kw <- numDeriv::hessian(func = llkw, x = mle_par_kw, data = sample_data_kw)
#'   ana_hess_kw <- hskw(par = mle_par_kw, data = sample_data_kw)
#'   cat("\nMax absolute difference between Kw Hessians:\n")
#'   print(max(abs(num_hess_kw - ana_hess_kw)))
#'
#' }
#'
#' }
#'
#' @export
grkw <- function(par, data) {
    .Call(`_gkwreg_grkw`, par, data)
}

#' @title Hessian Matrix of the Negative Log-Likelihood for the Kw Distribution
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize hessian kumaraswamy
#'
#' @description
#' Computes the analytic 2x2 Hessian matrix (matrix of second partial derivatives)
#' of the negative log-likelihood function for the two-parameter Kumaraswamy (Kw)
#' distribution with parameters \code{alpha} (\eqn{\alpha}) and \code{beta}
#' (\eqn{\beta}). The Hessian is useful for estimating standard errors and in
#' optimization algorithms.
#'
#' @param par A numeric vector of length 2 containing the distribution parameters
#'   in the order: \code{alpha} (\eqn{\alpha > 0}), \code{beta} (\eqn{\beta > 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a 2x2 numeric matrix representing the Hessian matrix of the
#'   negative log-likelihood function, \eqn{-\partial^2 \ell / (\partial \theta_i \partial \theta_j)},
#'   where \eqn{\theta = (\alpha, \beta)}.
#'   Returns a 2x2 matrix populated with \code{NaN} if any parameter values are
#'   invalid according to their constraints, or if any value in \code{data} is
#'   not in the interval (0, 1).
#'
#' @details
#' This function calculates the analytic second partial derivatives of the
#' negative log-likelihood function (\eqn{-\ell(\theta|\mathbf{x})}). The components
#' are the negative of the second derivatives of the log-likelihood \eqn{\ell}
#' (derived from the PDF in \code{\link{dkw}}).
#'
#' Let \eqn{v_i = 1 - x_i^{\alpha}}. The second derivatives of the positive log-likelihood (\eqn{\ell}) are:
#' \deqn{
#' \frac{\partial^2 \ell}{\partial \alpha^2} = -\frac{n}{\alpha^2} -
#' (\beta-1)\sum_{i=1}^{n}\frac{x_i^{\alpha}(\ln(x_i))^2}{v_i^2}
#' }
#' \deqn{
#' \frac{\partial^2 \ell}{\partial \alpha \partial \beta} = -
#' \sum_{i=1}^{n}\frac{x_i^{\alpha}\ln(x_i)}{v_i}
#' }
#' \deqn{
#' \frac{\partial^2 \ell}{\partial \beta^2} = -\frac{n}{\beta^2}
#' }
#' The function returns the Hessian matrix containing the negative of these values.
#'
#' Key properties of the returned matrix:
#' \itemize{
#'   \item Dimensions: 2x2.
#'   \item Symmetry: The matrix is symmetric.
#'   \item Ordering: Rows and columns correspond to the parameters in the order
#'     \eqn{\alpha, \beta}.
#'   \item Content: Analytic second derivatives of the *negative* log-likelihood.
#' }
#' This corresponds to the relevant 2x2 submatrix of the 5x5 GKw Hessian (\code{\link{hsgkw}})
#' evaluated at \eqn{\gamma=1, \delta=0, \lambda=1}.
#'
#' @references
#' Kumaraswamy, P. (1980). A generalized probability density function for
#' double-bounded random processes. *Journal of Hydrology*, *46*(1-2), 79-88.
#'
#'
#' Jones, M. C. (2009). Kumaraswamy's distribution: A beta-type distribution
#' with some tractability advantages. *Statistical Methodology*, *6*(1), 70-81.
#'
#' (Note: Specific Hessian formulas might be derived or sourced from additional references).
#'
#' @seealso
#' \code{\link{hsgkw}} (parent distribution Hessian),
#' \code{\link{llkw}} (negative log-likelihood for Kw),
#' \code{grkw} (gradient for Kw, if available),
#' \code{\link{dkw}} (density for Kw),
#' \code{\link[stats]{optim}},
#' \code{\link[numDeriv]{hessian}} (for numerical Hessian comparison).
#'
#' @examples
#' \donttest{
#' # Assuming existence of rkw, llkw, grkw, hskw functions for Kw
#'
#' # Generate sample data
#' set.seed(123)
#' true_par_kw <- c(alpha = 2, beta = 3)
#' sample_data_kw <- rkw(100, alpha = true_par_kw[1], beta = true_par_kw[2])
#' hist(sample_data_kw, breaks = 20, main = "Kw(2, 3) Sample")
#'
#' # --- Find MLE estimates ---
#' start_par_kw <- c(1.5, 2.5)
#' mle_result_kw <- stats::optim(par = start_par_kw,
#'                               fn = llkw,
#'                               gr = if (exists("grkw")) grkw else NULL,
#'                               method = "L-BFGS-B",
#'                               lower = c(1e-6, 1e-6),
#'                               hessian = TRUE, # Ask optim for numerical Hessian
#'                               data = sample_data_kw)
#'
#' # --- Compare analytical Hessian to numerical Hessian ---
#' if (mle_result_kw$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE) &&
#'     exists("hskw")) {
#'
#'   mle_par_kw <- mle_result_kw$par
#'   cat("\nComparing Hessians for Kw at MLE estimates:\n")
#'
#'   # Numerical Hessian of llkw
#'   num_hess_kw <- numDeriv::hessian(func = llkw, x = mle_par_kw, data = sample_data_kw)
#'
#'   # Analytical Hessian from hskw
#'   ana_hess_kw <- hskw(par = mle_par_kw, data = sample_data_kw)
#'
#'   cat("Numerical Hessian (Kw):\n")
#'   print(round(num_hess_kw, 4))
#'   cat("Analytical Hessian (Kw):\n")
#'   print(round(ana_hess_kw, 4))
#'
#'   # Check differences
#'   cat("Max absolute difference between Kw Hessians:\n")
#'   print(max(abs(num_hess_kw - ana_hess_kw)))
#'
#'   # Optional: Use analytical Hessian for Standard Errors
#'   # tryCatch({
#'   #   cov_matrix_kw <- solve(ana_hess_kw) # ana_hess_kw is already Hessian of negative LL
#'   #   std_errors_kw <- sqrt(diag(cov_matrix_kw))
#'   #   cat("Std. Errors from Analytical Kw Hessian:\n")
#'   #   print(std_errors_kw)
#'   # }, error = function(e) {
#'   #   warning("Could not invert analytical Kw Hessian: ", e$message)
#'   # })
#'
#' } else {
#'   cat("\nSkipping Kw Hessian comparison.\n")
#'   cat("Requires convergence, 'numDeriv' package, and function 'hskw'.\n")
#' }
#'
#' }
#'
#' @export
hskw <- function(par, data) {
    .Call(`_gkwreg_hskw`, par, data)
}

#' @title Density of the Beta Distribution (gamma, delta+1 Parameterization)
#' @author Lopes, J. E.
#' @keywords distribution density beta
#'
#' @description
#' Computes the probability density function (PDF) for the standard Beta
#' distribution, using a parameterization common in generalized distribution
#' families. The distribution is parameterized by \code{gamma} (\eqn{\gamma}) and
#' \code{delta} (\eqn{\delta}), corresponding to the standard Beta distribution
#' with shape parameters \code{shape1 = gamma} and \code{shape2 = delta + 1}.
#' The distribution is defined on the interval (0, 1).
#'
#' @param x Vector of quantiles (values between 0 and 1).
#' @param gamma First shape parameter (\code{shape1}), \eqn{\gamma > 0}. Can be a
#'   scalar or a vector. Default: 1.0.
#' @param delta Second shape parameter is \code{delta + 1} (\code{shape2}), requires
#'   \eqn{\delta \ge 0} so that \code{shape2 >= 1}. Can be a scalar or a vector.
#'   Default: 0.0 (leading to \code{shape2 = 1}).
#' @param log_prob Logical; if \code{TRUE}, the logarithm of the density is
#'   returned (\eqn{\log(f(x))}). Default: \code{FALSE}.
#'
#' @return A vector of density values (\eqn{f(x)}) or log-density values
#'   (\eqn{\log(f(x))}). The length of the result is determined by the recycling
#'   rule applied to the arguments (\code{x}, \code{gamma}, \code{delta}).
#'   Returns \code{0} (or \code{-Inf} if \code{log_prob = TRUE}) for \code{x}
#'   outside the interval (0, 1), or \code{NaN} if parameters are invalid
#'   (e.g., \code{gamma <= 0}, \code{delta < 0}).
#'
#' @details
#' The probability density function (PDF) calculated by this function corresponds
#' to a standard Beta distribution \eqn{Beta(\gamma, \delta+1)}:
#' \deqn{
#' f(x; \gamma, \delta) = \frac{x^{\gamma-1} (1-x)^{(\delta+1)-1}}{B(\gamma, \delta+1)} = \frac{x^{\gamma-1} (1-x)^{\delta}}{B(\gamma, \delta+1)}
#' }
#' for \eqn{0 < x < 1}, where \eqn{B(a,b)} is the Beta function
#' (\code{\link[base]{beta}}).
#'
#' This specific parameterization arises as a special case of the five-parameter
#' Generalized Kumaraswamy (GKw) distribution (\code{\link{dgkw}}) obtained
#' by setting the parameters \eqn{\alpha = 1}, \eqn{\beta = 1}, and \eqn{\lambda = 1}.
#' It is therefore equivalent to the McDonald (Mc)/Beta Power distribution
#' (\code{\link{dmc}}) with \eqn{\lambda = 1}.
#'
#' Note the difference in the second parameter compared to \code{\link[stats]{dbeta}},
#' where \code{dbeta(x, shape1, shape2)} uses \code{shape2} directly. Here,
#' \code{shape1 = gamma} and \code{shape2 = delta + 1}.
#'
#' @references
#' Johnson, N. L., Kotz, S., & Balakrishnan, N. (1995). *Continuous Univariate
#' Distributions, Volume 2* (2nd ed.). Wiley.
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#'
#' @seealso
#' \code{\link[stats]{dbeta}} (standard R implementation),
#' \code{\link{dgkw}} (parent distribution density),
#' \code{\link{dmc}} (McDonald/Beta Power density),
#' \code{pbeta_}, \code{qbeta_}, \code{rbeta_} (other functions for this parameterization, if they exist).
#'
#' @examples
#' \donttest{
#' # Example values
#' x_vals <- c(0.2, 0.5, 0.8)
#' gamma_par <- 2.0 # Corresponds to shape1
#' delta_par <- 3.0 # Corresponds to shape2 - 1
#' shape1 <- gamma_par
#' shape2 <- delta_par + 1
#'
#' # Calculate density using dbeta_
#' densities <- dbeta_(x_vals, gamma_par, delta_par)
#' print(densities)
#'
#' # Compare with stats::dbeta
#' densities_stats <- stats::dbeta(x_vals, shape1 = shape1, shape2 = shape2)
#' print(paste("Max difference vs stats::dbeta:", max(abs(densities - densities_stats))))
#'
#' # Compare with dgkw setting alpha=1, beta=1, lambda=1
#' densities_gkw <- dgkw(x_vals, alpha = 1.0, beta = 1.0, gamma = gamma_par,
#'                       delta = delta_par, lambda = 1.0)
#' print(paste("Max difference vs dgkw:", max(abs(densities - densities_gkw))))
#'
#' # Compare with dmc setting lambda=1
#' densities_mc <- dmc(x_vals, gamma = gamma_par, delta = delta_par, lambda = 1.0)
#' print(paste("Max difference vs dmc:", max(abs(densities - densities_mc))))
#'
#' # Calculate log-density
#' log_densities <- dbeta_(x_vals, gamma_par, delta_par, log_prob = TRUE)
#' print(log_densities)
#' print(stats::dbeta(x_vals, shape1 = shape1, shape2 = shape2, log = TRUE))
#'
#' # Plot the density
#' curve_x <- seq(0.001, 0.999, length.out = 200)
#' curve_y <- dbeta_(curve_x, gamma = 2, delta = 3) # Beta(2, 4)
#' plot(curve_x, curve_y, type = "l", main = "Beta(2, 4) Density via dbeta_",
#'      xlab = "x", ylab = "f(x)", col = "blue")
#' curve(stats::dbeta(x, 2, 4), add=TRUE, col="red", lty=2)
#' legend("topright", legend=c("dbeta_(gamma=2, delta=3)", "stats::dbeta(shape1=2, shape2=4)"),
#'        col=c("blue", "red"), lty=c(1,2), bty="n")
#'
#' }
#'
#' @export
dbeta_ <- function(x, gamma, delta, log_prob = FALSE) {
    .Call(`_gkwreg_dbeta_`, x, gamma, delta, log_prob)
}

#' @title CDF of the Beta Distribution (gamma, delta+1 Parameterization)
#' @author Lopes, J. E.
#' @keywords distribution cumulative beta
#'
#' @description
#' Computes the cumulative distribution function (CDF), \eqn{F(q) = P(X \le q)},
#' for the standard Beta distribution, using a parameterization common in
#' generalized distribution families. The distribution is parameterized by
#' \code{gamma} (\eqn{\gamma}) and \code{delta} (\eqn{\delta}), corresponding to
#' the standard Beta distribution with shape parameters \code{shape1 = gamma}
#' and \code{shape2 = delta + 1}.
#'
#' @param q Vector of quantiles (values generally between 0 and 1).
#' @param gamma First shape parameter (\code{shape1}), \eqn{\gamma > 0}. Can be a
#'   scalar or a vector. Default: 1.0.
#' @param delta Second shape parameter is \code{delta + 1} (\code{shape2}), requires
#'   \eqn{\delta \ge 0} so that \code{shape2 >= 1}. Can be a scalar or a vector.
#'   Default: 0.0 (leading to \code{shape2 = 1}).
#' @param lower_tail Logical; if \code{TRUE} (default), probabilities are
#'   \eqn{P(X \le q)}, otherwise, \eqn{P(X > q)}.
#' @param log_p Logical; if \code{TRUE}, probabilities \eqn{p} are given as
#'   \eqn{\log(p)}. Default: \code{FALSE}.
#'
#' @return A vector of probabilities, \eqn{F(q)}, or their logarithms/complements
#'   depending on \code{lower_tail} and \code{log_p}. The length of the result
#'   is determined by the recycling rule applied to the arguments (\code{q},
#'   \code{gamma}, \code{delta}). Returns \code{0} (or \code{-Inf} if
#'   \code{log_p = TRUE}) for \code{q <= 0} and \code{1} (or \code{0} if
#'   \code{log_p = TRUE}) for \code{q >= 1}. Returns \code{NaN} for invalid
#'   parameters.
#'
#' @details
#' This function computes the CDF of a Beta distribution with parameters
#' \code{shape1 = gamma} and \code{shape2 = delta + 1}. It is equivalent to
#' calling \code{stats::pbeta(q, shape1 = gamma, shape2 = delta + 1,
#' lower.tail = lower_tail, log.p = log_p)}.
#'
#' This distribution arises as a special case of the five-parameter
#' Generalized Kumaraswamy (GKw) distribution (\code{\link{pgkw}}) obtained
#' by setting \eqn{\alpha = 1}, \eqn{\beta = 1}, and \eqn{\lambda = 1}.
#' It is therefore also equivalent to the McDonald (Mc)/Beta Power distribution
#' (\code{\link{pmc}}) with \eqn{\lambda = 1}.
#'
#' The function likely calls R's underlying \code{pbeta} function but ensures
#' consistent parameter recycling and handling within the C++ environment,
#' matching the style of other functions in the related families.
#'
#' @references
#' Johnson, N. L., Kotz, S., & Balakrishnan, N. (1995). *Continuous Univariate
#' Distributions, Volume 2* (2nd ed.). Wiley.
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#'
#' @seealso
#' \code{\link[stats]{pbeta}} (standard R implementation),
#' \code{\link{pgkw}} (parent distribution CDF),
#' \code{\link{pmc}} (McDonald/Beta Power CDF),
#' \code{dbeta_}, \code{qbeta_}, \code{rbeta_} (other functions for this parameterization, if they exist).
#'
#' @examples
#' \donttest{
#' # Example values
#' q_vals <- c(0.2, 0.5, 0.8)
#' gamma_par <- 2.0 # Corresponds to shape1
#' delta_par <- 3.0 # Corresponds to shape2 - 1
#' shape1 <- gamma_par
#' shape2 <- delta_par + 1
#'
#' # Calculate CDF using pbeta_
#' probs <- pbeta_(q_vals, gamma_par, delta_par)
#' print(probs)
#'
#' # Compare with stats::pbeta
#' probs_stats <- stats::pbeta(q_vals, shape1 = shape1, shape2 = shape2)
#' print(paste("Max difference vs stats::pbeta:", max(abs(probs - probs_stats))))
#'
#' # Compare with pgkw setting alpha=1, beta=1, lambda=1
#' probs_gkw <- pgkw(q_vals, alpha = 1.0, beta = 1.0, gamma = gamma_par,
#'                   delta = delta_par, lambda = 1.0)
#' print(paste("Max difference vs pgkw:", max(abs(probs - probs_gkw))))
#'
#' # Compare with pmc setting lambda=1
#' probs_mc <- pmc(q_vals, gamma = gamma_par, delta = delta_par, lambda = 1.0)
#' print(paste("Max difference vs pmc:", max(abs(probs - probs_mc))))
#'
#' # Calculate upper tail P(X > q)
#' probs_upper <- pbeta_(q_vals, gamma_par, delta_par, lower_tail = FALSE)
#' print(probs_upper)
#' print(stats::pbeta(q_vals, shape1, shape2, lower.tail = FALSE))
#'
#' # Calculate log CDF
#' log_probs <- pbeta_(q_vals, gamma_par, delta_par, log_p = TRUE)
#' print(log_probs)
#' print(stats::pbeta(q_vals, shape1, shape2, log.p = TRUE))
#'
#' # Plot the CDF
#' curve_q <- seq(0.001, 0.999, length.out = 200)
#' curve_p <- pbeta_(curve_q, gamma = 2, delta = 3) # Beta(2, 4)
#' plot(curve_q, curve_p, type = "l", main = "Beta(2, 4) CDF via pbeta_",
#'      xlab = "q", ylab = "F(q)", col = "blue")
#' curve(stats::pbeta(x, 2, 4), add=TRUE, col="red", lty=2)
#' legend("bottomright", legend=c("pbeta_(gamma=2, delta=3)", "stats::pbeta(shape1=2, shape2=4)"),
#'        col=c("blue", "red"), lty=c(1,2), bty="n")
#'
#' }
#'
#' @export
pbeta_ <- function(q, gamma, delta, lower_tail = TRUE, log_p = FALSE) {
    .Call(`_gkwreg_pbeta_`, q, gamma, delta, lower_tail, log_p)
}

#' @title Quantile Function of the Beta Distribution (gamma, delta+1 Parameterization)
#' @author Lopes, J. E.
#' @keywords distribution quantile beta
#'
#' @description
#' Computes the quantile function (inverse CDF) for the standard Beta
#' distribution, using a parameterization common in generalized distribution
#' families. It finds the value \code{q} such that \eqn{P(X \le q) = p}. The
#' distribution is parameterized by \code{gamma} (\eqn{\gamma}) and \code{delta}
#' (\eqn{\delta}), corresponding to the standard Beta distribution with shape
#' parameters \code{shape1 = gamma} and \code{shape2 = delta + 1}.
#'
#' @param p Vector of probabilities (values between 0 and 1).
#' @param gamma First shape parameter (\code{shape1}), \eqn{\gamma > 0}. Can be a
#'   scalar or a vector. Default: 1.0.
#' @param delta Second shape parameter is \code{delta + 1} (\code{shape2}), requires
#'   \eqn{\delta \ge 0} so that \code{shape2 >= 1}. Can be a scalar or a vector.
#'   Default: 0.0 (leading to \code{shape2 = 1}).
#' @param lower_tail Logical; if \code{TRUE} (default), probabilities are \eqn{p = P(X \le q)},
#'   otherwise, probabilities are \eqn{p = P(X > q)}.
#' @param log_p Logical; if \code{TRUE}, probabilities \code{p} are given as
#'   \eqn{\log(p)}. Default: \code{FALSE}.
#'
#' @return A vector of quantiles corresponding to the given probabilities \code{p}.
#'   The length of the result is determined by the recycling rule applied to
#'   the arguments (\code{p}, \code{gamma}, \code{delta}).
#'   Returns:
#'   \itemize{
#'     \item \code{0} for \code{p = 0} (or \code{p = -Inf} if \code{log_p = TRUE},
#'           when \code{lower_tail = TRUE}).
#'     \item \code{1} for \code{p = 1} (or \code{p = 0} if \code{log_p = TRUE},
#'           when \code{lower_tail = TRUE}).
#'     \item \code{NaN} for \code{p < 0} or \code{p > 1} (or corresponding log scale).
#'     \item \code{NaN} for invalid parameters (e.g., \code{gamma <= 0},
#'           \code{delta < 0}).
#'   }
#'   Boundary return values are adjusted accordingly for \code{lower_tail = FALSE}.
#'
#' @details
#' This function computes the quantiles of a Beta distribution with parameters
#' \code{shape1 = gamma} and \code{shape2 = delta + 1}. It is equivalent to
#' calling \code{stats::qbeta(p, shape1 = gamma, shape2 = delta + 1,
#' lower.tail = lower_tail, log.p = log_p)}.
#'
#' This distribution arises as a special case of the five-parameter
#' Generalized Kumaraswamy (GKw) distribution (\code{\link{qgkw}}) obtained
#' by setting \eqn{\alpha = 1}, \eqn{\beta = 1}, and \eqn{\lambda = 1}.
#' It is therefore also equivalent to the McDonald (Mc)/Beta Power distribution
#' (\code{\link{qmc}}) with \eqn{\lambda = 1}.
#'
#' The function likely calls R's underlying \code{qbeta} function but ensures
#' consistent parameter recycling and handling within the C++ environment,
#' matching the style of other functions in the related families. Boundary
#' conditions (p=0, p=1) are handled explicitly.
#'
#' @references
#' Johnson, N. L., Kotz, S., & Balakrishnan, N. (1995). *Continuous Univariate
#' Distributions, Volume 2* (2nd ed.). Wiley.
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#'
#' @seealso
#' \code{\link[stats]{qbeta}} (standard R implementation),
#' \code{\link{qgkw}} (parent distribution quantile function),
#' \code{\link{qmc}} (McDonald/Beta Power quantile function),
#' \code{dbeta_}, \code{pbeta_}, \code{rbeta_} (other functions for this parameterization, if they exist).
#'
#' @examples
#' \donttest{
#' # Example values
#' p_vals <- c(0.1, 0.5, 0.9)
#' gamma_par <- 2.0 # Corresponds to shape1
#' delta_par <- 3.0 # Corresponds to shape2 - 1
#' shape1 <- gamma_par
#' shape2 <- delta_par + 1
#'
#' # Calculate quantiles using qbeta_
#' quantiles <- qbeta_(p_vals, gamma_par, delta_par)
#' print(quantiles)
#'
#' # Compare with stats::qbeta
#' quantiles_stats <- stats::qbeta(p_vals, shape1 = shape1, shape2 = shape2)
#' print(paste("Max difference vs stats::qbeta:", max(abs(quantiles - quantiles_stats))))
#'
#' # Compare with qgkw setting alpha=1, beta=1, lambda=1
#' quantiles_gkw <- qgkw(p_vals, alpha = 1.0, beta = 1.0, gamma = gamma_par,
#'                       delta = delta_par, lambda = 1.0)
#' print(paste("Max difference vs qgkw:", max(abs(quantiles - quantiles_gkw))))
#'
#' # Compare with qmc setting lambda=1
#' quantiles_mc <- qmc(p_vals, gamma = gamma_par, delta = delta_par, lambda = 1.0)
#' print(paste("Max difference vs qmc:", max(abs(quantiles - quantiles_mc))))
#'
#' # Calculate quantiles for upper tail
#' quantiles_upper <- qbeta_(p_vals, gamma_par, delta_par, lower_tail = FALSE)
#' print(quantiles_upper)
#' print(stats::qbeta(p_vals, shape1, shape2, lower.tail = FALSE))
#'
#' # Calculate quantiles from log probabilities
#' log_p_vals <- log(p_vals)
#' quantiles_logp <- qbeta_(log_p_vals, gamma_par, delta_par, log_p = TRUE)
#' print(quantiles_logp)
#' print(stats::qbeta(log_p_vals, shape1, shape2, log.p = TRUE))
#'
#' # Verify inverse relationship with pbeta_
#' p_check <- 0.75
#' q_calc <- qbeta_(p_check, gamma_par, delta_par)
#' p_recalc <- pbeta_(q_calc, gamma_par, delta_par)
#' print(paste("Original p:", p_check, " Recalculated p:", p_recalc))
#' # abs(p_check - p_recalc) < 1e-9 # Should be TRUE
#'
#' # Boundary conditions
#' print(qbeta_(c(0, 1), gamma_par, delta_par)) # Should be 0, 1
#' print(qbeta_(c(-Inf, 0), gamma_par, delta_par, log_p = TRUE)) # Should be 0, 1
#'
#' }
#'
#' @export
qbeta_ <- function(p, gamma, delta, lower_tail = TRUE, log_p = FALSE) {
    .Call(`_gkwreg_qbeta_`, p, gamma, delta, lower_tail, log_p)
}

#' @title Random Generation for the Beta Distribution (gamma, delta+1 Parameterization)
#' @author Lopes, J. E.
#' @keywords distribution random beta
#'
#' @description
#' Generates random deviates from the standard Beta distribution, using a
#' parameterization common in generalized distribution families. The distribution
#' is parameterized by \code{gamma} (\eqn{\gamma}) and \code{delta} (\eqn{\delta}),
#' corresponding to the standard Beta distribution with shape parameters
#' \code{shape1 = gamma} and \code{shape2 = delta + 1}. This is a special case
#' of the Generalized Kumaraswamy (GKw) distribution where \eqn{\alpha = 1},
#' \eqn{\beta = 1}, and \eqn{\lambda = 1}.
#'
#' @param n Number of observations. If \code{length(n) > 1}, the length is
#'   taken to be the number required. Must be a non-negative integer.
#' @param gamma First shape parameter (\code{shape1}), \eqn{\gamma > 0}. Can be a
#'   scalar or a vector. Default: 1.0.
#' @param delta Second shape parameter is \code{delta + 1} (\code{shape2}), requires
#'   \eqn{\delta \ge 0} so that \code{shape2 >= 1}. Can be a scalar or a vector.
#'   Default: 0.0 (leading to \code{shape2 = 1}, i.e., Uniform).
#'
#' @return A numeric vector of length \code{n} containing random deviates from the
#'   Beta(\eqn{\gamma, \delta+1}) distribution, with values in (0, 1). The length
#'   of the result is determined by \code{n} and the recycling rule applied to
#'   the parameters (\code{gamma}, \code{delta}). Returns \code{NaN} if parameters
#'   are invalid (e.g., \code{gamma <= 0}, \code{delta < 0}).
#'
#' @details
#' This function generates samples from a Beta distribution with parameters
#' \code{shape1 = gamma} and \code{shape2 = delta + 1}. It is equivalent to
#' calling \code{stats::rbeta(n, shape1 = gamma, shape2 = delta + 1)}.
#'
#' This distribution arises as a special case of the five-parameter
#' Generalized Kumaraswamy (GKw) distribution (\code{\link{rgkw}}) obtained
#' by setting \eqn{\alpha = 1}, \eqn{\beta = 1}, and \eqn{\lambda = 1}.
#' It is therefore also equivalent to the McDonald (Mc)/Beta Power distribution
#' (\code{\link{rmc}}) with \eqn{\lambda = 1}.
#'
#' The function likely calls R's underlying \code{rbeta} function but ensures
#' consistent parameter recycling and handling within the C++ environment,
#' matching the style of other functions in the related families.
#'
#' @references
#' Johnson, N. L., Kotz, S., & Balakrishnan, N. (1995). *Continuous Univariate
#' Distributions, Volume 2* (2nd ed.). Wiley.
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#'
#' Devroye, L. (1986). *Non-Uniform Random Variate Generation*. Springer-Verlag.
#'
#' @seealso
#' \code{\link[stats]{rbeta}} (standard R implementation),
#' \code{\link{rgkw}} (parent distribution random generation),
#' \code{\link{rmc}} (McDonald/Beta Power random generation),
#' \code{dbeta_}, \code{pbeta_}, \code{qbeta_} (other functions for this parameterization, if they exist).
#'
#' @examples
#' \donttest{
#' set.seed(2030) # for reproducibility
#'
#' # Generate 1000 samples using rbeta_
#' gamma_par <- 2.0 # Corresponds to shape1
#' delta_par <- 3.0 # Corresponds to shape2 - 1
#' shape1 <- gamma_par
#' shape2 <- delta_par + 1
#'
#' x_sample <- rbeta_(1000, gamma = gamma_par, delta = delta_par)
#' summary(x_sample)
#'
#' # Compare with stats::rbeta
#' x_sample_stats <- stats::rbeta(1000, shape1 = shape1, shape2 = shape2)
#' # Visually compare histograms or QQ-plots
#' hist(x_sample, main="rbeta_ Sample", freq=FALSE, breaks=30)
#' curve(dbeta_(x, gamma_par, delta_par), add=TRUE, col="red", lwd=2)
#' hist(x_sample_stats, main="stats::rbeta Sample", freq=FALSE, breaks=30)
#' curve(stats::dbeta(x, shape1, shape2), add=TRUE, col="blue", lwd=2)
#' # Compare summary stats (should be similar due to randomness)
#' print(summary(x_sample))
#' print(summary(x_sample_stats))
#'
#' # Compare summary stats with rgkw(alpha=1, beta=1, lambda=1)
#' x_sample_gkw <- rgkw(1000, alpha = 1.0, beta = 1.0, gamma = gamma_par,
#'                      delta = delta_par, lambda = 1.0)
#' print("Summary stats for rgkw(a=1,b=1,l=1) sample:")
#' print(summary(x_sample_gkw))
#'
#' # Compare summary stats with rmc(lambda=1)
#' x_sample_mc <- rmc(1000, gamma = gamma_par, delta = delta_par, lambda = 1.0)
#' print("Summary stats for rmc(l=1) sample:")
#' print(summary(x_sample_mc))
#'
#' }
#'
#' @export
rbeta_ <- function(n, gamma, delta) {
    .Call(`_gkwreg_rbeta_`, n, gamma, delta)
}

#' @title Negative Log-Likelihood for the Beta Distribution (gamma, delta+1 Parameterization)
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize beta
#'
#' @description
#' Computes the negative log-likelihood function for the standard Beta
#' distribution, using a parameterization common in generalized distribution
#' families. The distribution is parameterized by \code{gamma} (\eqn{\gamma}) and
#' \code{delta} (\eqn{\delta}), corresponding to the standard Beta distribution
#' with shape parameters \code{shape1 = gamma} and \code{shape2 = delta + 1}.
#' This function is suitable for maximum likelihood estimation.
#'
#' @param par A numeric vector of length 2 containing the distribution parameters
#'   in the order: \code{gamma} (\eqn{\gamma > 0}), \code{delta} (\eqn{\delta \ge 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a single \code{double} value representing the negative
#'   log-likelihood (\eqn{-\ell(\theta|\mathbf{x})}). Returns \code{Inf}
#'   if any parameter values in \code{par} are invalid according to their
#'   constraints, or if any value in \code{data} is not in the interval (0, 1).
#'
#' @details
#' This function calculates the negative log-likelihood for a Beta distribution
#' with parameters \code{shape1 = gamma} (\eqn{\gamma}) and \code{shape2 = delta + 1} (\eqn{\delta+1}).
#' The probability density function (PDF) is:
#' \deqn{
#' f(x | \gamma, \delta) = \frac{x^{\gamma-1} (1-x)^{\delta}}{B(\gamma, \delta+1)}
#' }
#' for \eqn{0 < x < 1}, where \eqn{B(a,b)} is the Beta function (\code{\link[base]{beta}}).
#' The log-likelihood function \eqn{\ell(\theta | \mathbf{x})} for a sample
#' \eqn{\mathbf{x} = (x_1, \dots, x_n)} is \eqn{\sum_{i=1}^n \ln f(x_i | \theta)}:
#' \deqn{
#' \ell(\theta | \mathbf{x}) = \sum_{i=1}^{n} [(\gamma-1)\ln(x_i) + \delta\ln(1-x_i)] - n \ln B(\gamma, \delta+1)
#' }
#' where \eqn{\theta = (\gamma, \delta)}.
#' This function computes and returns the *negative* log-likelihood, \eqn{-\ell(\theta|\mathbf{x})},
#' suitable for minimization using optimization routines like \code{\link[stats]{optim}}.
#' It is equivalent to the negative log-likelihood of the GKw distribution
#' (\code{\link{llgkw}}) evaluated at \eqn{\alpha=1, \beta=1, \lambda=1}, and also
#' to the negative log-likelihood of the McDonald distribution (\code{\link{llmc}})
#' evaluated at \eqn{\lambda=1}. The term \eqn{\ln B(\gamma, \delta+1)} is typically
#' computed using log-gamma functions (\code{\link[base]{lgamma}}) for numerical stability.
#'
#' @references
#' Johnson, N. L., Kotz, S., & Balakrishnan, N. (1995). *Continuous Univariate
#' Distributions, Volume 2* (2nd ed.). Wiley.
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#'
#' @seealso
#' \code{\link{llgkw}}, \code{\link{llmc}} (related negative log-likelihoods),
#' \code{dbeta_}, \code{pbeta_}, \code{qbeta_}, \code{rbeta_},
#' \code{grbeta} (gradient, if available),
#' \code{hsbeta} (Hessian, if available),
#' \code{\link[stats]{optim}}, \code{\link[base]{lbeta}}.
#'
#' @examples
#' \donttest{
#' # Assuming existence of rbeta_, llbeta, grbeta, hsbeta functions
#'
#' # Generate sample data from a Beta(2, 4) distribution
#' # (gamma=2, delta=3 in this parameterization)
#' set.seed(123)
#' true_par_beta <- c(gamma = 2, delta = 3)
#' sample_data_beta <- rbeta_(100, gamma = true_par_beta[1], delta = true_par_beta[2])
#' hist(sample_data_beta, breaks = 20, main = "Beta(2, 4) Sample")
#'
#' # --- Maximum Likelihood Estimation using optim ---
#' # Initial parameter guess
#' start_par_beta <- c(1.5, 2.5)
#'
#' # Perform optimization (minimizing negative log-likelihood)
#' # Use method="L-BFGS-B" for box constraints (params > 0 / >= 0)
#' mle_result_beta <- stats::optim(par = start_par_beta,
#'                                fn = llbeta, # Use the custom Beta neg-log-likelihood
#'                                method = "L-BFGS-B",
#'                                lower = c(1e-6, 1e-6), # Bounds: gamma>0, delta>=0
#'                                hessian = TRUE,
#'                                data = sample_data_beta)
#'
#' # Check convergence and results
#' if (mle_result_beta$convergence == 0) {
#'   print("Optimization converged successfully.")
#'   mle_par_beta <- mle_result_beta$par
#'   print("Estimated Beta parameters (gamma, delta):")
#'   print(mle_par_beta)
#'   print("True Beta parameters (gamma, delta):")
#'   print(true_par_beta)
#'   cat(sprintf("MLE corresponds approx to Beta(%.2f, %.2f)\n",
#'       mle_par_beta[1], mle_par_beta[2] + 1))
#'
#' } else {
#'   warning("Optimization did not converge!")
#'   print(mle_result_beta$message)
#' }
#'
#' # --- Compare numerical and analytical derivatives (if available) ---
#' # Requires 'numDeriv' package and analytical functions 'grbeta', 'hsbeta'
#' if (mle_result_beta$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE) &&
#'     exists("grbeta") && exists("hsbeta")) {
#'
#'   cat("\nComparing Derivatives at Beta MLE estimates:\n")
#'
#'   # Numerical derivatives of llbeta
#'   num_grad_beta <- numDeriv::grad(func = llbeta, x = mle_par_beta, data = sample_data_beta)
#'   num_hess_beta <- numDeriv::hessian(func = llbeta, x = mle_par_beta, data = sample_data_beta)
#'
#'   # Analytical derivatives (assuming they return derivatives of negative LL)
#'   ana_grad_beta <- grbeta(par = mle_par_beta, data = sample_data_beta)
#'   ana_hess_beta <- hsbeta(par = mle_par_beta, data = sample_data_beta)
#'
#'   # Check differences
#'   cat("Max absolute difference between gradients:\n")
#'   print(max(abs(num_grad_beta - ana_grad_beta)))
#'   cat("Max absolute difference between Hessians:\n")
#'   print(max(abs(num_hess_beta - ana_hess_beta)))
#'
#' } else {
#'    cat("\nSkipping derivative comparison for Beta.\n")
#'    cat("Requires convergence, 'numDeriv' pkg & functions 'grbeta', 'hsbeta'.\n")
#' }
#'
#' }
#'
#' @export
llbeta <- function(par, data) {
    .Call(`_gkwreg_llbeta`, par, data)
}

#' @title Gradient of the Negative Log-Likelihood for the Beta Distribution (gamma, delta+1 Parameterization)
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize gradient beta
#'
#' @description
#' Computes the gradient vector (vector of first partial derivatives) of the
#' negative log-likelihood function for the standard Beta distribution, using
#' a parameterization common in generalized distribution families. The
#' distribution is parameterized by \code{gamma} (\eqn{\gamma}) and \code{delta}
#' (\eqn{\delta}), corresponding to the standard Beta distribution with shape
#' parameters \code{shape1 = gamma} and \code{shape2 = delta + 1}.
#' The gradient is useful for optimization algorithms.
#'
#' @param par A numeric vector of length 2 containing the distribution parameters
#'   in the order: \code{gamma} (\eqn{\gamma > 0}), \code{delta} (\eqn{\delta \ge 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a numeric vector of length 2 containing the partial derivatives
#'   of the negative log-likelihood function \eqn{-\ell(\theta | \mathbf{x})} with
#'   respect to each parameter: \eqn{(-\partial \ell/\partial \gamma, -\partial \ell/\partial \delta)}.
#'   Returns a vector of \code{NaN} if any parameter values are invalid according
#'   to their constraints, or if any value in \code{data} is not in the
#'   interval (0, 1).
#'
#' @details
#' This function calculates the gradient of the negative log-likelihood for a
#' Beta distribution with parameters \code{shape1 = gamma} (\eqn{\gamma}) and
#' \code{shape2 = delta + 1} (\eqn{\delta+1}). The components of the gradient
#' vector (\eqn{-\nabla \ell(\theta | \mathbf{x})}) are:
#'
#' \deqn{
#' -\frac{\partial \ell}{\partial \gamma} = n[\psi(\gamma) - \psi(\gamma+\delta+1)] -
#' \sum_{i=1}^{n}\ln(x_i)
#' }
#' \deqn{
#' -\frac{\partial \ell}{\partial \delta} = n[\psi(\delta+1) - \psi(\gamma+\delta+1)] -
#' \sum_{i=1}^{n}\ln(1-x_i)
#' }
#'
#' where \eqn{\psi(\cdot)} is the digamma function (\code{\link[base]{digamma}}).
#' These formulas represent the derivatives of \eqn{-\ell(\theta)}, consistent with
#' minimizing the negative log-likelihood. They correspond to the relevant components
#' of the general GKw gradient (\code{\link{grgkw}}) evaluated at \eqn{\alpha=1, \beta=1, \lambda=1}.
#' Note the parameterization: the standard Beta shape parameters are \eqn{\gamma} and \eqn{\delta+1}.
#'
#' @references
#' Johnson, N. L., Kotz, S., & Balakrishnan, N. (1995). *Continuous Univariate
#' Distributions, Volume 2* (2nd ed.). Wiley.
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#' (Note: Specific gradient formulas might be derived or sourced from additional references).
#'
#' @seealso
#' \code{\link{grgkw}}, \code{\link{grmc}} (related gradients),
#' \code{\link{llbeta}} (negative log-likelihood function),
#' \code{hsbeta} (Hessian, if available),
#' \code{dbeta_}, \code{pbeta_}, \code{qbeta_}, \code{rbeta_},
#' \code{\link[stats]{optim}},
#' \code{\link[numDeriv]{grad}} (for numerical gradient comparison),
#' \code{\link[base]{digamma}}.
#'
#' @examples
#' \donttest{
#' # Assuming existence of rbeta_, llbeta, grbeta, hsbeta functions
#'
#' # Generate sample data from a Beta(2, 4) distribution
#' # (gamma=2, delta=3 in this parameterization)
#' set.seed(123)
#' true_par_beta <- c(gamma = 2, delta = 3)
#' sample_data_beta <- rbeta_(100, gamma = true_par_beta[1], delta = true_par_beta[2])
#' hist(sample_data_beta, breaks = 20, main = "Beta(2, 4) Sample")
#'
#' # --- Find MLE estimates ---
#' start_par_beta <- c(1.5, 2.5)
#' mle_result_beta <- stats::optim(par = start_par_beta,
#'                                fn = llbeta,
#'                                gr = grbeta, # Use analytical gradient
#'                                method = "L-BFGS-B",
#'                                lower = c(1e-6, 1e-6), # Bounds: gamma>0, delta>=0
#'                                hessian = TRUE,
#'                                data = sample_data_beta)
#'
#' # --- Compare analytical gradient to numerical gradient ---
#' if (mle_result_beta$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE)) {
#'
#'   mle_par_beta <- mle_result_beta$par
#'   cat("\nComparing Gradients for Beta at MLE estimates:\n")
#'
#'   # Numerical gradient of llbeta
#'   num_grad_beta <- numDeriv::grad(func = llbeta, x = mle_par_beta, data = sample_data_beta)
#'
#'   # Analytical gradient from grbeta
#'   ana_grad_beta <- grbeta(par = mle_par_beta, data = sample_data_beta)
#'
#'   cat("Numerical Gradient (Beta):\n")
#'   print(num_grad_beta)
#'   cat("Analytical Gradient (Beta):\n")
#'   print(ana_grad_beta)
#'
#'   # Check differences
#'   cat("Max absolute difference between Beta gradients:\n")
#'   print(max(abs(num_grad_beta - ana_grad_beta)))
#'
#' } else {
#'   cat("\nSkipping Beta gradient comparison.\n")
#' }
#'
#' # Example with Hessian comparison (if hsbeta exists)
#' if (mle_result_beta$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE) && exists("hsbeta")) {
#'
#'   num_hess_beta <- numDeriv::hessian(func = llbeta, x = mle_par_beta, data = sample_data_beta)
#'   ana_hess_beta <- hsbeta(par = mle_par_beta, data = sample_data_beta)
#'   cat("\nMax absolute difference between Beta Hessians:\n")
#'   print(max(abs(num_hess_beta - ana_hess_beta)))
#'
#' }
#'
#' }
#'
#' @export
grbeta <- function(par, data) {
    .Call(`_gkwreg_grbeta`, par, data)
}

#' @title Hessian Matrix of the Negative Log-Likelihood for the Beta Distribution (gamma, delta+1 Parameterization)
#' @author Lopes, J. E.
#' @keywords distribution likelihood optimize hessian beta
#'
#' @description
#' Computes the analytic 2x2 Hessian matrix (matrix of second partial derivatives)
#' of the negative log-likelihood function for the standard Beta distribution,
#' using a parameterization common in generalized distribution families. The
#' distribution is parameterized by \code{gamma} (\eqn{\gamma}) and \code{delta}
#' (\eqn{\delta}), corresponding to the standard Beta distribution with shape
#' parameters \code{shape1 = gamma} and \code{shape2 = delta + 1}. The Hessian
#' is useful for estimating standard errors and in optimization algorithms.
#'
#' @param par A numeric vector of length 2 containing the distribution parameters
#'   in the order: \code{gamma} (\eqn{\gamma > 0}), \code{delta} (\eqn{\delta \ge 0}).
#' @param data A numeric vector of observations. All values must be strictly
#'   between 0 and 1 (exclusive).
#'
#' @return Returns a 2x2 numeric matrix representing the Hessian matrix of the
#'   negative log-likelihood function, \eqn{-\partial^2 \ell / (\partial \theta_i \partial \theta_j)},
#'   where \eqn{\theta = (\gamma, \delta)}.
#'   Returns a 2x2 matrix populated with \code{NaN} if any parameter values are
#'   invalid according to their constraints, or if any value in \code{data} is
#'   not in the interval (0, 1).
#'
#' @details
#' This function calculates the analytic second partial derivatives of the
#' negative log-likelihood function (\eqn{-\ell(\theta|\mathbf{x})}) for a Beta
#' distribution with parameters \code{shape1 = gamma} (\eqn{\gamma}) and
#' \code{shape2 = delta + 1} (\eqn{\delta+1}). The components of the Hessian
#' matrix (\eqn{-\mathbf{H}(\theta)}) are:
#'
#' \deqn{
#' -\frac{\partial^2 \ell}{\partial \gamma^2} = n[\psi'(\gamma) - \psi'(\gamma+\delta+1)]
#' }
#' \deqn{
#' -\frac{\partial^2 \ell}{\partial \gamma \partial \delta} = -n\psi'(\gamma+\delta+1)
#' }
#' \deqn{
#' -\frac{\partial^2 \ell}{\partial \delta^2} = n[\psi'(\delta+1) - \psi'(\gamma+\delta+1)]
#' }
#'
#' where \eqn{\psi'(\cdot)} is the trigamma function (\code{\link[base]{trigamma}}).
#' These formulas represent the second derivatives of \eqn{-\ell(\theta)},
#' consistent with minimizing the negative log-likelihood. They correspond to
#' the relevant 2x2 submatrix of the general GKw Hessian (\code{\link{hsgkw}})
#' evaluated at \eqn{\alpha=1, \beta=1, \lambda=1}. Note the parameterization
#' difference from the standard Beta distribution (\code{shape2 = delta + 1}).
#'
#' The returned matrix is symmetric.
#'
#' @references
#' Johnson, N. L., Kotz, S., & Balakrishnan, N. (1995). *Continuous Univariate
#' Distributions, Volume 2* (2nd ed.). Wiley.
#'
#' Cordeiro, G. M., & de Castro, M. (2011). A new family of generalized
#' distributions. *Journal of Statistical Computation and Simulation*,
#'
#' (Note: Specific Hessian formulas might be derived or sourced from additional references).
#'
#' @seealso
#' \code{\link{hsgkw}}, \code{\link{hsmc}} (related Hessians),
#' \code{\link{llbeta}} (negative log-likelihood function),
#' \code{grbeta} (gradient, if available),
#' \code{dbeta_}, \code{pbeta_}, \code{qbeta_}, \code{rbeta_},
#' \code{\link[stats]{optim}},
#' \code{\link[numDeriv]{hessian}} (for numerical Hessian comparison),
#' \code{\link[base]{trigamma}}.
#'
#' @examples
#' \donttest{
#' # Assuming existence of rbeta_, llbeta, grbeta, hsbeta functions
#'
#' # Generate sample data from a Beta(2, 4) distribution
#' # (gamma=2, delta=3 in this parameterization)
#' set.seed(123)
#' true_par_beta <- c(gamma = 2, delta = 3)
#' sample_data_beta <- rbeta_(100, gamma = true_par_beta[1], delta = true_par_beta[2])
#' hist(sample_data_beta, breaks = 20, main = "Beta(2, 4) Sample")
#'
#' # --- Find MLE estimates ---
#' start_par_beta <- c(1.5, 2.5)
#' mle_result_beta <- stats::optim(par = start_par_beta,
#'                                fn = llbeta,
#'                                gr = if (exists("grbeta")) grbeta else NULL,
#'                                method = "L-BFGS-B",
#'                                lower = c(1e-6, 1e-6), # Bounds: gamma>0, delta>=0
#'                                hessian = TRUE, # Ask optim for numerical Hessian
#'                                data = sample_data_beta)
#'
#' # --- Compare analytical Hessian to numerical Hessian ---
#' if (mle_result_beta$convergence == 0 &&
#'     requireNamespace("numDeriv", quietly = TRUE) &&
#'     exists("hsbeta")) {
#'
#'   mle_par_beta <- mle_result_beta$par
#'   cat("\nComparing Hessians for Beta at MLE estimates:\n")
#'
#'   # Numerical Hessian of llbeta
#'   num_hess_beta <- numDeriv::hessian(func = llbeta, x = mle_par_beta, data = sample_data_beta)
#'
#'   # Analytical Hessian from hsbeta
#'   ana_hess_beta <- hsbeta(par = mle_par_beta, data = sample_data_beta)
#'
#'   cat("Numerical Hessian (Beta):\n")
#'   print(round(num_hess_beta, 4))
#'   cat("Analytical Hessian (Beta):\n")
#'   print(round(ana_hess_beta, 4))
#'
#'   # Check differences
#'   cat("Max absolute difference between Beta Hessians:\n")
#'   print(max(abs(num_hess_beta - ana_hess_beta)))
#'
#'   # Optional: Use analytical Hessian for Standard Errors
#'   # tryCatch({
#'   #   cov_matrix_beta <- solve(ana_hess_beta) # ana_hess_beta is already Hessian of negative LL
#'   #   std_errors_beta <- sqrt(diag(cov_matrix_beta))
#'   #   cat("Std. Errors from Analytical Beta Hessian:\n")
#'   #   print(std_errors_beta)
#'   # }, error = function(e) {
#'   #   warning("Could not invert analytical Beta Hessian: ", e$message)
#'   # })
#'
#' } else {
#'   cat("\nSkipping Beta Hessian comparison.\n")
#'   cat("Requires convergence, 'numDeriv' package, and function 'hsbeta'.\n")
#' }
#'
#' }
#'
#' @export
hsbeta <- function(par, data) {
    .Call(`_gkwreg_hsbeta`, par, data)
}

#' @title Enhanced Newton-Raphson Optimization for GKw Family Distributions
#' @author Enhanced by Lopes, J. E.
#' @keywords distribution optimization likelihood mle newton-raphson kumaraswamy mcdonald beta
#'
#' @description
#' An industrial-strength implementation of maximum likelihood estimation (MLE)
#' for the parameters of any distribution in the Generalized Kumaraswamy (GKw) family.
#' This function incorporates multiple advanced numerical techniques including trust region
#' methods, eigenvalue-based regularization, adaptive scaling, and sophisticated line
#' search to ensure robust convergence even for challenging datasets or extreme parameter values.
#'
#' @details
#' This enhanced algorithm provides robust parameter estimation for the Generalized
#' Kumaraswamy distribution and its subfamilies. The function implements several
#' advanced numerical optimization techniques to maximize the likelihood function
#' reliably even in difficult cases.
#'
#' \subsection{The GKw Family of Distributions}{
#' The Generalized Kumaraswamy (GKw) distribution, introduced by Carrasco, Ferrari,
#' and Cordeiro (2010), is a flexible five-parameter continuous distribution defined
#' on the standard unit interval (0,1). Its probability density function is given by:
#'
#' \deqn{f(x; \alpha, \beta, \gamma, \delta, \lambda) = \frac{\lambda\alpha\beta x^{\alpha-1}}{B(\gamma, \delta+1)}(1-x^{\alpha})^{\beta-1}[1-(1-x^{\alpha})^{\beta}]^{\gamma\lambda-1}\{1-[1-(1-x^{\alpha})^{\beta}]^{\lambda}\}^{\delta}}
#'
#' where \eqn{\alpha, \beta, \gamma, \lambda > 0} and \eqn{\delta \geq 0} are the model
#' parameters, and \eqn{B(\gamma, \delta+1)} is the beta function.
#'
#' The GKw distribution encompasses several important special cases:
#' \itemize{
#'   \item\bold{GKw} (5 parameters): \eqn{\alpha, \beta, \gamma, \delta, \lambda}
#'   \item\bold{BKw} (4 parameters): \eqn{\alpha, \beta, \gamma, \delta} (with \eqn{\lambda = 1})
#'   \item\bold{KKw} (4 parameters): \eqn{\alpha, \beta, \delta, \lambda} (with \eqn{\gamma = 1})
#'   \item\bold{EKw} (3 parameters): \eqn{\alpha, \beta, \lambda} (with \eqn{\gamma = 1, \delta = 0})
#'   \item\bold{Mc}  (3 parameters): \eqn{\gamma, \delta, \lambda} (with \eqn{\alpha = 1, \beta = 1})
#'   \item\bold{Kw}  (2 parameters): \eqn{\alpha, \beta} (with \eqn{\gamma = 1, \delta = 0, \lambda = 1})
#'   \item\bold{Beta}(2 parameters): \eqn{\gamma, \delta} (with \eqn{\alpha = 1, \beta = 1, \lambda = 1})
#' }
#' }
#'
#' \subsection{Trust Region Method with Levenberg-Marquardt Algorithm}{
#' The trust region approach restricts parameter updates to a region where the quadratic
#' approximation of the objective function is trusted to be accurate. This algorithm
#' implements the Levenberg-Marquardt variant, which solves the subproblem:
#'
#' \deqn{\min_p m_k(p) = -\nabla \ell(\theta_k)^T p + \frac{1}{2}p^T H_k p}
#' \deqn{\text{subject to } \|p\| \leq \Delta_k}
#'
#' where \eqn{\nabla \ell(\theta_k)} is the gradient, \eqn{H_k} is the Hessian, and \eqn{\Delta_k}
#' is the trust region radius at iteration \eqn{k}.
#'
#' The Levenberg-Marquardt approach adds a regularization parameter \eqn{\lambda} to the
#' Hessian, solving:
#'
#' \deqn{(H_k + \lambda I)p = -\nabla \ell(\theta_k)}
#'
#' The parameter \eqn{\lambda} controls the step size and direction:
#' \itemize{
#'   \item When \eqn{\lambda} is large, the step approaches a scaled steepest descent direction.
#'   \item When \eqn{\lambda} is small, the step approaches the Newton direction.
#' }
#'
#' The algorithm dynamically adjusts \eqn{\lambda} based on the agreement between the quadratic model and the actual function:
#'
#' \deqn{\rho_k = \frac{f(\theta_k) - f(\theta_k + p_k)}{m_k(0) - m_k(p_k)}}
#'
#' The trust region radius is updated according to:
#' \itemize{
#'   \item If \eqn{\rho_k < 0.25}, reduce the radius: \eqn{\Delta_{k+1} = 0.5\Delta_k}
#'   \item If \eqn{\rho_k > 0.75} and \eqn{\|p_k\| \approx \Delta_k}, increase the radius: \eqn{\Delta_{k+1} = 2\Delta_k}
#'   \item Otherwise, leave the radius unchanged: \eqn{\Delta_{k+1} = \Delta_k}
#' }
#'
#' The step is accepted if \eqn{\rho_k > \eta} (typically \eqn{\eta = 0.1}).
#' }
#'
#' \subsection{Eigenvalue-Based Hessian Regularization}{
#' For the Newton-Raphson method to converge, the Hessian matrix must be positive definite.
#' This algorithm uses eigendecomposition to create a positive definite approximation that
#' preserves the Hessian's structure:
#'
#' \deqn{H = Q\Lambda Q^T}
#'
#' where \eqn{Q} contains the eigenvectors and \eqn{\Lambda} is a diagonal matrix of eigenvalues.
#'
#' The regularized Hessian is constructed by:
#'
#' \deqn{\tilde{H} = Q\tilde{\Lambda}Q^T}
#'
#' where \eqn{\tilde{\Lambda}} contains modified eigenvalues:
#'
#' \deqn{\tilde{\lambda}_i = \max(\lambda_i, \epsilon)}
#'
#' with \eqn{\epsilon} being a small positive threshold (typically \eqn{10^{-6}}).
#'
#' This approach is superior to diagonal loading (\eqn{H + \lambda I}) as it:
#' \itemize{
#'   \item Preserves the eigenvector structure of the original Hessian
#'   \item Minimally modifies the eigenvalues needed to ensure positive definiteness
#'   \item Better maintains the directional information in the Hessian
#' }
#' }
#'
#' \subsection{Parameter Scaling for Numerical Stability}{
#' When parameters have widely different magnitudes, optimization can become numerically
#' unstable. The adaptive scaling system transforms the parameter space to improve conditioning:
#'
#' \deqn{\theta_i^{scaled} = s_i \theta_i}
#'
#' where scaling factors \eqn{s_i} are determined by:
#' \itemize{
#'   \item For large parameters (\eqn{|\theta_i| > 100}): \eqn{s_i = 100/|\theta_i|}
#'   \item For small parameters (\eqn{0 < |\theta_i| < 0.01}): \eqn{s_i = 0.01/|\theta_i|}
#'   \item Otherwise: \eqn{s_i = 1}
#' }
#'
#' The optimization is performed in the scaled space, with appropriate transformations
#' for the gradient and Hessian:
#'
#' \deqn{\nabla \ell(\theta^{scaled})_i = \frac{1}{s_i}\nabla \ell(\theta)_i}
#' \deqn{H(\theta^{scaled})_{ij} = \frac{1}{s_i s_j}H(\theta)_{ij}}
#'
#' The final results are back-transformed to the original parameter space before being returned.
#' }
#'
#' \subsection{Line Search with Wolfe Conditions}{
#' The line search procedure ensures sufficient decrease in the objective function when
#' taking a step in the search direction. The implementation uses Wolfe conditions which
#' include both:
#'
#' 1. Sufficient decrease (Armijo) condition:
#' \deqn{f(\theta_k + \alpha p_k) \leq f(\theta_k) + c_1 \alpha \nabla f(\theta_k)^T p_k}
#'
#' 2. Curvature condition:
#' \deqn{|\nabla f(\theta_k + \alpha p_k)^T p_k| \leq c_2 |\nabla f(\theta_k)^T p_k|}
#'
#' where \eqn{0 < c_1 < c_2 < 1}, typically \eqn{c_1 = 10^{-4}} and \eqn{c_2 = 0.9}.
#'
#' The step length \eqn{\alpha} is determined using polynomial interpolation:
#' \itemize{
#'   \item First iteration: quadratic interpolation
#'   \item Subsequent iterations: cubic interpolation using function and derivative values
#' }
#'
#' The cubic polynomial model has the form:
#' \deqn{a\alpha^3 + b\alpha^2 + c\alpha + d}
#'
#' The algorithm computes coefficients from values at two points, then finds the minimizer
#' of this polynomial subject to bounds to ensure convergence.
#' }
#'
#' \subsection{Adaptive Numerical Differentiation}{
#' When analytical derivatives are unreliable, the algorithm uses numerical differentiation
#' with adaptive step sizes based on parameter magnitudes:
#'
#' \deqn{h_i = \max(h_{min}, \min(h_{base}, h_{base} \cdot |\theta_i|))}
#'
#' where \eqn{h_{min}} is a minimum step size (typically \eqn{10^{-8}}), \eqn{h_{base}}
#' is a base step size (typically \eqn{10^{-5}}), and \eqn{\theta_i} is the parameter value.
#'
#' For computing diagonal Hessian elements, the central difference formula is used:
#'
#' \deqn{\frac{\partial^2 f}{\partial \theta_i^2} \approx \frac{f(\theta + h_i e_i) - 2f(\theta) + f(\theta - h_i e_i)}{h_i^2}}
#'
#' For mixed partial derivatives:
#'
#' \deqn{\frac{\partial^2 f}{\partial \theta_i \partial \theta_j} \approx \frac{f(\theta + h_i e_i + h_j e_j) - f(\theta + h_i e_i - h_j e_j) - f(\theta - h_i e_i + h_j e_j) + f(\theta - h_i e_i - h_j e_j)}{4h_i h_j}}
#'
#' The algorithm validates numerical differentiation by comparing with existing gradients
#' and adaptively adjusts step sizes when discrepancies are detected.
#' }
#'
#' \subsection{Stochastic Perturbation}{
#' To escape flat regions or local minima, the algorithm implements controlled stochastic
#' perturbation when progress stalls (detected by monitoring gradient norm changes):
#'
#' \deqn{\theta_i^{new} = \theta_i + \Delta\theta_i}
#'
#' where the perturbation \eqn{\Delta\theta_i} combines:
#' \itemize{
#'   \item A directed component opposite to the gradient: \eqn{-\text{sign}(\nabla \ell_i) \cdot 0.05 \cdot |\theta_i|}
#'   \item A random noise component: \eqn{U(-0.05|\theta_i|, 0.05|\theta_i|)}
#' }
#'
#' The perturbation is applied when:
#' \itemize{
#'   \item The relative change in gradient norm is below a threshold for several consecutive iterations
#'   \item The algorithm appears to be stuck in a non-optimal region
#' }
#'
#' The perturbation is accepted only if it improves the objective function value.
#' }
#'
#' \subsection{Multi-Start Strategy}{
#' For particularly challenging optimization landscapes, the algorithm can employ multiple
#' starting points:
#'
#' \itemize{
#'   \item Initial values are generated using moment-based estimation and domain knowledge about each distribution family
#'   \item Each initial point is randomly perturbed to explore different regions of the parameter space
#'   \item Independent optimization runs are performed from each starting point
#'   \item The best result (based on likelihood value and convergence status) is returned
#' }
#'
#' This approach increases the probability of finding the global optimum or a high-quality
#' local optimum, particularly for complex models with many parameters.
#' }
#'
#' \subsection{Advanced Parameter Initialization}{
#' Intelligent starting values are critical for convergence in complex models. The algorithm
#' uses data-driven initialization based on:
#'
#' \itemize{
#'   \item Method of moments estimators for beta parameters:
#'     \deqn{\alpha + \beta = \frac{\bar{x}(1-\bar{x})}{s^2} - 1}
#'     \deqn{\alpha = (\alpha + \beta)\bar{x}}
#'
#'   \item Transformations to Kumaraswamy parameters:
#'     \deqn{a_{Kw} = \sqrt{\alpha_{Beta}}}
#'     \deqn{b_{Kw} = \sqrt{\beta_{Beta}}}
#'
#'   \item Adjustments based on data skewness (detected via mean relative to 0.5)
#'
#'   \item Corrections based on data dispersion (range relative to (0,1) interval)
#' }
#'
#' The transformations between beta and Kumaraswamy parameters leverage the similarities
#' between these distributions while accounting for their parametric differences.
#' }
#'
#' \subsection{Hybrid Optimization Strategy}{
#' The algorithm can dynamically switch between trust region and Newton-Raphson methods
#' based on optimization progress:
#'
#' \itemize{
#'   \item Early iterations: trust region method for stability and global convergence properties
#'   \item Later iterations (when close to optimum): Newton-Raphson with line search for quadratic convergence rate
#' }
#'
#' The switching criteria are based on iteration count and gradient norm, with additional
#' logic to handle cases where one method consistently fails.
#' }
#'
#' @param start A numeric vector containing initial values for the parameters.
#'   If NULL, automatic initialization is used based on the dataset characteristics.
#'   The length and order must correspond to the selected \code{family}
#'   (e.g., \code{c(alpha, beta, gamma, delta, lambda)} for "gkw"; \code{c(alpha, beta)} for "kw";
#'   \code{c(gamma, delta)} for "beta").
#' @param data A numeric vector containing the observed data. All values must
#'   be strictly between 0 and 1.
#' @param family A character string specifying the distribution family. One of
#'   \code{"gkw"}, \code{"bkw"}, \code{"kkw"}, \code{"ekw"}, \code{"mc"},
#'   \code{"kw"}, or \code{"beta"}. Default: \code{"gkw"}.
#' @param tol Convergence tolerance. The algorithm stops when the Euclidean norm
#'   of the gradient is below this value, or if relative changes in parameters
#'   or the negative log-likelihood are below this threshold across consecutive
#'   iterations. Default: \code{1e-6}.
#' @param max_iter Maximum number of iterations allowed. Default: \code{100}.
#' @param verbose Logical; if \code{TRUE}, prints detailed progress information
#'   during optimization, including iteration number, negative log-likelihood,
#'   gradient norm, and step adjustment details. Default: \code{FALSE}.
#' @param optimization_method Character string specifying the optimization method:
#'   "trust-region" (default), "newton-raphson", or "hybrid" (starts with trust-region,
#'   switches to newton-raphson near convergence).
#' @param enforce_bounds Logical; if \code{TRUE}, parameter values are constrained
#'   to stay within \code{min_param_val}, \code{max_param_val} (and \eqn{\delta \ge 0})
#'   during optimization. Default: \code{TRUE}.
#' @param min_param_val Minimum allowed value for parameters constrained to be
#'   strictly positive (\eqn{\alpha, \beta, \gamma, \lambda}). Default: \code{1e-5}.
#' @param max_param_val Maximum allowed value for all parameters. Default: \code{1e5}.
#' @param adaptive_scaling Logical; if \code{TRUE}, parameters are automatically scaled
#'   to improve numerical stability. Default: \code{TRUE}.
#' @param use_stochastic_perturbation Logical; if \code{TRUE}, applies random perturbations
#'   when optimization stalls. Default: \code{TRUE}.
#' @param get_num_hess Logical; if \code{TRUE}, computes and returns a numerical
#'   approximation of the Hessian at the solution. Default: \code{FALSE}.
#' @param multi_start_attempts Integer specifying the number of different starting points
#'   to try if initial optimization fails to converge. Default: \code{3}.
#' @param eigenvalue_hessian_reg Logical; if \code{TRUE}, uses eigenvalue-based
#'   regularization for the Hessian matrix. Default: \code{TRUE}.
#' @param max_backtrack Integer specifying the maximum number of backtracking steps
#'   in line search. Default: \code{20}.
#' @param initial_trust_radius Initial radius for trust region method. Default: \code{1.0}.
#'
#' @return A list object of class \code{gkw_fit} containing the following components:
#' \item{parameters}{A named numeric vector with the estimated parameters.}
#' \item{loglik}{The maximized value of the log-likelihood function.}
#' \item{iterations}{Number of iterations performed.}
#' \item{converged}{Logical flag indicating whether the algorithm converged successfully.}
#' \item{param_history}{A matrix where rows represent iterations and columns represent parameter values.}
#' \item{loglik_history}{A vector of log-likelihood values at each iteration.}
#' \item{gradient}{The gradient vector at the final parameter estimates.}
#' \item{hessian}{The analytical Hessian matrix at the final parameter estimates.}
#' \item{std_errors}{A named numeric vector of approximate standard errors for the parameters.}
#' \item{aic}{Akaike Information Criterion.}
#' \item{bic}{Bayesian Information Criterion.}
#' \item{aicc}{AIC with small sample correction.}
#' \item{n}{The sample size.}
#' \item{status}{A character string indicating the termination status.}
#' \item{z_values}{A named numeric vector of Z-statistics for parameter significance testing.}
#' \item{p_values}{A named numeric vector of two-sided p-values corresponding to the Z-statistics.}
#' \item{param_names}{A character vector of the parameter names.}
#' \item{family}{The distribution family used.}
#' \item{optimization_method}{The optimization method used.}
#' \item{numeric_hessian}{The numerically approximated Hessian at the solution (if requested).}
#' \item{condition_number}{The condition number of the final Hessian, a measure of parameter identifiability.}
#' \item{scaling_factors}{The scaling factors used for parameters (if adaptive scaling was enabled).}
#'
#' @section Warning:
#' Although this implementation is highly robust, fitting complex distributions can still be challenging.
#' For best results:
#' \itemize{
#'   \item{Try multiple starting values if results seem suboptimal}
#'   \item{Examine diagnostic information carefully, especially condition numbers and standard errors}
#'   \item{Be cautious of parameter estimates at or very near boundaries}
#'   \item{Consider model simplification if convergence is consistently problematic}
#'   \item{For the full GKw model with 5 parameters, convergence may be sensitive to starting values}
#'   \item{High condition numbers (>1e6) may indicate parameter redundancy or weak identifiability}
#' }
#'
#' @references
#' Carrasco, J. M. F., Ferrari, S. L. P., & Cordeiro, G. M. (2010). A new generalized Kumaraswamy
#' distribution. arXiv preprint arXiv:1004.0911.
#'
#' Nocedal, J., & Wright, S. J. (2006). Numerical Optimization (2nd ed.). Springer.
#'
#' Conn, A. R., Gould, N. I. M., & Toint, P. L. (2000). Trust Region Methods. MPS-SIAM Series on Optimization.
#'
#' Kumaraswamy, P. (1980). A generalized probability density function for double-bounded
#' random processes. Journal of Hydrology, 46(1-2), 79-88.
#'
#' @examples
#' \donttest{
#' # Generate sample data from a Beta(2,5) distribution for testing
#' set.seed(123)
#' sample_data <- rbeta_(200, 2, 5)
#'
#' # Automatic initialization (recommended for beginners)
#' result_auto <- nrgkw(NULL, sample_data, family = "beta", verbose = FALSE)
#' print(result_auto$parameters)
#' print(result_auto$loglik)
#'
#' # Compare different optimization methods
#' methods <- c("trust-region", "newton-raphson", "hybrid")
#' results <- list()
#'
#' for (method in methods) {
#'   results[[method]] <- nrgkw(NULL, sample_data, family = "beta",
#'                                optimization_method = method)
#'   cat(sprintf("Method: %s, AIC: %.4f\n", method, results[[method]]$aic))
#' }
#'
#' # Fit the full GKw model with diagnostic information
#' gkw_result <- nrgkw(NULL, sample_data, family = "gkw",
#'                       verbose = FALSE, get_num_hess = TRUE)
#'
#' # Examine parameter identifiability through condition number
#' cat(sprintf("Condition number: %.2e\n", gkw_result$condition_number))
#' print(gkw_result)
#'
#' # Compare with simpler models using information criteria
#' cat("Information criteria comparison:\n")
#' cat(sprintf("GKw: AIC=%.4f, BIC=%.4f\n", gkw_result$aic, gkw_result$bic))
#' cat(sprintf("Beta: AIC=%.4f, BIC=%.4f\n",
#'            results[["trust-region"]]$aic, results[["trust-region"]]$bic))
#'}
#' @export
nrgkw <- function(start = NULL, data = as.numeric( c()), family = "gkw", tol = 1e-6, max_iter = 100L, verbose = FALSE, optimization_method = "trust-region", enforce_bounds = TRUE, min_param_val = 1e-5, max_param_val = 1e5, adaptive_scaling = TRUE, use_stochastic_perturbation = TRUE, get_num_hess = FALSE, multi_start_attempts = 3L, eigenvalue_hessian_reg = TRUE, max_backtrack = 20L, initial_trust_radius = 1.0) {
    .Call(`_gkwreg_nrgkw`, start, data, family, tol, max_iter, verbose, optimization_method, enforce_bounds, min_param_val, max_param_val, adaptive_scaling, use_stochastic_perturbation, get_num_hess, multi_start_attempts, eigenvalue_hessian_reg, max_backtrack, initial_trust_radius)
}

#' @title Calculate Parameters for the Generalized Kumaraswamy Distribution
#'
#' @description
#' Computes the parameters (alpha, beta, gamma, delta, lambda) for each observation based on design matrices and regression coefficients,
#' applying a positive link function as specified by link types and scale factors.
#'
#' @param X1 NumericMatrix design matrix for alpha.
#' @param X2 NumericMatrix design matrix for beta.
#' @param X3 NumericMatrix design matrix for gamma.
#' @param X4 NumericMatrix design matrix for delta.
#' @param X5 NumericMatrix design matrix for lambda.
#' @param beta1 NumericVector regression coefficients for X1.
#' @param beta2 NumericVector regression coefficients for X2.
#' @param beta3 NumericVector regression coefficients for X3.
#' @param beta4 NumericVector regression coefficients for X4.
#' @param beta5 NumericVector regression coefficients for X5.
#' @param link_types IntegerVector containing the link function type for each parameter.
#' @param scale_factors NumericVector with scale factors for each parameter.
#' @param family String specifying the distribution family (default: "gkw").
#'
#' @return NumericMatrix with n rows and 5 columns corresponding to the calculated parameters.
#' @export
calculateParameters <- function(X1, X2, X3, X4, X5, beta1, beta2, beta3, beta4, beta5, link_types, scale_factors, family = "gkw") {
    .Call(`_gkwreg_calculateParameters`, X1, X2, X3, X4, X5, beta1, beta2, beta3, beta4, beta5, link_types, scale_factors, family)
}

#' @title Calculate Means for Distribution
#'
#' @description
#' Computes the mean of the distribution for each observation using numerical integration
#' (quadrature) with caching to avoid redundant calculations.
#'
#' @param params NumericMatrix with parameters (columns: alpha, beta, gamma, delta, lambda).
#' @param family String specifying the distribution family (default: "gkw").
#'
#' @return NumericVector containing the calculated means for each observation.
#' @export
calculateMeans <- function(params, family = "gkw") {
    .Call(`_gkwreg_calculateMeans`, params, family)
}

#' @title Calculate Densities for Distribution
#'
#' @description
#' Evaluates the density (or its logarithm) for each observation given the parameters.
#'
#' @param y NumericVector of observations.
#' @param params NumericMatrix with parameters (columns: alpha, beta, gamma, delta, lambda).
#' @param family String specifying the distribution family (default: "gkw").
#' @param log Logical indicating whether to return the log-density (default FALSE).
#'
#' @return NumericVector containing the evaluated densities.
#' @export
calculateDensities <- function(y, params, family = "gkw", log = FALSE) {
    .Call(`_gkwreg_calculateDensities`, y, params, family, log)
}

#' @title Calculate Cumulative Probabilities for Distribution
#'
#' @description
#' Computes the cumulative probabilities (CDF) for each observation given the parameters.
#'
#' @param y NumericVector of observations.
#' @param params NumericMatrix with parameters (columns: alpha, beta, gamma, delta, lambda).
#' @param family String specifying the distribution family (default: "gkw").
#'
#' @return NumericVector containing the evaluated cumulative probabilities.
#' @export
calculateProbabilities <- function(y, params, family = "gkw") {
    .Call(`_gkwreg_calculateProbabilities`, y, params, family)
}

#' @title Calculate Quantiles for Distribution
#'
#' @description
#' Computes quantiles for the given probability levels using a bisection method for the first set
#' of parameters in the matrix.
#'
#' @param probs NumericVector of probabilities (values in (0,1)).
#' @param params NumericMatrix with parameters (columns: alpha, beta, gamma, delta, lambda).
#' @param family String specifying the distribution family (default: "gkw").
#'
#' @return NumericVector containing the calculated quantiles.
#' @export
calculateQuantiles <- function(probs, params, family = "gkw") {
    .Call(`_gkwreg_calculateQuantiles`, probs, params, family)
}

#' @title Calculate Response Residuals
#'
#' @description
#' Computes the raw response residuals as the difference between the observed and fitted values.
#'
#' @param y NumericVector of observations.
#' @param fitted NumericVector of fitted values.
#'
#' @return NumericVector of response residuals.
#' @export
calculateResponseResiduals <- function(y, fitted) {
    .Call(`_gkwreg_calculateResponseResiduals`, y, fitted)
}

#' @title Calculate Pearson Residuals
#'
#' @description
#' Computes the Pearson residuals based on the observed values, fitted means, and the approximate variance of the distribution.
#'
#' @param y NumericVector of observations.
#' @param fitted NumericVector of fitted values (means).
#' @param params NumericMatrix with parameters (columns: alpha, beta, gamma, delta, lambda).
#' @param family String specifying the distribution family (default: "gkw").
#'
#' @return NumericVector of Pearson residuals.
#' @export
calculatePearsonResiduals <- function(y, fitted, params, family = "gkw") {
    .Call(`_gkwreg_calculatePearsonResiduals`, y, fitted, params, family)
}

#' @title Calculate Deviance Residuals
#'
#' @description
#' Computes deviance residuals based on the log-likelihood of the observations.
#'
#' @param y NumericVector of observations.
#' @param fitted NumericVector of fitted values (means).
#' @param params NumericMatrix with parameters (columns: alpha, beta, gamma, delta, lambda).
#' @param family String specifying the distribution family (default: "gkw").
#'
#' @return NumericVector of deviance residuals.
#' @export
calculateDevianceResiduals <- function(y, fitted, params, family = "gkw") {
    .Call(`_gkwreg_calculateDevianceResiduals`, y, fitted, params, family)
}

#' @title Calculate Quantile Residuals
#'
#' @description
#' Computes quantile residuals by transforming the cumulative distribution function (CDF) values to the standard normal quantiles.
#'
#' @param y NumericVector of observations.
#' @param params NumericMatrix with parameters (columns: alpha, beta, gamma, delta, lambda).
#' @param family String specifying the distribution family (default: "gkw").
#'
#' @return NumericVector of quantile residuals.
#' @export
calculateQuantileResiduals <- function(y, params, family = "gkw") {
    .Call(`_gkwreg_calculateQuantileResiduals`, y, params, family)
}

#' @title Calculate Cox-Snell Residuals
#'
#' @description
#' Computes Cox-Snell residuals defined as -log(1 - F(y)), where F is the cumulative distribution function.
#'
#' @param y NumericVector of observations.
#' @param params NumericMatrix with parameters (columns: alpha, beta, gamma, delta, lambda).
#' @param family String specifying the distribution family (default: "gkw").
#'
#' @return NumericVector of Cox-Snell residuals.
#' @export
calculateCoxSnellResiduals <- function(y, params, family = "gkw") {
    .Call(`_gkwreg_calculateCoxSnellResiduals`, y, params, family)
}

#' @title Calculate Score Residuals
#'
#' @description
#' Computes score residuals based on the numerical derivative (score) of the log-likelihood with respect to the observation.
#'
#' @param y NumericVector of observations.
#' @param fitted NumericVector of fitted values (means).
#' @param params NumericMatrix with parameters (columns: alpha, beta, gamma, delta, lambda).
#' @param family String specifying the distribution family (default: "gkw").
#'
#' @return NumericVector of score residuals.
#' @export
calculateScoreResiduals <- function(y, fitted, params, family = "gkw") {
    .Call(`_gkwreg_calculateScoreResiduals`, y, fitted, params, family)
}

#' @title Calculate Modified Deviance Residuals
#'
#' @description
#' Adjusts deviance residuals to have a distribution closer to N(0,1) by standardizing them.
#'
#' @param y NumericVector of observations.
#' @param fitted NumericVector of fitted values (means).
#' @param params NumericMatrix with parameters (columns: alpha, beta, gamma, delta, lambda).
#' @param family String specifying the distribution family (default: "gkw").
#'
#' @return NumericVector of modified deviance residuals.
#' @export
calculateModifiedDevianceResiduals <- function(y, fitted, params, family = "gkw") {
    .Call(`_gkwreg_calculateModifiedDevianceResiduals`, y, fitted, params, family)
}

#' @title Calculate Partial Residuals
#'
#' @description
#' Computes partial residuals for a selected covariate by adding the product of the regression coefficient and
#' the corresponding design matrix value to the raw residual.
#'
#' @param y NumericVector of observations.
#' @param fitted NumericVector of fitted values.
#' @param X NumericMatrix of design matrix values.
#' @param beta NumericVector of regression coefficients.
#' @param covariate_idx Integer index for the selected covariate (0-indexed).
#'
#' @return NumericVector of partial residuals.
#' @export
calculatePartialResiduals <- function(y, fitted, X, beta, covariate_idx) {
    .Call(`_gkwreg_calculatePartialResiduals`, y, fitted, X, beta, covariate_idx)
}

Try the gkwreg package in your browser

Any scripts or data that you put into this service are public.

gkwreg documentation built on April 16, 2025, 1:10 a.m.