# Changelog¶

This file documents major changes to PICOS. The format is based on Keep a Changelog.

## 2.4 - 2022-02-12¶

*The performance update.*

Added

Support for noncovex quadratic constraints with Gurobi 9 (or later).

Setting

`UNRELIABLE_STRATEGIES`

to enable passing of problems to solvers that nominally support them but have proven unreliable.Setting

`PREFER_GUROBI_MATRIX_INTERFACE`

and option gurobi_matint to toggle between Gurobi’s legacy and matrix interface.Option mosek_basic_sol to let MOSEK (Optimizer) compute a basic solution for LPs.

Changed

The performance for solving problems with large data has been improved

drastically for CVXOPT and MOSEK (Optimizer; LPs in particular),

significantly for Cplex and SCIP, and

subtly for GLPK, Gurobi and ECOS.

This is most notable for LPs with a dense constraint matrix where the overhead for data passing can be significant in relation to the search time.

The performance of

`picos.sum`

when summing a large number of (bi-)affine expressions has been improved drastically.When possible, Gurobi is now interfaced through its matrix interface, which is faster for large data. This requires Gurobi 9 (or later) and SciPy.

By default, solving with MOSEK (Optimizer) does not return a basic LP solution any more. Use mosek_basic_sol to control this.

The default value of cvxopt_kktsolver is now

`None`

and means “try the fast`"chol"`

first and fall back to the reliable`"ldl"`

on error”.Dualization now makes use of variable bounds to reduce the number of auxiliary constraints.

The Python interface used to communicate with a solver is now mentioned in various log messages and exceptions.

Fixed

On-the-fly loading of a data vector in a multiplication with a matrix expression.

Maximization of a squared norm not being detected as a nonconvex quadratic objective and being passed to solvers that do not support it.

## 2.3 - 2021-10-07¶

*The syntactic sugar update.*

Important

When forming linear matrix inequalities with the

`<<`

or`>>`

operator, if one operand is an matrix and the other is an -dimensional vector (or a scalar), the latter is now understood as (respectively broadcasted along) the main diagonal of an diagonal matrix. In particular`X >> 1`

is now understood as as opposed to . If you want to express a constraint where is a matrix of all ones, use the new`picos.J`

.

Added

Support for the OSQP solver.

On-the-fly loading of

`scipy.sparse`

matrices. (See new note NumPy and SciPy.)Ability to negate or scale any expression and to sum any two expressions with the same or with a different type. This is established through a new

`WeightedSum`

fallback class. Convex or concave weighted sums can be used as an objective or in a constraint like any other expression.Properties

`sp`

,`np`

and`np2d`

to query the value of an expression as a SciPy or NumPy type. (See new class`Valuable`

for all value query options.)Ability to use

`numpy.array`

directly on valued PICOS objects, returning a zero, one or two-dimensional array depending on the shape of the value.New method

`require`

and an equivalent overload for`+=`

to add constraints to a`Problem`

.Cached functions

`I`

,`J`

, and`O`

that create, respectively, an identity matrix, a matrix of all ones, and a zero matrix.Cached properties

`BiaffineExpression.rowsum`

and`colsum`

to complement the existing property`sum`

and an argument`axis`

to`picos.sum`

for the same purpose.Option to give a name to

`problems`

via the first initialization argument or the`name`

property.Ability to perform some algebraic operations on

`objectives`

.Support for solving nonconvex continuous quadratic programs (QPs) with CPLEX and Gurobi. Gurobi further allows convex quadratic constraints to be present.

Ability to

`reshape`

affine expressions in C-order, like NumPy.Global option

`settings.RETURN_SOLUTION`

that controls whether`solve`

returns a`Solution`

.Methods

`Samples.shuffled`

and`kfold`

.Support for MOSEK remote optimization with the mosek_server option.

Option cplex_vmconfig to load a virtual machine configuration file with CPLEX.

Function

`picos.patch_scipy_array_priority`

to work around SciPy#4819.

Changed

The performance of solving semidefinite programs with trivial linear matrix inequalities of the form

`X >> 0`

using MOSEK (Optimizer) has been improved dramatically. Depending on your problem, you might experience this speedup when using the dualize option.`Problem.minimize`

and`Problem.maximize`

are now properties that you can assign a minimization or maximization objective to, respectively.All expression types as well as the classes

`Problem`

and`Objective`

now share the same interface to query their (objective) value. In particular, the new`np`

property can be used on all.Solving with

`duals=True`

will now raise an exception when duals were returned by the solver but not all could be converted. Use the default of`duals=None`

to accept also incomplete duals.The new argument

`name`

is the only optional argument to`Problem`

that may be passed as a positional argument; the arguments`copyOptions`

and`useOptions`

must now be passed as keyword arguments.

Fixed

Running

`setup.py`

under Python 3.6 and earlier.Bad shebang lines; all are now properly reading

`#!/usr/bin/env python3`

.Incorrect duals returned by MOSEK (Fusion).

An assertion failure when multiplying some quadratic expressions with a negative scalar.

A false expression being created when multiplying a

`DetRootN`

with a negative scalar.An exception when multiplying a scalar power with a constant.

A modify-during-iteration issue that could result in a suboptimal solver being chosen.

Building piecewise affine functions from a mix of certain and random expressions.

A failure when computing the convex hull of a

`ScenarioPerturbationSet`

with few points.Detection of string groups where the variable part is at the start or end of the strings.

CVXOPT reacting inconsistently to some infeasible problems.

A potential variable clash when reformulating a

`NuclearNormConstraint`

.Grammatical issues when printing variable groups of a problem.

Removed

The deprecated functions

`Problem.minimize`

and`Problem.maximize`

. See**Changed**for the new meaning of these names.The deprecated arguments

`it`

and`indices`

to`picos.sum`

.

## 2.2 - 2021-02-09¶

*The Python 3 update.*

Important

PICOS now requires Python 3.4 or later; Python 2 support was dropped.

Added

A synopsis to the

`NoStrategyFound`

exception, explaining why strategy search failed.

Fixed

Optimizing matrix -norms when columns of the matrix are constant.

Refining norms over a sparse constant term to a constant affine expression.

Gurobi printing empty lines to console when dual retrieval fails.

Changed

A bunch of Python 2 compatibility code was finally removed.

Exception readability has been improved using Python 3’s

`raise from`

syntax where applicable.The

`__version_info__`

field now contains integers instead of strings.`QuadraticExpression.scalar_factors`

is now`None`

instead of an empty tuple when no decomposition into scalar factors is known.

Deprecated

`QuadraticExpression.quadratic_forms`

, as write access would leave the expression in an inconsistent state. (At your own risk, use the equivalent`_sparse_quads`

instead.)

## 2.1 - 2020-12-29¶

*The robust optimization update.*

Important

The sign of dual values for affine equality constraints has been fixed by inversion.

Added

Support for a selection of robust optimization (RO) and distributionally robust stochastic programming (DRO) models through a new

`picos.uncertain`

namespace. You may now solvescenario-robust conic programs via

`ScenarioPerturbationSet`

,conically robust linear programs and robust conic quadratic programs under ellipsoidal uncertainty via

`ConicPerturbationSet`

and`UnitBallPerturbationSet`

, andleast squares and piecewise linear stochastic programs where the data generating distribution is defined ambiguously through a Wasserstein ball or through bounds on its first two moments via

`WassersteinAmbiguitySet`

and`MomentAmbiguitySet`

, respectively.

New function

`picos.block`

to create block matrices efficiently.New convenience class

`picos.Samples`

for data-driven applications.New set class

`picos.Ellipsoid`

(has overlap with but a different scope than`picos.Ball`

).Support for

`matrix reshuffling`

(aka*matrix realignment*) used in quantum information theory.Ability to define cones of fixed dimensionality and

`product cones`

thereof.Ability to query the

`solver-reported objective value`

(useful with RO and DRO objectives).Methods

`Problem.conic_form`

and`reformulated`

for internal use and educational purposes.New module

`picos.settings`

defining global options that can be set through environment variables prefixed with`PICOS_`

. Among other things, you can now blacklist all proprietary solvers for an application by passing`PICOS_NONFREE_SOLVERS=False`

to the Python interpreter.A new base class

`BiaffineExpression`

for all (uncertain) affine expression types. This gives developers extending PICOS a framework to support models with parameterized data.Support for

`factoring out`

variables and parameters from (bi)affine vector expression.Support for

`replacing`

variables and parameters with affine expressions of same shape to perform a change of variables in a mathematical sense.Support for SCIP Optimization Suite 7.

CVXOPT-specific solution search options cvxopt_kktsolver and cvxopt_kktreg.

Fixed

Quadratic expressions created from a squared norm failing to decompose due to a numerically singular quadratic form.

Solution objects unintendedly sharing memory.

Solution search options that take a dictionary as their argument.

Solution search with assume_conic set to

`False`

.The

`EpigraphReformulation`

falsely claiming that it can reformulate any nonconvex objective.A division by zero that could occur when computing the solution search overhead.

An exception with functions that look for short string descriptions, in particular with

`picos.sum`

.

Changed

The functions

`picos.max`

and`picos.min`

can now be used to express the maximum over a list of convex and the minimum over a list of concave expressions, respectively.Squared norms are now implemented as a subclass of quadratic expressions (

`SquaredNorm`

), skipping an unnecessary decomposition on constraint creation.Commutation matrices used internally for various algebraic tasks are now retrieved from a centralized cached function, improving performance.

The string description of

`Problem`

instances is not enclosed by dashed lines any more.

## 2.0 - 2020-03-03¶

*The backend update.*

Important

This is a major release featuring vast backend rewrites as well as interface changes. Programs written for older versions of PICOS are expected to raise deprecation warnings but should otherwise work as before. The following lists notable exceptions:

The solution returned by

`solve`

is now an instance of the new`Solution`

class instead of a dictionary.If solution search fails to find an optimal primal solution, PICOS will now raise a

`SolutionFailure`

by default. Old behavior of not raising an exception is achieved by setting`primals=None`

(see primals and duals options).The definition of the -norm has changed: It no longer refers to the -norm of the -norms of the matrix rows but to the -norm of the -norms of the matrix columns. This matches the definition you would find on Wikipedia and should reduce confusion for new users. See

`Norm`

.The signs in the Lagrange dual problem of a conic problem are now more consistent for all cones, see Dual Values. In particular the signs of dual values for (rotated) second order conic constraints have changed and the problem obtained by

`Problem.dual`

(new for`as_dual`

) has a different (but equivalent) form.

Added

A modular problem reformulation framework. Before selecting a solver, PICOS now builds a map of problem types that your problem can be reformulated to and makes a choice based on the expected complexity of the reposed problem.

An object oriented interface to solution search options. See

`Options`

.Support for arbitrary objective functions via an epigraph reformulation.

Support for MOSEK 9.

Support for ECOS 2.0.7.

Support for multiple subsystems with

`partial_trace`

.Quick-solve functions

`picos.minimize`

and`picos.maximize`

.Lower and upper diagonal matrix variable types.

`SecondOrderCone`

and`RotatedSecondOrderCone`

sets to explicitly create the associated constraints.*(You now need to use these if you want to obtain a conic instead of a quadratic dual.)*Possibility to use

`picos.sum`

to sum over the elements of a single multidimensional expression.Possibility to create a

`Ball`

or`Simplex`

with a non-constant radius.Many new properties (postfix operations) to work with affine expressions; for instance

`A.vec`

is a faster and cached way to express the vectorization`A[:]`

.Options assume_conic and verify_prediction.

An option for every solver to manipulate the chances of it being selected (e.g. penalty_cvxopt).

Ability to run doctests via

`test.py`

.

Fixed

The following are issues that were fixed in an effort of their own. If a bug is not listed here, it might still be fixed as a side effect of some of the large scale code rewrites that this release ships.

Upgrading the PyPI package via pip.

A regression that rendered the Kronecker product unusable.

Noisy exception handling in a sparse matrix helper function.

Shape detection for matrices given by string.

The hotstart option when solving with CPLEX.

Low precision QCP duals from Gurobi.

Changed

All algebraic expression code has been rewritten and organized in a new

`expressions`

package. In particular, real and complex expressions are distinguished more clearly.All algebraic expressions are now immutable.

The result of any unary operation on algebraic expressions (e.g. negation, transposition) is cached (only computed once per expression).

Slicing of affine expressions is more powerful, see Matrix Slicing.

Loading of constant numeric data has been unified, see

`load_data`

.Variables are now created independently of problems by instanciating one of the new

`variable types`

.*(*`Problem.add_variable`

*is deprecated.)*Constraints are added to problems as they are; any transformation is done transparently during solution search.

In particular, is now initially a (nonconvex) quadratic constraint and transformation to a conic constraint is controlled by the new assume_conic option.

Expressions constrained to be positive semidefinite are now required to be symmetric/hermitian by their own definition.

*(Use*`SymmetricVariable`

*or*`HermitianVariable`

*whenever applicable!)*Options passed to

`solve`

are only used for that particular search.The default value for the verbosity option (formerly

`verbose`

) is now .Available solvers are only imported when they are actually being used, which speeds up import of PICOS on platforms with many solvers installed.

The code obeys PEP 8 and PEP 257 more strongly. Exceptions: D105, D203, D213, D401, E122, E128, E221, E271, E272, E501, E702, E741.

Production testing code was moved out of the

`picos`

package.

Removed

The

`NoAppropriateSolverError`

exception that was previously raised by`solve`

. This is replaced by the new`SolutionFailure`

exception with error code .Some public functions in the

`tools`

module that were originally meant for internal use.

Deprecated

This section lists deprecated modules, functions and options with their respective replacement or deprecation reason on the right hand side. Deprecated entities produce a warning and will be removed in a future release.

The

`tools`

module as a whole. It previously contained both algebraic functions for the user as well as functions meant for internal use. The former group of functions can now be imported directly from the`picos`

namespace (though some are also individually deprecated). The other functions were either relocated (but can still be imported from`tools`

while it lasts) or removed.In the

`Problem`

class:`add_variable`

,`remove_variable`

,`set_var_value`

→ variables are instanciated directly and added to problems automatically`set_option`

→ assign to attributes or items of`Problem.options`

`countVar`

,`countCons`

,`numberOfVars`

,`numberLSEConstraints`

,`numberSDPConstraints`

,`numberQuadConstraints`

,`numberConeConstraints`

→ were meant for internal usearguments

`it`

,`indices`

and`key`

to`add_list_of_constraints`

→ are ignored

All expression types:

Affine expressions:

`hadamard`

→`^`

`Htranspose`

→`H`

`copy`

→ expressions are immutable`soft_copy`

→ expressions are immutable

Algebraic functions and shorthands in the

`picos`

namespace:arguments

`it`

and`indices`

to`sum`

→ are ignored

Solution search options:

`allow_license_warnings`

→ license_warnings`verbose`

→ verbosity (takes an integer)`noprimals`

→ primals (the meaning is inverted)`noduals`

→ duals (the meaning is inverted)`tol`

→`*_fsb_tol`

and`*_ipm_opt_tol`

`gaplim`

→ rel_bnb_opt_tol`maxit`

→ max_iterations`nbsol`

→ max_fsb_nodes`pool_relgap`

→ pool_rel_gap`pool_absgap`

→ pool_abs_gap`lboundlimit`

→ cplex_lwr_bnd_limit`uboundlimit`

→ cplex_upr_bnd_limit`boundMonitor`

→ cplex_bnd_monitor

## 1.2.0 - 2019-01-11¶

Important

`A scalar expression's value`

and`a scalar constraint's dual`

are returned as scalar types as opposed to 1×1 matrices.The dual value returned for rotated second order cone constraints is now a proper member of the dual cone (which equals the primal cone up to a factor of ). Previously, the dual of an equivalent second order cone constraint was returned.

The Python 2/3 compatibility library

`six`

is no longer a dependency.

Added

Support for the ECOS solver.

Experimental support for MOSEK’s new Fusion API.

Full support for exponential cone programming.

A production testing framework featuring around 40 novel optimization test cases that allows quick selection of tests, solvers, and solver options.

A “glyph” system that allows the user to adjust the string representations of future expressions and constraints. For instance,

`picos.latin1()`

disables use of unicode symbols.Support for symmetric variables with all solvers, even if they do not support semidefinite programming.

Changed

Solver implementations each have a source file of their own, and a common interface that makes implementing new solvers easier.

Likewise, constraint implementations each have a source file of their own.

The implementations of CPLEX, Gurobi, MOSEK and SCIP have been rewritten.

Solver selection takes into account how well a problem is supported, distinguishing between native, secondary, experimental and limited support.

Unsupported operations on expressions now produce meaningful exceptions.

`add_constraint`

and`add_list_of_constraints`

always return the constraints passed to them.`add_list_of_constraints`

and`picos.sum`

find a short string representation automatically.

Removed

The old production testing script.

Support for the SDPA solver.

Support for sequential quadratic programming.

The options

`convert_quad_to_socp_if_needed`

,`pass_simple_cons_as_bound`

,`return_constraints`

,`handleBarVars`

,`handleConeVars`

and`smcp_feas`

.Support for GLPK and MOSEK through CVXOPT.

Fixed

Performance issues when exporting variable bounds to CVXOPT.

Hadamard product involving complex matrices.

Adding constant terms to quadratic expression.

Incorrect or redundant expression string representations.

GLPK handling of the default

`maxit`

option.Miscellaneous solver-specific bugs in the solvers that were re-implemented.

## 1.1.3 - 2018-10-05¶

Added

Support for the solvers GLPK and SCIP.

PICOS packages on Anaconda Cloud.

PICOS packages in the Arch Linux User Repository.

Changed

The main repository has moved to GitLab.

Releases of packages and documentation changes are automated and thus more frequent. In particular, post release versions are available.

Test bench execution is automated for greater code stability.

Improved test bench output.

Improved support for the SDPA solver.

`partial_trace`

can handle rectangular subsystems.The documentation was restructured; examples were converted to Python 3.

Fixed

Upper bounding the norm of a complex scalar.

Multiplication with a complex scalar.

A couple of Python 3 specific errors, in particular when deleting constraints.

All documentation examples are reproducible with the current state of PICOS.

## 1.1.2 - 2016-07-04¶

Added

Ability to dynamically add and remove constraints.

Option

`pass_simple_cons_as_bound`

, see below.

Changed

Improved efficiency when processing large expressions.

Improved support for the SDPA solver.

`add_constraint`

returns a handle to the constraint when the option return_constraints is set.New signature for the function

`partial_transpose`

, which can now transpose arbitrary subsystems from a kronecker product.PICOS no longer turns constraints into variable bounds, unless the new option

`pass_simple_cons_as_bound`

is enabled.

Fixed

Minor bugs with complex expressions.

## 1.1.1 - 2015-08-29¶

Added

Support for the SDPA solver.

Partial trace of an affine expression, see

`partial_trace`

.

Changed

Improved PEP 8 compliance.

Fixed

Compatibility with Python 3.

## 1.1.0 - 2015-04-15¶

Added

Compatibility with Python 3.

Changed

The main repository has moved to GitHub.

## 1.0.2 - 2015-01-30¶

Added

Ability to read and write problems in conic benchmark format.

Support for inequalities involving the sum of the largest or smallest elements of an affine expression, see

`sum_k_largest`

and`sum_k_smallest`

.Support for inequalities involving the sum of the largest or smallest eigenvalues of a symmetric matrix, see

`sum_k_largest_lambda`

,`sum_k_smallest_lambda`

,`lambda_max`

and`lambda_min`

.Support for inequalities involving the -norm of an affine expression, see

`norm`

.Support for equalities involving complex coefficients.

Support for antisymmetric matrix variables.

Set expressions that affine expressions can be constrained to be an element of, see

`ball`

,`simplex`

and`truncated_simplex`

.Shorthand functions

`maximize`

and`minimize`

to specify the objective function of a problem and solve it.Hadamard (elementwise) product of affine expression, as an overload of the

`^`

operator, read the tutorial on overloads.Partial transposition of an aAffine Expression, see

`partial_transpose`

.

Changed

Improved efficiency of the sparse SDPA file format writer.

Improved efficiency of the complex to real transformation.

Fixed

Scalar product of hermitian matrices.

Conjugate of a complex expression.

## 1.0.1 - 2014-08-27¶

Added

Support for semidefinite programming over the complex domain, see the documentation on complex problems.

Helper function to input (multicommodity) graph flow problems, see the tutorial on flow constraints.

Additional argument to

`tracepow`

, to represent constraints of the form .

Changed

Significantly improved slicing performance for affine expressions.

Improved performance when loading data.

Improved performance when retrieving primal solution from CPLEX.

The documentation received an overhaul.

## 1.0.0 - 2013-07-19¶

Added

Ability to express rational powers of affine expressions with the

`**`

operator, traces of matrix powers with`tracepow`

, (generalized) p-norms with`norm`

and -th roots of a determinant with`detrootn`

.Ability to specify variable bounds directly rather than by adding constraints, see

`add_variable`

.Problem dualization.

Option

`solve_via_dual`

which controls passing the dual problem to the solver instead of the primal problem. This can result in a significant speedup for certain problems.Semidefinite programming interface for MOSEK 7.0.

Options

`handleBarVars`

and`handleConeVars`

to customize how SOCPs and SDPs are passed to MOSEK. When these are set to`True`

, PICOS tries to minimize the number of variables of the MOSEK instance.

Changed

If the chosen solver supports this, updated problems will be partially re-solved instead of solved from scratch.

Removed

Option

`onlyChangeObjective`

.

## 0.1.3 - 2013-04-17¶

Added

A

`geomean`

function to construct geometric mean inequalities that will be cast as rotated second order cone constraints.Options

`uboundlimit`

and`lboundlimit`

to tell CPLEX to stop the search as soon as the given threshold is reached for the upper and lower bound, respectively.Option

`boundMonitor`

to inspect the evolution of CPLEX lower and upper bounds.Ability to use the weak inequality operators as an alias for the strong ones.

Changed

The solver search time is returned in the dictionary returned by

`solve`

.

Fixed

Access to dual values of fixed variables with CPLEX.

Evaluation of constant affine expressions with a zero coefficient.

Number of constraints not being updated in

`remove_constraint`

.

## 0.1.2 - 2013-01-10¶

Fixed

Writing SDPA files. The lower triangular part of the constraint matrix was written instead of the upper triangular part.

A wrongly raised

`IndexError`

from`remove_constraint`

.