@@ -1556,26 +1556,33 @@ get_diagonalized_matrix_for_heatmap <- function(g) {
1556
1556
# ' It can be less than 1, meaning the identity permutation
1557
1557
# ' is more likely. Remember that this number can big and
1558
1558
# ' overflow to `Inf` or small and underflow to 0.
1559
- # ' 5. `n0` - the minimum number of observations needed for
1559
+ # ' 5. `log_times_more_likely_than_id` - log of `times_more_likely_than_id`.
1560
+ # ' 6. `likelihood_ratio_test_statistics`, `likelihood_ratio_test_p_value` -
1561
+ # ' statistics and p-value of Likelihood Ratio test, where
1562
+ # ' the H_0 is that the data was drawn from the normal distribution
1563
+ # ' with Covariance matrix invariant under the given permutation.
1564
+ # ' The p-value is calculated from the asymptotic distribution.
1565
+ # ' Note that this is sensibly defined only for \eqn{n \ge p}.
1566
+ # ' 7. `n0` - the minimum number of observations needed for
1560
1567
# ' the covariance matrix's maximum likelihood estimator
1561
1568
# ' (corresponding to a MAP) to exist. See **\eqn{C\sigma} and `n0`**
1562
1569
# ' section in `vignette("Theory", package = "gips")` or in its
1563
1570
# ' [pkgdown page](https://przechoj.github.io/gips/articles/Theory.html).
1564
- # ' 6 . `S_matrix` - the underlying matrix.
1571
+ # ' 8 . `S_matrix` - the underlying matrix.
1565
1572
# ' This matrix will be used in calculations of
1566
1573
# ' the posteriori value in [log_posteriori_of_gips()].
1567
- # ' 7 . `number_of_observations` - the number of observations that
1574
+ # ' 9 . `number_of_observations` - the number of observations that
1568
1575
# ' were observed for the `S_matrix` to be calculated.
1569
1576
# ' This value will be used in calculations of
1570
1577
# ' the posteriori value in [log_posteriori_of_gips()].
1571
- # ' 8 . `was_mean_estimated` - given by the user while creating the `gips` object:
1578
+ # ' 10 . `was_mean_estimated` - given by the user while creating the `gips` object:
1572
1579
# ' * `TRUE` means the `S` parameter was the output of [stats::cov()] function;
1573
1580
# ' * `FALSE` means the `S` parameter was calculated with
1574
1581
# ' `S = t(X) %*% X / number_of_observations`.
1575
- # ' 9 . `delta`, `D_matrix` - the hyperparameters of the Bayesian method.
1582
+ # ' 11 . `delta`, `D_matrix` - the hyperparameters of the Bayesian method.
1576
1583
# ' See the **Hyperparameters** section of [gips()] documentation.
1577
- # ' 10 . `AIC`, `BIC` - output of [AIC.gips()] and [BIC.gips()] functions .
1578
- # ' 11 . `n_parameters` - number of free parameters in the covariance matrix .
1584
+ # ' 12 . `n_parameters` - number of free parameters in the covariance matrix .
1585
+ # ' 13 . `AIC`, `BIC` - output of [AIC.gips()] and [BIC.gips()] functions .
1579
1586
# ' * For optimized `gips` object:
1580
1587
# ' 1. `optimized` - `TRUE`.
1581
1588
# ' 2. `found_permutation` - the permutation this `gips` represents.
@@ -1590,46 +1597,56 @@ get_diagonalized_matrix_for_heatmap <- function(g) {
1590
1597
# ' the `found_permutation` is over the `start_permutation`.
1591
1598
# ' It cannot be a number less than 1.
1592
1599
# ' Remember that this number can big and overflow to `Inf`.
1593
- # ' 7. `n0` - the minimal number of observations needed for the existence of
1600
+ # ' 7. `log_times_more_likely_than_start` - log of
1601
+ # ' `times_more_likely_than_start`.
1602
+ # ' 8. `likelihood_ratio_test_statistics`, `likelihood_ratio_test_p_value` -
1603
+ # ' statistics and p-value of Likelihood Ratio test, where
1604
+ # ' the H_0 is that the data was drawn from the normal distribution
1605
+ # ' with Covariance matrix invariant under `found_permutation`.
1606
+ # ' The p-value is calculated from the asymptotic distribution.
1607
+ # ' Note that this is sensibly defined only for \eqn{n \ge p}.
1608
+ # ' 9. `n0` - the minimal number of observations needed for the existence of
1594
1609
# ' the maximum likelihood estimator (corresponding to a MAP) of
1595
1610
# ' the covariance matrix (see **\eqn{C\sigma} and `n0`**
1596
1611
# ' section in `vignette("Theory", package = "gips")` or in its
1597
1612
# ' [pkgdown page](https://przechoj.github.io/gips/articles/Theory.html)).
1598
- # ' 8 . `S_matrix` - the underlying matrix.
1613
+ # ' 10 . `S_matrix` - the underlying matrix.
1599
1614
# ' This matrix will be used in calculations of
1600
1615
# ' the posteriori value in [log_posteriori_of_gips()].
1601
- # ' 9 . `number_of_observations` - the number of observations that
1616
+ # ' 11 . `number_of_observations` - the number of observations that
1602
1617
# ' were observed for the `S_matrix` to be calculated.
1603
1618
# ' This value will be used in calculations of
1604
1619
# ' the posteriori value in [log_posteriori_of_gips()].
1605
- # ' 10 . `was_mean_estimated` - given by the user while creating the `gips` object:
1620
+ # ' 12 . `was_mean_estimated` - given by the user while creating the `gips` object:
1606
1621
# ' * `TRUE` means the `S` parameter was output of the [stats::cov()] function;
1607
1622
# ' * `FALSE` means the `S` parameter was calculated with
1608
1623
# ' `S = t(X) %*% X / number_of_observations`.
1609
- # ' 11 . `delta`, `D_matrix` - the hyperparameters of the Bayesian method.
1624
+ # ' 13 . `delta`, `D_matrix` - the hyperparameters of the Bayesian method.
1610
1625
# ' See the **Hyperparameters** section of [gips()] documentation.
1611
- # ' 12 . `AIC`, `BIC` - output of [AIC.gips()] and [BIC.gips()] functions .
1612
- # ' 13 . `n_parameters` - number of free parameters in the covariance matrix .
1613
- # ' 14 . `optimization_algorithm_used` - all used optimization algorithms
1626
+ # ' 14 . `n_parameters` - number of free parameters in the covariance matrix .
1627
+ # ' 15 . `AIC`, `BIC` - output of [AIC.gips()] and [BIC.gips()] functions .
1628
+ # ' 16 . `optimization_algorithm_used` - all used optimization algorithms
1614
1629
# ' in order (one could start optimization with "MH", and then
1615
1630
# ' do an "HC").
1616
- # ' 15 . `did_converge` - a boolean, did the last used algorithm converge.
1617
- # ' 16 . `number_of_log_posteriori_calls` - how many times was
1631
+ # ' 17 . `did_converge` - a boolean, did the last used algorithm converge.
1632
+ # ' 18 . `number_of_log_posteriori_calls` - how many times was
1618
1633
# ' the [log_posteriori_of_gips()] function called during
1619
1634
# ' the optimization.
1620
- # ' 17 . `whole_optimization_time` - how long was the optimization process;
1635
+ # ' 19 . `whole_optimization_time` - how long was the optimization process;
1621
1636
# ' the sum of all optimization times (when there were multiple).
1622
- # ' 18 . `log_posteriori_calls_after_best` - how many times was
1637
+ # ' 20 . `log_posteriori_calls_after_best` - how many times was
1623
1638
# ' the [log_posteriori_of_gips()] function called after
1624
1639
# ' the `found_permutation`; in other words, how long ago
1625
1640
# ' could the optimization be stopped and have the same result.
1626
1641
# ' If this value is small, consider running [find_MAP()]
1627
1642
# ' again with `optimizer = "continue"`.
1628
1643
# ' For `optimizer = "BF"`, it is `NULL`.
1629
- # ' 19 . `acceptance_rate` - only interesting for `optimizer = "MH"`.
1644
+ # ' 21 . `acceptance_rate` - only interesting for `optimizer = "MH"`.
1630
1645
# ' How often was the algorithm accepting the change of permutation
1631
1646
# ' in an iteration.
1632
1647
# ' @export
1648
+ # '
1649
+ # ' @importFrom stats pchisq
1633
1650
# '
1634
1651
# ' @seealso
1635
1652
# ' * [find_MAP()] - Usually, the `summary.gips()`
@@ -1648,12 +1665,12 @@ get_diagonalized_matrix_for_heatmap <- function(g) {
1648
1665
# ' mu <- runif(6, -10, 10) # Assume we don't know the mean
1649
1666
# ' sigma_matrix <- matrix(
1650
1667
# ' data = c(
1651
- # ' 1.0 , 0.8, 0.6, 0.4, 0.6, 0.8,
1652
- # ' 0.8, 1.0 , 0.8, 0.6, 0.4, 0.6,
1653
- # ' 0.6, 0.8, 1.0 , 0.8, 0.6, 0.4,
1654
- # ' 0.4, 0.6, 0.8, 1.0 , 0.8, 0.6,
1655
- # ' 0.6, 0.4, 0.6, 0.8, 1.0 , 0.8,
1656
- # ' 0.8, 0.6, 0.4, 0.6, 0.8, 1.0
1668
+ # ' 1.1 , 0.8, 0.6, 0.4, 0.6, 0.8,
1669
+ # ' 0.8, 1.1 , 0.8, 0.6, 0.4, 0.6,
1670
+ # ' 0.6, 0.8, 1.1 , 0.8, 0.6, 0.4,
1671
+ # ' 0.4, 0.6, 0.8, 1.1 , 0.8, 0.6,
1672
+ # ' 0.6, 0.4, 0.6, 0.8, 1.1 , 0.8,
1673
+ # ' 0.8, 0.6, 0.4, 0.6, 0.8, 1.1
1657
1674
# ' ),
1658
1675
# ' nrow = perm_size, byrow = TRUE
1659
1676
# ' ) # sigma_matrix is a matrix invariant under permutation (1,2,3,4,5,6)
@@ -1662,6 +1679,7 @@ get_diagonalized_matrix_for_heatmap <- function(g) {
1662
1679
# ' S <- cov(Z) # Assume we have to estimate the mean
1663
1680
# '
1664
1681
# ' g <- gips(S, number_of_observations)
1682
+ # ' unclass(summary(g))
1665
1683
# '
1666
1684
# ' g_map <- find_MAP(g, max_iter = 10, show_progress_bar = FALSE, optimizer = "Metropolis_Hastings")
1667
1685
# ' unclass(summary(g_map))
@@ -1675,8 +1693,25 @@ summary.gips <- function(object, ...) {
1675
1693
tmp <- get_n0_and_edited_number_of_observations_from_gips(object )
1676
1694
n0 <- tmp [1 ]
1677
1695
edited_number_of_observations <- tmp [2 ]
1678
-
1696
+
1679
1697
n_parameters <- sum(get_structure_constants(object [[1 ]])[[" dim_omega" ]])
1698
+
1699
+ # Likelihood-Ratio test:
1700
+ if (edited_number_of_observations < n0 || ! is.positive.definite.matrix(attr(object , " S" ))) {
1701
+ likelihood_ratio_test_statistics <- NULL
1702
+ likelihood_ratio_test_p_value <- NULL
1703
+ } else {
1704
+ likelihood_ratio_test_statistics <- edited_number_of_observations * (determinant(project_matrix(attr(object , " S" ), object [[1 ]]))$ modulus - determinant(attr(object , " S" ))$ modulus )
1705
+ attributes(likelihood_ratio_test_statistics ) <- NULL
1706
+ p <- attr(object [[1 ]], " size" )
1707
+ df_chisq <- p * (p + 1 )/ 2 - n_parameters
1708
+ if (df_chisq == 0 ) {
1709
+ likelihood_ratio_test_p_value <- NULL
1710
+ } else {
1711
+ # when likelihood_ratio_test_statistics is close to 0, the H_0
1712
+ likelihood_ratio_test_p_value <- 1 - pchisq(likelihood_ratio_test_statistics , df_chisq )
1713
+ }
1714
+ }
1680
1715
1681
1716
if (is.null(attr(object , " optimization_info" ))) {
1682
1717
log_posteriori_id <- log_posteriori_of_perm(
@@ -1691,6 +1726,8 @@ summary.gips <- function(object, ...) {
1691
1726
start_permutation_log_posteriori = permutation_log_posteriori ,
1692
1727
times_more_likely_than_id = exp(permutation_log_posteriori - log_posteriori_id ),
1693
1728
log_times_more_likely_than_id = permutation_log_posteriori - log_posteriori_id ,
1729
+ likelihood_ratio_test_statistics = likelihood_ratio_test_statistics ,
1730
+ likelihood_ratio_test_p_value = likelihood_ratio_test_p_value ,
1694
1731
n0 = n0 ,
1695
1732
S_matrix = attr(object , " S" ),
1696
1733
number_of_observations = attr(object , " number_of_observations" ),
@@ -1728,7 +1765,7 @@ summary.gips <- function(object, ...) {
1728
1765
)
1729
1766
start_permutation_log_posteriori <- log_posteriori_of_gips(gips_start )
1730
1767
}
1731
-
1768
+
1732
1769
summary_list <- list (
1733
1770
optimized = TRUE ,
1734
1771
found_permutation = object [[1 ]],
@@ -1737,6 +1774,8 @@ summary.gips <- function(object, ...) {
1737
1774
start_permutation_log_posteriori = start_permutation_log_posteriori ,
1738
1775
times_more_likely_than_start = exp(permutation_log_posteriori - start_permutation_log_posteriori ),
1739
1776
log_times_more_likely_than_start = permutation_log_posteriori - start_permutation_log_posteriori ,
1777
+ likelihood_ratio_test_statistics = likelihood_ratio_test_statistics ,
1778
+ likelihood_ratio_test_p_value = likelihood_ratio_test_p_value ,
1740
1779
n0 = n0 ,
1741
1780
S_matrix = attr(object , " S" ),
1742
1781
number_of_observations = attr(object , " number_of_observations" ),
@@ -1805,6 +1844,15 @@ print.summary.gips <- function(x, ...) {
1805
1844
)
1806
1845
)
1807
1846
),
1847
+ ifelse(is.null(x [[" likelihood_ratio_test_statistics" ]]),
1848
+ ifelse(is.positive.definite.matrix(x [[" S_matrix" ]]),
1849
+ " \n\n det(S) == 0, so Likelihood-Ratio test cannot be performed" ,
1850
+ " \n\n n0 > number_of_observations, so Likelihood-Ratio test cannot be performed"
1851
+ ),
1852
+ ifelse(is.null(x [[" likelihood_ratio_test_p_value" ]]),
1853
+ " \n\n The current permutation is id, so Likelihood-Ratio test cannot be performed (there is nothing to compare)" ,
1854
+ paste0(" \n\n The p-value of Likelihood-Ratio test:\n " , format(x [[" likelihood_ratio_test_p_value" ]], digits = 4 )))
1855
+ ),
1808
1856
" \n\n The number of observations:\n " , x [[" number_of_observations" ]],
1809
1857
" \n\n " , ifelse(x [[" was_mean_estimated" ]],
1810
1858
paste0(
0 commit comments