```  1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
```
```//! Value and operators in calculation graph

use std::fmt::Debug;
use ndarray::*;
use ndarray_linalg::*;

use error::*;

pub mod neg;

/// Value in graph
///
/// Each node has a value in the following types:
///
/// - Scalar
/// - Vector (represented by `Array1<A>`)
/// - Matrix (represented by `Array2<A>`)
///
/// These types are selected dynamically, and operators returns `Err`
/// if it does not support the received value.
#[derive(Debug, Clone, IntoEnum)]
pub enum Value<A: Scalar> {
Scalar(A),
Vector(Array1<A>),
Matrix(Array2<A>),
}

impl<A: Scalar> Value<A> {
/// Return value if it is a scalar
pub fn as_scalar(&self) -> Result<A> {
match *self {
Value::Scalar(a) => Ok(a),
_ => Err(CastError {}.into()),
}
}

pub fn identity() -> Self {
Value::Scalar(A::from_f64(1.0))
}
}

/// Unary Operators
pub trait UnaryOperator<A: Scalar>: Clone + Debug {
/// Evaluate the result value of the operator
fn eval_value(&self, arg: &Value<A>) -> Result<Value<A>>;
/// Evaluate the derivative of the operator multiplied by the received
/// derivative from upper of the graph.
fn eval_deriv(&self, arg: &Value<A>, deriv: &Value<A>) -> Result<Value<A>>;
}

/// Enumerate of UnaryOperators implementing `UnaryOperator<A>` trait
#[derive(Debug, Clone, Copy, IntoEnum)]
pub enum UnaryOperatorAny {
Neg(neg::Neg),
}

/// Negate operator
pub fn neg() -> UnaryOperatorAny {
neg::Neg {}.into()
}

impl<A: Scalar> UnaryOperator<A> for UnaryOperatorAny {
fn eval_value(&self, arg: &Value<A>) -> Result<Value<A>> {
match self {
&UnaryOperatorAny::Neg(op) => op.eval_value(arg),
}
}

fn eval_deriv(&self, arg: &Value<A>, deriv: &Value<A>) -> Result<Value<A>> {
match self {
&UnaryOperatorAny::Neg(op) => op.eval_deriv(arg, deriv),
}
}
}

/// Binary Operators
pub trait BinaryOperator<A: Scalar>: Clone + Debug {
/// Evaluate the result value of the operator
fn eval_value(&self, lhs: &Value<A>, rhs: &Value<A>) -> Result<Value<A>>;
/// Evaluate the derivative of the operator multiplied by the received
/// derivative from upper of the graph.
fn eval_deriv(
&self,
lhs: &Value<A>,
rhs: &Value<A>,
deriv: &Value<A>,
) -> Result<(Value<A>, Value<A>)>;
}

/// Enumerate of BinaryOperator implementing `BinaryOperator<A>` trait
#[derive(Debug, Clone, Copy, IntoEnum)]
pub enum BinaryOperatorAny {
}

pub fn add() -> BinaryOperatorAny {
}

impl<A: Scalar> BinaryOperator<A> for BinaryOperatorAny {
fn eval_value(&self, lhs: &Value<A>, rhs: &Value<A>) -> Result<Value<A>> {
match self {
}
}

fn eval_deriv(
&self,
lhs: &Value<A>,
rhs: &Value<A>,
deriv: &Value<A>,
) -> Result<(Value<A>, Value<A>)> {
match self {