#![cfg(feature = "wasm")]
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn mean(data: &[f64]) -> f64 {
crate::stats::mean(data).unwrap_or(f64::NAN)
}
#[wasm_bindgen]
pub fn std_dev(data: &[f64]) -> f64 {
crate::stats::std_dev(data).unwrap_or(f64::NAN)
}
#[wasm_bindgen]
pub fn variance(data: &[f64]) -> f64 {
crate::stats::variance(data).unwrap_or(f64::NAN)
}
#[wasm_bindgen]
pub fn normal_cdf(x: f64) -> f64 {
crate::special::standard_normal_cdf(x)
}
#[wasm_bindgen]
pub fn normal_sf(x: f64) -> f64 {
crate::special::standard_normal_sf(x)
}
#[wasm_bindgen]
pub fn box_cox(data: &[f64], lambda: f64) -> Result<Vec<f64>, JsValue> {
crate::transforms::box_cox(data, lambda).map_err(|e| JsValue::from_str(&e.to_string()))
}
#[derive(serde::Serialize, tsify::Tsify)]
struct LambdaEstimateDto {
lambda: f64,
at_bound: bool,
}
#[wasm_bindgen(unchecked_return_type = "LambdaEstimateDto")]
pub fn estimate_lambda(data: &[f64], lambda_min: f64, lambda_max: f64) -> Result<JsValue, JsValue> {
let est = crate::transforms::estimate_lambda(data, lambda_min, lambda_max)
.map_err(|e| JsValue::from_str(&e.to_string()))?;
serde_wasm_bindgen::to_value(&LambdaEstimateDto {
lambda: est.lambda,
at_bound: est.at_bound,
})
.map_err(|e| JsValue::from_str(&e.to_string()))
}
#[wasm_bindgen]
pub fn rfft(data: &[f64]) -> Vec<f64> {
crate::fourier::rfft(data)
.into_iter()
.flat_map(|z| [z.re, z.im])
.collect()
}
fn check_probability(p: f64) -> Result<(), JsValue> {
if p.is_finite() && p > 0.0 && p < 1.0 {
Ok(())
} else {
Err(JsValue::from_str(&format!(
"p must be strictly between 0 and 1, got {p}"
)))
}
}
fn check_df(name: &str, df: f64) -> Result<(), JsValue> {
if df.is_finite() && df > 0.0 {
Ok(())
} else {
Err(JsValue::from_str(&format!(
"{name} must be a finite number > 0, got {df}"
)))
}
}
fn check_finite(name: &str, x: f64) -> Result<(), JsValue> {
if x.is_nan() {
Err(JsValue::from_str(&format!(
"{name} must be a number, got NaN"
)))
} else {
Ok(())
}
}
#[wasm_bindgen]
pub fn inverse_normal_cdf(p: f64) -> Result<f64, JsValue> {
check_probability(p)?;
Ok(crate::special::inverse_normal_cdf(p))
}
#[wasm_bindgen]
pub fn t_distribution_cdf(t: f64, df: f64) -> Result<f64, JsValue> {
check_finite("t", t)?;
check_df("df", df)?;
Ok(crate::special::t_distribution_cdf(t, df))
}
#[wasm_bindgen]
pub fn t_distribution_quantile(p: f64, df: f64) -> Result<f64, JsValue> {
check_probability(p)?;
check_df("df", df)?;
Ok(crate::special::t_distribution_quantile(p, df))
}
#[wasm_bindgen]
pub fn f_distribution_cdf(x: f64, df1: f64, df2: f64) -> Result<f64, JsValue> {
check_finite("x", x)?;
check_df("df1", df1)?;
check_df("df2", df2)?;
Ok(crate::special::f_distribution_cdf(x, df1, df2))
}
#[wasm_bindgen]
pub fn f_distribution_quantile(p: f64, df1: f64, df2: f64) -> Result<f64, JsValue> {
check_probability(p)?;
check_df("df1", df1)?;
check_df("df2", df2)?;
Ok(crate::special::f_distribution_quantile(p, df1, df2))
}
#[wasm_bindgen]
pub fn chi_squared_cdf(x: f64, k: f64) -> Result<f64, JsValue> {
check_finite("x", x)?;
check_df("k", k)?;
Ok(crate::special::chi_squared_cdf(x, k))
}
#[wasm_bindgen]
pub fn chi_squared_quantile(p: f64, k: f64) -> Result<f64, JsValue> {
check_probability(p)?;
check_df("k", k)?;
Ok(crate::special::chi_squared_quantile(p, k))
}