mech_interpreter/stdlib/math/
exp.rs

1#[macro_use]
2use crate::stdlib::*;
3
4// Exp ------------------------------------------------------------------------
5
6macro_rules! exp_op {
7  ($lhs:expr, $rhs:expr, $out:expr) => {
8    unsafe {*$out = (*$lhs).pow(*$rhs);}
9  };}
10  
11macro_rules! exp_vec_op {
12($lhs:expr, $rhs:expr, $out:expr) => {
13  unsafe {
14  for i in 0..(*$lhs).len() {
15    (*$out)[i] = (*$lhs)[i].pow((*$rhs)[i]);
16  }}};}
17
18macro_rules! exp_scalar_lhs_op {
19($lhs:expr, $rhs:expr, $out:expr) => {
20  unsafe {
21  for i in 0..(*$lhs).len() {
22    (*$out)[i] = (*$lhs)[i].pow((*$rhs));
23  }}};}
24
25macro_rules! exp_scalar_rhs_op {
26($lhs:expr, $rhs:expr, $out:expr) => {
27  unsafe {
28  for i in 0..(*$rhs).len() {
29    (*$out)[i] = (*$lhs).pow((*$rhs)[i]);
30  }}};}
31
32macro_rules! exp_mat_vec_op {
33  ($lhs:expr, $rhs:expr, $out:expr) => {
34    unsafe {
35      let mut out_deref = &mut (*$out);
36      let lhs_deref = &(*$lhs);
37      let rhs_deref = &(*$rhs);
38      for (mut col, lhs_col) in out_deref.column_iter_mut().zip(lhs_deref.column_iter()) {
39        for i in 0..col.len() {
40          col[i] = lhs_col[i].pow(rhs_deref[i]);
41        }
42      }
43    }
44  };}
45
46macro_rules! exp_vec_mat_op {
47  ($lhs:expr, $rhs:expr, $out:expr) => {
48    unsafe {
49      let mut out_deref = &mut (*$out);
50      let lhs_deref = &(*$lhs);
51      let rhs_deref = &(*$rhs);
52      for (mut col, rhs_col) in out_deref.column_iter_mut().zip(rhs_deref.column_iter()) {
53        for i in 0..col.len() {
54          col[i] = lhs_deref[i].pow(rhs_col[i]);
55        }
56      }
57    }
58  };}
59
60macro_rules! exp_mat_row_op {
61  ($lhs:expr, $rhs:expr, $out:expr) => {
62    unsafe {
63      let mut out_deref = &mut (*$out);
64      let lhs_deref = &(*$lhs);
65      let rhs_deref = &(*$rhs);
66      for (mut row, lhs_row) in out_deref.row_iter_mut().zip(lhs_deref.row_iter()) {
67        for i in 0..row.len() {
68          row[i] = lhs_row[i].pow(rhs_deref[i]);
69        }
70      }
71    }
72  };}
73
74macro_rules! exp_row_mat_op {
75  ($lhs:expr, $rhs:expr, $out:expr) => {
76    unsafe {
77      let mut out_deref = &mut (*$out);
78      let lhs_deref = &(*$lhs);
79      let rhs_deref = &(*$rhs);
80      for (mut row, rhs_row) in out_deref.row_iter_mut().zip(rhs_deref.row_iter()) {
81        for i in 0..row.len() {
82          row[i] = lhs_deref[i].pow(rhs_row[i]);
83        }
84      }
85    }
86  };} 
87  
88#[macro_export]
89macro_rules! impl_expop {
90($struct_name:ident, $arg1_type:ty, $arg2_type:ty, $out_type:ty, $op:ident) => {
91  #[derive(Debug)]
92  struct $struct_name<T> {
93    lhs: Ref<$arg1_type>,
94    rhs: Ref<$arg2_type>,
95    out: Ref<$out_type>,
96  }
97  impl<T> MechFunction for $struct_name<T>
98  where
99    T: Copy + Debug + Clone + Sync + Send + 'static + 
100    PartialEq + PartialOrd +
101    Add<Output = T> + AddAssign +
102    Sub<Output = T> + SubAssign +
103    Mul<Output = T> + MulAssign +
104    Div<Output = T> + DivAssign +
105    Pow<T, Output = T> +
106    Zero + One,
107    Ref<$out_type>: ToValue
108  {
109    fn solve(&self) {
110      let lhs_ptr = self.lhs.as_ptr();
111      let rhs_ptr = self.rhs.as_ptr();
112      let out_ptr = self.out.as_ptr();
113      $op!(lhs_ptr,rhs_ptr,out_ptr);
114    }
115    fn out(&self) -> Value { self.out.to_value() }
116    fn to_string(&self) -> String { format!("{:#?}", self) }
117  }};}
118
119#[macro_export]
120macro_rules! impl_math_fxns_exp {
121  ($lib:ident) => {
122    impl_fxns!($lib,T,T,impl_expop);
123  }}
124
125impl_math_fxns_exp!(Exp);
126
127fn impl_exp_fxn(lhs_value: Value, rhs_value: Value) -> Result<Box<dyn MechFunction>, MechError> {
128  impl_binop_match_arms!(
129      Exp,
130      (lhs_value, rhs_value),
131      U8,   U8   => MatrixU8,  u8,  u8::zero(), "U8";
132      U16,  U16  => MatrixU16, u16, u16::zero(), "U16";
133      U32,  U32  => MatrixU32, u32, u32::zero(), "U32";
134      F32,  F32  => MatrixF32,  F32,  F32::zero(), "F32";
135      F64,  F64  => MatrixF64,  F64,  F64::zero(), "F64";
136  )}
137
138impl_mech_binop_fxn!(MathExp,impl_exp_fxn);