Quadratic Programming in Geometric Optimization: Theory, Implementation, and Applications
Quadratic Programming in Geometric Optimization: Theory, Implementation, and Applications
14738
Quadratic Programming in
Geometric Optimization:
Theory, Implementation, and
Applications
Sven Schönherr
2002
Diss. ETH No. 14738
Quadratic Programming in
Geometric Optimization:
Theory, Implementation, and
Applications
Dissertation
submitted to the
Swiss Federal Institute of Technology
Zurich, Switzerland
presented by
Sven Schönherr
Diplom-Mathematiker, Freie Universität Berlin, Germany
born on March 17th , 1968, in Berlin, Germany
citizen of Germany
2002
Für Marc-Daniel,
unseren Sonnenschein
Acknowledgments
I want to thank all people who have contributed by some means or other
to the success of this thesis.
First and foremost among these is Bernd Gärtner, who supported and
guided me during the whole time of my studies. He gave me valuable
insights in the area of geometric optimization and always kept me on
the right track in countless discussions. The subject of this thesis was
proposed by him, and, without his ongoing encouragement and strong
support, the completion of this work would not have been possible. My
sincere thanks go to him.
The constant support of my family has been fundamental for the success
of this thesis. I thank them all, especially my wife, Martina.
Abstract
0 Introduction 1
0.1 Geometric Optimization . . . . . . . . . . . . . . . . . . 3
0.2 Statement of Results . . . . . . . . . . . . . . . . . . . . 9
0.3 Outline of the Thesis . . . . . . . . . . . . . . . . . . . . 10
Part I: Theory
Bibliography 139
Index 149
Chapter 0
Introduction
There are two particular aspects that need to be dealt with to close
the gap between the theoretical results of computational geometry and
practical implementations [86], namely the precision problem and the
degeneracy problem.
Theoretical papers assume exact arithmetic with real numbers. The cor-
rectness proofs of the algorithms rely on the exact computations, thus
replacing exact arithmetic by imprecise built-in floating point arithmetic
does not work in general. Geometric algorithms in particular are sensi-
tive to rounding errors since numerical data and control flow decisions
have usually strong interrelations. The numerical problems may destroy
the combinatorial or geometric consistency of the algorithm, thus result-
ing in a program crash, in an infinite loop, or in unpredictable erroneous
output.
2 Chapter 0. Introduction
The key tool in reaching this goal is Cgal, the Computational Geometry
Algorithms Library. It was developed during the first two projects by
several universities and research institutes in Europe and Israel. Since
then, the library is (and will be in the future) actively maintained and
extended.
I joined the Cgal team in January 1995. As one of the five members
of the kernel design group [30], I influenced the design of the geometric
kernel and the overall design of the library. My contributions to the
basic library lie in the area of geometric optimization. In particular,
I implemented two versions of Welzl’s algorithm [105] for computing
the smallest enclosing circle and the smallest enclosing ellipse, respec-
tively, of a finite set of points in the plane. The latter implementation
uses the exact primitives derived in Chapter 4. It is joint work with
Bernd Gärtner, who wrote the underlying conic class [43, 44]. Further
contributions are implementations of geometric optimization problems
based on the new quadratic programming solver presented in this thesis
as well as the implementation of the solver itself.
cT x + xTD x,
The scenario for which we developed the QP solver is the one where
min(n, m) is small. In the geometric optimization problems, this value
is closely related to the dimension of the space the problem lives in. The
value max(n, m), on the other hand, may be very large — it usually
comes from the number of objects (points, halfspaces, etc.) that define
the problem. Moreover, we assume no sparsity conditions, i.e. both
matrices A and D may be dense. Namely, the geometric optimization
problems we want to handle typically exhibit a dense structure; when
we deal with point sets in Euclidean space, for example, the concept
of sparsity can even be meaningless. Many properties of point sets are
translation invariant, in which case coordinates with value zero play no
special role at all.
Let us briefly discuss why ‘standard’ solvers (addressing the case where
both m and n may be large and the problem is sparse) cannot efficiently
be used in our scenario.
First of all, if n is large and the objective matrix D is dense, the prob-
lem cannot even be entered into solvers which require the Θ(n2 ) nonzero
entries of D to be explicitly given. This situation for example occurs
6 Chapter 0. Introduction
Hoping for the best. This strategy performs all numerical opera-
tions purely with floating point arithmetic. Although this is fast and
will produce the correct result in most cases, it fails on some problems.
This approach can be seen as too optimistic in the sense that all prob-
lems are assumed to be well-behaved, where in practice only most of
them are. It is used, for example, in the state-of-the-art solver CPLEX.
Summarizing, expecting the worst is always correct but also always slow,
while hoping for the best is always fast and usually correct. For our
scenario, we use a mixed strategy expecting the best and coping with the
worst by combining floating point and exact arithmetic as suggested
in [39]. This approach has the advantage of being always correct and
usually fast.
All finite methods have the property that actual work is done only for
problem instances whose size is bounded by a function in d. Assuming
that d is constant, such instances can be solved in constant time. How-
ever, as far as explicit formulae for these primitive operations have been
given — which is the case only for d = 2 — they are quite complicated
and rely on solving third-degree polynomials [97, 80, 88].
Theory
Chapter 1
(LP) minimize cT x
subject to A x S b (1.1)
` ≤ x ≤ u,
cT x + xTD x ,
the resulting standard form has few equality constraints. The crucial
observation here is that the former inequalities can be treated implic-
itly; intuitively, we ‘trade them in’ for the new slack variables, moving
the problem’s complexity from the constraints to the variables, after
which we are basically back to a quadratic program in standard form
with m ≤ n. The details are described in Section 2.4. In the sequel, we
assume that we are given a problem in the form of (1.3).
Pricing. Consider the vector γ := cTN − cTB A−1B AN of reduced costs. The
current basic feasible solution is optimal if γ ≥ 0, because then xN ≥ 0
implies γ T xN ≥ 0, i.e. the objective function value z in (1.6) cannot be
improved by increasing one of the nonbasic variables. In case γ T xN 6≥ 0,
the pricing step returns some index j with γj < 0. The corresponding xj
is the entering variable.
Further details and proofs can be found in the book of Chvátal [20].
Chapter 2
A Simplex-Like
Quadratic Programming
Algorithm
(i) The rows of A are linearly independent, i.e. A has full (row) rank.
(ii) The subsystem AG xG = b has only solutions for sets G ⊆ [n] with
|G| ≥ m.
20 Chapter 2. A Simplex-Like QP Algorithm
cT + 2x∗ TD = −λTA .
Note, if the rows of A are linearly independent, then λ and µ are unique
in Theorem 2.2. The same holds for λ in Theorem 2.3.
By the KKT conditions (Theorem 2.3), there exists a vector λ such that
U := { y | y TDB = x∗ TDB } , V := { y | AB y = b }
The process of going from one basic solution to the next is called a
pivot step. In the LP simplex, the pricing is the part of the pivot step
that decides whether the current solution is optimal, and which variable
enters the basis if an improvement is possible.
24 Chapter 2. A Simplex-Like QP Algorithm
2.3.1 Pricing
Since x∗B > 0, µB = 0 holds using (2.4). Extracting x∗j from (2.3) gives
The second part of the LP simplex’s pivot step is the ratio test. It
decides which variable has to leave the basis if another variable enters
it. Unless the problem is degenerate, there is a unique choice for the
leaving variable. In the QP simplex, it can happen that a variable enters
the basis, but there is no leaving variable, so that the basis gets larger.
This is the case if the objective function reaches a local minimum (while
the entering variable is increased), before some other (basic) variable
goes down to zero. Moreover, it can happen that even if some leaving
variable is found, the solution at that point is not basic. In this case,
the pivot step continues, and more variables may leave the basis, until
another basic solution is discovered. The QP ratio test consists of three
steps which are described below.
for t = 0. Furthermore, (UQPtj (B̂)) has a unique optimal solution x∗B̂ (t)
for each value of t, which is determined by
! ! !
λ(t) b Aj
MB = −t (2.7)
x∗B (t) −cB 2DB,j
and x∗j (t) = t. This follows from the KKT conditions for (2.6) (Theo-
rem 2.3), the regularity of MB , and some elementary transformations.
26 Chapter 2. A Simplex-Like QP Algorithm
While increasing t starting from zero (which improves the current solu-
tion), two things may happen. Either one of the basic variables becomes
zero, or a local minimum of the objective function is reached. The first
event can be tested by solving x∗i (t) = 0 for all i ∈ B. To check the
second event, we look at the linear function µj (t) derived from (2.3b)
and (2.8)
As soon as µj (t) becomes zero for some t > 0, λ(t) and µ = 0 fulfill the
KKT conditions of Theorem 2.2, thus x∗B̂ with x∗j (t) = t is an optimal
solution to (QP(B̂)). The following lemma shows that B̂ is the new
basis in case of the second event.
Lemma 2.7 If µj (t) in (2.9) becomes zero for some t > 0 before any
of the basic variables vanishes, then B̂ is the new basis.
Consider the matrices MB and MB̂ . The latter is just the basis
matrix MB plus one additional row and one additional column for
index j, which can be assumed to be the largest index in B, w.l.o.g.
It is easy to verify that
1 0 0 1 qλ
.. .. .. ..
. . MB . .
MB̂ =
qx
(2.10)
1 0 0
1
qλT qxT 1 0 ... 0 ν 0 ... 0 1
holds, where
ν := 2Dj,j − ATj qλ − 2DB,j
T
qx .
2.3. Pivot Step 27
det(MB̂ ) = det(MB ) ν ,
i.e. MB̂ is regular if ν 6= 0, since det(MB ) 6= 0 follows from the fact that
MB is a basis matrix. Suppose ν = 0, then by (2.9)
µj (t) = µj + t ν = µj < 0 ,
a contradiction to µj (t) = 0. 2
In case the first event happens, i.e. some basic variable xi becomes
zero, we implicitly add the constraint xi = 0 to (UQPtj (B̂)) by removing
index i from B. If MB\{i} is regular, we still have a unique optimal
solution to (UQPtj (B̂ \{i})) for each value of t and Step 1 is iterated.
Otherwise we proceed to Step 2.
Step 2. Let B be the set of basic variables after the last iteration
of Step 1. Since MB has become singular, (2.7) does no longer deter-
mine unique solutions to (UQPtj (B̂)) for arbitrary t (with B̂ = B ∪ {j}).
Reconsidering the KKT conditions for (QP(B̂)), i.e. Equations (2.3)
and (2.4), yields
λ b 0
x∗ −c
MB̂ B = B + µj 0 . (2.11)
x∗j −cj 1
with
pλ 0
p −1
:= M .
0 (2.12)
xB B̂
pxj 1
28 Chapter 2. A Simplex-Like QP Algorithm
While growing µj from µj (t1 ) towards zero (similar to t in Step 1), two
events may occur. Again, either one of the remaining basic variables
becomes zero, or a local minimum of the objective function is reached.
If the latter happens, i.e. µj equals zero, we found an optimal solu-
tion x∗B̂ (0) > 0 to (UQP(B̂)), which is at the same time an optimal
solution to the constrained problem (QP(B̂)) by Corollary 2.4. The
uniqueness of the solution follows from the regularity of MB̂ , which also
implies that B̂ is the new basis in that case.
On the other hand, if some basic variable xk becomes zero (first event),
we implicitly add the constraint xk = 0 to (UQP(B̂)) by removing k
from B̂. If MB̂\{k} stays regular, we still get unique solutions of (2.11)
for arbitrary values of µj . In this case Step 2 is iterated, otherwise we
continue with Step 3.
Lemma 2.8 In case MB̂ is singular after Step 2, then the linear equa-
tion system (2.11) has only solutions if µj = 0.
1
On the other hand, we get rj 6= 0 for all r 6= 0 with rT MB̂ = 0 by the
following case distinction, contradicting the assumption that (2.13) has
a solution.
If there has been no iteration in Step 2, i.e. both MB and MB̂ are
singular after Step 1, let xi with xi (t) = 0 be the last removed variable.
Then MB∪{i} is regular and (2.8) reads as
qλ Aj
MB∪{i} qx = 2DB,j ,
qxi 2Di,j
which gives ! ! !
qλ Ai Aj
MB + qxi =
qx 2DB,i 2DB,j
30 Chapter 2. A Simplex-Like QP Algorithm
T
if the last row is ignored. Now, for all r0 6= 0 with r0 MB = 0 holds
!
T A j
r0 6= 0, (2.15)
2DB,j
T
since (ATi |2DB,i )r0 6= 0 follows from the regularity of MB∪{i} and qxi 6= 0
is implied by xi (t) = 0. Suppose there exists a vector r̃ 6= 0 with r̃j = 0
and r̃T MB̂ = 0. Then
T !
T r̃B
T
T Aj
r̃ MB̂ = MB̂ = r̃B MB r̃B
0 2DB,j
shows !
T Aj
r̃B = 0,
2DB,j
contradicting (2.15), which completes the first case.
The second case occurs when there has been at least one iteration in
Step 2. Let xk with xk (µj ) = 0 be the last removed variable, then
MB̂∪{k} is regular and (2.12) gives
pλ 0
p
x 0
MB̂∪{k} B = .
pxk 0
pxj 1
By ignoring the ‘k’-th row, we obtain
pλ Ak 0
p 2D
MB̂ xB + B,k pxk = 0 .
pxj 2Dj,k 1
Finally, using the regularity of MB̂∪{k} and pxk 6= 0 (which is implied
by xk (µj ) = 0)), it follows that
0 Ak
rj = rT 0 = rT 2DB,k zk 6= 0
1 2Dj,k
holds for all r 6= 0 with rT MB̂ = 0. This is a contradiction to (2.14)
and completes the proof. 2
2.4. Inequality Constraints 31
2.3.3 Update
The old basis B gets replaced by the new basis B 0 ⊆ B ∪ {j} which
was determined in the ratio test. Furthermore, some representation of
the basis matrix MB has to be maintained, which allows to compute
x∗B and λ of (2.5), qλ and qx of (2.8), and pλ and pxB̂ of (2.12) efficiently.
In addition, the update should be substantially cheaper than computing
the representation from scratch when MB changes to MB 0 . As already
suggested in the previous chapter, we will see that the inverse of the
basis matrix is a suitable representation in our scenario (cf. Part II,
Section 6.3).
m
X
aij xj Q bi ,
j=1
by the equation
m
X
aij xj ± xsi = bi , (2.16)
j=1
AB xB = b, (2.18)
ATB λ + 2DB xB = −cB . (2.19)
equivalently
Two things follow from (2.17). Firstly, AE,BS and ASN,BS have only zero
entries, thus the second terms in (2.20) and (2.21) vanish. Secondly, the
values of the basic slack variables are determined by (2.22), i.e.
respectively
Here, only DBO,BO has nonzero entries while all other parts of D have
just zero entries, and so has −cBS . Together with the known charater-
istics of A, equation (2.24) boils down to
±λi = 0, i ∈ SB .
AE ∪S
˙ N,BO xBO = bE ∪S
˙ N (2.25)
ATE ∪S
˙ N,BO λE ∪S
˙ N + 2DBO,BO xBO = −cBO (2.26)
2.5 Degeneracies
where a0j,j 6= 0 holds if at least one nonzero entry exists in row j. This
can be always achieved by swapping the columns of A0 appropriately.2
In case we end up with all entries of the diagonal a01,1 to a0m,m being
nonzero, then A0 and A have full (row) rank m and we are done. Other-
wise some a0j,j = 0, i.e. row j of A0 has only zero entries, thus we found
a linearly dependent row of A. If the corresponding b0j is zero too, we
just remove constraint j from the equation system. This is done for
all ‘zero’ rows, resulting in an equivalent system where the constraint
2 The vector x0 contains the entries of x in possibly different order. A pair of
matrix has full row rank. Only if b0j 6= 0 holds, constraint j cannot be
fulfilled and the original equation system Ax = b has no solution.
Ax = b + ε (2.28)
2.6 Conclusion
Geometric Optimization
Problems
only bases of size d+2 at most. This proves that the closest features of
two d-polytopes are always determined by at most d+2 points. (If the
polytopes have positive distance, d+1 points suffice.)
(PD0 ) minimize yT y
subject to y = Cx
Pr
xi = 1 (3.2)
Pni=1
i=r+1 xi = 1
x ≥ 0.
This quadratic program has n+d variables and d+2 constraints, but
now the objective function has a sparse representation.
is the center of the smallest enclosing ball of P and the negative value
of the objective function at x∗ is the squared radius of this ball.
Pn
if and only if x∗ is optimal for (MB). Using Cx∗ = i=1 pi x∗i gives
equivalently
There is also a dual version of (3.8), namely the following linear program
in 2n variables λ := (λ1 , . . . , λn ) and µ := (µ1 , . . . , µn ) with d+2 con-
straints
3.4. Optimal Separating Hyperplane 43
Pn T Pn T
(MA’) minimize i=1pi pi µi − i=1 pi pi λi
Pn n
2pij λi + i=1 2pij µi = 0
P
subject to j = 1...d
Pni=1
λi = 1 (3.9)
Pi=1
n
i=1µi = 1
λ, µ ≥ 0 .
3.5 Conclusion
A Non-Quadratic
Geometric Optimization
Problem
(x − c)T M (x − c) = 1 (4.1)
Vol(Sd )
Vol(E) = p , (4.2)
det(M )
Proposition 4.1
(i) If there is any ellipsoid with R on its boundary that
encloses Q, then SmEll(Q, R) exists and is unique.
For a point set R ⊆ Rd let S(R) denote the set of (δ+1)-tuples of para-
meters that define second order surfaces through all points in R. It is
clear that S(R) is a vector space, and we define the degree of freedom
w.r.t. R to be dim(S(R)) − 1. Obviously, the degree of freedom is at
least δ − |R|, since any point in R introduces one linear relation between
the parameters.
Now we claim that during Algorithm 4.2, the degree of freedom w.r.t. R
is always exactly δ−|R|. This is clear for R = ∅. Moreover, if q is added
to R in the second recursive call of the algorithm, the degree of freedom
goes down, which proves the claim. To see this, assume on the contrary
that dim(S(R)) = dim(S(R ∪ {q})), hence S(R) = S(R ∪ {q}). Then
it follows that q already lies on any second order surface through R,
in particular on SmEll(Q\{q}, R). But then the second recursive call
would not have been made, a contradiction.
Now the claim of the lemma follows: if |R| = δ, the degree of freedom
is 0, i.e. S(R) has dimension 1. Since a second order surface is invariant
under scaling its parameters, this means that there is a unique second
order surface, in this case an ellipsoid, through R. 2
50 Chapter 4. A Non-Quadratic Geom. Optimization Problem
4.3.1 Conics
Now, given the query point q ∈ / R, there exists a unique conic C0 through
the five points R ∪ {q}, since R is an (intermediate) support set of Algo-
rithm 4.2, see also [98]. We can compute this conic as C0 = λ0 C1 +µ0 C2 ,
with λ0 := C2 (q) and µ0 := −C1 (q). In the sequel we assume that C0 is
normalized. Depending on the type of C0 we distinguish two cases.
C2
p4
C1 p3
p1
p2
p4 p3
p1
p2
Let us give some intuition, before we formally prove the lemma. Since
no three of the four support points are collinear, there exist two (possi-
bly degenerate) parabolas through these points, see Figure 4.4. These
parabolas cut the plane into regions which determine the type of C0 .
Only if q lies strictly inside one parabola and strictly outside the other,
C0 is an ellipse. Otherwise, q either lies inside both parabolas in which
54 Chapter 4. A Non-Quadratic Geom. Optimization Problem
Proof. Assume there are two ellipses E and E 0 through R, with E(q) ≤ 0
and E 0 (q) > 0. Then we find λ ∈ [0, 1) such that E 00 := (1−λ)E +λE 0
satisfies E 00 (q) = 0, i.e. E 00 goes through R ∪ {q}. Thus E 00 equals C0 and
is not an ellipse. On the other hand, the convex combination of two
ellipses is an ellipse again [88, Chapter 1], a contradiction. 2
Lemma 4.4 shows that it suffices to test q against any ellipse through
the four points to obtain the desired result. Let
α := r1 s1 − t21 , β := r1 s2 + r2 s1 − 2 t1 t2 , γ := r2 s2 − t22 ,
We will show that both factors have negative sign, thus proving that
the choice of λ and µ indeed yields an ellipse E.
where
E ∗ = λ∗ C1 + µ∗ C2 ,
E τ := (λ0 −τ r2 ) C1 + (µ0 +τ r1 ) C2 , τ ∈ R.
∗
Then E 0 = E and E τ = E ∗ . The function g(τ ) := E τ (q) is linear, hence
we get
∗ ∗ ∂ τ
= ρ τ ∗,
E (q) = τ E (q)
∂τ τ =0
E λ := (1−λ)E1 + λE2
d := det(M ), Z := u2 s − 2 uvt + v 2 r .
Since d(0) and z(0) are positive (recall that E is a normalized ellipse),
this is equal in sign to
σ := d (d0 z − 2 dz 0 ) ,
at least when evaluated for τ = 0, which is the value we are interested in.
Furthermore, we have
1 d0
d0 z = d0 ( Z − w) = Z − d0 w ,
d d
0 0
Z d − Zd Z 0 d − Zd0
dz 0 = d ( − w 0
) = − dw0 ,
d2 d
4.3. Exact Primitives in the Plane 57
hence
d = rs − t2 , Z 0 = u0 Z1 + uZ10 + v 0 Z2 + vZ20 ,
d0 = r0 s + rs0 − 2 t t0 , Z10 = u0 s + us0 − v 0 t − vt0 ,
Z20 = v 0 r + vr0 − u0 t − ut0 .
For τ = 0, all these values can be computed directly from r(0), . . . , w(0)
(the defining values of E) and their corresponding derived values
r0 (0), . . . , w0 (0). For the latter we get r0 (0) = 0, s0 (0) = r1 s2 −r2 s1 , . . . ,
w0 (0) = r1 w2 −r2 w1 . We obtain that q lies inside SmEll(∅, R) if and
only if ρ σ(0) ≤ 0.
Note that for deciding the in-ellipse test in the case |R| = 4, it was not
necessary to know SmEll(∅, R) explicitly. In fact, SmEll(∅, R) is not
even representable with rational coordinates in general, as shown by the
following example.
Consider the points p1 = (0, 0), p2 = (1, 0), p3 = (1/2, 1), and p4 = (0, 1),
see Figure 4.5. As noted before, SmEll(∅, {p1 , p2 , p3 , p4 }) is a linear
combination λC1 +µC2 of two special conics C1 and C2 through the four
points, as depicted in Figure 4.3. By explicitly computing these conics,
one finds that the linear combination in the form of (4.6) is given by
µ µ/4 −µ/2
M= , m= , w = 0.
µ/4 −λ/2 λ/4
Standard calculus shows that this defines the ellipse √ of minimum vol-
ume through p1 , p2 , p3 , p4 if and only if 4λ = −(3+ 13)µ holds. This
means, the linear form of SmEll(∅, {p1 , p2 , p3 , p4 }) contains irrational
coordinates, no matter how it is scaled. This also holds for the center
form. In particular, the center c = (xc , yc ) evaluates to
√ √
9 + 3 13 1 + 13
xc = √ ≈ 0.406 , yc = √ ≈ 0.377 .
20 + 8 13 5 + 2 13
58 Chapter 4. A Non-Quadratic Geom. Optimization Problem
p4 p3
p1 p2
4.4 Conclusion
Note that even a number type supporting k-th roots with arbitrary pre-
cision like leda real [68] can not handle the smallest enclosing ellipse
with four boundary points exactly, because third roots of complex num-
bers are needed to solve (4.10).
Implementation
Chapter 5
Cgal, the
Computational
Geometry Algorithms
Library
The birth of Cgal dates back to a meeting in Utrecht in January 1995.
Shortly afterwards, the five authors of [31] started developing the kernel.
The development of the whole library has been made possible through
the funding of two projects1 by the European Community. Since the
official start of the Cgal project in October 1996, the team of devel-
opers has grown considerably. It consists mostly of research assistants,
PhD students and postdocs in academia, who are professionals in the
field of computational geometry and related areas. They form a hetero-
geneous team of developers; some of them working part time for Cgal,
some of them full time. The Cgal release 2.3 (August 2001) consists
of approximately 200,000 lines of C++ source code2 for the library, plus
100,000 lines for accompanying sources, such as the test suite and exam-
ple programs. Cgal’s WWW home-page3 http://www.cgal.org/ pro-
1 ESPRIT IV LTR Projects No. 21957 (CGAL) and No. 28155 (GALIA)
2 C++ comments and empty lines are not counted.
3 The reservation of Cgal’s own domain was proposed by the author during the
The advantages are the explicit definition of the interface and the run-
time flexibility. But there are four main disadvantages: Firstly, the
object-oriented programming paradigm cannot provide strong type
checking at compile time whenever dynamic casts are used, which is
necessary in C++ to achieve flexibility. Secondly, this paradigm enforces
tight coupling through the inheritance relationship [61], thirdly, it re-
quires additional memory for each object (in C++ the so-called virtual
function table pointer ) and, fourthly, it adds for each call to a virtual
member function an indirection through the virtual function table [63].
The latter is of particular interest when considering runtime perfor-
mance since virtual member functions can usually not be made inline
and are therefore not subject to code optimization within the calling
66 Chapter 5. Computational Geometry Algorithms Library
function the actual member function that is called, which allows the compiler to
optimize this call. The keyword final has been introduced in Java to support this
intention. However, these techniques are not realized in C++ compilers so far and
they cannot succeed in all cases, even though it is arguable that typical uses in
Cgal can be optimized. However, distributing a software library in precompiled
components will hinder their optimization, which must be done at link time.
5.2. Generic Programming 67
class in Stl. Five different categories are defined for iterators: input,
output, forward, bidirectional and random-access iterators, according
to the different possibilities of accessing items in a container class. The
usual C-pointer referring to a C-array is a model for a random-access
iterator.
algorithms can be parameterized with the base class used in the object-
oriented programming to achieve runtime flexibility where needed.
Cgal is structured into three layers and a support library, which stands
apart. The three layers are the core library with basic non-geometric
functionality, the geometric kernel with basic geometric objects and
operations, and the basic library with geometric algorithms and geo-
metric data structures.
The three layers and the support library are further subdivided into
smaller modular units, see Figure 5.1. The modular approach has sev-
eral benefits. The library is easier to learn, because it is possible for
a user to understand a small part without having any knowledge of
other parts. For building the library, the modules are a good way of
distributing implementation work among the project partners. Test-
ing and maintainance of the library is easier when there are only few
dependencies between units [61].
Basic Support
planar convex triangu−
Library polygon ... Library
map hull lation
visuali−
Geometric zation
two− three− d−
Kernel dimensional dimensional dimensional
number
types
Core
Library configuration assertions circulators ... ...
operations needed in Cgal are quite basic, every library supplying num-
ber types can be easily adapted to work with Cgal.
The basic library contains more complex geometric objects and data
structures: polygons, planar maps, polyhedra and so on. It also contains
algorithms, such as computing the convex hull of a set of points, the
union of two polygons, smallest enclosing ellipse and so on. Figure 5.1
indicates the major parts in the basic library. These parts are mostly
independent from each other and even independent from the kernel.
This independence has been achieved with geometric traits classes as
described in Section 5.5.3 below.
library are defined in this namespace and can be accessed via the scope prefix CGAL::.
72 Chapter 5. Computational Geometry Algorithms Library
Class hierarchies are used rarely in Cgal. An example are affine trans-
formations which maintain distinct internal representations specialized
on restricted transformations. The internal representations differ con-
siderably in their space requirements and the efficiency of their member
5.4. Geometric Kernel 73
functions. For all but the most general representation we gain perfor-
mance in terms of space and time. And for the most general repre-
sentation, the performance penalty caused by the virtual functions is
negligible, because the member functions are computationally expen-
sive for this representation. Alternatively we could have used this most
general representation for affine transformations only. But the use of
a hierarchy is justified, since the specialized representations, namely
translation, rotation and scaling, arise frequently in geometric comput-
ing.
Like other libraries [68, 13, 57] we use reference counting for the kernel
objects. Objects point to a shared representation and each represen-
tation counts the number of objects pointing to it. Copying objects
increments the counter of the shared representation, deleting an object
decrements the counter of its representation. If the counter reaches zero
by the decrement, the representation itself is deleted (see [70, Item 29]
for further information). The implementation of reference counting
is simplified by the non-modifiability of the kernel objects. However,
the use of reference counting was not the reason for choosing non-
modifiability. Using ‘copy-on-write’, i.e. a new representation is created
for an object whenever its value is changed by a modifying operation,
reference counting of modifiable objects is possible and only slightly
more involved. A comparison with a prototype of a geometric kernel
without reference counting can be found in [85]. The test applications
are two-dimensional convex hull algorithms. Reference counting costs
74 Chapter 5. Computational Geometry Algorithms Library
about 15% to 30% runtime for the types double and float, but it gains
2% to 11% runtime for the type leda real. Meanwhile, Cgal provides
two additional representation classes without reference counting. They
are named CGAL::Simple cartesian and CGAL::Simple homogeneous.
Further details of the geometric kernel can be found in [31], for exam-
ple the polymorphic behaviour of the return type of the intersection
functions. Recent developments towards an even more adaptable and
extensible geometric kernel are described in [53].
The basic library contains more complex geometric objects and data
structures, such as polygons, polyhedrons, triangulations (including
Delaunay, constrained, and regular triangulations), planar maps, range
and segment trees, and kd-trees. It also contains geometric algorithms,
such as convex hull, smallest enclosing circle, ellipse, sphere, and annu-
lus, polytope distance, boolean operations on polygons, and map over-
lay.
class Triangulation {
public:
Vertex_iterator vertices_begin();
Vertex_iterator vertices_end();
Convex_hull_iterator convex_hull_begin();
Convex_hull_iterator convex_hull_end();
// ...
};
5.5. Basic Library 75
Here, the input is read from the iterator range [first,beyond) and the
output is written to the output iterator result. Let the return-value
be result beyond, then the iterator range [result,result beyond)
contains the sequence of points on the convex hull. This design decou-
ples the algorithm from the container and gives the user the flexibility
to use any container, e.g. from Stl, from other libraries or own imple-
mentations (provided they are Stl compliant). It is even possible to
use no container at all, for example a sequence of points read from the
standard input:
9 The actual implementation in Cgal differs slightly, i.e. the vertices of the convex
hull of the triangulation are accessed with a more efficient circulator [58], since the
internal representation of this convex hull is cyclic.
76 Chapter 5. Computational Geometry Algorithms Library
Points are taken from the standard input and the resulting points on the
convex hull are written to the standard output. Here so-called stream
iterators [72] from Stl are used. This example again demonstrates the
flexibility gained from the Stl-compliance of the geometric algorithms
in the basic library.
struct iterator_to_int {
typedef int value_type;
// ...
};
The value type of the iterator example class above can be expressed as
iterator traits< iterator to int >::value type. For C-pointers
a specialized version of iterator traits exists, i.e. a class template para-
meterized with a C-pointer.
Our approach using traits classes in the basic library does not attach
information to built-in types, but to our data structures and algorithms.
We use them as a modularization technique that allows a single imple-
mentation to be interfaced to different geometric representations and
primitive operations. Our traits class is therefore a single template
argument for algorithms and data structures in the basic library, for
example triangulations:
provided for the geometric kernel of Cgal. They are class templates
parameterized with a kernel representation class, for example CGAL::
Triangulation euclidean traits 2< CGAL::Cartesian<double> >.
A single traits class for triangulations is sufficient for all representations
and number types possible with the kernel. Further traits classes are
available in Cgal, for example for using the basic library with the
geometric part of Leda.
typedef CGAL::Cartesian<double> R;
typedef CGAL::Point_2<R> Point;
typedef CGAL::Polygon_2<R> Polygon;
Polygon hull;
CGAL::convex_hull_points_2( istream_iterator<Point>( cin),
istream_iterator<Point>( ),
back_inserter( hull));
In the call to the convex hull algorithm no traits class is visible to the
user. A default traits class is chosen automatically in the definition of
the algorithm:
The value type of the iterator InputIterator is the point type used
in the input. It is determined with the iterator traits described previ-
ously. Since the default traits class is supposed to use the geometric
kernel of Cgal, we know that the point type must be a Cgal point
5.6. Conclusion 79
5.6 Conclusion
The abstract concepts used in Stl are so powerful that only a few ad-
ditions and refinements are needed in Cgal. One refinement is the
concept of handles. Combinatorial data structures might not necessar-
ily possess a natural order on their items. Here, we restrict the concept
of iterators to the concept of handles, which is the item denoting part of
the iterator concept, and which ignores the traversal capabilities. Any
model of an iterator is a model for a handle. A handle is also known
as trivial iterator. Another refinement is the concept of circulators [58],
a kind of iterators with slightly adapted requirements to better suit the
needs of circular sequences. These occur naturally in several combina-
torial data structures, such as the sequence of edges around a vertex in
a triangulation.
80 Chapter 5. Computational Geometry Algorithms Library
The geometric traits classes offer great flexibility and modularity. There
is always a predefined traits class that uses types and operations of the
kernel. Where possible, this traits class is chosen by default, so the user
can totally ignore the existence of this mechanism.
A Quadratic
Programming Engine
6.2 Solver
The implementation of the QPE is divided in three parts: the solver [89],
the basis inverse [90], and the pricing strategies [91].
struct QPErep {
typedef ... A_iterator;
typedef ... B_iterator;
typedef ... C_iterator;
typedef ... D_iterator;
// ...
};
The iterators for the actual problem are passed as parameters to the
solver’s set method, which is declared as follows:
84 Chapter 6. A Quadratic Programming Engine
All five iterators have to allow random-access, e.g. b it[j] is the j-th
entry of b and c it[i] is the i-th entry of c. Since A is accessed column-
wise, a it[j] is an iterator referring to the first entry in the j-th column
of A, while d it[i] is an iterator referring to the first entry in the i-th
row of D.
There are two types for defining tags, namely Tag true and Tag false.
If a property is present, the corresponding tag is defined to be of type
Tag true, otherwise of type Tag false.
struct QPErep {
// ...
typedef ... Is_linear;
typedef ... Is_symmetric;
typedef ... Has_no_inequalities;
// ...
};
6.2. Solver 85
The current solution of the QPE consists of the values of the original
variables and the values of the slack variables. The latter are only
present, if the given problem has inequality constraints.
Thus, the code for computing the values of the slack variables is only
generated, if the given problem has inequality constraints.
struct QPErep {
typedef ... ET;
// ...
};
During the ratio test, we test which basic variable becomes zero first,
when we increase the entering variable. This is done by finding the
smallest positive quotient ti = xi /qxi for all i ∈ B (cf. Section 2.3.2).
6.3. Basis Inverse 87
xi ()
ti () =
qxi
x0 x1 x2 xm
= i + i + i 2 + · · · + i m , i∈B. (6.2)
qxi qxi qxi qxi
The second equation is derived using (2.29) on page 35. Since 0 < < 1,
we find the smaller of two ti () by comparing their first quotients as
defined in (6.2). Only if these have the same value, we compare their
second quotients, and so on. In other words, we compare two vectors
vi := (x0i /qxi , x1i /qxi , . . . , xm
i /qxi ) lexicographically. Because the first
entry of vi determines the sign of ti (), most comparisons are decided
after comparing the first entries. Usually, there are very few cases that
need the second or subsequent entries to decide the comparison.
and MB−1 is called the basis inverse. From our generalized simplex
method used in the QPE, we have the following additional structure
and requirements.
88 Chapter 6. A Quadratic Programming Engine
• If the matrix MB and the vectors bE ∪S˙ N and −cBO contain inte-
gral entries, then the entries of the solution vectors x∗BO and λ
are rational, and we would like to obtain exact rational represen-
tations of them. This means that explicit divisions have to be
avoided during the solution process (unless they do not leave a
remainder).
We will refer to the QP case or the LP case in the sequel, if the problem
to solve is a quadratic or linear program, respectively.
In the LP case, every basis has size m. The basis matrix assumes the
form !
0 AE ∪S
˙ N,BO
MB = ,
ATE ∪S
˙ N,BO 0
with |E| + |SN | = |E| + |S| − |SB | = m − |BS | = |B| − |BS | = |BO |,
˙ N,BO is quadratic. The resulting basis inverse is
i.e. AE ∪S
−1 T!
0 (AE ∪S
˙ N,BO )
MB−1 = −1
(6.4)
˙ N,BO )
(AE ∪S 0
6.3. Basis Inverse 89
−1
˙ N,BO )
and it suffices to store (AE ∪S , avoiding any space overhead com-
pared to a stand-alone implementation of the simplex method for solving
linear programs.
−1 (−1)i+j det(M ji )
Mi,j = .
det(M )
M̂ −1 := d M −1 ,
where d := |det(M )|. In the sequel, any value x and the corresponding x̂
satisfy x = x̂/d.
6.3.2 Updates
Note, the first four update types belong to the QP case, while the latter
four belong to the LP case.
An update of type U1, U4, or U7 enlarges the matrix M by one row and
one column. We may assume w.l.o.g. that the row and the column are
appended to the bottom and to the right of M , respectively, to simplify
the presentation. Let (uT, w) be the row and (v T, w)T the column to
add, with w being the entry they have in common. Then the new matrix
is
M v
M> = .
T
u w
It is easy to verify that
1 0 0 1
... .. .. ..
.
M .
. y
M> = (6.6)
1 0 0 1
xT 1 0 ... 0 z 0 ... 0 1
holds, where
xT := uT M −1 , y := M −1 v, z := w − uT M −1 v.
6.3. Basis Inverse 91
x̂T ŷ ẑ
xT =: , y =: , z =: . (6.8)
d d d
From (6.6) we get
The complementary operation, i.e. the removal of one row and one
column, is done by updates of type U2, U3, and U8. We assume
w.l.o.g. that the last row and the last column of M should be removed,
92 Chapter 6. A Quadratic Programming Engine
with common denominator |ẑ|. The integral part of the new inverse
−1
M< is obtained by
−1 .. ..
M̂< . 1 ŷ x̂T .
= sgn(ẑ) d M̂ −1 − , (6.11)
ẑ
... . ... .
ignoring the last row and the last column of M̂ −1 in the calculation
above. Again, the division by ẑ is without remainder, and the new
denominator is d = |det(M< )|. The sign of ẑ can be computed easily
using the fact that d has to be positive by definition.
The two remaining update types either replace one row (U5) or one
column (U6) of M . We can assume w.l.o.g. that the last row or column
is replaced. Let uT be the new row and v the new column, respectively.
and
1 y1
.. ..
. .
Mc = M . (6.13)
1 yk−1
0 . . . 0 yk
6.3. Basis Inverse 93
and
1 −y1
.. ..
1 . .
Mc−1 = M −1 .
yk 1 −yk−1
0 ... 0 1
and
1 −ŷ1 /d
.. .. M̂ −1
d . .
Mc−1 =
ŷk 1 −ŷk−1 /d d
0 ... 0 1
d −ŷ1
.. ..
sgn(ŷk ) . .
M̂ −1
= M̂ −1 /d = c . (6.15)
|ŷk | d −ŷk−1 |ŷk |
0 ... 0 d
94 Chapter 6. A Quadratic Programming Engine
The new denominators are |x̂k |, since det(Mr ) = xk det(M ) = x̂k holds
by (6.12), and |ŷk |, since det(Mc ) = yk det(M ) = ŷk holds by (6.13).
Updates of the first four types can be performed in time O((m + |BO |)2 )
and updates of the latter four types in time O(m2 ). This is substantially
cheaper than computing the basis inverse from scratch.
The technique of updating the basis inverse when a column in the basis
matrix is replaced has been proposed before by Edmonds and termed
‘Q-pivoting’ [28]. It is also used, for example, by Gärtner in his exact
implementation of the simplex method [39] and by Avis in his vertex
enumeration algorithm [5].
6.3.3 Implementation
The basis inverse is realized in the class template QPE basis inverse.
It is parameterized with an exact number type ET and a compile time
tag IsLP. The latter indicates whether the problem to solve is a linear
program.
As in the implementation of the solver, the tag IsLP lets the compiler
decide which code to generate for the basis inverse, resulting in an effi-
cient tailored implementation for the specific problem to solve.
From the description of the update types we know, that in the QP case
the index sets BO and E ∪˙ SN can increase and decrease independently.
This means that the number of rows (columns) in the submatrix of A
(AT ) can increase and decrease. To handle this, one could append new
rows and columns always at the lower right part of the matrix, and
fill up a removed row and column by the last row and column of the
matrix, respectively. The major drawback of this approach is, besides
the additional work for the swapping, that the index sets get mixed up
after some updates, which makes multiplying vectors with the matrix
complicated and expensive. We want to keep the rows and columns
corresponding to the same index set together, without having to move
or copy parts of the basis inverse when rows are added to the submatrix
of A. Therefore we must make sure that enough space is available in the
upper left part of the matrix. Fortunately, the size of E ∪˙ SN is bounded
by l := min{n, m} (cf. Section 2.4), so we are able to reserve enough
space for the upper left part at once when the matrix is initialized, see
Figure 6.1.
µj = cj + ATj λ + 2DB,j
T
x∗B .
column 0 column l
↓ ↓
···
row 0 → m1,1 . . . m1,s m1,l+1 ... m1,l+b
.. .. .. .. →
. . . . ←
&
- ↓↑
···
row l → ml+1,1 . . . ml+1,s ml+1,l+1 . . . ml+1,l+b
.. .. → .. ..
. . ← . .
↓↑ &
-
.. ..
. .
Since the basis inverse has a rational representation, so has the current
∗
solution, and the entries of the vectors λE ∪S
˙ N and xBO are quotients
with common denominator d. We obtain
∗
µ̂j = d cj + ATE ∪S
˙ N ,j λ̂E ∪S
T
˙ N + 2DBO ,j x̂BO , (6.16)
∗ ∗
where λ̂E ∪S
˙ N and x̂BO contain the numerators of λE ∪S ˙ N and xBO ,
respectively. The values µj and µ̂j agree in sign because d is positive
by definition.
Usually many nonbasic variables qualify for entering the current basis,
in which case we have the freedom to choose one of them. The actual
choice is done by the pricing strategy according to some pivot rule.
6.4. Pricing Strategies 97
Testing all nonbasic variables in one iteration of the pivot step can be
very expensive, if the set of nonbasic variables N is large. This is the
case for optimization problems with high variables-to-constraints ratio,
which we have in our applications. The idea of partial pricing is to
maintain a set S of active variables, which is initially relatively small
(see below). The entering variable is chosen from the variables in S.
Only if no active variable qualifies for entering the current basis, the
remaining nonbasic variables are tested.
The intuition behind partial pricing is that S and V are always small
and that S is augmented only a few times. In this case, most pricing
98 Chapter 6. A Quadratic Programming Engine
steps are cheap, because they operate on a small set of active variables.
Furthermore, only a few runs through the whole set N of nonbasic vari-
ables to find the set V are needed. Exactly the same intuition lies behind
Clarkson’s LP algorithm [21]. It works in the dual setting (i.e. with
few variables and many constraints) and can easily be formulated as
a dual simplex method. The interpretation of Clarkson’s algorithm as
a dual partial pricing scheme has already been suggested by Adler and
Shamir [1].
Another way of speeding up the pricing step is to use fast floating point
arithmetic instead of exact arithmetic. The following scheme is based
on a similar scheme proposed by Gärtner [39] for linear programs, which
we adapted to our quadratic programming solver.
Using Dantzig’s rule, the obvious candidate for the entering variable is
the nonbasic variable xj with smallest value µ̃j . For the correctness of
6.4. Pricing Strategies 99
Note that the bounds in (6.18) can be exactly evaluated with floating
point arithmetic. This is important, because otherwise rounding errors
could occur in computing the error bounds. Since q is quite small, the
bounds are usually very good. A good choice for the floating point arith-
metic is the type Double as defined in the IEEE standard 754 for binary
floating-point arithmetic [55], which has p = 53 bits of precision. In C++
it is realized as the type double, which we use in our implementation
of filtered pricing.
with |δi | ≤ u, |εi | ≤ u, and |ηi | ≤ u for i ∈ [l]. Furthermore, if lu < 0.01,
then
Xl
x̃T y = x̃i yi (1+1.01 lΘi u)
i=1
holds, with |Θi | ≤ 1 for i ∈ [l]. Using this, the error of the inner product
in floating point arithmetic can be estimated as
Xl
| x̃T y − xT y | = (xi yi (1+δi )(1+1.01 lΘi u) − xi yi )
i=1
Xl
= x̃i yi (1+εi )(1.01 lΘi u + δi + 1.01 lδi Θi u)
i=1
Xl
≤ x̃i yi (1+u)(1.01 lu + u + 1.01 lu2 )
i=1
l
≤ max |x̃i yi | (1+u)(1.01 l2 u + lu + 1.01 l2 u2 )
i=1
l
≤ max |x̃i ⊗ yi | (1+u)2 (1.01 l2 u + lu + 1.01 l2 u2 )
i=1
l
≤ max |x̃i ⊗ yi | 1.01 l (l+1) u .
i=1
where y runs over all vectors we consider during the pricing. Secondly,
we get
l l l
max |x̃i ⊗ yi | ≤ max |x̃i | ⊗ max |yi | .
i=1 i=1 i=1
6.4.3 Implementations
The class template QPE pricing strategy is the base class for all pric-
ing strategies. It is parameterized with the representation class QPErep
of the ambient solver and optionally with a fast and possibly inexact
number type used in the filtered pricing.
The pointer to the ambient solver gives access to the original problem
and the current solution. The variable solverP is set, when the pricing
strategy becomes the current pricing strategy of the solver.
Any pricing strategy has to check the sign of µj for all nonbasic variables,
or at least for a subset of them. We provide two member functions
which compute µ̂j and µ̃j , respectively. One uses exact arithmetic over
the number type QPErep::ET, the other one uses the fast and possibly
inexact number type NT (as described in the previous section).
These member functions are called several times during the pricing step.
Thus, we provide a member function init NT that computes the floating
point approximations λ̃E ∪S ∗ ˜
˙ N , x̃BO , and d and stores the values for later
use by the member function mu NT. Pricing strategies using this function
have to call init NT at the beginning of their pricing member function.
Some pricing strategies maintain an internal status, e.g. the set of active
variables in case of partial pricing. The necessary initialization can be
6.4. Pricing Strategies 103
The pricing starts with finding the active variable xj ∈ S with smallest
value µ̃j using floating point arithmetic. If the exact check µ̂j < 0 suc-
ceeds, xj is returned. Otherwise the smallest µ̃j among the remaining
nonbasic variables is computed using floating point arithmetic a second
time. Again, if the exact check µ̂j < 0 succeeds, xj is the entering vari-
able. In this case, S is augmented with V , i.e. all nonbasic variables
104 Chapter 6. A Quadratic Programming Engine
with µ̃j < 0 found during the last scan are added to the set of active
variables. If no entering variable has been found so far, we have to verify
that really no entering variable exists. For each nonbasic variable, we
check µ̃j against the two bounds of Lemma 6.2. If this does not decide
the sign of µ̂j , we use exact arithmetic to determine it. In case a nega-
tive µ̂j is found, xj is returned, otherwise optimality has been certified.
The following pseudocode describes the partial pricing strategy.
The approximate values µ̃k and the exact values µ̂k are computed using
the base class’ member functions mu NT and mu, respectively.
To apply the error bounds of the floating point filter, we need the row
and column maxima of the quadratic program as defined in Lemma 6.2.
6.5. Conclusion 105
Just before the FOREACH loop in Algorithm 6.3, we compute RkA for
each k ∈ E ∪˙ SN and RkD for each k ∈ BO . The Cj s are updated with the
absolute values of A’s rows in E ∪˙ SN and D’s rows in BO . To avoid
repeated computations of the same values, we store all maxima com-
puted so far and keep track of the rows already handled. This scheme
avoids unnecessary computations, thus providing the needed maxima
efficiently at minimal cost.
6.5 Conclusion
Geometric Optimization
Problems in Cgal
7.1.1 Definition
(by size we mean |SP | + |SQ |). The distance between the two polytopes
is realized by a pair of points p and q lying on the convex hull of SP
and SQ , respectively, i.e. ||p − q|| = pd(P, Q). In general, neither the
support sets nor the realizing points are necessarily unique.
The underlying solver can cope with all kinds of input, e.g. P and Q
may be in non-convex position or points may occur more than once.
The algorithm computes a pair of support sets SP and SQ and the
corresponding realizing points p and q.
7.1.2 Solution
(PD) minimize xT C T C x
Pr
subject to xi = 1
Pi=1
n (7.1)
i=r+1 xi = 1
x ≥ 0,
with C = (p1 , . . . , pr ,−q1 , . . . ,−qs ). Then the support sets are deter-
mined by the positive x∗i s, namely
The realizing points are convex combinations of the given points, i.e.
r
X
p= x∗i pi ,
i=1
s
X
q= x∗i+r qi .
i=1
7.1.3 Implementation
Matrix A in (7.1) has two rows of length n. The first row contains
a block of r ones, followed by a block of s zeros. The second row contains
7.1. Polytope Distance 109
the same blocks with ones and zeros swapped. Since A is accessed
column-wise, we store it as a vector of C-arrays of length 2. Since b
is the 1-vector and c the 0-vector, we represent them with a special
iterator referring always to the same constant value.
// data members
Point_it points; // iterator to C
int i; // row index
int j; // column index
public:
PD_D_row_iterator( Point_it it, int row)
110 Chapter 7. Geometric Optimization Problems in Cgal
// data members
Point_it points; // iterator to C
int i; // row index
public:
PD_D_iterator( Point_it it) : points( it), i( 0) { }
Row_it operator * ( ) { return Row_it( points, i); }
// ...
};
The primal version of the polytope distance problem we use here has
the special properties of a symmetric objective matrix and no inequality
constraints. The following class template collects all types needed by
the QPE to solve (7.1).
7.2.1 Definition
The underlying algorithm can cope with all kinds of input, e.g. P may
be empty or points may occur more than once. The algorithm computes
a support set S together with the center and the (squared) radius of the
smallest enclosing sphere.
7.2.2 Solution
7.2.3 Implementation
The smallest enclosing ball problem has the special properties of a sym-
metric objective matrix and no inequality constraints. The following
class template collects all types needed by the QPE to solve (7.3).
7.3.1 Definition
The underlying algorithm can cope with all kinds of input, e.g. P may
be empty or points may occur more than once. The algorithm computes
a support set S together with the center and the (squared) radii of the
smallest enclosing annulus.
7.3.2 Solution
Then the values of the dual variables determine the solution to the
smallest enclosing annulus problem. Let A−1 B be the lower left part of
the final basis inverse (cf. Section 6.3.1). The center c∗ is obtained by
r2 = α∗ + ||c∗ ||2 ,
R2 = β ∗ + ||c∗ ||2 .
7.3.3 Implementation
The dual version of the smallest enclosing annulus problem we use here
has the special properties of a linear objective function and no inequality
constraints. The following class template collects all types needed by
the QPE to solve (7.4).
7.4 Conclusion
Experimental Results
As our major test problem, we chose the smallest enclosing ball problem,
because there the largest number of competing implementations was
available to us. We performed extensive tests, and compared the results
to the ones obtained using the other codes (including the QP solver of
CPLEX).
great care has been taken to ensure runtime efficiency (see last but one
chapter).
Most tests have been performed with pseudo-random input, i.e. the
coordinates were chosen as the lower-order 24 bits of the pseudo-random
numbers generated by the function random from the C++ standard
library. It uses a non-linear additive feedback random number gen-
erator with a very large period, which is approximately 16 (231 −1).
Since random does not use a linear congruential generator, it is not sub-
ject to ‘non-random’ effects as described in [41], as far as we know. For
smallest enclosing ball, annulus, and ellipse, we further have tested with
degenerate inputs, sets of points lying exactly or almost on a circle or
sphere.
The three types of arithmetics used are double (floating point only),
filtered (a standard floating point filter approach in case of Leda,
and our hybrid scheme in case of the QP method), as well as exact,
denoting full multiple precision number arithmetic.
In case of the QP solver, two pricing strategies are available, full and
partial. Partial pricing is almost always faster than full pricing, which
is therefore not tabulated for all tests.
1 In most cases, we averaged the runtimes over 100 runs. Only in a few cases,
where a single run needed several minutes to complete, we averaged over 10 runs.
8.2. Polytope Distance 119
random points
d 10,000 100,000
2 1.4 s 15.8 s
3 1.7 s 18.2 s
5 2.7 s 25.5 s
10 5.1 s 48.3 s
15 8.1 s 1:13 min
20 11.9 s 1:44 min
30 29.2 s 3:51 min
50 1:36 min 10:06 min
random points
Algorithm (d = 2)
10,000 100,000 1,000,000
Miniball (double) 4 ms 50 ms 646 ms
LEDA Min circle (double) 14 ms 223 ms 2.8 s
CGAL Min sphere (double) 13 ms 169 ms 1.7 s
CGAL Min circle (double) 45 ms 487 ms 4.6 s
QP Solver (partial,double) 14 ms 160 ms 1.6 s
QP Solver (full,double) 28 ms 331 ms 3.4 s
LEDA Min circle (filtered) 51 ms 561 ms 6.2 s
QP Solver (partial,filtered) 31 ms 327 ms 3.2 s
QP Solver (full,filtered) 44 ms 498 ms 5.5 s
QP Solver (partial,exact) 1.7 s 16.9 s 2:49 min
QP Solver (full,exact) 3.3 s 31.8 s
CGAL Min sphere (exact) 3.2 s 30.4 s
CGAL Min circle (exact) 5.3 s 52.2 s
points on circle
Algorithm (d = 2)
6,144 13,824 6,144 (perturbed)
Miniball (double) <1 ms 5 ms 5 ms
CGAL Min circle (double) 10 ms 29 ms
LEDA Min circle (filtered) 1.27 s 3.1 s 6.5 s
QP Solver (partial,filtered) 412 ms 2.5 s 60 ms
QP Solver (full,filtered) 431 ms 4.8 s 110 ms
QP Solver (partial,exact) 416 ms 7.1 s 1.3 s
QP Solver (full,exact) 845 ms 23.7 s 4.3 s
CGAL Min sphere (exact) 423 ms 1.0 s 3.4 s
CGAL Min circle (exact) 894 ms 1.9 s 3.4 s
points on sphere
Algorithm (d = 3)
10,000 (perturbed)
Miniball (double) 19 ms
QP Solver (partial,filtered) 123 ms
QP Solver (full,filtered) 127 ms
QP Solver (partial,exact) 10.9 s
QP Solver (full,exact) 11.6 s
CGAL Min sphere (exact) 23.8 s
the exact QP solver is faster than Leda’s filtered approach, and much
faster than all exact versions. An interesting phenomenon occurs when
one slightly perturbs the points, so that they are no longer cocircular.
The QP solver becomes much faster because the perturbation already
suffices to make the built-in error bounds work effectively: to verify
optimality in the last iteration, no exact checks are necessary anymore,
while they extensively happen for the non-perturbed degenerate input.
In d = 3, we have chosen a point set almost on a sphere, obtained by
tiling the sphere according to longitude and latitude values. The only
double code still able to handle this problem is Miniball; our filtered
approach, however, is only by a factor of six slower, while the exact
versions are out of the game (Table 8.4).
We also have results for higher dimensions (Tables 8.5, 8.6, and 8.7).
These show how the missing ‘curse of dimensionality’ in the QP solver
compensates for the effect of exact arithmetic, so that our exact solver
is already faster than the inexact solver Miniball in dimension 20, for
10,000 points. (For n = 100,000 we are not far off, but for 1,000,000
points we reach the machine’s memory limit). Note that the table entry
is blank for most pure double versions in higher dimensions, which
means that the results were too inaccurate.
Probably most interesting is that problems up to dimension 100 can
routinely be handled, and even for 10,000 points in d = 200, we only
need about three and a half minutes (Table 8.8). It should be noted
that these results hold for random points, where we observed that the
number of points that determine the final ball is quite small (much
smaller than the dimension itself). In this situation, the QP-bases the
algorithm needs to handle are relatively small, which makes the exact
arithmetic fast.
Finally, we have performed comparisons with the QP solver of CPLEX
(an interior point code) using formulation (3.7) on page 41, showing
that such codes are not competitive in our scenario (Table 8.9). It is
interesting to note that the performance of the CPLEX solver mainly
depends on the product of n and d (which is closely related to the
number of nonzeros in the problem description), while we pay a penalty
for larger values of d. However, the results show that our exact method
is still superior to CPLEX for dimensions below 30, which is the range
of dimensions our code is made for. It is clear that CPLEX’s method
will become superior as d goes higher up.
122
random points (10,000)
Algorithm
d 2 3 5 10 15 20
Miniball (double) 4 ms 7 ms 16 ms 57 ms 168 ms 1.0 s
CGAL Min sphere (double) 13 ms 18 ms
QP Solver (partial,double) 14 ms 17 ms 26 ms 62 ms
QP Solver (partial,filtered) 31 ms 41 ms 74 ms 219 ms 408 ms 847 ms
QP Solver (partial,exact) 1.7 s 2.1 s 3.4 s 7.2 s 11.5 s 17.1 s
CGAL Min sphere (exact) 3.2 s 6.1 s 15.7 s 1:07 min 3:40 min
random points
Algorithm
100,000 (d = 3) 10,000 (d = 30)
CPLEX (double) 12.8 s 10.2 s
QP Solver (partial,filtered) 671 ms 6.8 s
We have tested our QP solver against the exact solver described in [39]
which employs basically the same combination of exact and floating
point arithmetic (denoted as LP simplex in the tables). However, as
the results show, our solver is even faster than the dedicated LP solver.
This is due to the fact that we invested much effort in optimizing the
code.
124 Chapter 8. Experimental Results
random points (d = 2)
Algorithm
10,000 100,000
QP Solver (partial,double) 7 ms 115 ms
QP Solver (full,double) 31 ms 416 ms
LEDA Min annulus (double) 2.2 s 28.7 s
QP Solver (partial,filtered) 20 ms 192 ms
QP Solver (full,filtered) 41 ms 546 ms
LP Simplex (partial,filtered) 246 ms 2.4 s
LEDA Min annulus (filtered) 19.6 s 3:52 min
QP Solver (partial,exact) 4.0 s 48.1 s
QP Solver (full,exact) 13.8 s 2:20 min
points on circle (d = 2)
Algorithm
6,144 13,824 6,144 (perturbed)
QP Solver (partial,filtered) 0.8 s 2.1 s 24 ms
QP Solver (full,filtered) 0.8 s 2.1 s 38 ms
LP Simplex (partial,filtered) 0.9 s 1.7 s 159 ms
LEDA Min annulus (filtered) 2.8 s 6.5 s
QP Solver (partial,exact) 0.8 s 2.1 s 3.3 s
QP Solver (full,exact) 4.1 s 13.5 s 14.4 s
points on sphere (d = 3)
Algorithm
10,000 (perturbed)
QP Solver (partial,double) 39 ms
QP Solver (full,double) 58 ms
QP Solver (partial,filtered) 88 ms
QP Solver (full,filtered) 102 ms
LP Simplex (partial,filtered) 311 ms
QP Solver (partial,exact) 18.2 s
QP Solver (full,exact) 29.5 s
As before, the filtered approach is much faster than the exact approach,
and comparable to pure floating point solutions. Unlike in the case
of smallest enclosing ball, double versions are still able to compute the
correct result in higher dimensions, which indicates that true QP is more
challenging for the numerics than LP (Tables 8.10, 8.13, and 8.14). We
used the dual version (3.9) on page 43 for our tests, which turned out
to be always faster than the primal version (3.8) on page 42. The more
involved pivot step of the primal version (due to the handling of the
slack variables) and a higher number of iterations resulted in a slow
down by a factor of at least two.
Table 8.15 shows the results of our Cgal implementation for smallest
enclosing ellipse problems. We tested the method on random point sets
of different size as well as on degenerate sets consisting of points lying
on or almost on a circle (described above). Note, Cgal Min circle
implements the same method of Welzl for the smallest enclosing circle
problem. A comparison of the runtimes here with those in Tables 8.2
and 8.3 shows the following. As expected, the much more involved
8.6 Conclusion
Our major test problem, namely the smallest enclosing ball problem,
was used to compare our solver with other implementations. Among the
competitors were mathematical programming codes as well as dedicated
geometric algorithms.
Almost always the partial filtered pricing strategy was best. Using this
combination of exact and floating point arithmetic yields very good
runtimes. They are not far behind pure floating point implementations,
but much faster than codes using exact arithmetic for all numerical
operations.
Applications
Chapter 9
Two Applications
This chapter presents two applications, where our method was used
to solve ‘real-world’ problems. As part of a joint project with a big
Swiss bank, our quadratic programming solver was used to solve a large
portfolio optimization problem. In another cooperation with a German
company developing medical navigation systems, the smallest enclosing
annulus implementation was used to calibrate the tip of medical probes.
At CSAM, they tried to solve this problem using CPLEX. It was neither
able to find a feasible solution nor to show infeasibility of the quadratic
program. CPLEX just terminated after some amount of time, indicat-
ing that it detected ‘cycling’. Further details, e.g. version and parameter
settings of CPLEX and the particular reason for its failure, were not
available to us.
9.1.3 Results
The problem finally feeded into the solver consisted of 165 original and
211 slack variables, resulting in a total of 371 variables (the preliminary
version of the solver used here was not able to handle slack variables
implicitly). It contained 271 constraints, devided in 60 equality and
211 inequality constraints.
Our solver (using full exact pricing) needed an overall runtime of 1 hour
and 53 minutes. After 395 iterations in phase I, it returned that the
problem is INFEASIBLE. We checked the solution and found it to be
correct.
Since we were able to ‘solve’ the problem, our approach seems promis-
ing in this application domain. Although the computation took quite a
while, future versions using partial filtered pricing on up-to-date hard-
ware will need only a fraction of the observed runtime. At least we
showed that our exact solver might be used as a tool in portfolio opti-
mization.
1 Actually, the cooperation with FIT started with a project on the image regis-
9.2.3 Solution
StylusCalibration(P ):
a := ma(P )
WHILE width(a) > bound DO
P := P \ {p ∈ P | p is a ‘most extreme’ outlier}
a := ma(P )
END
RETURN center(a)
The navigation system has two kind of styli. The difference lies in
the length of the pointer, resulting in different length of the offset vec-
tors. The short version has an offset of about 12cm, the long version of
about 19cm.
For each stylus to calibrate, we acquired between 5,000 and 10,000 posi-
tion samples. Usually one or two iterations in Algorithm 9.1 were suf-
ficient to obtain an annulus of width smaller than 2mm (short version)
and 3mm (long version). The annulus’ center was then used to compute
the offset vector for each point in the final set P . Averaging over all
these vectors gave the desired offset vector for the stylus.
9.2. Stylus Calibration 137
— A — of LP, 17
access to original problem, 83–84 of QP, 17, 21–22
active variable, 97, 102, 103, 104 basis inverse, 81, 82, 87–95, 96
algorithm implementation, 94–95
PartialFilteredPricing, rational representation,
104, 105 88–89, 94, 96
PartialPricing, 97 update, 89–94
SmEll, 48, 49, 50, 52, 59 basis matrix, 18, 24, 31, 87, 88
StylusCalibration, 136 boundary points, 47, 48, 49, 59
annulus bounding volume heuristic, 4
smallest enclosing, 4, 42–43,
113–114, 123–126, 135 — C —
application, 131–137
Cartesian (class), 71, 72, 78
financial, 131–133
Cartesian representation, 71–72,
medical, 133–137
73
asset management, 131
Cgal, iv, vi, vii, viii, ix, 2, 3, 9,
10, 59, 63–80, 81, 86,
— B — 105, 107, 111, 114, 115,
ball 117, 118, 119, 126
smallest enclosing, 4, 6, 7, basic library, 70, 74–79
39–41, 45, 83, 111–112, Cartesian representation,
119–123 71–72, 73
basic feasible solution, 17, 18, 21, circulator, 79
22 core library, 70
basic library, 3, 70, 74–79 geometric kernel, 69, 71–74
basic solution, 21–23 homogeneous representation,
basic variable, 17, 21, 22, 86, 89 71–72, 73
basis, 17, 18, 31, 88, 89, 96, 97 library structure, 69–70
150 Index
exact arithmetic, 86, 98, 99, 102, hoping for the best, 7
104 hyperplane
exact number type, 86, 94 optimal separating, 5, 43
expecting the best and coping
with the worst, 7 — I —
expecting the worst, 7
image registration, 134
experimental results, 117–127
implementation
basis inverse, 94–95
— F — pricing strategy, 101–105
feasible solution, 16, 21, 22 implicit representation
filtered pricing, 98–101 of objective matrix, 83, 109,
financial application, 131–133 112
floating point filter, 86, 99, 104 in-ellipse test, 50–51
function |R| = 3, 52
convex hull points 2, 78, |R| = 4, 52–57
79 |R| = 5, 58
ellipsoid, 46 in-ellipsoid test, 50
objective, 16, 17, 18, 47, 88, inequality constraint, 110, 112
97 -, see also slack variable
handling of -s, 31–34
— G — inexact number type, 102
intraoperative navigation system,
Galia, 2, 63
133
generalized simplex method, 87
irrational ellipse, 57
generic programming, 65, 66–69,
iterator, 83, 84, 105
79, 81, 105
geometric kernel, 3, 69, 71–74
representation class, 72 — K —
geometric optimization, 3, 6, 7 Karush-Kuhn-Tucker conditions,
scenario, 5–6 20–21, 39
for QP, 20
— H — for UQP, 20
kernel, 3
handling of
geometric, 3
degeneracies, 34–35
KKT, see Karush-Kuhn-Tucker
inequality constraints, 31–34
conditions
heuristic
move-to-front, 50
Homogeneous (class), 71, 72 — L —
homogeneous representation, Lagrange multipliers, 20
71–72, 73 lazy evaluation, 105
152 Index
— N — — P —
navigation system partial filtered pricing, 103–105
intraoperative, 133 partial pricing, 97–98, 102
neurosurgery, 133 PartialFilteredPricing
nonbasic variable, 17, 18, 21, 22, (algorithm), 104, 105
89, 95, 96, 97, 98, 102, PartialPricing (algorithm),
103, 104 97
nondegenerate quadratic pivot rule, 96
program, 19 pivot step, 18, 23–31
normalized pricing, 24–25, 86
conic, 51 ratio test, 25–86
ellipse, 51 step 1, 25–27
number type, 82, 102 step 2, 27–28
exact, 86, 94 step 3, 28–30
inexact, 102 update, 31
Index 153
point linear, 15
boundary -s, 47, 48, 49, 59 object-oriented, 65–66, 69,
realizing -s, 108 80, 105
support -s, 47, 50, 107, 111, quadratic, 15, 35, 98, 105
113
Point 2 (class), 71, 78 — Q —
Polygon 2 (class), 78 Q-pivoting, 94
polytope distance, 3, 37–39, 83, QP, see quadratic programming
107–111, 112, 119 QP-basis, 21–22
dual version, 38, 111 size of, 22–23
primal version, 37, 110 QPE, see quadratic programming
sparse version, 38 engine
Polytope distance d (class), QPE basis inverse (class), 94
107 QPE full exact pricing (class),
portfolio optimization, 131–133 103
multi-period, 131, 132 QPE full filtered pricing
precision problem, 1 (class), 103
pricing, 18, 24–25, 86 QPE partial exact pricing
pricing strategy, 81, 82, 95–105 (class), 103
filtered pricing, 98–101 QPE partial filtered
implementation, 101–105 pricing (class), 103
partial filtered pricing, QPE pricing strategy (class),
103–105 101, 102
partial pricing, 97–98, 102 QPE solver (class), 82, 83, 85,
primal version 94, 101
polytope distance, 37, 110 QPErep (class), 83, 84, 86
smallest enclosing annulus, quadratic program, 15–16, 17,
42, 114, 126 35, 81, 86, 88, 104
primitive operation, 3, 8, 45, degenerate, 86
50–58, 59 nondegenerate, 19
program standard form, 16–17
convex, 46 unconstrained, 21
linear, 15, 17, 81, 88, 89, 94, quadratic programming, 3, 15,
98 35, 98, 105
quadratic, 15–16, 17, 35, 81, basis, 17, see QP-basis
86, 88, 104 solver, 3
programming quadratic programming engine,
convex, 8, 45 81–105
generic, 65, 66–69, 79, 81, basis inverse, 81, 82, 87–95
105 implementation, 94–95
154 Index
compile time tags, 84–86, 94, basic, 17, 21, 22, 86, 89
105 entering, 18, 86, 89, 90, 95,
exact arithmetic, 86 97, 98, 99, 102, 103, 104
quadratic programming, 3 leaving, 18, 90, 103
standard, 5–6 nonbasic, 17, 18, 21, 22, 89,
symbolic perturbation, 86–87 95, 96, 97, 98, 102, 103,
sparse version 104
polytope distance, 38 original, 89, 90
smallest enclosing ball, 41, slack, 16, 17, 89, 90
121 variables-to-constraints ratio, 97
sparsity conditions, 5
standard form — W —
of quadratic program, 16–17
standard solver, 5–6 Welzl’s method, 3, 8, 9, 45,
Stl, 67, 68, 75, 76, 79, 81 47–50, 58, 59
stylus calibration, 133–137
StylusCalibration
(algorithm), 136
support points, 47, 50, 107, 111,
113
support set, 47, 58, 107, 108,
111, 112, 113
symbolic perturbation, 35, 86–87
symmetric objective matrix, 84,
85, 88, 110, 112
— T —
test environment, 117–118
traits class, 70, 76–79, 80, 82,
107, 111, 113
Triangulation 2 (class), 77
— U —
update, 18, 31
basis inverse, 89–94
— V —
variable
active, 97, 102, 103, 104
Curriculum Vitae
Education
1998 – 2002 Swiss Federal Institute of Technology Zurich /
Freie Universität Berlin, Germany
Ph.D. Studies in Computer Science
Candidate for Doctor of Technical Sciences
Experience