pub struct Variable<'v> {
pub graph: &'v Graph,
pub index: usize,
pub value: f64,
}
Expand description
Struct to contain the initial variables.
Fields§
§graph: &'v Graph
Pointer to the graph.
index: usize
Index to the vertex.
value: f64
Value associated to the vertex.
Implementations§
Source§impl<'v> Variable<'v>
impl<'v> Variable<'v>
Sourcepub fn abs(self) -> Variable<'v>
pub fn abs(self) -> Variable<'v>
Absolute value function. d/dx abs(x) = sign(x)
let g = Graph::new();
let x1 = g.var(1.0);
let z1 = x1.abs();
let grad1 = z1.accumulate();
assert!((z1.value - 1.0).abs() <= 1e-15);
assert!((grad1.wrt(&x1) - 1.0).abs() <= 1e-15);
let x2 = g.var(-1.0);
let z2 = x2.abs();
let grad2 = z2.accumulate();
assert!((z2.value - 1.0).abs() <= 1e-15);
assert!((grad2.wrt(&x2) - (-1.0)).abs() <= 1e-15);
Sourcepub fn acos(self) -> Variable<'v>
pub fn acos(self) -> Variable<'v>
Inverse cosine function. d/dx cos^-1(x) = - 1 / sqrt(1 - x^2)
let g = Graph::new();
let x1 = g.var(0.0);
let z1 = x1.acos();
let grad1 = z1.accumulate();
assert!((z1.value - 1.5707963267948966).abs() <= 1e-15);
assert!((grad1.wrt(&x1) - (-1.0)).abs() <= 1e-15);
Sourcepub fn acosh(self) -> Variable<'v>
pub fn acosh(self) -> Variable<'v>
Inverse hyperbolic cosine function. d/dx cosh^-1(x) = 1 / ( sqrt(x-1) * sqrt(x+1) )
let g = Graph::new();
let x = g.var(5.0);
let z = x.acosh();
let grad = z.accumulate();
assert!((z.value - 2.2924316695611777).abs() <= 1e-15);
assert!((grad.wrt(&x) - 0.20412414523193150818).abs() <= 1e-15);
Sourcepub fn asin(self) -> Variable<'v>
pub fn asin(self) -> Variable<'v>
Inverse sine function. d/dx sin^-1(x) = 1 / sqrt(1 - x^2)
let g = Graph::new();
let x = g.var(0.0);
let z = x.asin();
let grad = z.accumulate();
//assert_eq!(z.value, std::f64::consts::PI / 2.0);
assert_eq!(z.value, 0.0);
assert_eq!(grad.wrt(&x), 1.0);
Sourcepub fn asinh(self) -> Variable<'v>
pub fn asinh(self) -> Variable<'v>
Inverse hyperbolic sine function. d/dx sinh^-1(x) = 1 / sqrt(1 + x^2)
let g = Graph::new();
let x = g.var(0.0);
let z = x.asinh();
let grad = z.accumulate();
assert_eq!(z.value, 0.0);
assert_eq!(grad.wrt(&x), 1.0);
Sourcepub fn atan(self) -> Variable<'v>
pub fn atan(self) -> Variable<'v>
Inverse tangent function. d/dx tan^-1(x) = 1 / (1 + x^2)
let g = Graph::new();
let x = g.var(0.0);
let z = x.atan();
let grad = z.accumulate();
assert_eq!(z.value, 0.0);
assert_eq!(grad.wrt(&x), 1.0);
Sourcepub fn atanh(self) -> Variable<'v>
pub fn atanh(self) -> Variable<'v>
Inverse hyperbolic tangent function. d/dx tanh^-1(x) = 1 / (1 + x^2)
let g = Graph::new();
let x = g.var(0.0);
let z = x.atanh();
let grad = z.accumulate();
assert_approx_equal!(z.value, 0.00000000000, 1e-10);
assert_approx_equal!(grad.wrt(&x), 1.00000000000, 1e-10);
Sourcepub fn cbrt(self) -> Variable<'v>
pub fn cbrt(self) -> Variable<'v>
Cuberoot function. d/dx cuberoot(x) = 1 / ( 3 * x^(2/3) )
let g = Graph::new();
let x = g.var(1.0);
let z = x.cbrt();
let grad = z.accumulate();
assert_approx_equal!(z.value, 1.00000000000, 1e-10);
assert_approx_equal!(grad.wrt(&x), 0.33333333333, 1e-10);
Sourcepub fn cos(self) -> Variable<'v>
pub fn cos(self) -> Variable<'v>
Cosine function. d/dx cos(x) = -sin(x)
let g = Graph::new();
let x = g.var(1.0);
let z = x.cos();
let grad = z.accumulate();
assert_approx_equal!(z.value, 0.54030230586, 1e-10);
assert_approx_equal!(grad.wrt(&x), -0.84147098480, 1e-10);
Sourcepub fn cosh(self) -> Variable<'v>
pub fn cosh(self) -> Variable<'v>
Inverse hyperbolic cosine function. d/dx cosh(x) = sinh(x)
let g = Graph::new();
let x = g.var(1.0);
let z = x.cosh();
let grad = z.accumulate();
assert_approx_equal!(z.value, 1.54308063481, 1e-10);
assert_approx_equal!(grad.wrt(&x), 1.17520119364, 1e-10);
Sourcepub fn exp(self) -> Variable<'v>
pub fn exp(self) -> Variable<'v>
Exponential function (base e). d/dx exp(x) = exp(x) = y
let g = Graph::new();
let x = g.var(1.0);
let z = x.exp();
let grad = z.accumulate();
assert_eq!(z.value, std::f64::consts::E);
assert_eq!(grad.wrt(&x), std::f64::consts::E);
Sourcepub fn exp2(self) -> Variable<'v>
pub fn exp2(self) -> Variable<'v>
Exponential function (base 2) d/dx 2^x = 2^x * ln(2)
let g = Graph::new();
let x = g.var(1.0);
let z = x.exp2();
let grad = z.accumulate();
assert_approx_equal!(z.value, 2.00000000000, 1e-10);
assert_approx_equal!(grad.wrt(&x), 1.38629436111, 1e-10);
Sourcepub fn exp_m1(self) -> Variable<'v>
pub fn exp_m1(self) -> Variable<'v>
Exponential function minus 1 function. d/dx exp(x) - 1 = exp(x)
let g = Graph::new();
let x = g.var(1.0);
let z = x.exp_m1();
let grad = z.accumulate();
assert_approx_equal!(z.value, 1.71828182845, 1e-10);
assert_approx_equal!(grad.wrt(&x), 2.71828182845, 1e-10);
Sourcepub fn ln(self) -> Variable<'v>
pub fn ln(self) -> Variable<'v>
Logarithm (natural) of x
.
d/dx ln(x) = 1 / x
let g = Graph::new();
let x = g.var(std::f64::consts::E);
let z = x.ln();
let grad = z.accumulate();
assert_eq!(z.value, 1.0);
assert_eq!(grad.wrt(&x), 0.36787944117144233);
Sourcepub fn ln_1p(self) -> Variable<'v>
pub fn ln_1p(self) -> Variable<'v>
Logarithm (natural) of 1 + x
.
d/dx ln(1+x) = 1 / (1+x)
let g = Graph::new();
let x = g.var(1.0);
let z = x.ln_1p();
let grad = z.accumulate();
assert_approx_equal!(z.value, 0.69314718055, 1e-10);
assert_approx_equal!(grad.wrt(&x), 0.50000000000, 1e-10);
Sourcepub fn log10(self) -> Variable<'v>
pub fn log10(self) -> Variable<'v>
Logarithm (base 10). d/dx log_10(x) = 1 / x
let g = Graph::new();
let x = g.var(1.0);
let z = x.log10();
let grad = z.accumulate();
assert_approx_equal!(z.value, 0.00000000000, 1e-10);
assert_approx_equal!(grad.wrt(&x), 1.00000000000, 1e-10);
Sourcepub fn log2(self) -> Variable<'v>
pub fn log2(self) -> Variable<'v>
Logarithm (base 2). d/dx log_2(x) = 1 / x
let g = Graph::new();
let x = g.var(1.0);
let z = x.log2();
let grad = z.accumulate();
assert_approx_equal!(z.value, 0.00000000000, 1e-10);
assert_approx_equal!(grad.wrt(&x), 1.00000000000, 1e-10);
Sourcepub fn recip(self) -> Variable<'v>
pub fn recip(self) -> Variable<'v>
Reciprocal function. d/dx 1 / x = - 1 / x^2
let g = Graph::new();
let x = g.var(1.0);
let z = x.recip();
let grad = z.accumulate();
assert_eq!(z.value, 1.0);
assert_eq!(grad.wrt(&x), -1.0);
Sourcepub fn sin(self) -> Variable<'v>
pub fn sin(self) -> Variable<'v>
Sine function. d/dx sin(x) = cos(x)
let g = Graph::new();
let x = g.var(1.0);
let z = x.sin();
let grad = z.accumulate();
assert_approx_equal!(z.value, 0.84147098480, 1e-10);
assert_approx_equal!(grad.wrt(&x), 0.54030230586, 1e-10);
Sourcepub fn sinh(self) -> Variable<'v>
pub fn sinh(self) -> Variable<'v>
Hyperbolic sine function. d/dx sinh(x) = cosh(x)
let g = Graph::new();
let x = g.var(1.0);
let z = x.sinh();
let grad = z.accumulate();
assert_approx_equal!(z.value, 1.17520119364, 1e-10);
assert_approx_equal!(grad.wrt(&x), 1.54308063481, 1e-10);
Sourcepub fn sqrt(self) -> Variable<'v>
pub fn sqrt(self) -> Variable<'v>
Square root function. d/dx sqrt(x) = 1 / 2*sqrt(x)
let g = Graph::new();
let x = g.var(2.0);
let z = x.sqrt();
let grad = z.accumulate();
assert_eq!(z.value, std::f64::consts::SQRT_2);
assert_eq!(grad.wrt(&x), 1.0 / (2.0 * std::f64::consts::SQRT_2));
Sourcepub fn tan(self) -> Variable<'v>
pub fn tan(self) -> Variable<'v>
Tangent function. d/dx tan(x) = 1 / cos^2(x) = sec^2(x)
let g = Graph::new();
let x = g.var(1.0);
let z = x.tan();
let grad = z.accumulate();
assert_approx_equal!(z.value, 1.55740772465, 1e-10);
assert_approx_equal!(grad.wrt(&x), 3.42551882081, 1e-10);
Sourcepub fn tanh(self) -> Variable<'v>
pub fn tanh(self) -> Variable<'v>
Hyperbolic tangent function. d/dx tanh(x) = sech^2(x) = 1 / cosh^2(x)
let g = Graph::new();
let x = g.var(1.0);
let z = x.tanh();
let grad = z.accumulate();
assert_approx_equal!(z.value, 0.7615941559, 1e-10);
assert_approx_equal!(grad.wrt(&x), 0.4199743416, 1e-10);
Source§impl<'v> Variable<'v>
impl<'v> Variable<'v>
Sourcepub fn erf(self) -> Variable<'v>
pub fn erf(self) -> Variable<'v>
Error function. d/dx erf(x) = 2e^(-x^2) / sqrt(PI)
let g = Graph::new();
let x = g.var(1.0);
let z = x.erf();
let grad = z.accumulate();
assert_approx_equal!(z.value, 0.84270079294, 1e-10);
assert_approx_equal!(grad.wrt(&x), 0.41510749742, 1e-10);
Sourcepub fn erfc(self) -> Variable<'v>
pub fn erfc(self) -> Variable<'v>
Error function (complementary). d/dx erfc(x) = -2e^(-x^2) / sqrt(PI)
let g = Graph::new();
let x = g.var(1.0);
let z = x.erfc();
let grad = z.accumulate();
assert_approx_equal!(z.value, 0.15729920705, 1e-10);
assert_approx_equal!(grad.wrt(&x), -0.41510749742, 1e-10);
Source§impl<'v> Variable<'v>
impl<'v> Variable<'v>
Sourcepub const fn new(graph: &'v Graph, index: usize, value: f64) -> Variable<'v>
pub const fn new(graph: &'v Graph, index: usize, value: f64) -> Variable<'v>
Instantiate a new variable.
Sourcepub fn is_infinite(&self) -> bool
pub fn is_infinite(&self) -> bool
Check if variable is infinite.
Sourcepub fn is_subnormal(&self) -> bool
pub fn is_subnormal(&self) -> bool
Check if variable is subnormal.
Sourcepub fn is_positive(&self) -> bool
pub fn is_positive(&self) -> bool
Check if variable is positive.
Sourcepub fn is_negative(&self) -> bool
pub fn is_negative(&self) -> bool
Check if variable is negative.
Trait Implementations§
Source§impl Accumulate<Vec<f64>> for Variable<'_>
impl Accumulate<Vec<f64>> for Variable<'_>
Source§fn accumulate(&self) -> Vec<f64>
fn accumulate(&self) -> Vec<f64>
Function to reverse accumulate the gradient for a Variable
.
- Allocate the array of adjoints.
- Set the seed (dx/dx = 1).
- Traverse the graph backwards, updating the adjoints for the parent vertices.
Source§impl ActivationFunction for Variable<'_>
impl ActivationFunction for Variable<'_>
Source§impl<'v> Add<f64> for Variable<'v>
Variable<’v> + f64
impl<'v> Add<f64> for Variable<'v>
Variable<’v> + f64
Source§impl<'v> Add for Variable<'v>
Variable<’v> + Variable<’v>
impl<'v> Add for Variable<'v>
Variable<’v> + Variable<’v>
Source§impl<'v> AddAssign<f64> for Variable<'v>
AddAssign: Variable<’v> += f64
impl<'v> AddAssign<f64> for Variable<'v>
AddAssign: Variable<’v> += f64
Source§fn add_assign(&mut self, other: f64)
fn add_assign(&mut self, other: f64)
+=
operation. Read moreSource§impl<'v> AddAssign for Variable<'v>
Overload the standard addition operator (+
).
d/dx x + y = 1
d/dy x + y = 1
AddAssign: Variable<’v> += Variable<’v>
impl<'v> AddAssign for Variable<'v>
Overload the standard addition operator (+
).
d/dx x + y = 1
d/dy x + y = 1
AddAssign: Variable<’v> += Variable<’v>
Source§fn add_assign(&mut self, other: Variable<'v>)
fn add_assign(&mut self, other: Variable<'v>)
+=
operation. Read moreSource§impl<'v> Div<f64> for Variable<'v>
Variable<’v> / f64
impl<'v> Div<f64> for Variable<'v>
Variable<’v> / f64
Source§impl<'v> Div for Variable<'v>
Variable<’v> / Variable<’v>
impl<'v> Div for Variable<'v>
Variable<’v> / Variable<’v>
Source§impl<'v> DivAssign<f64> for Variable<'v>
DivAssign
: Variable<’v> /= f64
impl<'v> DivAssign<f64> for Variable<'v>
DivAssign
: Variable<’v> /= f64
Source§fn div_assign(&mut self, other: f64)
fn div_assign(&mut self, other: f64)
/=
operation. Read moreSource§impl<'v> DivAssign for Variable<'v>
Overload the standard division operator (/
).
d/dx x/y = 1/y
d/dy x/y = -x/y^2
DivAssign
: Variable<’v> /= Variable<’v>
impl<'v> DivAssign for Variable<'v>
Overload the standard division operator (/
).
d/dx x/y = 1/y
d/dy x/y = -x/y^2
DivAssign
: Variable<’v> /= Variable<’v>
Source§fn div_assign(&mut self, other: Variable<'v>)
fn div_assign(&mut self, other: Variable<'v>)
/=
operation. Read moreSource§impl<'v> Mul<f64> for Variable<'v>
Variable<’v> * f64
impl<'v> Mul<f64> for Variable<'v>
Variable<’v> * f64
Source§impl<'v> Mul for Variable<'v>
Variable<’v> * Variable<’v>
impl<'v> Mul for Variable<'v>
Variable<’v> * Variable<’v>
Source§impl<'v> MulAssign<f64> for Variable<'v>
MulAssign: Variable<’v> *= f64
impl<'v> MulAssign<f64> for Variable<'v>
MulAssign: Variable<’v> *= f64
Source§fn mul_assign(&mut self, other: f64)
fn mul_assign(&mut self, other: f64)
*=
operation. Read moreSource§impl<'v> MulAssign for Variable<'v>
Overload the standard multiplication operator (*
).
d/dx x * y = y
d/dy x * y = x
MulAssign: Variable<’v> *= Variable<’v>
impl<'v> MulAssign for Variable<'v>
Overload the standard multiplication operator (*
).
d/dx x * y = y
d/dy x * y = x
MulAssign: Variable<’v> *= Variable<’v>
Source§fn mul_assign(&mut self, other: Variable<'v>)
fn mul_assign(&mut self, other: Variable<'v>)
*=
operation. Read moreSource§impl<'v> Ord for Variable<'v>
impl<'v> Ord for Variable<'v>
1.21.0 · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl<'v> PartialOrd for Variable<'v>
impl<'v> PartialOrd for Variable<'v>
Source§impl<'v> Product for Variable<'v>
impl<'v> Product for Variable<'v>
Source§fn product<I>(iter: I) -> Variable<'v>
fn product<I>(iter: I) -> Variable<'v>
let g = Graph::new();
let params = (1..=5).map(|x| g.var(x as f64)).collect::<Vec<_>>();
let prod = params.iter().copied().product::<Variable>();
let derivs = prod.accumulate();
let true_gradient = vec![120.0, 60.0, 40.0, 30.0, 24.0];
let n = derivs.wrt(¶ms).len();
let m = true_gradient.len();
assert_eq!(n, m);
for i in 0..n {
assert_eq!(derivs.wrt(¶ms)[i], true_gradient[i]);
}
Source§impl<'v> Sub<f64> for Variable<'v>
Variable<’v> - f64
impl<'v> Sub<f64> for Variable<'v>
Variable<’v> - f64
Source§impl<'v> Sub for Variable<'v>
Variable<’v> - Variable<’v>
impl<'v> Sub for Variable<'v>
Variable<’v> - Variable<’v>
Source§impl<'v> SubAssign<f64> for Variable<'v>
SubAssign
: Variable<’v> -= f64
impl<'v> SubAssign<f64> for Variable<'v>
SubAssign
: Variable<’v> -= f64
Source§fn sub_assign(&mut self, other: f64)
fn sub_assign(&mut self, other: f64)
-=
operation. Read moreSource§impl<'v> SubAssign for Variable<'v>
Overload the standard subtraction operator (-
).
d/dx x - y = 1
d/dy x - y = -1
SubAssign
: Variable<’v> -= Variable<’v>
impl<'v> SubAssign for Variable<'v>
Overload the standard subtraction operator (-
).
d/dx x - y = 1
d/dy x - y = -1
SubAssign
: Variable<’v> -= Variable<’v>
Source§fn sub_assign(&mut self, other: Variable<'v>)
fn sub_assign(&mut self, other: Variable<'v>)
-=
operation. Read moreSource§impl<'v> Sum for Variable<'v>
impl<'v> Sum for Variable<'v>
impl<'v> Copy for Variable<'v>
impl<'v> Eq for Variable<'v>
Auto Trait Implementations§
impl<'v> Freeze for Variable<'v>
impl<'v> !RefUnwindSafe for Variable<'v>
impl<'v> !Send for Variable<'v>
impl<'v> !Sync for Variable<'v>
impl<'v> Unpin for Variable<'v>
impl<'v> !UnwindSafe for Variable<'v>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Comparable<K> for Q
impl<Q, K> Comparable<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self
from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self
is actually part of its subset T
(and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset
but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self
to the equivalent element of its superset.Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self
from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self
is actually part of its subset T
(and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset
but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self
to the equivalent element of its superset.Source§impl<T> ToCompactString for Twhere
T: Display,
impl<T> ToCompactString for Twhere
T: Display,
Source§fn try_to_compact_string(&self) -> Result<CompactString, ToCompactStringError>
fn try_to_compact_string(&self) -> Result<CompactString, ToCompactStringError>
ToCompactString::to_compact_string()
Read moreSource§fn to_compact_string(&self) -> CompactString
fn to_compact_string(&self) -> CompactString
CompactString
. Read more