use crate::math::{CastAs, CastAsNumeric, CastFrom, CastFromNumeric, Float};
use std::{
fmt::Display,
ops::{Add, AddAssign, Mul},
};
mod errors;
mod models;
pub mod modules;
pub mod sam_parser;
pub(crate) mod state;
mod traits;
mod viterbi;
#[cfg(feature = "alignment-diagnostics")]
pub mod editing;
#[cfg(not(feature = "alignment-diagnostics"))]
#[doc(auto_cfg(hide(feature, values("alignment-diagnostics"))))]
pub(crate) mod indexing;
#[cfg(feature = "alignment-diagnostics")]
pub mod indexing;
#[cfg(feature = "alignment-diagnostics")]
pub mod score_from_path;
#[cfg(not(feature = "alignment-diagnostics"))]
#[doc(auto_cfg(hide(feature, values("alignment-diagnostics"))))]
pub(crate) mod views;
#[cfg(feature = "alignment-diagnostics")]
pub mod views;
#[cfg(feature = "alignment-diagnostics")]
pub mod visit_params;
pub use errors::*;
pub use models::*;
#[cfg(feature = "alignment-diagnostics")]
pub use state::*;
pub trait PhmmNumber:
Copy
+ Add<Output = Self>
+ Mul<Output = Self>
+ AddAssign
+ PartialOrd
+ CastAs
+ CastAsNumeric
+ CastFrom
+ CastFromNumeric
+ Default
+ Display {
const INFINITY: Self;
const ZERO: Self;
fn from_prob<T: Float>(prob: T) -> Self;
fn to_prob<T: Float>(self) -> T;
fn to_float<T: Float>(self) -> T;
#[must_use]
fn min(self, other: Self) -> Self;
}
impl PhmmNumber for f32 {
const INFINITY: Self = f32::INFINITY;
const ZERO: Self = 0.0;
#[inline]
fn from_prob<T: Float>(prob: T) -> Self {
let param = (-prob.ln()).cast_as::<f32>();
if param.is_nan() { Self::INFINITY } else { param }
}
#[inline]
fn to_prob<T: Float>(self) -> T {
(-T::cast_from(self)).exp()
}
#[inline]
fn to_float<T: Float>(self) -> T {
T::cast_from(self)
}
#[inline]
fn min(self, other: Self) -> Self {
self.min(other)
}
}
impl PhmmNumber for f64 {
const INFINITY: Self = f64::INFINITY;
const ZERO: Self = 0.0;
#[inline]
fn from_prob<T: Float>(prob: T) -> Self {
let param = -prob.cast_as::<f64>().ln();
if param.is_nan() { Self::INFINITY } else { param }
}
#[inline]
fn to_prob<T: Float>(self) -> T {
T::cast_from((-self).exp())
}
#[inline]
fn to_float<T: Float>(self) -> T {
T::cast_from(self)
}
#[inline]
fn min(self, other: Self) -> Self {
self.min(other)
}
}