## Version 0.1.2

o UPDATE: `polychoric_matrix()` overhauled for speed and accuracy:

  - Bivariate normal CDF replaced with Genz's (2004) double-precision
    extension of Drezner & Wesolowsky (1990), translated from the Fortran
    TVPACK `MVBVU` routine (via the pbivnorm R package). Uses a
    variable-order (6-, 12-, or 20-point) Gauss-Legendre rule depending on
    |rho|, with an extended tail-correction series for |rho| close to 1,
    giving higher accuracy than the fixed 5-point rule it replaces
  - Optimizer replaced Brent's method with Newton-Raphson (Fisher scoring
    on rho, falling back to an exact-Hessian arcsin-reparameterized Newton
    step to guarantee rho stays in (-1, 1), with damped step sizes to avoid
    overshoot near the boundary), seeded from a Pearson-correlation
    starting value
  - Several C-level optimizations: caching bivariate CDF/density
    evaluations across a grid of category thresholds instead of
    recomputing each corner up to 4x redundantly; merging the
    joint-frequency-table pass with the Pearson starting-value computation
    into a single scan of the data; replacing per-pair heap allocations
    with fixed-size stack buffers; replacing a from-scratch Chebyshev
    expansion with an `erfc()`-based univariate normal CDF; and hoisting
    rho-only quantities out of the per-cell evaluation loop
  - Net effect: consistently faster than {bifactor}'s single-core
    implementation and competitive with (sometimes faster than) its
    16-core implementation, and 1.2-5.6x faster than {EGAnet}'s
    implementation across a range of dataset sizes and category counts,
    with results agreeing to 5-8 significant digits

o FIX: removed an unnecessary `as.numeric()` copy of the (already-numeric)
  precision matrix in `atan_derivative`, `exp_derivative`,
  `gumbel_derivative`, `log_derivative`, and `weibull_derivative`, avoiding
  a full matrix copy on every LLA iteration in `network_estimation()`

o UPDATE: `proxswap_lattice()` no longer reflattens its (invariant)
  node-pairs list on every shuffle pass; it is now flattened once and
  reused across all `shuffles` passes

o UPDATE: `inst/COPYRIGHTS` and `DESCRIPTION` updated to credit Alan Genz
  for the bivariate normal CDF implementation in `polychoric_matrix.c`,
  replacing the earlier Drezner-Wesolowsky approximation translated from
  Alexander Robitzsch's pbv package, which is no longer present


## Version 0.1.1

o ADD: refrences for adaptive regularization methods

o UPDATE: added functionality for `shape` to be set in `network_estimation` for the Weibull penalty (enables reproducibility)

o UPDATE: added maximum likelihood parameter estimates to output in `network_estimation` (`$MLE`) when `network_only = FALSE`

o UPDATE: changed `LLA` default to be `TRUE` to ensure most rigorous application is the default


## Version 0.1.0

o FIX: several bugs in `simulate_smallworld`; also updated edge weight assignment 

o UPDATE: SUR model updated with proper SE parameter

o UPDATE: adaptive regularization uses first decile for distributions in `network_estimation`

o UPDATE: internal MLE for Gumbel was updated to root finding function (slightly faster)

o UPDATE: `smallworldness()` offers weighted version, placing largest edge weights on the nearest neighbors

o REMOVE: `ring2lattice()` algorithm was revised and the logic updated to the `proxswap_lattice()` algorithm

- `proxswap_lattice()`: Converts a network matrix into a connected ring lattice
  whose degree sequence exactly matches the original, while maximising the
  average local clustering coefficient. Accepts any weighted or binary network
  directly; the binary adjacency is derived internally from non-zero entries.
  The algorithm runs `shuffles` (default 100) independent passes. Each pass
  randomly permutes the degree sequence onto ring positions, then runs a
  proximity construction (implemented in C via `proximity_pass_c`) that assigns
  edges greedily in increasing ring-distance order, prioritising high-need pairs
  at each distance band. Any residual degree deficit is resolved by a swap-repair
  phase (implemented in C via `swapping_pass_c`) that connects the
  highest-deficit node to its nearest available ring neighbour, performing an
  edge swap when no direct partner with remaining budget exists. Passes that
  yield a disconnected graph or an unsatisfied degree sequence are discarded.
  When `weighted = TRUE`, edge weights from the original network are reassigned
  to lattice edges by ring distance following Muldoon, Bridgeford, & Bassett
  (2016): largest-magnitude weights are placed on shortest-distance edges, with
  original signs preserved. Among valid passes the one with the highest average
  clustering coefficient is returned; if no valid pass is found, or if the best
  lattice clustering coefficient is lower than that of the original network, the
  empirical adjacency (or weighted matrix) is returned with a warning. The
  resulting average clustering coefficient is attached as attribute `"CC"`.


## Initial Commit: Version 0.0.1

### Network Estimation

- `network_estimation()`: Estimates Gaussian graphical models using L0 penalty
  approximations (atan, exp, gumbel, weibull) via single-pass or full Local
  Linear Approximation (LLA). Supports adaptive penalties, multiple information
  criteria (AIC, AICc, BIC, BIC0, EBIC, MBIC), and automatic correlation
  computation for mixed continuous/ordinal data

### Fit Evaluation

- `network_fit()`: Computes traditional structural equation model-style fit
  metrics for an estimated network, including chi-square, RMSEA (with CIs),
  CFI, TLI, SRMR, log-likelihood, AIC, and BIC

- `edge_confusion()`: Computes confusion matrix metrics (sensitivity,
  specificity, PPV, NPV, FDR, FOM, balanced accuracy, F1, CSI, MCC) for
  comparing an estimated network against a ground-truth network

### Correlation Utilities

- `auto_correlate()`: Automatically selects and computes appropriate
  correlations for mixed data types — Pearson for continuous, polychoric for
  ordinal, tetrachoric for binary, and polyserial/biserial for mixed pairs

- `polychoric_matrix()`: Fast C implementation of polychoric correlations using
  the Beasley-Springer-Moro algorithm, Drezner-Wesolosky bivariate normal
  approximation, and Brent's optimization method

### Data Simulation

- `ring2lattice()`: Converts a partial correlation network matrix into a
  near-degree-preserving ring lattice for use as the lattice baseline in
  small-worldness calculations. Derives the binary adjacency internally,
  reorders nodes by degree, seeds a ring lattice from a circular-distance
  threshold, and runs dual pruning passes (highest-first and lowest-first
  surplus order) with a lexicographic edge-removal priority (clustering
  constraint, surplus, ring distance). Retains whichever pass minimises
  total residual surplus (ties broken by average clustering coefficient),
  with a final fallback to the empirical adjacency when the lattice cannot
  exceed the empirical clustering coefficient. Attaches the resulting
  average clustering coefficient as the attribute `"CC"`

- `simulate_smallworld()`: Simulates data from a GGM with a small-world network
  structure using degree-weighted rewiring. Supports continuous and skewed data,
  and accepts control over nodes, density, rewire probability, sample size, and
  signal-to-noise ratio

- `simulate_sbm()`: Simulates data from a GGM with a stochastic block model
  (SBM) structure. Community edge densities are controlled via a block density
  matrix; edge weights are drawn from a Weibull distribution whose parameters
  are predicted from network size and sample size

### Supporting Functions

- `weibull_parameters()`: Predicts Weibull shape and scale parameters for
  absolute partial correlation edge weights given network size, sample size,
  and signal-to-noise ratio, using a Seemingly Unrelated Regression (SUR)
  model fitted to 194 empirical psychometric networks

- `categorize()`: Converts continuous data to ordinal categories (2–6+) with
  optional skew control based on empirical category boundary tables
  (Garrido, Abad, & Ponsoda, 2011)

### Datasets

- `basic_smallworld`: Toy small-world network dataset (n = 500, 20 variables)
  generated via `simulate_smallworld()` for use in examples

