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
//! Canonical problem-side constraint sets and checked evaluation capabilities.
//!
//! [`Constraints`] optionally declares the complete constraint set. Constrained
//! solvers accept only block combinations they support. Unconstrained solvers
//! ignore the declaration. Bounds, linear equalities and
//! inequalities, and nonlinear equalities and inequalities remain distinct.
//!
//! An unconstrained solver can optimize an objective without enforcing its box:
//!
//! ```
//! use basin::{BoxBounds, Constrained, ConstraintSet, CostFunction, Executor,
//! NelderMead};
//! struct Sphere;
//! impl CostFunction for Sphere {
//! type Param = Vec<f64>;
//! type Output = f64;
//! type Error = std::convert::Infallible;
//! fn cost(&self, x: &Vec<f64>) -> Result<f64, Self::Error> {
//! Ok(x.iter().map(|v| (v - 2.0).powi(2)).sum())
//! }
//! }
//! let constraints = ConstraintSet::new()
//! .with_bounds(BoxBounds::new(Some(vec![-1.0]), Some(vec![1.0])));
//! let problem = Constrained::new(Sphere, constraints);
//! let result = Executor::from_start(problem, NelderMead::new(), vec![0.5])
//! .max_iter(1000).run().unwrap();
//! assert!(result.param()[0] > 1.0);
//! ```
//!
//! A box-only solver also rejects an additional nonlinear block, even when
//! the problem supplies the required value callback:
//!
//! ```compile_fail
//! use basin::{BoxBounds, Constrained, ConstraintSolveError, ConstraintSet,
//! CostFunction, Executor, NelderMead,
//! NonlinearInequalityValues};
//! struct Sphere;
//! impl CostFunction for Sphere {
//! type Param = Vec<f64>;
//! type Output = f64;
//! type Error = std::convert::Infallible;
//! fn cost(&self, x: &Vec<f64>) -> Result<f64, Self::Error> {
//! Ok(x.iter().map(|v| v * v).sum())
//! }
//! }
//! impl NonlinearInequalityValues for Sphere {
//! type Param = Vec<f64>;
//! type Values = Vec<f64>;
//! type Error = std::convert::Infallible;
//! fn nonlinear_inequalities(&self, x: &Vec<f64>)
//! -> Result<Vec<f64>, ConstraintSolveError<Self::Error>> {
//! Ok(vec![x[0] - 0.25])
//! }
//! }
//! let constraints = ConstraintSet::new()
//! .with_bounds(BoxBounds::new(Some(vec![-1.0]), Some(vec![1.0])))
//! .with_nonlinear_inequalities(1);
//! let problem = Constrained::new(Sphere, constraints);
//! Executor::from_start(problem, NelderMead::new().projected(), vec![0.5]).run();
//! ```
pub
pub use *;
pub
pub use *;
/// Analytic Jacobian of the declared nonlinear blocks.
///
/// Rows contain nonlinear equalities first, followed by nonlinear inequalities
/// in callback order. Columns correspond to parameters. Linear blocks supply
/// their own derivatives and are excluded. This storage is independent of the
/// linear matrices. Finite-difference adapters synthesize this capability.