Matrix Backend for SDP solvers

It stores the SDP data in Sage matrices. It allows users to specify a base ring and can store either floating-point SDPs or exact SDPs with rational or algebraic data.

The class does not provide a solver method. It can be used as a base class for other classes implementing solvers.

class sage.numerical.backends.matrix_sdp_backend.MatrixSDPBackend[source]

Bases: GenericSDPBackend

Cython constructor.

EXAMPLES:

sage: from sage.numerical.backends.generic_sdp_backend import get_solver
sage: p = get_solver(solver = "CVXOPT")
>>> from sage.all import *
>>> from sage.numerical.backends.generic_sdp_backend import get_solver
>>> p = get_solver(solver = "CVXOPT")
add_linear_constraint(coefficients, name=None)[source]

Add a linear constraint.

INPUT:

  • coefficients an iterable with (c,v) pairs where c is a variable index (integer) and v is a value (matrix). The pairs come sorted by indices. If c is -1 it represents the constant coefficient.

  • name – an optional name for this row (default: None)

EXAMPLES:

sage: from sage.numerical.backends.generic_sdp_backend import get_solver
sage: p = get_solver(solver = "CVXOPT")
sage: p.add_variables(2)
1
sage: p.add_linear_constraint(  [(0, matrix([[33., -9.], [-9., 26.]])) , (1,  matrix([[-7., -11.] ,[ -11., 3.]]) )])
sage: p.row(0)
([0, 1],
 [
[ 33.0000000000000 -9.00000000000000]
[-9.00000000000000  26.0000000000000],

[-7.00000000000000 -11.0000000000000]
[-11.0000000000000  3.00000000000000]
])
sage: p.add_linear_constraint(  [(0, matrix([[33., -9.], [-9., 26.]])) , (1,  matrix([[-7., -11.] ,[ -11., 3.]]) )],name='fun')
sage: p.row_name(-1)
'fun'
>>> from sage.all import *
>>> from sage.numerical.backends.generic_sdp_backend import get_solver
>>> p = get_solver(solver = "CVXOPT")
>>> p.add_variables(Integer(2))
1
>>> p.add_linear_constraint(  [(Integer(0), matrix([[RealNumber('33.'), -RealNumber('9.')], [-RealNumber('9.'), RealNumber('26.')]])) , (Integer(1),  matrix([[-RealNumber('7.'), -RealNumber('11.')] ,[ -RealNumber('11.'), RealNumber('3.')]]) )])
>>> p.row(Integer(0))
([0, 1],
 [
[ 33.0000000000000 -9.00000000000000]
[-9.00000000000000  26.0000000000000],
<BLANKLINE>
[-7.00000000000000 -11.0000000000000]
[-11.0000000000000  3.00000000000000]
])
>>> p.add_linear_constraint(  [(Integer(0), matrix([[RealNumber('33.'), -RealNumber('9.')], [-RealNumber('9.'), RealNumber('26.')]])) , (Integer(1),  matrix([[-RealNumber('7.'), -RealNumber('11.')] ,[ -RealNumber('11.'), RealNumber('3.')]]) )],name='fun')
>>> p.row_name(-Integer(1))
'fun'
add_linear_constraints(number, names=None)[source]

Add constraints.

INPUT:

  • number – integer; the number of constraints to add

  • names – an optional list of names (default: None)

EXAMPLES:

sage: from sage.numerical.backends.generic_sdp_backend import get_solver
sage: p = get_solver(solver = "CVXOPT")
sage: p.add_variables(5)
4
sage: p.add_linear_constraints(5)
sage: p.row(4)
([], [])
>>> from sage.all import *
>>> from sage.numerical.backends.generic_sdp_backend import get_solver
>>> p = get_solver(solver = "CVXOPT")
>>> p.add_variables(Integer(5))
4
>>> p.add_linear_constraints(Integer(5))
>>> p.row(Integer(4))
([], [])
add_variable(obj=0.0, name=None)[source]

Add a variable.

This amounts to adding a new column of matrices to the matrix. By default, the variable is both positive and real.

INPUT:

  • obj – (optional) coefficient of this variable in the objective function (default: 0.0)

  • name – an optional name for the newly added variable (default: None)

OUTPUT: the index of the newly created variable

EXAMPLES:

sage: from sage.numerical.backends.generic_sdp_backend import get_solver
sage: p = get_solver(solver = "CVXOPT")
sage: p.ncols()
0
sage: p.add_variable()
0
sage: p.ncols()
1
sage: p.add_variable()
1
sage: p.add_variable(name='x',obj=1.0)
2
sage: p.col_name(2)
'x'
sage: p.objective_coefficient(2)
1.00000000000000
>>> from sage.all import *
>>> from sage.numerical.backends.generic_sdp_backend import get_solver
>>> p = get_solver(solver = "CVXOPT")
>>> p.ncols()
0
>>> p.add_variable()
0
>>> p.ncols()
1
>>> p.add_variable()
1
>>> p.add_variable(name='x',obj=RealNumber('1.0'))
2
>>> p.col_name(Integer(2))
'x'
>>> p.objective_coefficient(Integer(2))
1.00000000000000
add_variables(n, names=None)[source]

Add n variables.

This amounts to adding new columns to the matrix. By default, the variables are both positive and real.

INPUT:

  • n – the number of new variables (must be > 0)

  • names – list of names (default: None)

OUTPUT: the index of the variable created last

EXAMPLES:

sage: from sage.numerical.backends.generic_sdp_backend import get_solver
sage: p = get_solver(solver = "CVXOPT")
sage: p.ncols()
0
sage: p.add_variables(5)
4
sage: p.ncols()
5
sage: p.add_variables(2, names=['a','b'])
6
>>> from sage.all import *
>>> from sage.numerical.backends.generic_sdp_backend import get_solver
>>> p = get_solver(solver = "CVXOPT")
>>> p.ncols()
0
>>> p.add_variables(Integer(5))
4
>>> p.ncols()
5
>>> p.add_variables(Integer(2), names=['a','b'])
6
base_ring()[source]

The base ring.

col_name(index)[source]

Return the index-th col name.

INPUT:

  • index – integer; the col’s id

  • name – (char *) its name; when set to NULL (default), the method returns the current name

EXAMPLES:

sage: from sage.numerical.backends.generic_sdp_backend import get_solver
sage: p = get_solver(solver = "CVXOPT")
sage: p.add_variable(name="I am a variable")
0
sage: p.col_name(0)
'I am a variable'
>>> from sage.all import *
>>> from sage.numerical.backends.generic_sdp_backend import get_solver
>>> p = get_solver(solver = "CVXOPT")
>>> p.add_variable(name="I am a variable")
0
>>> p.col_name(Integer(0))
'I am a variable'
get_matrix()[source]

Get a block of a matrix coefficient.

EXAMPLES:

sage: p = SemidefiniteProgram(solver='cvxopt')
sage: x = p.new_variable()
sage: a1 = matrix([[1, 2.], [2., 3.]])
sage: a2 = matrix([[3, 4.], [4., 5.]])
sage: p.add_constraint(a1*x[0] + a2*x[1] <= a1)
sage: b = p.get_backend()
sage: b.get_matrix()[0][0]
(
    [-1.0 -2.0]
-1, [-2.0 -3.0]
)
>>> from sage.all import *
>>> p = SemidefiniteProgram(solver='cvxopt')
>>> x = p.new_variable()
>>> a1 = matrix([[Integer(1), RealNumber('2.')], [RealNumber('2.'), RealNumber('3.')]])
>>> a2 = matrix([[Integer(3), RealNumber('4.')], [RealNumber('4.'), RealNumber('5.')]])
>>> p.add_constraint(a1*x[Integer(0)] + a2*x[Integer(1)] <= a1)
>>> b = p.get_backend()
>>> b.get_matrix()[Integer(0)][Integer(0)]
(
    [-1.0 -2.0]
-1, [-2.0 -3.0]
)
is_maximization()[source]

Test whether the problem is a maximization

EXAMPLES:

sage: from sage.numerical.backends.generic_sdp_backend import get_solver
sage: p = get_solver(solver = "CVXOPT")
sage: p.is_maximization()
True
sage: p.set_sense(-1)
sage: p.is_maximization()
False
>>> from sage.all import *
>>> from sage.numerical.backends.generic_sdp_backend import get_solver
>>> p = get_solver(solver = "CVXOPT")
>>> p.is_maximization()
True
>>> p.set_sense(-Integer(1))
>>> p.is_maximization()
False
ncols()[source]

Return the number of columns/variables.

EXAMPLES:

sage: from sage.numerical.backends.generic_sdp_backend import get_solver
sage: p = get_solver(solver = "CVXOPT")
sage: p.ncols()
0
sage: p.add_variables(2)
1
sage: p.ncols()
2
>>> from sage.all import *
>>> from sage.numerical.backends.generic_sdp_backend import get_solver
>>> p = get_solver(solver = "CVXOPT")
>>> p.ncols()
0
>>> p.add_variables(Integer(2))
1
>>> p.ncols()
2
nrows()[source]

Return the number of rows/constraints.

EXAMPLES:

sage: from sage.numerical.backends.generic_sdp_backend import get_solver
sage: p = get_solver(solver = "CVXOPT")
sage: p.nrows()
0
sage: p.add_variables(5)
4
sage: p.add_linear_constraints(2)
sage: p.nrows()
2
>>> from sage.all import *
>>> from sage.numerical.backends.generic_sdp_backend import get_solver
>>> p = get_solver(solver = "CVXOPT")
>>> p.nrows()
0
>>> p.add_variables(Integer(5))
4
>>> p.add_linear_constraints(Integer(2))
>>> p.nrows()
2
objective_coefficient(variable, coeff=None)[source]

Set or get the coefficient of a variable in the objective function

INPUT:

  • variable – integer; the variable’s id

  • coeff – double; its coefficient

EXAMPLES:

sage: from sage.numerical.backends.generic_sdp_backend import get_solver
sage: p = get_solver(solver = "CVXOPT")
sage: p.add_variable()
0
sage: p.objective_coefficient(0)
0.0
sage: p.objective_coefficient(0,2)
sage: p.objective_coefficient(0)
2.0
>>> from sage.all import *
>>> from sage.numerical.backends.generic_sdp_backend import get_solver
>>> p = get_solver(solver = "CVXOPT")
>>> p.add_variable()
0
>>> p.objective_coefficient(Integer(0))
0.0
>>> p.objective_coefficient(Integer(0),Integer(2))
>>> p.objective_coefficient(Integer(0))
2.0
problem_name(name=None)[source]

Return or define the problem’s name.

INPUT:

  • name – string; the problem’s name. When set to NULL (default), the method returns the problem’s name.

EXAMPLES:

sage: from sage.numerical.backends.generic_sdp_backend import get_solver
sage: p = get_solver(solver = "CVXOPT")
sage: p.problem_name("There once was a french fry")
sage: print(p.problem_name())
There once was a french fry
>>> from sage.all import *
>>> from sage.numerical.backends.generic_sdp_backend import get_solver
>>> p = get_solver(solver = "CVXOPT")
>>> p.problem_name("There once was a french fry")
>>> print(p.problem_name())
There once was a french fry
row(i)[source]

Return a row.

INPUT:

  • index – integer; the constraint’s id

OUTPUT:

A pair (indices, coeffs) where indices lists the entries whose coefficient is nonzero, and to which coeffs associates their coefficient on the model of the add_linear_constraint method.

EXAMPLES:

sage: from sage.numerical.backends.generic_sdp_backend import get_solver
sage: p = get_solver(solver = "CVXOPT")
sage: p.add_variables(5)
4
sage: p.add_linear_constraint(  [(0, matrix([[33., -9.], [-9., 26.]])) , (1,  matrix([[-7., -11.] ,[ -11., 3.]]) )])
sage: p.row(0)
([0, 1],
 [
[ 33.0000000000000 -9.00000000000000]
[-9.00000000000000  26.0000000000000],

[-7.00000000000000 -11.0000000000000]
[-11.0000000000000  3.00000000000000]
])
>>> from sage.all import *
>>> from sage.numerical.backends.generic_sdp_backend import get_solver
>>> p = get_solver(solver = "CVXOPT")
>>> p.add_variables(Integer(5))
4
>>> p.add_linear_constraint(  [(Integer(0), matrix([[RealNumber('33.'), -RealNumber('9.')], [-RealNumber('9.'), RealNumber('26.')]])) , (Integer(1),  matrix([[-RealNumber('7.'), -RealNumber('11.')] ,[ -RealNumber('11.'), RealNumber('3.')]]) )])
>>> p.row(Integer(0))
([0, 1],
 [
[ 33.0000000000000 -9.00000000000000]
[-9.00000000000000  26.0000000000000],
<BLANKLINE>
[-7.00000000000000 -11.0000000000000]
[-11.0000000000000  3.00000000000000]
])
row_name(index)[source]

Return the index-th row name.

INPUT:

  • index – integer; the row’s id

EXAMPLES:

sage: from sage.numerical.backends.generic_sdp_backend import get_solver
sage: p = get_solver(solver = "CVXOPT")
sage: p.add_linear_constraints(1, names='A')
sage: p.row_name(0)
'A'
>>> from sage.all import *
>>> from sage.numerical.backends.generic_sdp_backend import get_solver
>>> p = get_solver(solver = "CVXOPT")
>>> p.add_linear_constraints(Integer(1), names='A')
>>> p.row_name(Integer(0))
'A'
set_objective(coeff, d=0.0)[source]

Set the objective function.

INPUT:

  • coeff – list of real values, whose i-th element is the coefficient of the i-th variable in the objective function

  • d – double; the constant term in the linear function (set to \(0\) by default)

EXAMPLES:

sage: from sage.numerical.backends.generic_sdp_backend import get_solver
sage: p = get_solver(solver = "CVXOPT")
sage: p.add_variables(5)
4
sage: p.set_objective([1, 1, 2, 1, 3])
sage: [p.objective_coefficient(x) for x in range(5)]
[1, 1, 2, 1, 3]
>>> from sage.all import *
>>> from sage.numerical.backends.generic_sdp_backend import get_solver
>>> p = get_solver(solver = "CVXOPT")
>>> p.add_variables(Integer(5))
4
>>> p.set_objective([Integer(1), Integer(1), Integer(2), Integer(1), Integer(3)])
>>> [p.objective_coefficient(x) for x in range(Integer(5))]
[1, 1, 2, 1, 3]
set_sense(sense)[source]

Set the direction (maximization/minimization).

INPUT:

  • sense – integer:

    • +1 => Maximization

    • -1 => Minimization

EXAMPLES:

sage: from sage.numerical.backends.generic_sdp_backend import get_solver
sage: p = get_solver(solver = "CVXOPT")
sage: p.is_maximization()
True
sage: p.set_sense(-1)
sage: p.is_maximization()
False
>>> from sage.all import *
>>> from sage.numerical.backends.generic_sdp_backend import get_solver
>>> p = get_solver(solver = "CVXOPT")
>>> p.is_maximization()
True
>>> p.set_sense(-Integer(1))
>>> p.is_maximization()
False