acme_tensor/impls/ops/
unary.rs1use crate::prelude::{Scalar, ScalarExt, TensorExpr};
6use crate::tensor::*;
7use acme::ops::unary::UnaryOp;
8use core::ops;
9
10impl<T> ops::Neg for TensorBase<T>
11where
12 T: Copy + ops::Neg<Output = T>,
13{
14 type Output = Self;
15
16 fn neg(self) -> Self::Output {
17 let shape = self.shape().clone();
18 let store = self.data().iter().map(|a| (*a).neg()).collect();
19 let op = TensorExpr::unary(self, UnaryOp::Neg);
20 from_vec_with_op(false, op, shape, store)
21 }
22}
23
24impl<'a, T> ops::Neg for &'a TensorBase<T>
25where
26 T: Copy + ops::Neg<Output = T>,
27{
28 type Output = TensorBase<T>;
29
30 fn neg(self) -> Self::Output {
31 let shape = self.shape();
32 let store = self.data().iter().map(|a| (*a).neg()).collect();
33 let op = TensorExpr::unary(self.clone(), UnaryOp::Neg);
34 from_vec_with_op(false, op, shape, store)
35 }
36}
37
38impl<T> ops::Not for TensorBase<T>
39where
40 T: Copy + ops::Not<Output = T>,
41{
42 type Output = Self;
43
44 fn not(self) -> Self::Output {
45 let shape = self.shape().clone();
46 let store = self.data().iter().map(|a| (*a).not()).collect();
47 let op = TensorExpr::unary(self, UnaryOp::Not);
48 from_vec_with_op(false, op, shape, store)
49 }
50}
51
52impl<'a, T> ops::Not for &'a TensorBase<T>
53where
54 T: Copy + ops::Not<Output = T>,
55{
56 type Output = TensorBase<T>;
57
58 fn not(self) -> Self::Output {
59 let shape = self.shape();
60 let store = self.data.iter().copied().map(|a| !a).collect();
61 let op = TensorExpr::unary(self.clone(), UnaryOp::Not);
62 from_vec_with_op(false, op, shape, store)
63 }
64}
65
66macro_rules! impl_unary_op {
67 ($variant:ident, $method:ident) => {
68 pub fn $method(&self) -> Self {
69 let shape = self.shape();
70 let store = self.data().iter().copied().map(|v| v.$method()).collect();
71 let op = TensorExpr::unary(self.clone(), UnaryOp::$variant);
72 from_vec_with_op(false, op, shape, store)
73 }
74 };
75 (custom $variant:ident, $method:ident, $f:expr) => {
76 pub fn $method(self) -> Self {
77 let shape = self.shape().clone();
78 let store = self.store.iter().copied().map($f).collect();
79 let op = TensorExpr::unary(self, UnaryOp::$variant);
80 from_vec_with_op(false, op, shape, store)
81 }
82 };
83}
84
85impl<T> TensorBase<T>
86where
87 T: Scalar,
88{
89 pub fn abs(&self) -> TensorBase<<T as Scalar>::Real>
90 where
91 T: Scalar<Real = T>,
92 {
93 let shape = self.shape();
94 let store = self.data.iter().copied().map(Scalar::abs).collect();
95 let op = TensorExpr::unary(self.clone(), UnaryOp::Abs);
96 from_vec_with_op(false, op, shape, store)
97 }
98
99 pub fn sigmoid(&self) -> TensorBase<T>
100 where
101 T: ScalarExt,
102 {
103 let op = TensorExpr::sigmoid(self.clone());
104 let shape = self.shape();
105 let store = self.iter().copied().map(ScalarExt::sigmoid).collect();
106 from_vec_with_op(false, op, shape, store)
107 }
108
109 impl_unary_op!(Cos, cos);
110 impl_unary_op!(Cosh, cosh);
111 impl_unary_op!(Exp, exp);
112 impl_unary_op!(Ln, ln);
113 impl_unary_op!(Recip, recip);
114 impl_unary_op!(Sin, sin);
115 impl_unary_op!(Sinh, sinh);
116 impl_unary_op!(Square, sqr);
117 impl_unary_op!(Sqrt, sqrt);
118 impl_unary_op!(Tan, tan);
119 impl_unary_op!(Tanh, tanh);
120}