picos.expressions.expression¶
Backend for expression type implementations.
Exceptions
- exception picos.expressions.expression.NotValued[source]¶
Bases:
RuntimeError
The operation cannot be performed due to a mutable without a value.
Note that the
value
andvalue_as_matrix
attributes do not raise this exception, but returnNone
.- __init__(*args, **kwargs)¶
Initialize self. See help(type(self)) for accurate signature.
- __new__(**kwargs)¶
Create and return a new object. See help(type) for accurate signature.
- exception picos.expressions.expression.PredictedFailure[source]¶
Bases:
TypeError
Denotes that comparing two expressions will not form a constraint.
- __init__(*args, **kwargs)¶
Initialize self. See help(type(self)) for accurate signature.
- __new__(**kwargs)¶
Create and return a new object. See help(type) for accurate signature.
Classes
- class picos.expressions.expression.Expression(typeStr, symbStr)[source]¶
Bases:
abc.ABC
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.- __init__(typeStr, symbStr)[source]¶
Perform basic initialization for
Expression
instances.
- 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 safe_value¶
Value of the expression, if defined.
Refer to
value
for when it is defined.- Returns
The value as a Python scalar or CVXOPT matrix.
- Raises
NotValued – If the value is not defined.
- Distinction
- property safe_value_as_matrix¶
Value of the expression as a CVXOPT matrix type, if defined.
Refer to
value
for when it is defined.- Returns
The value as a CVXOPT matrix.
- Raises
NotValued – If the value is not defined.
- Distinction
- 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).
- property value¶
Value of the expression, or
None
.It is defined if the expression is constant or if all mutables involved in the expression are valued. Mutables can be valued directly by writing to their
value
attribute. Variables are also valued by PICOS when an optimization solution is found.Some expressions can also be valued directly if PICOS can find a minimal norm mutable assignment that makes the expression have the desired value. In particular, this works with affine expressions whose linear part has an under- or well-determined coefficient matrix.
- Returns
The value as a Python scalar or CVXOPT matrix, or
None
if it is not defined.- Distinction
Unlike
safe_value
andsafe_value_as_matrix
, an undefined value is returned asNone
.Unlike
value_as_matrix
andsafe_value_as_matrix
, scalars are returned as scalar types.For uncertain expressions, see also
worst_case_value
.
- Example
>>> from picos import RealVariable >>> x = RealVariable("x", (1,3)) >>> y = RealVariable("y", (1,3)) >>> e = x - 2*y + 3 >>> print("e:", e) e: x - 2·y + [3] >>> e.value = [4, 5, 6] >>> print("e: ", e, "\nx: ", x, "\ny: ", y, sep = "") e: [ 4.00e+00 5.00e+00 6.00e+00] x: [ 2.00e-01 4.00e-01 6.00e-01] y: [-4.00e-01 -8.00e-01 -1.20e+00]
- property value_as_matrix¶
Value of the expression as a CVXOPT matrix type, or
None
.Refer to
value
for when it is defined (notNone
).- Returns
The value as a CVXOPT matrix, or
None
if it is not defined.- Distinction
- property valued¶
Whether the expression is valued.
Note
Querying this attribute is not faster than immediately querying
value
and checking whether it isNone
. Use it only if you do not need to know the value, but only whether it is available.- Example
>>> from picos import RealVariable >>> x = RealVariable("x", 3) >>> x.valued False >>> x.value >>> print((x|1)) ∑(x) >>> x.value = [1, 2, 3] >>> (x|1).valued True >>> print((x|1)) 6.0
- 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.