Skip to main content

gam_solve/
row_measure.rs

1//! Row-subsample mask handle for trust-region invariant enforcement.
2//!
3//! The `RowSubsampleMask` data type and its pure data methods (`full_data`,
4//! `subsample`, `indices_and_weights`) have descended to `gam-problem` so
5//! lower tiers can consume the row measure without depending on `gam-solve`;
6//! they are re-exported here unchanged.
7//!
8//! The `BlockwiseFitOptions`-coupled constructor stays here: it reads the
9//! outer optimizer's `outer_score_subsample` (an option type that lives above
10//! `gam-problem`), so it cannot descend. Because the data type is now foreign
11//! to this crate, the constructor is provided through the [`RowSubsampleMaskExt`]
12//! extension trait rather than an inherent method.
13
14use std::sync::Arc;
15
16use gam_model_api::families::custom_family::BlockwiseFitOptions;
17
18pub use gam_problem::RowSubsampleMask;
19
20/// Extension trait carrying the `BlockwiseFitOptions`-coupled constructor for
21/// [`RowSubsampleMask`]. The data type lives in `gam-problem`; this constructor
22/// stays in `gam-solve` because it depends on `BlockwiseFitOptions`.
23pub trait RowSubsampleMaskExt {
24    /// Build a `RowSubsampleMask` from blockwise-fit options. The outer
25    /// optimizer is the sole source of `outer_score_subsample`; inner
26    /// paths read this once at the top of each TR iteration and freeze
27    /// it for every quantity in that iteration.
28    fn from_options(options: &BlockwiseFitOptions, n: usize) -> Self;
29}
30
31impl RowSubsampleMaskExt for RowSubsampleMask {
32    fn from_options(options: &BlockwiseFitOptions, n: usize) -> Self {
33        match options.outer_score_subsample.as_ref() {
34            Some(mask) => Self::subsample(Arc::clone(mask)),
35            None => Self::full_data(n),
36        }
37    }
38}