                     Changes in version 0.2.0.9000                      

Performance

  - The split search was rewritten and fitting is about 25 to 60 times
    faster (for example, 12.6 s to 0.33 s with 32,000 rows, 10 numeric
    predictors and max_splits = 10), allocating about 30 times less
    memory. Everything that depends on the predictors alone (row order,
    cutpoints, level groups) is computed once per node instead of once
    per iteration, every cutpoint of a predictor is scored from a single
    cumulative sum of the residuals instead of one pass per cutpoint,
    and a leaf whose residuals did not change since the last iteration
    keeps its previous best split. The fitted model is unchanged: the
    same splits, cutpoints, missing-value directions and sample indices
    as 0.2.0, which a new regression test checks on fourteen data sets.

                        Changes in version 0.2.0                        

Documentation

  - A new vignette, vignette("missing-values"), works through na_method
    = "mia" on the real Pima Indians Diabetes Database, where
    missingness is informative but modest, and shows plot()'s new main,
    tree_names and sign-colored leaves on it.

New data

  - pima_diabetes: the Pima Indians Diabetes Database (Smith et
    al. 1988), 768 patients, ships lazily loaded like iris. Its five
    physiologically impossible zeros (Glucose, BloodPressure,
    SkinThickness, Insulin, BMI) are already recoded to NA, so it is
    ready to demonstrate na_method = "mia" without an internet
    connection or preprocessing.

New features

  - plot() gained main, an overall title drawn once above every tree
    panel, and tree_names, overriding the automatic per-tree panel
    titles (a single string applies to every tree; a vector is indexed
    by each tree's position in the fit, so it stays correct when
    tree_idx only plots some of them; NA in a position keeps that tree's
    default title). In the "scientific" and "modern" styles, a leaf's
    background, border and text now depend on the sign of its
    contribution -- green for positive, red for negative; "classic"
    stays monochromatic by design.

  - figs(), fit_figs() and bagging_figs() gained na_method. The default
    "omit" is the previous behavior. "mia" (missingness incorporated in
    attributes, Twala et al. 2008) keeps every row: at each split the
    search also tries sending missing values left or right of the
    cutpoint, and splitting on missingness itself, and uses the learned
    direction at prediction time. summary() prints these as IS MISSING
    clauses, plot() labels the edge missing values take, and
    figsr_importance() reports a split on missingness on its own
    missing(<predictor>) row.

Bug fixes

  - The parsnip engine now fits through the formula interface. The
    previous data.frame interface ran model.frame() with na.omit before
    the engine, so fit() silently dropped rows with a missing predictor.

                 Changes in version 0.1.1 (2026-08-31)                  

Bug fixes

  - figs() now carries the parent leaf's value into the two leaves
    created by splitting it. Predictions from any tree deeper than one
    split were wrong before this fix.

  - Classification probabilities are no longer passed through a logistic
    function. The engine fits squared error on the 0/1 encoding of the
    outcome, so the sum of the leaf values already estimates the
    probability of the second level; it is now clamped to the unit
    interval instead. fitted_values is clamped the same way, so it
    agrees with predict().

  - predict() now rebuilds the model frame from the fitted terms, so a
    formula with a transformed term such as y ~ log(x) can be predicted
    from. It previously failed with a missing-predictor error.

  - A matrix-valued term such as poly(x, 2) raised a cryptic "missing
    value where TRUE/FALSE needed" during fitting; it is now rejected
    with a clear message.

  - figs() gained subset and na.action arguments, which were previously
    swallowed by ... and silently ignored. Passing weights now raises an
    error rather than fitting an unweighted model in silence.

  - A model that accepts no split at all predicts the outcome mean
    instead of zero. In classification this was a probability of zero
    for every observation.

  - Integer predictors with large values no longer overflow when the
    candidate cutpoints are computed.

  - Numeric cutpoints above the 30-candidate cap are now quantiles of
    the sample rather than of its distinct values, so they follow the
    density of the data.

  - Factor predictors are judged by the levels present in a node rather
    than by the declared level set, so a factor carrying many unused
    levels is no longer skipped as if it had too many levels.

  - A missing value in a predictor at prediction time raises a clear
    error, and a factor level unseen in training is rejected the way
    other stats model functions reject it, instead of failing deep
    inside the tree traversal.

  - predict() rejects an unsupported type instead of quietly returning
    numeric predictions.

  - bagging_figs() records the mode that was actually fitted. A factor
    outcome with the default mode = "regression" produced an ensemble
    that returned numeric scores instead of class predictions. Bagged
    classification also averages member probabilities rather than hard
    labels, and supports type = "prob". A character outcome is converted
    to a factor once, so a bootstrap resample that misses the minority
    class no longer aborts the fit.

  - fit_figs() no longer drops a predictor genuinely named .outcome.

  - plot() validates style and tree_idx instead of rendering the wrong
    style silently or failing with an internal error on NA. The
    "classic" style labels leaves dy =, like the other styles, because a
    leaf holds one tree's contribution rather than the prediction.

  - Registering the parsnip model is now idempotent, so reloading the
    package in a live session no longer errors.

New features

  - figs_tree() gained an engine argument defaulting to "figsr", and an
    update() method, so specifications behave like the rest of parsnip.

  - print() reports which predictors actually carry a split, and
    summary() states that classification leaf values are contributions
    to the probability of the second class.

Documentation

  - The Description field no longer quotes acronyms, following the
    request from CRAN.
  - Help pages are rendered from markdown, so inline code and
    cross-references appear as such.
  - The introductory vignette covers prediction, importance, plotting,
    classification, parsnip integration and bagging, and its example
    data no longer draws the outcome independently of the predictors.

                 Changes in version 0.1.0 (2026-08-31)                  

  - First release.

  - figs() fits Fast Interpretable Greedy-Tree Sums for regression and
    two-class classification, growing a sum of shallow trees by greedily
    taking the split that most reduces residual impurity, whether that
    split opens a new tree or deepens an existing one.

  - figs_tree() registers the model with parsnip, so FIGS can be used
    inside tidymodels workflows. max_splits() and max_trees() provide
    dials parameter objects for tuning; min_n reuses dials::min_n().

  - summary() prints the tree sum as IF-THEN decision rules and plot()
    draws the trees, in a "scientific", "modern" or "classic" style.

  - figsr_importance() ranks predictors by the total residual
    sum-of-squares reduction attributable to each of them.

  - bagging_figs() fits a bootstrap ensemble of FIGS models.
