library("broadcast")
# variances ====
vc <- datasets::ability.cov$cov
X <- matrix(rnorm(100), 100, ncol(vc))
solve(vc)
#> general picture blocks maze reading
#> general 0.082259001 -0.0312406436 -7.750932e-03 -0.013309494 -2.061705e-02
#> picture -0.031240644 0.2369906996 -2.484938e-02 0.017844845 8.603286e-04
#> blocks -0.007750932 -0.0248493822 1.344272e-02 -0.012544830 -3.802671e-05
#> maze -0.013309494 0.0178448450 -1.254483e-02 0.101625400 5.508423e-03
#> reading -0.020617049 0.0008603286 -3.802671e-05 0.005508423 5.713620e-02
#> vocab -0.002420800 0.0019394999 -1.157864e-03 -0.002857265 -2.406969e-02
#> vocab
#> general -0.002420800
#> picture 0.001939500
#> blocks -0.001157864
#> maze -0.002857265
#> reading -0.024069692
#> vocab 0.020323179
cinv(vc) # faster than `solve()`, but only works on positive definite matrices
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 0.082259001 -0.0312406436 -7.750932e-03 -0.013309494 -2.061705e-02
#> [2,] -0.031240644 0.2369906996 -2.484938e-02 0.017844845 8.603286e-04
#> [3,] -0.007750932 -0.0248493822 1.344272e-02 -0.012544830 -3.802671e-05
#> [4,] -0.013309494 0.0178448450 -1.254483e-02 0.101625400 5.508423e-03
#> [5,] -0.020617049 0.0008603286 -3.802671e-05 0.005508423 5.713620e-02
#> [6,] -0.002420800 0.0019394999 -1.157864e-03 -0.002857265 -2.406969e-02
#> [,6]
#> [1,] -0.002420800
#> [2,] 0.001939500
#> [3,] -0.001157864
#> [4,] -0.002857265
#> [5,] -0.024069692
#> [6,] 0.020323179
all(round(solve(vc), 6) == round(cinv(vc), 6)) # they're the same
#> [1] TRUE
sd_lc(X, vc)
#> [1] 23.18594182 58.14607162 34.27339432 32.28476554 10.93475350
#> [6] 19.24168468 36.91661748 38.92937001 0.09604826 13.55537283
#> [11] 65.61885428 9.43946882 0.76641024 26.53762776 25.92132816
#> [16] 26.03322670 40.15308386 17.76423215 13.85465371 19.10481584
#> [21] 9.02798560 9.16136462 28.35501637 30.54722549 16.75492220
#> [26] 58.14854167 36.72877757 39.83679500 22.79293876 39.77087712
#> [31] 18.70804026 39.43864610 12.78972429 21.96297958 7.61901299
#> [36] 43.48673728 4.51898480 38.06475711 27.08126117 47.20583632
#> [41] 38.53069900 29.72965226 5.41031394 18.34307431 47.65382727
#> [46] 36.18299909 42.51546063 10.13121645 19.93433892 32.72450173
#> [51] 17.16106368 5.12765413 4.32398259 2.26509333 56.24283283
#> [56] 18.25201245 22.64193112 27.28711613 26.98491609 35.96467012
#> [61] 110.57966804 3.49978303 25.69103267 24.54147534 6.09460056
#> [66] 40.36310789 4.99633511 42.04627203 36.58094067 27.91771872
#> [71] 16.34412622 38.55372964 29.49890771 18.16415528 3.51298410
#> [76] 57.31163256 23.22014040 26.18610584 25.92235634 11.60769305
#> [81] 14.78182767 1.68496353 13.85877086 33.90020982 2.57156370
#> [86] 7.74430150 1.31459335 1.71452483 22.13882479 9.09777109
#> [91] 73.67519183 42.52566123 15.09131690 15.16787807 0.52663982
#> [96] 46.16171218 15.59868345 38.98880181 51.06437072 24.36791662
# ecumprob() ====
sim <- rnbinom(10 * 1e4, mu = 3, size = 2) |> matrix(10, 1e4)
y <- sample(0:9)
# vector:
pnbinom(y[1], mu = 3, size = 2) # real probability
#> [1] 0.76672
ecumprob(y[1], sim[1, , drop = TRUE]) # approximation
#> [1] 0.7732
# matrix:
cbind(
real = pnbinom(y, mu = 3, size = 2), # real probability
approx = ecumprob(y, sim) # approximation
)
#> real approx
#> [1,] 0.7667200 0.7732
#> [2,] 0.8413696 0.8449
#> [3,] 0.1600000 0.1618
#> [4,] 0.9294561 0.9303
#> [5,] 0.9697669 0.9717
#> [6,] 0.3520000 0.3520
#> [7,] 0.6630400 0.6646
#> [8,] 0.5248000 0.5253
#> [9,] 0.9536426 0.9547
#> [10,] 0.8936243 0.8919
# data.frame:
cbind(
real = pnbinom(y, mu = 3, size = 2), # real probability
approx = ecumprob(y, as.data.frame(sim)) # approximation
)
#> real approx
#> [1,] 0.7667200 0.7732
#> [2,] 0.8413696 0.8449
#> [3,] 0.1600000 0.1618
#> [4,] 0.9294561 0.9303
#> [5,] 0.9697669 0.9717
#> [6,] 0.3520000 0.3520
#> [7,] 0.6630400 0.6646
#> [8,] 0.5248000 0.5253
#> [9,] 0.9536426 0.9547
#> [10,] 0.8936243 0.8919linear_algebra_stats
Simple Linear Algebra Functions for Statistics
Description
โbroadcastโ provides some simple Linear Algebra Functions for Statistics:
cinv()
sd_lc()
ecumprob()
Usage
cinv(x)
sd_lc(X, vc, bad_rp = NaN)
ecumprob(y, sim, eps = 0)
Arguments
x
|
a real symmetric positive-definite square matrix. |
X
|
a numeric (or logical) matrix of multipliers/constants |
vc
|
the variance-covariance matrix for the (correlated) random variables. |
bad_rp
|
if vc is not a Positive (semi-) Definite matrix, give here the value to replace bad standard deviations with. |
y
|
values to estimate the cumulative probability for. |
sim
|
a matrix (or data.frame) with at least 500 columns of simulated values. If sim is given as a dimensionless vector, it will be treated as a matrix with 1 row and length(sim) columns, and this will be noted with a message.
|
eps
|
a non-negative numeric scaler smaller than 0.1, giving the cut-off value for probabilities. Probabilities smaller than eps will be replaced with eps, and probabilities larger than 1 - eps will be replaced with 1 - eps. Set eps = 0 to disable probability trimming.
|
Details
cinv()
cinv() computes the Choleski inverse of a real symmetric positive-definite square matrix.
sd_lc()
Given the linear combination X %*% b, where:
-
Xis a matrix of multipliers/constants; -
bis a vector of (correlated) random variables; -
vcis the symmetric variance-covariance matrix forb;
sd_lc(X, vc) computes the standard deviations for the linear combination X %*% b, without making needless copies.
sd_lc(X, vc) will use much less memory than a base โRโ approach.
sd_lc(X, vc) will usually be faster than a base โRโ approach (depending on the Linear Algebra Library used for base โRโ).
ecumprob()
The ecumprod(y, sim) function takes a matrix (or data.frame) of simulated values sim, and for each row i (after broadcasting), estimates the cumulative distribution function of sim[i, ], and returns the cumulative probability for y[i].
In terms of statistics, it is equivalent to the following operation for each index i:
ecdf(sim[i,])(y[i])
However, ecumprob() is much faster, and supports NAs/NaNs.
In terms of linear algebra, it is equivalent to the following broadcasted operation:
rowMeans(sim <= y)
where y and sim are broadcaster arrays.
However, ecumprob() is much more memory-efficient, supports a data.frame for sim, and has statistical safety checks.
Value
For cinv():
A matrix.
For sd_lc():
A vector of standard deviations.
For ecumprob():
A vector of cumulative probabilities.
If for any observation i (after broadcasting), y[i] is NA/NaN or any of sim[i,] is NA/NaN, the result for i will be NA.
If zero-length y or sim is given, a zero-length numeric vector is returned.
References
John A. Rice (2007), Mathematical Statistics and Data Analysis (6th Edition)
See Also
chol, chol2inv