extern crate ndarray;
use NdArray;
use Tensor;
pub type ComputeResult = ;
/// Operation trait. `Tensor` wraps trait-object of this.
///
/// # Usage
///
/// ```
/// extern crate ndarray;
/// extern crate autograd as ag;
///
/// type NdArray = ndarray::Array<f32, ndarray::IxDyn>;
///
/// struct Sigmoid;
///
/// // Implements `Operation` trait for `Sigmoid`
/// impl ag::op::Op for Sigmoid {
///
/// fn name(&self) -> &str
/// {
/// "Sigmoid"
/// }
///
/// fn compute(&self, ctx: ag::runtime::OpComputeContext)
/// -> Vec<Result<NdArray, ag::op::ComputeError>>
/// {
/// let xs = ctx.grab_inputs();
/// let x = xs[0];
/// // Use `ndarray::Array::mapv` for element-wise computation.
/// let y = x.mapv(|a| ((a * 0.5).tanh() * 0.5) + 0.5);
/// vec![Ok(y)]
/// }
///
/// fn grad(&self, gy: &ag::Tensor, xs: &[&ag::Tensor], y: &ag::Tensor)
/// -> Vec<Option<ag::Tensor>>
/// {
/// // Symbolic gradient of `x`
/// let gx = gy * (y - ag::square(y));
/// vec![Some(gx)]
/// }
/// }
///
/// // Symbolic `sigmoid` function for end-user.
/// fn sigmoid(x: &ag::Tensor) -> ag::Tensor
/// {
/// ag::Tensor::builder()
/// .set_inputs(vec![x])
/// .set_shape(x.shape())
/// .build(Sigmoid)
/// }
/// ```