1
- //! Element-wise methods for ndarray
1
+ // Element-wise methods for ndarray
2
2
3
+ #[ cfg( feature = "std" ) ]
3
4
use num_traits:: Float ;
4
5
5
6
use crate :: imp_prelude:: * ;
6
7
7
- macro_rules! boolean_op {
8
- ( $( $( #[ $meta1: meta] ) * fn $id1: ident $( #[ $meta2: meta] ) * fn $id2: ident -> $func: ident) +) => {
9
- $( $( #[ $meta1] ) *
8
+ #[ cfg( feature = "std" ) ]
9
+ macro_rules! boolean_ops {
10
+ ( $( #[ $meta1: meta] ) * fn $func: ident
11
+ $( #[ $meta2: meta] ) * fn $all: ident
12
+ $( #[ $meta3: meta] ) * fn $any: ident) => {
13
+ $( #[ $meta1] ) *
10
14
#[ must_use = "method returns a new array and does not mutate the original value" ]
11
- pub fn $id1 ( & self ) -> Array <bool , D > {
15
+ pub fn $func ( & self ) -> Array <bool , D > {
12
16
self . mapv( A :: $func)
13
17
}
14
18
$( #[ $meta2] ) *
15
19
#[ must_use = "method returns a new boolean value and does not mutate the original value" ]
16
- pub fn $id2( & self ) -> bool {
17
- self . mapv( A :: $func) . iter( ) . any( |& b| b)
18
- } ) +
20
+ pub fn $all( & self ) -> bool {
21
+ $crate:: Zip :: from( self ) . all( |& elt| !elt. $func( ) )
22
+ }
23
+ $( #[ $meta3] ) *
24
+ #[ must_use = "method returns a new boolean value and does not mutate the original value" ]
25
+ pub fn $any( & self ) -> bool {
26
+ !self . $all( )
27
+ }
19
28
} ;
20
29
}
21
30
22
- macro_rules! unary_op {
31
+ #[ cfg( feature = "std" ) ]
32
+ macro_rules! unary_ops {
23
33
( $( $( #[ $meta: meta] ) * fn $id: ident) +) => {
24
34
$( $( #[ $meta] ) *
25
35
#[ must_use = "method returns a new array and does not mutate the original value" ]
@@ -29,7 +39,8 @@ macro_rules! unary_op {
29
39
} ;
30
40
}
31
41
32
- macro_rules! binary_op {
42
+ #[ cfg( feature = "std" ) ]
43
+ macro_rules! binary_ops {
33
44
( $( $( #[ $meta: meta] ) * fn $id: ident( $ty: ty) ) +) => {
34
45
$( $( #[ $meta] ) *
35
46
#[ must_use = "method returns a new array and does not mutate the original value" ]
@@ -39,103 +50,87 @@ macro_rules! binary_op {
39
50
} ;
40
51
}
41
52
42
- /// # Element-wise methods for Float Array
53
+ /// # Element-wise methods for float arrays
43
54
///
44
55
/// Element-wise math functions for any array type that contains float number.
56
+ #[ cfg( feature = "std" ) ]
45
57
impl < A , S , D > ArrayBase < S , D >
46
58
where
47
- A : Float ,
59
+ A : ' static + Float ,
48
60
S : Data < Elem = A > ,
49
61
D : Dimension ,
50
62
{
51
- boolean_op ! {
63
+ boolean_ops ! {
52
64
/// If the number is `NaN` (not a number), then `true` is returned for each element.
53
65
fn is_nan
66
+ /// Return `true` if all elements are `NaN` (not a number).
67
+ fn is_all_nan
54
68
/// Return `true` if any element is `NaN` (not a number).
55
- fn is_any_nan -> is_nan
56
-
69
+ fn is_any_nan
70
+ }
71
+ boolean_ops ! {
57
72
/// If the number is infinity, then `true` is returned for each element.
58
73
fn is_infinite
74
+ /// Return `true` if all elements are infinity.
75
+ fn is_all_infinite
59
76
/// Return `true` if any element is infinity.
60
- fn is_any_infinite -> is_infinite
77
+ fn is_any_infinite
61
78
}
62
- unary_op ! {
79
+ unary_ops ! {
63
80
/// The largest integer less than or equal to each element.
64
81
fn floor
65
-
66
82
/// The smallest integer less than or equal to each element.
67
83
fn ceil
68
-
69
84
/// The nearest integer of each element.
70
85
fn round
71
-
72
86
/// The integer part of each element.
73
87
fn trunc
74
-
75
88
/// The fractional part of each element.
76
89
fn fract
77
-
78
90
/// Absolute of each element.
79
91
fn abs
80
-
81
92
/// Sign number of each element.
82
93
///
83
94
/// + `1.0` for all positive numbers.
84
95
/// + `-1.0` for all negative numbers.
85
96
/// + `NaN` for all `NaN` (not a number).
86
97
fn signum
87
-
88
98
/// The reciprocal (inverse) of each element, `1/x`.
89
99
fn recip
90
-
91
100
/// Square root of each element.
92
101
fn sqrt
93
-
94
102
/// `e^x` of each element (exponential function).
95
103
fn exp
96
-
97
104
/// `2^x` of each element.
98
105
fn exp2
99
-
100
106
/// Natural logarithm of each element.
101
107
fn ln
102
-
103
108
/// Base 2 logarithm of each element.
104
109
fn log2
105
-
106
110
/// Base 10 logarithm of each element.
107
111
fn log10
108
-
109
112
/// Cubic root of each element.
110
113
fn cbrt
111
-
112
114
/// Sine of each element (in radians).
113
115
fn sin
114
-
115
116
/// Cosine of each element (in radians).
116
117
fn cos
117
-
118
118
/// Tangent of each element (in radians).
119
119
fn tan
120
-
121
120
/// Converts radians to degrees for each element.
122
121
fn to_degrees
123
-
124
122
/// Converts degrees to radians for each element.
125
123
fn to_radians
126
124
}
127
- binary_op ! {
125
+ binary_ops ! {
128
126
/// Integer power of each element.
129
127
///
130
128
/// This function is generally faster than using float power.
131
129
fn powi( i32 )
132
-
133
130
/// Float power of each element.
134
131
fn powf( A )
135
-
136
132
/// Logarithm of each element with respect to an arbitrary base.
137
133
fn log( A )
138
-
139
134
/// The positive difference between given number and each element.
140
135
fn abs_sub( A )
141
136
}
@@ -145,18 +140,37 @@ where
145
140
pub fn pow2 ( & self ) -> Array < A , D > {
146
141
self . mapv ( |v : A | v * v)
147
142
}
143
+ }
148
144
149
- /// Limit the values for each element.
145
+ impl < A , S , D > ArrayBase < S , D >
146
+ where
147
+ A : ' static + PartialOrd + Clone ,
148
+ S : Data < Elem = A > ,
149
+ D : Dimension ,
150
+ {
151
+ /// Limit the values for each element, similar to NumPy's `clip` function.
150
152
///
151
153
/// ```
152
- /// use ndarray::{Array1, array} ;
154
+ /// use ndarray::array;
153
155
///
154
- /// let a = Array1::range(0., 10., 1.);
155
- /// assert_eq!(a.clip(1., 8.), array![1., 1., 2., 3., 4., 5., 6., 7., 8., 8.]);
156
- /// assert_eq!(a.clip(8., 1.), array![1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]);
157
- /// assert_eq!(a.clip(3., 6.), array![3., 3., 3., 3., 4., 5., 6., 6., 6., 6.]);
156
+ /// let a = array![0., 1., 2., 3., 4., 5., 6., 7., 8., 9.];
157
+ /// assert_eq!(a.clamp(1., 8.), array![1., 1., 2., 3., 4., 5., 6., 7., 8., 8.]);
158
+ /// assert_eq!(a.clamp(3., 6.), array![3., 3., 3., 3., 4., 5., 6., 6., 6., 6.]);
158
159
/// ```
159
- pub fn clip ( & self , min : A , max : A ) -> Array < A , D > {
160
- self . mapv ( |v| A :: min ( A :: max ( v, min) , max) )
160
+ ///
161
+ /// # Panics
162
+ ///
163
+ /// Panics if `min > max`, `min` is `NaN`, or `max` is `NaN`.
164
+ pub fn clamp ( & self , min : A , max : A ) -> Array < A , D > {
165
+ assert ! ( min <= max, "min must be less than or equal to max" ) ;
166
+ self . mapv ( |v| {
167
+ if v < min {
168
+ min. clone ( )
169
+ } else if v > max {
170
+ max. clone ( )
171
+ } else {
172
+ v
173
+ }
174
+ } )
161
175
}
162
176
}
0 commit comments