#![cfg(feature = "wasm")]
use wasm_bindgen::prelude::*;
use super::domain::check_domain;
use crate::error::{error_json, error_to_json};
use crate::loess;
#[wasm_bindgen]
pub fn loess_fit(
y_json: &str,
x_vars_json: &str,
span: f64,
degree: usize,
robust_iterations: usize,
surface: &str,
) -> String {
if let Err(e) = check_domain() {
return error_to_json(&e);
}
let y: Vec<f64> = match serde_json::from_str(y_json) {
Ok(v) => v,
Err(e) => return error_json(&format!("Failed to parse y: {}", e)),
};
let x_vars: Vec<Vec<f64>> = match serde_json::from_str(x_vars_json) {
Ok(v) => v,
Err(e) => return error_json(&format!("Failed to parse x_vars: {}", e)),
};
let n_predictors = x_vars.len();
let surface = match surface.to_lowercase().as_str() {
"interpolate" => loess::LoessSurface::Interpolate,
_ => loess::LoessSurface::Direct,
};
let options = loess::LoessOptions {
span,
degree,
robust_iterations,
n_predictors,
surface,
};
match loess::loess_fit(&y, &x_vars, &options) {
Ok(output) => serde_json::to_string(&output)
.unwrap_or_else(|_| error_json("Failed to serialize LOESS result")),
Err(e) => error_json(&e.to_string()),
}
}
#[wasm_bindgen]
pub fn loess_predict(
new_x_json: &str,
original_x_json: &str,
original_y_json: &str,
span: f64,
degree: usize,
robust_iterations: usize,
surface: &str,
) -> String {
if let Err(e) = check_domain() {
return error_to_json(&e);
}
let new_x: Vec<Vec<f64>> = match serde_json::from_str(new_x_json) {
Ok(v) => v,
Err(e) => return error_json(&format!("Failed to parse new_x: {}", e)),
};
let original_x: Vec<Vec<f64>> = match serde_json::from_str(original_x_json) {
Ok(v) => v,
Err(e) => return error_json(&format!("Failed to parse original_x: {}", e)),
};
let original_y: Vec<f64> = match serde_json::from_str(original_y_json) {
Ok(v) => v,
Err(e) => return error_json(&format!("Failed to parse original_y: {}", e)),
};
let n_predictors = original_x.len();
let surface = match surface.to_lowercase().as_str() {
"interpolate" => loess::LoessSurface::Interpolate,
_ => loess::LoessSurface::Direct,
};
let fit = loess::LoessFit {
fitted: vec![0.0; original_y.len()], predictions: None,
span,
degree,
robust_iterations,
surface,
};
let options = loess::LoessOptions {
span,
degree,
robust_iterations,
n_predictors,
surface,
};
match fit.predict(&new_x, &original_x, &original_y, &options) {
Ok(predictions) => {
let result = serde_json::json!({
"predictions": predictions
});
result.to_string()
},
Err(e) => error_json(&e.to_string()),
}
}