use std::{marker::PhantomData, ops::Range};
use crate::{DesignMatrix, LinearPredictorBlock, PredictorBlock};
pub trait ParameterName {
const NAME: &'static str;
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Mu;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Sigma;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Nu;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Tau;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Rate;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Shape;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Scale;
impl ParameterName for Mu {
const NAME: &'static str = "mu";
}
impl ParameterName for Sigma {
const NAME: &'static str = "sigma";
}
impl ParameterName for Nu {
const NAME: &'static str = "nu";
}
impl ParameterName for Tau {
const NAME: &'static str = "tau";
}
impl ParameterName for Rate {
const NAME: &'static str = "rate";
}
impl ParameterName for Shape {
const NAME: &'static str = "shape";
}
impl ParameterName for Scale {
const NAME: &'static str = "scale";
}
#[derive(Debug, Clone, PartialEq)]
pub struct ParameterBlock<P, L, X, Penalty> {
pub x: X,
pub penalty: Penalty,
pub offset: usize,
pub len: usize,
marker: PhantomData<(P, L)>,
}
impl<P, L, X, Penalty> ParameterBlock<P, L, X, Penalty>
where
X: PredictorBlock,
{
pub fn new(x: X, penalty: Penalty, offset: usize) -> Self {
let len = x.nparams();
Self::from_len(x, penalty, offset, len)
}
pub fn from_predictor(x: X, penalty: Penalty, offset: usize) -> Self {
Self::new(x, penalty, offset)
}
}
impl<P, L, X, Penalty> ParameterBlock<P, L, LinearPredictorBlock<X>, Penalty>
where
X: DesignMatrix,
{
pub fn linear(x: X, penalty: Penalty, offset: usize) -> Self {
Self::new(LinearPredictorBlock::new(x), penalty, offset)
}
}
impl<P, L, X, Penalty> ParameterBlock<P, L, X, Penalty> {
fn from_len(x: X, penalty: Penalty, offset: usize, len: usize) -> Self {
Self {
x,
penalty,
offset,
len,
marker: PhantomData,
}
}
pub fn with_offset(mut self, offset: usize) -> Self {
self.offset = offset;
self
}
pub fn range(&self) -> Range<usize> {
self.offset..self.offset + self.len
}
pub fn end(&self) -> usize {
self.offset + self.len
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
}