conspire/math/optimize/
mod.rs1#[cfg(test)]
2mod test;
3
4mod constraint;
5mod gradient_descent;
6mod line_search;
7mod newton_raphson;
8
9pub use constraint::EqualityConstraint;
10pub use gradient_descent::GradientDescent;
11pub use line_search::LineSearch;
12pub use newton_raphson::NewtonRaphson;
13
14use crate::{
15 defeat_message,
16 math::{
17 TestError,
18 integrate::IntegrationError,
19 matrix::square::{Banded, SquareMatrixError},
20 },
21};
22use std::fmt::{self, Debug, Display, Formatter};
23
24pub trait ZerothOrderRootFinding<X> {
26 fn root(
27 &self,
28 function: impl Fn(&X) -> Result<X, OptimizeError>,
29 initial_guess: X,
30 equality_constraint: EqualityConstraint,
31 ) -> Result<X, OptimizeError>;
32}
33
34pub trait FirstOrderRootFinding<F, J, X> {
36 fn root(
37 &self,
38 function: impl Fn(&X) -> Result<F, OptimizeError>,
39 jacobian: impl Fn(&X) -> Result<J, OptimizeError>,
40 initial_guess: X,
41 equality_constraint: EqualityConstraint,
42 ) -> Result<X, OptimizeError>;
43}
44
45pub trait FirstOrderOptimization<F, X> {
47 fn minimize(
48 &self,
49 function: impl Fn(&X) -> Result<F, OptimizeError>,
50 jacobian: impl Fn(&X) -> Result<X, OptimizeError>,
51 initial_guess: X,
52 equality_constraint: EqualityConstraint,
53 ) -> Result<X, OptimizeError>;
54}
55
56pub trait SecondOrderOptimization<F, J, H, X> {
58 fn minimize(
59 &self,
60 function: impl Fn(&X) -> Result<F, OptimizeError>,
61 jacobian: impl Fn(&X) -> Result<J, OptimizeError>,
62 hessian: impl Fn(&X) -> Result<H, OptimizeError>,
63 initial_guess: X,
64 equality_constraint: EqualityConstraint,
65 banded: Option<Banded>,
66 ) -> Result<X, OptimizeError>;
67}
68
69pub enum OptimizeError {
71 Generic(String),
72 MaximumStepsReached(usize, String),
73 NotMinimum(String, String),
74 SingularMatrix,
75}
76
77impl From<OptimizeError> for TestError {
78 fn from(error: OptimizeError) -> Self {
79 Self {
80 message: error.to_string(),
81 }
82 }
83}
84
85impl From<IntegrationError> for OptimizeError {
86 fn from(_error: IntegrationError) -> Self {
87 todo!()
88 }
89}
90
91impl From<SquareMatrixError> for OptimizeError {
92 fn from(_error: SquareMatrixError) -> Self {
93 Self::SingularMatrix
94 }
95}
96
97impl Debug for OptimizeError {
98 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
99 let error = match self {
100 Self::Generic(message) => message.to_string(),
101 Self::MaximumStepsReached(steps, solver) => {
102 format!(
103 "\x1b[1;91mMaximum number of steps ({steps}) reached.\x1b[0;91m\n\
104 In solver: {solver}."
105 )
106 }
107 Self::NotMinimum(solution, solver) => {
108 format!(
109 "\x1b[1;91mThe obtained solution is not a minimum.\x1b[0;91m\n\
110 For solution: {solution}.\n\
111 In solver: {solver}."
112 )
113 }
114 Self::SingularMatrix => "\x1b[1;91mMatrix is singular.".to_string(),
115 };
116 write!(f, "\n{error}\n\x1b[0;2;31m{}\x1b[0m\n", defeat_message())
117 }
118}
119
120impl Display for OptimizeError {
121 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
122 let error = match self {
123 Self::Generic(message) => message.to_string(),
124 Self::MaximumStepsReached(steps, solver) => {
125 format!(
126 "\x1b[1;91mMaximum number of steps ({steps}) reached.\x1b[0;91m\n\
127 In solver: {solver}."
128 )
129 }
130 Self::NotMinimum(solution, solver) => {
131 format!(
132 "\x1b[1;91mThe obtained solution is not a minimum.\x1b[0;91m\n\
133 For solution: {solution}.\n\
134 In solver: {solver}."
135 )
136 }
137 Self::SingularMatrix => "\x1b[1;91mMatrix is singular.".to_string(),
138 };
139 write!(f, "{error}\x1b[0m")
140 }
141}