picos.expressions.expression

Backend for expression type implementations.

Exceptions

exception picos.expressions.expression.PredictedFailure[source]

Bases: TypeError

Denotes that comparing two expressions will not form a constraint.

Classes

class picos.expressions.expression.Expression(typeStr, symbStr)[source]

Bases: picos.valuable.Valuable

Abstract base class for mathematical expressions, including mutables.

For mutables, this is the secondary base class, with Mutable or a subclass thereof being the primary one.

__abs__()[source]

Denote the default norm of the expression.

The norm used depends on the expression’s domain. It is

  1. the absolute value of a real scalar,

  2. the modulus of a complex scalar,

  3. the Euclidean norm of a vector, and

  4. the Frobenius norm of a matrix.

__add__(other)[source]

Denote addition with another expression on the right-hand side.

__and__(other)[source]

Denote horizontal stacking with another expression on the right.

__eq__(exp)[source]

Return an equality constraint concerning the expression.

__floordiv__(other)[source]

Denote vertical stacking with another expression below.

__ge__(other)[source]

Return a constraint that the expression is lower-bounded.

__init__(typeStr, symbStr)[source]

Perform basic initialization for Expression instances.

Parameters
  • typeStr (str) – Short string denoting the expression type.

  • symbStr (str) – Algebraic string description of the expression.

__le__(other)[source]

Return a constraint that the expression is upper-bounded.

__lshift__(other)[source]

Denote either set membership or a linear matrix inequality.

If the other operand is a set, then this denotes that the expression shall be constrained to that set. Otherwise, it is expected that both expressions are square matrices of same shape and this denotes that the expression is upper-bounded by the other expression with respect to the Loewner order (i.e. other - self is positive semidefinite).

__matmul__(other)[source]

Denote the Kronecker product with another expression on the right.

__mul__(other)[source]

Denote multiplication with another expression on the right.

__neg__()[source]

Denote the negation of the expression.

__or__(other)[source]

Denote the scalar product with another expression on the right.

For (complex) vectors a and b this is the dot product

(a \mid b)
&= \langle a, b \rangle \\
&= a \cdot b \\
&= b^H a.

For (complex) matrices A and B this is the Frobenius inner product

(A \mid B)
&= \langle A, B \rangle_F \\
&= A : B \\
&= \operatorname{tr}(B^H A) \\
&= \operatorname{vec}(B)^H \operatorname{vec}(\overline{A})

Note

Write (A|B) instead of A|B for the scalar product of A and B to obtain correct operator binding within a larger expression context.

__pos__()[source]

Return the expression as-is.

__pow__(other)[source]

Denote exponentiation with another, scalar expression.

__radd__(other)[source]

Denote addition with another expression on the left-hand side.

__rand__(other)[source]

Denote horizontal stacking with another expression on the left.

__rfloordiv__(other)[source]

Denote vertical stacking with another expression above.

__rmatmul__(other)[source]

Denote the Kronecker product with another expression on the left.

__rmul__(other)[source]

Denote multiplication with another expression on the left.

__ror__(other)[source]

Denote the scalar product with another expression on the left.

See __or__ for details on this operation.

__rpow__(other)[source]

Denote taking another expression to the power of the expression.

__rshift__(other)[source]

Denote that the expression is lower-bounded in the Lowener order.

In other words, return a constraint that self - other is positive semidefinite.

__rsub__(other)[source]

Denote subtraction of the expression from another expression.

__rtruediv__(other)[source]

Denote scalar division of another expression.

__rxor__(other)[source]

Denote the entrywise product with another expression on the left.

__sub__(other)[source]

Denote subtraction of another expression from the expression.

__truediv__(other)[source]

Denote division by another, scalar expression.

__xor__(other)[source]

Denote the entrywise product with another expression on the right.

frozen(subset=None)[source]

The expression with valued mutables frozen to their current value.

If all mutables of the expression are valued (and in the subset unless subset=None), this is the same as the inversion operation ~.

If the mutables to be frozen do not appear in the expression, then the expression is not copied but returned as is.

Parameters

subset – An iterable of valued mutables or names thereof that should be frozen. If None, then all valued mutables are frozen to their current value. May include mutables that are not present in the expression, but may not include mutables without a value.

Returns Expression

The frozen expression, refined to a more suitable type if possible.

Example

>>> from picos import RealVariable
>>> x, y = RealVariable("x"), RealVariable("y")
>>> f = x + y; f
<1×1 Real Linear Expression: x + y>
>>> sorted(f.mutables, key=lambda mtb: mtb.name)
[<1×1 Real Variable: x>, <1×1 Real Variable: y>]
>>> x.value = 5
>>> g = f.frozen(); g  # g is f with x frozen at its current value of 5.
<1×1 Real Affine Expression: [x] + y>
>>> sorted(g.mutables, key=lambda mtb: mtb.name)
[<1×1 Real Variable: y>]
>>> x.value, y.value = 10, 10
>>> f.value  # x takes its new value in f.
20.0
>>> g.value  # x remains frozen at [x] = 5 in g.
15.0
>>> # If an expression is frozen to a constant, this is reversable:
>>> f.frozen().equals(~f) and ~f.frozen() is f
True
is_valued()[source]

Whether the expression is valued.

Deprecated since version 2.0: Use valued instead.

classmethod make_type(*args, **kwargs)[source]

Create a detailed expression type from subtype parameters.

replace_mutables(replacement)[source]

Return a copy of the expression concerning different mutables.

New mutables must have the same shape and vectorization format as the mutables that they replace. This means in particular that RealVariable, IntegerVariable and BinaryVariable of same shape are interchangeable.

If the mutables to be replaced do not appear in the expression, then the expression is not copied but returned as is.

Parameters

replacement (tuple or list or dict) – Either a map from mutables or mutable names to new mutables or an iterable of new mutables to replace existing mutables of same name with. See the section on advanced usage for additional options.

Returns Expression

The new expression, refined to a more suitable type if possible.

Advanced replacement

It is also possible to replace mutables with real affine expressions concerning pairwise disjoint sets of fresh mutables. This works only on real-valued mutables that have a trivial internal vectorization format (i.e. FullVectorization). The shape of the replacing expression must match the variable’s. Additional limitations depending on the type of expression that the replacement is invoked on are possible. The replacement argument must be a dictionary.

Example

>>> import picos
>>> x = picos.RealVariable("x"); x.value = 1
>>> y = picos.RealVariable("y"); y.value = 10
>>> z = picos.RealVariable("z"); z.value = 100
>>> c = picos.Constant("c", 1000)
>>> a = x + 2*y; a
<1×1 Real Linear Expression: x + 2·y>
>>> a.value
21.0
>>> b = a.replace_mutables({y: z}); b  # Replace y with z.
<1×1 Real Linear Expression: x + 2·z>
>>> b.value
201.0
>>> d = a.replace_mutables({x: 2*x + z, y: c}); d  # Advanced use.
<1×1 Real Affine Expression: 2·x + z + 2·c>
>>> d.value
2102.0
set_value(value)[source]

Set the value of an expression.

Deprecated since version 2.0: Use value instead.

property certain

Always True for certain expression types.

This can be False for Expression types that inherit from UncertainExpression (with priority).

property concave

Whether the expression is concave.

property constant

Whether the expression involves no mutables.

property convex

Whether the expression is convex.

property mutables

Return the set of mutables that are involved in the expression.

property parameters[source]

The set of parameters that are involved in the expression.

property refined

A refined version of the expression.

The refined expression can be an instance of a different Expression subclass than the original expression, if that type is better suited for the mathematical object in question.

The refined expression is automatically used instead of the original one whenever a constraint is created, and in some other places.

The idea behind refined expressions is that operations that produce new expressions can be executed quickly without checking for exceptionnel cases. For instance, the sum of two ComplexAffineExpression instances could have the complex part eliminated so that storing the result as an AffineExpression would be prefered, but checking for this case on every addition would be too slow. Refinement is used sparingly to detect such cases at times where it makes the most sense.

Refinement may be disallowed within a context with the no_refinement context manager. In this case, this property returns the expression as is.

property scalar

Whether the expression is scalar.

property shape

Return the algebraic shape of the expression.

property size

The same as shape.

property square

Whether the expression is a square matrix.

property string

Symbolic string representation of the expression.

Use this over Python’s str if you want to output the symbolic representation even when the expression is valued.

property subtype

The subtype part of the expression’s detailed type.

Returns a hashable object that, together with the Python class part of the expression’s type, is sufficient to predict the constraint outcome (constraint class and subtype) of any comparison operation with any other expression.

By convention the object returned is a namedtuple instance.

property type

The expression’s detailed type for constraint prediction.

The returned value is suffcient to predict the detailed type of any constraint that can be created by comparing with another expression.

Since constraints are created from refined expressions only, the Python class part of the detailed type may differ from the type of the expression whose type is queried.

property uncertain

Always False for certain expression types.

This can be True for Expression types that inherit from UncertainExpression (with priority).

property variables[source]

The set of decision variables that are involved in the expression.

class picos.expressions.expression.ExpressionType(theClass, subtype)[source]

Bases: picos.containers.DetailedType

The detailed type of an expression for predicting constraint outcomes.

This is suffcient to predict the detailed type of any constraint that can be created by comparing with another expression.

predict(relation, other)[source]

Predict the constraint outcome of comparing expressions.

Parameters
  • relation – An object from the operator namespace representing the operation being predicted.

  • other (ExpressionType) – Another expression type representing the right hand side operand.

Example

>>> import operator, picos
>>> a = picos.RealVariable("x") + 1
>>> b = picos.RealVariable("y") + 2
>>> (a <= b).type == a.type.predict(operator.__le__, b.type)
True

Functions

picos.expressions.expression.no_refinement()[source]

Context manager that disables the effect of Expression.refined.

This can be necessary to ensure that the outcome of a constraint coversion is as predicted, in particular when PICOS uses overridden comparison operators for constraint creation internally.

picos.expressions.expression.refine_operands(stop_at_affine=False)[source]

Cast refined on both operands.

If the left hand side operand (i.e. self) is refined to an instance of a different type, then, instead of the decorated method, the method with the same name on the refined type is invoked with the (refined) right hand side operand as its argument.

This decorator is supposed to be used on all constraint creating binary operator methods so that degenerated instances (e.g. a complex affine expression with an imaginary part of zero) can occur but are not used in constraints. This speeds up many computations involving expressions as these degenerate cases do not need to be detected. Note that Expression.type also refers to the refined version of an expression.

Parameters

stop_at_affine (bool) – Do not refine any affine expressions, in particular do not refine complex affine expressions to real ones.

picos.expressions.expression.validate_prediction(the_operator)[source]

Validate that the constraint outcome matches the predicted outcome.