- various refactorings:

- mps reader is now derived from a model that allows to set
	  up and manipulate a program entrywise
	- old copying models removed
        - free models removed (they are utterly useless)
        - a() -> get_a() etc.
        - the solver can now solve problems with no variables :-)
- manual:
        - added maker pages
        - adapted to above changes
This commit is contained in:
Bernd Gärtner 2007-04-11 15:48:19 +00:00
parent ea71b8eaa1
commit a2712eb429
64 changed files with 2211 additions and 3092 deletions

15
.gitattributes vendored
View File

@ -1834,12 +1834,6 @@ QP_solver/doc_tex/QP_solver/first_qp.eps -text svneol=unset#application/postscri
QP_solver/doc_tex/QP_solver/first_qp.fig -text svneol=unset#application/octet-stream
QP_solver/doc_tex/QP_solver/first_qp.gif -text svneol=unset#image/gif
QP_solver/doc_tex/QP_solver/first_qp.pdf -text svneol=unset#application/pdf
QP_solver/doc_tex/QP_solver_ref/Free_linear_program.tex -text
QP_solver/doc_tex/QP_solver_ref/Free_linear_program_from_iterators.tex -text
QP_solver/doc_tex/QP_solver_ref/Free_linear_program_from_pointers.tex -text
QP_solver/doc_tex/QP_solver_ref/Free_quadratic_program.tex -text
QP_solver/doc_tex/QP_solver_ref/Free_quadratic_program_from_iterators.tex -text
QP_solver/doc_tex/QP_solver_ref/Free_quadratic_program_from_pointers.tex -text
QP_solver/doc_tex/QP_solver_ref/Linear_program.tex -text
QP_solver/doc_tex/QP_solver_ref/Linear_program_from_iterators.tex -text
QP_solver/doc_tex/QP_solver_ref/Linear_program_from_mps.tex -text
@ -1847,15 +1841,19 @@ QP_solver/doc_tex/QP_solver_ref/Linear_program_from_pointers.tex -text
QP_solver/doc_tex/QP_solver_ref/MPSFormat.tex -text
QP_solver/doc_tex/QP_solver_ref/Nonnegative_linear_program.tex -text
QP_solver/doc_tex/QP_solver_ref/Nonnegative_linear_program_from_iterators.tex -text
QP_solver/doc_tex/QP_solver_ref/Nonnegative_linear_program_from_mps.tex -text
QP_solver/doc_tex/QP_solver_ref/Nonnegative_linear_program_from_pointers.tex -text
QP_solver/doc_tex/QP_solver_ref/Nonnegative_quadratic_program.tex -text
QP_solver/doc_tex/QP_solver_ref/Nonnegative_quadratic_program_from_iterators.tex -text
QP_solver/doc_tex/QP_solver_ref/Nonnegative_quadratic_program_from_mps.tex -text
QP_solver/doc_tex/QP_solver_ref/Nonnegative_quadratic_program_from_pointers.tex -text
QP_solver/doc_tex/QP_solver_ref/Quadratic_program.tex -text
QP_solver/doc_tex/QP_solver_ref/Quadratic_program_from_mps.tex -text
QP_solver/doc_tex/QP_solver_ref/Quadratic_program_from_pointers.tex -text
QP_solver/doc_tex/QP_solver_ref/Sparse_linear_program_from_mps.tex -text
QP_solver/doc_tex/QP_solver_ref/Sparse_quadratic_program_from_mps.tex -text
QP_solver/doc_tex/QP_solver_ref/make_linear_program_from_iterators.tex -text
QP_solver/doc_tex/QP_solver_ref/make_nonnegative_linear_program_from_iterators.tex -text
QP_solver/doc_tex/QP_solver_ref/make_nonnegative_quadratic_program_from_iterators.tex -text
QP_solver/doc_tex/QP_solver_ref/make_quadratic_program_from_iterators.tex -text
QP_solver/doc_tex/QP_solver_ref/print_linear_program.tex -text
QP_solver/doc_tex/QP_solver_ref/print_nonnegative_linear_program.tex -text
QP_solver/doc_tex/QP_solver_ref/print_nonnegative_quadratic_program.tex -text
@ -1876,6 +1874,7 @@ QP_solver/examples/QP_solver/unboundedness_certificate.cpp -text
QP_solver/maintainer -text
QP_solver/test/QP_solver/create_test_solver_cin -text
QP_solver/test/QP_solver/debug_bug.cpp -text
QP_solver/test/QP_solver/test_empty_qp.cpp -text
QP_solver/test/QP_solver/test_random_qp.cpp -text
QP_solver/test/QP_solver/test_solver.cout -text
Qt_widget/demo/Qt_widget/hellosegment.vcproj eol=crlf

View File

@ -1,51 +0,0 @@
\begin{ccRefClass}{Free_linear_program<NT>}
\ccInclude{CGAL/QP_models.h}
\ccDefinition
An object of class \ccRefName\ describes a linear program of the form
%%
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b
\end{eqnarray*}
%%
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$. The term ``free'' refers
to the fact that there are no explicit bounds on the variables.
Here,
\begin{itemize}
\item $A$ is an $m\times n$ matrix (the constraint matrix),
\item $b$ is an $m$-dimensional vector (the right-hand side),
\item $\qprel$ is an $m$-dimensional vector of relations
from $\{\leq, =, \geq\}$,
\item $c$ is an $n$-dimensional vector (the linear objective
function), and
\item $c_0$ is a constant.
\end{itemize}
This class copies the program data from given iterator ranges;
if you only need to wrap existing iterators, you may use the classes
\ccc{Free_linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>} and \ccc{Free_linear_program_from_pointers<NT>}).
\ccIsModel
\ccc{LinearProgramInterface}
\ccCreation
\ccIndexClassCreation
\ccCreationVariable{qp}
\ccConstructor{template <A_it, B_it, R_it, C_it>
Free_linear_program(int n, int m,
const A_it& a,
const B_it& b,
const R_it& r,
const C_it& c,
const std::iterator_traits<C_it>value_type& c0 = 0
)}{constructs \ccVar\ from given input iterators and the constant \ccc{c0}. The passed iterators are merely stored, no copying of the program data takes place. }
\ccSeeAlso
\ccc{Free_linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>}\\
\ccc{Free_linear_program_from_pointers<NT>}
\end{ccRefClass}

View File

@ -1,50 +0,0 @@
\begin{ccRefClass}{Free_linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>}
\ccInclude{CGAL/QP_models.h}
\ccDefinition
An object of class \ccRefName\ describes a linear program of the form
%%
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b
\end{eqnarray*}
%%
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$. The term ``free'' refers
to the fact that there are no explicit bounds on the variables.
Here,
\begin{itemize}
\item $A$ is an $m\times n$ matrix (the constraint matrix),
\item $b$ is an $m$-dimensional vector (the right-hand side),
\item $\qprel$ is an $m$-dimensional vector of relations
from $\{\leq, =, \geq\}$,
\item $c$ is an $n$-dimensional vector (the linear objective
function), and
\item $c_0$ is a constant.
\end{itemize}
This class is simply a wrapper for existing iterators, and it does not
copy the program data (if you need a copy, you may use the class
\ccc{Free_linear_program<NT>}).
\ccIsModel
\ccc{LinearProgramInterface}
\ccCreation
\ccIndexClassCreation
\ccCreationVariable{lp}
\ccConstructor{Free_linear_program_from_iterators(int n, int m,
const A_it& a,
const B_it& b,
const R_it& r,
const C_it& c,
const std::iterator_traits<C_it>value_type& c0 = 0
)}{constructs \ccVar\ from given random-access iterators and the constant \ccc{c0}. The passed iterators are merely stored, no copying of the program data takes place. }
\ccSeeAlso
\ccc{Free_linear_program_from_pointers<NT>}\\
\ccc{Free_linear_program<NT>}
\end{ccRefClass}

View File

@ -1,41 +0,0 @@
\begin{ccRefClass}{Free_linear_program_from_pointers<NT>}
\ccInclude{CGAL/QP_models.h}
\ccDefinition
An object of class \ccRefName\ describes a linear program of the form
%%
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b
\end{eqnarray*}
%%
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$. The term ``free'' refers
to the fact that there are no explicit bounds on the variables.
Here,
\begin{itemize}
\item $A$ is an $m\times n$ matrix (the constraint matrix),
\item $b$ is an $m$-dimensional vector (the right-hand side),
\item $\qprel$ is an $m$-dimensional vector of relations
from $\{\leq, =, \geq\}$,
\item $c$ is an $n$-dimensional vector (the linear objective
function), and
\item $c_0$ is a constant.
\end{itemize}
This class specializes the class
\ccc{Free_linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>} for the case where all iterators are of type
\ccc{NT**} (for
$A$) and \ccc{NT*} otherwise, for some number type \ccc{NT}.
The class is simply a wrapper for
existing pointers, and it does not copy the program data (if you need
a copy, you may use the class \ccc{Free_linear_program<NT>}).
\ccIsModel
\ccc{LinearProgramInterface}
\ccSeeAlso
\ccc{Free_linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>}\\
\ccc{Free_linear_program<NT>}
\end{ccRefClass}

View File

@ -1,54 +0,0 @@
\begin{ccRefClass}{Free_quadratic_program<NT>}
\ccInclude{CGAL/QP_models.h}
\ccDefinition
An object of class \ccRefName\ describes a convex quadratic program of the form
%%
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & x^{T}Dx+c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b
\end{eqnarray*}
%%
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$. The term ``free'' refers
to the fact that there are no explicit bounds on the variables.
Here,
\begin{itemize}
\item $A$ is an $m\times n$ matrix (the constraint matrix),
\item $b$ is an $m$-dimensional vector (the right-hand side),
\item $\qprel$ is an $m$-dimensional vector of relations
from $\{\leq, =, \geq\}$,
\item $D$ is a symmetric positive-semidefinite $n\times n$ matrix (the
quadratic objective function),
\item $c$ is an $n$-dimensional vector (the linear objective
function), and
\item $c_0$ is a constant.
\end{itemize}
This class copies the program data from given iterator ranges;
if you only need to wrap existing iterators, you may use the classes
\ccc{Free_quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>} and \ccc{Free_quadratic_program_from_pointers<NT>}).
\ccIsModel
\ccc{QuadraticProgramInterface}
\ccCreation
\ccIndexClassCreation
\ccCreationVariable{qp}
\ccConstructor{template <A_it, B_it, R_it, D_it, C_it>
Free_quadratic_program(int n, int m,
const A_it& a,
const B_it& b,
const R_it& r,
const D_it& d,
const C_it& c,
const std::iterator_traits<C_it>value_type& c0 = 0
)}{constructs \ccVar\ from given input iterators and the constant \ccc{c0}. The passed iterators are merely stored, no copying of the program data takes place. }
\ccSeeAlso
\ccc{Free_quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
\ccc{Free_quadratic_program_from_pointers<NT>}
\end{ccRefClass}

View File

@ -1,53 +0,0 @@
\begin{ccRefClass}{Free_quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}
\ccInclude{CGAL/QP_models.h}
\ccDefinition
An object of class \ccRefName\ describes a convex quadratic program of the form
%%
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & x^{T}Dx+c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b
\end{eqnarray*}
%%
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$. The term ``free'' refers
to the fact that there are no explicit bounds on the variables.
Here,
\begin{itemize}
\item $A$ is an $m\times n$ matrix (the constraint matrix),
\item $b$ is an $m$-dimensional vector (the right-hand side),
\item $\qprel$ is an $m$-dimensional vector of relations
from $\{\leq, =, \geq\}$,
\item $D$ is a symmetric positive-semidefinite $n\times n$ matrix (the
quadratic objective function),
\item $c$ is an $n$-dimensional vector (the linear objective
function), and
\item $c_0$ is a constant.
\end{itemize}
This class is simply a wrapper for existing iterators, and it does not
copy the program data (if you need a copy, you may use the class
\ccc{Free_quadratic_program<NT>}).
\ccIsModel
\ccc{QuadraticProgramInterface}
\ccCreation
\ccIndexClassCreation
\ccCreationVariable{qp}
\ccConstructor{Free_quadratic_program_from_iterators(int n, int m,
const A_it& a,
const B_it& b,
const R_it& r,
const D_it& d,
const C_it& c,
const std::iterator_traits<C_it>value_type& c0 = 0
)}{constructs \ccVar\ from given random-access iterators and the constant \ccc{c0}. The passed iterators are merely stored, no copying of the program data takes place. }
\ccSeeAlso
\ccc{Free_quadratic_program_from_pointers<NT>}\\
\ccc{Free_quadratic_program<NT>}
\end{ccRefClass}

View File

@ -1,43 +0,0 @@
\begin{ccRefClass}{Free_quadratic_program_from_pointers<NT>}
\ccInclude{CGAL/QP_models.h}
\ccDefinition
An object of class \ccRefName\ describes a convex quadratic program of the form
%%
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & x^{T}Dx+c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b
\end{eqnarray*}
%%
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$. The term ``free'' refers
to the fact that there are no explicit bounds on the variables.
Here,
\begin{itemize}
\item $A$ is an $m\times n$ matrix (the constraint matrix),
\item $b$ is an $m$-dimensional vector (the right-hand side),
\item $\qprel$ is an $m$-dimensional vector of relations
from $\{\leq, =, \geq\}$,
\item $D$ is a symmetric positive-semidefinite $n\times n$ matrix (the
quadratic objective function),
\item $c$ is an $n$-dimensional vector (the linear objective
function), and
\item $c_0$ is a constant.
\end{itemize}
This class specializes the class
\ccc{Free_quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>} for the case where all iterators are of type
\ccc{NT**} (for
$A$ and $D$) and \ccc{NT*} otherwise, for some number type \ccc{NT}.
The class is simply a wrapper for
existing pointers, and it does not copy the program data (if you need
a copy, you may use the class \ccc{Free_quadratic_program<NT>}).
\ccIsModel
\ccc{QuadraticProgramInterface}
\ccSeeAlso
\ccc{Free_quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
\ccc{Free_quadratic_program<NT>}
\end{ccRefClass}

View File

@ -4,7 +4,7 @@
A model of \ccRefName\ describes a linear program of the form
%%
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
\mbox{(LP)}& \mbox{minimize} & c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b, \\
& & l \leq x \leq u
\end{eqnarray*}
@ -25,13 +25,14 @@ $x$,
\item $c_0$ is a constant.
\end{itemize}
The description is given by appropriate \emph{random-access}
iterators over the program data, see below. The program therefore
comes in \emph{dense} representation which includes zero entries.
\ccHasModels
\ccc{CGAL::Linear_program<NT>}\\
\ccc{CGAL::Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
\ccc{CGAL::Linear_program_from_pointers<NT>}\\
\ccc{CGAL::Linear_program<NT>}\\
\ccc{CGAL::Free_linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
\ccc{CGAL::Free_linear_program_from_pointers<NT>}\\
\ccc{CGAL::Free_linear_program<NT>}\\
\ccc{CGAL::Linear_program_from_mps<NT>}\\
\ccTypes
@ -69,54 +70,56 @@ $x$,
\ccCreationVariable{qp}
\ccMethod{int n() const;}{returns the number $n$ of variables (number
\ccMethod{int get_n() const;}{returns the number $n$ of variables (number
of columns of $A$) in \ccVar.}
\ccMethod{int m() const;}{returns the number $m$ of constraints
\ccMethod{int get_m() const;}{returns the number $m$ of constraints
(number of rows of $A$) in \ccVar.}
\ccMethod{const A_iterator& a() const;}{returns an iterator over the columns
\ccMethod{A_iterator get_a() const;}{returns an iterator over the columns
of $A$. For $j=0,\ldots,n-1$, $\ccc{*(a()+j)}$ is a random access
iterator for column $j$.}
\ccMethod{const B_iterator& b() const;}{returns an iterator over the entries
\ccMethod{B_iterator get_b() const;}{returns an iterator over the entries
of $b$.}
\ccMethod{const R_iterator& r() const;}{returns an iterator over the entries
\ccMethod{R_iterator get_r() const;}{returns an iterator over the entries
of $\qprel$. The value \ccc{CGAL::SMALLER} stands
for $\leq$, \ccc{CGAL::EQUAL} stands for $=$, and \ccc{CGAL::LARGER}
stands for $\geq$.}
\ccMethod{const FL_iterator& fl() const;}{returns an iterator over the
\ccMethod{FL_iterator get_fl() const;}{returns an iterator over the
existence of the lower bounds $l_j, j=0,\ldots,n-1$. If
$\ccVar.\ccc{fl()}[j]=true$, the variable $x_j$ has a lower
bound, otherwise it has no lower bound.}
\ccMethod{const L_iterator& l() const;}{returns an iterator for the
\ccMethod{L_iterator get_l() const;}{returns an iterator for the
entries of $l$. If $\ccVar.\ccc{fl()}[j]=\ccc{false}$, the value
$\ccVar.\ccc{l()}[j]$ is not accessed.}
\ccMethod{const FU_iterator& fu() const;}{returns an iterator over the
\ccMethod{FU_iterator get_fu() const;}{returns an iterator over the
existence of the upper bounds $u_j, j=0,\ldots,n-1$. If
$\ccVar.\ccc{fu()}[j]=true$, the variable $x_j$ has an upper
bound, otherwise it has no upper bound.}
\ccMethod{const U_iterator& u() const;}{returns an iterator over the
\ccMethod{U_iterator get_u() const;}{returns an iterator over the
entries of $u$. If $\ccVar.\ccc{fu()}[j]=\ccc{false}$, the value
$\ccVar.\ccc{u()}[j]$ is not accessed.}
\ccMethod{const C_iterator& c() const;}{returns an iterator over the entries
\ccMethod{C_iterator get_c() const;}{returns an iterator over the entries
of $c$.}
\ccMethod{const std::iterator_traits<C_iterator>::value_type& c0() const;}{returns the constant
term $c_0$ of the objective function.}
\ccMethod{std::iterator_traits<C_iterator>::value_type c0() const;}
{returns the constant term $c_0$ of the objective function.}
\ccRequirements
The value types of all iterator types (nested iterator types,
respectively, for \ccc{A_iterator} and \ccc{D_iterator}) must be
respectively, for \ccc{A_iterator}) must be
convertible to some common \ccc{IntegralDomain} \ccc{ET}.
\ccSeeAlso
\ccc{QuadraticProgramInterface}\\
\ccc{NonnegativeQuadraticProgramInterface}\\
\ccc{NonnegativeLinearProgramInterface}
\end{ccRefConcept}

View File

@ -6,7 +6,7 @@
An object of class \ccRefName\ describes a linear program of the form
%%
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
\mbox{(LP)}& \mbox{minimize} & c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b, \\
& & l \leq x \leq u
\end{eqnarray*}
@ -27,40 +27,71 @@ $x$,
\item $c_0$ is a constant.
\end{itemize}
This class copies the program data from given iterator ranges; this
is useful if the iterators that you have are not random-access.
The time taken to copy the data is $\Theta(nm+n^2)$, though, even if
the program description is very sparse. Usually,
you only need to wrap existing (random-access)
iterators, and then you may use the classes
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>} and \ccc{Linear_program_from_pointers<NT>}).
This class allows you to build your program entry by entry, using
the set-methods below. If you only need to wrap existing (random-access)
iterators, then you may use the classes
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>} and \ccc{Linear_program_from_pointers<NT>}). If you want
to read a linear program in \ccc{MPSFormat} from a file, please use
the model \ccc{Linear_program_from_mps<NT>}.
\ccIsModel
\ccc{LinearProgramInterface}
\ccTypes
\ccNestedType{NT}{The number type of the program entries.}
\ccCreation
\ccIndexClassCreation
\ccCreationVariable{lp}
The following constructor is a template, so you can provide input
iterators of any types.
\ccConstructor{
Linear_program(CGAL::Comparison_result default_r = CGAL::EQUAL);}
{constructs a linear program with no variables and no constraints, ready
for data to be added. Unless
bounds are explicitly set using one of the methods below, bounds will be
$x\geq 0$. Unless relations are explicitly set, relations will be of type
\ccc{default_r}. Numerical entries that are not explicitly set will
default to $0$.}
\ccConstructor{template <A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>
Linear_program(int n, int m,
const A_it& a,
const B_it& b,
const R_it& r,
const FL_it& fl,
const L_it& l,
const FU_it& fu,
const U_it& u,
const C_it& c,
const std::iterator_traits<C_it>value_type& c0 = 0
)}{constructs \ccVar\ from given input iterators and the constant \ccc{c0}.}
\ccOperations
\ccCreationVariable{lp}
\ccMethod{bool is_linear() const;}{returns \ccc{true}.}
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true} iff
the bounds of \ccVar\ are $x\geq 0$.}
\ccMethod{void set_a (int j, int i, const NT& val);}{sets the entry $A_{ij}$
in column $j$ and row $i$ of the constraint matrix $A$ of \ccVar\ to
\ccc{val}. An existing entry is overwritten. \ccVar\ is enlarged if
necessary to accomodate this entry.}
\ccMethod{void set_b (int i, const NT& val);}{sets the entry $b_i$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_l (int j, bool is_finite, const NT& val = NT(0));}
{if \ccc{is_finite}, this sets the entry $l_j$ of \ccVar\ to \ccc{val},
otherwise it sets $l_j$ to $-\infty$. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_u (int j, bool is_finite, const NT& val = NT(0));}
{if \ccc{is_finite}, this sets the entry $u_j$ of \ccVar\ to \ccc{val},
otherwise it sets $u_j$ to $\infty$. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_c (int j, const NT& val);}{sets the entry $c_j$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_c0 (const NT& val);}{sets the entry $c_0$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.}
\ccSeeAlso
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
\ccc{Linear_program_from_pointers<NT>}
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>}\\
\ccc{Linear_program_from_pointers<NT>}\\
\ccc{Linear_program_from_mps<NT>}
\end{ccRefClass}

View File

@ -6,7 +6,7 @@
An object of class \ccRefName\ describes a linear program of the form
%%
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
\mbox{(LP)}& \mbox{minimize} & c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b, \\
& & l \leq x \leq u
\end{eqnarray*}
@ -52,7 +52,8 @@ copy the program data (if you need a copy, you may use the class
)}{constructs \ccVar\ from given random-access iterators and the constant \ccc{c0}. The passed iterators are merely stored, no copying of the program data takes place. }
\ccSeeAlso
\ccc{Linear_program<NT>}\\
\ccc{Linear_program_from_pointers<NT>}\\
\ccc{Linear_program<NT>}
\ccc{Linear_program_from_mps<NT>}
\end{ccRefClass}

View File

@ -6,7 +6,7 @@
An object of class \ccRefName\ describes a linear program of the form
%%
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
\mbox{(LP)}& \mbox{minimize} & c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b, \\
& & l \leq x \leq u
\end{eqnarray*}
@ -30,45 +30,68 @@ $x$,
The program data are read from an input stream in \ccc{MPSFormat}. This is
a commonly used format for encoding linear and quadratic programs that
is understood by many solvers. All values are expected to be readable
into type \ccc{NT}.
\textbf{Note:} The space required to store the program is $\Theta(nm +
n^2)$, even if these matrix $A$ is very sparse. This might be
prohibitive. In this case, you may use the model
\ccc{Sparse_linear_program_from_mps<NT>} whose space requirements
are bounded by the number of nonzero entries in the program
description. In this latter model, access to the iterators in
\ccc{LinearProgramInterface} will be a little slower, though.
As a rule of thumb, however, if there is a need for the sparse model,
then \cgal's linear programming solver will probably not be able to
solve it anyway.
into type \ccc{NT}. The constructed program can be further manipulated
by using the set-methods below.
\ccIsModel
\ccc{LinearProgramInterface}
\ccTypes
\ccNestedType{NT}{The number type of the program entries.}
\ccCreation
\ccIndexClassCreation
\ccCreationVariable{lp}
\ccConstructor{Sparse_linear_program_from_mps(std::istream& in)} {reads \ccVar\ from the input stream \ccc{in}.}
\ccConstructor{Linear_program_from_mps(std::istream& in)}
{reads \ccVar\ from the input stream \ccc{in}.}
\ccOperations
\ccMethod{bool is_valid() const;}{returns \ccc{true} if and only if an
MPS-encoded linear program could be extracted from the input stream.}
\ccMethod{const std::string& name_of_variable (int i) const;} {returns the name of the $i$-th variable.\ccPrecond \ccVar\ccc{.is_valid()}}
\ccMethod{const std::string& get_name_of_variable (int j) const;}
{returns the name of the $j$-th variable.}
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true} if and only if the linear program read into \ccVar\ is a nonnegative program
\ccPrecond \ccVar\ccc{.is_valid()}.}
\ccMethod{bool is_linear() const;}{returns \ccc{true}.}
\ccMethod{const std::string& error() const;}{returns an error message explaining why the input is not in MPS format \ccPrecond \ccc{!} \ccVar\ccc{.is_valid()}}
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true} if and only
if the linear program read into \ccVar\ is a nonnegative program.}
\ccMethod{const std::string& get_error() const;}{if !\ccVar\ccc{.is_valid()},
this method returns an error message explaining why the input does not
conform to the \ccc{MPSFormat}.}
\ccMethod{void set_a (int j, int i, const NT& val);}{sets the entry $A_{ij}$
in column $j$ and row $i$ of the constraint matrix $A$ of \ccVar\ to
\ccc{val}. An existing entry is overwritten. \ccVar\ is enlarged if
necessary to accomodate this entry.}
\ccMethod{void set_b (int i, const NT& val);}{sets the entry $b_i$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_l (int j, bool is_finite, const NT& val = NT(0));}
{if \ccc{is_finite}, this sets the entry $l_j$ of \ccVar\ to \ccc{val},
otherwise it sets $l_j$ to $-\infty$. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_u (int j, bool is_finite, const NT& val = NT(0));}
{if \ccc{is_finite}, this sets the entry $u_j$ of \ccVar\ to \ccc{val},
otherwise it sets $u_j$ to $\infty$. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_c (int j, const NT& val);}{sets the entry $c_j$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_c0 (const NT& val);}{sets the entry $c_0$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.}
\ccSeeAlso
\ccc{Sparse_linear_program_from_mps<NT>}\\
\ccc{Linear_program<NT>}\\
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>}\\
\ccc{Linear_program_from_pointers<NT>}

View File

@ -6,7 +6,7 @@
An object of class \ccRefName\ describes a linear program of the form
%%
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
\mbox{(LP)}& \mbox{minimize} & c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b, \\
& & l \leq x \leq u
\end{eqnarray*}
@ -37,8 +37,12 @@ a copy, you may use the class \ccc{Linear_program<NT>}).
\ccIsModel
\ccc{LinearProgramInterface}
\ccTypes
\ccNestedType{NT}{The number type of the program entries.}
\ccSeeAlso
\ccc{Linear_program<NT>}\\
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>}\\
\ccc{Linear_program<NT>}
\ccc{Linear_program_from_mps<NT>}
\end{ccRefClass}

View File

@ -75,8 +75,9 @@ of one or two sequences of three tokens $j i val$, where $j$ is the
name of a variable (here, we have variables \texttt{x0,x1}), $i$ is
the name of a constraint or the objective function, and $val$ is the
value $A_{ij}$ (if $i$ names a constraint), or $c_j$ (if $i$ names the
linear objective function). Values that are not specified in this
section default to $0$.
linear objective function). Values for pairs $(i,j)$ that are not
specified in this section default to $0$. Otherwise, for every pair
$(i,j)$, the \emph{last} specified value determines $A_{ij}$ or $c_j$.
\section*{RHS section}
This (mandatory) section encodes the right-hand side vector $b$ and
@ -86,10 +87,13 @@ encode several right-hand sides $b$ by using several such identifiers,
but we ignore all lines having an identifier different from that of
the first line.
The second token $i$ in every line names a constraint or the linear
objective function, and the third token $val$ is the value $b_i$ (if
The right-hand side identifier is succeeded by one or two sequences
of tokens $i val$, where $i$ names a constraint or the linear
objective function, and $val$ specifies the value $b_i$ (if
$i$ names a constraint), or $-c_0$ (if $i$ names the linear objective
function). Values that are not specified in this section default to $0$.
Otherwise, for every $i$, the \emph{last} specified value determines
$b_{i}$ or $-c_0$.
\section*{BOUNDS section}
This (optional) section encodes the lower and upper bound vectors $l$
@ -114,7 +118,7 @@ they are processed in order of appearance.
\begin{tabular}{l|l}
bound type & resulting bound \\ \hline
FX & $x_j \leq val$ (lower bound remains unchanged) \\
FX & $x_j = val$ ($x_j$ becomes a fixed variable) \\
LO & $x_j \geq val$ (upper bound remains unchanged) \\
UP & $x_j \leq val$ (lower bound remains unchanged, except if $val<0$; then,
a zero lower bound is reset to $-\infty$)\\
@ -133,16 +137,17 @@ or \texttt{QUADOBJ}), or $D_{ij}$ (in case of \texttt{DMATRIX}).
In case of \texttt{QMATRIX} and \texttt{DMATRIX}, \emph{all} nonzero
entries must be specified: if there is a line $i j val$, then there
must also be a line $j i val$, since $D$ is required to be symmetric.
In case of \texttt{QUADOBJ}, only the entries of $2D$ on or below the
diagonal must be specified, and the entries above the diagonal are
deduced from symmetry.
In case of \texttt{QUADOBJ}, only the entries of $2D$ on or below the
diagonal must be specified, entries above the diagonal are deduced from
symmetry. It is not allowed to specify two or more \emph{different}
nonzero values for an unordered pair $\{i,j\}$.
If this seftion is missing or does not contain nonzero values, the
If this section is missing or does not contain nonzero values, the
program is a model of the concept \ccc{LinearProgramInterface}.
\section*{Miscellaneous}
Our MPS format also supports an (optional) \texttt{RANGES} section,
but we won't explain this here.
but we don't explain this here.
\end{ccRefConcept}

View File

@ -4,9 +4,9 @@
A model of \ccRefName\ describes a linear program of the form
%%
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
\mbox{(LP)}& \mbox{minimize} & c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b, \\
& & x\geq \mathbf{0}
& & x\geq 0
\end{eqnarray*}
%%
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
@ -21,11 +21,15 @@ from $\{\leq, =, \geq\}$,
\item $c_0$ is a constant.
\end{itemize}
The description is given by appropriate \emph{random-access}
iterators over the program data, see below. The program therefore
comes in \emph{dense} representation which includes zero entries.
\ccHasModels
\ccc{CGAL::Nonnegative_linear_program<NT>}\\
\ccc{CGAL::Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
\ccc{CGAL::Nonnegative_linear_program_from_pointers<NT>}\\
\ccc{CGAL::Nonnegative_linear_program<NT>}\\
\ccc{CGAL::Linear_program_from_mps<NT>}\\
\ccc{CGAL::Nonnegative_linear_program_from_mps<NT>}\\
\ccTypes
@ -48,36 +52,38 @@ from $\{\leq, =, \geq\}$,
\ccCreationVariable{qp}
\ccMethod{int n() const;}{returns the number $n$ of variables (number
\ccMethod{int get_n() const;}{returns the number $n$ of variables (number
of columns of $A$) in \ccVar.}
\ccMethod{int m() const;}{returns the number $m$ of constraints
\ccMethod{int get_m() const;}{returns the number $m$ of constraints
(number of rows of $A$) in \ccVar.}
\ccMethod{const A_iterator& a() const;}{returns an iterator over the columns
\ccMethod{A_iterator get_a() const;}{returns an iterator over the columns
of $A$. For $j=0,\ldots,n-1$, $\ccc{*(a()+j)}$ is a random access
iterator for column $j$.}
\ccMethod{const B_iterator& b() const;}{returns an iterator over the entries
\ccMethod{B_iterator get_b() const;}{returns an iterator over the entries
of $b$.}
\ccMethod{const R_iterator& r() const;}{returns an iterator over the entries
\ccMethod{R_iterator get_r() const;}{returns an iterator over the entries
of $\qprel$. The value \ccc{CGAL::SMALLER} stands
for $\leq$, \ccc{CGAL::EQUAL} stands for $=$, and \ccc{CGAL::LARGER}
stands for $\geq$.}
\ccMethod{const C_iterator& c() const;}{returns an iterator over the entries
\ccMethod{C_iterator get_c() const;}{returns an iterator over the entries
of $c$.}
\ccMethod{const std::iterator_traits<C_iterator>::value_type& c0() const;}{returns the constant
term $c_0$ of the objective function.}
\ccMethod{std::iterator_traits<C_iterator>::value_type get_c0() const;}
{returns the constant term $c_0$ of the objective function.}
\ccRequirements
The value types of all iterator types (nested iterator types,
respectively, for \ccc{A_iterator} and \ccc{D_iterator}) must be
convertible to some common \ccc{IntegralDomain} \ccc{ET}.
respectively, for \ccc{A_iterator}) must be convertible to some common
\ccc{IntegralDomain} \ccc{ET}.
\ccSeeAlso
\ccc{QuadraticProgramInterface}\\
\ccc{LinearProgramInterface}\\
\ccc{NonnegativeQuadraticProgramInterface}
\end{ccRefConcept}

View File

@ -6,7 +6,7 @@ A model of \ccRefName\ describes a convex quadratic program of the form
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & x^{T}Dx+c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b, \\
& & x\geq \mathbf{0}
& & x\geq 0
\end{eqnarray*}
%%
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
@ -23,11 +23,15 @@ from $\{\leq, =, \geq\}$,
\item $c_0$ is a constant.
\end{itemize}
The description is given by appropriate \emph{random-access}
iterators over the program data, see below. The program therefore
comes in \emph{dense} representation which includes zero entries.
\ccHasModels
\ccc{CGAL::Nonnegative_quadratic_program<NT>}\\
\ccc{CGAL::Nonnegative_quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
\ccc{CGAL::Nonnegative_quadratic_program_from_pointers<NT>}\\
\ccc{CGAL::Nonnegative_quadratic_program<NT>}\\
\ccc{CGAL::Quadratic_program_from_mps<NT>}\\
\ccc{CGAL::Nonnegative_quadratic_program_from_mps<NT>}\\
\ccTypes
@ -56,32 +60,32 @@ from $\{\leq, =, \geq\}$,
\ccCreationVariable{qp}
\ccMethod{int n() const;}{returns the number $n$ of variables (number
\ccMethod{int get_n() const;}{returns the number $n$ of variables (number
of columns of $A$) in \ccVar.}
\ccMethod{int m() const;}{returns the number $m$ of constraints
\ccMethod{int get_m() const;}{returns the number $m$ of constraints
(number of rows of $A$) in \ccVar.}
\ccMethod{const A_iterator& a() const;}{returns an iterator over the columns
\ccMethod{A_iterator get_a() const;}{returns an iterator over the columns
of $A$. For $j=0,\ldots,n-1$, $\ccc{*(a()+j)}$ is a random access
iterator for column $j$.}
\ccMethod{const B_iterator& b() const;}{returns an iterator over the entries
\ccMethod{B_iterator get_b() const;}{returns an iterator over the entries
of $b$.}
\ccMethod{const R_iterator& r() const;}{returns an iterator over the entries
\ccMethod{R_iterator get_r() const;}{returns an iterator over the entries
of $\qprel$. The value \ccc{CGAL::SMALLER} stands
for $\leq$, \ccc{CGAL::EQUAL} stands for $=$, and \ccc{CGAL::LARGER}
stands for $\geq$.}
\ccMethod{const D_iterator& d() const;}{returns an iterator for the rows of
\ccMethod{D_iterator get_d() const;}{returns an iterator for the rows of
$2D$. For $i=0,\ldots,n-1$, $\ccc{*(d()+i)}$ is a random access
iterator for the entries in row $i$ below or on the diagonal.}
\ccMethod{const C_iterator& c() const;}{returns an iterator over the entries
\ccMethod{C_iterator get_c() const;}{returns an iterator over the entries
of $c$.}
\ccMethod{const std::iterator_traits<C_iterator>::value_type& c0() const;}{returns the constant
\ccMethod{std::iterator_traits<C_iterator>::value_type c0() const;}{returns the constant
term $c_0$ of the objective function.}
\ccRequirements
@ -91,5 +95,7 @@ respectively, for \ccc{A_iterator} and \ccc{D_iterator}) must be
convertible to some common \ccc{IntegralDomain} \ccc{ET}.
\ccSeeAlso
\ccc{QuadraticProgramInterface}\\
\ccc{LinearProgramInterface}\\
\ccc{NonnegativeLinearProgramInterface}
\end{ccRefConcept}

View File

@ -6,9 +6,9 @@
An object of class \ccRefName\ describes a linear program of the form
%%
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
\mbox{(LP)}& \mbox{minimize} & c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b, \\
& & x \geq \mathbf{0}
& & x \geq 0
\end{eqnarray*}
%%
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
@ -23,31 +23,59 @@ from $\{\leq, =, \geq\}$,
\item $c_0$ is a constant.
\end{itemize}
This class copies the program data from given iterator ranges;
if you only need to wrap existing iterators, you may use the classes
\ccc{Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, C_it>} and \ccc{Nonnegative_linear_program_from_pointers<NT>}).
This class allows you to build your program entry by entry, using
the set-methods below. If you only need to wrap existing (random-access)
iterators, then you may use the classes
\ccc{Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>} and \ccc{Nonnegative_linear_program_from_pointers<NT>}).
If you want to read a nonnegative linear program in \ccc{MPSFormat} from a
file, please use the model \ccc{Nonnegative_linear_program_from_mps<NT>}.
\ccIsModel
\ccc{NonnegativeLinearProgramInterface}
\ccTypes
\ccNestedType{NT}{The number type of the program entries.}
\ccCreation
\ccIndexClassCreation
\ccCreationVariable{lp}
The following constructor is a template, so you can provide input
iterators of any types.
\ccConstructor{
Nonnegative_linear_program(CGAL::Comparison_result default_r = CGAL::EQUAL);}
{constructs a nonnegative
linear program with no variables and no constraints, ready
for data to be added. Unless relations are explicitly set,
relations will be of type \ccc{default_r}.
Numerical entries that are not explicitly set will default to $0$.}
\ccConstructor{template <A_it, B_it, R_it, C_it>
Nonnegative_linear_program(int n, int m,
const A_it& a,
const B_it& b,
const R_it& r,
const C_it& c,
const std::iterator_traits<C_it>value_type& c0 = 0
)}{constructs \ccVar\ from given input iterators and the constant \ccc{c0}. The passed iterators are merely stored, no copying of the program data takes place. }
\ccOperations
\ccCreationVariable{lp}
\ccMethod{bool is_linear() const;}{returns \ccc{true}.}
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true}.}
\ccMethod{void set_a (int j, int i, const NT& val);}{sets the entry $A_{ij}$
in column $j$ and row $i$ of the constraint matrix $A$ of \ccVar\ to
\ccc{val}. An existing entry is overwritten. \ccVar\ is enlarged if
necessary to accomodate this entry.}
\ccMethod{void set_b (int i, const NT& val);}{sets the entry $b_i$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_c (int j, const NT& val);}{sets the entry $c_j$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_c0 (const NT& val);}{sets the entry $c_0$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.}
\ccSeeAlso
\ccc{Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, D_it, C_it>}\\
\ccc{Nonnegative_linear_program_from_pointers<NT>}
\ccc{Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, C_it>}\\
\ccc{Nonnegative_linear_program_from_pointers<NT>}\\
\ccc{Nonnegative_linear_program_from_mps<NT>}
\end{ccRefClass}

View File

@ -6,9 +6,9 @@
An object of class \ccRefName\ describes a linear program of the form
%%
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
\mbox{(LP)}& \mbox{minimize} & c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b, \\
& & x \geq \mathbf{0}
& & x \geq 0
\end{eqnarray*}
%%
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
@ -44,7 +44,7 @@ copy the program data (if you need a copy, you may use the class
)}{constructs \ccVar\ from given random-access iterators and the constant \ccc{c0}. The passed iterators are merely stored, no copying of the program data takes place. }
\ccSeeAlso
\ccc{Nonnegative_linear_program<NT>}\\
\ccc{Nonnegative_linear_program_from_pointers<NT>}\\
\ccc{Nonnegative_linear_program<NT>}
\ccc{Nonnegative_linear_program_from_mps<NT>}
\end{ccRefClass}

View File

@ -0,0 +1,84 @@
\begin{ccRefClass}{Nonnegative_linear_program_from_mps<NT>}
\ccInclude{CGAL/QP_models.h}
\ccDefinition
An object of class \ccRefName\ describes a linear program of the form
%%
\begin{eqnarray*}
\mbox{(LP)}& \mbox{minimize} & c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b, \\
& & x \geq 0
\end{eqnarray*}
%%
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
Here,
\begin{itemize}
\item $A$ is an $m\times n$ matrix (the constraint matrix),
\item $b$ is an $m$-dimensional vector (the right-hand side),
\item $\qprel$ is an $m$-dimensional vector of relations
from $\{\leq, =, \geq\}$,
\item $c$ is an $n$-dimensional vector (the linear objective
function), and
\item $c_0$ is a constant.
\end{itemize}
The program data are read from an input stream in \ccc{MPSFormat}. This is
a commonly used format for encoding linear and quadratic programs that
is understood by many solvers. All values are expected to be readable
into type \ccc{NT}. The constructed program can be further manipulated
by using the set-methods below.
\ccIsModel
\ccc{NonnegativeLinearProgramInterface}
\ccTypes
\ccNestedType{NT}{The number type of the program entries.}
\ccCreation
\ccIndexClassCreation
\ccCreationVariable{lp}
\ccConstructor{Nonnegative_linear_program_from_mps(std::istream& in)}
{reads \ccVar\ from the input stream \ccc{in}.}
\ccOperations
\ccMethod{bool is_valid() const;}{returns \ccc{true} if and only if an
MPS-encoded nonnegative linear program could be extracted from the input
stream.}
\ccMethod{const std::string& get_name_of_variable (int j) const;}
{returns the name of the $j$-th variable.}
\ccMethod{bool is_linear() const;}{returns \ccc{true}.}
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true}.}
\ccMethod{const std::string& get_error() const;}{if !\ccVar\ccc{.is_valid()},
this method returns an error message explaining why the input does not
conform to the \ccc{MPSFormat}.}
\ccMethod{void set_a (int j, int i, const NT& val);}{sets the entry $A_{ij}$
in column $j$ and row $i$ of the constraint matrix $A$ of \ccVar\ to
\ccc{val}. An existing entry is overwritten. \ccVar\ is enlarged if
necessary to accomodate this entry.}
\ccMethod{void set_b (int i, const NT& val);}{sets the entry $b_i$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_c (int j, const NT& val);}{sets the entry $c_j$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_c0 (const NT& val);}{sets the entry $c_0$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.}
\ccSeeAlso
\ccc{Nonnegative_linear_program<NT>}\\
\ccc{Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, C_it>}\\
\ccc{Nonnegative_linear_program_from_pointers<NT>}
\end{ccRefClass}

View File

@ -6,9 +6,9 @@
An object of class \ccRefName\ describes a linear program of the form
%%
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
\mbox{(LP)}& \mbox{minimize} & c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b, \\
& & x \geq \mathbf{0}
& & x \geq 0
\end{eqnarray*}
%%
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
@ -34,8 +34,12 @@ a copy, you may use the class \ccc{Nonnegative_linear_program<NT>}).
\ccIsModel
\ccc{NonnegativeLinearProgramInterface}
\ccTypes
\ccNestedType{NT}{The number type of the program entries.}
\ccSeeAlso
\ccc{Nonnegative_linear_program<NT>}\\
\ccc{Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, C_it>}\\
\ccc{Nonnegative_linear_program<NT>}
\ccc{Nonnegative_linear_program_from_mps<NT>}
\end{ccRefClass}

View File

@ -8,7 +8,7 @@ An object of class \ccRefName\ describes a convex quadratic program of the form
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & x^{T}Dx+c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b, \\
& & x \geq \mathbf{0}
& & x \geq 0
\end{eqnarray*}
%%
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
@ -25,33 +25,65 @@ from $\{\leq, =, \geq\}$,
\item $c_0$ is a constant.
\end{itemize}
This class copies the program data from given iterator ranges;
if you only need to wrap existing iterators, you may use the classes
\ccc{Nonnegative_quadratic_program_from_iterators<A_it, B_it, R_it, D_it, C_it>} and \ccc{Nonnegative_quadratic_program_from_pointers<NT>}).
This class allows you to build your program entry by entry, using
the set-methods below. If you only need to wrap existing (random-access)
iterators, then you may use the classes
\ccc{Nonnegative_quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>} and \ccc{Nonnegative_quadratic_program_from_pointers<NT>}). If you want
to read a quadratic program in \ccc{MPSFormat} from a file, please use
the model \ccc{Nonnegative_quadratic_program_from_mps<NT>}.
\ccIsModel
\ccc{NonnegativeQuadraticProgramInterface}
\ccTypes
\ccNestedType{NT}{The number type of the program entries.}
\ccCreation
\ccIndexClassCreation
\ccCreationVariable{qp}
The following constructor is a template, so you can provide input
iterators of any types.
\ccConstructor{
Nonnegative_quadratic_program(CGAL::Comparison_result default_r =
CGAL::EQUAL);}
{constructs a nonnegative quadratic program with no variables and no
constraints, ready for data to be added. Unless relations are explicitly set,
relations will be of type \ccc{default_r}. Numerical entries that are not
explicitly set will default to $0$.}
\ccOperations
\ccCreationVariable{qp}
\ccMethod{bool is_linear() const;}{returns \ccc{true} iff the
objective function matrix of \ccVar\ satisfies $D=0$.}
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true}.}
\ccMethod{void set_a (int j, int i, const NT& val);}{sets the entry $A_{ij}$
in column $j$ and row $i$ of the constraint matrix $A$ of \ccVar\ to
\ccc{val}. An existing entry is overwritten. \ccVar\ is enlarged if
necessary to accomodate this entry.}
\ccMethod{void set_b (int i, const NT& val);}{sets the entry $b_i$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_c (int j, const NT& val);}{sets the entry $c_j$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_c0 (const NT& val);}{sets the entry $c_0$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.}
\ccMethod{void set_d (int i, int j, const NT& val);}{sets the entry
$2D_{ij}$ of \ccVar\ to \ccc{val}. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccConstructor{template <A_it, B_it, R_it, D_it, C_it>
Nonnegative_quadratic_program(int n, int m,
const A_it& a,
const B_it& b,
const R_it& r,
const D_it& d,
const C_it& c,
const std::iterator_traits<C_it>value_type& c0 = 0
)}{constructs \ccVar\ from given input iterators and the constant \ccc{c0}. }
\ccSeeAlso
\ccc{Nonnegative_quadratic_program_from_iterators<A_it, B_it, R_it, D_it, C_it>}\\
\ccc{Nonnegative_quadratic_program_from_pointers<NT>}
\ccc{Nonnegative_quadratic_program_from_pointers<NT>}\\
\ccc{Nonnegative_quadratic_program_from_mps<NT>}
\end{ccRefClass}

View File

@ -8,7 +8,7 @@ An object of class \ccRefName\ describes a convex quadratic program of the form
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & x^{T}Dx+c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b, \\
& & x \geq \mathbf{0}
& & x \geq 0
\end{eqnarray*}
%%
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
@ -47,7 +47,7 @@ copy the program data (if you need a copy, you may use the class
)}{constructs \ccVar\ from given random-access iterators and the constant \ccc{c0}. The passed iterators are merely stored, no copying of the program data takes place. }
\ccSeeAlso
\ccc{Nonnegative_quadratic_program<NT>}\\
\ccc{Nonnegative_quadratic_program_from_pointers<NT>}\\
\ccc{Nonnegative_quadratic_program<NT>}
\ccc{Nonnegative_quadratic_program_from_mps<NT>}
\end{ccRefClass}

View File

@ -0,0 +1,90 @@
\begin{ccRefClass}{Nonnegative_quadratic_program_from_mps<NT>}
\ccInclude{CGAL/QP_models.h}
\ccDefinition
An object of class \ccRefName\ describes a convex quadratic program of the form
%%
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & x^{T}Dx+c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b, \\
& & x \geq 0
\end{eqnarray*}
%%
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
Here,
\begin{itemize}
\item $A$ is an $m\times n$ matrix (the constraint matrix),
\item $b$ is an $m$-dimensional vector (the right-hand side),
\item $\qprel$ is an $m$-dimensional vector of relations
from $\{\leq, =, \geq\}$,
\item $D$ is a symmetric positive-semidefinite $n\times n$ matrix (the
quadratic objective function),
\item $c$ is an $n$-dimensional vector (the linear objective
function), and
\item $c_0$ is a constant.
\end{itemize}
The program data are read from an input stream in \ccc{MPSFormat}. This is
a commonly used format for encoding linear and quadratic programs that
is understood by many solvers. All values are expected to be readable
into type \ccc{NT}. The constructed program can be further manipulated
by using the set-methods below.
\ccIsModel
\ccc{NonnegativeQuadraticProgramInterface}
\ccTypes
\ccNestedType{NT}{The number type of the program entries.}
\ccCreation
\ccIndexClassCreation
\ccCreationVariable{qp}
\ccConstructor{Nonnegative_quadratic_program_from_mps(std::istream& in)}
{reads \ccVar\ from the input stream \ccc{in}.}
\ccOperations
\ccMethod{bool is_valid() const;}{returns \ccc{true} if and only if an
MPS-encoded nonnegative
quadratic program could be extracted from the input stream.}
\ccMethod{const std::string& get_name_of_variable (int j) const;}
{returns the name of the $j$-th variable.}
\ccMethod{bool is_linear() const;}{returns \ccc{true} if and only if the quadratic program read into \ccVar\ is a linear program.}
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true}.}
\ccMethod{const std::string& get_error() const;}{if !\ccVar\ccc{.is_valid()},
this method returns an error message explaining why the input does not
conform to the \ccc{MPSFormat}.}
\ccMethod{void set_a (int j, int i, const NT& val);}{sets the entry $A_{ij}$
in column $j$ and row $i$ of the constraint matrix $A$ of \ccVar\ to
\ccc{val}. An existing entry is overwritten. \ccVar\ is enlarged if
necessary to accomodate this entry.}
\ccMethod{void set_b (int i, const NT& val);}{sets the entry $b_i$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_c (int j, const NT& val);}{sets the entry $c_j$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_c0 (const NT& val);}{sets the entry $c_0$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.}
\ccMethod{void set_d (int i, int j, const NT& val);}{sets the entry
$2D_{ij}$ of \ccVar\ to \ccc{val}. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccSeeAlso
\ccc{Nonnegative_quadratic_program<NT>}\\
\ccc{Nonnegative_quadratic_program_from_iterators<A_it, B_it, R_it, D_it, C_it>}\\
\ccc{Nonnegative_quadratic_program_from_pointers<NT>}
\end{ccRefClass}

View File

@ -8,7 +8,7 @@ An object of class \ccRefName\ describes a convex quadratic program of the form
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & x^{T}Dx+c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b, \\
& & x \geq \mathbf{0}
& & x \geq 0
\end{eqnarray*}
%%
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
@ -35,8 +35,12 @@ a copy, you may use the class \ccc{Nonnegative_quadratic_program<NT>}).
\ccIsModel
\ccc{NonnegativeQuadraticProgramInterface}
\ccTypes
\ccNestedType{NT}{The number type of the program entries.}
\ccSeeAlso
\ccc{Nonnegative_quadratic_program<NT>}\\
\ccc{Nonnegative_quadratic_program_from_iterators<A_it, B_it, R_it, D_it, C_it>}\\
\ccc{Nonnegative_quadratic_program<NT>}
\ccc{Nonnegative_quadratic_program_from_mps<NT>}
\end{ccRefClass}

View File

@ -27,13 +27,14 @@ $x$,
\item $c_0$ is a constant.
\end{itemize}
The description is given by appropriate \emph{random-access}
iterators over the program data, see below. The program therefore
comes in \emph{dense} representation which includes zero entries.
\ccHasModels
\ccc{CGAL::Quadratic_program<NT>}\\
\ccc{CGAL::Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
\ccc{CGAL::Quadratic_program_from_pointers<NT>}\\
\ccc{CGAL::Quadratic_program<NT>}\\
\ccc{CGAL::Free_quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
\ccc{CGAL::Free_quadratic_program_from_pointers<NT>}\\
\ccc{CGAL::Free_quadratic_program<NT>}\\
\ccc{CGAL::Quadratic_program_from_mps<NT>}\\
\ccTypes
@ -77,51 +78,51 @@ $x$,
\ccCreationVariable{qp}
\ccMethod{int n() const;}{returns the number $n$ of variables (number
\ccMethod{int get_n() const;}{returns the number $n$ of variables (number
of columns of $A$) in \ccVar.}
\ccMethod{int m() const;}{returns the number $m$ of constraints
\ccMethod{int get_m() const;}{returns the number $m$ of constraints
(number of rows of $A$) in \ccVar.}
\ccMethod{const A_iterator& a() const;}{returns an iterator over the columns
\ccMethod{A_iterator get_a() const;}{returns an iterator over the columns
of $A$. For $j=0,\ldots,n-1$, $\ccc{*(a()+j)}$ is a random access
iterator for column $j$.}
\ccMethod{const B_iterator& b() const;}{returns an iterator over the entries
\ccMethod{B_iterator get_b() const;}{returns an iterator over the entries
of $b$.}
\ccMethod{const R_iterator& r() const;}{returns an iterator over the entries
\ccMethod{R_iterator get_r() const;}{returns an iterator over the entries
of $\qprel$. The value \ccc{CGAL::SMALLER} stands
for $\leq$, \ccc{CGAL::EQUAL} stands for $=$, and \ccc{CGAL::LARGER}
stands for $\geq$.}
\ccMethod{const FL_iterator& fl() const;}{returns an iterator over the
\ccMethod{FL_iterator get_fl() const;}{returns an iterator over the
existence of the lower bounds $l_j, j=0,\ldots,n-1$. If
$\ccVar.\ccc{fl()}[j]=true$, the variable $x_j$ has a lower
bound, otherwise it has no lower bound.}
\ccMethod{const L_iterator& l() const;}{returns an iterator for the
\ccMethod{L_iterator get_l() const;}{returns an iterator for the
entries of $l$. If $\ccVar.\ccc{fl()}[j]=\ccc{false}$, the value
$\ccVar.\ccc{l()}[j]$ is not accessed.}
\ccMethod{const FU_iterator& fu() const;}{returns an iterator over the
\ccMethod{FU_iterator get_fu() const;}{returns an iterator over the
existence of the upper bounds $u_j, j=0,\ldots,n-1$. If
$\ccVar.\ccc{fu()}[j]=true$, the variable $x_j$ has an upper
bound, otherwise it has no upper bound.}
\ccMethod{const U_iterator& u() const;}{returns an iterator over the
\ccMethod{U_iterator get_u() const;}{returns an iterator over the
entries of $u$. If $\ccVar.\ccc{fu()}[j]=\ccc{false}$, the value
$\ccVar.\ccc{u()}[j]$ is not accessed.}
\ccMethod{const D_iterator& d() const;}{returns an iterator for the rows of
\ccMethod{D_iterator get_d() const;}{returns an iterator for the rows of
$2D$. For $i=0,\ldots,n-1$, $\ccc{*(d()+i)}$ is a random access
iterator for the entries in row $i$ below or on the diagonal.}
\ccMethod{const C_iterator& c() const;}{returns an iterator over the entries
\ccMethod{C_iterator get_c() const;}{returns an iterator over the entries
of $c$.}
\ccMethod{const std::iterator_traits<C_iterator>::value_type& c0() const;}{returns the constant
term $c_0$ of the objective function.}
\ccMethod{std::iterator_traits<C_iterator>::value_type c0() const;}
{returns the constant term $c_0$ of the objective function.}
\ccRequirements
@ -130,5 +131,7 @@ respectively, for \ccc{A_iterator} and \ccc{D_iterator}) must be
convertible to some common \ccc{IntegralDomain} \ccc{ET}.
\ccSeeAlso
\ccc{NonnegativeQuadraticProgramInterface}\\
\ccc{LinearProgramInterface}\\
\ccc{NonnegativeLinearProgramInterface}
\end{ccRefConcept}

View File

@ -29,41 +29,77 @@ $x$,
\item $c_0$ is a constant.
\end{itemize}
This class copies the program data from given iterator ranges;this
is useful if the iterators that you have are not random-access.
The time taken to copy the data is $\Theta(nm+n^2)$, though, even if the
program description is very sparse. Usually,
you only need to wrap existing (random-access)
iterators, and then you may use the classes
\ccc{Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>} and \ccc{Quadratic_program_from_pointers<NT>}).
This class allows you to build your program entry by entry, using
the set-methods below. If you only need to wrap existing (random-access)
iterators, then you may use the classes
\ccc{Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>} and \ccc{Quadratic_program_from_pointers<NT>}). If you want
to read a quadratic program in \ccc{MPSFormat} from a file, please use
the model \ccc{Quadratic_program_from_mps<NT>}.
\ccIsModel
\ccc{QuadraticProgramInterface}
\ccTypes
\ccNestedType{NT}{The number type of the program entries.}
\ccCreation
\ccIndexClassCreation
\ccCreationVariable{qp}
The following constructor is a template, so you can provide input
iterators of any types.
\ccConstructor{
Quadratic_program(CGAL::Comparison_result default_r = CGAL::EQUAL);}
{constructs a quadratic program with no variables and no constraints, ready
for data to be added. Unless
bounds are explicitly set using one of the methods below, bounds will be
$x\geq 0$. Unless relations are explicitly set, relations will be of type
\ccc{default_r}. Numerical entries that are not explicitly set will
default to $0$.}
\ccOperations
\ccCreationVariable{qp}
\ccMethod{bool is_linear() const;}{returns \ccc{true} iff the
objective function matrix of \ccVar\ satisfies $D=0$.}
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true} iff
the bounds of \ccVar\ are $x\geq 0$.}
\ccMethod{void set_a (int j, int i, const NT& val);}{sets the entry $A_{ij}$
in column $j$ and row $i$ of the constraint matrix $A$ of \ccVar\ to
\ccc{val}. An existing entry is overwritten. \ccVar\ is enlarged if
necessary to accomodate this entry.}
\ccMethod{void set_b (int i, const NT& val);}{sets the entry $b_i$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_l (int j, bool is_finite, const NT& val = NT(0));}
{if \ccc{is_finite}, this sets the entry $l_j$ of \ccVar\ to \ccc{val},
otherwise it sets $l_j$ to $-\infty$. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_u (int j, bool is_finite, const NT& val = NT(0));}
{if \ccc{is_finite}, this sets the entry $u_j$ of \ccVar\ to \ccc{val},
otherwise it sets $u_j$ to $\infty$. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_c (int j, const NT& val);}{sets the entry $c_j$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_c0 (const NT& val);}{sets the entry $c_0$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.}
\ccMethod{void set_d (int i, int j, const NT& val);}{sets the entry
$2D_{ij}$ of \ccVar\ to \ccc{val}. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccConstructor{template<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>
Quadratic_program(int n, int m,
const A_it& a,
const B_it& b,
const R_it& r,
const FL_it& fl,
const L_it& l,
const FU_it& fu,
const U_it& u,
const D_it& d,
const C_it& c,
const std::iterator_traits<C_it>value_type& c0 = 0
)}{constructs \ccVar\ from given input iterators and the constant \ccc{c0}.}
\ccSeeAlso
\ccc{Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
\ccc{Quadratic_program_from_pointers<NT>}
\ccc{Quadratic_program_from_pointers<NT>}\\
\ccc{Quadratic_program_from_mps<NT>}
\end{ccRefClass}

View File

@ -55,7 +55,8 @@ copy the program data (if you need a copy, you may use the class
)}{constructs \ccVar\ from given random-access iterators and the constant \ccc{c0}. The passed iterators are merely stored, no copying of the program data takes place. }
\ccSeeAlso
\ccc{Quadratic_program<NT>}\\
\ccc{Quadratic_program_from_pointers<NT>}\\
\ccc{Quadratic_program<NT>}
\ccc{Quadratic_program_from_mps<NT>}
\end{ccRefClass}

View File

@ -32,48 +32,69 @@ $x$,
The program data are read from an input stream in \ccc{MPSFormat}. This is
a commonly used format for encoding linear and quadratic programs that
is understood by many solvers. All values are expected to be readable
into type \ccc{NT}.
\textbf{Note:}
The space required to store the matrices
$A$ and $D$ is $\Theta(nm + n^2)$, even if these matrices are very sparse. This
might be prohibitive (for example, if there are many variables, but only
few of them are involved in the quadratic objective function). In this
case, you may use the model \ccc{Sparse_quadratic_program_from_mps<NT>}
whose space requirements are bounded by the number of nonzero entries
in the program description. In this latter model, access to the iterators
in \ccc{QuadraticProgramInterface} will be a little slower, though.
As a rule of thumb, however, if there is a need for the sparse model
\emph{because both $m$ and $n$ are large}, then \cgal's quadratic
programming solver will probably not be able to solve it anyway.
into type \ccc{NT}. The constructed program can be further manipulated
by using the set-methods below.
\ccIsModel
\ccc{QuadraticProgramInterface}
\ccTypes
\ccNestedType{NT}{The number type of the program entries.}
\ccCreation
\ccIndexClassCreation
\ccCreationVariable{qp}
\ccConstructor{Quadratic_program_from_mps(std::istream& in)} {reads \ccVar\ fromthe input stream \ccc{in}.}
\ccConstructor{Quadratic_program_from_mps(std::istream& in)}
{reads \ccVar\ from the input stream \ccc{in}.}
\ccOperations
\ccMethod{bool is_valid() const;}{returns \ccc{true} if and only if an
MPS-encoded program could be extracted from the input stream.}
MPS-encoded quadratic program could be extracted from the input stream.}
\ccMethod{const std::string& name_of_variable (int i) const;} {returns the name of the $i$-th variable.\ccPrecond \ccVar\ccc{.is_valid()}}
\ccMethod{const std::string& get_name_of_variable (int j) const;}
{returns the name of the $j$-th variable.}
\ccMethod{bool is_linear() const;}{returns \ccc{true} if and only if the quadratic program read into \ccVar\ is a linear program.
\ccPrecond \ccVar\ccc{.is_valid()}}
\ccMethod{bool is_linear() const;}{returns \ccc{true} if and only if the quadratic program read into \ccVar\ is a linear program.}
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true} if and only if the quadratic program read into \ccVar\ is a nonnegative program
\ccPrecond \ccVar\ccc{.is_valid()}.}
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true} if and only if the quadratic program read into \ccVar\ is a nonnegative program.}
\ccMethod{const std::string& error() const;}{returns an error message explaining why the input is not in MPS format \ccPrecond \ccc{!} \ccVar\ccc{.is_valid()}}
\ccMethod{const std::string& get_error() const;}{if !\ccVar\ccc{.is_valid()},
this method returns an error message explaining why the input does not
conform to the \ccc{MPSFormat}.}
\ccMethod{void set_a (int j, int i, const NT& val);}{sets the entry $A_{ij}$
in column $j$ and row $i$ of the constraint matrix $A$ of \ccVar\ to
\ccc{val}. An existing entry is overwritten. \ccVar\ is enlarged if
necessary to accomodate this entry.}
\ccMethod{void set_b (int i, const NT& val);}{sets the entry $b_i$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_l (int j, bool is_finite, const NT& val = NT(0));}
{if \ccc{is_finite}, this sets the entry $l_j$ of \ccVar\ to \ccc{val},
otherwise it sets $l_j$ to $-\infty$. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_u (int j, bool is_finite, const NT& val = NT(0));}
{if \ccc{is_finite}, this sets the entry $u_j$ of \ccVar\ to \ccc{val},
otherwise it sets $u_j$ to $\infty$. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_c (int j, const NT& val);}{sets the entry $c_j$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccMethod{void set_c0 (const NT& val);}{sets the entry $c_0$
of \ccVar\ to \ccc{val}. An existing entry is overwritten.}
\ccMethod{void set_d (int i, int j, const NT& val);}{sets the entry
$2D_{ij}$ of \ccVar\ to \ccc{val}. An existing entry is overwritten.
\ccVar\ is enlarged if necessary to accomodate this entry.}
\ccSeeAlso
\ccc{Sparse_quadratic_program_from_mps<NT>}\\
\ccc{Quadratic_program<NT>}\\
\ccc{Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
\ccc{Quadratic_program_from_pointers<NT>}

View File

@ -39,8 +39,13 @@ a copy, you may use the class \ccc{Quadratic_program<NT>}).
\ccIsModel
\ccc{QuadraticProgramInterface}
\ccTypes
\ccNestedType{NT}{The number type of the program entries.}
\ccSeeAlso
\ccc{Quadratic_program<NT>}\\
\ccc{Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
\ccc{Quadratic_program<NT>}
\ccc{Quadratic_program_from_mps<NT>}
\end{ccRefClass}

View File

@ -1,73 +0,0 @@
\begin{ccRefClass}{Sparse_linear_program_from_mps<NT>}
\ccInclude{CGAL/QP_models.h}
\ccDefinition
An object of class \ccRefName\ describes a linear program of the form
%%
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b, \\
& & l \leq x \leq u
\end{eqnarray*}
%%
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
Here,
\begin{itemize}
\item $A$ is an $m\times n$ matrix (the constraint matrix),
\item $b$ is an $m$-dimensional vector (the right-hand side),
\item $\qprel$ is an $m$-dimensional vector of relations
from $\{\leq, =, \geq\}$,
\item $l$ is an $n$-dimensional vector of lower
bounds for $x$,
\item $u$ is an $n$-dimensional vector of upper bounds for
$x$,
\item $c$ is an $n$-dimensional vector (the linear objective
function), and
\item $c_0$ is a constant.
\end{itemize}
The program data are read from an input stream in \ccc{MPSFormat}. This is
a commonly used format for encoding linear and quadratic programs that
is understood by many solvers. All values are expected to be readable
into type \ccc{NT}.
\textbf{Note:}
The space requirements are bounded by the number of nonzero entries
in the program description. However, if you can afford space
$\Theta(nm)$, the model \ccc{Linear_program_from_mps<NT>}
might be preferrable, since in the latter model, access to the
iterators in \ccc{LinearProgramInterface} will be faster.
As a rule of thumb, if there is a need for this sparse model,
then \cgal's linear programming solver will probably not be able to
solve it anyway.
\ccIsModel
\ccc{LinearProgramInterface}
\ccCreation
\ccIndexClassCreation
\ccCreationVariable{lp}
\ccConstructor{Sparse_linear_program_from_mps(std::istream& in)} {reads \ccVar\ from the input stream \ccc{in}.}
\ccOperations
\ccMethod{bool is_valid() const;}{returns \ccc{true} if and only if an
MPS-encoded linear program could be extracted from the input stream.}
\ccMethod{const std::string& name_of_variable (int i) const;} {returns the name of the $i$-th variable.\ccPrecond \ccVar\ccc{.is_valid()}}
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true} if and only if the linear program read into \ccVar\ is a nonnegative program
\ccPrecond \ccVar\ccc{.is_valid()}.}
\ccMethod{const std::string& error() const;}{returns an error message explaining why the input is not in MPS format \ccPrecond \ccc{!} \ccVar\ccc{.is_valid()}}
\ccSeeAlso
\ccc{Linear_program_from_mps<NT>}\\
\ccc{Linear_program<NT>}\\
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
\ccc{Linear_program_from_pointers<NT>}
\end{ccRefClass}

View File

@ -1,79 +0,0 @@
\begin{ccRefClass}{Sparse_quadratic_program_from_mps<NT>}
\ccInclude{CGAL/QP_models.h}
\ccDefinition
An object of class \ccRefName\ describes a convex quadratic program of the form
%%
\begin{eqnarray*}
\mbox{(QP)}& \mbox{minimize} & x^{T}Dx+c^{T}x+c_0 \\
&\mbox{subject to} & Ax\qprel b, \\
& & l \leq x \leq u
\end{eqnarray*}
%%
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
Here,
\begin{itemize}
\item $A$ is an $m\times n$ matrix (the constraint matrix),
\item $b$ is an $m$-dimensional vector (the right-hand side),
\item $\qprel$ is an $m$-dimensional vector of relations
from $\{\leq, =, \geq\}$,
\item $l$ is an $n$-dimensional vector of lower
bounds for $x$,
\item $u$ is an $n$-dimensional vector of upper bounds for
$x$,
\item $D$ is a symmetric positive-semidefinite $n\times n$ matrix (the
quadratic objective function),
\item $c$ is an $n$-dimensional vector (the linear objective
function), and
\item $c_0$ is a constant.
\end{itemize}
The program data are read from an input stream in \ccc{MPSFormat}. This is
a commonly used format for encoding linear and quadratic programs that
is understood by many solvers. All values are expected to be readable
into type \ccc{NT}.
\textbf{Note:}
The space requirements are bounded by the number of nonzero entries
in the program description. However, if you can afford space
$\Theta(nm + n^2)$, the model \ccc{Quadratic_program_from_mps<NT>}
might be preferrable, since in the latter model, access to the iterators
in \ccc{QuadraticProgramInterface} will be faster.
As a rule of thumb, if there is a need for the sparse model
\emph{because both $m$ and $n$ are large}, then \cgal's quadratic
programming solver will probably not be able to solve it anyway.
\ccIsModel
\ccc{QuadraticProgramInterface}
\ccCreation
\ccIndexClassCreation
\ccCreationVariable{qp}
\ccConstructor{Sparse_quadratic_program_from_mps(std::istream& in)} {reads \ccVar\ from the input stream \ccc{in}.}
\ccOperations
\ccMethod{bool is_valid() const;}{returns \ccc{true} if and only if an
MPS-encoded program could be extracted from the input stream.}
\ccMethod{const std::string& name_of_variable (int i) const;} {returns the name of the $i$-th variable.\ccPrecond \ccVar\ccc{.is_valid()}}
\ccMethod{bool is_linear() const;}{returns \ccc{true} if and only if the quadratic program read into \ccVar\ is a linear program.
\ccPrecond \ccVar\ccc{.is_valid()}}
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true} if and only if the quadratic program read into \ccVar\ is a nonnegative program
\ccPrecond \ccVar\ccc{.is_valid()}.}
\ccMethod{const std::string& error() const;}{returns an error message explaining why the input is not in MPS format \ccPrecond \ccc{!} \ccVar\ccc{.is_valid()}}
\ccSeeAlso
\ccc{Quadratic_program_from_mps<NT>}\\
\ccc{Quadratic_program<NT>}\\
\ccc{Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
\ccc{Quadratic_program_from_pointers<NT>}
\end{ccRefClass}

View File

@ -11,9 +11,9 @@ $\quad$ (for quadratic programs with variable bounds $l\leq x \leq u$) \\
\ccRefConceptPage{LinearProgramInterface} \\
$\quad$(for linear programs with variable bounds $l\leq x \leq u$)\\
\ccRefConceptPage{NonnegativeQuadraticProgramInterface}\\
$\quad$ (for quadratic programs with variable bounds $x\geq\mathbf{0}$) \\
$\quad$ (for quadratic programs with variable bounds $x\geq 0$) \\
\ccRefConceptPage{NonnegativeLinearProgramInterface}\\
$\quad$ (for linear programs with variable bounds $x\geq\mathbf{0}$)
$\quad$ (for linear programs with variable bounds $x\geq 0$)
\ccRefConceptPage{MPSFormat}\\
$\quad$ (the format used for reading and writing linear and quadratic
@ -34,74 +34,67 @@ Here are the models that conform to the concept
\ccc{QuadraticProgramInterface}.
\ccc{Quadratic_program<NT>}\\
$\quad$ (for quadratic programs that copy data from iterator ranges) \\
$\quad$ (for quadratic programs that own their data and are built entry-wise; probably the most useful model)\\
\ccc{Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
$\quad$ (for quadratic programs that wrap given iterators, without copying
data) \\
\ccc{Quadratic_program_from_pointers<NT>}\\
$\quad$ (for quadratic programs that wrap given pointers, without copying
data) \\
\ccc{Free_quadratic_program<NT>}\\
$\quad$ (for quadratic programs with no variable bounds, copied from iterator ranges)\\
\ccc{Free_quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
$\quad$ (for quadratic programs with no variable bounds, wrapping given iterators)\\
\ccc{Free_quadratic_program_from_pointers<NT>}\\
$\quad$ (for quadratic programs with no variable bounds, wrapping given pointers)\\
\ccc{Quadratic_program_from_mps<NT>}\\
$\quad$ (for quadratic programs copied from an input stream in
\ccc{MPSFormat})\\
\ccc{Sparse_quadratic_program_from_mps<NT>}\\
$\quad$ (for sparse quadratic programs copied from an input stream in
\ccc{MPSFormat})
$\quad$ (for quadratic programs read from an input stream in
\ccc{MPSFormat}; the constructed program can be manipulate entry-wise)
These are the models for \ccc{LinearProgramInterface}.
\ccc{Linear_program<NT>}\\
$\quad$ (for linear programs that copy data from iterator ranges) \\
$\quad$ (for linear programs that own their data and are built entry-wise; probably the most useful model)\\
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>}\\
$\quad$ (for linear programs that wrap given iterators, without copying
data) \\
\ccc{Linear_program_from_pointers<NT>}\\
$\quad$ (for linear programs that wrap given pointers, without copying
data) \\
\ccc{Free_linear_program<NT>}\\
$\quad$ (for linear programs with no variable bounds, copied from iterator ranges)\\
\ccc{Free_linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>}\\
$\quad$ (for linear programs with no variable bounds, wrapping given
iterators)\\
\ccc{Free_linear_program_from_pointers<NT>}\\
$\quad$ (for linear programs with no variable bounds, wrapping given
pointers)\\
\ccc{Linear_program_from_mps<NT>}\\
$\quad$ (for linear programs copied from an input stream in
\ccc{MPSFormat})\\
\ccc{Sparse_linear_program_from_mps<NT>}\\
$\quad$ (for sparse linear programs copied from an input stream in
\ccc{MPSFormat})
$\quad$ (for linear programs read from an input stream in
\ccc{MPSFormat}; the constructed program can be manipulate entry-wise)
For \ccc{NonnegativeQuadraticProgramInterface}, we offer these
three models.
four models.
\ccc{Nonnegative_quadratic_program<NT>}\\
$\quad$ (for nonnegative quadratic programs, copied from iterator ranges)\\
$\quad$ (for nonnegative quadratic programs that own their data and are built entry-wise; probably the most useful model)\\
\ccc{Nonnegative_quadratic_program_from_iterators<A_it, B_it, R_it, D_it, C_it>}\\
$\quad$ (for nonnegative quadratic programs, wrapping given iterators)\\
\ccc{Nonnegative_quadratic_program_from_pointers<NT>}\\
$\quad$ (for nonnegative quadratic programs, wrapping given pointers)
$\quad$ (for nonnegative quadratic programs, wrapping given pointers)\\
\ccc{Nonnegative_quadratic_program_from_mps<NT>}\\
$\quad$ (for nonnegative quadratic programs read from an input stream in
\ccc{MPSFormat}; the constructed program can be manipulate entry-wise)
And finally, the three models for \ccc{NonnegativeLinearProgramInterface}.
And finally, the four models for \ccc{NonnegativeLinearProgramInterface}.
\ccc{Nonnegative_linear_program<NT>}\\
$\quad$ (for nonnegative linear programs, copied from iterator ranges)\\
$\quad$ (for nonnegative linear programs that own their data and are built entry-wise; probably the most useful model)\\
\ccc{Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, C_it>}\\
$\quad$ (for nonnegative linear programs, wrapping given iterators)\\
\ccc{Nonnegative_linear_program_from_pointers<NT>}\\
$\quad$ (for nonnegative linear programs, wrapping given pointers)\\
\ccc{Nonnegative_linear_program_from_mps<NT>}\\
$\quad$ (for nonnegative linear programs read from an input stream in
\ccc{MPSFormat}; the constructed programt can be manipulate entry-wise)
\ccHeading{Functions}
In case you want to construct a program from complicated iterators
(whose types you don't know, or simply don't want to bother with),
we provide four makers.
\ccc{make_quadratic_program_from_iterators}\\
\ccc{make_linear_program_from_iterators}\\
\ccc{make_nonnegative_quadratic_program_from_iterators}\\
\ccc{make_nonnegative_linear_program_from_iterators}
There are four functions to solve a program, one for each program
concept.

View File

@ -15,28 +15,27 @@
\input{QP_solver_ref/Quadratic_program}
\input{QP_solver_ref/Quadratic_program_from_iterators}
\input{QP_solver_ref/Quadratic_program_from_pointers}
\input{QP_solver_ref/Free_quadratic_program}
\input{QP_solver_ref/Free_quadratic_program_from_iterators}
\input{QP_solver_ref/Free_quadratic_program_from_pointers}
\input{QP_solver_ref/Quadratic_program_from_mps}
\input{QP_solver_ref/Sparse_quadratic_program_from_mps}
\input{QP_solver_ref/Linear_program}
\input{QP_solver_ref/Linear_program_from_iterators}
\input{QP_solver_ref/Linear_program_from_pointers}
\input{QP_solver_ref/Free_linear_program}
\input{QP_solver_ref/Free_linear_program_from_iterators}
\input{QP_solver_ref/Free_linear_program_from_pointers}
\input{QP_solver_ref/Linear_program_from_mps}
\input{QP_solver_ref/Sparse_linear_program_from_mps}
\input{QP_solver_ref/Nonnegative_quadratic_program}
\input{QP_solver_ref/Nonnegative_quadratic_program_from_iterators}
\input{QP_solver_ref/Nonnegative_quadratic_program_from_pointers}
\input{QP_solver_ref/Nonnegative_quadratic_program_from_mps}
\input{QP_solver_ref/Nonnegative_linear_program}
\input{QP_solver_ref/Nonnegative_linear_program_from_iterators}
\input{QP_solver_ref/Nonnegative_linear_program_from_pointers}
\input{QP_solver_ref/Nonnegative_linear_program_from_mps}
\input{QP_solver_ref/make_quadratic_program_from_iterators.tex}
\input{QP_solver_ref/make_linear_program_from_iterators.tex}
\input{QP_solver_ref/make_nonnegative_quadratic_program_from_iterators.tex}
\input{QP_solver_ref/make_nonnegative_linear_program_from_iterators.tex}
\input{QP_solver_ref/solve_quadratic_program.tex}
\input{QP_solver_ref/solve_linear_program.tex}

View File

@ -0,0 +1,36 @@
\begin{ccRefFunction}{make_linear_program_from_iterators}
\ccInclude{CGAL/QP_models.h}
This template function creates an instance of
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>} from given iterators. This function can be useful if the types of these
iterators are too complicated (or of too little interest for you)
to write them down explicitly.
\ccFunction{template <
typename A_it,
typename B_it,
typename R_it,
typename FL_it,
typename L_it,
typename FU_it,
typename U_it,
typename C_it >
Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>
make_linear_program_from_iterators (
int n, int m,
const A_it& a,
const B_it& b,
const R_it& r,
const FL_it& fl,
const L_it& l,
const FU_it& fu,
const U_it& u,
const C_it& c,
typename std::iterator_traits<C_it>::value_type c0 =
typename std::iterator_traits<C_it>::value_type(0));}
{returns an instance of \ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>}, constructed from the given iterators.}
\ccSeeAlso
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>}
\end{ccRefFunction}

View File

@ -0,0 +1,30 @@
\begin{ccRefFunction}{make_nonnegative_linear_program_from_iterators}
\ccInclude{CGAL/QP_models.h}
This template function creates an instance of
\ccc{Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, C_it>}
from given iterators. This function can be useful if the types of these
iterators are too complicated (or of too little interest for you)
to write them down explicitly.
\ccFunction{template <
typename A_it,
typename B_it,
typename R_it,
typename C_it >
Nonnegative_linear_program_from_iterators
<A_it, B_it, R_it, C_it>
make_nonnegative_linear_program_from_iterators (
int n, int m,
const A_it& a,
const B_it& b,
const R_it& r,
const C_it& c,
typename std::iterator_traits<C_it>::value_type c0 =
typename std::iterator_traits<C_it>::value_type(0));}
{returns an instance of \ccc{Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, C_it>}, constructed from the given iterators.}
\ccSeeAlso
\ccc{Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, C_it>}
\end{ccRefFunction}

View File

@ -0,0 +1,31 @@
\begin{ccRefFunction}{make_nonnegative_quadratic_program_from_iterators}
\ccInclude{CGAL/QP_models.h}
This template function creates an instance of
\ccc{Nonnegative_quadratic_program_from_iterators<A_it, B_it, R_it, D_it, C_it>} from given iterators. This function can be useful if the types of these
iterators are too complicated (or of too little interest for you)
to write them down explicitly.
\ccFunction{template <
typename A_it,
typename B_it,
typename R_it,
typename D_it,
typename C_it >
Nonnegative_quadratic_program_from_iterators
<A_it, B_it, R_it, D_it, C_it>
make_nonnegative_quadratic_program_from_iterators (
int n, int m,
const A_it& a,
const B_it& b,
const R_it& r,
const D_it& d,
const C_it& c,
typename std::iterator_traits<C_it>::value_type c0 =
typename std::iterator_traits<C_it>::value_type(0));}
{returns an instance of \ccc{Nonnegative_quadratic_program_from_iterators<A_it, B_it, R_it, D_it, C_it>}, constructed from the given iterators.}
\ccSeeAlso
\ccc{Nonnegative_quadratic_program_from_iterators<A_it, B_it, R_it, D_it, C_it>}
\end{ccRefFunction}

View File

@ -0,0 +1,38 @@
\begin{ccRefFunction}{make_quadratic_program_from_iterators}
\ccInclude{CGAL/QP_models.h}
This template function creates an instance of
\ccc{Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>} from given iterators. This function can be useful if the types of these
iterators are too complicated (or of too little interest for you)
to write them down explicitly.
\ccFunction{template <
typename A_it,
typename B_it,
typename R_it,
typename FL_it,
typename L_it,
typename FU_it,
typename U_it,
typename D_it,
typename C_it >
Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>
make_quadratic_program_from_iterators (
int n, int m,
const A_it& a,
const B_it& b,
const R_it& r,
const FL_it& fl,
const L_it& l,
const FU_it& fu,
const U_it& u,
const D_it& d,
const C_it& c,
typename std::iterator_traits<C_it>::value_type c0 =
typename std::iterator_traits<C_it>::value_type(0));}
{returns an instance of \ccc{Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}, constructed from the given iterators.}
\ccSeeAlso
\ccc{Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}
\end{ccRefFunction}

View File

@ -2,7 +2,9 @@
\ccInclude{CGAL/QP_functions.h}
This function writes a linear program to an output stream.
This function writes a linear program to an output stream (in
\ccc{MPSFormat}). The time
complexity is $\Theta (mn)$, even if the program is very sparse.
\ccFunction{template <LinearProgramInterface>
void print_linear_program

View File

@ -2,7 +2,9 @@
\ccInclude{CGAL/QP_functions.h}
This function writes a nonnegative linear program to an output stream.
This function writes a nonnegative linear program to an output stream
(in \ccc{MPSFormat}). The time
complexity is $\Theta (mn)$, even if the program is very sparse.
\ccFunction{template <NonnegativeLinearProgramInterface>
void print_nonnegative_linear_program

View File

@ -2,7 +2,9 @@
\ccInclude{CGAL/QP_functions.h}
This function writes a nonnegative quadratic program to an output stream.
This function writes a nonnegative quadratic program
to an output stream (in \ccc{MPSFormat}). The time
complexity is $\Theta (n^2 + mn)$, even if the program is very sparse.
\ccFunction{template <NonnegativeQuadraticProgramInterface>
void print_nonnegative_quadratic_program

View File

@ -2,7 +2,9 @@
\ccInclude{CGAL/QP_functions.h}
This function writes a quadratic program to an output stream.
This function writes a quadratic program to an output stream (in
\ccc{MPSFormat}). The time complexity is $\Theta (n^2 + mn)$, even
if the program is very sparse.
\ccFunction{template <QuadraticProgramInterface>
void print_quadratic_program

View File

@ -21,6 +21,5 @@ be an exact type, and all entries of \ccc{lp} are convertible to
runtime-checks to ensure consistency during the solution process.
However, these checks slow down the computations by a considerable
factor. For maximum efficiency, it is advisable to define the macros
\texttt{CGAL\_QP\_NO\_ASSERTIONS} or (still better)
\texttt{NDEBUG}.
\texttt{CGAL\_QP\_NO\_ASSERTIONS} or \texttt{NDEBUG}.
\end{ccRefFunction}

View File

@ -21,6 +21,5 @@ be an exact type, and all entries of \ccc{lp} are convertible to
runtime-checks to ensure consistency during the solution process.
However, these checks slow down the computations by a considerable
factor. For maximum efficiency, it is advisable to define the macros
\texttt{CGAL\_QP\_NO\_ASSERTIONS} or (still better)
\texttt{NDEBUG}.
\texttt{CGAL\_QP\_NO\_ASSERTIONS} or \texttt{NDEBUG}.
\end{ccRefFunction}

View File

@ -21,6 +21,5 @@ be an exact type, and all entries of \ccc{qp} are convertible to
runtime-checks to ensure consistency during the solution process.
However, these checks slow down the computations by a considerable
factor. For maximum efficiency, it is advisable to define the macros
\texttt{CGAL\_QP\_NO\_ASSERTIONS} or (still better)
\texttt{NDEBUG}.
\texttt{CGAL\_QP\_NO\_ASSERTIONS} or \texttt{NDEBUG}.
\end{ccRefFunction}

View File

@ -21,6 +21,5 @@ be an exact type, and all entries of \ccc{qp} are convertible to
runtime-checks to ensure consistency during the solution process.
However, these checks slow down the computations by a considerable
factor. For maximum efficiency, it is advisable to define the macros
\texttt{CGAL\_QP\_NO\_ASSERTIONS} or (still better)
\texttt{NDEBUG}.
\texttt{CGAL\_QP\_NO\_ASSERTIONS} or \texttt{NDEBUG}.
\end{ccRefFunction}

View File

@ -43,7 +43,7 @@ int main(const int argNr,const char **args) {
using std::endl;
// get desired level of additional logging output:
const int verbosity = argNr < 2? 1 : std::atoi(args[1]);
//const int verbosity = argNr < 2? 1 : std::atoi(args[1]);
// construct QP instance:
typedef double IT;
@ -55,11 +55,11 @@ int main(const int argNr,const char **args) {
#endif
typedef CGAL::Quadratic_program_from_mps<IT> QP;
QP qp(std::cin,true,verbosity);
QP qp(std::cin);
// check for format errors in MPS f\ile:
if (!qp.is_valid()) {
cout << "Input is not a valid MPS file." << endl
<< "Error: " << qp.error() << endl;
<< "Error: " << qp.get_error() << endl;
std::exit(2);
}
@ -75,8 +75,8 @@ int main(const int argNr,const char **args) {
cout << "Variable values:" << endl;
Solution::Variable_value_iterator vit =
s.variable_values_begin() ;
for (int i=0; i < qp.n(); ++vit, ++i)
cout << " " << qp.name_of_variable(i) << " = "
for (int i=0; i < qp.get_n(); ++vit, ++i)
cout << " " << qp.get_name_of_variable(i) << " = "
<< CGAL::to_double(*vit) << endl;
cout << "Basic variables (index, value):" << endl;

View File

@ -44,10 +44,12 @@ namespace QP_functions_detail {
Is_linear is_linear,
Is_nonnegative is_nonnegative);
// internal routine:
// test whether the system is of the form A x == b (equations only)
template <typename R>
bool is_in_equational_form (const R& r);
// internal routine:
// test whether the row vectors of A that correpsond to equations
// are linearly independent; this is done using type ET. The value
// type of LinearInequalitySystem must be convertible to ET

File diff suppressed because it is too large Load Diff

View File

@ -231,85 +231,85 @@ public:
Quotient<ET> solution() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
return (*(this->Ptr()))->solution();
}
QP_status status() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
return (*(this->Ptr()))->status();
}
Variable_value_iterator variable_values_begin() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
return (*(this->Ptr()))->original_variable_values_begin();
}
Variable_value_iterator variable_values_end() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
return (*(this->Ptr()))->original_variable_values_end();
}
Variable_numerator_iterator variable_numerators_begin() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
return (*(this->Ptr()))->original_variables_numerator_begin();
}
Variable_numerator_iterator variable_numerators_end() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
return (*(this->Ptr()))->original_variables_numerator_end();
}
// ET variable_numerator_value (int i) const
// {
// CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
// CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
// return (*(this->Ptr()))->variable_numerator_value(i);
// }
const ET& variables_common_denominator() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
return (*(this->Ptr()))->variables_common_denominator();
}
Index_iterator basic_variable_indices_begin() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
return (*(this->Ptr()))->basic_original_variable_indices_begin();
}
Index_iterator basic_variable_indices_end() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
return (*(this->Ptr()))->basic_original_variable_indices_end();
}
int number_of_basic_variables() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
return (*(this->Ptr()))->number_of_basic_original_variables();
}
Index_iterator basic_constraint_indices_begin() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
return (*(this->Ptr()))->basic_constraint_indices_begin();
}
Index_iterator basic_constraint_indices_end() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
return (*(this->Ptr()))->basic_constraint_indices_end();
}
int number_of_basic_constraints() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
return (*(this->Ptr()))->number_of_basic_constraints();
}
@ -319,46 +319,46 @@ public:
// ----------
// ET optimality_certificate_numerator (int i)
// {
// CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
// CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
// return (*(this->Ptr()))->
// }
Optimality_certificate_numerator_iterator
optimality_certifcate_numerator_begin() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_precondition(status() == QP_OPTIMAL);
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion(status() == QP_OPTIMAL);
return (*(this->Ptr()))->optimality_certifcate_numerator_begin();
}
Optimality_certificate_numerator_iterator
optimality_certifcate_numerator_end() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_precondition(status() == QP_OPTIMAL);
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion(status() == QP_OPTIMAL);
return (*(this->Ptr()))->optimality_certifcate_numerator_end();
}
Optimality_certificate_iterator
optimality_certificate_begin() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_precondition(status() == QP_OPTIMAL);
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion(status() == QP_OPTIMAL);
return (*(this->Ptr()))->optimality_certificate_begin();
}
Optimality_certificate_iterator
optimality_certificate_end() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_precondition(status() == QP_OPTIMAL);
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion(status() == QP_OPTIMAL);
return (*(this->Ptr()))->optimality_certificate_end();
}
ET optimality_certificate_denominator() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_precondition(status() == QP_OPTIMAL);
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion(status() == QP_OPTIMAL);
return (*(this->Ptr()))->optimality_certificate_denominator();
}
@ -367,16 +367,16 @@ public:
Infeasibility_certificate_iterator
infeasibility_certificate_begin() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_precondition(status() == QP_INFEASIBLE);
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion(status() == QP_INFEASIBLE);
return (*(this->Ptr()))->optimality_certificate_numerator_begin();
}
Infeasibility_certificate_iterator
infeasibility_certificate_end() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_precondition(status() == QP_INFEASIBLE);
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion(status() == QP_INFEASIBLE);
return (*(this->Ptr()))->optimality_certificate_numerator_end();
}
@ -384,15 +384,15 @@ public:
// -------------
Unboundedness_certificate_iterator unboundedness_certificate_begin() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_precondition(status() == QP_UNBOUNDED);
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion(status() == QP_UNBOUNDED);
return (*(this->Ptr()))->unbounded_direction_begin();
}
Unboundedness_certificate_iterator unboundedness_certificate_end() const
{
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_precondition(status() == QP_UNBOUNDED);
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
CGAL_qpe_assertion(status() == QP_UNBOUNDED);
return (*(this->Ptr()))->unbounded_direction_end();
}

View File

@ -534,14 +534,14 @@ private:
// ----------
// pivot step
QP_status pivot( )
{ CGAL_qpe_precondition( phase() > 0);
CGAL_qpe_precondition( phase() < 3);
{ CGAL_qpe_assertion( phase() > 0);
CGAL_qpe_assertion( phase() < 3);
pivot_step();
return status(); }
// solve QP
QP_status solve( )
{ CGAL_qpe_precondition( phase() > 0);
{ CGAL_qpe_assertion( phase() > 0);
while ( phase() < 3) { pivot_step(); }
return status(); }
@ -686,15 +686,15 @@ public: // only the pricing strategies (including user-defined ones
bool is_basic( int j) const
{
CGAL_qpe_precondition(j >= 0);
CGAL_qpe_precondition(j < number_of_working_variables());
CGAL_qpe_assertion(j >= 0);
CGAL_qpe_assertion(j < number_of_working_variables());
return (in_B[ j] >= 0);
}
bool is_original(int j) const
{
CGAL_qpe_precondition(j >= 0);
CGAL_qpe_precondition(j < number_of_working_variables());
CGAL_qpe_assertion(j >= 0);
CGAL_qpe_assertion(j < number_of_working_variables());
return (j < qp_n);
}
@ -726,7 +726,7 @@ public: // only the pricing strategies (including user-defined ones
// Returns w[j] for an original variable x_j.
ET w_j_numerator(int j) const
{
CGAL_qpe_precondition((0 <= j) && (j < qp_n) && is_phaseII);
CGAL_qpe_assertion((0 <= j) && (j < qp_n) && is_phaseII);
return w[j];
}
@ -1970,7 +1970,7 @@ template < typename Q, typename ET, typename Tags > inline
bool QP_solver<Q, ET, Tags>::
basis_matrix_stays_regular()
{
CGAL_qpe_precondition( is_phaseII);
CGAL_qpe_assertion( is_phaseII);
int new_row, k;
if ( has_ineq && (i >= qp_n)) { // slack variable

View File

@ -76,7 +76,7 @@ template < typename Q, typename ET, typename Tags >
void QP_solver<Q, ET, Tags>::
set_D(const Q& qp, Tag_false /*is_linear*/)
{
qp_D = qp.d();
qp_D = qp.get_d();
}
template < typename Q, typename ET, typename Tags >
@ -84,15 +84,15 @@ void QP_solver<Q, ET, Tags>::
set(const Q& qp)
{
// assertions:
CGAL_qpe_precondition(qp.n() > 0);
CGAL_qpe_precondition(qp.m() >= 0);
CGAL_qpe_assertion(qp.get_n() >= 0);
CGAL_qpe_assertion(qp.get_m() >= 0);
// store QP
qp_n = qp.n(); qp_m = qp.m();
qp_A = qp.a(); qp_b = qp.b(); qp_c = qp.c(); qp_c0 = qp.c0();
qp_n = qp.get_n(); qp_m = qp.get_m();
qp_A = qp.get_a(); qp_b = qp.get_b(); qp_c = qp.get_c(); qp_c0 = qp.get_c0();
set_D(qp, Is_linear());
qp_r = qp.r();
qp_r = qp.get_r();
// set up slack variables and auxiliary problem
// --------------------------------------------
@ -171,10 +171,10 @@ set_explicit_bounds(const Q& /*qp*/, Tag_true) {
template < typename Q, typename ET, typename Tags >
void QP_solver<Q, ET, Tags>::
set_explicit_bounds(const Q& qp, Tag_false) {
qp_fl = qp.fl();
qp_l = qp.l();
qp_fu = qp.fu();
qp_u = qp.u();
qp_fl = qp.get_fl();
qp_l = qp.get_l();
qp_fu = qp.get_fu();
qp_u = qp.get_u();
}
@ -339,7 +339,7 @@ init()
init_solution();
// initialize pricing strategy
CGAL_qpe_precondition(strategyP != static_cast< Pricing_strategy*>(0));
CGAL_qpe_assertion(strategyP != static_cast< Pricing_strategy*>(0));
strategyP->init(0);
// basic feasible solution already available?
@ -389,8 +389,8 @@ init_basis()
// we only have equality constraints
// art_A.push_back(std::make_pair(s_i, !slack_A[s_i].second));
CGAL_qpe_precondition(s_i_absolute >= 0);
CGAL_qpe_precondition(s_i_absolute == slack_A[s_i].first);
CGAL_qpe_assertion(s_i_absolute >= 0);
CGAL_qpe_assertion(s_i_absolute == slack_A[s_i].first);
art_A.push_back(std::make_pair(s_i_absolute, !slack_A[s_i].second));
}
@ -572,7 +572,7 @@ init_solution()
// latter restricted to basic variables B_O:
if (!minus_c_B.empty()) minus_c_B.clear();
minus_c_B.insert(minus_c_B.end(), l, -et1); // todo: what is minus_c_B?
CGAL_qpe_precondition(l >= (int)art_A.size());
CGAL_qpe_assertion(l >= (int)art_A.size());
if (art_s_i > 0)
minus_c_B[art_A.size()-1] *= ET(qp_n+qp_m); // Note: the idea here is to
// give more weight to the

View File

@ -103,12 +103,12 @@ class QP_basis_inverse {
// special matrix-vector multiplication functions for LPs
template < class ForwardIterator, class OutputIterator > inline
void multiply_l( ForwardIterator v_x_it, OutputIterator y_l_it) const
{ CGAL_qpe_precondition( is_LP || is_phaseI);
{ CGAL_qpe_assertion( is_LP || is_phaseI);
multiply__l( v_x_it, y_l_it); }
template < class ForwardIterator, class OutputIterator > inline
void multiply_x( ForwardIterator v_l_it, OutputIterator y_x_it) const
{ CGAL_qpe_precondition( is_LP || is_phaseI);
{ CGAL_qpe_assertion( is_LP || is_phaseI);
multiply__x( v_l_it, y_x_it); }
// vector-matrix multiplication ( x^T = u^T M )
@ -221,10 +221,10 @@ class QP_basis_inverse {
// swap functions
void swap_variable( unsigned int j) // ``to the end'' of R
{ CGAL_qpe_precondition( j < b);
{ CGAL_qpe_assertion( j < b);
swap_variable( j, Is_LP()); }
void swap_constraint( unsigned int i) // ``to the end'' of P
{ CGAL_qpe_precondition( i < s);
{ CGAL_qpe_assertion( i < s);
swap_constraint( i, Is_LP()); }
private:
@ -323,13 +323,13 @@ class QP_basis_inverse {
void
init( unsigned int art_size, InputIterator art_first)
{
CGAL_qpe_precondition_msg( art_size <= l, \
CGAL_qpe_assertion_msg( art_size <= l, \
"There are more equality constraints than original variables!");
init( art_size, art_first, Is_LP());
d = et1;
CGAL_qpe_postcondition( s == art_size);
CGAL_qpe_postcondition( b == art_size);
CGAL_qpe_assertion( s == art_size);
CGAL_qpe_assertion( b == art_size);
is_phaseI = true;
is_phaseII = false;
@ -438,7 +438,7 @@ class QP_basis_inverse {
// update matrix in-place
// ----------------------
// handle sign of new denominator
CGAL_qpe_precondition( z != et0);
CGAL_qpe_assertion( z != et0);
bool z_neg = ( z < et0);
// update matrix
@ -478,7 +478,7 @@ class QP_basis_inverse {
// store new denominator
// ---------------------
d = ( z_neg ? -z : z);
CGAL_qpe_postcondition( d > et0);
CGAL_qpe_assertion( d > et0);
CGAL_qpe_debug {
if ( vout.verbose()) print();
@ -502,7 +502,7 @@ class QP_basis_inverse {
Tag_false()); // ignore 1st argument
ET z = -inner_product_x( x_x.begin(), u_x_it);
bool z_neg = ( z < et0);
CGAL_qpe_precondition( z != et0);
CGAL_qpe_assertion( z != et0);
// update matrix
update_inplace_QP( x_l.begin(), x_x.begin(), z, ( z_neg ? -d : d));
@ -535,7 +535,7 @@ class QP_basis_inverse {
// store new denominator
// ---------------------
d = ( z_neg ? -z : z);
CGAL_qpe_postcondition( d > et0);
CGAL_qpe_assertion( d > et0);
CGAL_qpe_debug {
if ( vout.verbose()) print();
@ -548,8 +548,8 @@ class QP_basis_inverse {
enter_original_leave_original( RandomAccessIterator y_x_it, unsigned int k)
{
// assert LP case or phase I
CGAL_qpe_precondition( is_LP || is_phaseI);
CGAL_qpe_precondition( k < b);
CGAL_qpe_assertion( is_LP || is_phaseI);
CGAL_qpe_assertion( k < b);
// update matrix in place
// ----------------------
@ -599,7 +599,7 @@ class QP_basis_inverse {
// store new denominator
// ---------------------
d = ( z_neg ? -z : z);
CGAL_qpe_postcondition( d > et0);
CGAL_qpe_assertion( d > et0);
// diagnostic output
CGAL_qpe_debug {
@ -613,8 +613,8 @@ class QP_basis_inverse {
enter_slack_leave_slack( ForwardIterator u_x_it, unsigned int k)
{
// assert LP case or phase I
CGAL_qpe_precondition( is_LP || is_phaseI);
CGAL_qpe_precondition( k < s);
CGAL_qpe_assertion( is_LP || is_phaseI);
CGAL_qpe_assertion( k < s);
// compute new row of basis inverse
multiply__l( u_x_it, x_x.begin());
@ -663,7 +663,7 @@ class QP_basis_inverse {
// store new denominator
// ---------------------
d = ( z_neg ? -z : z);
CGAL_qpe_postcondition( d > et0);
CGAL_qpe_assertion( d > et0);
// diagnostic output
CGAL_qpe_debug {
@ -677,7 +677,7 @@ class QP_basis_inverse {
ForwardIterator2 u_x_it)
{
// assert LP case or phase I
CGAL_qpe_precondition( is_LP || is_phaseI);
CGAL_qpe_assertion( is_LP || is_phaseI);
// update matrix in-place
// ----------------------
@ -685,7 +685,7 @@ class QP_basis_inverse {
multiply__l( u_x_it, x_x.begin());
ET z = d*u_x_it[ b] - inner_product_x( y_x_it, u_x_it);
bool z_neg = ( z < et0);
CGAL_qpe_precondition( z != et0);
CGAL_qpe_assertion( z != et0);
// update matrix
update_inplace_LP( x_x.begin(), y_x_it, z, ( z_neg ? -d : d));
@ -722,7 +722,7 @@ class QP_basis_inverse {
// store new denominator
// ---------------------
d = ( z_neg ? -z : z);
CGAL_qpe_postcondition( d > et0);
CGAL_qpe_assertion( d > et0);
CGAL_qpe_debug {
if ( vout.verbose()) print();
@ -762,21 +762,21 @@ class QP_basis_inverse {
// append row in Q if no allocated row available
void ensure_physical_row (unsigned int row) {
unsigned int rows = M.size();
CGAL_qpe_precondition(rows >= row);
CGAL_qpe_assertion(rows >= row);
if (rows == row) {
M.push_back(Row(row+1, et0));
// do we have to grow x_x?
CGAL_qpe_precondition(x_x.size() >= row-l);
CGAL_qpe_assertion(x_x.size() >= row-l);
if (x_x.size() == row-l)
x_x.push_back(et0);
// do we have to grow tmp_x?
CGAL_qpe_precondition(tmp_x.size() >= row-l);
CGAL_qpe_assertion(tmp_x.size() >= row-l);
if (tmp_x.size() == row-l)
tmp_x.push_back(et0);
CGAL_qpe_postcondition(M[row].size()==row+1);
CGAL_qpe_assertion(M[row].size()==row+1);
CGAL_qpe_debug {
if ( vout.verbose()) {
vout << "physical row " << (row) << " appended in Q\n";
@ -1101,8 +1101,8 @@ template < class ET_, class Is_LP_ > inline
const ET_& QP_basis_inverse<ET_,Is_LP_>::
entry( unsigned int r, unsigned int c, Tag_false) const
{
CGAL_qpe_precondition( ( r < s) || ( ( r >= l) && ( r < l+b)));
CGAL_qpe_precondition( ( c < s) || ( ( c >= l) && ( c < l+b)));
CGAL_qpe_assertion( ( r < s) || ( ( r >= l) && ( r < l+b)));
CGAL_qpe_assertion( ( c < s) || ( ( c >= l) && ( c < l+b)));
return ( c < r ? M[ r][ c] : M[ c][ r]);
}
@ -1111,8 +1111,8 @@ template < class ET_, class Is_LP_ > inline
const ET_& QP_basis_inverse<ET_,Is_LP_>::
entry( unsigned int r, unsigned int c, Tag_true) const
{
CGAL_qpe_precondition( r < s);
CGAL_qpe_precondition( c < b);
CGAL_qpe_assertion( r < s);
CGAL_qpe_assertion( c < b);
return M[ r][ c];
}

View File

@ -33,8 +33,8 @@ template < class ET_, class Is_LP_ >
void QP_basis_inverse<ET_,Is_LP_>::
set( int n, int m, int nr_equalities)
{
CGAL_qpe_precondition( n > 0);
//CGAL_qpe_precondition( m > 0);
CGAL_qpe_assertion( n >= 0);
CGAL_qpe_assertion( m >= 0);
b = s = 0;
// l is the maximum size of the basis in phase I
l = (std::min)( n+nr_equalities+1, m);
@ -69,7 +69,7 @@ leave_original( )
--b;
ET z = M[ l+b][ l+b];
bool z_neg = ( z < et0);
CGAL_qpe_precondition( z != et0);
CGAL_qpe_assertion( z != et0);
// update matrix in place
update_inplace_QP( M[ l+b].begin(), M[ l+b].begin()+l,
@ -77,7 +77,7 @@ leave_original( )
// store new denominator
d = ( z_neg ? -z : z);
CGAL_qpe_postcondition( d > et0);
CGAL_qpe_assertion( d > et0);
CGAL_qpe_debug {
if ( vout.verbose()) print();
@ -96,7 +96,7 @@ enter_slack( )
--s;
ET z = M[ s][ s];
bool z_neg = ( z < et0);
CGAL_qpe_precondition( z != et0);
CGAL_qpe_assertion( z != et0);
// update matrix in place
typename Matrix::iterator col_it;
@ -111,7 +111,7 @@ enter_slack( )
// store new denominator
d = ( z_neg ? -z : z);
CGAL_qpe_postcondition( d > et0);
CGAL_qpe_assertion( d > et0);
CGAL_qpe_debug {
if ( vout.verbose()) print();
@ -124,7 +124,7 @@ void QP_basis_inverse<ET_,Is_LP_>::
enter_slack_leave_original( )
{
// assert LP case or phase I
CGAL_qpe_precondition( is_LP || is_phaseI);
CGAL_qpe_assertion( is_LP || is_phaseI);
// update matrix in-place
// ----------------------
@ -145,7 +145,7 @@ enter_slack_leave_original( )
}
ET z = (*matrix_it)[ b];
bool z_neg = ( z < et0);
CGAL_qpe_precondition( z != et0);
CGAL_qpe_assertion( z != et0);
// update matrix
update_inplace_LP( matrix_it->begin(), x_x.begin(), -z, ( z_neg ? d : -d));
@ -153,7 +153,7 @@ enter_slack_leave_original( )
// store new denominator
// ---------------------
d = ( z_neg ? -z : z);
CGAL_qpe_postcondition( d > et0);
CGAL_qpe_assertion( d > et0);
CGAL_qpe_debug {
if ( vout.verbose()) print();
@ -172,7 +172,7 @@ z_replace_original_by_original(ForwardIterator y_l_it,
{
// assert QP case and phaseII
CGAL_qpe_precondition(is_QP && is_phaseII);
CGAL_qpe_assertion(is_QP && is_phaseII);
// prepare \hat{k}_{1} -scalar
@ -197,7 +197,7 @@ z_replace_original_by_original(ForwardIterator y_l_it,
// prepare \hat{k}_{2} -scalar
ET hat_k_2 = s_nu - (et2 * s_delta * hat_k_1);
CGAL_qpe_precondition( d != et0);
CGAL_qpe_assertion( d != et0);
// update matrix in place
z_update_inplace(x_l.begin(), x_x.begin(), tmp_l.begin(), tmp_x.begin(),
@ -206,7 +206,7 @@ z_replace_original_by_original(ForwardIterator y_l_it,
// store new denominator
d = CGAL::integral_division(hat_k_1 * hat_k_1, d);
CGAL_qpe_postcondition( d > et0);
CGAL_qpe_assertion( d > et0);
CGAL_qpe_debug {
if ( vout.verbose()) print();
@ -223,7 +223,7 @@ z_replace_original_by_slack( )
{
// assert QP case and phaseII
CGAL_qpe_precondition(is_QP && is_phaseII);
CGAL_qpe_assertion(is_QP && is_phaseII);
// adapt s and b
--s; --b;
@ -240,7 +240,7 @@ z_replace_original_by_slack( )
// prepare \hat{\xi} -scalar
ET hat_xi = M[s][s];
CGAL_qpe_precondition( d != et0);
CGAL_qpe_assertion( d != et0);
// update matrix in place
z_update_inplace(x_l.begin(), x_x.begin(), tmp_l.begin(), tmp_x.begin(),
@ -249,7 +249,7 @@ z_replace_original_by_slack( )
// store new denominator
d = CGAL::integral_division(hat_kappa * hat_kappa, d);
CGAL_qpe_postcondition( d > et0);
CGAL_qpe_assertion( d > et0);
CGAL_qpe_debug {
if ( vout.verbose()) print();
@ -269,13 +269,13 @@ z_replace_slack_by_original(ForwardIterator y_l_it,
const ET& hat_nu)
{
// assert QP case and phaseII
CGAL_qpe_precondition(is_QP && is_phaseII);
CGAL_qpe_assertion(is_QP && is_phaseII);
// get copies of y_l_it and y_x_it for later use
ForwardIterator y_l_it_copy = y_l_it;
ForwardIterator y_x_it_copy = y_x_it;
CGAL_qpe_precondition( d != et0);
CGAL_qpe_assertion( d != et0);
// prepare \hat{\phi}
@ -349,7 +349,7 @@ z_replace_slack_by_original(ForwardIterator y_l_it,
// store new denominator
d = CGAL::integral_division(hat_kappa * hat_kappa, d);
CGAL_qpe_postcondition( d > et0);
CGAL_qpe_assertion( d > et0);
CGAL_qpe_debug {
if ( vout.verbose()) print();
@ -367,7 +367,7 @@ z_replace_slack_by_slack(ForwardIterator u_x_it, unsigned int k_j)
{
// assert QP case and phaseII
CGAL_qpe_precondition(is_QP && is_phaseII);
CGAL_qpe_assertion(is_QP && is_phaseII);
// prepare \hat{v} -vector in x_l, x_x
multiply(u_x_it, u_x_it, x_l.begin(), x_x.begin(),Tag_false(),
@ -383,7 +383,7 @@ z_replace_slack_by_slack(ForwardIterator u_x_it, unsigned int k_j)
// prepare \hat{k}_{3} -scalar
ET hat_k_3 = -M[k_j][k_j];
CGAL_qpe_precondition( d != et0);
CGAL_qpe_assertion( d != et0);
// update matrix in place
z_update_inplace(x_l.begin(), x_x.begin(), tmp_l.begin(), tmp_x.begin(),
@ -392,7 +392,7 @@ z_replace_slack_by_slack(ForwardIterator u_x_it, unsigned int k_j)
// store new denominator
d = CGAL::integral_division(hat_k_1 * hat_k_1, d);
CGAL_qpe_postcondition( d > et0);
CGAL_qpe_assertion( d > et0);
CGAL_qpe_debug {
if ( vout.verbose()) print();

View File

@ -32,8 +32,8 @@ namespace QP_functions_detail {
template <typename R>
bool is_in_equational_form (const R& r)
{
typename R::R_iterator it = r.r();
typename R::R_iterator end = it + r.m();
typename R::R_iterator it = r.get_r();
typename R::R_iterator end = it + r.get_m();
for (; it < end; ++it)
if (*it != CGAL::EQUAL) return false;
return true;
@ -67,7 +67,7 @@ namespace QP_functions_detail {
typename Ar::R_iterator, C_iterator> LP;
// auxiliary LP
LP lp (ar.n(), ar.m(), ar.a(), B_iterator(0), ar.r(), C_iterator(0));
LP lp (ar.get_n(), ar.get_m(), ar.get_a(), B_iterator(0), ar.get_r(), C_iterator(0));
// solver Tags
typedef QP_solver_impl::QP_tags<
@ -98,11 +98,11 @@ namespace QP_functions_detail {
(std::ostream& out, const P& p,
CGAL::Tag_false /*is_nonnegative*/)
{
typename P::FL_iterator fl = p.fl();
typename P::FU_iterator fu = p.fu();
typename P::L_iterator l = p.l();
typename P::U_iterator u = p.u();
int n = p.n();
typename P::FL_iterator fl = p.get_fl();
typename P::FU_iterator fu = p.get_fu();
typename P::L_iterator l = p.get_l();
typename P::U_iterator u = p.get_u();
int n = p.get_n();
out << "BOUNDS\n";
for (int j=0; j<n; ++j, ++fl, ++l, ++fu, ++u) {
if (!*fl || !CGAL::is_zero(*l)) {
@ -131,8 +131,8 @@ namespace QP_functions_detail {
(std::ostream& out, const P& p,
CGAL::Tag_false /*is_linear*/)
{
typename P::D_iterator it = p.d();
int n = p.n();
typename P::D_iterator it = p.get_d();
int n = p.get_n();
bool empty_D = true;
for (int i=0; i<n; ++i, ++it) {
// handle only entries on/below diagonal
@ -160,22 +160,22 @@ namespace QP_functions_detail {
{
bool return_val = true;
// check n
if (qp1.n() != qp2.n()) {
if (qp1.get_n() != qp2.get_n()) {
std::cerr << "Equality test fails with n: "
<< qp1.n() << " vs. " << qp2.n() << std::endl;
<< qp1.get_n() << " vs. " << qp2.get_n() << std::endl;
return false; // wildly wrong, abort now
}
// check m
if (qp1.m() != qp2.m()) {
if (qp1.get_m() != qp2.get_m()) {
std::cerr << "Equality test fails with m: "
<< qp1.m() << " vs. " << qp2.m() << std::endl;
<< qp1.get_m() << " vs. " << qp2.get_m() << std::endl;
return false; // wildly wrong, abort now
}
int n = qp1.n();
int m = qp1.m();
int n = qp1.get_n();
int m = qp1.get_m();
// check A
typename Quadratic_program1::A_iterator a1 = qp1.a();
typename Quadratic_program2::A_iterator a2 = qp2.a();
typename Quadratic_program1::A_iterator a1 = qp1.get_a();
typename Quadratic_program2::A_iterator a2 = qp2.get_a();
for (int j=0; j<n; ++j, ++a1, ++a2)
for (int i=0; i<m; ++i)
if (*((*a1)+i) != *((*a2)+i)) {
@ -185,8 +185,8 @@ namespace QP_functions_detail {
return_val = false;
}
// check b
typename Quadratic_program1::B_iterator b1 = qp1.b();
typename Quadratic_program2::B_iterator b2 = qp2.b();
typename Quadratic_program1::B_iterator b1 = qp1.get_b();
typename Quadratic_program2::B_iterator b2 = qp2.get_b();
for (int i=0; i<m; ++i, ++b1, ++b2)
if (*b1 != *b2) {
std::cerr << "Equality test fails with b[" << i << "]: "
@ -194,8 +194,8 @@ namespace QP_functions_detail {
return_val = false;
}
// check r
typename Quadratic_program1::R_iterator r1 = qp1.r();
typename Quadratic_program2::R_iterator r2 = qp2.r();
typename Quadratic_program1::R_iterator r1 = qp1.get_r();
typename Quadratic_program2::R_iterator r2 = qp2.get_r();
for (int i=0; i<m; ++i, ++r1, ++r2)
if (*r1 != *r2) {
std::cerr << "Equality test fails with r[" << i << "]: "
@ -203,10 +203,10 @@ namespace QP_functions_detail {
return_val = false;
}
// check fl, l
typename Quadratic_program1::FL_iterator fl1 = qp1.fl();
typename Quadratic_program2::FL_iterator fl2 = qp2.fl();
typename Quadratic_program1::L_iterator l1 = qp1.l();
typename Quadratic_program2::L_iterator l2 = qp2.l();
typename Quadratic_program1::FL_iterator fl1 = qp1.get_fl();
typename Quadratic_program2::FL_iterator fl2 = qp2.get_fl();
typename Quadratic_program1::L_iterator l1 = qp1.get_l();
typename Quadratic_program2::L_iterator l2 = qp2.get_l();
for (int j=0; j<n; ++j, ++fl1, ++fl2, ++l1, ++l2) {
if (*fl1 != *fl2) {
std::cerr << "Equality test fails with fl[" << j << "]: "
@ -221,10 +221,10 @@ namespace QP_functions_detail {
}
// check fu, u
typename Quadratic_program1::FU_iterator fu1 = qp1.fu();
typename Quadratic_program2::FU_iterator fu2 = qp2.fu();
typename Quadratic_program1::U_iterator u1 = qp1.u();
typename Quadratic_program2::U_iterator u2 = qp2.u();
typename Quadratic_program1::FU_iterator fu1 = qp1.get_fu();
typename Quadratic_program2::FU_iterator fu2 = qp2.get_fu();
typename Quadratic_program1::U_iterator u1 = qp1.get_u();
typename Quadratic_program2::U_iterator u2 = qp2.get_u();
for (int j=0; j<n; ++j, ++fu1, ++fu2, ++u1, ++u2) {
if (*fu1 != *fu2) {
std::cerr << "Equality test fails with fu[" << j << "]: "
@ -238,8 +238,8 @@ namespace QP_functions_detail {
}
}
// check d
typename Quadratic_program1::D_iterator d1 = qp1.d();
typename Quadratic_program2::D_iterator d2 = qp2.d();
typename Quadratic_program1::D_iterator d1 = qp1.get_d();
typename Quadratic_program2::D_iterator d2 = qp2.get_d();
for (int i=0; i<n; ++i, ++d1, ++d2)
for (int j=0; j<i+1; ++j) // only access entries on/below diagonal
if (*((*d1)+j) != *((*d2)+j)) {
@ -249,8 +249,8 @@ namespace QP_functions_detail {
return_val = false;
}
// check c
typename Quadratic_program1::C_iterator c1 = qp1.c();
typename Quadratic_program2::C_iterator c2 = qp2.c();
typename Quadratic_program1::C_iterator c1 = qp1.get_c();
typename Quadratic_program2::C_iterator c2 = qp2.get_c();
for (int j=0; j<n; ++j, ++c1, ++c2)
if (*c1 != *c2) {
std::cerr << "Equality test fails with c[" << j << "]: "
@ -258,8 +258,8 @@ namespace QP_functions_detail {
return_val = false;
}
// check c0
typename Quadratic_program1::C_entry c01 = qp1.c0();
typename Quadratic_program2::C_entry c02 = qp2.c0();
typename Quadratic_program1::C_entry c01 = qp1.get_c0();
typename Quadratic_program2::C_entry c02 = qp2.get_c0();
if (c01 != c02) {
std::cerr << "Equality test fails with c0: "
<< c01 << " vs. " << c02 << std::endl;
@ -278,11 +278,11 @@ namespace QP_functions_detail {
// NAME:
out << "NAME " << problem_name << "\n";
int n = p.n();
int m = p.m();
int n = p.get_n();
int m = p.get_m();
// ROWS section:
typename P::R_iterator r = p.r();
typename P::R_iterator r = p.get_r();
out << "ROWS\n"
<< " N obj\n"; // for the objective function
for (int i=0; i<m; ++i, ++r) {
@ -298,8 +298,8 @@ namespace QP_functions_detail {
}
// COLUMNS section:
typename P::A_iterator a = p.a();
typename P::C_iterator c = p.c();
typename P::A_iterator a = p.get_a();
typename P::C_iterator c = p.get_c();
typedef
typename std::iterator_traits<typename P::C_iterator>::value_type IT;
out << "COLUMNS\n";
@ -322,10 +322,10 @@ namespace QP_functions_detail {
}
// RHS section:
typename P::B_iterator b = p.b();
typename P::B_iterator b = p.get_b();
out << "RHS\n";
if (!CGAL_NTS is_zero (p.c0()))
out << " rhs obj " << -p.c0() << "\n";
if (!CGAL_NTS is_zero (p.get_c0()))
out << " rhs obj " << -p.get_c0() << "\n";
for (int i=0; i<m; ++i, ++b)
if (!CGAL_NTS is_zero (*b))
out << " rhs c" << i << " " << *b << "\n";

View File

@ -1,682 +0,0 @@
// Copyright (c) 1997-2001 ETH Zurich (Switzerland).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Sven Schoenherr <sven@inf.fu-berlin.de>
// Bernd Gaertner <gaertner@inf.ethz.ch>
// Franz Wessendorp <fransw@inf.ethz.ch>
// Kaspar Fischer <fischerk@inf.ethz.ch>
#include <CGAL/Quotient.h>
#include <CGAL/MP_Float.h>
#include <CGAL/Gmpz.h>
#include <CGAL/Gmpq.h>
CGAL_BEGIN_NAMESPACE
template<typename IT_, typename Is_linear_,
typename Sparse_D_,
typename Sparse_A_>
QP_from_mps<IT_, Is_linear_,
Sparse_D_,
Sparse_A_>::
QP_from_mps(std::istream& in,bool use_CPLEX_convention,
int verbosity)
: has_linear_tag (check_tag(Is_linear_())),
verbosity_(verbosity), from(in),
is_format_okay_(false),
is_linear_(true),
use_CPLEX_convention(use_CPLEX_convention),
it0(0),
is_nonnegative_cached(false),
use_put_back_token(false)
{
// read NAME section:
if (!name_section())
return;
// read ROWS section:
if (!rows_section())
return;
// read COLUMNS section:
if (!columns_section())
return;
// read RHS section:
if (!rhs_section())
return;
// check for (optional) RANGES section:
if (!ranges_section())
return;
// read optional BOUNDS section:
if (!bounds_section())
return;
// initialize matrix D (in the linear case, this is not needed,
// since we return a Const_oneset_iterator that never accesses D
if (!has_linear_tag)
initialize_D(var_names.size(), Sparse_D());
// read optional QMATRIX section:
if (!qmatrix_section())
return;
// check for ENDATA:
const std::string end = token();
if (end != "ENDATA") {
err1("ENDDATA expected but found '%'",end);
return;
}
//std::cout << "MPS stream successfully read." << std::endl;
is_format_okay_ = true;
}
template<typename IT_, typename Is_linear_,
typename Sparse_D_,
typename Sparse_A_>
bool QP_from_mps<IT_, Is_linear_,
Sparse_D_,
Sparse_A_>::is_valid() const
{
return is_format_okay_;
}
template<typename IT_, typename Is_linear_,
typename Sparse_D_,
typename Sparse_A_>
const std::string& QP_from_mps<IT_, Is_linear_,
Sparse_D_,
Sparse_A_>::error() const
{
CGAL_qpe_assertion(!is_valid());
return error_msg;
}
template<typename IT_, typename Is_linear_,
typename Sparse_D_,
typename Sparse_A_>
const std::string& QP_from_mps<IT_, Is_linear_,
Sparse_D_,
Sparse_A_>::comment() const
{
return comment_;
}
template<typename IT_, typename Is_linear_,
typename Sparse_D_,
typename Sparse_A_>
bool QP_from_mps<IT_, Is_linear_, Sparse_D_, Sparse_A_>
::is_symmetric(Tag_false /*sparse_D*/, unsigned int&i, unsigned int&j) const
{
// only called if we have a qp, i.e. if D is initialized
const unsigned int var_nr = var_names.size();
for (i=0; i<var_nr; ++i)
for (j=i+1; j<var_nr; ++j)
if (D_[i][j] != D_[j][i])
return false;
return true;
}
template<typename IT_, typename Is_linear_,
typename Sparse_D_,
typename Sparse_A_>
bool QP_from_mps<IT_, Is_linear_, Sparse_D_, Sparse_A_>
::is_symmetric(Tag_true /*sparse_D*/, unsigned int&i, unsigned int&j) const
{
// only called if we have a qp, i.e. if D is initialized
const unsigned int var_nr = var_names.size();
for (i=0; i<var_nr; ++i) {
typename Map::const_iterator b = D_[i].begin();
typename Map::const_iterator e = D_[i].end();
for (; b != e; ++b) {
j = b->first;
// check entry (j, i)
IT expected_val = b->second;
IT found_val = it0;
typename Map::const_iterator it = D_[j].find(i);
if (it != D_[j].end()) found_val = it->second;
if (expected_val != found_val) return false;
}
}
return true;
}
template<typename IT_, typename Is_linear_,
typename Sparse_D_,
typename Sparse_A_>
bool QP_from_mps<IT_, Is_linear_,
Sparse_D_,
Sparse_A_>::name_section()
{
const std::string t = token();
if (t != "NAME")
return err("expected 'NAME'");
// NAME: everything found until line break; whitespaces are allowed
char c;
std::string token;
std::string whitespaces;
if (whitespace())
// line break eaten, name is empty
return true;
do {
from.get(c);
if (c == '\r' || c == '\n') break;
if (isspace(c))
whitespaces.push_back(c); // save whitespace
else {
// new actual character found: previous whitespaces belong to name
name += whitespaces;
whitespaces.clear();
name.push_back(c);
}
} while (true);
return true;
}
template<typename IT_, typename Is_linear_,
typename Sparse_D_,
typename Sparse_A_>
bool QP_from_mps<IT_, Is_linear_,
Sparse_D_,
Sparse_A_>::rows_section()
{
std::string t = token();
if (t != "ROWS")
return err1("expected 'ROWS' but found '%'",t);
// read 'N', 'G', 'L', or 'E', and the name of the constraint:
t = token();
while (t != "COLUMNS") {
const char type = t[0];
const std::string symbol(t); // for error message below
t = token();
switch (type) {
case 'N':
// register name of objective row:
if (obj.size() == 0) // remember first (and ignore others)
obj = t;
break;
case 'G':
case 'L':
case 'E':
{
// register name of >=, <=, or = constraint:
const unsigned int index = row_types_.size();
row_types_.push_back(type == 'G'? CGAL::LARGER :
(type == 'E'? CGAL::EQUAL : CGAL::SMALLER));
if (row_names.find(t) != row_names.end())
return err1("duplicate row name '%' in section ROWS",t);
row_names.insert(String_int_pair(t,index));
row_by_index.push_back(t);
b_.push_back(IT(0));
}
break;
default:
return err1(
"expected 'N', 'L', 'E', or 'G' in ROWS section but found '%'",
symbol);
}
t = token();
}
put_token_back(t);
return true;
}
template<typename IT_, typename Is_linear_,
typename Sparse_D_,
typename Sparse_A_>
bool QP_from_mps<IT_, Is_linear_,
Sparse_D_,
Sparse_A_>::columns_section()
{
std::string t = token();
if (t != "COLUMNS")
return err1("expected 'COLUMNS' but found '%'",t);
t = token();
while (t != "RHS") {
// find variable name:
unsigned int var_index;
std::string col_name;
const Index_map::const_iterator var_name = var_names.find(t);
if (var_name == var_names.end()) { // new variable?
var_index = var_names.size();
col_name = t;
var_names.insert(String_int_pair(t,var_index));
var_by_index.push_back(t);
add_column (Sparse_A_());
c_.push_back(IT(0));
fl_.push_back(true); // default lower bound is finite...
l_.push_back(IT(0)); // ...namely zero
fu_.push_back(false); // default upper bound is infinite
u_.push_back(IT()); // (dummy value)
} else { // variable that is already known?
var_index = var_name->second;
col_name = var_name->first;
}
bool doItAgain = true;
for (int i=0; doItAgain; ++i) {
// read row identifier:
t = token();
// read number:
IT val;
if (!number(val))
return err2("number expected after row identifier '%' in '%' COLUMNS record",t,col_name);
// store number:
if (t == obj) { // objective row?
c_[var_index] = val;
} else { // not objective row?
const Index_map::const_iterator row_name = row_names.find(t);
if (row_name == row_names.end())
return err1("unknown row identifier '%' in section COLUMNS",t);
set_entry_in_A (var_index, row_name->second, val, Sparse_A_());
}
// determine if we need to read another number:
doItAgain = i==0 && !whitespace();
}
// read next token:
t = token();
}
put_token_back(t);
return true;
}
template<typename IT_, typename Is_linear_,
typename Sparse_D_,
typename Sparse_A_>
bool QP_from_mps<IT_, Is_linear_,
Sparse_D_,
Sparse_A_>::rhs_section()
{
c_0 = IT(0); // no constant term yet
std::string t = token();
if (t != "RHS")
return err1("expected 'RHS' but found '%'",t);
t = token();
std::string rhs_id;
while (t != "RANGES" && t != "BOUNDS" &&
t != "DMATRIX" && t != "QMATRIX" && t != "QUADOBJ" &&
t != "ENDATA") {
// read rhs identifier and if it is different from the one
// from the previous iteration, ignore the whole row:
bool ignore = false;
std::string ignored;
if (rhs_id.size() == 0) { // first time we enter the loop?
rhs_id = t;
} else { // rhs_id already set
if (t != rhs_id) {
ignore = true; // ignore other rhs identifiers
ignored = t;
}
}
bool doItAgain = true;
for (int i=0; doItAgain; ++i) {
// read row identifier:
t = token();
// read number:
IT val;
if (!number(val))
return err1("number expected after '%' in this RHS record",t);
// store number:
const Index_map::const_iterator row_name = row_names.find(t);
if (row_name == row_names.end()) {
// no corresponding constraint; is it the constant term?
if (t == obj)
c_0 = -val;
else
return err1("unknown row identifier '%' in section RHS",t);
} else {
// we have an actual constraint
if (!ignore) {
b_[row_name->second] = val;
} else {
warn1("rhs with identifier '%' ignored", ignored);
}
}
// determine if we need to read another number:
doItAgain = i==0 && !whitespace();
}
// read next token:
t = token();
}
put_token_back(t);
return true;
}
template<typename IT_, typename Is_linear_,
typename Sparse_D_,
typename Sparse_A_>
bool QP_from_mps<IT_, Is_linear_,
Sparse_D_,
Sparse_A_>::ranges_section()
{
std::string t = token();
if (t != "RANGES") { // (Note: RANGES section is optional.)
put_token_back(t);
return true;
}
t = token();
std::string range_id;
while ((t != "BOUNDS" && t != "QMATRIX" &&
t != "DMATRIX" && t != "QUADOBJ" && t != "ENDATA")) {
// read rhs identifier and if it is different from the one
// from the previous iteration, ignore the whole row:
bool ignore = false;
std::string ignored;
if (range_id.size() == 0) { // first time we enter the loop?
range_id = t;
} else { // range_id already set
if (t != range_id) {
ignore = true; // ignore other range identifiers
ignored = t;
}
}
bool doItAgain = true;
for (int i=0; doItAgain; ++i) {
// read row identifier:
t = token();
// read number:
IT val;
if (!number(val))
return err1("number expected after '%' in this RANGES record",t);
// duplicate the constraint, depending on sign of val and type
// of constraint
const Index_map::const_iterator row_name = row_names.find(t);
if (row_name == row_names.end()) {
return err1("unknown row identifier '%' in section RANGES",t);
} else {
if (!ignore) {
int index = row_name->second;
CGAL::Comparison_result type = row_types_[index];
// duplicate the row, unless it has already been duplicated
const Index_map::const_iterator duplicated_row_name =
duplicated_row_names.find(t);
if (duplicated_row_name != duplicated_row_names.end())
return err1("duplicate row identifier '%' in section RANGES",t);
duplicated_row_names.insert(*row_name);
int new_index = b_.size();
for (unsigned int j=0; j<var_names.size(); ++j) {
IT val = get_entry_in_A (j, index, Sparse_A_());
add_entry_in_A (j, new_index, val, Sparse_A_());
}
// determine rhs for this new row. Here are the rules:
// if r is the ranges value and b is the old right-hand
// side, then we have h <= constraint <= u according to
// this table:
//
// row type sign of r h u
// ----------------------------------------------
// G + or - b b + |r|
// L + or - b - |r| b
// E + b b + |r|
// E - b - |r| b
switch (type) {
case CGAL::LARGER: // introduce "<= b+|r|"
row_types_.push_back(CGAL::SMALLER);
b_.push_back(b_[index] + CGAL::abs(val));
break;
case CGAL::SMALLER: // introduce ">= b-|r|"
row_types_.push_back(CGAL::LARGER);
b_.push_back(b_[index] - CGAL::abs(val));
break;
case CGAL::EQUAL:
if (CGAL_NTS is_positive (val)) {
// introduce "<= b+|r|"
row_types_.push_back(CGAL::SMALLER);
} else {
// introduce ">= b-|r|"
row_types_.push_back(CGAL::LARGER);
}
b_.push_back(b_[index] + val);
break;
default:
CGAL_qpe_assertion(false);
}
} else {
warn1("range with identifier '%' ignored", ignored);
}
}
// determine if we need to read another number:
doItAgain = i==0 && !whitespace();
}
// read next token:
t = token();
}
put_token_back(t);
return true;
}
template<typename IT_, typename Is_linear_,
typename Sparse_D_,
typename Sparse_A_>
bool QP_from_mps<IT_, Is_linear_,
Sparse_D_,
Sparse_A_>::bounds_section()
{
std::string t = token();
if (t != "BOUNDS") { // (Note: BOUNDS section is optional.)
put_token_back(t);
return true;
}
t = token();
std::string bound_id;
while (t != "QMATRIX" && t != "DMATRIX" && t != "QUADOBJ" && t != "ENDATA") {
// process type of bound:
enum Bound_type { LO, UP, FX, FR, MI, PL};
Bound_type type;
if (t=="LO")
type = LO;
else if (t=="UP")
type = UP;
else if (t=="FX")
type = FX;
else if (t=="FR")
type = FR;
else if (t=="MI")
type = MI;
else if (t=="PL")
type = PL;
else
return
err1("expected 'LO', 'UP', 'FX', 'FR', 'MI', or 'PL' here but found '%'",t);
// remember bound:
const std::string bound = t;
// find bound label; there may be several, but we only process
// the bounds having the first bound label that occurs. This
// label may be empty, though
t = token(); // bound label or variable name (case of empty bound label)
if (bound_id.size() == 0) { // first time we see a bound label / variable?
const Index_map::const_iterator var_name = var_names.find(t);
if (var_name != var_names.end()) { // is the token a variable?
bound_id = " "; // there is no bound label
put_token_back(t); // the variable name is processed below
} else
bound_id = t; // we found a bound label
} else {
// now we already know the bound label
if (bound_id == " ") // empty bound label?
put_token_back(t); // the variable name is processed below
else
if (t != bound_id) {
warn1("ignoring all bounds for bound label '%'",t);
warn1("(only bounds for bound label '%' are accepted)",bound_id);
}
}
// find variable name;
t = token();
const Index_map::const_iterator var_name = var_names.find(t);
if (var_name == var_names.end()) // unknown variable?
return err1("unknown variable '%' in BOUNDS section",t);
const unsigned int var_index = var_name->second;;
// read value of bound, if appropriate:
IT val;
if (type==LO || type==UP || type==FX)
if (!number(val))
return err2("expected number after '%' in % bound",t,bound);
// store bound:
switch (type) {
case FX:
fu_[var_index] = true;
u_ [var_index] = val;
case LO:
fl_[var_index] = true;
l_ [var_index] = val;
break;
case UP:
fu_[var_index] = true;
u_ [var_index] = val;
if (val <= 0 && fl_[var_index] == true && l_[var_index] == 0)
if (val < 0 || !use_CPLEX_convention)
fl_[var_index] = false;
break;
case FR:
fu_[var_index] = false;
fl_[var_index] = false;
break;
case MI:
fl_[var_index] = false;
break;
case PL:
fu_[var_index] = false;
break;
default:
CGAL_qpe_assertion(false);
}
// read next token:
t = token();
}
put_token_back(t);
return true;
}
template<typename IT_, typename Is_linear_,
typename Sparse_D_,
typename Sparse_A_>
bool QP_from_mps<IT_, Is_linear_,
Sparse_D_,
Sparse_A_>::qmatrix_section()
{
std::string t = token();
if (t!="QMATRIX" && t!="DMATRIX" && t!="QUADOBJ") { // optional
put_token_back(t);
return true;
}
// remember section name:
D_section = t;
const bool multiply_by_two = t=="DMATRIX";
const bool only_get_lower_part = t =="QUADOBJ";
t = token();
std::string bound_id;
while (t != "ENDATA") {
// find first variable name;
const Index_map::const_iterator var1_name = var_names.find(t);
if (var1_name == var_names.end()) // unknown variable?
return err2("unknown first variable '%' in '%' section", t, D_section);
const unsigned int var1_index = var1_name->second;;
//std::cout << "qvar1 " << t << std::endl;
// find second variable name;
t = token();
const Index_map::const_iterator var2_name = var_names.find(t);
if (var2_name == var_names.end()) // unknown variable?
return err2("unknown second variable '%' in '%' section",t, D_section);
const unsigned int var2_index = var2_name->second;;
//std::cout << "qvar2 " << t << std::endl;
// read value:
IT val;
if (!number(val))
return err1("expected number after '%' in section QMATRIX",t);
// multiply by two if approriate:
if (multiply_by_two)
val *= IT(2);
// mark problem as nonlinear if value is nonzero, and
// bail out if we are supposed to read a linear program
if (is_linear_ && !CGAL::is_zero(val)) {
is_linear_ = false;
if (has_linear_tag)
return err1
("nonzero value in '%' section while reading linear program",
D_section);
}
// set entry in D:
set_entry_in_D(var1_index, var2_index, val, Sparse_D());
if (only_get_lower_part)
// duplicate entry if not on diagonal
if (var1_index != var2_index)
set_entry_in_D(var2_index, var1_index, val, Sparse_D());
// read next token:
t = token();
}
put_token_back(t);
// now check symmetry
unsigned int bad_i, bad_j;
if (!is_symmetric(Sparse_D(), bad_i, bad_j)) {
std::string bad_i_name = var_by_index[bad_i];
std::string bad_j_name = var_by_index[bad_j];
return
err3("nonsymmetric '%' section for variables '%' and '%'",
D_section, bad_i_name, bad_j_name);
}
return true;
}
CGAL_END_NAMESPACE

View File

@ -203,7 +203,7 @@ pricing_helper(int& direction, Tag_false /*is_in_standard_form*/)
it != this->inactive_set_end(); ++it) {
// don't price basics/artificials
CGAL_qpe_precondition (!this->solver().is_basic(*it));
CGAL_qpe_assertion (!this->solver().is_basic(*it));
if (this->solver().is_artificial( *it)) continue;
// compute mu_j

View File

@ -173,8 +173,8 @@ template <typename NT>
bool QP_pricing_strategy<Q, ET, Tags>::
is_improving (int j, const NT& mu, const NT& nt0 ) const
{
CGAL_qpe_precondition(!this->solver().is_basic(j));
CGAL_qpe_precondition(!this->solver().is_artificial(j));
CGAL_qpe_assertion(!this->solver().is_basic(j));
CGAL_qpe_assertion(!this->solver().is_artificial(j));
if (this->solver().is_original(j)) {
const Bound_index bnd_ind =
this->solver().nonbasic_original_variable_bound_index(j);
@ -207,8 +207,8 @@ template <typename NT>
bool QP_pricing_strategy<Q, ET, Tags>::
price_dantzig (int j, const NT& mu, const NT& nt0,
int& min_j, NT& min_mu, int& direction) {
CGAL_qpe_precondition(!this->solver().is_basic(j));
CGAL_qpe_precondition(!this->solver().is_artificial(j));
CGAL_qpe_assertion(!this->solver().is_basic(j));
CGAL_qpe_assertion(!this->solver().is_artificial(j));
if (this->solver().is_original(j)) {
// original variable
const Bound_index bnd_ind =

View File

@ -1690,7 +1690,7 @@ void
QP_solver<Q, ET, Tags>::
enter_variable( )
{
CGAL_qpe_precondition (is_phaseII);
CGAL_qpe_assertion (is_phaseII);
CGAL_qpe_debug {
vout2 << "--> nonbasic (" << variable_type( j) << ") variable "
<< j << " enters basis" << std::endl << std::endl;
@ -1711,7 +1711,7 @@ enter_variable( )
// correct size). We check here
// whether we need to enlarge
// them.
CGAL_qpe_precondition(minus_c_B.size() == B_O.size());
CGAL_qpe_assertion(minus_c_B.size() == B_O.size());
minus_c_B.push_back(et0);
q_x_O.push_back(et0);
tmp_x .push_back(et0);
@ -2184,7 +2184,7 @@ z_replace_variable_slack_by_original( )
// correct size). We check here
// whether we need to enlarge
// them.
CGAL_qpe_precondition(minus_c_B.size() == B_O.size());
CGAL_qpe_assertion(minus_c_B.size() == B_O.size());
minus_c_B.push_back(et0);
q_x_O.push_back(et0);
tmp_x .push_back(et0);
@ -2950,8 +2950,8 @@ template < typename Q, typename ET, typename Tags >
void QP_solver<Q, ET, Tags>::
set_pricing_strategy( Pricing_strategy *strategy)
{
CGAL_qpe_precondition( phase() != 1);
CGAL_qpe_precondition( phase() != 2);
CGAL_qpe_assertion( phase() != 1);
CGAL_qpe_assertion( phase() != 2);
if (defaultStrategy != static_cast< Pricing_strategy*>( 0))
delete defaultStrategy;

View File

@ -126,7 +126,7 @@ template < typename Q, typename ET, typename Tags >
void QP_solver<Q, ET, Tags>::
multiply__A_CxN_O(Value_iterator out) const
{
CGAL_qpe_precondition(!check_tag(Is_nonnegative()));
CGAL_qpe_assertion(!check_tag(Is_nonnegative()));
// initialize with zero vector:
std::fill_n(out, C.size(), et0);
@ -157,7 +157,7 @@ template < typename Q, typename ET, typename Tags >
void QP_solver<Q, ET, Tags>::
multiply__2D_OxN_O(Value_iterator out) const
{
CGAL_qpe_precondition(!check_tag(Is_nonnegative()));
CGAL_qpe_assertion(!check_tag(Is_nonnegative()));
// initialize with zero vector:
std::fill_n(out, B_O.size(), et0);
@ -203,7 +203,7 @@ template < typename Q, typename ET, typename Tags >
void QP_solver<Q, ET, Tags>::
init_r_B_O()
{
CGAL_qpe_precondition(!check_tag(Is_nonnegative()) &&
CGAL_qpe_assertion(!check_tag(Is_nonnegative()) &&
!check_tag(Is_linear()));
r_B_O.resize(B_O.size());
multiply__2D_B_OxN_O(r_B_O.begin());
@ -217,7 +217,7 @@ template < typename Q, typename ET, typename Tags >
void QP_solver<Q, ET, Tags>::
init_w()
{
CGAL_qpe_precondition(!check_tag(Is_nonnegative()) &&
CGAL_qpe_assertion(!check_tag(Is_nonnegative()) &&
!check_tag(Is_linear()));
w.resize(qp_n);
multiply__2D_OxN_O(w.begin());

View File

@ -25,8 +25,8 @@ template < typename Q, typename ET, typename Tags >
ET QP_solver<Q, ET, Tags>::optimality_certificate_numerator(int i) const
{
// we use the vector lambda which conforms to C (basic constraints)
CGAL_qpe_precondition (i >= 0);
CGAL_qpe_precondition (i <= qp_m);
CGAL_qpe_assertion (i >= 0);
CGAL_qpe_assertion (i <= qp_m);
if (no_ineq)
return lambda[i];
else {
@ -710,7 +710,7 @@ bool QP_solver<Q, ET, Tags>::is_solution_unbounded() const
// w^TDw = 0, (C11)
// (c^T+2x^TD)w < 0. (C12)
CGAL_expensive_precondition(is_solution_feasible());
CGAL_expensive_assertion(is_solution_feasible());
// get solution vector of original problem (multiplied by d):
Values x(qp_n, et0);

View File

@ -41,8 +41,8 @@ public:
typedef std::random_access_iterator_tag iterator_category;
typedef typename Map::difference_type difference_type;
typedef typename Map::mapped_type value_type;
typedef value_type* pointer;
typedef value_type& reference;
typedef const value_type* pointer;
typedef const value_type& reference;
typedef Fake_random_access_const_iterator Self;
typedef difference_type Diff;
@ -118,8 +118,8 @@ public:
typedef std::random_access_iterator_tag iterator_category;
typedef Diff difference_type;
typedef typename Op::result_type value_type;
typedef value_type* pointer;
typedef value_type& reference;
typedef const value_type* pointer;
typedef const value_type& reference;
typedef Transform_diff_const_iterator Self;
typedef value_type Val;

View File

@ -27,6 +27,7 @@
#include <boost/iterator/zip_iterator.hpp>
#include <CGAL/Gmpq.h>
#include <CGAL/MP_Float.h>
#include <CGAL/QP_solver.h>
#include <CGAL/QP_solver/QP_full_exact_pricing.h>
#include <CGAL/QP_solver/QP_exact_bland_pricing.h>
@ -37,13 +38,6 @@
#include <CGAL/QP_models.h>
#include <CGAL/QP_functions.h>
using CGAL::Tag_true;
using CGAL::Tag_false;
typedef Tag_false Sparse_D;
typedef Tag_false Sparse_A;
typedef Tag_false Is_linear;
// Routines to output to MPS format:
namespace QP_from_mps_detail {
@ -151,8 +145,7 @@ template<typename IT, // input number type
typename ET> // exact number type compatible with IT (ET is used,
// for instance, by QP in the query methods
// has_equalities_only_and_full_rank())
void create_shifted_instance(CGAL::QP_from_mps
<IT, Is_linear, Sparse_D, Sparse_A>& qp,
void create_shifted_instance(const CGAL::Quadratic_program_from_mps <IT>& qp,
const char *file, // Note: "Bernd3" and
// not "Bernd3.mps".
const char *dir)
@ -172,8 +165,8 @@ void create_shifted_instance(CGAL::QP_from_mps
// where v = [1,...,n]^T.
// extract data from qp:
const int n = qp.n();
const int m = qp.m();
const int n = qp.get_n();
const int m = qp.get_m();
// offset vector:
std::vector<IT> v(n);
@ -184,13 +177,13 @@ void create_shifted_instance(CGAL::QP_from_mps
std::vector<IT> Av(m, IT(0));
for (int i=0; i<m; ++i)
for (int j=0; j<n; ++j)
Av[i] += qp.a()[j][i] * v[j];
Av[i] += qp.get_a()[j][i] * v[j];
// compute - 2 v^T D into mvTD:
std::vector<IT> mvTD(n, IT(0)); // -2D^Tv
for (int i=0; i<n; ++i) {
for (int j=0; j<n; ++j)
mvTD[i] += qp.d()[j][i] * v[j];
mvTD[i] += ( j <= i ? qp.get_d()[i][j] : qp.get_d()[j][i]) * v[j];
mvTD[i] *= -1;
}
@ -204,46 +197,30 @@ void create_shifted_instance(CGAL::QP_from_mps
"", // deduce number-type
"Shifted instance of original file",
"master_mps_to_derivatives-create_shifted_instance",
qp.problem_name(),
qp.get_problem_name(),
CGAL::make_quadratic_program_from_iterators(
n,
m,
qp.a(),
qp.get_a(),
make_transform_iterator(
make_zip_iterator(make_tuple(qp.b(),Av.begin())),
make_zip_iterator(make_tuple(qp.get_b(),Av.begin())),
tuple_add<IT>()),
qp.r(),
qp.fl(),
qp.get_r(),
qp.get_fl(),
make_transform_iterator(
make_zip_iterator(make_tuple(qp.l(),v.begin())),
make_zip_iterator(make_tuple(qp.get_l(),v.begin())),
tuple_add<IT>()),
qp.fu(),
qp.get_fu(),
make_transform_iterator(
make_zip_iterator(make_tuple(qp.u(),v.begin())),
make_zip_iterator(make_tuple(qp.get_u(),v.begin())),
tuple_add<IT>()),
qp.d(),
qp.get_d(),
make_transform_iterator(
make_zip_iterator(make_tuple(qp.c(),mvTD.begin())),
make_zip_iterator(make_tuple(qp.get_c(),mvTD.begin())),
tuple_add<IT>()),
qp.c0()
qp.get_c0()
)
);
// n, m,
// qp.a(),
// make_transform_iterator(
// make_zip_iterator(make_tuple(qp.b(),Av.begin())),
// tuple_add<IT>()),
// make_transform_iterator(
// make_zip_iterator(make_tuple(qp.c(),mvTD.begin())),
// tuple_add<IT>()), qp.c0(),
// qp.d(), qp.fu(), qp.fl(),
// make_transform_iterator(
// make_zip_iterator(make_tuple(qp.u(),v.begin())),
// tuple_add<IT>()),
// make_transform_iterator(
// make_zip_iterator(make_tuple(qp.l(),v.begin())),
// tuple_add<IT>()),
// qp.r());
out->close();
}
@ -251,8 +228,7 @@ template<typename IT, // input number type
typename ET> // exact number type compatible with IT (ET is used,
// for instance, by QP in the query methods
// has_equalities_only_and_full_rank())
void create_free_instance(CGAL::QP_from_mps<IT, Is_linear,
Sparse_D, Sparse_A>& qp_,
void create_free_instance(CGAL::Quadratic_program_from_mps<IT>& qp,
const char *file, // Note: "Bernd3" and
// not "Bernd3.mps".
const char *dir)
@ -266,78 +242,46 @@ void create_free_instance(CGAL::QP_from_mps<IT, Is_linear,
// (and fl and fu are adjusted as well).
// extract data from qp:
const unsigned int n = qp_.n();
const unsigned int m = qp_.m();
// allocate storage (admittedly, I don't care about efficiency and
// elegance here...):
typedef CGAL::QP_from_mps<IT, Is_linear, Sparse_D, Sparse_A> QP_MPS;
typedef typename QP_MPS::Vector Vector;
typedef typename QP_MPS::B_iterator Vector_iterator;
typedef typename QP_MPS::A_Matrix Matrix;
typedef typename QP_MPS::A_Beginner A_Beginner;
typedef typename QP_MPS::A_iterator A_iterator;
typedef CGAL::Comparison_result Row_type;
typedef typename QP_MPS::R_vector R_vector;
// copy the qp
QP_MPS qp (qp_);
// copy some of its vectors (they get manipulated)
Vector b = qp.b_vector();
R_vector row_types = qp.r_vector();
const unsigned int n = qp.get_n();
unsigned int m = qp.get_m();
// add rows to A and corresponding entries to b:
int nr_of_rows_added = 0;
for (unsigned int i=0; i<n; ++i) {
if (*(qp.fl()+i)) { // x >= l
if (*(qp.get_fl()+i)) { // x >= l
// add a row to A:
for (unsigned int j=0; j<n; ++j)
qp.add_entry_in_A (j, b.size(),(i==j? 1 : 0));
//A[j].push_back(i==j? 1 : 0);
qp.set_a (j, m, (i==j? 1 : 0));
// add corresponding entry to b:
b.push_back(qp.l()[i]);
qp.set_b(m, qp.get_l()[i]);
// add corresponding row type:
row_types.push_back(CGAL::LARGER);
++nr_of_rows_added;
qp.set_r(m, CGAL::LARGER);
++m;
}
if (*(qp.fu()+i)) { // x <= u
qp.set_l(i, false); // variable becomes free
if (*(qp.get_fu()+i)) { // x <= u
// add a row to A:
for (unsigned int j=0; j<n; ++j)
qp.add_entry_in_A (j, b.size(),(i==j? 1 : 0));
//A[j].push_back(i==j? 1 : 0);
qp.set_a (j, m ,(i==j? 1 : 0));
// add corresponding entry to b:
b.push_back(qp.u()[i]);
qp.set_b(m, qp.get_u()[i]);
// add corresponding row type:
row_types.push_back(CGAL::SMALLER);
++nr_of_rows_added;
qp.set_r(m, CGAL::SMALLER);
++m;
}
qp.set_u(i, false); // variable becomes free
}
// output:
std::auto_ptr<std::ofstream> out = create_output_file(file, dir, "free");
write_MPS(*out,
"", // deduce number-type
"Freed instance of original file",
"master_mps_to_derivatives-create_free_instance",
qp.problem_name(),
CGAL::make_quadratic_program_from_iterators (
n, m+nr_of_rows_added,
A_iterator(qp.A_matrix().begin(),A_Beginner()),
b.begin(),
row_types.begin(),
CGAL::Const_oneset_iterator<bool>(false), // fl
qp.l(), // dummy
CGAL::Const_oneset_iterator<bool>(false), // fu
qp.u(), // dummy
qp.d(),
qp.c(), qp.c0()));
qp.get_problem_name(),
qp);
out->close();
}
@ -364,20 +308,19 @@ bool create_derivatives(const char *path,
}
// load QP instance:
const int verbosity = 5;
typedef typename QP_from_mps_detail::IT_to_ET<IT>::ET ET;
typedef CGAL::QP_from_mps<IT, Is_linear, Sparse_D, Sparse_A> QP;
QP qp(f,true,verbosity);
typedef CGAL::Quadratic_program_from_mps<IT> QP;
QP qp(f);
// check for format errors in MPS file:
if (!qp.is_valid()) {
msg = "Input is not a valid MPS file: " + qp.error();
msg = "Input is not a valid MPS file: " + qp.get_error();
return false;
}
cerr << " MPS-file successfully input.\n";
// no derivatives if comment says so
if (qp.comment().find(std::string("Derivatives: none"))!=std::string::npos)
if (qp.get_comment().find(std::string("Derivatives: none"))!=std::string::npos)
cerr << " No derivatives made.\n";
else {
// derivates:

View File

@ -55,13 +55,13 @@ int main(const int argNr,const char **args) {
#else
typedef CGAL::Gmpz ET;
#endif
typedef CGAL::QP_from_mps<IT, CGAL::Tag_false, CGAL::Tag_true> QP;
QP qp(std::cin,true,verbosity);
typedef CGAL::Quadratic_program_from_mps<IT> QP;
QP qp(std::cin);
// check for format errors in MPS f\ile:
if (!qp.is_valid()) {
cout << "Input is not a valid MPS file." << endl
<< "Error: " << qp.error() << endl;
<< "Error: " << qp.get_error() << endl;
std::exit(2);
}
@ -84,8 +84,8 @@ int main(const int argNr,const char **args) {
cout << "Variable values:" << endl;
Solver::Variable_value_iterator it
= s.original_variable_values_begin() ;
for (int i=0; i < qp.n(); ++it, ++i)
cout << " " << qp.name_of_variable(i) << " = "
for (int i=0; i < qp.get_n(); ++it, ++i)
cout << " " << qp.get_name_of_variable(i) << " = "
<< CGAL::to_double(*it) << endl;
return 0;
}

View File

@ -0,0 +1,29 @@
#include <cstdlib>
#include <cassert>
#include <iostream>
#include <CGAL/basic.h>
#include <CGAL/QP_models.h>
#include <CGAL/QP_functions.h>
// choose exact integral type
#ifndef CGAL_USE_GMP
#include <CGAL/MP_Float.h>
typedef CGAL::MP_Float ET;
#else
#include <CGAL/Gmpz.h>
typedef CGAL::Gmpz ET;
#endif
int main()
{
CGAL::Quadratic_program<int> qp; // no variables, no constraints
assert (qp.is_valid());
CGAL::Quadratic_program_solution<ET> s =
CGAL::solve_quadratic_program (qp, ET());
std::cout << "Solution = " << s.solution() << std::endl;
std::cout << "Status = " << s.status() << std::endl;
return 0;
}

View File

@ -337,23 +337,15 @@ bool process(const std::string& filename,
// extract verbosity:
const int verbosity = options.find("Verbosity")->second;
// read QP instance, first using dense representation:
// read QP instance
std::ifstream in(filename.c_str());
if (!in)
bailout1("could not open file '%'",filename);
typedef CGAL::Quadratic_program_from_mps <IT> QP_instance;
QP_instance qp(in,true,verbosity);
QP_instance qp(in);
in.close();
// then read it again, using sparse representation
std::ifstream in2(filename.c_str());
if (!in2)
bailout1("could not open file '%'",filename);
typedef CGAL::Sparse_quadratic_program_from_mps <IT> Sparse_QP_instance;
Sparse_QP_instance qp2(in2,true,verbosity);
in2.close();
std::string comment = qp.comment();
std::string comment = qp.get_comment();
// check for the number-type:
Input_type type;
@ -402,26 +394,13 @@ bool process(const std::string& filename,
(is_rational(ET())? "Gmpq" : "Double"))
<< endl;
// check for format errors in MPS file (dense):
// check for format errors in MPS file:
if (!qp.is_valid()) {
cout << "Input is not a valid MPS file." << endl
<< "Error: " << qp.error() << endl;
<< "Error: " << qp.get_error() << endl;
return false;
}
// check for format errors in MPS file (sparse):
if (!qp2.is_valid()) {
cout << "Input is not a valid MPS file." << endl
<< "Error: " << qp2.error() << endl;
return false;
}
// compare qp1, qp2
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp2)) {
cout << "Dense/Sparse readers disagree.\n" << endl;
return false;
}
// print program (using QMATRIX format), read it back in and check
// whether it still agrees with the original program
std::stringstream inout;
@ -430,100 +409,58 @@ bool process(const std::string& filename,
CGAL::QP_functions_detail::print_program
(inout, qp, std::string("test_io_mps"),
Is_linear(),Is_nonnegative());
QP_instance qp3(inout, true, verbosity);
CGAL_qpe_assertion (qp3.is_valid());
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp3)) {
cout << "Warning: MPS reader and MPS writer disagree.\n" << endl;
}
// copy program and check whether it is still the same
if (!qp.is_linear() && !qp.is_nonnegative()) {
CGAL::Quadratic_program<IT> qp4 (qp.n(), qp.m(), qp.a(), qp.b(), qp.r(),
qp.fl(), qp.l(), qp.fu(), qp.u(),
qp.d(), qp.c(), qp.c0());
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp4)) {
cout << "Program not correctly copied.\n" << endl;
return false;
}
// test default/copy constructor, assignment
CGAL::Quadratic_program<IT> qp5;
qp5 = qp4;
if (!CGAL::QP_functions_detail::are_equal_qp (qp5, qp4)) {
cout << "Program not correctly assigned.\n" << endl;
return false;
}
CGAL::Quadratic_program<IT> qp6 (qp4);
if (!CGAL::QP_functions_detail::are_equal_qp (qp6, qp4)) {
cout << "Program not correctly copy-constructed.\n" << endl;
return false;
}
}
if (qp.is_linear() && !qp.is_nonnegative()) {
CGAL::Linear_program<IT> qp4 (qp.n(), qp.m(), qp.a(), qp.b(), qp.r(),
qp.fl(), qp.l(), qp.fu(), qp.u(),
qp.c(), qp.c0());
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp4)) {
cout << "Program not correctly copied.\n" << endl;
return false;
}
// test default/copy constructor, assignment
CGAL::Linear_program<IT> qp5;
qp5 = qp4;
if (!CGAL::QP_functions_detail::are_equal_qp (qp5, qp4)) {
cout << "Program not correctly assigned.\n" << endl;
return false;
}
CGAL::Linear_program<IT> qp6 (qp4);
if (!CGAL::QP_functions_detail::are_equal_qp (qp6, qp4)) {
cout << "Program not correctly copy-constructed.\n" << endl;
return false;
}
}
if (!qp.is_linear() && qp.is_nonnegative()) {
CGAL::Nonnegative_quadratic_program<IT>
qp4 (qp.n(), qp.m(), qp.a(), qp.b(), qp.r(),
qp.d(), qp.c(), qp.c0());
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp4)) {
cout << "Program not correctly copied.\n" << endl;
return false;
}
// test default/copy constructor, assignment
CGAL::Nonnegative_quadratic_program<IT> qp5;
qp5 = qp4;
if (!CGAL::QP_functions_detail::are_equal_qp (qp5, qp4)) {
cout << "Program not correctly assigned.\n" << endl;
return false;
}
CGAL::Nonnegative_quadratic_program<IT> qp6 (qp4);
if (!CGAL::QP_functions_detail::are_equal_qp (qp6, qp4)) {
cout << "Program not correctly copy-constructed.\n" << endl;
return false;
}
}
// test all four readers
if (qp.is_linear() && qp.is_nonnegative()) {
CGAL::Nonnegative_linear_program<IT>
qp4 (qp.n(), qp.m(), qp.a(), qp.b(), qp.r(),
qp.c(), qp.c0());
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp4)) {
cout << "Program not correctly copied.\n" << endl;
return false;
CGAL::Nonnegative_linear_program_from_mps<IT> qp2(inout);
CGAL_qpe_assertion (qp2.is_valid());
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp2)) {
cout << "Warning: MPS reader (NLP) and MPS writer disagree.\n" << endl;
}
// test default/copy constructor, assignment
CGAL::Nonnegative_linear_program<IT> qp5;
qp5 = qp4;
if (!CGAL::QP_functions_detail::are_equal_qp (qp5, qp4)) {
cout << "Program not correctly assigned.\n" << endl;
return false;
}
if (qp.is_linear() && !qp.is_nonnegative()) {
CGAL::Linear_program_from_mps<IT> qp2(inout);
CGAL_qpe_assertion (qp2.is_valid());
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp2)) {
cout << "Warning: MPS reader (LP) and MPS writer disagree.\n" << endl;
}
CGAL::Nonnegative_linear_program<IT> qp6 (qp4);
if (!CGAL::QP_functions_detail::are_equal_qp (qp6, qp4)) {
cout << "Program not correctly copy-constructed.\n" << endl;
return false;
}
if (!qp.is_linear() && !qp.is_nonnegative()) {
CGAL::Quadratic_program_from_mps<IT> qp2(inout);
CGAL_qpe_assertion (qp2.is_valid());
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp2)) {
cout << "Warning: MPS reader (QP) and MPS writer disagree.\n" << endl;
}
}
if (!qp.is_linear() && qp.is_nonnegative()) {
CGAL::Nonnegative_quadratic_program_from_mps<IT> qp2(inout);
CGAL_qpe_assertion (qp2.is_valid());
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp2)) {
cout << "Warning: MPS reader (NQP) and MPS writer disagree.\n" << endl;
}
}
// now copy from the iterators, check for equality
CGAL::Quadratic_program_base<IT>
qp4 (qp.get_n(), qp.get_m(), qp.get_a(), qp.get_b(), qp.get_r(),
qp.get_fl(), qp.get_l(), qp.get_fu(), qp.get_u(),
qp.get_d(), qp.get_c(), qp.get_c0());
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp4)) {
cout << "Program not correctly copied.\n" << endl;
return false;
}
// test consistency of types
if (qp.is_linear() != qp4.is_linear()) {
cout << "Program types inconsistent (linearity): "
<< qp.is_linear() << " vs. " << qp4.is_linear()
<< "\n"<< endl;
return false;
}
if (qp.is_nonnegative() != qp4.is_nonnegative()) {
cout << "Program types inconsistent (nonnegativity): "
<< qp.is_nonnegative() << " vs. " << qp4.is_nonnegative()
<< "\n"<< endl;
return false;
}
typedef CGAL::QP_solver_impl::QP_tags<Is_linear,Is_nonnegative> Tags;
@ -548,14 +485,15 @@ bool process(const std::string& filename,
// general form
typedef CGAL::QP_solver_impl::QP_tags<CGAL::Tag_false,CGAL::Tag_false>
LocalTags;
typedef CGAL::Quadratic_program<IT>
typedef CGAL::Quadratic_program_base<IT>
LocalQP;
CGAL::QP_pricing_strategy<LocalQP, ET, LocalTags> *slocal = new
CGAL::QP_full_exact_pricing <LocalQP, ET, LocalTags>();
LocalQP qplocal (qp.n(), qp.m(), qp.a(), qp.b(), qp.r(),
qp.fl(), qp.l(), qp.fu(), qp.u(),
qp.d(), qp.c(), qp.c0());
LocalQP qplocal (qp.get_n(), qp.get_m(), qp.get_a(), qp.get_b(),
qp.get_r(),
qp.get_fl(), qp.get_l(), qp.get_fu(), qp.get_u(),
qp.get_d(), qp.get_c(), qp.get_c0());
CGAL::QP_solver<LocalQP, ET, LocalTags> solverlocal (qplocal, slocal, 0);
std::cout << "(c) ";
delete slocal;