Skip to content

Commit 3c25534

Browse files
committed
Updated docs/src/guide/kkt.md and added qpsolver/README.md and lp_data/UserScale.md
1 parent a65e195 commit 3c25534

File tree

4 files changed

+336
-49
lines changed

4 files changed

+336
-49
lines changed

docs/README.md

Lines changed: 0 additions & 27 deletions
This file was deleted.

docs/src/guide/kkt.md

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,12 @@ tolerance.
113113

114114
### Solutions without a corresponding basis
115115

116-
The HiGHS PDLP solver and the interior point solver without crossover
117-
(IPX) yield "optimal" primal and dual values that satisfy internal
118-
conditions for termination of the underlying algorithm. These
119-
conditions are discussed below, and are used for good reason. However
120-
they can lead to a misleading claim of optimality.
116+
The HiGHS PDLP solver and the interior point solvers (HiPO and IPX)
117+
without crossover yield "optimal" primal and dual values that satisfy
118+
internal conditions for termination of the underlying algorithm. These
119+
conditions are discussed below, and are used for good reason. However,
120+
particularly in the case of PDLP, they can lead to a misleading claim
121+
of optimality.
121122

122123
#### Interior point solutions
123124

@@ -138,6 +139,13 @@ HiGHS. It terminates when
138139
\end{aligned}
139140
```
140141

142+
In practice, the feasibility tolerances are readily satisfied when
143+
using interior point solvers. Hence their termination generally
144+
depends on satisfying the optimality tolerance, with relative
145+
feasibility satisfied to a higher tolerance than required. Thus the
146+
solution obtained using interior point solvers typically has small
147+
absolute feasibility errors.
148+
141149
#### PDLP solutions
142150

143151
The PDLP algorithm uses an independent [optimality tolerance](@ref
@@ -155,27 +163,32 @@ feasibility by construction. It terminates when
155163
\end{aligned}
156164
```
157165

166+
Unlike interior point solvers, PDLP does not readily satisfy the
167+
relative feasibility tolerances. Although they and the optimality
168+
tolerance are satisfied on successful termination, the solution
169+
obtained may have meaningful absolute feasibility errors.
170+
158171
#### HiGHS solutions
159172

160-
The relative measures used by PDLP and IPX assume that all components
161-
of the cost and RHS vectors are relevant. When an LP problem is in
162-
standard form this is true for ``b``, but not necessarily for the cost
163-
vector ``c``. Consider a large component of ``c`` for which the
164-
corresponding reduced cost value in ``s`` is also large, in which case
165-
the LP solution is insensitive to the cost. This component will
166-
contribute significantly to ``\|c\|`` and, hence, the RHS of the dual
167-
residual condition, allowing large values of ``\|c-A^Ty-s\|`` to be
168-
accepted. However, this can lead to unacceptably large absolute
169-
residual errors and non-optimal solutions being deemed "optimal". When
170-
equations in ``Ax=b`` correspond to inequality constraints with large
171-
RHS values and a slack variable (so the constraint is redundant) the
172-
same issue occurs in the case of primal residual errors. The solution
173-
of the LP is not sensitive to this large RHS value, but its
174-
contribution to ``||b||`` can allow large absolute primal residual
175-
errors to be overlooked.
173+
The relative measures used by HiPO, IPX and PDLP assume that all
174+
components of the cost and RHS vectors are relevant. When an LP
175+
problem is in standard form this is true for ``b``, but not
176+
necessarily for the cost vector ``c``. Consider a large component of
177+
``c`` for which the corresponding reduced cost value in ``s`` is also
178+
large, in which case the LP solution is insensitive to the cost. This
179+
component will contribute significantly to ``\|c\|`` and, hence, the
180+
RHS of the dual residual condition, allowing large values of
181+
``\|c-A^Ty-s\|`` to be accepted. However, this can lead to
182+
unacceptably large absolute residual errors and non-optimal solutions
183+
being deemed "optimal". When equations in ``Ax=b`` correspond to
184+
inequality constraints with large RHS values and a slack variable (so
185+
the constraint is redundant) the same issue occurs in the case of
186+
primal residual errors. The solution of the LP is not sensitive to
187+
this large RHS value, but its contribution to ``||b||`` can allow
188+
large absolute primal residual errors to be overlooked.
176189

177190
To make an informed assessment of whether an "optimal" solution
178-
obtained by IPX or PDLP is acceptable, HiGHS computes infinity norm
191+
obtained by HiPO, IPX or PDLP is acceptable, HiGHS computes infinity norm
179192
measures of ``b`` and ``c`` corresponding to the components that
180193
define the optimal solution. For ``c`` these are the components
181194
corresponding to positive values of ``x`` and reduced costs that are

highs/lp_data/UserScale.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# HiGHS - User bound and cost scaling
2+
3+
User bound and cost scaling have been introduced to assess solver
4+
performance if a user's model were better scaled. It is achieved using
5+
the integer `HighsOptions::user_bound_scale` and
6+
`HighsOptions::user_cost_scale` options, where the scaling factor
7+
itself is two to the power of the option value. For simplicity, the
8+
scaling is applied to the incumbent model - as if the model had been
9+
well scaled by the user.
10+
11+
Scaling of costs is simple, since all costs are scaled. Scaling of LPs
12+
is also simple since all finite column and row bounds are scaled, so
13+
the constraint matrix is unchanged. However, nonzero (finite) bounds
14+
on non-continuous variables cannot be scaled, since it would change
15+
the number of feasible values. For a non-continuous variable, its
16+
contributions to the objective and constraint activites are scaled by
17+
scaling the cost coefficient and matrix values.
18+
19+
In summary, the incumbent data affected by user bound and cost scaling
20+
are as follows
21+
22+
- User bound scaling affects
23+
- Costs of non-continuous variables — using `userScaleCosts`
24+
- Matrix coefficients of non-continuous variables — using `userScaleMatrix`
25+
- Bounds of continuous variables — using `userScaleColBounds`
26+
- All row bounds — using `userScaleRowBounds`
27+
- User cost scaling affects
28+
- All column costs — using `userScaleCosts`
29+
30+
The only exception is the case of changes driven by a
31+
`HighsIndexCollection`, where scaling is performed on individual
32+
entries
33+
34+
## Where user scaling takes place
35+
36+
User scaling typically takes place when a model has been passed to
37+
HiGHS and the values of `user_bound_scale` or `user_cost_scale` are
38+
nonzero, or when the values of `user_bound_scale` or `user_cost_scale`
39+
are changed after a model has been passed to HiGHS. However, for
40+
consistency, when the incumbent model has been scaled that must be
41+
maintained when other operations take place.
42+
43+
Although scaling is more likely to be done to reduce the magnitude of
44+
bounds and costs, extreme scaling up can make increase the magnitude
45+
of bounds and costs beyond the value at which HiGHS considers them to
46+
be infinite. This (arguably) changes the model fundamentally. Hence,
47+
whenever user scaling is applied, an initial pass is made to determine
48+
whether it generates infinite bounds or costs or large matrix values,
49+
returning an error if this occurs. If they only create small matrix
50+
values, then a warning is issued.
51+
52+
### `Highs::passModel`
53+
54+
When a model is passed to HiGHS, if `user_bound_scale` or
55+
`user_cost_scale` are nonzero then their use is considered. If they
56+
create no infinte bounds or costs, or large matrix values, then the
57+
user scaling is applied, otherwise an error is returned. If they only
58+
create small matrix values, then the user scaling is applied, and a
59+
warning is issued.
60+
61+
### `Highs::addColsInterface`
62+
63+
When new columns are added to a model, they have no integrality, so
64+
the scaling of their bounds and costs is simple. Hence,
65+
`user_bound_scale` is applied uniformly to the (local) lower and upper
66+
bounds of the new columns, and `user_cost_scale` is applied uniformly
67+
to the (local) costs of the new columns.
68+
69+
### `Highs::addRowsInterface`
70+
71+
When new rows are added to a model, any column integrality must be
72+
respected. Hence `user_bound_scale` must be applied to the columns of
73+
non-continuous variables in the (local) matrix, and must be applied
74+
uniformly to the lower and upper bounds of the new rows
75+
76+
### `Highs::changeIntegralityInterface`
77+
78+
When integrality changes, the simplest thing to do is first remove any
79+
scaling specific to non-continuous variables — by using the negation
80+
of `user_bound_scale` to scale the costs and matrix coefficient for
81+
non-continuous variables. Then, after updating the integrality, use
82+
`user_bound_scale` to scale the costs and matrix coefficient for
83+
non-continuous variables.
84+
85+
### `Highs::changeCostsInterface`
86+
87+
When costs change, `user_bound_scale` must be applied to the changed
88+
costs of non-continuous variables, and `user_cost_scale` must be
89+
applied uniformly.
90+
91+
### `Highs::changeColBoundsInterface`
92+
93+
When column bounds change, `user_bound_scale` must be applied to the
94+
changed bounds of continuous variables
95+
96+
### `Highs::changeRowBoundsInterface`
97+
98+
When row bounds change, `user_bound_scale` must be applied uniformly
99+
to the changed bounds
100+
101+
### `Highs::changeCoefficientInterface
102+
103+
The coefficient is scaled using `user_bound_scale` if is corresponds
104+
to a non-continuous variable
105+
106+
### `Highs::optionChangeAction`
107+
108+
When `user_bound_scale` or `user_cost_scale` change (the difference
109+
in) this value must be applied as for a whole model. Since this is
110+
typically the first application of user scaling, there is a check for
111+
infinte bounds or costs, and whichever of `user_bound_scale` and
112+
`user_cost_scale` causes then is rejected with an error return.
113+
114+
### `Highs::passModel`
115+
116+

0 commit comments

Comments
 (0)