chela 0.0.2

High-performance Machine Learning, Auto-Differentiation and Tensor Algebra crate for Rust
Documentation
use crate::RawDataType;
use crate::ndarray::NdArrayFlags;
use crate::NdArray;
use std::ops::{AddAssign, BitAndAssign, BitOrAssign, DivAssign, MulAssign, RemAssign, ShlAssign, ShrAssign, SubAssign};

macro_rules! define_binary_iop {
    ( $trait_: ident, $operator: tt, $method: ident ) => {
        impl<T: RawDataType + $trait_> $trait_<NdArray<'_, T>> for NdArray<'_, T> {
            fn $method(&mut self, rhs: NdArray<'_, T>) {
                *self $operator &rhs
            }
        }
    
        impl<T: RawDataType + $trait_> $trait_<&NdArray<'_, T>> for NdArray<'_, T> {
            fn $method(&mut self, rhs: &NdArray<'_, T>) {
                if !self.flags.contains(NdArrayFlags::Writeable) {
                    panic!("tensor is readonly.");
                }
    
                let rhs = rhs.broadcast_to(&self.shape);
                
                for (lhs, rhs) in self.flatiter_ptr().zip(rhs.flatiter()) {
                    unsafe { *lhs $operator rhs; }
                }
            }
        }
        
        impl<T: RawDataType + $trait_> $trait_<T> for NdArray<'_, T> {
            fn $method(&mut self, rhs: T) {
                if !self.flags.contains(NdArrayFlags::Writeable) {
                    panic!("tensor is readonly.");
                }
                
                for lhs in self.flatiter_ptr() {
                    unsafe { *lhs $operator rhs; }
                }
            }
        }
    };
}

define_binary_iop!(AddAssign, +=, add_assign);
define_binary_iop!(SubAssign, -=, sub_assign);
define_binary_iop!(MulAssign, *=, mul_assign);
define_binary_iop!(DivAssign, /=, div_assign);
define_binary_iop!(RemAssign, %=, rem_assign);
define_binary_iop!(BitAndAssign, &=, bitand_assign);
define_binary_iop!(BitOrAssign, |=, bitor_assign);
define_binary_iop!(ShlAssign, <<=, shl_assign);
define_binary_iop!(ShrAssign, >>=, shr_assign);