UPDATE: Dump of initial files

This commit is contained in:
Nicolás Hatcher
2023-11-18 21:26:18 +01:00
commit c5b8efd83d
279 changed files with 42654 additions and 0 deletions

View File

@@ -0,0 +1,176 @@
use crate::{
calc_result::{CalcResult, CellReference},
expressions::{parser::Node, token::Error},
model::Model,
};
use super::transcendental::{bessel_i, bessel_j, bessel_k, bessel_y, erf};
// https://root.cern/doc/v610/TMath_8cxx_source.html
// Notice that the parameters for Bessel functions in Excel and here have inverted order
// EXCEL_BESSEL(x, n) => bessel(n, x)
impl Model {
pub(crate) fn fn_besseli(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
if args.len() != 2 {
return CalcResult::new_args_number_error(cell);
}
let x = match self.get_number_no_bools(&args[0], cell) {
Ok(f) => f,
Err(s) => return s,
};
let n = match self.get_number_no_bools(&args[1], cell) {
Ok(f) => f,
Err(s) => return s,
};
let n = n.trunc() as i32;
let result = bessel_i(n, x);
if result.is_infinite() || result.is_nan() {
return CalcResult::Error {
error: Error::NUM,
origin: cell,
message: "Invalid parameter for Bessel function".to_string(),
};
}
CalcResult::Number(result)
}
pub(crate) fn fn_besselj(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
if args.len() != 2 {
return CalcResult::new_args_number_error(cell);
}
let x = match self.get_number_no_bools(&args[0], cell) {
Ok(f) => f,
Err(s) => return s,
};
let n = match self.get_number_no_bools(&args[1], cell) {
Ok(f) => f,
Err(s) => return s,
};
let n = n.trunc() as i32;
if n < 0 {
// In Excel this ins #NUM!
return CalcResult::Error {
error: Error::NUM,
origin: cell,
message: "Invalid parameter for Bessel function".to_string(),
};
}
let result = bessel_j(n, x);
if result.is_infinite() || result.is_nan() {
return CalcResult::Error {
error: Error::NUM,
origin: cell,
message: "Invalid parameter for Bessel function".to_string(),
};
}
CalcResult::Number(result)
}
pub(crate) fn fn_besselk(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
if args.len() != 2 {
return CalcResult::new_args_number_error(cell);
}
let x = match self.get_number_no_bools(&args[0], cell) {
Ok(f) => f,
Err(s) => return s,
};
let n = match self.get_number_no_bools(&args[1], cell) {
Ok(f) => f,
Err(s) => return s,
};
let n = n.trunc() as i32;
let result = bessel_k(n, x);
if result.is_infinite() || result.is_nan() {
return CalcResult::Error {
error: Error::NUM,
origin: cell,
message: "Invalid parameter for Bessel function".to_string(),
};
}
CalcResult::Number(result)
}
pub(crate) fn fn_bessely(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
if args.len() != 2 {
return CalcResult::new_args_number_error(cell);
}
let x = match self.get_number_no_bools(&args[0], cell) {
Ok(f) => f,
Err(s) => return s,
};
let n = match self.get_number_no_bools(&args[1], cell) {
Ok(f) => f,
Err(s) => return s,
};
let n = n.trunc() as i32;
if n < 0 {
// In Excel this ins #NUM!
return CalcResult::Error {
error: Error::NUM,
origin: cell,
message: "Invalid parameter for Bessel function".to_string(),
};
}
let result = bessel_y(n, x);
if result.is_infinite() || result.is_nan() {
return CalcResult::Error {
error: Error::NUM,
origin: cell,
message: "Invalid parameter for Bessel function".to_string(),
};
}
CalcResult::Number(result)
}
pub(crate) fn fn_erf(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
if !(1..=2).contains(&args.len()) {
return CalcResult::new_args_number_error(cell);
}
let x = match self.get_number_no_bools(&args[0], cell) {
Ok(f) => f,
Err(s) => return s,
};
if args.len() == 2 {
let y = match self.get_number_no_bools(&args[1], cell) {
Ok(f) => f,
Err(s) => return s,
};
CalcResult::Number(erf(y) - erf(x))
} else {
CalcResult::Number(erf(x))
}
}
pub(crate) fn fn_erfprecise(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
if args.len() != 1 {
return CalcResult::new_args_number_error(cell);
};
let x = match self.get_number_no_bools(&args[0], cell) {
Ok(f) => f,
Err(s) => return s,
};
CalcResult::Number(erf(x))
}
pub(crate) fn fn_erfc(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
if args.len() != 1 {
return CalcResult::new_args_number_error(cell);
};
let x = match self.get_number_no_bools(&args[0], cell) {
Ok(f) => f,
Err(s) => return s,
};
CalcResult::Number(1.0 - erf(x))
}
pub(crate) fn fn_erfcprecise(&mut self, args: &[Node], cell: CellReference) -> CalcResult {
if args.len() != 1 {
return CalcResult::new_args_number_error(cell);
};
let x = match self.get_number_no_bools(&args[0], cell) {
Ok(f) => f,
Err(s) => return s,
};
CalcResult::Number(1.0 - erf(x))
}
}