Nothing
##### d1_i (documentation) #####
#' Coefficients in polynomial expansion of generating function---single matrix
#'
#' These are internal functions to calculate the coefficients
#' in polynomial expansion of generating functions for quadratic forms
#' in multivariate normal variables.
#'
#' \code{d1_i()} calculates \eqn{d_k(\mathbf{A})}{d_k(A)}, and
#' \code{dtil1_i_v()} and \code{dtil1_i_m()} calculate
#' \eqn{\tilde{d}_k(\mathbf{A})}{\tilde{d}_k(A)} in
#' Hillier et al. (2009, 2014) and Bao and Kan (2013). The former is
#' related to the top-order zonal polynomial
#' \eqn{C_{[k]}(\mathbf{A})}{C_[k](A)} in the following way:
#' \eqn{ d_k(\mathbf{A}) = \frac{1}{k!} \left( \frac{1}{2} \right)_k
#' C_{[k]}(\mathbf{A}) }{d_k(A) = (1/k!) (1/2)_k C_[k](A)},
#' where \eqn{(x)_k = x (x + 1) \dots (x + k - 1)}.
#'
#' These functions calculate the coefficients based on the super-short
#' recursion algorithm described in Hillier et al. (2014: 3.2, eqs. 28--30).
#'
#' ## Scaling
#' The coefficients described herein (and in \code{\link{d2_ij}} and
#' \code{\link{d3_ijk}}) can become very large for higher-order terms,
#' so there is a practical risk of numerical overflow when applied to
#' large matrices or matrices with many large eigenvalues
#' (note that the latter typically arises from those with many small
#' eigenvalues for the front-end \code{qfrm()} functions). To avoid
#' numerical overflow, these functions automatically scale
#' coefficients (and temporary objects used to calculate them) by a large number
#' (\code{1e10} at present) when any value in the temporary objects exceeds
#' a threshold, \code{.Machine$double.xmax / thr_margin / n}, where \code{n}
#' is the number of variables. This default value empirically seems to work well
#' in most conditions, but use a large \code{thr_margin} (e.g., \code{1e5})
#' if you encounter numerical overflow. (The \proglang{C++} functions use
#' an equivalent expression,
#' \code{std::numeric_limits<Scalar>::max() / thr_margin / Scalar(n)}, with
#' \code{Scalar} being \code{double} or \code{long double}.)
#'
#' In these \R functions, the scaling happens order-wise;
#' i.e., it influences all the coefficients of the same order in
#' multidimensional coefficients (in \code{\link{d2_ij}} and
#' \code{\link{d3_ijk}}) and the coefficients of the subsequent orders.
#'
#' These scaling factors are recorded in the attribute \code{"logscale"} of the
#' return value, which is a vector/matrix/array whose size is identical to the
#' return value, so that \code{value / exp(attr(value, "logscale"))} equals
#' the original quantities to be obtained (if there were no overflow).
#'
#' The \code{qfrm} and \code{qfmrm} functions handle return values of these
#' functions by first multiplying them with hypergeometric coefficients
#' (which are typically \eqn{\ll 1}{<< 1}) and then scaling the products back
#' to the original scale using the recorded scaling factors. (To be precise,
#' this typically happens within \code{\link{hgs}} functions.) The
#' \proglang{C++} functions handle the problem similarly (but by using
#' separate objects rather than attributes).
#'
#' However, this procedure does not always mitigate the problem in
#' multiple series; when there are very large and very small
#' coefficients in the same order, smaller ones can diminish/underflow to
#' the numerical \code{0} after repeated scaling. (The \code{qfrm} and
#' \code{qfmrm} functions try to detect and warn against
#' this by examining whether any of the highest-order terms is \code{0}.)
#' The present version of this package has implemented two methods to mitigate
#' this problem, but only through \proglang{C++} functions. One is to use the
#' \code{long double} variable type, and the other is to use coefficient-wise
#' scaling (see \code{\link{qfrm}} and \code{\link{qfmrm}}).
#'
#' @return
#' Vector of length \code{m + 1}, corresponding to
#' the 0th, 1st, ..., and mth order terms. Hence, the \code{[m + 1]}-th
#' element should be extracted when the coefficient for the \eqn{m}th order
#' term is required.
#'
#' Has the attribute \code{"logscale"} as described in \dQuote{Scaling} above.
#'
#' @param L
#' Vector of eigenvalues of the argument matrix
#' @param m
#' Integer-alike to specify the order of polynomials
#' @param A
#' Argument matrix. Assumed to be symmetric in these functions.
#' @param mu
#' Mean vector \eqn{\bm{\mu}}{\mu} for \eqn{\mathbf{x}}{x}
#' @param thr_margin
#' Optional argument to adjust the threshold for scaling
#' (see \dQuote{Details})
#'
#' @references
#' Bao, Y. and Kan, R. (2013) On the moments of ratios of quadratic forms in
#' normal random variables. *Journal of Multivariate Analysis*, **117**,
#' 229--245.
#' \doi{10.1016/j.jmva.2013.03.002}.
#'
#' Hillier, G., Kan, R. and Wang, X. (2009) Computationally efficient recursions
#' for top-order invariant polynomials with applications.
#' *Econometric Theory*, **25**, 211--242.
#' \doi{10.1017/S0266466608090075}.
#'
#' Hillier, G., Kan, R. and Wang, X. (2014) Generating functions and
#' short recursions, with applications to the moments of quadratic forms
#' in noncentral normal vectors. *Econometric Theory*, **30**, 436--473.
#' \doi{10.1017/S0266466613000364}.
#'
#' @seealso
#' \code{\link{qfpm}}, \code{\link{qfrm}}, and \code{\link{qfmrm}} are
#' major front-end functions that utilize these functions
#'
#' \code{\link{dtil2_pq}} for \eqn{\tilde{d}}
#' used for moments of a product of quadratic forms
#'
#' \code{\link{d2_ij}} and \code{\link{d3_ijk}} for \eqn{d}, \eqn{h},
#' \eqn{\tilde{h}}, and \eqn{\hat{h}} used for moments of ratios
#' of quadratic forms
#'
#' @name d1_i
#' @aliases dtil1_i
#'
NULL
##### dtil2_pq (documentation) #####
#' Coefficients in polynomial expansion of generating function---for products
#'
#' These are internal functions to calculate the coefficients
#' in polynomial expansion of joint generating functions for two or three
#' quadratic forms in potentially noncentral multivariate normal variables,
#' \eqn{\mathbf{x} \sim N_n(\bm{\mu}, \mathbf{I}_n)}{x ~ N_n(\mu, I_n)}. They
#' are primarily used to calculate moments of a product of two or
#' three quadratic forms.
#'
#' \code{dtil2_pq_m()} and \code{dtil2_pq_v()} calculate
#' \eqn{\tilde{d}_{p,q}(\mathbf{A}_1, \mathbf{A}_2)}{\tilde{d}_{p,q}(A_1, A_2)}
#' in Hillier et al. (2014). \code{dtil2_1q_m()} and \code{dtil2_1q_v()} are
#' fast versions for the commonly used case where \eqn{p = 1}. Similarly,
#' \code{dtil3_pqr_m()} and \code{dtil3_pqr_v()} are for
#' \eqn{\tilde{d}_{p,q,r}(\mathbf{A}_1, \mathbf{A}_2, \mathbf{A}_3)
#' }{\tilde{d}_{p,q,r}(A_1, A_2, A_3)}.
#'
#' Those ending with \code{_m} take matrices as arguments, whereas
#' those with \code{_v} take eigenvalues. The latter can be used only when
#' the argument matrices share the same eigenvectors, to which the eigenvalues
#' correspond in the orders given, but is substantially faster.
#'
#' These functions calculate the coefficients based on the super-short
#' recursion algorithm described in Hillier et al. (2014: sec. 4.2).
#'
#' @return
#' A \code{(p + 1) * (q + 1)} matrix for the 2D functions,
#' or a \code{(p + 1) * (q + 1) * (r + 1)} array for the 3D functions.
#'
#' The 1st, 2nd, and 3rd dimensions correspond to increasing orders for
#' \eqn{\mathbf{A}_1}{A_1}, \eqn{\mathbf{A}_2}{A_2}, and
#' \eqn{\mathbf{A}_3}{A_3}, respectively. And the 1st row/column of each
#' dimension corresponds to the 0th order (hence \code{[p + 1, q + 1]} for
#' the \eqn{(p,q)}-th moment).
#'
#' @param A1,A2,A3
#' Argument matrices. Assumed to be symmetric and of the same order.
#' @param L1,L2,L3
#' Eigenvalues of the argument matrices
#' @param mu
#' Mean vector \eqn{\bm{\mu}}{\mu} for \eqn{\mathbf{x}}{x}
#' @param p,q,r
#' Integer-alikes to specify the order along the three argument matrices
#'
#' @references
#' Hillier, G., Kan, R. and Wang, X. (2014) Generating functions and
#' short recursions, with applications to the moments of quadratic forms
#' in noncentral normal vectors. *Econometric Theory*, **30**, 436--473.
#' \doi{10.1017/S0266466613000364}.
#'
#' @seealso
#' \code{\link{qfpm}} is a front-end functions that utilizes these functions
#'
#' \code{\link{d1_i}} for a single-matrix equivalent of \eqn{\tilde{d}}
#'
#' @name dtil2_pq
#' @aliases dtil3_pqr
#'
NULL
##### d2_ij (documentation) #####
#' Coefficients in polynomial expansion of generating function---for
#' ratios with two matrices
#'
#' These are internal functions to calculate the coefficients
#' in polynomial expansion of joint generating functions for two
#' quadratic forms in potentially noncentral multivariate normal variables,
#' \eqn{\mathbf{x} \sim N_n(\bm{\mu}, \mathbf{I}_n)}{x ~ N_n(\mu, I_n)}. They
#' are primarily used in calculations around moments of a ratio
#' involving two or three quadratic forms.
#'
#' \code{d2_**_*()} functions calculate
#' \eqn{d_{i,j}(\mathbf{A}_1, \mathbf{A}_2)}{d_{i,j}(A_1, A_2)} in
#' Hillier et al. (2009, 2014) and Bao and Kan (2013). These are also related to
#' the top-order invariant polynomials
#' \eqn{C_{[k_1],[k_2]}(\mathbf{A}_1, \mathbf{A}_2)}{C_{[k_1],[k_2]}(A_1, A_2)}
#' in the following way:
#' \eqn{ d_{i,j}(\mathbf{A}_1, \mathbf{A}_2) =
#' \frac{1}{k_1! k_2!} \left( \frac{1}{2} \right)_{k_1 + k_2}
#' C_{[k_1],[k_2]}(\mathbf{A}_1, \mathbf{A}_2) }{d_{i,j}(A_1, A_2) =
#' (1 / (k_1! k_2!)) ( 1/2 )_{k_1 + k_2} C_{[k_1],[k_2]}(A_1, A_2) },
#' where \eqn{(x)_k = x (x + 1) \dots (x + k - 1)}
#' (Chikuse 1987; Hillier et al. 2009).
#'
#' \code{h2_ij_*()} and \code{htil2_pj_*()} functions calculate
#' \eqn{h_{i,j}(\mathbf{A}_1, \mathbf{A}_2)}{h_{i,j}(A_1, A_2)} and
#' \eqn{\tilde{h}_{i,j}(\mathbf{A}_1; \mathbf{A}_2)}{\tilde{h}_{i,j}(A_1; A_2)},
#' respectively, in Bao and Kan (2013). Note that the latter is denoted by the
#' symbol \eqn{h_{i,j}} in Hillier et al. (2014). \code{hhat2_pj_*()}
#' functions are for
#' \eqn{\hat{h}_{i,j}(\mathbf{A}_1; \mathbf{A}_2)}{\hat{h}_{i,j}(A_1; A_2)}
#' in Hillier et al. (2014), used to calculate an error bound for
#' truncated sum for moments of a ratio of quadratic forms. The
#' mean vector \eqn{\bm{\mu}}{\mu} is a parameter in all these.
#'
#' There are two different situations in which these coefficients are used
#' in calculation of moments of ratios of quadratic forms:
#' **1**) within an infinite series for one of the subscripts, with the
#' other subscript fixed (when the exponent \eqn{p} of the numerator
#' is integer); **2**) within a double infinite series for both subscripts
#' (when \eqn{p} is non-integer) (see Bao and Kan 2013). In this package,
#' the situation **1** is handled by the \code{*_pj_*} (and \code{*_1j_*})
#' functions, and **2** is by the \code{*_ij_*} functions.
#'
#' In particular, the \code{*_pj_*} functions always return a
#' \code{(p + 1) * (m + 1)} matrix where all elements are filled with
#' the relevant coefficients (e.g., \eqn{d_{i,j}}, \eqn{\tilde{h}_{i,j}}),
#' from which, typically, the \code{[p + 1, ]}-th row is used for
#' subsequent calculations. (Those with \code{*_1q_*} are simply fast versions
#' for the commonly used case where \eqn{p = 1}.)
#' On the other hand, the \code{*_ij_*} functions by default return a
#' \code{(m + 1) * (m + 1)} matrix whose upper-left triangular part
#' (including the diagonals) is filled with the coefficients
#' (\eqn{d_{i,j}} or \eqn{h_{i,j}}), the rest being 0, and all the coefficients
#' are used in subsequent calculations.
#'
#' (At present, the \code{*_ij_*} functions also have the functionality to
#' fill all coefficients of a potentially non-square output matrix,
#' but this is less efficient than \code{*_pj_*} functions so may
#' be omitted in the future development.)
#'
#' Those ending with \code{_m} take matrices as arguments, whereas
#' those with \code{_v} take eigenvalues. The latter can be used only when
#' the argument matrices share the same eigenvectors, to which the eigenvalues
#' correspond in the orders given, but is substantially faster.
#'
#' This package also involves \proglang{C++} equivalents for most of these functions
#' (which are suffixed by \code{E} for \code{Eigen}),
#' but these are exclusively for internal use and not exposed to the user.
#'
#' @return
#' \code{(p + 1) * (m + 1)} matrix for the \code{*_pj_*} functions.
#'
#' \code{(m + 1) * (m + 1)} matrix for the \code{*_ij_*} functions.
#'
#' The rows and columns correspond to increasing orders for
#' \eqn{\mathbf{A}_1}{A_1} and \eqn{\mathbf{A}_2}{A_2}, respectively. And
#' the 1st row/column of each dimension corresponds
#' to the 0th order (hence \code{[p + 1, q + 1]} for the \eqn{(p,q)}-th order).
#'
#' Has the attribute \code{"logscale"} as described in the
#' \dQuote{Scaling} section in \code{\link{d1_i}}. This is
#' a matrix of the same size as the return itself.
#'
#' @param A1,A2
#' Argument matrices. Assumed to be symmetric and of the same order.
#' @param L1,L2
#' Eigenvalues of the argument matrices
#' @param mu
#' Mean vector \eqn{\bm{\mu}}{\mu} for \eqn{\mathbf{x}}{x}
#' @param m
#' Integer-alike to specify the desired order along \code{A2}/\code{L2}
#' @param p,q
#' Integer-alikes to specify the desired orders along
#' \code{A1}/\code{L1} and \code{A2}/\code{L2}, respectively.
#' @param thr_margin
#' Optional argument to adjust the threshold for scaling (see \dQuote{Scaling}
#' in \code{\link{d1_i}})
#' @param fill_all
#' Logical to specify whether all the output matrix should be filled. See
#' \dQuote{Details}.
#'
#' @references
#' Bao, Y. and Kan, R. (2013) On the moments of ratios of quadratic forms in
#' normal random variables. *Journal of Multivariate Analysis*, **117**,
#' 229--245.
#' \doi{10.1016/j.jmva.2013.03.002}.
#'
#' Chikuse, Y. (1987) Methods for constructing top order invariant polynomials.
#' *Econometric Theory*, **3**, 195--207.
#' \doi{10.1017/S026646660001029X}.
#'
#' Hillier, G., Kan, R. and Wang, X. (2009) Computationally efficient recursions
#' for top-order invariant polynomials with applications.
#' *Econometric Theory*, **25**, 211--242.
#' \doi{10.1017/S0266466608090075}.
#'
#' Hillier, G., Kan, R. and Wang, X. (2014) Generating functions and
#' short recursions, with applications to the moments of quadratic forms
#' in noncentral normal vectors. *Econometric Theory*, **30**, 436--473.
#' \doi{10.1017/S0266466613000364}.
#'
#' @seealso
#' \code{\link{qfrm}} and \code{\link{qfmrm}} are
#' major front-end functions that utilize these functions
#'
#' \code{\link{dtil2_pq}} for \eqn{\tilde{d}}
#' used for moments of a product of quadratic forms
#'
#' \code{\link{d3_ijk}} for equivalents for three matrices
#'
#' @name d2_ij
#' @aliases d2_pj h2_ij htil2_pj hhat2_pj d2_1j htil2_1j hhat2_1j
#'
NULL
##### d3_ijk (documentation) #####
#' Coefficients in polynomial expansion of generating function---for
#' ratios with three matrices
#'
#' These are internal functions to calculate the coefficients
#' in polynomial expansion of joint generating functions for three
#' quadratic forms in potentially noncentral multivariate normal variables,
#' \eqn{\mathbf{x} \sim N_n(\bm{\mu}, \mathbf{I}_n)}{x ~ N_n(\mu, I_n)}. They
#' are primarily used in calculations around moments of a ratio
#' involving three quadratic forms.
#'
#' All these functions have equivalents for two-matrix cases
#' (\code{\link{d2_ij}}), to which the user is referred for
#' documentations. The primary difference of these functions from the latter is
#' the addition of arguments for the third matrix \code{A3}/\code{L3}.
#'
#' \code{d3_*jk_*()} functions calculate
#' \eqn{d_{i,j,k}(\mathbf{A}_1, \mathbf{A}_2, \mathbf{A}_3)
#' }{d_{i,j,k}(A_1, A_2, A_3)} in
#' Hillier et al. (2009, 2014) and Bao and Kan (2013). These are
#' also related to the top-order invariant polynomials as described
#' in \code{\link{d2_ij}}.
#'
#' \code{h3_ijk_*()}, \code{htil3_pjk_*()}, and \code{hhat3_pjk_*()} functions
#' calculate \eqn{h_{i,j,k}(\mathbf{A}_1, \mathbf{A}_2, \mathbf{A}_3)
#' }{h_{i,j,k}(A_1, A_2, A_3)},
#' \eqn{\tilde{h}_{i;j,k}(\mathbf{A}_1; \mathbf{A}_2, \mathbf{A}_3)
#' }{\tilde{h}_{i;j,k}(A_1; A_2, A_3)}, and
#' \eqn{\hat{h}_{i;j,k}(\mathbf{A}_1; \mathbf{A}_2, \mathbf{A}_3)
#' }{\hat{h}_{i;j,k}(A_1; A_2, A_3)},
#' respectively, as described in the package vignette. These are equivalent
#' to similar coefficients described in Bao and Kan (2013) and
#' Hillier et al. (2014).
#'
#' The difference between the \code{*_pjk_*} and \code{*_ijk_*} functions
#' is as described for \code{*_pj_*} and \code{*_ij_*}
#' (see \dQuote{Details} in \code{\link{d2_ij}}). The only difference is
#' that these functions return a 3D array. In the \code{*_pjk_*} functions,
#' all the slices along the first dimension (i.e., \code{[i, , ]}) are
#' an upper-left triangular matrix like what the \code{*_ij_*} functions return
#' in the 2D case; in other words, the return has the coefficients for the terms
#' that satisfy \eqn{j + k \le m} for all \eqn{i = 0, 1, \dots, p}. Typically,
#' the \code{[p + 1, , ]}-th slice is used for subsequent calculations. In the
#' return of the \code{*_ijk_*} functions, only the triangular prism
#' close to the \code{[1, 1, 1]} is filled with coefficients, which
#' correspond to the terms satisfying \eqn{i + j + k \le m}.
#'
#' @return
#'
#' \code{(p + 1) * (m + 1) * (m + 1)} array for the \code{*_pjk_*} functions
#'
#' \code{(m + 1) * (m + 1) * (m + 1)} array for the \code{*_ijk_*} functions
#' (by default; see \dQuote{Details}).
#'
#' The 1st, 2nd, and 3rd dimensions correspond to increasing orders for
#' \eqn{\mathbf{A}_1}{A_1}, \eqn{\mathbf{A}_2}{A_2}, and
#' \eqn{\mathbf{A}_3}{A_3}, respectively. And the 1st row/column of
#' each dimension corresponds to the 0th order (hence
#' \code{[p + 1, q + 1, r + 1]} for the \eqn{(p,q,r)}-th order).
#'
#' Has the attribute \code{"logscale"} as described in the \dQuote{Scaling}
#' section in \code{\link{d1_i}}. This is an array of the same size
#' as the return itself.
#'
#' @inheritParams d2_ij
#' @param A1,A2,A3
#' Argument matrices. Assumed to be symmetric and of the same order.
#' @param L1,L2,L3
#' Eigenvalues of the argument matrices
#' @param m
#' Integer-alike to specify the desired order along \code{A2}/\code{L2}
#' and \code{A3}/\code{L3}
#' @param p,q,r
#' Integer-alikes to specify the desired orders along
#' \code{A1}/\code{L1}, \code{A2}/\code{L2}, and \code{A3}/\code{L3},
#' respectively.
#' @param fill_across
#' Logical vector of length 3, to specify whether each dimension of
#' the output matrix should be filled.
#'
#' @references
#' Bao, Y. and Kan, R. (2013) On the moments of ratios of quadratic forms in
#' normal random variables. *Journal of Multivariate Analysis*, **117**,
#' 229--245.
#' \doi{10.1016/j.jmva.2013.03.002}.
#'
#' Hillier, G., Kan, R. and Wang, X. (2014) Generating functions and
#' short recursions, with applications to the moments of quadratic forms
#' in noncentral normal vectors. *Econometric Theory*, **30**, 436--473.
#' \doi{10.1017/S0266466613000364}.
#'
#' @seealso
#' \code{\link{qfmrm}} is a
#' major front-end function that utilizes these functions
#'
#' \code{\link{dtil2_pq}} for \eqn{\tilde{d}}
#' used for moments of a product of quadratic forms
#'
#' \code{\link{d2_ij}} for equivalents for two matrices
#'
#' @name d3_ijk
#' @aliases d3_pjk h3_ijk htil3_pjk hhat3_pjk
#'
NULL
##### d1_i #####
#' Coefficients in polynomial expansion of generating function
#'
#' \code{d1_i()} is for standard multivariate normal variables,
#' \eqn{\mathbf{x} \sim N_n(\mathbf{0}_n, \mathbf{I}_n)}{x ~ N_n(0_n, I_n)}.
#'
#' @rdname d1_i
#'
d1_i <- function(L, m = 100L, thr_margin = 100) {
n <- length(L)
dks <- rep.int(c(1, 0), c(1L, m))
lscf <- rep.int(0, length(dks))
thr <- .Machine$double.xmax / thr_margin / n
uk <- rep.int(0, n)
for(k in seq_len(m)) {
uk <- L * (dks[k] + uk)
dks[k + 1L] <- sum(uk) / (2 * k)
if(max(uk) > thr) {
dks[k + 1L] <- dks[k + 1L] / 1e10
uk <- uk / 1e10
lscf[(k + 1L):length(lscf)] <- lscf[(k + 1L):length(lscf)] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### dtil1_i_v #####
#' Coefficients in polynomial expansion of generating function
#'
#' \code{dtil1_i_v()} is for noncentral multivariate normal variables,
#' \eqn{\mathbf{x} \sim N_n(\bm{\mu}, \mathbf{I}_n)}{x ~ N_n(\mu, I_n)}.
#'
#' @rdname d1_i
#'
dtil1_i_v <- function(L, mu = rep.int(0, n), m = 100L, thr_margin = 100) {
n <- length(L)
D <- mu ^ 2
dks <- rep.int(c(1, 0), c(1L, m))
lscf <- rep.int(0, length(dks))
thr <- .Machine$double.xmax / thr_margin / n
uk <- rep.int(0, n)
vk <- rep.int(0, n)
for(k in seq_len(m)) {
uk <- L * (dks[k] + uk)
vk <- D * uk + L * vk
dks[k + 1L] <- sum(uk + vk) / (2 * k)
if(max(uk) > thr || max(vk) > thr) {
dks[k + 1L] <- dks[k + 1L] / 1e10
uk <- uk / 1e10
vk <- vk / 1e10
lscf[(k + 1L):length(lscf)] <- lscf[(k + 1L):length(lscf)] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### dtil1_i_m #####
#' Coefficients in polynomial expansion of generating function
#'
#' \code{dtil1_i_m()} is a wrapper for \code{dtil1_i_v()}
#' and takes the argument matrix rather than its eigenvalues.
#'
#' @rdname d1_i
#'
dtil1_i_m <- function(A, mu = rep.int(0, n), m = 100L, thr_margin = 100) {
eigA <- eigen(A, symmetric = TRUE)
L <- eigA$values
D <- c(crossprod(eigA$vectors, mu)) ^ 2
n <- length(L)
dks <- rep.int(c(1, 0), c(1L, m))
lscf <- rep.int(0, length(dks))
thr <- .Machine$double.xmax / thr_margin / n
uk <- rep.int(0, n)
vk <- rep.int(0, n)
for(k in seq_len(m)) {
uk <- L * (dks[k] + uk)
vk <- D * uk + L * vk
dks[k + 1L] <- sum(uk + vk) / (2 * k)
if(max(uk) > thr || max(vk) > thr) {
dks[k + 1L] <- dks[k + 1L] / 1e10
uk <- uk / 1e10
vk <- vk / 1e10
lscf[(k + 1L):length(lscf)] <- lscf[(k + 1L):length(lscf)] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### dtil2_pq_m #####
#' Coefficients in polynomial expansion of generating function---for
#' product of two matrices
#'
#' @rdname dtil2_pq
#'
dtil2_pq_m <- function(A1, A2, mu = rep.int(0, n), p = 1L, q = 1L) {
if(p == 1L) return(dtil2_1q_m(A1, A2, mu, q))
n <- ncol(A1)
In <- diag(n)
dks <- matrix(0, p + 1L, q + 1L)
dks[1L, 1L] <- 1
zeromat <- matrix(0, n, n)
zerovec <- matrix(0, n, 1)
G_k_i <- list()
g_k_i <- list()
G_k_i[1L:(p + 1L)] <- list(zeromat)
g_k_i[1L:(p + 1L)] <- list(zerovec)
for(i in 1L:p) {
G_k_i[[i + 1L]] <- A1 %*% (dks[i, 1L] * In + G_k_i[[i]])
g_k_i[[i + 1L]] <- G_k_i[[i + 1L]] %*% mu + A1 %*% g_k_i[[i]]
dks[i + 1L, 1L] <- (tr(G_k_i[[i + 1L]]) + c(crossprod(mu, g_k_i[[i + 1L]]))) / (2 * i)
}
for(k in 1L:q) {
G_k_i[[1L]] <- A2 %*% (dks[1L, k] * In + G_k_i[[1L]])
g_k_i[[1L]] <- G_k_i[[1L]] %*% mu + A2 %*% g_k_i[[1L]]
dks[1L, k + 1L] <- (tr(G_k_i[[1L]]) + c(crossprod(mu, g_k_i[[1L]]))) / (2 * k)
for(i in 1L:p) {
G_k_i[[i + 1L]] <- A1 %*% (dks[i, k + 1L] * In + G_k_i[[i]]) +
A2 %*% (dks[i + 1L, k] * In + G_k_i[[i + 1L]])
g_k_i[[i + 1L]] <- G_k_i[[i + 1L]] %*% mu +
A1 %*% g_k_i[[i]] + A2 %*% g_k_i[[i + 1L]]
dks[i + 1L, k + 1L] <- (tr(G_k_i[[i + 1L]]) + c(crossprod(mu, g_k_i[[i + 1L]]))) / (2 * (k + i))
}
}
return(dks)
}
##### dtil2_1q_m #####
#' Coefficients in polynomial expansion of generating function---for
#' product of two matrices
#'
#' @rdname dtil2_pq
#'
dtil2_1q_m <- function(A1, A2, mu = rep.int(0, n), q = 1L) {
n <- ncol(A1)
In <- diag(n)
dks <- matrix(0, 2L, q + 1L)
dks[1L, 1L] <- 1
G_k_0 <- matrix(0, n, n)
G_k_1 <- A1
g_k_0 <- matrix(0, n, 1)
g_k_1 <- G_k_1 %*% mu
dks[2L, 1L] <- (tr(G_k_1) + c(crossprod(mu, g_k_1))) / 2
for(k in 1L:q) {
G_k_0 <- A2 %*% (dks[1L, k] * In + G_k_0)
g_k_0 <- G_k_0 %*% mu + A2 %*% g_k_0
dks[1L, k + 1L] <- (tr(G_k_0) + c(crossprod(mu, g_k_0))) / (2 * k)
G_k_1 <- A1 %*% (dks[1L, k + 1L] * In + G_k_0) +
A2 %*% (dks[2L, k] * In + G_k_1)
g_k_1 <- G_k_1 %*% mu + A1 %*% g_k_0 + A2 %*% g_k_1
dks[2L, k + 1L] <- (tr(G_k_1) + c(crossprod(mu, g_k_1))) / (2 * (k + 1))
}
return(dks)
}
##### dtil2_pq_v #####
#' Coefficients in polynomial expansion of generating function---for
#' product of two matrices
#'
#' @rdname dtil2_pq
#'
dtil2_pq_v <- function(L1, L2, mu = rep.int(0, n), p = 1L, q = 1L) {
if(p == 1L) return(dtil2_1q_v(L1, L2, mu, q))
n <- length(L1)
dks <- matrix(0, p + 1L, q + 1L)
dks[1L, 1L] <- 1
zeros <- rep.int(0, n)
G_k_i <- list()
g_k_i <- list()
G_k_i[1L:(p + 1L)] <- list(zeros)
g_k_i[1L:(p + 1L)] <- list(zeros)
for(i in 1L:p) {
G_k_i[[i + 1L]] <- L1 * (dks[i, 1L] + G_k_i[[i]])
g_k_i[[i + 1L]] <- G_k_i[[i + 1L]] * mu + L1 * g_k_i[[i]]
dks[i + 1L, 1L] <- sum(G_k_i[[i + 1L]] + mu * g_k_i[[i + 1L]]) / (2 * i)
}
for(k in 1L:q) {
G_k_i[[1L]] <- L2 * (dks[1L, k] + G_k_i[[1L]])
g_k_i[[1L]] <- G_k_i[[1L]] * mu + L2 * g_k_i[[1L]]
dks[1L, k + 1L] <- sum(G_k_i[[1L]] + mu * g_k_i[[1L]]) / (2 * k)
for(i in 1L:p) {
G_k_i[[i + 1L]] <- L1 * (dks[i, k + 1L] + G_k_i[[i]]) +
L2 * (dks[i + 1L, k] + G_k_i[[i + 1L]])
g_k_i[[i + 1L]] <- G_k_i[[i + 1L]] * mu +
L1 * g_k_i[[i]] + L2 * g_k_i[[i + 1L]]
dks[i + 1L, k + 1L] <- sum(G_k_i[[i + 1L]] + mu * g_k_i[[i + 1L]]) / (2 * (k + i))
}
}
return(dks)
}
##### dtil2_1q_v #####
#' Coefficients in polynomial expansion of generating function---for
#' product of two matrices
#'
#' @rdname dtil2_pq
#'
dtil2_1q_v <- function(L1, L2, mu = rep.int(0, n), q = 1L) {
n <- length(L1)
dks <- matrix(0, 2L, q + 1L)
dks[1L, 1L] <- 1
G_k_0 <- rep.int(0, n)
G_k_1 <- L1
g_k_0 <- rep.int(0, n)
g_k_1 <- G_k_1 * mu
dks[2L, 1L] <- sum(G_k_1 + mu * g_k_1) / 2
for(k in 1L:q) {
G_k_0 <- L2 * (dks[1L, k] + G_k_0)
g_k_0 <- G_k_0 * mu + L2 * g_k_0
dks[1L, k + 1L] <- sum(G_k_0 + mu * g_k_0) / (2 * k)
G_k_1 <- L1 * (dks[1L, k + 1L] + G_k_0) + L2 * (dks[2L, k] + G_k_1)
g_k_1 <- G_k_1 * mu + L1 * g_k_0 + L2 * g_k_1
dks[2L, k + 1L] <- sum(G_k_1 + mu * g_k_1) / (2 * (k + 1))
}
return(dks)
}
##### dtil3_pqr_m #####
#' Coefficients in polynomial expansion of generating function---for
#' product of three matrices
#'
#' @rdname dtil2_pq
#'
dtil3_pqr_m <- function(A1, A2, A3, mu = rep.int(0, n),
p = 1L, q = 1L, r = 1L) {
n <- ncol(A1)
In <- diag(n)
m <- q + r
dks <- array(0, dim = c(p + 1L, q + 1L, r + 1L))
dks[1L] <- 1
zeromat <- matrix(0, n, n)
zerovec <- matrix(0, n, 1)
Gc <- list()
gc <- list()
Gc[1L:(p + 1L)] <- list(zeromat)
gc[1L:(p + 1L)] <- list(zerovec)
for(i in 1L:p) {
Gc[[i + 1L]] <- A1 %*% (dks[i, 1L, 1L] * In + Gc[[i]])
gc[[i + 1L]] <- Gc[[i + 1L]] %*% mu + A1 %*% gc[[i]]
dks[i + 1L, 1L, 1L] <- (tr(Gc[[i + 1L]]) + c(crossprod(mu, gc[[i + 1L]]))) / (2 * i)
}
Gn <- list(Gc)
gn <- list(gc)
for(k in 1L:m) {
Go <- Gn
go <- gn
if(k <= q) {
Gc[[1L]] <- A2 %*% (dks[1L, k, 1L] * In + Go[[1L]][[1L]])
gc[[1L]] <- Gc[[1L]] %*% mu + A2 %*% go[[1L]][[1L]]
dks[1L, k + 1L, 1L] <- (tr(Gc[[1L]]) + c(crossprod(mu, gc[[1L]]))) / (2 * k)
for(i in 1L:p) {
Gc[[i + 1L]] <- A1 %*% (dks[i, k + 1L, 1L] * In + Gc[[i]]) +
A2 %*% (dks[i + 1L, k, 1L] * In + Go[[1L]][[i + 1L]])
gc[[i + 1L]] <- Gc[[i + 1L]] %*% mu +
A1 %*% gc[[i]] + A2 %*% go[[1L]][[i + 1L]]
dks[i + 1L, k + 1L, 1L] <- (tr(Gc[[i + 1L]]) + c(crossprod(mu, gc[[i + 1L]]))) / (2 * (k + i))
}
Gn <- list(Gc)
gn <- list(gc)
} else {
Gn <- list(0)
gn <- list(0)
}
if(k >= 2L) {
for(j in 1L:(k - 1L)) {
if(k - j <= q && j <= r) {
Gc[[1L]] <- A2 %*% (dks[1L, k - j, j + 1L] * In + Go[[j + 1L]][[1L]]) + A3 %*% (dks[1L, k - j + 1L, j] * In + Go[[j]][[1L]])
gc[[1L]] <- Gc[[1L]] %*% mu + A2 %*% go[[j + 1L]][[1L]] + A3 %*% go[[j]][[1L]]
dks[1L, k - j + 1L, j + 1L] <- (tr(Gc[[1L]]) + c(crossprod(mu, gc[[1L]]))) / (2 * k)
for(i in 1L:p) {
Gc[[i + 1L]] <- A1 %*% (dks[i, k - j + 1L, j + 1L] * In + Gc[[i]]) +
A2 %*% (dks[i + 1L, k - j, j + 1L] * In + Go[[j + 1L]][[i + 1L]]) +
A3 %*% (dks[i + 1L, k - j + 1L, j] * In + Go[[j]][[i + 1L]])
gc[[i + 1L]] <- Gc[[i + 1L]] %*% mu +
A1 %*% gc[[i]] + A2 %*% go[[j + 1L]][[i + 1L]] + A3 %*% go[[j]][[i + 1L]]
dks[i + 1L, k - j + 1L, j + 1L] <- (tr(Gc[[i + 1L]]) + c(crossprod(mu, gc[[i + 1L]]))) / (2 * (k + i))
}
Gn <- c(Gn, list(Gc))
gn <- c(gn, list(gc))
} else {
Gn <- c(Gn, list(0))
gn <- c(gn, list(0))
}
}
}
if(k <= r) {
Gc[[1L]] <- A3 %*% (dks[1L, 1L, k] * In + Go[[k]][[1L]])
gc[[1L]] <- Gc[[1L]] %*% mu + A3 %*% go[[k]][[1L]]
dks[1L, 1L, k + 1L] <- (tr(Gc[[1L]]) + c(crossprod(mu, gc[[1L]]))) / (2 * k)
for(i in 1L:p) {
Gc[[i + 1L]] <- A1 %*% (dks[i, 1L, k + 1L] * In + Gc[[i]]) +
A3 %*% (dks[i + 1L, 1L, k] * In + Go[[k]][[i + 1L]])
gc[[i + 1L]] <- Gc[[i + 1L]] %*% mu +
A1 %*% gc[[i]] + A3 %*% go[[k]][[i + 1L]]
dks[i + 1L, 1L, k + 1L] <- (tr(Gc[[i + 1L]]) + c(crossprod(mu, gc[[i + 1L]]))) / (2 * (k + i))
}
Gn <- c(Gn, list(Gc))
gn <- c(gn, list(gc))
} else {
Gn <- c(Gn, list(0))
gn <- c(gn, list(0))
}
}
return(dks)
}
##### dtil3_pqr_v #####
#' Coefficients in polynomial expansion of generating function---for
#' product of three matrices
#'
#' @rdname dtil2_pq
#'
dtil3_pqr_v <- function(L1, L2, L3, mu = rep.int(0, n),
p = 1L, q = 1L, r = 1L) {
n <- length(L1)
m <- q + r
dks <- array(0, dim = c(p + 1L, q + 1L, r + 1L))
dks[1L] <- 1
zeros <- rep.int(0, n)
Gc <- list()
gc <- list()
Gc[1L:(p + 1L)] <- list(zeros)
gc[1L:(p + 1L)] <- list(zeros)
for(i in 1L:p) {
Gc[[i + 1L]] <- L1 * (dks[i, 1L, 1L] + Gc[[i]])
gc[[i + 1L]] <- Gc[[i + 1L]] * mu + L1 * gc[[i]]
dks[i + 1L, 1L, 1L] <- (sum(Gc[[i + 1L]]) + sum(mu * gc[[i + 1L]])) / (2 * i)
}
Gn <- list(Gc)
gn <- list(gc)
for(k in 1L:m) {
Go <- Gn
go <- gn
if(k <= q) {
Gc[[1L]] <- L2 * (dks[1L, k, 1L] + Go[[1L]][[1L]])
gc[[1L]] <- Gc[[1L]] * mu + L2 * go[[1L]][[1L]]
dks[1L, k + 1L, 1L] <- (sum(Gc[[1L]]) + sum(mu * gc[[1L]])) / (2 * k)
for(i in 1L:p) {
Gc[[i + 1L]] <- L1 * (dks[i, k + 1L, 1L] + Gc[[i]]) +
L2 * (dks[i + 1L, k, 1L] + Go[[1L]][[i + 1L]])
gc[[i + 1L]] <- Gc[[i + 1L]] * mu +
L1 * gc[[i]] + L2 * go[[1L]][[i + 1L]]
dks[i + 1L, k + 1L, 1L] <- (sum(Gc[[i + 1L]]) + sum(mu * gc[[i + 1L]])) / (2 * (k + i))
}
Gn <- list(Gc)
gn <- list(gc)
} else {
Gn <- list(0)
gn <- list(0)
}
if(k >= 2L) {
for(j in 1L:(k - 1L)) {
if(k - j <= q && j <= r) {
Gc[[1L]] <- L2 * (dks[1L, k - j, j + 1L] + Go[[j + 1L]][[1L]]) + L3 * (dks[1L, k - j + 1L, j] + Go[[j]][[1L]])
gc[[1L]] <- Gc[[1L]] * mu + L2 * go[[j + 1L]][[1L]] + L3 * go[[j]][[1L]]
dks[1L, k - j + 1L, j + 1L] <- (sum(Gc[[1L]]) + sum(mu * gc[[1L]])) / (2 * k)
for(i in 1L:p) {
Gc[[i + 1L]] <- L1 * (dks[i, k - j + 1L, j + 1L] + Gc[[i]]) +
L2 * (dks[i + 1L, k - j, j + 1L] + Go[[j + 1L]][[i + 1L]]) +
L3 * (dks[i + 1L, k - j + 1L, j] + Go[[j]][[i + 1L]])
gc[[i + 1L]] <- Gc[[i + 1L]] * mu +
L1 * gc[[i]] + L2 * go[[j + 1L]][[i + 1L]] + L3 * go[[j]][[i + 1L]]
dks[i + 1L, k - j + 1L, j + 1L] <- (sum(Gc[[i + 1L]]) + sum(mu * gc[[i + 1L]])) / (2 * (k + i))
}
Gn <- c(Gn, list(Gc))
gn <- c(gn, list(gc))
} else {
Gn <- c(Gn, list(0))
gn <- c(gn, list(0))
}
}
}
if(k <= r) {
Gc[[1L]] <- L3 * (dks[1L, 1L, k] + Go[[k]][[1L]])
gc[[1L]] <- Gc[[1L]] * mu + L3 * go[[k]][[1L]]
dks[1L, 1L, k + 1L] <- (sum(Gc[[1L]]) + sum(mu * gc[[1L]])) / (2 * k)
for(i in 1L:p) {
Gc[[i + 1L]] <- L1 * (dks[i, 1L, k + 1L] + Gc[[i]]) +
L3 * (dks[i + 1L, 1L, k] + Go[[k]][[i + 1L]])
gc[[i + 1L]] <- Gc[[i + 1L]] * mu +
L1 * gc[[i]] + L3 * go[[k]][[i + 1L]]
dks[i + 1L, 1L, k + 1L] <- (sum(Gc[[i + 1L]]) + sum(mu * gc[[i + 1L]])) / (2 * (k + i))
}
Gn <- c(Gn, list(Gc))
gn <- c(gn, list(gc))
} else {
Gn <- c(Gn, list(0))
gn <- c(gn, list(0))
}
}
return(dks)
}
##### a1_pk #####
#' Recursion for a_\{p,k\}
#'
#' \code{a1_pk()} is an internal function to calculate \eqn{a_{p,k}}
#' (\eqn{a_{r,l}} in Hillier et al. 2014; eq. 24), which is used in the
#' calculation of the moment of such a ratio of quadratic forms in normal
#' variables where the denominator matrix is identity.
#'
#' This function implements the super-short recursion described in
#' Hillier et al. (2014 eqs. 31--32). Note that
#' \eqn{w_{r,i}} there should be understood as \eqn{w_{r,l,i}} with
#' the index \eqn{l} fixed for each \eqn{a_{r,l}}.
#'
#' @param L
#' Eigenvalues of the argument matrix; vector of \eqn{\lambda_i}
#' @param mu
#' Mean vector \eqn{\bm{\mu}}{\mu} for \eqn{\mathbf{x}}{x}
#' @param m
#' Scalar to specify the desired order
#'
#' @seealso
#' \code{\link{qfrm_ApIq_int}()}, in which this function is used
#' (for noncentral cases only)
#'
#' @name a1_pk
#'
a1_pk <- function(L, mu = rep.int(0, n), m = 10L) {
n <- length(L)
D <- mu ^ 2
arls <- matrix(0, m + 1L, m + 1L)
arls[, 1L] <- d1_i(L, m)
wrls <- matrix(0, n, m)
for(k in 1:m) {
for(l in 1:k) {
wrls[, l] <- L * (arls[k, l] + wrls[, l])
arls[k + 1L, l + 1L] <- sum(D * wrls[, l])
}
}
return(arls)
}
##### d2_ij_m #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with two matrices
#'
#' @rdname d2_ij
#'
d2_ij_m <- function(A1, A2, m = 100L, p = m, q = m, thr_margin = 100,
fill_all = !missing(p) || !missing(q)) {
il2 <- function(i1, i2) i1 + i2 * (p + 1L) + 1L
n <- ncol(A1)
In <- diag(n)
zeromat <- matrix(0, n, n)
dks <- matrix(rep.int(c(1, 0), c(1L, (p + 1) * (q + 1) - 1L)), p + 1, q + 1)
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
Gs <- list(zeromat)
order_mat <- outer(0:p, 0:q, "+")
kmax <- if(fill_all) sum(dim(dks) - 1L) else max(dim(dks) - 1L)
for(k in 1L:kmax) {
Gs[which(order_mat == k - 2L)] <- 0
for(i1 in min(k, p):max(k - q, 0L)) {
i2 <- k - i1
tG <- zeromat
if(i1 >= 1L) tG <- tG + A1 %*% (dks[i1, i2 + 1L] * In + Gs[[il2(i1 - 1L, i2)]])
if(i2 >= 1L) tG <- tG + A2 %*% (dks[i1 + 1L, i2] * In + Gs[[il2(i1, i2 - 1L)]])
Gs[[il2(i1, i2)]] <- tG
dks[i1 + 1L, i2 + 1L] <- tr(tG) / (2 * k)
}
if(max(unlist(Gs)) > thr) {
ind_dks <- which(order_mat == k)
ind_lscf <- which(order_mat >= k)
dks[ind_dks] <- dks[ind_dks] / 1e10
Gs <- lapply(Gs, function(x) x / 1e10)
lscf[ind_lscf] <- lscf[ind_lscf] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### d2_ij_v #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with two matrices
#'
#' @rdname d2_ij
#'
d2_ij_v <- function(L1, L2, m = 100L, p = m, q = m, thr_margin = 100,
fill_all = !missing(p) || !missing(q)) {
il2 <- function(i1, i2) i1 + i2 * (p + 1L) + 1L
n <- length(L1)
zeros <- rep.int(0, n)
dks <- matrix(rep.int(c(1, 0), c(1L, (p + 1) * (q + 1) - 1L)), p + 1, q + 1)
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
Gs <- list(zeros)
order_mat <- outer(0:p, 0:q, "+")
kmax <- if(fill_all) sum(dim(dks) - 1L) else max(dim(dks) - 1L)
for(k in 1L:kmax) {
Gs[which(order_mat == k - 2L)] <- 0
for(i1 in min(k, p):max(k - q, 0L)) {
i2 <- k - i1
tG <- zeros
if(i1 >= 1L) tG <- tG + L1 * (dks[i1, i2 + 1L] + Gs[[il2(i1 - 1L, i2)]])
if(i2 >= 1L) tG <- tG + L2 * (dks[i1 + 1L, i2] + Gs[[il2(i1, i2 - 1L)]])
Gs[[il2(i1, i2)]] <- tG
dks[i1 + 1L, i2 + 1L] <- sum(tG) / (2 * k)
}
if(max(unlist(Gs)) > thr) {
ind_dks <- which(order_mat == k)
ind_lscf <- which(order_mat >= k)
dks[ind_dks] <- dks[ind_dks] / 1e10
Gs <- lapply(Gs, function(x) x / 1e10)
lscf[ind_lscf] <- lscf[ind_lscf] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### d2_pj_m #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with two matrices
#'
#' @rdname d2_ij
#'
d2_pj_m <- function(A1, A2, m = 100L, p = 1L, thr_margin = 100) {
if(p == 1L) return(d2_1j_m(A1, A2, m))
n <- ncol(A1)
p1 <- p + 1L
m1 <- m + 1L
In <- diag(n)
dks <- matrix(0, p1, m1)
dks[1L, 1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
zeromat <- matrix(0, n, n)
G_k_i <- list()
G_k_i[1L:p1] <- list(zeromat)
for(i in 1L:p) {
G_k_i[[i + 1L]] <- A1 %*% (dks[i, 1L] * In + G_k_i[[i]])
dks[i + 1L, 1L] <- tr(G_k_i[[i + 1L]]) / (2 * i)
}
for(k in 1L:m) {
G_k_i[[1L]] <- A2 %*% (dks[1L, k] * In + G_k_i[[1L]])
dks[1L, k + 1L] <- tr(G_k_i[[1L]]) / (2 * k)
for(i in 1L:p) {
G_k_i[[i + 1L]] <- A1 %*% (dks[i, k + 1L] * In + G_k_i[[i]]) +
A2 %*% (dks[i + 1L, k] * In + G_k_i[[i + 1L]])
dks[i + 1L, k + 1L] <- tr(G_k_i[[i + 1L]]) / (2 * (k + i))
}
if(max(G_k_i[[i + 1L]]) > thr) {
dks[, k + 1L] <- dks[, k + 1L] / 1e10
G_k_i <- lapply(G_k_i, function(x) x / 1e10)
lscf[, (k + 1L):m1] <- lscf[, (k + 1L):m1] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### d2_1j_m #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with two matrices
#'
#' @rdname d2_ij
#'
d2_1j_m <- function(A1, A2, m = 100L, thr_margin = 100) {
n <- ncol(A1)
m1 <- m + 1L
In <- diag(n)
dks <- matrix(0, 2L, m1)
dks[1L, 1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
G_k_0 <- matrix(0, n, n)
G_k_1 <- A1
dks[2L, 1L] <- tr(G_k_1) / 2
for(k in 1L:m) {
G_k_0 <- A2 %*% (dks[1L, k] * In + G_k_0)
dks[1L, k + 1L] <- tr(G_k_0) / (2 * k)
G_k_1 <- A1 %*% (dks[1L, k + 1L] * In + G_k_0) +
A2 %*% (dks[2L, k] * In + G_k_1)
dks[2L, k + 1L] <- tr(G_k_1) / (2 * (k + 1))
if(max(G_k_1) > thr) {
dks[, k + 1L] <- dks[, k + 1L] / 1e10
G_k_0 <- G_k_0 / 1e10
G_k_1 <- G_k_1 / 1e10
lscf[, (k + 1L):m1] <- lscf[, (k + 1L):m1] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### d2_pj_v #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with two matrices
#'
#' @rdname d2_ij
#'
d2_pj_v <- function(L1, L2, m = 100L, p = 1L, thr_margin = 100) {
if(p == 1L) return(d2_1j_v(L1, L2, m))
n <- length(L1)
p1 <- p + 1L
m1 <- m + 1L
dks <- matrix(0, p1, m1)
dks[1L, 1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
zeros <- rep.int(0, n)
G_k_i <- list()
G_k_i[1L:p1] <- list(zeros)
for(i in 1L:p) {
G_k_i[[i + 1L]] <- L1 * (dks[i, 1L] + G_k_i[[i]])
dks[i + 1L, 1L] <- sum(G_k_i[[i + 1L]]) / (2 * i)
}
for(k in 1L:m) {
G_k_i[[1L]] <- L2 * (dks[1L, k] + G_k_i[[1L]])
dks[1L, k + 1L] <- sum(G_k_i[[1L]]) / (2 * k)
for(i in 1L:p) {
G_k_i[[i + 1L]] <- L1 * (dks[i, k + 1L] + G_k_i[[i]]) +
L2 * (dks[i + 1L, k] + G_k_i[[i + 1L]])
dks[i + 1L, k + 1L] <- sum(G_k_i[[i + 1L]]) / (2 * (k + i))
}
if(max(G_k_i[[i + 1L]]) > thr) {
dks[, k + 1L] <- dks[, k + 1L] / 1e10
G_k_i <- lapply(G_k_i, function(x) x / 1e10)
lscf[, (k + 1L):m1] <- lscf[, (k + 1L):m1] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### d2_1j_v #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with two matrices
#'
#' @rdname d2_ij
#'
d2_1j_v <- function(L1, L2, m = 100L, thr_margin = 100) {
n <- length(L1)
m1 <- m + 1L
dks <- matrix(0, 2L, m1)
dks[1L, 1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
G_k_0 <- rep.int(0, n)
G_k_1 <- L1
dks[2L, 1L] <- sum(G_k_1) / 2
for(k in 1L:m) {
G_k_0 <- L2 * (dks[1L, k] + G_k_0)
dks[1L, k + 1L] <- sum(G_k_0) / (2 * k)
G_k_1 <- L1 * (dks[1L, k + 1L] + G_k_0) + L2 * (dks[2L, k] + G_k_1)
dks[2L, k + 1L] <- sum(G_k_1) / (2 * (k + 1))
if(max(G_k_1) > thr) {
dks[, k + 1L] <- dks[, k + 1L] / 1e10
G_k_0 <- G_k_0 / 1e10
G_k_1 <- G_k_1 / 1e10
lscf[, (k + 1L):m1] <- lscf[, (k + 1L):m1] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### d3_ijk_m #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with three matrices
#'
#' @rdname d3_ijk
#'
d3_ijk_m <- function(A1, A2, A3, m = 100L, p = m, q = m, r = m,
thr_margin = 100,
fill_across = c(!missing(p), !missing(q), !missing(r))) {
il3 <- function(i1, i2, i3) i1 + i2 * p1 + i3 * p1 * q1 + 1L
n <- ncol(A1)
p1 <- p + 1L
q1 <- q + 1L
r1 <- r + 1L
In <- diag(n)
zeromat <- matrix(0, n, n)
dks <- array(0, dim = c(p1, q1, r1))
dks[1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
Gs <- list(zeromat)
order_array <- outer(outer(0:p, 0:q, "+"), 0:r, "+")
kmax <- min(any(!fill_across) * m + sum(fill_across * c(p, q, r)), sum(dim(dks) - 1L))
for(k in 1L:kmax) {
Gs[which(order_array == k - 2L)] <- 0
for(i1 in min(k, p):max(k - q - r, 0L, fill_across[1L] * (k + p - kmax))) {
for(i2 in min(k - i1, q):max(k - i1 - r, 0L)) {
i3 <- k - i1 - i2
if(fill_across[3L] && i1 + i2 + r > kmax) next
if(fill_across[2L] && i1 + i3 + q > kmax) next
tG <- zeromat
if(i1 >= 1L) tG <- tG + A1 %*% (dks[i1, i2 + 1L, i3 + 1L] * In + Gs[[il3(i1 - 1L, i2, i3)]])
if(i2 >= 1L) tG <- tG + A2 %*% (dks[i1 + 1L, i2, i3 + 1L] * In + Gs[[il3(i1, i2 - 1L, i3)]])
if(i3 >= 1L) tG <- tG + A3 %*% (dks[i1 + 1L, i2 + 1L, i3] * In + Gs[[il3(i1, i2, i3 - 1L)]])
Gs[[il3(i1, i2, i3)]] <- tG
dks[i1 + 1L, i2 + 1L, i3 + 1L] <- tr(tG) / (2 * k)
}
}
if(max(unlist(Gs)) > thr) {
ind_dks <- which(order_array == k)
ind_lscf <- which(order_array >= k)
dks[ind_dks] <- dks[ind_dks] / 1e10
Gs <- lapply(Gs, function(x) x / 1e10)
lscf[ind_lscf] <- lscf[ind_lscf] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### d3_ijk_v #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with three matrices
#'
#' @rdname d3_ijk
#'
d3_ijk_v <- function(L1, L2, L3, m = 100L, p = m, q = m, r = m,
thr_margin = 100,
fill_across = c(!missing(p), !missing(q), !missing(r))) {
il3 <- function(i1, i2, i3) i1 + i2 * p1 + i3 * p1 * q1 + 1L
n <- length(L1)
p1 <- p + 1L
q1 <- q + 1L
r1 <- r + 1L
zeros <- rep.int(0, n)
dks <- array(0, dim = c(p1, q1, r1))
dks[1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
Gs <- list(zeros)
order_array <- outer(outer(0:p, 0:q, "+"), 0:r, "+")
kmax <- min(any(!fill_across) * m + sum(fill_across * c(p, q, r)), sum(dim(dks) - 1L))
for(k in 1L:kmax) {
Gs[which(order_array == k - 2L)] <- 0
for(i1 in min(k, p):max(k - q - r, 0L, fill_across[1L] * (k + p - kmax))) {
for(i2 in min(k - i1, q):max(k - i1 - r, 0L)) {
i3 <- k - i1 - i2
if(fill_across[3L] && i1 + i2 + r > kmax) next
if(fill_across[2L] && i1 + i3 + q > kmax) next
tG <- zeros
if(i1 >= 1L) tG <- tG + L1 * (dks[i1, i2 + 1L, i3 + 1L] + Gs[[il3(i1 - 1L, i2, i3)]])
if(i2 >= 1L) tG <- tG + L2 * (dks[i1 + 1L, i2, i3 + 1L] + Gs[[il3(i1, i2 - 1L, i3)]])
if(i3 >= 1L) tG <- tG + L3 * (dks[i1 + 1L, i2 + 1L, i3] + Gs[[il3(i1, i2, i3 - 1L)]])
Gs[[il3(i1, i2, i3)]] <- tG
dks[i1 + 1L, i2 + 1L, i3 + 1L] <- sum(tG) / (2 * k)
}
}
if(max(unlist(Gs)) > thr) {
ind_dks <- which(order_array == k)
ind_lscf <- which(order_array >= k)
dks[ind_dks] <- dks[ind_dks] / 1e10
Gs <- lapply(Gs, function(x) x / 1e10)
lscf[ind_lscf] <- lscf[ind_lscf] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### d3_pjk_m #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with three matrices
#'
#' @rdname d3_ijk
#'
d3_pjk_m <- function(A1, A2, A3, m = 100L, p = 1L, thr_margin = 100) {
n <- ncol(A1)
p1 <- p + 1L
m1 <- m + 1L
In <- diag(n)
dks <- array(0, dim = c(p1, m1, m1))
dks[1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
order_array <- outer(outer(rep.int(0, p1), 0:m, "+"), 0:m, "+")
zeromat <- matrix(0, n, n)
Gc <- list()
Gc[1L:p1] <- list(zeromat)
for(i in 1L:p) {
Gc[[i + 1L]] <- A1 %*% (dks[i, 1L, 1L] * In + Gc[[i]])
dks[i + 1L, 1L, 1L] <- tr(Gc[[i + 1L]]) / (2 * i)
}
Gn <- list(Gc)
for(k in 1L:m) {
Go <- Gn
Gc[[1L]] <- A2 %*% (dks[1L, k, 1L] * In + Go[[1L]][[1L]])
dks[1L, k + 1L, 1L] <- tr(Gc[[1L]]) / (2 * k)
for(i in 1L:p) {
Gc[[i + 1L]] <- A1 %*% (dks[i, k + 1L, 1L] * In + Gc[[i]]) +
A2 %*% (dks[i + 1L, k, 1L] * In + Go[[1L]][[i + 1L]])
dks[i + 1L, k + 1L, 1L] <- tr(Gc[[i + 1L]]) / (2 * (k + i))
}
Gn <- list(Gc)
if(k >= 2L) {
for(j in 1L:(k - 1L)) {
Gc[[1L]] <- A2 %*% (dks[1L, k - j, j + 1L] * In + Go[[j + 1L]][[1L]]) + A3 %*% (dks[1L, k - j + 1L, j] * In + Go[[j]][[1L]])
dks[1L, k - j + 1L, j + 1L] <- tr(Gc[[1L]]) / (2 * k)
for(i in 1L:p) {
Gc[[i + 1L]] <- A1 %*% (dks[i, k - j + 1L, j + 1L] * In + Gc[[i]]) +
A2 %*% (dks[i + 1L, k - j, j + 1L] * In + Go[[j + 1L]][[i + 1L]]) +
A3 %*% (dks[i + 1L, k - j + 1L, j] * In + Go[[j]][[i + 1L]])
dks[i + 1L, k - j + 1L, j + 1L] <- tr(Gc[[i + 1L]]) / (2 * (k + i))
}
Gn <- c(Gn, list(Gc))
}
}
Gc[[1L]] <- A3 %*% (dks[1L, 1L, k] * In + Go[[k]][[1L]])
dks[1L, 1L, k + 1L] <- tr(Gc[[1L]]) / (2 * k)
for(i in 1L:p) {
Gc[[i + 1L]] <- A1 %*% (dks[i, 1L, k + 1L] * In + Gc[[i]]) +
A3 %*% (dks[i + 1L, 1L, k] * In + Go[[k]][[i + 1L]])
dks[i + 1L, 1L, k + 1L] <- tr(Gc[[i + 1L]]) / (2 * (k + i))
}
Gn <- c(Gn, list(Gc))
if(max(unlist(Gn)) > thr) {
ind_dks <- which(order_array == k + 1L)
ind_lscf <- which(order_array >= k + 1L)
dks[ind_dks] <- dks[ind_dks] / 1e10
Gn <- lapply(Gn, function(x) lapply(x, function(y) y / 1e10))
lscf[ind_lscf] <- lscf[ind_lscf] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### d3_pjk_v #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with three matrices
#'
#' @rdname d3_ijk
#'
d3_pjk_v <- function(L1, L2, L3, m = 100L, p = 1L, thr_margin = 100) {
n <- length(L1)
p1 <- p + 1L
m1 <- m + 1L
dks <- array(0, dim = c(p1, m1, m1))
dks[1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
order_array <- outer(outer(rep.int(0, p1), 0:m, "+"), 0:m, "+")
zeros <- rep.int(0, n)
Gc <- list()
Gc[1L:p1] <- list(zeros)
for(i in 1L:p) {
Gc[[i + 1L]] <- L1 * (dks[i, 1L, 1L] + Gc[[i]])
dks[i + 1L, 1L, 1L] <- sum(Gc[[i + 1L]]) / (2 * i)
}
Gn <- list(Gc)
for(k in 1L:m) {
Go <- Gn
Gc[[1L]] <- L2 * (dks[1L, k, 1L] + Go[[1L]][[1L]])
dks[1L, k + 1L, 1L] <- sum(Gc[[1L]]) / (2 * k)
for(i in 1L:p) {
Gc[[i + 1L]] <- L1 * (dks[i, k + 1L, 1L] + Gc[[i]]) +
L2 * (dks[i + 1L, k, 1L] + Go[[1L]][[i + 1L]])
dks[i + 1L, k + 1L, 1L] <- sum(Gc[[i + 1L]]) / (2 * (k + i))
}
Gn <- list(Gc)
if(k >= 2L) {
for(j in 1L:(k - 1L)) {
Gc[[1L]] <- L2 * (dks[1L, k - j, j + 1L] + Go[[j + 1L]][[1L]]) + L3 * (dks[1L, k - j + 1L, j] + Go[[j]][[1L]])
dks[1L, k - j + 1L, j + 1L] <- sum(Gc[[1L]]) / (2 * k)
for(i in 1L:p) {
Gc[[i + 1L]] <- L1 * (dks[i, k - j + 1L, j + 1L] + Gc[[i]]) +
L2 * (dks[i + 1L, k - j, j + 1L] + Go[[j + 1L]][[i + 1L]]) +
L3 * (dks[i + 1L, k - j + 1L, j] + Go[[j]][[i + 1L]])
dks[i + 1L, k - j + 1L, j + 1L] <- sum(Gc[[i + 1L]]) / (2 * (k + i))
}
Gn <- c(Gn, list(Gc))
}
}
Gc[[1L]] <- L3 * (dks[1L, 1L, k] + Go[[k]][[1L]])
dks[1L, 1L, k + 1L] <- sum(Gc[[1L]]) / (2 * k)
for(i in 1L:p) {
Gc[[i + 1L]] <- L1 * (dks[i, 1L, k + 1L] + Gc[[i]]) +
L3 * (dks[i + 1L, 1L, k] + Go[[k]][[i + 1L]])
dks[i + 1L, 1L, k + 1L] <- sum(Gc[[i + 1L]]) / (2 * (k + i))
}
Gn <- c(Gn, list(Gc))
if(max(unlist(Gn)) > thr) {
ind_dks <- which(order_array == k)
ind_lscf <- which(order_array >= k)
dks[ind_dks] <- dks[ind_dks] / 1e10
Gn <- lapply(Gn, function(x) lapply(x, function(y) y / 1e10))
lscf[ind_lscf] <- lscf[ind_lscf] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### h2_1j_m #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with two matrices
#'
#' @rdname d2_ij
#'
h2_ij_m <- function(A1, A2, mu = rep.int(0, n), m = 100L, p = m, q = m,
thr_margin = 100,
fill_all = !missing(p) || !missing(q)) {
il2 <- function(i1, i2) i1 + i2 * (p + 1L) + 1L
n <- ncol(A1)
In <- diag(n)
zeromat <- matrix(0, n, n)
zerovec <- matrix(0, n, 1)
dks <- matrix(rep.int(c(1, 0), c(1L, (p + 1) * (q + 1) - 1L)), p + 1, q + 1)
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
Gs <- list(zeromat)
gs <- list(zerovec)
order_mat <- outer(0:p, 0:q, "+")
kmax <- if(fill_all) sum(dim(dks) - 1L) else max(dim(dks) - 1L)
for(k in 1L:kmax) {
Gs[which(order_mat == k - 2L)] <- 0
gs[which(order_mat == k - 2L)] <- 0
for(i1 in min(k, p):max(k - q, 0L)) {
i2 <- k - i1
tG <- zeromat
if(i1 >= 1L) tG <- tG + A1 %*% (dks[i1, i2 + 1L] * In + Gs[[il2(i1 - 1L, i2)]])
if(i2 >= 1L) tG <- tG + A2 %*% (dks[i1 + 1L, i2] * In + Gs[[il2(i1, i2 - 1L)]])
Gs[[il2(i1, i2)]] <- tG
tg <- tG %*% mu
if(i1 >= 1L) tg <- tg - Gs[[il2(i1 - 1L, i2)]] %*% mu - dks[i1, i2 + 1L] * mu + A1 %*% gs[[il2(i1 - 1L, i2)]]
if(i2 >= 1L) tg <- tg - Gs[[il2(i1, i2 - 1L)]] %*% mu - dks[i1 + 1L, i2] * mu + A2 %*% gs[[il2(i1, i2 - 1L)]]
gs[[il2(i1, i2)]] <- tg
dks[i1 + 1L, i2 + 1L] <- (tr(tG) + c(crossprod(mu, tg))) / (2 * k)
}
if(max(unlist(Gs)) > thr || max(unlist(gs)) > thr) {
ind_dks <- which(order_mat == k)
ind_lscf <- which(order_mat >= k)
dks[ind_dks] <- dks[ind_dks] / 1e10
Gs <- lapply(Gs, function(x) x / 1e10)
gs <- lapply(gs, function(x) x / 1e10)
lscf[ind_lscf] <- lscf[ind_lscf] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### h2_1j_v #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with two matrices
#'
#' @rdname d2_ij
#'
h2_ij_v <- function(L1, L2, mu = rep.int(0, n), m = 100L, p = m, q = m,
thr_margin = 100,
fill_all = !missing(p) || !missing(q)) {
il2 <- function(i1, i2) i1 + i2 * (p + 1L) + 1L
n <- length(L1)
zeros <- rep.int(0, n)
dks <- matrix(rep.int(c(1, 0), c(1L, (p + 1) * (q + 1) - 1L)), p + 1, q + 1)
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
Gs <- list(zeros)
gs <- list(zeros)
order_mat <- outer(0:p, 0:q, "+")
kmax <- if(fill_all) sum(dim(dks) - 1L) else max(dim(dks) - 1L)
for(k in 1L:kmax) {
Gs[which(order_mat == k - 2L)] <- 0
gs[which(order_mat == k - 2L)] <- 0
for(i1 in min(k, p):max(k - q, 0L)) {
i2 <- k - i1
tG <- zeros
if(i1 >= 1L) tG <- tG + L1 * (dks[i1, i2 + 1L] + Gs[[il2(i1 - 1L, i2)]])
if(i2 >= 1L) tG <- tG + L2 * (dks[i1 + 1L, i2] + Gs[[il2(i1, i2 - 1L)]])
Gs[[il2(i1, i2)]] <- tG
tg <- tG * mu
if(i1 >= 1L) tg <- tg - (Gs[[il2(i1 - 1L, i2)]] + dks[i1, i2 + 1L]) * mu + L1 * gs[[il2(i1 - 1L, i2)]]
if(i2 >= 1L) tg <- tg - (Gs[[il2(i1, i2 - 1L)]] + dks[i1 + 1L, i2]) * mu + L2 * gs[[il2(i1, i2 - 1L)]]
gs[[il2(i1, i2)]] <- tg
dks[i1 + 1L, i2 + 1L] <- (sum(tG) + sum(mu * tg)) / (2 * k)
}
if(max(unlist(Gs)) > thr || max(unlist(gs)) > thr) {
ind_dks <- which(order_mat == k)
ind_lscf <- which(order_mat >= k)
dks[ind_dks] <- dks[ind_dks] / 1e10
Gs <- lapply(Gs, function(x) x / 1e10)
gs <- lapply(gs, function(x) x / 1e10)
lscf[ind_lscf] <- lscf[ind_lscf] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### htil2_pj_m #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with two matrices
#'
#' @rdname d2_ij
#'
htil2_pj_m <- function(A1, A2, mu = rep.int(0, n), m = 100L, p = 1L,
thr_margin = 100) {
if(p == 1L) return(htil2_1j_m(A1, A2, mu, m))
n <- ncol(A1)
p1 <- p + 1L
m1 <- m + 1L
In <- diag(n)
dks <- matrix(0, p1, m1)
dks[1L, 1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
zeromat <- matrix(0, n, n)
zerovec <- matrix(0, n, 1)
G_k_i <- list()
g_k_i <- list()
G_k_i[1L:p1] <- list(zeromat)
g_k_i[1L:p1] <- list(zerovec)
for(i in 1L:p) {
G_k_i[[i + 1L]] <- A1 %*% (dks[i, 1L] * In + G_k_i[[i]])
g_k_i[[i + 1L]] <- G_k_i[[i + 1L]] %*% mu + A1 %*% g_k_i[[i]]
dks[i + 1L, 1L] <- (tr(G_k_i[[i + 1L]]) + c(crossprod(mu, g_k_i[[i + 1L]]))) / (2 * i)
}
for(k in 1L:m) {
tG <- A2 %*% (dks[1L, k] * In + G_k_i[[1L]])
g_k_i[[1L]] <- (tG - G_k_i[[1L]] - (dks[1L, k] * In)) %*% mu + A2 %*% g_k_i[[1L]]
G_k_i[[1L]] <- tG
dks[1L, k + 1L] <- (tr(G_k_i[[1L]]) + c(crossprod(mu, g_k_i[[1L]]))) / (2 * k)
for(i in 1L:p) {
tG <- A1 %*% (dks[i, k + 1L] * In + G_k_i[[i]]) +
A2 %*% (dks[i + 1L, k] * In + G_k_i[[i + 1L]])
g_k_i[[i + 1L]] <- (tG - G_k_i[[i + 1L]]
- (dks[i + 1L, k] * In)) %*% mu +
A1 %*% g_k_i[[i]] + A2 %*% g_k_i[[i + 1L]]
G_k_i[[i + 1L]] <- tG
dks[i + 1L, k + 1L] <- (tr(G_k_i[[i + 1L]]) + c(crossprod(mu, g_k_i[[i + 1L]]))) / (2 * (k + i))
}
if(max(unlist(G_k_i)) > thr || max(unlist(g_k_i)) > thr) {
dks[, k + 1L] <- dks[, k + 1L] / 1e10
G_k_i <- lapply(G_k_i, function(x) x / 1e10)
g_k_i <- lapply(g_k_i, function(x) x / 1e10)
lscf[, (k + 1L):m1] <- lscf[, (k + 1L):m1] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### htil2_1j_m #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with two matrices
#'
#' @rdname d2_ij
#'
htil2_1j_m <- function(A1, A2, mu = rep.int(0, n), m = 100L, thr_margin = 100) {
n <- ncol(A1)
m1 <- m + 1L
In <- diag(n)
dks <- matrix(0, 2L, m + 1L)
dks[1L, 1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
G_k_0 <- matrix(0, n, n)
G_k_1 <- A1
g_k_0 <- matrix(0, n, 1)
g_k_1 <- G_k_1 %*% mu
dks[2L, 1L] <- (tr(G_k_1) + c(crossprod(mu, g_k_1))) / 2
for(k in 1L:m) {
tG <- A2 %*% (dks[1L, k] * In + G_k_0)
g_k_0 <- (tG - G_k_0 - (dks[1L, k] * In)) %*% mu + A2 %*% g_k_0
G_k_0 <- tG
dks[1L, k + 1L] <- (tr(G_k_0) + c(crossprod(mu, g_k_0))) / (2 * k)
tG <- A1 %*% (dks[1L, k + 1L] * In + G_k_0) +
A2 %*% (dks[2L, k] * In + G_k_1)
g_k_1 <- (tG - G_k_1 - (dks[2L, k] * In)) %*% mu +
A1 %*% g_k_0 + A2 %*% g_k_1
G_k_1 <- tG
dks[2L, k + 1L] <- (tr(G_k_1) + c(crossprod(mu, g_k_1))) / (2 * (k + 1))
if(max(G_k_1) > thr || max(g_k_1) > thr) {
dks[, k + 1L] <- dks[, k + 1L] / 1e10
G_k_0 <- G_k_0 / 1e10
G_k_1 <- G_k_1 / 1e10
g_k_0 <- g_k_0 / 1e10
g_k_1 <- g_k_1 / 1e10
lscf[, (k + 1L):m1] <- lscf[, (k + 1L):m1] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### htil2_pj_v #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with two matrices
#'
#' @rdname d2_ij
#'
htil2_pj_v <- function(L1, L2, mu = rep.int(0, n), m = 100L, p = 1L,
thr_margin = 100) {
if(p == 1L) return(htil2_1j_v(L1, L2, mu, m))
n <- length(L1)
p1 <- p + 1L
m1 <- m + 1L
dks <- matrix(0, p1, m1)
dks[1L, 1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
zeros <- rep.int(0, n)
G_k_i <- list()
g_k_i <- list()
G_k_i[1L:p1] <- list(zeros)
g_k_i[1L:p1] <- list(zeros)
for(i in 1L:p) {
G_k_i[[i + 1L]] <- L1 * (dks[i, 1L] + G_k_i[[i]])
g_k_i[[i + 1L]] <- G_k_i[[i + 1L]] * mu + L1 * g_k_i[[i]]
dks[i + 1L, 1L] <- sum(G_k_i[[i + 1L]] + mu * g_k_i[[i + 1L]]) / (2 * i)
}
for(k in 1L:m) {
tG <- L2 * (dks[1L, k] + G_k_i[[1L]])
g_k_i[[1L]] <- (tG - G_k_i[[1L]] - dks[1L, k]) * mu + L2 * g_k_i[[1L]]
G_k_i[[1L]] <- tG
dks[1L, k + 1L] <- sum(G_k_i[[1L]] + mu * g_k_i[[1L]]) / (2 * k)
for(i in 1L:p) {
tG <- L1 * (dks[i, k + 1L] + G_k_i[[i]]) +
L2 * (dks[i + 1L, k] + G_k_i[[i + 1L]])
g_k_i[[i + 1L]] <- (tG - G_k_i[[i + 1L]] - dks[i + 1L, k]) * mu +
L1 * g_k_i[[i]] + L2 * g_k_i[[i + 1L]]
G_k_i[[i + 1L]] <- tG
dks[i + 1L, k + 1L] <- sum(G_k_i[[i + 1L]] + mu * g_k_i[[i + 1L]]) / (2 * (k + i))
}
if(max(unlist(G_k_i)) > thr || max(unlist(g_k_i)) > thr) {
dks[, k + 1L] <- dks[, k + 1L] / 1e10
G_k_i <- lapply(G_k_i, function(x) x / 1e10)
g_k_i <- lapply(g_k_i, function(x) x / 1e10)
lscf[, (k + 1L):m1] <- lscf[, (k + 1L):m1] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### htil2_1j_v #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with two matrices
#'
#' @rdname d2_ij
#'
htil2_1j_v <- function(L1, L2, mu = rep.int(0, n), m = 100L,
thr_margin = 100) {
n <- length(L1)
m1 <- m + 1L
dks <- matrix(0, 2L, m1)
dks[1L, 1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
G_k_0 <- rep.int(0, n)
G_k_1 <- L1
g_k_0 <- rep.int(0, n)
g_k_1 <- G_k_1 * mu
dks[2L, 1L] <- sum(G_k_1 + mu * g_k_1) / 2
for(k in 1L:m) {
tG <- L2 * (dks[1L, k] + G_k_0)
g_k_0 <- (tG - G_k_0 - dks[1L, k]) * mu + L2 * g_k_0
G_k_0 <- tG
dks[1L, k + 1L] <- sum(G_k_0 + mu * g_k_0) / (2 * k)
tG <- L1 * (dks[1L, k + 1L] + G_k_0) + L2 * (dks[2L, k] + G_k_1)
g_k_1 <- (tG - G_k_1 - dks[2L, k]) * mu + L1 * g_k_0 + L2 * g_k_1
G_k_1 <- tG
dks[2L, k + 1L] <- sum(G_k_1 + mu * g_k_1) / (2 * (k + 1))
if(max(G_k_1) > thr || max(g_k_1) > thr) {
dks[, k + 1L] <- dks[, k + 1L] / 1e10
G_k_0 <- G_k_0 / 1e10
G_k_1 <- G_k_1 / 1e10
g_k_0 <- g_k_0 / 1e10
g_k_1 <- g_k_1 / 1e10
lscf[, (k + 1L):m1] <- lscf[, (k + 1L):m1] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### h3_ijk_m #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with three matrices
#'
#' @rdname d3_ijk
#'
h3_ijk_m <- function(A1, A2, A3, mu = rep.int(0, n), m = 100L,
p = m, q = m, r = m, thr_margin = 100,
fill_across = c(!missing(p), !missing(q), !missing(r))) {
il3 <- function(i1, i2, i3) i1 + i2 * (p + 1L) + i3 * (p + 1L) * (q + 1L) + 1L
n <- ncol(A1)
In <- diag(n)
zeromat <- matrix(0, n, n)
zerovec <- matrix(0, n, 1)
dks <- array(0, dim = c(p + 1L, q + 1L, r + 1L))
dks[1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
Gs <- list(zeromat)
gs <- list(zerovec)
order_array <- outer(outer(0:p, 0:q, "+"), 0:r, "+")
kmax <- min(any(!fill_across) * m + sum(fill_across * c(p, q, r)), sum(dim(dks) - 1L))
for(k in 1L:kmax) {
Gs[which(order_array == k - 2L)] <- 0
gs[which(order_array == k - 2L)] <- 0
for(i1 in min(k, p):max(k - q - r, 0L, fill_across[1L] * (k + p - kmax))) {
for(i2 in min(k - i1, q):max(k - i1 - r, 0L)) {
i3 <- k - i1 - i2
if(fill_across[3L] && i1 + i2 + r > kmax) next
if(fill_across[2L] && i1 + i3 + q > kmax) next
tG <- zeromat
if(i1 >= 1L) tG <- tG + A1 %*% (dks[i1, i2 + 1L, i3 + 1L] * In + Gs[[il3(i1 - 1L, i2, i3)]])
if(i2 >= 1L) tG <- tG + A2 %*% (dks[i1 + 1L, i2, i3 + 1L] * In + Gs[[il3(i1, i2 - 1L, i3)]])
if(i3 >= 1L) tG <- tG + A3 %*% (dks[i1 + 1L, i2 + 1L, i3] * In + Gs[[il3(i1, i2, i3 - 1L)]])
Gs[[il3(i1, i2, i3)]] <- tG
tg <- tG %*% mu
if(i1 >= 1L) tg <- tg - Gs[[il3(i1 - 1L, i2, i3)]] %*% mu - dks[i1, i2 + 1L, i3 + 1L] * mu + A1 %*% gs[[il3(i1 - 1L, i2, i3)]]
if(i2 >= 1L) tg <- tg - Gs[[il3(i1, i2 - 1L, i3)]] %*% mu - dks[i1 + 1L, i2, i3 + 1L] * mu + A2 %*% gs[[il3(i1, i2 - 1L, i3)]]
if(i3 >= 1L) tg <- tg - Gs[[il3(i1, i2, i3 - 1L)]] %*% mu - dks[i1 + 1L, i2 + 1L, i3] * mu + A3 %*% gs[[il3(i1, i2, i3 - 1L)]]
gs[[il3(i1, i2, i3)]] <- tg
dks[i1 + 1L, i2 + 1L, i3 + 1L] <- (tr(tG) + c(crossprod(mu, tg))) / (2 * k)
}
}
if(max(unlist(Gs)) > thr || max(unlist(gs)) > thr) {
ind_dks <- which(order_array == k)
ind_lscf <- which(order_array >= k)
dks[ind_dks] <- dks[ind_dks] / 1e10
Gs <- lapply(Gs, function(x) x / 1e10)
gs <- lapply(gs, function(x) x / 1e10)
lscf[ind_lscf] <- lscf[ind_lscf] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### h3_ijk_v #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with three matrices
#'
#' @rdname d3_ijk
#'
h3_ijk_v <- function(L1, L2, L3, mu = rep.int(0, n), m = 100L,
p = m, q = m, r = m, thr_margin = 100,
fill_across = c(!missing(p), !missing(q), !missing(r))) {
il3 <- function(i1, i2, i3) i1 + i2 * (p + 1L) + i3 * (p + 1L) * (q + 1L) + 1L
n <- length(L1)
zeros <- rep.int(0, n)
dks <- array(0, dim = c(p + 1L, q + 1L, r + 1L))
dks[1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
Gs <- list(zeros)
gs <- list(zeros)
order_array <- outer(outer(0:p, 0:q, "+"), 0:r, "+")
kmax <- min(any(!fill_across) * m + sum(fill_across * c(p, q, r)), sum(dim(dks) - 1L))
for(k in 1L:kmax) {
Gs[which(order_array == k - 2L)] <- 0
gs[which(order_array == k - 2L)] <- 0
for(i1 in min(k, p):max(k - q - r, 0L, fill_across[1L] * (k + p - kmax))) {
for(i2 in min(k - i1, q):max(k - i1 - r, 0L)) {
i3 <- k - i1 - i2
if(fill_across[3L] && i1 + i2 + r > kmax) next
if(fill_across[2L] && i1 + i3 + q > kmax) next
tG <- zeros
if(i1 >= 1L) tG <- tG + L1 * (dks[i1, i2 + 1L, i3 + 1L] + Gs[[il3(i1 - 1L, i2, i3)]])
if(i2 >= 1L) tG <- tG + L2 * (dks[i1 + 1L, i2, i3 + 1L] + Gs[[il3(i1, i2 - 1L, i3)]])
if(i3 >= 1L) tG <- tG + L3 * (dks[i1 + 1L, i2 + 1L, i3] + Gs[[il3(i1, i2, i3 - 1L)]])
Gs[[il3(i1, i2, i3)]] <- tG
tg <- tG * mu
if(i1 >= 1L) tg <- tg - (Gs[[il3(i1 - 1L, i2, i3)]] + dks[i1, i2 + 1L, i3 + 1L]) * mu + L1 * gs[[il3(i1 - 1L, i2, i3)]]
if(i2 >= 1L) tg <- tg - (Gs[[il3(i1, i2 - 1L, i3)]] + dks[i1 + 1L, i2, i3 + 1L]) * mu + L2 * gs[[il3(i1, i2 - 1L, i3)]]
if(i3 >= 1L) tg <- tg - (Gs[[il3(i1, i2, i3 - 1L)]] + dks[i1 + 1L, i2 + 1L, i3]) * mu + L3 * gs[[il3(i1, i2, i3 - 1L)]]
gs[[il3(i1, i2, i3)]] <- tg
dks[i1 + 1L, i2 + 1L, i3 + 1L] <- (sum(tG) + sum(mu * tg)) / (2 * k)
}
}
if(max(unlist(Gs)) > thr || max(unlist(gs)) > thr) {
ind_dks <- which(order_array == k)
ind_lscf <- which(order_array >= k)
dks[ind_dks] <- dks[ind_dks] / 1e10
Gs <- lapply(Gs, function(x) x / 1e10)
gs <- lapply(gs, function(x) x / 1e10)
lscf[ind_lscf] <- lscf[ind_lscf] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### htil3_pjk_m #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with three matrices
#'
#' @rdname d3_ijk
#'
htil3_pjk_m <- function(A1, A2, A3, mu = rep.int(0, n), m = 100L, p = 1L,
thr_margin = 100) {
n <- ncol(A1)
p1 <- p + 1L
m1 <- m + 1L
In <- diag(n)
dks <- array(0, dim = c(p1, m1, m1))
dks[1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
order_array <- outer(outer(rep.int(0, p1), 0:m, "+"), 0:m, "+")
zeromat <- matrix(0, n, n)
zerovec <- matrix(0, n, 1)
Gc <- list()
gc <- list()
Gc[1L:p1] <- list(zeromat)
gc[1L:p1] <- list(zerovec)
for(i in 1L:p) {
Gc[[i + 1L]] <- A1 %*% (dks[i, 1L, 1L] * In + Gc[[i]])
gc[[i + 1L]] <- Gc[[i + 1L]] %*% mu + A1 %*% gc[[i]]
dks[i + 1L, 1L, 1L] <- (tr(Gc[[i + 1L]]) + c(crossprod(mu, gc[[i + 1L]]))) / (2 * i)
}
Gn <- list(Gc)
gn <- list(gc)
for(k in 1L:m) {
Go <- Gn
go <- gn
tG <- A2 %*% (dks[1L, k, 1L] * In + Go[[1L]][[1L]])
gc[[1L]] <- (tG - Go[[1L]][[1L]] - (dks[1L, k, 1L] * In)) %*% mu + A2 %*% go[[1L]][[1L]]
Gc[[1L]] <- tG
dks[1L, k + 1L, 1L] <- (tr(Gc[[1L]]) + c(crossprod(mu, gc[[1L]]))) / (2 * k)
for(i in 1L:p) {
tG <- A1 %*% (dks[i, k + 1L, 1L] * In + Gc[[i]]) +
A2 %*% (dks[i + 1L, k, 1L] * In + Go[[1L]][[i + 1L]])
gc[[i + 1L]] <- (tG - Go[[1L]][[i + 1L]]
- (dks[i + 1L, k, 1L] * In)) %*% mu +
A1 %*% gc[[i]] + A2 %*% go[[1L]][[i + 1L]]
Gc[[i + 1L]] <- tG
dks[i + 1L, k + 1L, 1L] <- (tr(Gc[[i + 1L]]) + c(crossprod(mu, gc[[i + 1L]]))) / (2 * (k + i))
}
Gn <- list(Gc)
gn <- list(gc)
if(k >= 2L) {
for(j in 1L:(k - 1L)) {
tG <- A2 %*% (dks[1L, k - j, j + 1L] * In + Go[[j + 1L]][[1L]]) + A3 %*% (dks[1L, k - j + 1L, j] * In + Go[[j]][[1L]])
gc[[1L]] <- (tG - Go[[j + 1L]][[1L]] - Go[[j]][[1L]] - ((dks[1L, k - j, j + 1L] + dks[1L, k - j + 1L, j]) * In)) %*% mu + A2 %*% go[[j + 1L]][[1L]] + A3 %*% go[[j]][[1L]]
Gc[[1L]] <- tG
dks[1L, k - j + 1L, j + 1L] <- (tr(Gc[[1L]]) + c(crossprod(mu, gc[[1L]]))) / (2 * k)
for(i in 1L:p) {
tG <- A1 %*% (dks[i, k - j + 1L, j + 1L] * In + Gc[[i]]) +
A2 %*% (dks[i + 1L, k - j, j + 1L] * In + Go[[j + 1L]][[i + 1L]]) +
A3 %*% (dks[i + 1L, k - j + 1L, j] * In + Go[[j]][[i + 1L]])
gc[[i + 1L]] <- (tG - Go[[j + 1L]][[i + 1L]] - Go[[j]][[i + 1L]]
- ((dks[i + 1L, k - j, j + 1L] + dks[i + 1L, k - j + 1L, j]) * In)) %*% mu +
A1 %*% gc[[i]] + A2 %*% go[[j + 1L]][[i + 1L]] + A3 %*% go[[j]][[i + 1L]]
Gc[[i + 1L]] <- tG
dks[i + 1L, k - j + 1L, j + 1L] <- (tr(Gc[[i + 1L]]) + c(crossprod(mu, gc[[i + 1L]]))) / (2 * (k + i))
}
Gn <- c(Gn, list(Gc))
gn <- c(gn, list(gc))
}
}
tG <- A3 %*% (dks[1L, 1L, k] * In + Go[[k]][[1L]])
gc[[1L]] <- (tG - Go[[k]][[1L]] - (dks[1L, 1L, k] * In)) %*% mu + A3 %*% go[[k]][[1L]]
Gc[[1L]] <- tG
dks[1L, 1L, k + 1L] <- (tr(Gc[[1L]]) + c(crossprod(mu, gc[[1L]]))) / (2 * k)
for(i in 1L:p) {
tG <- A1 %*% (dks[i, 1L, k + 1L] * In + Gc[[i]]) +
A3 %*% (dks[i + 1L, 1L, k] * In + Go[[k]][[i + 1L]])
gc[[i + 1L]] <- (tG - Go[[k]][[i + 1L]]
- (dks[i + 1L, 1L, k] * In)) %*% mu +
A1 %*% gc[[i]] + A3 %*% go[[k]][[i + 1L]]
Gc[[i + 1L]] <- tG
dks[i + 1L, 1L, k + 1L] <- (tr(Gc[[i + 1L]]) + c(crossprod(mu, gc[[i + 1L]]))) / (2 * (k + i))
}
Gn <- c(Gn, list(Gc))
gn <- c(gn, list(gc))
if(max(unlist(Gn)) > thr || max(unlist(gn)) > thr) {
ind_dks <- which(order_array == k)
ind_lscf <- which(order_array >= k)
dks[ind_dks] <- dks[ind_dks] / 1e10
Gn <- lapply(Gn, function(x) lapply(x, function(y) y / 1e10))
gn <- lapply(gn, function(x) lapply(x, function(y) y / 1e10))
lscf[ind_lscf] <- lscf[ind_lscf] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### htil3_pjk_v #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with three matrices
#'
#' @rdname d3_ijk
#'
htil3_pjk_v <- function(L1, L2, L3, mu = rep.int(0, n), m = 100L, p = 1L,
thr_margin = 100) {
n <- length(L1)
p1 <- p + 1L
m1 <- m + 1L
dks <- array(0, dim = c(p1, m1, m1))
dks[1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
order_array <- outer(outer(rep.int(0, p1), 0:m, "+"), 0:m, "+")
zeros <- rep.int(0, n)
Gc <- list()
gc <- list()
Gc[1L:p1] <- list(zeros)
gc[1L:p1] <- list(zeros)
for(i in 1L:p) {
Gc[[i + 1L]] <- L1 * (dks[i, 1L, 1L] + Gc[[i]])
gc[[i + 1L]] <- Gc[[i + 1L]] * mu + L1 * gc[[i]]
dks[i + 1L, 1L, 1L] <- (sum(Gc[[i + 1L]]) + sum(mu * gc[[i + 1L]])) / (2 * i)
}
Gn <- list(Gc)
gn <- list(gc)
for(k in 1L:m) {
Go <- Gn
go <- gn
tG <- L2 * (dks[1L, k, 1L] + Go[[1L]][[1L]])
gc[[1L]] <- (tG - (Go[[1L]][[1L]] + dks[1L, k, 1L])) * mu + L2 * go[[1L]][[1L]]
Gc[[1L]] <- tG
dks[1L, k + 1L, 1L] <- (sum(Gc[[1L]]) + sum(mu * gc[[1L]])) / (2 * k)
for(i in 1L:p) {
tG <- L1 * (dks[i, k + 1L, 1L] + Gc[[i]]) +
L2 * (dks[i + 1L, k, 1L] + Go[[1L]][[i + 1L]])
gc[[i + 1L]] <- (tG - (Go[[1L]][[i + 1L]]
+ dks[i + 1L, k, 1L])) * mu +
L1 * gc[[i]] + L2 * go[[1L]][[i + 1L]]
Gc[[i + 1L]] <- tG
dks[i + 1L, k + 1L, 1L] <- (sum(Gc[[i + 1L]]) + sum(mu * gc[[i + 1L]])) / (2 * (k + i))
}
Gn <- list(Gc)
gn <- list(gc)
if(k >= 2L) {
for(j in 1L:(k - 1L)) {
tG <- L2 * (dks[1L, k - j, j + 1L] + Go[[j + 1L]][[1L]]) + L3 * (dks[1L, k - j + 1L, j] + Go[[j]][[1L]])
gc[[1L]] <- (tG - (Go[[j + 1L]][[1L]] + Go[[j]][[1L]] + dks[1L, k - j, j + 1L] + dks[1L, k - j + 1L, j])) * mu + L2 * go[[j + 1L]][[1L]] + L3 * go[[j]][[1L]]
Gc[[1L]] <- tG
dks[1L, k - j + 1L, j + 1L] <- (sum(Gc[[1L]]) + sum(mu * gc[[1L]])) / (2 * k)
for(i in 1L:p) {
tG <- L1 * (dks[i, k - j + 1L, j + 1L] + Gc[[i]]) +
L2 * (dks[i + 1L, k - j, j + 1L] + Go[[j + 1L]][[i + 1L]]) +
L3 * (dks[i + 1L, k - j + 1L, j] + Go[[j]][[i + 1L]])
gc[[i + 1L]] <- (tG - (Go[[j + 1L]][[i + 1L]] + Go[[j]][[i + 1L]]
+ dks[i + 1L, k - j, j + 1L]
+ dks[i + 1L, k - j + 1L, j])) * mu +
L1 * gc[[i]] + L2 * go[[j + 1L]][[i + 1L]] + L3 * go[[j]][[i + 1L]]
Gc[[i + 1L]] <- tG
dks[i + 1L, k - j + 1L, j + 1L] <- (sum(Gc[[i + 1L]]) + sum(mu * gc[[i + 1L]])) / (2 * (k + i))
}
Gn <- c(Gn, list(Gc))
gn <- c(gn, list(gc))
}
}
tG <- L3 * (dks[1L, 1L, k] + Go[[k]][[1L]])
gc[[1L]] <- (tG - (Go[[k]][[1L]] + dks[1L, 1L, k])) * mu + L3 * go[[k]][[1L]]
Gc[[1L]] <- tG
dks[1L, 1L, k + 1L] <- (sum(Gc[[1L]]) + sum(mu * gc[[1L]])) / (2 * k)
for(i in 1L:p) {
tG <- L1 * (dks[i, 1L, k + 1L] + Gc[[i]]) +
L3 * (dks[i + 1L, 1L, k] + Go[[k]][[i + 1L]])
gc[[i + 1L]] <- (tG - (Go[[k]][[i + 1L]]
+ dks[i + 1L, 1L, k])) * mu +
L1 * gc[[i]] + L3 * go[[k]][[i + 1L]]
Gc[[i + 1L]] <- tG
dks[i + 1L, 1L, k + 1L] <- (sum(Gc[[i + 1L]]) + sum(mu * gc[[i + 1L]])) / (2 * (k + i))
}
Gn <- c(Gn, list(Gc))
gn <- c(gn, list(gc))
if(max(unlist(Gn)) > thr || max(unlist(gn)) > thr) {
ind_dks <- which(order_array == k)
ind_lscf <- which(order_array >= k)
dks[ind_dks] <- dks[ind_dks] / 1e10
Gn <- lapply(Gn, function(x) lapply(x, function(y) y / 1e10))
gn <- lapply(gn, function(x) lapply(x, function(y) y / 1e10))
lscf[ind_lscf] <- lscf[ind_lscf] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### hhat2_pj_m #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with two matrices
#'
#' @rdname d2_ij
#'
hhat2_pj_m <- function(A1, A2, mu = rep.int(0, n), m = 100L, p = 1L,
thr_margin = 100) {
if(p == 1L) return(hhat2_1j_m(A1, A2, mu, m))
n <- ncol(A1)
p1 <- p + 1L
m1 <- m + 1L
In <- diag(n)
dks <- matrix(0, p1, m1)
dks[1L, 1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
zeromat <- matrix(0, n, n)
zerovec <- matrix(0, n, 1)
G_k_i <- list()
g_k_i <- list()
G_k_i[1L:p1] <- list(zeromat)
g_k_i[1L:p1] <- list(zerovec)
for(i in 1L:p) {
G_k_i[[i + 1L]] <- A1 %*% (dks[i, 1L] * In + G_k_i[[i]])
g_k_i[[i + 1L]] <- G_k_i[[i + 1L]] %*% mu + A1 %*% g_k_i[[i]]
dks[i + 1L, 1L] <- (tr(G_k_i[[i + 1L]]) + c(crossprod(mu, g_k_i[[i + 1L]]))) / (2 * i)
}
for(k in 1L:m) {
tG <- A2 %*% (dks[1L, k] * In + G_k_i[[1L]])
g_k_i[[1L]] <- (tG + G_k_i[[1L]] + (dks[1L, k] * In)) %*% mu + A2 %*% g_k_i[[1L]]
G_k_i[[1L]] <- tG
dks[1L, k + 1L] <- (tr(G_k_i[[1L]]) + c(crossprod(mu, g_k_i[[1L]]))) / (2 * k)
for(i in 1L:p) {
tG <- A1 %*% (dks[i, k + 1L] * In + G_k_i[[i]]) +
A2 %*% (dks[i + 1L, k] * In + G_k_i[[i + 1L]])
g_k_i[[i + 1L]] <- (tG + G_k_i[[i + 1L]]
+ (dks[i + 1L, k] * In)) %*% mu +
A1 %*% g_k_i[[i]] + A2 %*% g_k_i[[i + 1L]]
G_k_i[[i + 1L]] <- tG
dks[i + 1L, k + 1L] <- (tr(G_k_i[[i + 1L]]) + c(crossprod(mu, g_k_i[[i + 1L]]))) / (2 * (k + i))
}
if(max(unlist(G_k_i)) > thr || max(unlist(g_k_i)) > thr) {
dks[, k + 1L] <- dks[, k + 1L] / 1e10
G_k_i <- lapply(G_k_i, function(x) x / 1e10)
g_k_i <- lapply(g_k_i, function(x) x / 1e10)
lscf[, (k + 1L):m1] <- lscf[, (k + 1L):m1] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### hhat2_1j_m #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with two matrices
#'
#' @rdname d2_ij
#'
hhat2_1j_m <- function(A1, A2, mu = rep.int(0, n), m = 100L, thr_margin = 100) {
n <- ncol(A1)
m1 <- m + 1L
In <- diag(n)
dks <- matrix(0, 2L, m + 1L)
dks[1L, 1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
G_k_0 <- matrix(0, n, n)
G_k_1 <- A1
g_k_0 <- matrix(0, n, 1)
g_k_1 <- G_k_1 %*% mu
dks[2L, 1L] <- (tr(G_k_1) + c(crossprod(mu, g_k_1))) / 2
for(k in 1L:m) {
tG <- A2 %*% (dks[1L, k] * In + G_k_0)
g_k_0 <- (tG + G_k_0 + (dks[1L, k] * In)) %*% mu + A2 %*% g_k_0
G_k_0 <- tG
dks[1L, k + 1L] <- (tr(G_k_0) + c(crossprod(mu, g_k_0))) / (2 * k)
tG <- A1 %*% (dks[1L, k + 1L] * In + G_k_0) +
A2 %*% (dks[2L, k] * In + G_k_1)
g_k_1 <- (tG + G_k_1 + (dks[2L, k] * In)) %*% mu +
A1 %*% g_k_0 + A2 %*% g_k_1
G_k_1 <- tG
dks[2L, k + 1L] <- (tr(G_k_1) + c(crossprod(mu, g_k_1))) / (2 * (k + 1))
if(max(G_k_1) > thr || max(g_k_1) > thr) {
dks[, k + 1L] <- dks[, k + 1L] / 1e10
G_k_0 <- G_k_0 / 1e10
G_k_1 <- G_k_1 / 1e10
g_k_0 <- g_k_0 / 1e10
g_k_1 <- g_k_1 / 1e10
lscf[, (k + 1L):m1] <- lscf[, (k + 1L):m1] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### hhat2_pj_v #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with two matrices
#'
#' @rdname d2_ij
#'
hhat2_pj_v <- function(L1, L2, mu = rep.int(0, n), m = 100L, p = 1L,
thr_margin = 100) {
if(p == 1L) return(hhat2_1j_v(L1, L2, mu, m))
n <- length(L1)
p1 <- p + 1L
m1 <- m + 1L
dks <- matrix(0, p1, m1)
dks[1L, 1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
zeros <- rep.int(0, n)
G_k_i <- list()
g_k_i <- list()
G_k_i[1L:p1] <- list(zeros)
g_k_i[1L:p1] <- list(zeros)
for(i in 1L:p) {
G_k_i[[i + 1L]] <- L1 * (dks[i, 1L] + G_k_i[[i]])
g_k_i[[i + 1L]] <- G_k_i[[i + 1L]] * mu + L1 * g_k_i[[i]]
dks[i + 1L, 1L] <- sum(G_k_i[[i + 1L]] + mu * g_k_i[[i + 1L]]) / (2 * i)
}
for(k in 1L:m) {
tG <- L2 * (dks[1L, k] + G_k_i[[1L]])
g_k_i[[1L]] <- (tG + G_k_i[[1L]] + dks[1L, k]) * mu + L2 * g_k_i[[1L]]
G_k_i[[1L]] <- tG
dks[1L, k + 1L] <- sum(G_k_i[[1L]] + mu * g_k_i[[1L]]) / (2 * k)
for(i in 1L:p) {
tG <- L1 * (dks[i, k + 1L] + G_k_i[[i]]) +
L2 * (dks[i + 1L, k] + G_k_i[[i + 1L]])
g_k_i[[i + 1L]] <- (tG + G_k_i[[i + 1L]] + dks[i + 1L, k]) * mu +
L1 * g_k_i[[i]] + L2 * g_k_i[[i + 1L]]
G_k_i[[i + 1L]] <- tG
dks[i + 1L, k + 1L] <- sum(G_k_i[[i + 1L]] + mu * g_k_i[[i + 1L]]) / (2 * (k + i))
}
if(max(unlist(G_k_i)) > thr || max(unlist(g_k_i)) > thr) {
dks[, k + 1L] <- dks[, k + 1L] / 1e10
G_k_i <- lapply(G_k_i, function(x) x / 1e10)
g_k_i <- lapply(g_k_i, function(x) x / 1e10)
lscf[, (k + 1L):m1] <- lscf[, (k + 1L):m1] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### hhat2_1j_v #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with two matrices
#'
#' @rdname d2_ij
#'
hhat2_1j_v <- function(L1, L2, mu = rep.int(0, n), m = 100L, thr_margin = 100) {
n <- length(L1)
m1 <- m + 1L
dks <- matrix(0, 2L, m1)
dks[1L, 1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
G_k_0 <- rep.int(0, n)
G_k_1 <- L1
g_k_0 <- rep.int(0, n)
g_k_1 <- G_k_1 * mu
dks[2L, 1L] <- sum(G_k_1 + mu * g_k_1) / 2
for(k in 1L:m) {
tG <- L2 * (dks[1L, k] + G_k_0)
g_k_0 <- (tG + G_k_0 + dks[1L, k]) * mu + L2 * g_k_0
G_k_0 <- tG
dks[1L, k + 1L] <- sum(G_k_0 + mu * g_k_0) / (2 * k)
tG <- L1 * (dks[1L, k + 1L] + G_k_0) + L2 * (dks[2L, k] + G_k_1)
g_k_1 <- (tG + G_k_1 + dks[2L, k]) * mu + L1 * g_k_0 + L2 * g_k_1
G_k_1 <- tG
dks[2L, k + 1L] <- sum(G_k_1 + mu * g_k_1) / (2 * (k + 1))
if(max(G_k_1) > thr || max(g_k_1) > thr) {
dks[, k + 1L] <- dks[, k + 1L] / 1e10
G_k_0 <- G_k_0 / 1e10
G_k_1 <- G_k_1 / 1e10
g_k_0 <- g_k_0 / 1e10
g_k_1 <- g_k_1 / 1e10
lscf[, (k + 1L):m1] <- lscf[, (k + 1L):m1] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### hhat3_pjk_m #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with three matrices
#'
#' @rdname d3_ijk
#'
hhat3_pjk_m <- function(A1, A2, A3, mu = rep.int(0, n), m = 100L, p = 1L,
thr_margin = 100) {
n <- ncol(A1)
p1 <- p + 1L
m1 <- m + 1L
In <- diag(n)
dks <- array(0, dim = c(p1, m1, m1))
dks[1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
order_array <- outer(outer(rep.int(0, p1), 0:m, "+"), 0:m, "+")
zeromat <- matrix(0, n, n)
zerovec <- matrix(0, n, 1)
Gc <- list()
gc <- list()
Gc[1L:p1] <- list(zeromat)
gc[1L:p1] <- list(zerovec)
for(i in 1L:p) {
Gc[[i + 1L]] <- A1 %*% (dks[i, 1L, 1L] * In + Gc[[i]])
gc[[i + 1L]] <- Gc[[i + 1L]] %*% mu + A1 %*% gc[[i]]
dks[i + 1L, 1L, 1L] <- (tr(Gc[[i + 1L]]) + c(crossprod(mu, gc[[i + 1L]]))) / (2 * i)
}
Gn <- list(Gc)
gn <- list(gc)
for(k in 1L:m) {
Go <- Gn
go <- gn
tG <- A2 %*% (dks[1L, k, 1L] * In + Go[[1L]][[1L]])
gc[[1L]] <- (tG + Go[[1L]][[1L]] + (dks[1L, k, 1L] * In)) %*% mu + A2 %*% go[[1L]][[1L]]
Gc[[1L]] <- tG
dks[1L, k + 1L, 1L] <- (tr(Gc[[1L]]) + c(crossprod(mu, gc[[1L]]))) / (2 * k)
for(i in 1L:p) {
tG <- A1 %*% (dks[i, k + 1L, 1L] * In + Gc[[i]]) +
A2 %*% (dks[i + 1L, k, 1L] * In + Go[[1L]][[i + 1L]])
gc[[i + 1L]] <- (tG + Go[[1L]][[i + 1L]]
+ (dks[i + 1L, k, 1L] * In)) %*% mu +
A1 %*% gc[[i]] + A2 %*% go[[1L]][[i + 1L]]
Gc[[i + 1L]] <- tG
dks[i + 1L, k + 1L, 1L] <- (tr(Gc[[i + 1L]]) + c(crossprod(mu, gc[[i + 1L]]))) / (2 * (k + i))
}
Gn <- list(Gc)
gn <- list(gc)
if(k >= 2L) {
for(j in 1L:(k - 1L)) {
tG <- A2 %*% (dks[1L, k - j, j + 1L] * In + Go[[j + 1L]][[1L]]) + A3 %*% (dks[1L, k - j + 1L, j] * In + Go[[j]][[1L]])
gc[[1L]] <- (tG + Go[[j + 1L]][[1L]] + Go[[j]][[1L]] + ((dks[1L, k - j, j + 1L] + dks[1L, k - j + 1L, j]) * In)) %*% mu + A2 %*% go[[j + 1L]][[1L]] + A3 %*% go[[j]][[1L]]
Gc[[1L]] <- tG
dks[1L, k - j + 1L, j + 1L] <- (tr(Gc[[1L]]) + c(crossprod(mu, gc[[1L]]))) / (2 * k)
for(i in 1L:p) {
tG <- A1 %*% (dks[i, k - j + 1L, j + 1L] * In + Gc[[i]]) +
A2 %*% (dks[i + 1L, k - j, j + 1L] * In + Go[[j + 1L]][[i + 1L]]) +
A3 %*% (dks[i + 1L, k - j + 1L, j] * In + Go[[j]][[i + 1L]])
gc[[i + 1L]] <- (tG + Go[[j + 1L]][[i + 1L]] + Go[[j]][[i + 1L]]
+ ((dks[i + 1L, k - j, j + 1L] + dks[i + 1L, k - j + 1L, j]) * In)) %*% mu +
A1 %*% gc[[i]] + A2 %*% go[[j + 1L]][[i + 1L]] + A3 %*% go[[j]][[i + 1L]]
Gc[[i + 1L]] <- tG
dks[i + 1L, k - j + 1L, j + 1L] <- (tr(Gc[[i + 1L]]) + c(crossprod(mu, gc[[i + 1L]]))) / (2 * (k + i))
}
Gn <- c(Gn, list(Gc))
gn <- c(gn, list(gc))
}
}
tG <- A3 %*% (dks[1L, 1L, k] * In + Go[[k]][[1L]])
gc[[1L]] <- (tG + Go[[k]][[1L]] + (dks[1L, 1L, k] * In)) %*% mu + A3 %*% go[[k]][[1L]]
Gc[[1L]] <- tG
dks[1L, 1L, k + 1L] <- (tr(Gc[[1L]]) + c(crossprod(mu, gc[[1L]]))) / (2 * k)
for(i in 1L:p) {
tG <- A1 %*% (dks[i, 1L, k + 1L] * In + Gc[[i]]) +
A3 %*% (dks[i + 1L, 1L, k] * In + Go[[k]][[i + 1L]])
gc[[i + 1L]] <- (tG + Go[[k]][[i + 1L]]
+ (dks[i + 1L, 1L, k] * In)) %*% mu +
A1 %*% gc[[i]] + A3 %*% go[[k]][[i + 1L]]
Gc[[i + 1L]] <- tG
dks[i + 1L, 1L, k + 1L] <- (tr(Gc[[i + 1L]]) + c(crossprod(mu, gc[[i + 1L]]))) / (2 * (k + i))
}
Gn <- c(Gn, list(Gc))
gn <- c(gn, list(gc))
if(max(unlist(Gn)) > thr || max(unlist(gn)) > thr) {
ind_dks <- which(order_array == k)
ind_lscf <- which(order_array >= k)
dks[ind_dks] <- dks[ind_dks] / 1e10
Gn <- lapply(Gn, function(x) lapply(x, function(y) y / 1e10))
gn <- lapply(gn, function(x) lapply(x, function(y) y / 1e10))
lscf[ind_lscf] <- lscf[ind_lscf] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
##### hhat3_pjk_v #####
#' Coefficients in polynomial expansion of generating function---for
#' ratio with three matrices
#'
#' @rdname d3_ijk
#'
hhat3_pjk_v <- function(L1, L2, L3, mu = rep.int(0, n), m = 100L, p = 1L,
thr_margin = 100) {
n <- length(L1)
p1 <- p + 1L
m1 <- m + 1L
dks <- array(0, dim = c(p1, m1, m1))
dks[1L] <- 1
lscf <- array(0, dim(dks))
thr <- .Machine$double.xmax / thr_margin / n
order_array <- outer(outer(rep.int(0, p1), 0:m, "+"), 0:m, "+")
zeros <- rep.int(0, n)
Gc <- list()
gc <- list()
Gc[1L:p1] <- list(zeros)
gc[1L:p1] <- list(zeros)
for(i in 1L:p) {
Gc[[i + 1L]] <- L1 * (dks[i, 1L, 1L] + Gc[[i]])
gc[[i + 1L]] <- Gc[[i + 1L]] * mu + L1 * gc[[i]]
dks[i + 1L, 1L, 1L] <- (sum(Gc[[i + 1L]]) + sum(mu * gc[[i + 1L]])) / (2 * i)
}
Gn <- list(Gc)
gn <- list(gc)
for(k in 1L:m) {
Go <- Gn
go <- gn
tG <- L2 * (dks[1L, k, 1L] + Go[[1L]][[1L]])
gc[[1L]] <- (tG + (Go[[1L]][[1L]] + dks[1L, k, 1L])) * mu + L2 * go[[1L]][[1L]]
Gc[[1L]] <- tG
dks[1L, k + 1L, 1L] <- (sum(Gc[[1L]]) + sum(mu * gc[[1L]])) / (2 * k)
for(i in 1L:p) {
tG <- L1 * (dks[i, k + 1L, 1L] + Gc[[i]]) +
L2 * (dks[i + 1L, k, 1L] + Go[[1L]][[i + 1L]])
gc[[i + 1L]] <- (tG + (Go[[1L]][[i + 1L]]
+ dks[i + 1L, k, 1L])) * mu +
L1 * gc[[i]] + L2 * go[[1L]][[i + 1L]]
Gc[[i + 1L]] <- tG
dks[i + 1L, k + 1L, 1L] <- (sum(Gc[[i + 1L]]) + sum(mu * gc[[i + 1L]])) / (2 * (k + i))
}
Gn <- list(Gc)
gn <- list(gc)
if(k >= 2L) {
for(j in 1L:(k - 1L)) {
tG <- L2 * (dks[1L, k - j, j + 1L] + Go[[j + 1L]][[1L]]) + L3 * (dks[1L, k - j + 1L, j] + Go[[j]][[1L]])
gc[[1L]] <- (tG + (Go[[j + 1L]][[1L]] + Go[[j]][[1L]] + dks[1L, k - j, j + 1L] + dks[1L, k - j + 1L, j])) * mu + L2 * go[[j + 1L]][[1L]] + L3 * go[[j]][[1L]]
Gc[[1L]] <- tG
dks[1L, k - j + 1L, j + 1L] <- (sum(Gc[[1L]]) + sum(mu * gc[[1L]])) / (2 * k)
for(i in 1L:p) {
tG <- L1 * (dks[i, k - j + 1L, j + 1L] + Gc[[i]]) +
L2 * (dks[i + 1L, k - j, j + 1L] + Go[[j + 1L]][[i + 1L]]) +
L3 * (dks[i + 1L, k - j + 1L, j] + Go[[j]][[i + 1L]])
gc[[i + 1L]] <- (tG + (Go[[j + 1L]][[i + 1L]] + Go[[j]][[i + 1L]]
+ dks[i + 1L, k - j, j + 1L]
+ dks[i + 1L, k - j + 1L, j])) * mu +
L1 * gc[[i]] + L2 * go[[j + 1L]][[i + 1L]] + L3 * go[[j]][[i + 1L]]
Gc[[i + 1L]] <- tG
dks[i + 1L, k - j + 1L, j + 1L] <- (sum(Gc[[i + 1L]]) + sum(mu * gc[[i + 1L]])) / (2 * (k + i))
}
Gn <- c(Gn, list(Gc))
gn <- c(gn, list(gc))
}
}
tG <- L3 * (dks[1L, 1L, k] + Go[[k]][[1L]])
gc[[1L]] <- (tG + (Go[[k]][[1L]] + dks[1L, 1L, k])) * mu + L3 * go[[k]][[1L]]
Gc[[1L]] <- tG
dks[1L, 1L, k + 1L] <- (sum(Gc[[1L]]) + sum(mu * gc[[1L]])) / (2 * k)
for(i in 1L:p) {
tG <- L1 * (dks[i, 1L, k + 1L] + Gc[[i]]) +
L3 * (dks[i + 1L, 1L, k] + Go[[k]][[i + 1L]])
gc[[i + 1L]] <- (tG + (Go[[k]][[i + 1L]]
+ dks[i + 1L, 1L, k])) * mu +
L1 * gc[[i]] + L3 * go[[k]][[i + 1L]]
Gc[[i + 1L]] <- tG
dks[i + 1L, 1L, k + 1L] <- (sum(Gc[[i + 1L]]) + sum(mu * gc[[i + 1L]])) / (2 * (k + i))
}
Gn <- c(Gn, list(Gc))
gn <- c(gn, list(gc))
if(max(unlist(Gn)) > thr || max(unlist(gn)) > thr) {
ind_dks <- which(order_array == k)
ind_lscf <- which(order_array >= k)
dks[ind_dks] <- dks[ind_dks] / 1e10
Gn <- lapply(Gn, function(x) lapply(x, function(y) y / 1e10))
gn <- lapply(gn, function(x) lapply(x, function(y) y / 1e10))
lscf[ind_lscf] <- lscf[ind_lscf] - log(1e10)
}
}
attr(dks, "logscale") <- lscf
return(dks)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.