argmin/solver/conjugategradient/
beta.rs1use crate::prelude::*;
18use serde::{Deserialize, Serialize};
19
20#[derive(
23 Default, Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug,
24)]
25pub struct FletcherReeves {}
26
27impl FletcherReeves {
28 pub fn new() -> Self {
30 FletcherReeves {}
31 }
32}
33
34impl<T, F> ArgminNLCGBetaUpdate<T, F> for FletcherReeves
35where
36 T: Clone + ArgminDot<T, F>,
37 F: ArgminFloat,
38{
39 fn update(&self, dfk: &T, dfk1: &T, _pk: &T) -> F {
40 dfk1.dot(&dfk1) / dfk.dot(&dfk)
41 }
42}
43
44#[derive(
47 Default, Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug,
48)]
49pub struct PolakRibiere {}
50
51impl PolakRibiere {
52 pub fn new() -> Self {
54 PolakRibiere {}
55 }
56}
57
58impl<T, F> ArgminNLCGBetaUpdate<T, F> for PolakRibiere
59where
60 T: Clone + ArgminDot<T, F> + ArgminSub<T, T> + ArgminNorm<F>,
61 F: ArgminFloat,
62{
63 fn update(&self, dfk: &T, dfk1: &T, _pk: &T) -> F {
64 let dfk_norm_sq = dfk.norm().powi(2);
65 dfk1.dot(&dfk1.sub(&dfk)) / dfk_norm_sq
66 }
67}
68
69#[derive(
72 Default, Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug,
73)]
74pub struct PolakRibierePlus {}
75
76impl PolakRibierePlus {
77 pub fn new() -> Self {
79 PolakRibierePlus {}
80 }
81}
82
83impl<T, F> ArgminNLCGBetaUpdate<T, F> for PolakRibierePlus
84where
85 T: Clone + ArgminDot<T, F> + ArgminSub<T, T> + ArgminNorm<F>,
86 F: ArgminFloat,
87{
88 fn update(&self, dfk: &T, dfk1: &T, _pk: &T) -> F {
89 let dfk_norm_sq = dfk.norm().powi(2);
90 let beta = dfk1.dot(&dfk1.sub(&dfk)) / dfk_norm_sq;
91 F::from_f64(0.0).unwrap().max(beta)
92 }
93}
94
95#[derive(
98 Default, Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug,
99)]
100pub struct HestenesStiefel {}
101
102impl HestenesStiefel {
103 pub fn new() -> Self {
105 HestenesStiefel {}
106 }
107}
108
109impl<T, F> ArgminNLCGBetaUpdate<T, F> for HestenesStiefel
110where
111 T: Clone + ArgminDot<T, F> + ArgminSub<T, T> + ArgminNorm<F>,
112 F: ArgminFloat,
113{
114 fn update(&self, dfk: &T, dfk1: &T, pk: &T) -> F {
115 let d = dfk1.sub(&dfk);
116 dfk1.dot(&d) / d.dot(&pk)
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123 use crate::test_trait_impl;
124
125 test_trait_impl!(fletcher_reeves, FletcherReeves);
126 test_trait_impl!(polak_ribiere, PolakRibiere);
127 test_trait_impl!(polak_ribiere_plus, PolakRibierePlus);
128 test_trait_impl!(hestenes_stiefel, HestenesStiefel);
129}