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
//! Wire representations for serde (roadmap 3.3).
//!
//! Ledge serialization exists for **bug reproduction**: dump a problem (and
//! optionally settings, warm start, and the returned solution) on one
//! machine, attach it to an issue, replay it on another. Every type keeps
//! plain derived serde impls except where an invariant or a format
//! limitation forces a custom wire shape:
//!
//! - [`Matrix`](crate::Matrix) travels as `{ rows, cols, data }` and is
//! rebuilt through `Matrix::new`, so a corrupted dump cannot construct a
//! matrix whose shape disagrees with its storage.
//! - [`PortfolioProblem`](crate::PortfolioProblem) travels as its builder
//! inputs and is rebuilt through the same builder methods, so
//! deserialization enforces exactly the validation construction does.
//! - Variable bounds may legally be infinite, but JSON has no
//! representation for non-finite floats (`serde_json` writes `null` and
//! refuses to read it back). Bound vectors therefore travel as
//! `Option<f64>` per entry, where `None` means "unbounded on this side"
//! (`-inf` in a lower bound, `+inf` in an upper bound) — see
//! [`lower_bounds`] / [`upper_bounds`]. The pathological wrong-sign
//! infinity (a lower bound of `+inf`) also maps to `None`; such problems
//! are rejected by validation anyway.
//!
//! Solutions from a [`NumericalFailure`](crate::SolveStatus) contain
//! non-finite iterates by definition; those round-trip through
//! self-describing binary formats (for example `postcard`) but not through
//! JSON. Problems and settings never contain non-finite data outside the
//! bounds handled above.
/// (De)serializes a bound vector as `Option<f64>` entries where `None`
/// stands for the direction's natural infinity.
bound_representation!;
bound_representation!;