1use crate::*;
2use mech_core::*;
3use libm::{tanh, tanhf};
4
5macro_rules! tanh_op {
7 ($arg:expr, $out:expr) => {
8 unsafe { (*$out).0 = tanh((*$arg).0); }
9 };
10}
11
12macro_rules! tanh_vec_op {
13 ($arg:expr, $out:expr) => {
14 unsafe {
15 for i in 0..(*$arg).len() {
16 ((*$out)[i]).0 = tanh(((*$arg)[i]).0);
17 }
18 }
19 };
20}
21
22macro_rules! tanhf_op {
23 ($arg:expr, $out:expr) => {
24 unsafe { (*$out).0 = tanhf((*$arg).0); }
25 };
26}
27
28macro_rules! tanhf_vec_op {
29 ($arg:expr, $out:expr) => {
30 unsafe {
31 for i in 0..(*$arg).len() {
32 ((*$out)[i]).0 = tanhf(((*$arg)[i]).0);
33 }
34 }
35 };
36}
37
38impl_math_urop!(MathTanh, F32, tanhf);
39impl_math_urop!(MathTanh, F64, tanh);
40
41fn impl_tanh_fxn(lhs_value: Value) -> Result<Box<dyn MechFunction>, MechError> {
42 impl_urnop_match_arms2!(
43 MathTanh,
44 (lhs_value),
45 F32 => MatrixF32, F32, F32::zero(), "F32";
46 F64 => MatrixF64, F64, F64::zero(), "F64";
47 )
48}
49
50pub struct MathTanh {}
51
52impl NativeFunctionCompiler for MathTanh {
53 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
54 if arguments.len() != 1 {
55 return Err(MechError {
56 file: file!().to_string(),
57 tokens: vec![],
58 msg: "".to_string(),
59 id: line!(),
60 kind: MechErrorKind::IncorrectNumberOfArguments,
61 });
62 }
63 let input = arguments[0].clone();
64 match impl_tanh_fxn(input.clone()) {
65 Ok(fxn) => Ok(fxn),
66 Err(_) => match input {
67 Value::MutableReference(input) => impl_tanh_fxn(input.borrow().clone()),
68 _ => Err(MechError {
69 file: file!().to_string(),
70 tokens: vec![],
71 msg: "".to_string(),
72 id: line!(),
73 kind: MechErrorKind::UnhandledFunctionArgumentKind,
74 }),
75 },
76 }
77 }
78}