Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_pickle_expression(self):
node = Node(Operations.PLUS,
Node(Operations.MULTIPLICATION,
left=Node(Operations.IDENTITY, value='x'),
right=Node(Operations.NUMBER, value=4)),
Node(Operations.MULTIPLICATION,
left=Node(Operations.IDENTITY, value='y'),
right=Node(Operations.NUMBER, value=2)))
e = Expression(root=node, variables=['x', 'y'])
returned_expression = pickle.loads(pickle.dumps(e))
self.assertEqual(e.variables, returned_expression.variables)
self.assertEqual(e.root.operation._operation_type, returned_expression.root.operation._operation_type)
self.assertEqual(e.root.operation.action, returned_expression.root.operation.action)
self.assertEqual(e.root.value, returned_expression.root.value)
self.assertEqual(e.root.left.operation._operation_type, returned_expression.root.left.operation._operation_type)
self.assertEqual(e.root.left.operation.action, returned_expression.root.left.operation.action)
self.assertEqual(e.root.left.value, returned_expression.root.left.value)
self.assertEqual(e.root.right.operation._operation_type, returned_expression.root.right.operation._operation_type)
self.assertEqual(e.root.right.operation.action, returned_expression.root.right.operation.action)
self.assertEqual(e.root.right.value, returned_expression.root.right.value)
sage: sage.symbolic.units.unit_derivations_expr('invalid')
Traceback (most recent call last):
...
KeyError: 'invalid'
"""
v = str(v)
Z = unit_derivations[v]
if isinstance(Z,str):
d = dict([(x,str_to_unit(x)) for x in vars_in_str(Z)])
from sage.misc.all import sage_eval
Z = sage_eval(Z, d)
unit_derivations[v] = Z
return Z
class UnitExpression(Expression):
"""
A symbolic unit.
EXAMPLES::
sage: acre = units.area.acre
sage: type(acre)
TESTS::
sage: bool(loads(dumps(acre)) == acre)
True
sage: type(loads(dumps(acre)))
"""
import expression
import operator as op
class UnaryOperator(expression.Expression):
"""
Base class for expressions involving unary operators.
"""
def __init__(self, expr):
self.expr = expr
self.subexpressions = [expr]
self._context = self.OP_FUNC(self.expr._context)
super(UnaryOperator, self).__init__()
# Applies the unary operator to the value.
def numeric(self, values):
return self.OP_FUNC(values[0])
def name(self):
return self.OP_NAME + self.expr.name()
return curvature.Convex()
if curvature.isconcave(right) and sign.ispositive(left):
return curvature.Concave()
if curvature.isconvex(right) and sign.isnegative(left):
return curvature.Concave()
return curvature.Nonconvex()
else:
# do i raise an error? do i complain about non-dcp compliance?
#curvature = Nonconvex()
raise TypeError("Not DCP compliant multiply %s * %s (lefthand side should be known Number or Parameter)" % (repr(left), repr(right)))
""" Expression AST nodes
What follows are nodes that are used to form expressions.
"""
class Add(e.Expression, e.BinaryOperatorMixin):
OP_NAME = ' + '
OP_FUNC = operator.__add__
IDENTITY = 0
ZERO = False
def __init__(self, left, right):
setup = {
'left': left,
'right': right,
'curvature': left.curvature + right.curvature,
'sign': left.sign + right.sign,
'shape': left.shape + right.shape
}
super(Add, self).__init__(**setup)
def _associate(self):
# perform macro expansion on the RPN
(obj_stack, cones, new_lines) = self.expander.expand( expr )
if not obj_stack: # should never happen
raise Exception("No objective parsed.")
obj = obj_stack.pop()
if obj_stack: # should never happen
raise Exception("Unparsed operands.")
if not isscalar(obj.shape):
raise Exception("\"%s\"\n\tObjective function %s should be scalar." % (self.line, obj.name))
if not check[tok](obj):
raise Exception(
"\"%s\"\n\tObjective vexity %s does not agree with %s" %
(self.line, Expression.vexity_names[obj.vexity], tok)
)
# label the top
self.description += ["",
"# " + 70*"=",
"# \"%s\"" % self.line,
"# " + 70*"="]
# add the objective
self.description += new_lines
self.description += ["# \"%s\"" % self.line,
"%s %s" % (val, obj.name)]
# convert to minimization prob
if tok == 'MAXIMIZE': self.codegen.obj = -obj
else: self.codegen.obj = obj
OP_NAME = "1'*"
IS_POSTFIX = False
OP_FUNC = sum_func
def __init__(self, x):
super(Sum, self).__init__(expr = x, sign = x.sign, curvature = x.curvature, shape = shape.Scalar())
def distribute(self):
if isinstance(self.expr, Add):
return (Sum(self.expr.left) + Sum(self.expr.right)).simplify()
if isinstance(self.expr, Mul) and shape.isscalar(self.expr.left):
return (Mul(self.expr.left, Sum(self.expr.right))).simplify()
return self
class Transpose(e.Expression, e.UnaryOperatorMixin):
""" Can only be applied to parameters
"""
def transpose(self,x):
if isinstance(x, e.Expression): return Transpose(x)
return x
OP_NAME = "'"
IS_POSTFIX = True
OP_FUNC = transpose
def __init__(self, expr):
super(Transpose, self).__init__(expr = expr, shape = expr.shape.transpose(), curvature = expr.curvature, sign = expr.sign)
def distribute(self):
if shape.isscalar(self.expr):
return self.expr
def post(self):
for line in self.lines:
if line:
new = []
expr = None
for token in line:
if token.priority > tokens.Pri.INVALID:
expr = expr or Expression()
expr.append(token)
else:
if expr:
new.append(expr)
expr = None
new.append(token)
if expr:
new.append(expr)
if new:
# implied expressions need to be added to tuples in their entirety, instead of just their last element
pops = []
for i in xrange(0, len(new)-1):
e, t = new[i], new[i+1]
def cast_to_const(expr):
if isinstance(expr, AffExpression):
return expr
if isinstance(expr, Expression):
return NotImplemented
else:
return types.constant()(expr)
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CVXPY. If not, see .
"""
from .. import interface as intf
from .. import settings as s
from .. import utilities as u
from ..utilities import key_utils as ku
from expression import Expression, cast_other
import types
import operator as op
import numpy as np
class AffExpression(Expression):
""" An affine expression. """
# coefficients - a dict of {variable/Constant: [coefficients]}.
# dcp_attr - the curvature, sign, and shape of the expression.
def __init__(self, coefficients, dcp_attr):
self._coeffs = self.format_coeffs(coefficients)
self._stored_dcp_attr = dcp_attr
# Acts as a leaf node, so has no subexpressions.
self.subexpressions = []
# Reduces the coefficients to scalars if possible.
def format_coeffs(self, coefficients):
for var_id,blocks in coefficients.items():
for i,block in enumerate(blocks):
if intf.is_scalar(block):
blocks[i] = intf.scalar_value(block)
return coefficients