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

2.4 - 2022-02-12

The performance update.


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


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


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


  • When forming linear matrix inequalities with the << or >> operator, if one operand is an n \times n matrix and the other is an n-dimensional vector (or a scalar), the latter is now understood as (respectively broadcasted along) the main diagonal of an n \times n diagonal matrix. In particular X >> 1 is now understood as X
\succeq I as opposed to X \succeq J. If you want to express a constraint X \succeq \alpha J where J is a matrix of all ones, use the new picos.J.


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

  • Ability to pass constant values to picos.sum, min and max.

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


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


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


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.