1use thiserror::Error;
2
3#[derive(Debug, Error)]
5pub enum BlpError {
6 #[error("dimension mismatch in {context}: expected {expected} but found {found}")]
8 DimensionMismatch {
9 context: &'static str,
11 expected: usize,
13 found: usize,
15 },
16
17 #[error("market identifiers must appear in contiguous blocks; market `{market_id}` is split")]
19 NonContiguousMarket { market_id: String },
20
21 #[error("product share at index {index} must be positive, found {share}")]
23 NonPositiveShare { index: usize, share: f64 },
24
25 #[error("outside share for market `{market_id}` must be positive, found {share}")]
27 NonPositiveOutsideShare { market_id: String, share: f64 },
28
29 #[error("weights must be strictly positive and sum to one (slack {slack})")]
31 InvalidWeights { slack: f64 },
32
33 #[error("matrix in {context} is singular")]
35 SingularMatrix { context: &'static str },
36
37 #[error(
39 "BLP contraction did not converge after {iterations} iterations; best max gap {max_gap}"
40 )]
41 ContractionDidNotConverge {
42 iterations: usize,
44 max_gap: f64,
46 },
47
48 #[error("encountered NaN during {context}")]
50 NumericalError { context: &'static str },
51
52 #[error("{component} must be provided before solving the problem")]
54 MissingComponent { component: &'static str },
55}
56
57impl BlpError {
58 pub fn dimension_mismatch(context: &'static str, expected: usize, found: usize) -> Self {
60 Self::DimensionMismatch {
61 context,
62 expected,
63 found,
64 }
65 }
66
67 pub fn singular(context: &'static str) -> Self {
69 Self::SingularMatrix { context }
70 }
71
72 pub fn missing_component(component: &'static str) -> Self {
74 Self::MissingComponent { component }
75 }
76}
77
78pub type Result<T> = std::result::Result<T, BlpError>;