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:
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
the absolute value of a real scalar,
the modulus of a complex scalar,
the Euclidean norm of a vector, and
the Frobenius norm of a matrix.
- __init__(typeStr, symbStr)[source]¶
Perform basic initialization for
Expression
instances.
- __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).
- __or__(other)[source]¶
Denote the scalar product with another expression on the right.
For (complex) vectors
and
this is the dot product
For (complex) matrices
and
this is the Frobenius inner product
Note
Write
(A|B)
instead ofA|B
for the scalar product ofA
andB
to obtain correct operator binding within a larger expression context.
- __ror__(other)[source]¶
Denote the scalar product with another expression on the left.
See
__or__
for details on this operation.
- __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.
- 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. IfNone
, 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
andBinaryVariable
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. Thereplacement
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 fromUncertainExpression
(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 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 anAffineExpression
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 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 whosetype
is queried.
- property uncertain¶
Always
False
for certain expression types.This can be
True
for Expression types that inherit fromUncertainExpression
(with priority).
- class picos.expressions.expression.ExpressionType(theClass, subtype)[source]¶
Bases:
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.