Skip to main content

gamlss_core/
param.rs

1use std::{marker::PhantomData, ops::Range};
2
3use crate::{DesignMatrix, LinearPredictorBlock, PredictorBlock};
4
5/// Stable public name for a distribution parameter marker.
6pub trait ParameterName {
7    /// Name used in parameter layouts and unpacked coefficient views.
8    const NAME: &'static str;
9}
10
11/// Маркер для location-параметра `mu`.
12#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
13pub struct Mu;
14
15/// Маркер для scale-параметра `sigma`.
16#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
17pub struct Sigma;
18
19/// Маркер для третьего GAMLSS-параметра `nu`.
20#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
21pub struct Nu;
22
23/// Маркер для четвёртого GAMLSS-параметра `tau`.
24#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
25pub struct Tau;
26
27/// Маркер для rate-параметра распределения.
28#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
29pub struct Rate;
30
31/// Маркер для shape-параметра распределения.
32#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
33pub struct Shape;
34
35/// Маркер для scale-параметра распределения.
36#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
37pub struct Scale;
38
39impl ParameterName for Mu {
40    const NAME: &'static str = "mu";
41}
42
43impl ParameterName for Sigma {
44    const NAME: &'static str = "sigma";
45}
46
47impl ParameterName for Nu {
48    const NAME: &'static str = "nu";
49}
50
51impl ParameterName for Tau {
52    const NAME: &'static str = "tau";
53}
54
55impl ParameterName for Rate {
56    const NAME: &'static str = "rate";
57}
58
59impl ParameterName for Shape {
60    const NAME: &'static str = "shape";
61}
62
63impl ParameterName for Scale {
64    const NAME: &'static str = "scale";
65}
66
67/// Типизированный block коэффициентов для одного параметра распределения.
68///
69/// `P` задаёт роль параметра, `L` задаёт link-функцию, `X` хранит predictor
70/// block, а `Penalty` добавляет регуляризацию. `offset` и `len` описывают
71/// диапазон коэффициентов блока внутри общего вектора beta.
72#[derive(Debug, Clone, PartialEq)]
73pub struct ParameterBlock<P, L, X, Penalty> {
74    /// Predictor block.
75    pub x: X,
76    /// Penalty, применяемый к коэффициентам блока.
77    pub penalty: Penalty,
78    /// Начальная позиция блока в общем beta-векторе.
79    pub offset: usize,
80    /// Число коэффициентов в блоке.
81    pub len: usize,
82    marker: PhantomData<(P, L)>,
83}
84
85impl<P, L, X, Penalty> ParameterBlock<P, L, X, Penalty>
86where
87    X: PredictorBlock,
88{
89    /// Создаёт блок и берёт `len` из `x.nparams()`.
90    pub fn new(x: X, penalty: Penalty, offset: usize) -> Self {
91        let len = x.nparams();
92        Self::from_len(x, penalty, offset, len)
93    }
94
95    /// Создаёт блок из generic predictor.
96    ///
97    /// Это синоним [`Self::new`], оставленный для кода, где явное слово
98    /// `predictor` делает вызов читаемее.
99    pub fn from_predictor(x: X, penalty: Penalty, offset: usize) -> Self {
100        Self::new(x, penalty, offset)
101    }
102}
103
104impl<P, L, X, Penalty> ParameterBlock<P, L, LinearPredictorBlock<X>, Penalty>
105where
106    X: DesignMatrix,
107{
108    /// Создаёт линейный block из design matrix.
109    pub fn linear(x: X, penalty: Penalty, offset: usize) -> Self {
110        Self::new(LinearPredictorBlock::new(x), penalty, offset)
111    }
112}
113
114impl<P, L, X, Penalty> ParameterBlock<P, L, X, Penalty> {
115    fn from_len(x: X, penalty: Penalty, offset: usize, len: usize) -> Self {
116        Self {
117            x,
118            penalty,
119            offset,
120            len,
121            marker: PhantomData,
122        }
123    }
124
125    /// Возвращает копию блока с новым offset.
126    pub fn with_offset(mut self, offset: usize) -> Self {
127        self.offset = offset;
128        self
129    }
130
131    /// Диапазон коэффициентов блока в общем beta-векторе.
132    pub fn range(&self) -> Range<usize> {
133        self.offset..self.offset + self.len
134    }
135
136    /// Индекс сразу после последнего коэффициента блока.
137    pub fn end(&self) -> usize {
138        self.offset + self.len
139    }
140
141    /// Число коэффициентов блока.
142    pub fn len(&self) -> usize {
143        self.len
144    }
145
146    /// `true`, если block не содержит коэффициентов.
147    pub fn is_empty(&self) -> bool {
148        self.len == 0
149    }
150}