src/tolerance.rs

branch
dev
changeset 61
4f468d35fa29
parent 0
eb3c7813b67a
equal deleted inserted replaced
60:9738b51d90d7 61:4f468d35fa29
1 //! Tolerance update schemes for subproblem solution quality 1 //! Tolerance update schemes for subproblem solution quality
2 use serde::{Serialize, Deserialize}; 2 use crate::types::*;
3 use numeric_literals::replace_float_literals; 3 use numeric_literals::replace_float_literals;
4 use crate::types::*; 4 use serde::{Deserialize, Serialize};
5 5
6 /// Update style for optimality system solution tolerance 6 /// Update style for optimality system solution tolerance
7 #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)] 7 #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)]
8 #[allow(dead_code)] 8 #[allow(dead_code)]
9 pub enum Tolerance<F : Float> { 9 pub enum Tolerance<F: Float> {
10 /// $ε_k = εθ^k$ for the `factor` $θ$ and initial tolerance $ε$. 10 /// $ε_k = εθ^k$ for the `factor` $θ$ and initial tolerance $ε$.
11 Exponential{ factor : F, initial : F }, 11 Exponential { factor: F, initial: F },
12 /// $ε_k = ε/(1+θk)^p$ for the `factor` $θ$, `exponent` $p$, and initial tolerance $ε$. 12 /// $ε_k = ε/(1+θk)^p$ for the `factor` $θ$, `exponent` $p$, and initial tolerance $ε$.
13 Power{ factor : F, exponent : F, initial : F}, 13 Power { factor: F, exponent: F, initial: F },
14 /// $ε_k = εθ^{⌊k^p⌋}$ for the `factor` $θ$, initial tolerance $ε$, and exponent $p$. 14 /// $ε_k = εθ^{⌊k^p⌋}$ for the `factor` $θ$, initial tolerance $ε$, and exponent $p$.
15 SlowExp{ factor : F, exponent : F, initial : F } 15 SlowExp { factor: F, exponent: F, initial: F },
16 } 16 }
17 17
18 #[replace_float_literals(F::cast_from(literal))] 18 #[replace_float_literals(F::cast_from(literal))]
19 impl<F : Float> Default for Tolerance<F> { 19 impl<F: Float> Default for Tolerance<F> {
20 fn default() -> Self { 20 fn default() -> Self {
21 Tolerance::Power { 21 Tolerance::Power {
22 initial : 0.5, 22 initial: 0.5,
23 factor : 0.2, 23 factor: 0.2,
24 exponent : 1.4 // 1.5 works but is already slower in practise on our examples. 24 exponent: 1.4, // 1.5 works but is already slower in practise on our examples.
25 } 25 }
26 } 26 }
27 } 27 }
28 28
29 #[replace_float_literals(F::cast_from(literal))] 29 #[replace_float_literals(F::cast_from(literal))]
30 impl<F : Float> Tolerance<F> { 30 impl<F: Float> Tolerance<F> {
31 /// Get the initial tolerance 31 /// Get the initial tolerance
32 pub fn initial(&self) -> F { 32 pub fn initial(&self) -> F {
33 match self { 33 match self {
34 &Tolerance::Exponential { initial, .. } => initial, 34 &Tolerance::Exponential { initial, .. } => initial,
35 &Tolerance::Power { initial, .. } => initial, 35 &Tolerance::Power { initial, .. } => initial,
45 Tolerance::SlowExp { ref mut initial, .. } => initial, 45 Tolerance::SlowExp { ref mut initial, .. } => initial,
46 } 46 }
47 } 47 }
48 48
49 /// Set the initial tolerance 49 /// Set the initial tolerance
50 pub fn set_initial(&mut self, set : F) { 50 pub fn set_initial(&mut self, set: F) {
51 *self.initial_mut() = set; 51 *self.initial_mut() = set;
52 } 52 }
53 53
54 /// Update `tolerance` for iteration `iter`. 54 /// Update `tolerance` for iteration `iter`.
55 /// `tolerance` may or may not be used depending on the specific 55 /// `tolerance` may or may not be used depending on the specific
56 /// update scheme. 56 /// update scheme.
57 pub fn update(&self, tolerance : F, iter : usize) -> F { 57 pub fn update(&self, tolerance: F, iter: usize) -> F {
58 match self { 58 match self {
59 &Tolerance::Exponential { factor, .. } => { 59 &Tolerance::Exponential { factor, .. } => tolerance * factor,
60 tolerance * factor
61 },
62 &Tolerance::Power { factor, exponent, initial } => { 60 &Tolerance::Power { factor, exponent, initial } => {
63 initial /(1.0 + factor * F::cast_from(iter)).powf(exponent) 61 initial / (1.0 + factor * F::cast_from(iter)).powf(exponent)
64 }, 62 }
65 &Tolerance::SlowExp { factor, exponent, initial } => { 63 &Tolerance::SlowExp { factor, exponent, initial } => {
66 // let m = (speed 64 // let m = (speed
67 // * factor.powi(-(iter as i32)) 65 // * factor.powi(-(iter as i32))
68 // * F::cast_from(iter).powf(-exponent) 66 // * F::cast_from(iter).powf(-exponent)
69 // ).floor().as_(); 67 // ).floor().as_();
70 let m = F::cast_from(iter).powf(exponent).floor().as_(); 68 let m = F::cast_from(iter).powf(exponent).floor().as_();
71 initial * factor.powi(m) 69 initial * factor.powi(m)
72 }, 70 }
73 } 71 }
74 } 72 }
75 } 73 }
76 74
77 impl<F: Float> std::ops::MulAssign<F> for Tolerance<F> { 75 impl<F: Float> std::ops::MulAssign<F> for Tolerance<F> {
78 fn mul_assign(&mut self, factor : F) { 76 fn mul_assign(&mut self, factor: F) {
79 *self.initial_mut() *= factor; 77 *self.initial_mut() *= factor;
80 } 78 }
81 } 79 }
82 80
83 impl<F: Float> std::ops::Mul<F> for Tolerance<F> { 81 impl<F: Float> std::ops::Mul<F> for Tolerance<F> {
84 type Output = Tolerance<F>; 82 type Output = Tolerance<F>;
85 fn mul(mut self, factor : F) -> Self::Output { 83 fn mul(mut self, factor: F) -> Self::Output {
86 *self.initial_mut() *= factor; 84 *self.initial_mut() *= factor;
87 self 85 self
88 } 86 }
89 } 87 }

mercurial