Skip to content

Commit 2e8aba8

Browse files
authored
Merge pull request #374 from jturner314/unary-ref
Implement Neg and Not for &ArrayBase
2 parents 6e99ef8 + 848ec42 commit 2e8aba8

File tree

3 files changed

+49
-5
lines changed

3 files changed

+49
-5
lines changed

src/impl_ops.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,19 @@ mod arithmetic_ops {
292292
}
293293
}
294294

295+
impl<'a, A, S, D> Neg for &'a ArrayBase<S, D>
296+
where &'a A: 'a + Neg<Output=A>,
297+
S: Data<Elem=A>,
298+
D: Dimension
299+
{
300+
type Output = Array<A, D>;
301+
/// Perform an elementwise negation of reference `self` and return the
302+
/// result as a new `Array`.
303+
fn neg(self) -> Array<A, D> {
304+
self.map(Neg::neg)
305+
}
306+
}
307+
295308
impl<A, S, D> Not for ArrayBase<S, D>
296309
where A: Clone + Not<Output=A>,
297310
S: DataOwned<Elem=A> + DataMut,
@@ -306,6 +319,19 @@ mod arithmetic_ops {
306319
self
307320
}
308321
}
322+
323+
impl<'a, A, S, D> Not for &'a ArrayBase<S, D>
324+
where &'a A: 'a + Not<Output=A>,
325+
S: Data<Elem=A>,
326+
D: Dimension
327+
{
328+
type Output = Array<A, D>;
329+
/// Perform an elementwise unary not of reference `self` and return the
330+
/// result as a new `Array`.
331+
fn not(self) -> Array<A, D> {
332+
self.map(Not::not)
333+
}
334+
}
309335
}
310336

311337
mod assign_ops {

src/lib.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,8 @@ pub type Ixs = isize;
529529
///
530530
/// Since the trait implementations are hard to overview, here is a summary.
531531
///
532+
/// ### Binary Operators with Two Arrays
533+
///
532534
/// Let `A` be an array or view of any kind. Let `B` be an array
533535
/// with owned storage (either `Array` or `RcArray`).
534536
/// Let `C` be an array with mutable data (either `Array`, `RcArray`
@@ -542,6 +544,8 @@ pub type Ixs = isize;
542544
/// - `B @ &A` which consumes `B`, updates it with the result, and returns it
543545
/// - `C @= &A` which performs an arithmetic operation in place
544546
///
547+
/// ### Binary Operators with Array and Scalar
548+
///
545549
/// The trait [`ScalarOperand`](trait.ScalarOperand.html) marks types that can be used in arithmetic
546550
/// with arrays directly. For a scalar `K` the following combinations of operands
547551
/// are supported (scalar can be on either the left or right side, but
@@ -551,6 +555,15 @@ pub type Ixs = isize;
551555
/// - `B @ K` or `K @ B` which consumes `B`, updates it with the result and returns it
552556
/// - `C @= K` which performs an arithmetic operation in place
553557
///
558+
/// ### Unary Operators
559+
///
560+
/// Let `A` be an array or view of any kind. Let `B` be an array with owned
561+
/// storage (either `Array` or `RcArray`). The following operands are supported
562+
/// for an arbitrary unary operator denoted by `@` (it can be `-` or `!`).
563+
///
564+
/// - `@&A` which produces a new `Array`
565+
/// - `@B` which consumes `B`, updates it with the result, and returns it
566+
///
554567
/// ## Broadcasting
555568
///
556569
/// Arrays support limited *broadcasting*, where arithmetic operations with

tests/oper.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,32 @@ use ndarray::Si;
1111
use ndarray::{Ix, Ixs};
1212

1313
use std::fmt;
14+
use std::ops::Neg;
1415
use num_traits::Float;
1516

1617
fn test_oper(op: &str, a: &[f32], b: &[f32], c: &[f32])
1718
{
1819
let aa = rcarr1(a);
1920
let bb = rcarr1(b);
2021
let cc = rcarr1(c);
21-
test_oper_arr(op, aa.clone(), bb.clone(), cc.clone());
22+
test_oper_arr::<f32, _>(op, aa.clone(), bb.clone(), cc.clone());
2223
let dim = (2, 2);
2324
let aa = aa.reshape(dim);
2425
let bb = bb.reshape(dim);
2526
let cc = cc.reshape(dim);
26-
test_oper_arr(op, aa.clone(), bb.clone(), cc.clone());
27+
test_oper_arr::<f32, _>(op, aa.clone(), bb.clone(), cc.clone());
2728
let dim = (1, 2, 1, 2);
2829
let aa = aa.reshape(dim);
2930
let bb = bb.reshape(dim);
3031
let cc = cc.reshape(dim);
31-
test_oper_arr(op, aa.clone(), bb.clone(), cc.clone());
32+
test_oper_arr::<f32, _>(op, aa.clone(), bb.clone(), cc.clone());
3233
}
3334

34-
fn test_oper_arr<A: NdFloat + fmt::Debug, D: ndarray::Dimension>
35-
(op: &str, mut aa: RcArray<A,D>, bb: RcArray<A, D>, cc: RcArray<A, D>)
35+
fn test_oper_arr<A, D>(op: &str, mut aa: RcArray<A, D>, bb: RcArray<A, D>, cc: RcArray<A, D>)
36+
where
37+
A: NdFloat,
38+
for<'a> &'a A: Neg<Output=A>,
39+
D: Dimension,
3640
{
3741
match op {
3842
"+" => {
@@ -61,6 +65,7 @@ fn test_oper_arr<A: NdFloat + fmt::Debug, D: ndarray::Dimension>
6165
assert_eq!(aa, cc);
6266
},
6367
"neg" => {
68+
assert_eq!(-&aa, cc);
6469
assert_eq!(-aa.clone(), cc);
6570
},
6671
_ => panic!()

0 commit comments

Comments
 (0)