diff --git a/docs/src/reference/quadratic_approximations.md b/docs/src/reference/quadratic_approximations.md index c9e70ae..082e1e3 100644 --- a/docs/src/reference/quadratic_approximations.md +++ b/docs/src/reference/quadratic_approximations.md @@ -54,11 +54,11 @@ decreases as ``O(1/S^2)``. ### Variables and Constraints -| Container Type | Description | -|:---|:---| -| [`QuadraticApproxVariable`](@ref) | Lambda (``\lambda``) convex combination weights | -| [`QuadraticApproxLinkingConstraint`](@ref) | Links ``x`` to weighted breakpoints | -| [`QuadraticApproxNormalizationConstraint`](@ref) | Ensures ``\sum \lambda_i = 1`` | +| Container Type | Description | +|:------------------------------------------------ |:----------------------------------------------- | +| [`QuadraticApproxVariable`](@ref) | Lambda (``\lambda``) convex combination weights | +| [`QuadraticApproxLinkingConstraint`](@ref) | Links ``x`` to weighted breakpoints | +| [`QuadraticApproxNormalizationConstraint`](@ref) | Ensures ``\sum \lambda_i = 1`` | ## Manual SOS2 @@ -88,13 +88,13 @@ linear constraints per component per time step. Same approximation quality as So ### Variables and Constraints -| Container Type | Description | -|:---|:---| -| [`QuadraticApproxVariable`](@ref) | Lambda (``\lambda``) convex combination weights | -| [`ManualSOS2BinaryVariable`](@ref) | Binary segment-selection variables (``z``) | -| [`QuadraticApproxLinkingConstraint`](@ref) | Links ``x`` to weighted breakpoints | -| [`QuadraticApproxNormalizationConstraint`](@ref) | Ensures ``\sum \lambda_i = 1`` | -| [`ManualSOS2SegmentSelectionConstraint`](@ref) | Ensures ``\sum z_j = 1`` | +| Container Type | Description | +|:------------------------------------------------ |:----------------------------------------------- | +| [`QuadraticApproxVariable`](@ref) | Lambda (``\lambda``) convex combination weights | +| [`ManualSOS2BinaryVariable`](@ref) | Binary segment-selection variables (``z``) | +| [`QuadraticApproxLinkingConstraint`](@ref) | Links ``x`` to weighted breakpoints | +| [`QuadraticApproxNormalizationConstraint`](@ref) | Ensures ``\sum \lambda_i = 1`` | +| [`ManualSOS2SegmentSelectionConstraint`](@ref) | Ensures ``\sum z_j = 1`` | ## Sawtooth @@ -143,21 +143,21 @@ constraints per component per time step. The approximation interpolates ``x^2`` ### Variables and Constraints -| Container Type | Description | -|:---|:---| -| [`SawtoothAuxVariable`](@ref) | Auxiliary continuous variables (``g_0, \ldots, g_L``) | -| [`SawtoothBinaryVariable`](@ref) | Binary variables (``\alpha_1, \ldots, \alpha_L``) | -| [`SawtoothLinkingConstraint`](@ref) | Links ``g_0`` to normalized ``x`` | +| Container Type | Description | +|:----------------------------------- |:----------------------------------------------------- | +| [`SawtoothAuxVariable`](@ref) | Auxiliary continuous variables (``g_0, \ldots, g_L``) | +| [`SawtoothBinaryVariable`](@ref) | Binary variables (``\alpha_1, \ldots, \alpha_L``) | +| [`SawtoothLinkingConstraint`](@ref) | Links ``g_0`` to normalized ``x`` | ## Comparison -| Property | Solver SOS2 | Manual SOS2 | Sawtooth | -|:---|:---|:---|:---| -| Binary variables | 0 | ``S`` | ``L`` | -| Continuous variables | ``S + 1`` | ``S + 1`` | ``L + 1`` | -| Breakpoints | ``S + 1`` | ``S + 1`` | ``2^L + 1`` | -| Max error | ``O(\Delta^2 / S^2)`` | ``O(\Delta^2 / S^2)`` | ``\Delta^2 \cdot 2^{-2L-2}`` | -| Solver requirements | SOS2 support | MIP only | MIP only | +| Property | Solver SOS2 | Manual SOS2 | Sawtooth | +|:-------------------- |:--------------------- |:--------------------- |:---------------------------- | +| Binary variables | 0 | ``S`` | ``L`` | +| Continuous variables | ``S + 1`` | ``S + 1`` | ``L + 1`` | +| Breakpoints | ``S + 1`` | ``S + 1`` | ``2^L + 1`` | +| Max error | ``O(\Delta^2 / S^2)`` | ``O(\Delta^2 / S^2)`` | ``\Delta^2 \cdot 2^{-2L-2}`` | +| Solver requirements | SOS2 support | MIP only | MIP only | To match the number of breakpoints between methods, set ``S = 2^L``. At equal breakpoint count the approximation quality is identical, but the sawtooth uses ``L = \log_2 S`` diff --git a/test/test_quadratic_approximations.jl b/test/test_quadratic_approximations.jl index 9f38182..c84aa2b 100644 --- a/test/test_quadratic_approximations.jl +++ b/test/test_quadratic_approximations.jl @@ -187,7 +187,7 @@ end @testset "Approximation quality improves with more segments" begin # min (√2)x² - (√3)x on [0, 6], analytic minimum at x=√3/8 - analytic_min = sqrt(2)*(sqrt(3/8)^2) - sqrt(3)*sqrt(3/8) + analytic_min = sqrt(2) * (sqrt(3 / 8)^2) - sqrt(3) * sqrt(3 / 8) errors = Float64[] for num_segments in 2 .^ (1:6) setup = _setup_qa_test(["dev1"], 1:1) @@ -208,7 +208,7 @@ end ) x_sq = result[("dev1", 1)] - JuMP.@objective(setup.jump_model, Min, sqrt(2)*x_sq - sqrt(3)*x_var) + JuMP.@objective(setup.jump_model, Min, sqrt(2) * x_sq - sqrt(3) * x_var) JuMP.set_optimizer(setup.jump_model, HiGHS.Optimizer) JuMP.set_silent(setup.jump_model) JuMP.optimize!(setup.jump_model) @@ -509,7 +509,7 @@ end @testset "Approximation quality improves with depth" begin # min (√2)x² - (√3)x on [0, 6], analytic minimum at x=√3/8 - analytic_min = sqrt(2)*(sqrt(3/8)^2) - sqrt(3)*sqrt(3/8) + analytic_min = sqrt(2) * (sqrt(3 / 8)^2) - sqrt(3) * sqrt(3 / 8) errors = Float64[] for depth in 1:6 setup = _setup_qa_test(["dev1"], 1:1) @@ -530,7 +530,7 @@ end ) x_sq = result[("dev1", 1)] - JuMP.@objective(setup.jump_model, Min, sqrt(2)*x_sq - sqrt(3)*x_var) + JuMP.@objective(setup.jump_model, Min, sqrt(2) * x_sq - sqrt(3) * x_var) JuMP.set_optimizer(setup.jump_model, HiGHS.Optimizer) JuMP.set_silent(setup.jump_model) JuMP.optimize!(setup.jump_model) @@ -581,7 +581,7 @@ end x_sq = result[("dev1", 1)] end - JuMP.@objective(setup.jump_model, Min, sqrt(2)*x_sq - sqrt(3)*x_var) + JuMP.@objective(setup.jump_model, Min, sqrt(2) * x_sq - sqrt(3) * x_var) JuMP.set_optimizer(setup.jump_model, HiGHS.Optimizer) JuMP.set_silent(setup.jump_model) JuMP.optimize!(setup.jump_model)