oxilean_std/convex_analysis/types.rs
1//! Types for convex analysis.
2
3/// Description of a convex set.
4#[derive(Debug, Clone)]
5pub enum SetDescription {
6 /// Half-space { x : <normal, x> <= offset }.
7 HalfSpace { normal: Vec<f64>, offset: f64 },
8 /// Polytope defined by linear inequalities Ax <= b.
9 /// Each entry is (row of A, corresponding b_i).
10 Polytope { inequalities: Vec<(Vec<f64>, f64)> },
11 /// Euclidean ball { x : ||x - center|| <= radius }.
12 Ball { center: Vec<f64>, radius: f64 },
13 /// Convex hull of given vertices.
14 Simplex { vertices: Vec<Vec<f64>> },
15 /// Intersection of a list of sets.
16 Intersection(Vec<Box<SetDescription>>),
17}
18
19/// A convex set in R^d.
20#[derive(Debug, Clone)]
21pub struct ConvexSet {
22 /// Ambient dimension.
23 pub dimension: usize,
24 /// Geometric description.
25 pub description: SetDescription,
26}
27
28impl ConvexSet {
29 /// Construct a new convex set.
30 pub fn new(dimension: usize, description: SetDescription) -> Self {
31 Self {
32 dimension,
33 description,
34 }
35 }
36}
37
38/// The kind / parametrisation of a convex function f : R^n -> R.
39#[derive(Debug, Clone)]
40pub enum FunctionKind {
41 /// Quadratic: f(x) = (1/2) x^T Q x + b^T x + c.
42 Quadratic {
43 q: Vec<Vec<f64>>,
44 b: Vec<f64>,
45 c: f64,
46 },
47 /// Linear: f(x) = a^T x + b.
48 Linear { a: Vec<f64>, b: f64 },
49 /// p-norm: f(x) = ||x||_p.
50 Norm { p: f64 },
51 /// Indicator of the domain convex set (0 inside, +inf outside).
52 Indicator,
53 /// Max-affine function: f(x) = max_i (a_i^T x + b_i).
54 MaxAffine { pieces: Vec<(Vec<f64>, f64)> },
55}
56
57/// A convex function with an explicit domain.
58#[derive(Debug, Clone)]
59pub struct ConvexFunction {
60 /// Domain over which the function is defined (and finite).
61 pub domain: ConvexSet,
62 /// Functional form.
63 pub kind: FunctionKind,
64}
65
66impl ConvexFunction {
67 /// Construct a new convex function.
68 pub fn new(domain: ConvexSet, kind: FunctionKind) -> Self {
69 Self { domain, kind }
70 }
71}
72
73/// Result of a subgradient computation.
74#[derive(Debug, Clone)]
75pub struct SubgradientResult {
76 /// Point at which the subgradient was computed.
77 pub point: Vec<f64>,
78 /// A subgradient g such that f(y) >= f(x) + <g, y-x> for all y.
79 pub subgradient: Vec<f64>,
80 /// Function value f(x).
81 pub value: f64,
82}
83
84/// Result of a projection onto a convex set.
85#[derive(Debug, Clone)]
86pub struct ProjectionResult {
87 /// The projected point.
88 pub projected: Vec<f64>,
89 /// Euclidean distance from the original point to the projection.
90 pub distance: f64,
91}
92
93/// A separating hyperplane { x : <normal, x> = offset }.
94#[derive(Debug, Clone)]
95pub struct SeparatingHyperplane {
96 /// Outward normal (unit or unnormalised).
97 pub normal: Vec<f64>,
98 /// Scalar offset so that the hyperplane is { x : <normal,x> = offset }.
99 pub offset: f64,
100}
101
102/// Fenchel conjugate f*(y) = sup_x { <y, x> - f(x) }.
103#[derive(Debug, Clone)]
104pub struct ConjugateFunction {
105 /// The original function kind (kept for reference).
106 pub original_kind: FunctionKind,
107}
108
109/// Proximal operator prox_{t f}(v) = argmin_x { f(x) + (1/2t)||x - v||^2 }.
110#[derive(Debug, Clone)]
111pub struct ProximalOperator {
112 /// The function whose proximal map is represented.
113 pub function: ConvexFunction,
114 /// Step size t > 0.
115 pub step_size: f64,
116}
117
118impl ProximalOperator {
119 /// Construct a new proximal operator.
120 pub fn new(function: ConvexFunction, step_size: f64) -> Self {
121 Self {
122 function,
123 step_size,
124 }
125 }
126}
127
128/// Result of a convex optimisation run.
129#[derive(Debug, Clone)]
130pub struct OptimizationResult {
131 /// Best iterate found.
132 pub optimal_point: Vec<f64>,
133 /// Objective value at the best iterate.
134 pub optimal_value: f64,
135 /// Number of iterations performed.
136 pub iterations: usize,
137 /// Whether the algorithm declared convergence.
138 pub converged: bool,
139}