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

2.2 - 2021-02-09

The Python 3 update.


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


  • A synopsis to the NoStrategyFound exception, explaining why strategy search failed.


  • Optimizing matrix (p,q)-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.


  • 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.


2.1 - 2020-12-29

The robust optimization update.


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


  • Support for a selection of robust optimization (RO) and distributionally robust stochastic programming (DRO) models through a new picos.uncertain namespace. You may now solve

  • 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.


  • 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.


  • 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.


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 L_{p,q}-norm has changed: It no longer refers to the p-norm of the q-norms of the matrix rows but to the q-norm of the p-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.


  • 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


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.


  • 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, x^2 \leq yz 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 0.

  • 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.


  • The NoAppropriateSolverError exception that was previously raised by solve. This is replaced by the new SolutionFailure exception with error code 1.

  • Some public functions in the tools module that were originally meant for internal use.


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.

1.2.0 - 2019-01-11


  • 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 4). Previously, the dual of an equivalent second order cone constraint was returned.

  • The Python 2/3 compatibility library six is no longer a dependency.


  • 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.


  • 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.


  • 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.


  • 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



  • 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.


  • 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


  • Ability to dynamically add and remove constraints.

  • Option pass_simple_cons_as_bound, see below.


  • 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.


  • Minor bugs with complex expressions.

1.1.1 - 2015-08-29


  • Support for the SDPA solver.

  • Partial trace of an affine expression, see partial_trace.


  • Improved PEP 8 compliance.


  • Compatibility with Python 3.

1.1.0 - 2015-04-15


  • Compatibility with Python 3.


  • The main repository has moved to GitHub.

1.0.2 - 2015-01-30



  • Improved efficiency of the sparse SDPA file format writer.

  • Improved efficiency of the complex to real transformation.


  • Scalar product of hermitian matrices.

  • Conjugate of a complex expression.

1.0.1 - 2014-08-27



  • 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


  • Ability to express rational powers of affine expressions with the ** operator, traces of matrix powers with tracepow, (generalized) p-norms with norm and n-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.


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


  • Option onlyChangeObjective.

0.1.3 - 2013-04-17


  • 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.


  • The solver search time is returned in the dictionary returned by solve.


  • 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


  • 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.

0.1.1 - 2012-12-08


  • Interface to Gurobi.

  • Ability to give an initial solution to warm-start mixed integer optimizers.

  • Ability to get a reference to a constraint that was added.


  • Minor bugs with quadratic expressions.

0.1.0 - 2012-06-22


  • Initial release of PICOS.