picos.modeling.problem

Implementation of Problem.

Exceptions

exception picos.modeling.problem.SolutionFailure(code, message)[source]

Bases: RuntimeError

Solving the problem failed.

Classes

class picos.modeling.problem.Problem(name=None, *, copyOptions=None, useOptions=None, **extra_options)[source]

Bases: Valuable

PICOS’ representation of an optimization problem.

Example

>>> from picos import Problem, RealVariable
>>> X = RealVariable("X", (2,2), lower = 0)
>>> P = Problem("Example")
>>> P.maximize = X.tr
>>> C = X.sum <= 10
>>> P += C, X[0,0] == 1
>>> print(P)
Example (Linear Program)
  maximize tr(X)
  over
    2×2 real variable X (bounded below)
  subject to
    ∑(X) ≤ 10
    X[0,0] = 1
>>> # PICOS will select a suitable solver if you don't specify one.
>>> solution = P.solve(solver = "cvxopt")
>>> solution.claimedStatus
'optimal'
>>> solution.searchTime 
0.002137422561645508
>>> round(P, 1)
10.0
>>> print(X) 
[ 1.00e+00  4.89e-10]
[ 4.89e-10  9.00e+00]
>>> round(C.dual, 1)
1.0
__iadd__(constraints)[source]

See require.

__init__(name=None, *, copyOptions=None, useOptions=None, **extra_options)[source]

Create an empty problem and optionally set initial solver options.

Parameters
  • name (str) – A name or title to give to the optimization problem.

  • copyOptions – An Options object to copy instead of using the default options.

  • useOptions – An Options object to use (without making a copy) instead of using the default options.

  • extra_options – A sequence of additional solver options to apply on top of the default options or those given by copyOptions or useOptions.

add_constraint(constraint, key=None)[source]

Add a single constraint to the problem and return it.

Parameters
  • constraint (Constraint) – The constraint to be added.

  • key – DEPRECATED

Returns

The constraint that was added to the problem.

Note

This method is superseded by the more compact and more flexible require method or, at your preference, the += operator.

add_list_of_constraints(lst, it=None, indices=None, key=None)[source]

Add constraints from an iterable to the problem.

Parameters
  • lst – Iterable of constraints to add.

  • it – DEPRECATED

  • indices – DEPRECATED

  • key – DEPRECATED

Returns

A list of all constraints that were added.

Example

>>> import picos as pic
>>> import cvxopt as cvx
>>> from pprint import pprint
>>> prob=pic.Problem()
>>> x=[prob.add_variable('x[{0}]'.format(i),2) for i in range(5)]
>>> pprint(x)
[<2×1 Real Variable: x[0]>,
 <2×1 Real Variable: x[1]>,
 <2×1 Real Variable: x[2]>,
 <2×1 Real Variable: x[3]>,
 <2×1 Real Variable: x[4]>]
>>> y=prob.add_variable('y',5)
>>> IJ=[(1,2),(2,0),(4,2)]
>>> w={}
>>> for ij in IJ:
...         w[ij]=prob.add_variable('w[{},{}]'.format(*ij),3)
...
>>> u=pic.new_param('u',cvx.matrix([2,5]))
>>> C1=prob.add_list_of_constraints([u.T*x[i] < y[i] for i in range(5)])
>>> C2=prob.add_list_of_constraints([abs(w[i,j])<y[j] for (i,j) in IJ])
>>> C3=prob.add_list_of_constraints([y[t] > y[t+1] for t in range(4)])
>>> print(prob)
Feasibility Problem
  find an assignment
  for
    2×1 real variable x[i] ∀ i ∈ [0…4]
    3×1 real variable w[i,j] ∀ (i,j) ∈ zip([1,2,4],[2,0,2])
    5×1 real variable y
  subject to
    uᵀ·x[i] ≤ y[i] ∀ i ∈ [0…4]
    ‖w[i,j]‖ ≤ y[j] ∀ (i,j) ∈ zip([1,2,4],[2,0,2])
    y[i] ≥ y[i+1] ∀ i ∈ [0…3]

Note

This method is superseded by the more compact and more flexible require method or, at your preference, the += operator.

add_variable(name, size=1, vtype='continuous', lower=None, upper=None)[source]

Legacy method to create a PICOS variable.

Parameters
  • name (str) – The name of the variable.

  • size (anything recognized by load_shape) – The shape of the variable.

  • vtype (str) –

    Domain of the variable. Can be any of

    • 'continuous' – real valued,

    • 'binary' – either zero or one,

    • 'integer' – integer valued,

    • 'symmetric' – symmetric matrix,

    • 'antisym' or 'skewsym' – skew-symmetric matrix,

    • 'complex' – complex matrix,

    • 'hermitian' – complex hermitian matrix.

  • lower (anything recognized by load_data) – A lower bound on the variable.

  • upper (anything recognized by load_data) – An upper bound on the variable.

Returns

A BaseVariable instance.

Example

>>> from picos import Problem
>>> P = Problem()
>>> x = P.add_variable("x", 3)
>>> x
<3×1 Real Variable: x>
>>> # Variable are not stored inside the problem any more:
>>> P.variables
mappingproxy(OrderedDict())
>>> # They are only part of the problem if they actually appear:
>>> P.set_objective("min", abs(x)**2)
>>> P.variables
mappingproxy(OrderedDict([('x', <3×1 Real Variable: x>)]))

Deprecated since version 2.0: Variables can now be created independent of problems, and do not need to be added to any problem explicitly.

as_dual()[source]

Return the Lagrangian dual problem of the standardized problem.

Deprecated since version 2.0: Use dual instead.

check_current_value_feasibility(tol=1e-5, inttol=None)[source]

Check if the problem is feasibly valued.

Checks whether all variables that appear in constraints are valued and satisfy both their bounds and the constraints up to the given tolerance.

Parameters
  • tol (float) – Largest tolerated absolute violation of a constraint or variable bound. If None, then the abs_prim_fsb_tol solver option is used.

  • inttol – DEPRECATED

Returns

A tuple (feasible, violation) where feasible is a bool stating whether the solution is feasible and violation is either None, if feasible == True, or the amount of violation, otherwise.

Raises

picos.uncertain.IntractableWorstCase – When computing the worst-case (expected) value of the constrained expression is not supported.

clone(copyOptions=True)[source]

Create a semi-deep copy of the problem.

The copy is constrained by the same constraint objects and has the same objective function and thereby references the existing variables and parameters that appear in these objects.

The clone can be modified to describe a new problem but when its variables and parameters are valued, in particular when a solution is applied to the new problem, then the same values are found in the corresponding variables and parameters of the old problem. If this is not a problem to you, then cloning can be much faster than copying.

Parameters

copyOptions (bool) – Whether to make an independent copy of the problem’s options. Disabling this will apply any option changes to the original problem as well but yields a (very small) reduction in cloning time.

continuous_relaxation(copy_other_mutables=True)[source]

Return a continuous relaxation of the problem.

This is done by replacing integer variables with continuous ones.

Parameters

copy_other_mutables (bool) – Whether variables that are already continuous as well as parameters should be copied. If this is False, then the relxation shares these mutables with the original problem.

copy()[source]

Create a deep copy of the problem, using new mutables.

get_constraint(idOrIndOrCon)[source]

Return a (list of) constraint(s) of the problem.

Parameters

idOrIndOrCon (picos.constraints.Constraint or int or tuple or list) –

One of the following:

  • A constraint object. It will be returned when the constraint is part of the problem, otherwise a KeyError is raised.

  • The integer ID of the constraint.

  • The integer offset of the constraint in the list of all constraints that are part of the problem, in the order that they were added.

  • A list or tuple of length 1. Its only element is the index of a constraint group (of constraints that were added together), where groups are indexed in the order that they were added to the problem. The whole group is returned as a list of constraints. That list has the constraints in the order that they were added.

  • A list or tuple of length 2. The first element is a constraint group offset as above, the second an offset within that list.

Returns

A constraint or a list thereof.

Example

>>> import picos as pic
>>> import cvxopt as cvx
>>> from pprint import pprint
>>> prob=pic.Problem()
>>> x=[prob.add_variable('x[{0}]'.format(i),2) for i in range(5)]
>>> y=prob.add_variable('y',5)
>>> Cx=prob.add_list_of_constraints([(1|x[i]) < y[i] for i in range(5)])
>>> Cy=prob.add_constraint(y>0)
>>> print(prob)
Linear Feasibility Problem
  find an assignment
  for
    2×1 real variable x[i] ∀ i ∈ [0…4]
    5×1 real variable y
  subject to
    ∑(x[i]) ≤ y[i] ∀ i ∈ [0…4]
    y ≥ 0
>>> # Retrieve the second constraint, indexed from zero:
>>> prob.get_constraint(1)
<1×1 Affine Constraint: ∑(x[1]) ≤ y[1]>
>>> # Retrieve the fourth consraint from the first group:
>>> prob.get_constraint((0,3))
<1×1 Affine Constraint: ∑(x[3]) ≤ y[3]>
>>> # Retrieve the whole first group of constraints:
>>> pprint(prob.get_constraint((0,)))
[<1×1 Affine Constraint: ∑(x[0]) ≤ y[0]>,
 <1×1 Affine Constraint: ∑(x[1]) ≤ y[1]>,
 <1×1 Affine Constraint: ∑(x[2]) ≤ y[2]>,
 <1×1 Affine Constraint: ∑(x[3]) ≤ y[3]>,
 <1×1 Affine Constraint: ∑(x[4]) ≤ y[4]>]
>>> # Retrieve the second "group", containing just one constraint:
>>> prob.get_constraint((1,))
[<5×1 Affine Constraint: y ≥ 0>]
get_valued_variable(name)[source]

Retrieve values of variables referenced by the problem.

This method works the same get_variable but it returns the variable’s values instead of the variable objects.

Raises

NotValued – If any of the selected variables is not valued.

get_variable(name)[source]

Retrieve variables referenced by the problem.

Retrieves either a single variable with the given name or a group of variables all named name[param] with different values for param. If the values for param are the integers from zero to the size of the group minus one, then the group is returned as a list ordered by param, otherwise it is returned as a dict with the values of param as keys.

Note

Since PICOS 2.0, variables are independent of problems and only appear in a problem for as long as they are referenced by the problem’s objective function or constraints.

Parameters

name (str) – The name of a variable, or the base name of a group of variables.

Returns

A variable or a list or dict thereof.

Example

>>> from picos import Problem, RealVariable
>>> from pprint import pprint
>>> # Create a number of variables with structured names.
>>> vars = [RealVariable("x")]
>>> for i in range(4):
...     vars.append(RealVariable("y[{}]".format(i)))
>>> for key in ["alice", "bob", "carol"]:
...     vars.append(RealVariable("z[{}]".format(key)))
>>> # Make the variables appear in a problem.
>>> P = Problem()
>>> P.set_objective("min", sum([var for var in vars]))
>>> print(P)
Linear Program
  minimize x + y[0] + y[1] + y[2] + y[3] + z[alice] + z[bob] + z[carol]
  over
    1×1 real variables x, y[0], y[1], y[2], y[3], z[alice], z[bob],
      z[carol]
>>> # Retrieve the variables from the problem.
>>> P.get_variable("x")
<1×1 Real Variable: x>
>>> pprint(P.get_variable("y"))
[<1×1 Real Variable: y[0]>,
 <1×1 Real Variable: y[1]>,
 <1×1 Real Variable: y[2]>,
 <1×1 Real Variable: y[3]>]
>>> pprint(P.get_variable("z"))
{'alice': <1×1 Real Variable: z[alice]>,
 'bob': <1×1 Real Variable: z[bob]>,
 'carol': <1×1 Real Variable: z[carol]>}
>>> P.get_variable("z")["alice"] is P.get_variable("z[alice]")
True
is_continuous()[source]

Whether all variables are of continuous types.

Deprecated since version 2.0: Use continuous instead.

is_pure_integer()[source]

Whether all variables are of integral types.

Deprecated since version 2.0: Use pure_integer instead.

obj_value()[source]

Objective function value.

Raises

AttributeError – If the problem is a feasibility problem or if the objective function is not valued. This is legacy behavior. Note that value just returns None while functions that do raise an exception to denote an unvalued expression would raise NotValued instead.

Deprecated since version 2.0: Use value instead.

prepared(steps=None, **extra_options)[source]

Perform a dry-run returning the reformulated (prepared) problem.

This behaves like solve in that it takes a number of additional temporary options, finds a solution strategy matching the problem and options, and performs the strategy’s reformulations in turn to obtain modified problems. However, it stops after the given number of steps and never hands the reformulated problem to a solver. Instead of a solution, prepared then returns the last reformulated problem.

Unless this method returns the problem itself, the special attributes prepared_strategy and prepared_steps are added to the returned problem. They then contain the (partially) executed solution strategy and the number of performed reformulations, respectively.

Parameters
  • steps (int) – Number of reformulations to perform. None means as many as there are. If this parameter is 0, then the problem itself is returned. If it is 1, then only the implicit first reformulation ExtraOptions is executed, which may also output the problem itself, depending on extra_options.

  • extra_options – Additional solver options to use with this dry-run only.

Returns

The reformulated problem, with extra_options set unless they were “consumed” by a reformulation (e.g. option_dualize).

Raises
  • NoStrategyFound – If no solution strategy was found.

  • ValueError – If there are not as many reformulation steps as requested.

Example

>>> from picos import Problem, RealVariable
>>> x = RealVariable("x", 2)
>>> P = Problem()
>>> P.set_objective("min", abs(x)**2)
>>> Q = P.prepared(solver = "cvxopt")
>>> print(Q.prepared_strategy)  # Show prepared reformulation steps.
1. ExtraOptions
2. EpigraphReformulation
3. SquaredNormToConicReformulation
4. CVXOPTSolver
>>> Q.prepared_steps  # Check how many steps have been performed.
3
>>> print(P)
Quadratic Program
  minimize ‖x‖²
  over
    2×1 real variable x
>>> print(Q)
Second Order Cone Program
  minimize __..._t
  over
    1×1 real variable __..._t
    2×1 real variable x
  subject to
    ‖fullroot(‖x‖²)‖² ≤ __..._t ∧ __..._t ≥ 0
reformulated(specification, **extra_options)[source]

Return the problem reformulated to match a specification.

Internally this creates a dummy solver accepting problems of the desired form and then calls prepared with the dummy solver passed via option_ad_hoc_solver. See meth:prepared for more details.

Parameters
  • specification (Specification) – A problem class that the resulting problem must be a member of.

  • extra_options – Additional solver options to use with this reformulation only.

Returns

The reformulated problem, with extra_options set unless they were “consumed” by a reformulation (e.g. dualize).

Raises

NoStrategyFound – If no reformulation strategy was found.

Example

>>> from picos import Problem, RealVariable
>>> from picos.modeling import Specification
>>> from picos.expressions import AffineExpression
>>> from picos.constraints import (
...     AffineConstraint, SOCConstraint, RSOCConstraint)
>>> # Define the class/specification of second order conic problems:
>>> S = Specification(objectives=[AffineExpression],
...     constraints=[AffineConstraint, SOCConstraint, RSOCConstraint])
>>> # Define a quadratic program and reformulate it:
>>> x = RealVariable("x", 2)
>>> P = Problem()
>>> P.set_objective("min", abs(x)**2)
>>> Q = P.reformulated(S)
>>> print(P)
Quadratic Program
  minimize ‖x‖²
  over
    2×1 real variable x
>>> print(Q)
Second Order Cone Program
  minimize __..._t
  over
    1×1 real variable __..._t
    2×1 real variable x
  subject to
    ‖fullroot(‖x‖²)‖² ≤ __..._t ∧ __..._t ≥ 0

Note

This method is intended for educational purposes. You do not need to use it when solving a problem as PICOS will perform the necessary reformulations automatically.

remove_all_constraints()[source]

Remove all constraints from the problem.

Note

This method does not remove bounds set directly on variables.

remove_constraint(idOrIndOrCon)[source]

Delete a constraint from the problem.

Parameters

idOrIndOrCon – See get_constraint.

Example

>>> import picos
>>> from pprint import pprint
>>> P = picos.Problem()
>>> x = [P.add_variable('x[{0}]'.format(i), 2) for i in range(4)]
>>> y = P.add_variable('y', 4)
>>> Cxy = P.add_list_of_constraints(
...     [(1 | x[i]) <= y[i] for i in range(4)])
>>> Cy = P.add_constraint(y >= 0)
>>> Cx0to2 = P.add_list_of_constraints([x[i] <= 2 for i in range(3)])
>>> Cx3 = P.add_constraint(x[3] <= 1)
>>> pprint(list(P.constraints.values()))
[<1×1 Affine Constraint: ∑(x[0]) ≤ y[0]>,
 <1×1 Affine Constraint: ∑(x[1]) ≤ y[1]>,
 <1×1 Affine Constraint: ∑(x[2]) ≤ y[2]>,
 <1×1 Affine Constraint: ∑(x[3]) ≤ y[3]>,
 <4×1 Affine Constraint: y ≥ 0>,
 <2×1 Affine Constraint: x[0] ≤ [2]>,
 <2×1 Affine Constraint: x[1] ≤ [2]>,
 <2×1 Affine Constraint: x[2] ≤ [2]>,
 <2×1 Affine Constraint: x[3] ≤ [1]>]
>>> # Delete the 2nd constraint (counted from 0):
>>> P.remove_constraint(1)
>>> pprint(list(P.constraints.values()))
[<1×1 Affine Constraint: ∑(x[0]) ≤ y[0]>,
 <1×1 Affine Constraint: ∑(x[2]) ≤ y[2]>,
 <1×1 Affine Constraint: ∑(x[3]) ≤ y[3]>,
 <4×1 Affine Constraint: y ≥ 0>,
 <2×1 Affine Constraint: x[0] ≤ [2]>,
 <2×1 Affine Constraint: x[1] ≤ [2]>,
 <2×1 Affine Constraint: x[2] ≤ [2]>,
 <2×1 Affine Constraint: x[3] ≤ [1]>]
>>> # Delete the 2nd group of constraints, i.e. the constraint y > 0:
>>> P.remove_constraint((1,))
>>> pprint(list(P.constraints.values()))
[<1×1 Affine Constraint: ∑(x[0]) ≤ y[0]>,
 <1×1 Affine Constraint: ∑(x[2]) ≤ y[2]>,
 <1×1 Affine Constraint: ∑(x[3]) ≤ y[3]>,
 <2×1 Affine Constraint: x[0] ≤ [2]>,
 <2×1 Affine Constraint: x[1] ≤ [2]>,
 <2×1 Affine Constraint: x[2] ≤ [2]>,
 <2×1 Affine Constraint: x[3] ≤ [1]>]
>>> # Delete the 3rd remaining group of constraints, i.e. x[3] < [1]:
>>> P.remove_constraint((2,))
>>> pprint(list(P.constraints.values()))
[<1×1 Affine Constraint: ∑(x[0]) ≤ y[0]>,
 <1×1 Affine Constraint: ∑(x[2]) ≤ y[2]>,
 <1×1 Affine Constraint: ∑(x[3]) ≤ y[3]>,
 <2×1 Affine Constraint: x[0] ≤ [2]>,
 <2×1 Affine Constraint: x[1] ≤ [2]>,
 <2×1 Affine Constraint: x[2] ≤ [2]>]
>>> # Delete 2nd constraint of the 2nd remaining group, i.e. x[1] < |2|:
>>> P.remove_constraint((1,1))
>>> pprint(list(P.constraints.values()))
[<1×1 Affine Constraint: ∑(x[0]) ≤ y[0]>,
 <1×1 Affine Constraint: ∑(x[2]) ≤ y[2]>,
 <1×1 Affine Constraint: ∑(x[3]) ≤ y[3]>,
 <2×1 Affine Constraint: x[0] ≤ [2]>,
 <2×1 Affine Constraint: x[2] ≤ [2]>]
remove_variable(name)[source]

Does nothing.

Deprecated since version 2.0: Whether a problem references a variable is now determined dynamically, so this method has no effect.

require(*constraints, ret=False)[source]

Add constraints to the problem.

Parameters
  • constraints – A sequence of constraints or constraint groups (iterables yielding constraints) or a mix thereof.

  • ret (bool) – Whether to return the added constraints.

Returns

When ret=True, returns either the single constraint that was added, the single group of constraint that was added in the form of a list or, when multiple arguments are given, a list of constraints or constraint groups represented as above. When ret=False, returns nothing.

Example

>>> from picos import Problem, RealVariable
>>> x = RealVariable("x", 5)
>>> P = Problem()
>>> P.require(x >= -1, x <= 1)  # Add individual constraints.
>>> P.require([x[i] <= x[i+1] for i in range(4)])  # Add groups.
>>> print(P)
Linear Feasibility Problem
  find an assignment
  for
    5×1 real variable x
  subject to
    x ≥ [-1]
    x ≤ [1]
    x[i] ≤ x[i+1] ∀ i ∈ [0…3]

Note

For a single constraint C, P.require(C) may also be written as P += C. For multiple constraints, P.require([C1, C2]) can be abbreviated P += [C1, C2] while P.require(C1, C2) can be written as either P += (C1, C2) or just P += C1, C2.

reset(resetOptions=False)[source]

Reset the problem instance to its initial empty state.

Parameters

resetOptions (bool) – Whether also solver options should be reset to their default values.

set_all_options_to_default()[source]

Set all solver options to their default value.

Deprecated since version 2.0: Use Problem.options instead.

set_objective(direction=None, expression=None)[source]

Set the optimization direction and objective function of the problem.

Parameters
  • direction (str) –

    Case insensitive search direction string. One of

    • "min" or "minimize",

    • "max" or "maximize",

    • "find" or None (for a feasibility problem).

  • expression (Expression) – The objective function. Must be None for a feasibility problem.

set_option(key, val)[source]

Set a single solver option to the given value.

Parameters
  • key (str) – String name of the option, see below for a list.

  • val – New value for the option.

Deprecated since version 2.0: Use Problem.options instead.

set_var_value(name, value)[source]

Set the value of a variable.

For a Problem P, this is the same as P.variables[name] = value.

Parameters
  • name (str) – Name of the variable to be valued.

  • value (anything recognized by load_data) – The value to be set.

Deprecated since version 2.0: Use variables instead.

solve(**extra_options)[source]

Hand the problem to a solver.

You can select the solver manually with the solver option. Otherwise a suitable solver will be selected among those that are available on the platform.

The default behavior (options primals=True, duals=None) is to raise a SolutionFailure when the primal solution is not found optimal by the solver, while the dual solution is allowed to be missing or incomplete.

When this method succeeds and unless apply_solution=False, you can access the solution as follows:

  • The problem’s value denotes the objective function value.

  • The variables’ value is set according to the primal solution. You can in fact query the value of any expression involving valued variables like this.

  • The constraints’ dual is set according to the dual solution.

  • The value of any parameter involved in the problem may have changed, depending on the parameter.

Parameters

extra_options

A sequence of additional solver options to use with this solution search only. In particular, this lets you

  • select a solver via the solver option,

  • obtain non-optimal primal solutions by setting primals=None,

  • require a complete and optimal dual solution with duals=True, and

  • skip valuing variables or constraints with apply_solution=False.

Returns ~picos.Solution or list(~picos.Solution)

A solution object or list thereof.

Raises

SolutionFailure

In the following cases:

  1. No solution strategy was found.

  2. Multiple solutions were requested but none were returned.

  3. A primal solution was explicitly requested (primals=True) but the primal solution is missing/incomplete or not claimed optimal.

  4. A dual solution was explicitly requested (duals=True) but the dual solution is missing/incomplete or not claimed optimal.

The case number is stored in the code attribute of the exception.

update_options(**options)[source]

Set multiple solver options at once.

Parameters

options – A parameter sequence of options to set.

Deprecated since version 2.0: Use Problem.options instead.

verbosity()[source]

Return the problem’s current verbosity level.

Deprecated since version 2.0: Use Problem.options instead.

write_to_file(filename, writer='picos')[source]

See picos.modeling.file_out.write.

CONIC_FORM = <Specification: Optimize AffineExpression subject to AffineConstraint, ComplexAffineConstraint, ComplexLMIConstraint, DummyConstraint, LMIConstraint, ProductConeConstraint, RSOCConstraint, SOCConstraint using any variables and any options.>

The specification for problems returned by conic_form.

property conic_form

The problem in conic form.

Reformulates the problem such that the objective is affine and all constraints are ConicConstraint instances.

Raises

NoStrategyFound – If no reformulation strategy was found.

Example

>>> from picos import Problem, RealVariable
>>> x = RealVariable("x", 2)
>>> P = Problem()
>>> P.set_objective("min", abs(x)**2)
>>> print(P)
Quadratic Program
  minimize ‖x‖²
  over
    2×1 real variable x
>>> print(P.conic_form)
Second Order Cone Program
  minimize __..._t
  over
    1×1 real variable __..._t
    2×1 real variable x
  subject to
    ‖fullroot(‖x‖²)‖² ≤ __..._t ∧ __..._t ≥ 0

Note

This property is intended for educational purposes. You do not need to use it when solving a problem as PICOS will perform the necessary reformulations automatically.

property constraints

Maps constraint IDs to constraints that are part of the problem.

Returns

A read-only view to an OrderedDict. The order is that in which constraints were added.

property continuous

Whether all variables are of continuous types.

property countCons

The same as len applied to constraints.

Deprecated since version 2.0: Still used internally by legacy code; will be removed together with that code.

property countVar

The same as len applied to variables.

Deprecated since version 2.0: Still used internally by legacy code; will be removed together with that code.

property dual

The Lagrangian dual problem of the standardized problem.

More precisely, this property invokes the following:

  1. The primal problem is posed as an equivalent conic standard form minimization problem, with variable bounds expressed as additional constraints.

  2. The Lagrangian dual problem of the reposed primal is computed.

  3. The optimization direction and objective function sign of the dual are adjusted such that, given strong duality and primal feasibility, the optimal values of both problems are equal. In particular, if the primal problem is a minimization or a maximization problem, the dual problem returned will be the respective other.

Raises

NoStrategyFound – If no reformulation strategy was found.

Note

This property is intended for educational purposes. If you want to solve the primal problem via its dual, use the dualize option instead.

property footprint

Problem footprint as a Footprint object.

property last_solution

The last Solution applied to the problem.

property maximize

Maximization objective as an Expression.

This can be used to set a maximization objective. For querying the objective, it is recommended to use objective instead.

property minimize

Minimization objective as an Expression.

This can be used to set a minimization objective. For querying the objective, it is recommended to use objective instead.

property mutables

Maps names to variables and parameters in use by the problem.

Returns

A read-only view to an OrderedDict. The order is deterministic and depends on the order of operations performed on the Problem instance as well as on the mutables’ names.

property name

Name or title of the problem.

property no

Normalized objective as an Objective instance.

Either a minimization or a maximization objective, with feasibility posed as “minimize 0”.

The same as the normalized attribute of the objective.

property numberConeConstraints

Number of quadratic conic constraints stored.

Deprecated since version 2.0: Still used internally by legacy code; will be removed together with that code.

property numberLSEConstraints

Number of LogSumExpConstraint stored.

Deprecated since version 2.0: Still used internally by legacy code; will be removed together with that code.

property numberOfVars

The sum of the dimensions of all referenced variables.

Deprecated since version 2.0: Still used internally by legacy code; will be removed together with that code.

property numberQuadConstraints

Number of quadratic constraints stored.

Deprecated since version 2.0: Still used internally by legacy code; will be removed together with that code.

property numberSDPConstraints

Number of LMIConstraint stored.

Deprecated since version 2.0: Still used internally by legacy code; will be removed together with that code.

property objective

Optimization objective as an Objective instance.

property options

Solution search parameters as an Options object.

property parameters

Maps names to parameters in use by the problem.

Returns

See mutables.

property pure_integer

Whether all variables are of integral types.

property status

The solution status string as claimed by last_solution.

property strategy

Solution strategy as a Strategy object.

A strategy is available once you order the problem to be solved and it will be reused for successive solution attempts (of a modified problem) while it remains valid with respect to the problem’s footprint.

When a strategy is reused, modifications to the objective and constraints of a problem are passed step by step through the strategy’s reformulation pipeline while existing reformulation work is not repeated. If the solver also supports these kinds of updates, then modifying and re-solving a problem can be much faster than solving the problem from scratch.

Example

>>> from picos import Problem, RealVariable
>>> x = RealVariable("x", 2)
>>> P = Problem()
>>> P.set_objective("min", abs(x)**2)
>>> print(P.strategy)
None
>>> sol = P.solve(solver = "cvxopt")  # Creates a solution strategy.
>>> print(P.strategy)
1. ExtraOptions
2. EpigraphReformulation
3. SquaredNormToConicReformulation
4. CVXOPTSolver
>>> # Add another constraint handled by SquaredNormToConicReformulation:
>>> P.add_constraint(abs(x - 2)**2 <= 1)
<Squared Norm Constraint: ‖x - [2]‖² ≤ 1>
>>> P.strategy.valid(solver = "cvxopt")
True
>>> P.strategy.valid(solver = "glpk")
False
>>> sol = P.solve(solver = "cvxopt")  # Reuses the strategy.

It’s also possible to create a startegy from scratch:

>>> from picos.modeling import Strategy
>>> from picos.reforms import (EpigraphReformulation,
...     ConvexQuadraticToConicReformulation)
>>> from picos.solvers import CVXOPTSolver
>>> # Mimic what solve() does when no strategy exists:
>>> P.strategy = Strategy(P, CVXOPTSolver, EpigraphReformulation,
...     ConvexQuadraticToConicReformulation)
property type

The problem type as a string, such as “Linear Program”.

property variables

Maps names to variables in use by the problem.

Returns

See mutables.