mod binary_arith;
mod boolean;
mod builtin_arith;
mod cmp;
mod combine;
mod constructors;
mod convert;
mod index;
mod masked;
mod reduce;
mod scatter;
mod shape;
mod slice;
mod unary_arith;
use crate::{shape::NdimMax, Shape, Tensor, TensorValue};
use ella_common::ops::{TensorOp, TensorUnaryOp};
fn unary_op<T, O, S, F>(t: &Tensor<T, S>, f: F) -> Tensor<O, S>
where
T: TensorValue,
O: TensorValue,
S: Shape,
F: Fn(T) -> O,
{
unsafe { Tensor::from_trusted_len_iter(t.iter().map(f), t.shape().clone()) }
}
fn binary_op<T1, T2, O, S1, S2, F>(
a: &Tensor<T1, S1>,
b: &Tensor<T2, S2>,
op: F,
) -> Tensor<O, <S1 as NdimMax<S2>>::Output>
where
T1: TensorValue,
T2: TensorValue,
O: TensorValue,
S1: Shape + NdimMax<S2>,
S2: Shape,
F: Fn(T1, T2) -> O,
{
if a.ndim() == b.ndim() && a.shape().slice() == b.shape().slice() {
let shape = <<S1 as NdimMax<S2>>::Output as Shape>::from_shape(a.shape()).unwrap();
unsafe {
Tensor::from_trusted_len_iter(a.iter().zip(b.iter()).map(|(a, b)| op(a, b)), shape)
}
} else {
let (a, b) = a.broadcast_with(b).unwrap();
let shape = a.shape().clone();
unsafe {
Tensor::from_trusted_len_iter(a.iter().zip(b.iter()).map(|(a, b)| op(a, b)), shape)
}
}
}