# gips 1.3.0

### Multi-sample support

`gips()` now accepts a **list of covariance matrices** and a vector of sample
sizes, enabling Bayesian model selection with a shared permutation symmetry
across G independent groups:

```r
g <- gips(list(S1, S2, S3), c(n1, n2, n3))
g_MAP <- find_MAP(g, optimizer = "BF")
```

Each group has its own covariance matrix `Sigma_g` and can have its own prior
hyperparameters `D_matrix_g` and `delta_g`, but all share the same symmetry
group Gamma.
The MLE exists when `min(n_g) >= n0`. **All existing single-sample usage is
fully unchanged**.


# gips 1.2.4

### Performance gain

`project_matrix()` is now implemented in C++ internally. Additionally, several internal calculations used by `log_posteriori_of_gips()` and `find_MAP(optimizer = "BF")` were optimized.

For Brute Force optimization:

| permutation size | 6 | 7 | 8 | 9 | 10 |
|---|---:|---:|---:|---:|---:|
| v1.2.3 | 1.26 s | 4.06 s | 30.19 s | 4.35 min | 1 h 46 min |
| v1.2.4 | 0.52 s | 1.89 s | 10.34 s | 1.21 min | 12.14 min |

For `log_posteriori_of_gips()` evaluated on 1000 random permutations of a given size:

| permutation size | 30 | 50 | 100 | 200 | 300 |
|---|---:|---:|---:|---:|---:|
| v1.2.3 | 2.31 s | 2.31 s | 11.70 s | 46.49 s | 110.17 s |
| v1.2.4 | 0.84 s | 1.26 s | 3.24 s | 15.73 s | 39.47 s |

The above tables are based on the code from [Pull Request #99](https://github.com/PrzeChoj/gips/pull/99#issuecomment-4847288063).

### Update to functions

- `find_MAP()` now uses its precomputed cyclic-subgroup generators for `optimizer = "BF"` through `perm_size = 10`; Brute Force is the default through this size.
- Added caching for `find_MAP(optimizer = "MH")` to store computed values. This reduces computation time for the Markov chain, particularly when the acceptance rate is low.
- Improved `find_MAP(optimizer = "MH")` with a forced move mechanism: when the cache is full (all neighbors have been evaluated), the algorithm now makes a probabilistic move based on the cached values instead of exiting early, which improves exploration of the permutation space. See #115.
- `plot.gips()` now uses `ggplot2` for all plot types.
- `plot.gips(type = "all", "best", "both", or "n0")` is now much faster for large iteration counts.
- `project_matrix()`: The `precomputed_equal_indices` parameter is no longer used and will be removed in v1.4.0.

### Bugfixes:

- Documentation improvements: grammar and style corrections in roxygen comments, vignettes, and error messages.
- `plot.gips(type = "n0")` works properly after multiple optimizations. See #114.


# gips 1.2.3

### Performance gain

There was a significant speed improvement in `get_structure_constants()`, which is used internally by posterior calculations. For 1000 random permutations of a given size:

| permutation size | 30 | 50 | 100 | 200 | 300 |
|---|---:|---:|---:|---:|---:|
| v1.2.2 | 0.09 s | 0.10 s | 0.25 s | ~10 s | ~25 s |
| v1.2.3 | 0.07 s | 0.08 s | 0.10 s | 0.17 s | ~0.20 s |

This change consequently improved `log_posteriori_of_gips()`. For 1000 random permutations of a given size:

| permutation size | 30 | 50 | 100 | 200 | 300 |
|---|---:|---:|---:|---:|---:|
| v1.2.2 | 1.50 s | 2.49 s | 7.08 s | 55.25 s | 169.77 s |
| v1.2.3 | 1.29 s | 2.24 s | 6.84 s | 31.73 s | 85.10 s |

### Update to functions

-   `plot.gips()` can get `type = "n0"`, which will plot the change of `n0` along the "MH" optimization. Handy for deciding of burn-in time;
-   `find_MAP(optimizer = "MH")` tracks the `n0` along the optimization;
-   `summary.gips()` calculates Likelihood-Ratio test.


# gips 1.2.2

### Bugfixes:

- `logLik.gips()` will return an object of class `logLik`;
- Better Vignettes titles.


# gips 1.2.1

### Bugfix:

-   One test on alternative BLAS/LAPACK has an alternative check for a singular matrix. Found by CRAN's ATLAS test.


# gips 1.2.0

### New functions

-   `BIC.gips()`
-   `AIC.gips()`
-   `logLik.gips()`
-   `as.character.gips()`

### Update to functions

-   `gips()` has a new default `D_matrix = mean(diag(S)) * diag(p)`;
-   `summary.gips()` calculates `AIC`, `BIC`, and `n_parameters` (number of free parameters in the covariance matrix);
-   `get_probabilities_from_gips()` will return a sorted vector;
-   `compare_posteriories_of_perms()` and `compare_log_posteriories_of_perms()` have a new parameter `digits`;
-   Everywhere a permutation was expected, the `gips` object can now be passed and interpreted as a permutation. Those are:
    -   `perm` in `gips()`, `project_matrix()`, `prepare_orthogonal_matrix()`, `get_structure_constants()`, `calculate_gamma_function()`;
    -   `perm1` and `perm2` in `compare_posteriories_of_perms()`, `compare_log_posteriories_of_perms()`;
    -   `x` in `gips_perm()`;
-   `plot.gips()` can get `type = "MLE"`, which is an alias for `type = "heatmap"`;
-   `find_MAP(optimizer = "BF")` is 3 times faster;
-   `find_MAP(optimizer = "BF")` is default for `perm_size <= 9`.

### Bugfixes:

-   Sometimes, `post_probabilities` underflows to 0. This is appropriately validated now;
-   `NaN`s should not occur in `find_MAP()` for `D_matrix <- diag(ncol(S)) * d` when `1000 < d < 1e300`;
-   When `NaN`s do occur in `find_MAP()`, they will throw an error (used to show a warning);
-   `Inf` better handled in `print.gips()`;
-   `print.*()` functions will print `\n` in the end;
-   Slightly different punctuation in `print.gips()`;
-   Tremendous vignettes and documentation improvements;
-   Proper testing of examples;
-   `delta` parameter of `gips()` has to be bigger than `1`. We used to restrict it to bigger than `2`;
-   `project_matrix()` shows a warning when the non-positive-semi-definite matrix is passed as an `S` argument;
-   `project_matrix()` preserves `colnames()` and `rownames()` of a matrix;
-   `D_matrix` is checked for containing any `NaN` or `Inf` values;
-   Absurdly long structure constants vectors may overflow an `integer`. Now we use `double`;
-   `compare_log_posteriories_of_perms()` and `compare_posteriories_of_perms()` show an error when given two incomparable `gips` objects (with different parameters).

# gips 1.0.0

-   This is the first release of gips.
