This document is to provide an overview of the moment-related
functionalities of the R
package qfratio
(CRAN; GitHub). Distribution-related functionalities are
documented in a separate vignette:
vignette("qfratio_distr")
.
The use of n for the number of variables and p, q, … for exponents is to conform with Bao and Kan (2013).
The package primarily concerns moments of ratios of quadratic forms of the following forms: In this package, these are called a simple and multiple ratio, respectively, following Smith (1989) (to be precise, the latter is a very specific case of the multiple ratios treated therein).
Quantities of the above forms frequently occur in the statistical and econometric literature (Mathai and Provost, 1992; Hillier et al., 2009, 2014). In evolutionary biology, the quantities known as evolvability measures have the same general form, and evaluation of their expectation (average or mean evolvability measures) can be of practical interest (Hansen and Houle, 2008; Melo et al., 2016; Watanabe, 2023).
The package is mainly for evaluating the moments of the above quantity assuming the multivariate normality of x, that is, where $\mathbf{x} \sim \qfrmvnorm{\boldsymbol{\mu}}{\boldsymbol{\Sigma}}$.
Here are simple example use cases:
## Simple matrices
nv <- 4
A <- diag(1:nv)
B <- diag(sqrt(nv:1))
D <- diag((nv:1) ^ 2)
## Expectation of (x^T A x)^2 / (x^T x)^1 where x ~ N(0, I)
qfrm(A, p = 2, q = 1) # By default, B = I
#>
#> Moment of ratio of quadratic forms
#>
#> Moment = 26.66667
#> This value is exact
## Expectation of (x^T A x)^2 / (x^T B x)^2 where x ~ N(0, I)
qfrm(A, B, p = 2) # By default, q = p
#>
#> Moment of ratio of quadratic forms
#>
#> Moment = 3.467871, Error = 0 (one-sided)
#> Possible range:
#> 3.46787143 3.46787143
## Expectation of (x^T A x)^1/2 / (x^T B x)^1 where x ~ N(0, I)
qfrm(A, B, p = 1/2, q = 1)
#>
#> Moment of ratio of quadratic forms
#>
#> Moment = 0.6652398
#> Error bound unavailable; recommended to inspect plot() of this object
## Expectation of (x^T A x)^2 / ((x^T B x)^1 (x^T D x)^1) where x ~ N(0, I)
qfmrm(A, B, D, p = 2, q = 1, r = 1)
#>
#> Moment of ratio of quadratic forms
#>
#> Moment = 1.135126
#> Error bound unavailable; recommended to inspect plot() of this object
## Expectation of (x^T A x)^1 / (x^T B x)^1 where x ~ N(mu, Sigma)
## with arbitrary mu and Sigma
mu <- 1:nv / nv
Sigma <- diag(runif(nv) * 3)
qfrm(A, B, p = 1, q = 1, mu = mu, Sigma = Sigma, m = 300)
#>
#> Moment of ratio of quadratic forms
#>
#> Moment = 2.210412, Error = 0 (two-sided)
#> Possible range:
#> 2.21041201 2.21041201
In each of the above examples, the function qfrm()
(quadratic form ratio moment) or
qfmrm()
(quadratic form multiple
ratio moment) is called to calculate the moment. The
function calls are followed by outputs from the print
method for the results, which show the values of the moments.
You might have wondered what it means by results being “exact” or
having “error”, or about the unexplained argument m = 300
in the last example. Seeing this requires some excursion into the math
involved.
For the above quantities to be well-defined and have finite moments:
For the simple ratio, the necessary and sufficient conditions for the moment to exist is stated in Bao and Kan (2013, proposition 1):
For the multiple ratio, the existence conditions are more difficult
to define. When the null space of B is a subspace of that of
D (or vice versa), the
existence problem reduces to that of the simple ratio, and the above
conditions apply by inserting the rank of B and q + r into l and q above (Watanabe, 2023). However, when
both B and D are singular and neither
of their ranges is a subspace of each other, no general existence
conditions seem to be known in the literature. See the documentations
for qfrm
and qfmrm
for the behaviors when the
existence conditions are not satisfied.
There are several equivalent expressions for moments of ratios of quadratic forms in normal variables, only some of which are amenable to straightforward numerical evaluation. The package uses one class of such expressions, based on a series expansion and term-by-term integration of a ratio (Smith, 1989, 1993; Hillier, 2001; Hillier et al., 2009, 2014; Bao and Kan, 2013).
The following expressions assume $\mathbf{x} \sim \qfrmvnorm{\boldsymbol{\mu}}{\mathbf{I}_n}$. For arbitrary but nonsingular Σ, it is always possible to transform the variables and argument matrices by using xnew = K−1x, Anew = KTAK, etc., where K is an n × n matrix that satisfies KKT = Σ (Mathai and Provost, 1992, chap. 3). When Σ is singular, certain conditions need to be met by the argument matrices, Σ, and μ for this transformation, and hence the following expressions, to be valid (Watanabe, 2023, appendix C).
For the simple ratio with an arbitrary (positive real) p, when the moment exists, the expression is (Bao and Kan, 2013, eq. (12)) and for a positive-integral p, this can be simplified into (Bao and Kan, 2013, eq. (13), correcting a typo):
For the multiple ratio, the expression for an arbitrary p is (after Smith, 1989, eq. (5.2)) and for a positive-integral p (Watanabe, 2023, eq. (B28)),
In these expressions, β⋅ are arbitrary scaling constants that satisfy $0 < \beta < 2 / \qfrlmax$, with $\qfrlmax$ being the largest eigenvalue of the argument matrix. In addition, hk1, …ks and h̃k1; k2…ks are the coefficients of t1k1…tsks in the following power series expansions: (These notations follow Bao and Kan (2013); Hillier et al. (2014) used the symbol h for h̃ here.)
A common special case is when μ = 0n, in which case the coefficients d in the following expansion is used:
Actually, the above expressions (1)–(4) can be written in terms of d with an additional argument (Hillier et al., 2009; Bao and Kan, 2013), but those alternative expressions are not utilized in the package.
A theoretically important result is that this d is related to the top-order zonal and invariant polynomials of matrix arguments, C (Chikuse, 1987; Hillier et al., 2009): where $\qfrbrc{k_i}$ and the like denote the top-order partitions of ki, in the notation of Smith (1989).
Note that the order of the argument matrices is arbitrary in d or h, but not in h̃ where A1 is not interchangeable with the other arguments.
A notable special case for moments of simple ratios is when p is a positive integer and B = In. In this case, (2) simplifies into (Hillier et al., 2014, theorem 4) where 1F1(⋅; ⋅; ⋅) is the confluent hypergeometric function, and ap, k are the coefficients of tp in As the lowest-order term in this last expansion is that of tk, ap, k = 0 for k > p, so that the series in (5) truncates at k = p. This truncation enables quasi-exact evaluation of the moment, given accurate evaluation of the hypergeometric function.
When μ = 0n in addition, (5) further simplifies as ap, k = 0 for k > 0, so that the series essentially vanishes leaving only the term for k = 0. Similar simplification happens in (1), (3), and (4) as well when any of the argument matrices is In and μ = 0n, although they will still involve a single or double infinite series.
The above expressions (1)–(4) are exact, but their exact values
cannot generally be evaluated as they involve infinite series, except
when the conditions for (5) apply. Fortunately, the series are
absolutely convergent, so that their partial sums up to certain orders
typically yield a sufficiently accurate result. This is what is done by
the qfrm()
and qfmrm()
functions. The order of
evaluation is determined by the argument m
; the functions
calculate the terms from i = j = k = 0 to
i + j + k ≤ m
(as i, j, k
appear in the above summations) and then return an m + 1 vector that contains sums of
the same-order terms, along with other things.
The default is m = 100
, which sufficed for most of the
above examples, but for large problems, the user would want to use a
larger value (which can be hundreds of thousands for very large
problems; see below).
The coefficients d, h, h̃ are evaluated by recursive algorithms described below. At the core of this package are internal functions to implement these recursive algorithms, which can be computationally intensive as the problem becomes larger.
A great advantage in the above expressions is that an error bound is available for a partial (truncated) sum for the simple ratio, provided that p is a positive integer and B is positive definite. By denoting the expression (2) as M(A, B, p, q) and the partial sum of the same up to j = m as M̂m(A, B, p, q), the error bound is (Hillier et al., 2014, theorem 7) where A+ is a symmetric matrix constructed from the eigenvectors and “positivized” eigenvalues of A (above), $\bar{\boldsymbol{\mu}} = \sqrt{2}\left( \beta_\mathbf{B} \mathbf{B} \right)^{-\frac{1}{2}} \boldsymbol{\mu}$, $\bar{\mathbf{A}} = \beta_{\mathbf{B}}^{-1} \mathbf{B}^{-\frac{1}{2}} \mathbf{A}^+ \mathbf{B}^{-\frac{1}{2}}$, and d̃ and ĥ are coefficients in the following generating functions:
For the multiple ratio, a similar error bound is available when D = In, in addition to p being a positive integer. By denoting the expression (4) as M(A, B, D, p, q, r), and the partial sum of (4) up to j + k = m as M̂m(A, B, D, p, q, r), the error bound is where $\tilde{\boldsymbol{\mu}} = \sqrt{3}\left( \beta_\mathbf{B} \mathbf{B} \right)^{-\frac{1}{2}} \boldsymbol{\mu}$ and other notations are as above.
The coefficients h, h̃, and ĥ in the above series expressions are evaluated by the “super-short” recursive algorithm developed by Hillier and colleagues (Bao and Kan, 2013; Hillier et al., 2014). That is, where with the initial conditions h0, 0, 0 = h̃0, 0, 0 = ĥ0, 0, 0 = 1 (as per Hillier et al. (2014), but not 0, as incorrectly printed in Bao and Kan (2013)), $\mathbf{G}_{0,0,0} = \tilde{\mathbf{G}}_{0,0,0} = \hat{\mathbf{G}}_{0,0,0} = \mathbf{0}_{n \times n}$, and $\mathbf{g}_{0,0,0} = \tilde{\mathbf{g}}_{0,0,0} = \hat{\mathbf{g}}_{0,0,0} = \mathbf{0}_n$. If any of the indices is negative, the term is treated as 0.
The recursion for d can be obtained by just inserting μ = 0n (and hence omitting g altogether) in that for h, and those for the two-argument versions are by omitting any terms with A3 or k − 1 as an index in the corresponding three-argument versions.
The recursion for $\qfrdtk{\mathbf{A}}{\boldsymbol{\mu}}$ is (Bao and Kan, 2013; Hillier et al., 2014): where with λi being the ith eigenvalue of A, δi = (hiTμ)2, hi being the eigenvector of A corresponding to λi, and the initial conditions are d̃0 = 1 and u0, i = v0, i = 0 for all i.
The recursion for ap, k(A, μ) is (Hillier et al., 2014, eqs. (31), (32), noting that w should be indexed by k as well): where with $a_{p,0} = \qfrdk[p]{\mathbf{A}}$ and w0, k, i = 0 for any k, i.
The recursion for $\qfrdk{\mathbf{A}}$ can be obtained either as that for $\qfrdtk{\mathbf{A}}{\mathbf{0}_n}$ (where all v’s are 0) or by dropping any terms with A2 or j − 1 as an index from that for the two-argument version of d above.
The package is designed for evaluation of moments of ratios of
quadratic forms using the recursive algorithms described above. The
primary front-end functions are qfrm()
and
qfmrm()
, which return a qfrm
object containing
terms in the truncated series and error bound when available. Simple
print
and plot
methods are defined for the
qfrm
class, for quick inspection of evaluation results.
qfrm()
: quadratic form ratio
momentThis function is for evaluating moments of the simple ratios of quadratic forms, $\qfrE \left( \frac{\left( \mathbf{x}^T \mathbf{A} \mathbf{x} \right)^p} {\left( \mathbf{x}^T \mathbf{B} \mathbf{x} \right)^q} \right)$, where $\mathbf{x} \sim \qfrmvnorm{\boldsymbol{\mu}}{\boldsymbol{\Sigma}}$.
qfrm(A, B, p = 1, q = p, m = 100L,
mu = rep.int(0, n), Sigma = diag(n),
tol_zero = .Machine$double.eps * 100,
tol_sing = tol_zero, ...)
A
and B
are the argument matrices; when one
is missing, In is
inserted.
m
determines the order of evaluation, so will be one of
the most important arguments specified by the user.
mu
and Sigma
specify the mean and
covariance of x, so by
default $\mathbf{x} \sim
\qfrmvnorm{\mathbf{0}_n}{\mathbf{I}_n}$.
tol_zero
and tol_sing
just determine the
numerical tolerance for assessing identity and singularity,
respectively, so usually need not be changed except when handling edgy
cases.
When Sigma
is provided and not In, this
function calls itself recursively with A
, B
,
and mu
transformed as described above (and dropping
Sigma
).
As the evaluation is based on different series expressions depending
on whether B = In
or not and whether p is an
integer or not, the actual calculation is done by one of the following
four “internal” functions, for which qfrm()
acts as a
switcher:
Function | Argument matrices | p | Expression | Error bound | Number of recursions |
---|---|---|---|---|---|
qfrm_ApIq_int() |
B = In | integer | (5) | Exact* | ∼ p |
qfrm_ApIq_npi() |
B = In | non-positive-integer | (1) (simplified when μ = 0n) | Available only when μ = 0n | ∼ m when μ = 0n; ∼ m2/2 otherwise |
qfrm_ApBq_int() |
B arbitrary | integer | (2) | Available | ∼ (p + 1)m |
qfrm_ApBq_npi() |
B arbitrary | non-positive-integer | (1) | Unavailable | ∼ m2/2 |
*: assuming accurate evaluation of the confluent hypergeometric function when μ ≠ 0n
These functions are exported into the package namespace so can be directly used if necessary.
They do the following operations:
A
, B
being square, p
, q
being scalar)A <- (A + t(A)) / 2
; same for B
)A
, B
, and mu
with the
eigenvectors of B
, to
A
is co-diagonalized, in which case
computation can be simplifiedm
with an internal functionqfrm_ApBq_npi()
, the same-order terms in the double
series are summed upBy default, the steps 4–8 are handled by internal C++
functions. The steps 7 and 8 can be suppressed if desired (by using
check_convergence = "none"
or FALSE
and
error_bound = FALSE
, respectively).
qfmrm()
: quadratic form
multiple ratio momentThis function is for evaluating moments of the multiple ratios of quadratic forms, $\qfrE \left( \frac{\left( \mathbf{x}^T \mathbf{A} \mathbf{x} \right)^p} {\left( \mathbf{x}^T \mathbf{B} \mathbf{x} \right)^q\left( \mathbf{x}^T \mathbf{D} \mathbf{x} \right)^r} \right)$, where $\mathbf{x} \sim \qfrmvnorm{\boldsymbol{\mu}}{\boldsymbol{\Sigma}}$.
It works in a way very similar to qfrm()
, just with the
additional arguments D
and r
. The
corresponding “internal” functions are:
Function | Argument matrices | p | Expression | Error bound | Number of recursions |
---|---|---|---|---|---|
qfmrm_ApBIqr_int() |
D = In | integer | (4) (simplified when μ = 0n) | Available | ∼ (p + 1)m when μ = 0n; ∼ (p + 1)m2/2 otherwise |
qfmrm_ApBIqr_npi() |
D = In | non-positive-integer | (3) (simplified when μ = 0n) | Unavailable | ∼ m2/2 when μ = 0n; ∼ m3/6 otherwise |
qfmrm_IpBDqr_gen() |
A = In | general | (4) simplified (when μ = 0n) or (3) (otherwise) | Unavailable | ∼ m2/2 when μ = 0n; ∼ m3/6 otherwise |
qfmrm_ApBDqr_int() |
Arbitrary | integer | (4) | Unavailable | ∼ (p + 1)m2/2 |
qfmrm_ApBDqr_npi() |
Arbitrary | non-positive-integer | (3) | Unavailable | ∼ m3/6 |
qfmrm(A, B, D, p = 1, q = p/2, r = q, m = 100L,
mu = rep.int(0, n), Sigma = diag(n),
tol_zero = .Machine$double.eps * 100,
tol_sing = tol_zero, ...)
Essentially the same as qfrm()
.
qfm_Ap_int()
, qfpm_ABpq_int()
,
qfpm_ABDpqr_int()
: quadratic form
(product) momentThese functions are for evaluating moments of (products of) quadratic forms, $\qfrE \left( \left( \mathbf{x}^T \mathbf{A} \mathbf{x} \right)^p \right)$, $\qfrE \left( \left( \mathbf{x}^T \mathbf{A} \mathbf{x} \right)^p \left( \mathbf{x}^T \mathbf{B} \mathbf{x} \right)^q \right)$, and $\qfrE \left( \left( \mathbf{x}^T \mathbf{A} \mathbf{x} \right)^p \left( \mathbf{x}^T \mathbf{B} \mathbf{x} \right)^q \left( \mathbf{x}^T \mathbf{D} \mathbf{x} \right)^r \right)$, where $\mathbf{x} \sim \qfrmvnorm{\boldsymbol{\mu}}{\boldsymbol{\Sigma}}$, using the algorithm described in Hillier et al. (2014, secs. 3–4). The exponents must be positive integers.
In principle, the same algorithm can be applied to a product of more than three quadratic forms, but this package has not implemented functions for them.
As these expressions only involve finite series, all the results are
exact. The functions return a qfpm
object, for which a
simple print
method is defined.
qfpm_ABDpqr_int(A, B, D, p = 1, q = 1, r = 1,
mu = rep.int(0, n), Sigma = diag(n),
use_cpp = TRUE, cpp_method = "double",
tol_zero = .Machine$double.eps * 100,
tol_sing = tol_zero)
The other two functions have the same arguments, just dropping the inapplicable argument matrices and exponents.
cpp_method
is a dummy argument and ignored in these
functions.
rqfr()
, rqfmr()
, rqfp()
:
random number generationThese functions generate a random sample of the simple ratio $\frac{\left( \mathbf{x}^T \mathbf{A} \mathbf{x} \right)^p} {\left( \mathbf{x}^T \mathbf{B} \mathbf{x} \right)^q}$, multiple ratio $\frac{\left( \mathbf{x}^T \mathbf{A} \mathbf{x} \right)^p} {\left( \mathbf{x}^T \mathbf{B} \mathbf{x} \right)^q\left( \mathbf{x}^T \mathbf{D} \mathbf{x} \right)^r}$, and product (xTAx)p(xTBx)q(xTDx)r, respectively, of quadratic forms in normal variables $\mathbf{x} \sim \qfrmvnorm{\boldsymbol{\mu}}{\boldsymbol{\Sigma}}$.
They can be used for verifying results from the above functions, or as a Monte Carlo surrogate when numerical convergence cannot be obtained within reasonable computational memory and time.
rqfr(nit = 1000L, A, B, p = 1, q = p, mu, Sigma, use_cpp = TRUE)
rqfmr(nit = 1000L, A, B, D, p = 1, q = p/2, r = q, mu, Sigma, use_cpp = TRUE)
rqfp(nit = 1000L, A, B, D, p = 1, q = 1, r = 1, mu, Sigma, use_cpp = TRUE)
Similar to the regular random number generation functions, e.g.,
stats::rnorm()
; the first argument nit
is the
desired size of the random sample (or number of
iteration), followed by other parameters.
d1_i()
, d2_*j_*()
,
d3_*jk_*()
, etc.: recursion algorithmsThe package has a number of internal functions that implement the
recursive algorithms described above. They are usually
not accessed by the user, but are documented herein to
aid understanding of the package structure. Note also that, by default,
the actual calculations are handled by C++
equivalents,
which are not exposed to the user.
Arranged in the target variable and the number of argument matrices, these are:
Target | One matrix | Two matrices | Three matrices |
---|---|---|---|
d | d1_i() |
d2_ij_*() , d2_pj_*() |
d3_ijk_*() , d3_pjk_*() |
d̃ | dtil1_i_*() |
dtil2_pq_*() |
dtil3_pqr_*() |
h | — | h2_ij_*() |
h3_ijk_*() |
h̃ | — | htil2_pj_*() |
htil3_pjk_*() |
ĥ | — | hhat2_pj_*() |
htil3_pjk_*() |
a | a1_pk() |
— | — |
The functions with *_ij_*
or *_ijk_*
are to
calculate terms in double and triple infinite series, with the
dimensions of the output determined by the argument m
(typically used with non-integer p, (1) or (3) above), whereas
*_pj_*
and *_pjk_*
are for the terms in series
truncated along the first argument matrix (used with integral p, (2) or (4)). The one matrix
functions assume either of these two cases, and
dtil2_pq_*()
and dtil3_pqr_*()
assume finite
series along all argument matrices.
All these functions, excepting d1_i()
and
a1_pk()
, have two versions ending in *_m
or
*_v
, which stand for the matrix and vector “methods”. The
latter is for the situations where all the argument matrices are
co-diagonalized by the same eigenvectors, in which case the above
recursive algorithms reduce from full matrix arithmetic to element-wise
operations of the eigenvalues (and the rotated mean vector), which is
much less computationally intensive.
Most of these functions automatically scale the result to avoid numerical overflow, and (log of) the scaling factors are appended as an attribute of the return value, so that the front-end functions can appropriately scale the results back to the original one (see below).
This package implements the recursive algorithms with
C++
functions with the aid of the RcppEigen
package to accelerate calculations. The evaluation of moments can still
be computationally intensive and take non-trivial computational time,
especially when a double or triple series is involved (see (1), (3) and
(4)).
Unless an exact solution is available (i.e., when using (5)), it is
always recommended to check for numerical convergence by inspecting the
error bound and the plot
method. Thus, a recommended
workflow is:
qfrm()
(or qfmrm()
) with the desired
arguments with a small m
(perhaps the default
m = 100
), assigning the result into an
object
print
method (or list
element access), paying attention to the error bound whenever
availableplot()
of the object to see if numerical
convergence has been reachedm
Here are some examples:
## Preparing simple objects
nv <- 10
A <- diag(1:nv)
B <- diag(sqrt(nv:1))
#####
## I: Simple case, (x^T A t)^2 / (x^T x)^2, where x ~ N(0, I)
## Exact solution available
res <- qfrm(A, p = 2, q = 2)
res
#>
#> Moment of ratio of quadratic forms
#>
#> Moment = 31.625
#> This value is exact
## In this case, plot is moot because the result is exact
#####
## II: Simple case, (x^T A t)^2 / (x^T B x)^2, where x ~ N(0, I)
## Error bound available
res <- qfrm(A, B, 2, 2)
res
#>
#> Moment of ratio of quadratic forms
#>
#> Moment = 7.319712, Error = 8.470329e-21 (one-sided)
#> Possible range:
#> 7.31971208 7.31971208
## Displaying more digits
print(res, digits = 10)
#>
#> Moment of ratio of quadratic forms
#>
#> Moment = 7.319712084, Error = 8.470329473e-21 (one-sided)
#> Possible range:
#> 7.31971208375 7.31971208375
## Direct access to the results:
names(res)
#> [1] "statistic" "error_bound" "terms" "seq_error"
res$statistic # Evaluation result (partial sum)
#> [1] 7.319712
res$error_bound # Error bound for $statistic
#> [1] 8.470329e-21
tail(res$terms) # Tail of truncated series; sum($terms) == $statistic
#> [1] 3.543891e-20 2.339201e-20 1.544571e-20 1.020231e-20 6.741185e-21
#> [6] 4.455725e-21
tail(res$seq_error) # Tail of sequence of error bounds; last one is $error_bound
#> [1] 7.877406e-20 5.421011e-20 4.065758e-20 2.964615e-20 1.948176e-20
#> [6] 8.470329e-21
## Inspect plot
plot(res)
## Note that profile for error bound is shown as
## upper bound of the true value in the plot
#####
## III: Simple case, (x^T A t)^(1/2) / (x^T x)^(1/2), where x ~ N(0, I)
## Error bound can be negative
res <- qfrm(A, p = 1/2, q = 1/2)
res # Note negative (though one-sided) error bound
#>
#> Moment of ratio of quadratic forms
#>
#> Moment = 2.3313, Error = -8.091943e-14 (one-sided)
#> Possible range:
#> 2.33129983 2.33129983
## Inspect plot
plot(res)
#####
## IV: Non-central case, (x^T A t)^2 / (x^T B x)^2, where x ~ N(mu, I)
## Two-sided error bound
mu <- 1:nv / sum(1:nv)
res <- qfrm(A, B, p = 2, q = 2, mu = mu)
res # Note two-sided error bound
#>
#> Moment of ratio of quadratic forms
#>
#> Moment = 7.428816, Error = 3.489776e-19 (two-sided)
#> Possible range:
#> 7.42881636 7.42881636
## plot() automatically handles two-sided error bound
plot(res)
#####
## V: Difficult case with highly dispersed eigenvalues
## Error bound available
A <- diag((1:nv) ^ 2)
B <- diag((nv:1) ^ 3)
res <- qfrm(A, B, 2, 2) # Note the warning
#> Warning in qfrm_ApBq_int(A = A, B = B, p = p, q = q, m = m, mu = mu, tol_zero = tol_zero, : Last term is >1.2e-04 times as large as the series,
#> suggesting non-convergence. Consider using larger m
res
#>
#> Moment of ratio of quadratic forms
#>
#> Moment = 0.06799312, Error = 2.254503 (one-sided)
#> Possible range:
#> 0.0679931219 2.3224957273
plot(res) # Non-convergence evident
## Try larger m
res <- qfrm(A, B, 2, 2, m = 2000)
res
#>
#> Moment of ratio of quadratic forms
#>
#> Moment = 0.06976012, Error = 4.865235e-07 (one-sided)
#> Possible range:
#> 0.0697601234 0.0697606100
plot(res) # Much better
#####
## VI: Difficult case with highly dispersed eigenvalues
## Error bound unavailable
## It is recommended to use a tol_conv stricter than
## the default value, which is .Machine$double.eps ^ (1/4)
res <- qfrm(A, B, 1/2, 1/2, tol_conv = sqrt(.Machine$double.eps))
#> Warning in qfrm_ApBq_npi(A = A, B = B, p = p, q = q, m = m, mu = mu, tol_zero = tol_zero, : Last term is >1.5e-08 times as large as the series,
#> suggesting non-convergence. Consider using larger m
res
#>
#> Moment of ratio of quadratic forms
#>
#> Moment = 0.3954463
#> Error bound unavailable; recommended to inspect plot() of this object
plot(res) # Close to convergence, but still growing
In the last example above, the argument tol_conv
was
used to adjust the tolerance in assessing numerical convergence; by
default (check_convergence = "relative"
), a warning is
thrown when the ratio of the last term in the series to the partial sum
is larger than this tolerance, whose default is
.Machine$double.eps ^ (1/4)
(= ~1.2e-4
). Using
a smaller value for this argument as done above can safeguard against
non-convergence, although it is up to the user’s discretion at which
point the result is deemed satisfactory.
Other options:
check_convergence = "strict_relative"
or
TRUE
: sets tol_conv = .Machine$double.eps
(unless a smaller tol_conv
is specified by the user), which
is rather strictcheck_convergence = "absolute"
: check is done in terms
of absolute value rather than relative magnitudecheck_convergence = "none"
or FALSE
: skips
convergence checkThe computational cost for the recursive algorithms increases
drastically with the order of evaluation m. An approximate number of
recursions required in each function is listed in the tables for
qfrm
and qfmrm
functions above; the
computational memory and time increase at least proportionally to this
value. Of course the computational cost is also influenced by the number
of variables n.
In extremely large problems, therefore, it may be impossible to
obtain a satisfactory numerical convergence within reasonable amount of
time and memory. A potential practical alternative is a Monte Carlo
approach using rqfr()
.
## A large problem
nv <- 200
large_A <- diag(c(1000, rep.int(1, nv - 1)))
large_B <- diag(c(rep.int(1, nv - 1), 1000))
large_D <- diag((nv:1) ^ 2)
res <- qfmrm(large_A, large_B, large_D, 1, 1/2, 1/2, m = 500)
#> Warning in qfmrm_ApBDqr_int(A = A, B = B, D = D, p = p, q = q, r = r, m = m, : Last term is >1.2e-04 times as large as the series,
#> suggesting non-convergence. Consider using larger m
res
#>
#> Moment of ratio of quadratic forms
#>
#> Moment = 0.02519373
#> Error bound unavailable; recommended to inspect plot() of this object
plot(res) # Far to convergence
## This problem needs much larger m (>5000)
## taking computational time + memory
## (though still manageable with a regular machine in this particular case)
## Monte Carlo sample
MCres <- rqfmr(10000, large_A, large_B, large_D, 1, 1/2, 1/2)
## Monte Carlo 95% CI of the moment
mean(MCres) + sd(MCres) / sqrt(10000) * qt(c(0.025, 0.975), 10000 - 1)
#> [1] 0.02958917 0.03117620