use crate::{glm::Glm, num::Float};
use ndarray::Array1;
pub trait Link<M: Glm>: Transform {
fn func<F: Float>(y: F) -> F;
fn func_inv<F: Float>(lin_pred: F) -> F;
}
pub trait Transform {
fn nat_param<F: Float>(lin_pred: Array1<F>) -> Array1<F>;
fn d_nat_param<F: Float>(lin_pred: &Array1<F>) -> Array1<F>;
fn adjust_errors_variance<F: Float>(
errors: Array1<F>,
variance: Array1<F>,
lin_pred: &Array1<F>,
) -> (Array1<F>, Array1<F>) {
let eta_d = Self::d_nat_param(lin_pred);
let err_adj = &eta_d * &errors;
let var_adj = &eta_d * &variance * eta_d;
(err_adj, var_adj)
}
}
pub trait Canonical {}
impl<T> Transform for T
where
T: Canonical,
{
#[inline]
fn nat_param<F: Float>(lin_pred: Array1<F>) -> Array1<F> {
lin_pred
}
#[inline]
fn d_nat_param<F: Float>(lin_pred: &Array1<F>) -> Array1<F> {
Array1::<F>::ones(lin_pred.len())
}
#[inline]
fn adjust_errors_variance<F: Float>(
errors: Array1<F>,
variance: Array1<F>,
_lin_pred: &Array1<F>,
) -> (Array1<F>, Array1<F>) {
(errors, variance)
}
}