How to get a value from multiple functions in Pyomo - pyomo

Let's suppose that the objective function is
max z(x,y) = f1(x) - f2(y)
where f1 is function of variables x and f2 is functions of variables y.
This could be written in Pyomo as
def z(model):
return f1(model) - f2(model)
def f1(model):
return [some summation of x variables with some coefficients]
def f2(model):
return [some summation of y variables with some coefficients]
model.objective = Objective(rule=z)
I know it is possible to get the numeric value of z(x,y) easily by calling (since it is the objective function) :
print(model.objective())
but is there a way to get the numeric value of any of these sub-functions separetedly after the optimization, even if they are not explicitly defined as objectives?

I'll answer your question in terms of a ConcreteModel, since rules in Pyomo, for the most part, are nothing more than a mechanism to delay building a ConcereteModel. For now, they are also required to define indexed objects, but that will likely change soon.
First, there is nothing stopping you from defining those "rules" as standard functions that take in some argument and return a value. E.g.,
def z(x, y):
return f1(x) - f2(y)
def f1(x):
return x + 1
def f2(x):
return y**2
Now if you call any of these functions with a built-in type (e.g., f(1,5)), you will get a number back. However, if you call them with Pyomo variables (or Pyomo expressions) you will get a Pyomo expression back, which you can assign to an objective or constraint. This works because Pyomo modeling components, such as variables, overload the standard algebraic operators like +, -, *, etc. Here is an example of how you can build an objective with these functions:
import pyomo.environ as aml
m = aml.ConcreteModel()
m.x = aml.Var()
m.y = aml.Var()
m.o = aml.Objective(expr= z(m.x, m.y))
Now if m.x and m.y have a value loaded into them (i.e., the .value attribute is something other than None), then you can call one of the sub-functions with them and evaluate the returned expression (slower)
aml.value(f1(m.x))
aml.value(f2(m.y))
or you can extract the value from them and pass that to the sub-functions (faster)
f1(m.x.value)
f2(m.y.value)
You can also use the Expression object to store sub-expressions that you want to evaluate on the fly or share inside multiple other expression on a model (all of which you can update by changing what expression is stored under the Expression object).

Related

Sympy Typeerror: cannot determine truth value of Relational (How to make sure x > 0)

I want to check if 6**x1 is bigger than 0 for every positive value of x1. I am using sympy.
I've done the following:
x1 = sm.symbols('x_1',nonnegative=True)
u = 6**x1
def checker(func):
if u > 0:
return True
else:
return False
However, I get the error:
TypeError: cannot determine truth value of Relational
I think this is because the function does not know that x1 is positive. But how do I make sure it knows this? Apparently, its not enough with the sm.symbols definition.
Zebraboard
SymPy only let's you compare things that can be computed to a number with literal > (and similar). If you want to make a query on a symbolic expression use expr.is_positive or (expr.is_extended_positive if you want oo to be considered, too).
>>> u.is_positive
True
This can be None or False, too. None is returned when a definitive determination cannot be made, e.g. symbols('x').is_positive is None -> True.

Evaluate constraint expression as boolean

I want to evaluate if a constraint is respected or not in Pyomo when the values of the variables contained in constraint expression are known.
Use case: We know that one particular constraint sometimes makes the problem infeasible, depending on the value of the variable. Instead of sending the problem to the solver to test if the problem is feasible, converting the constraint expression to a boolean type would be enough to determine if the constraint is the culprit.
For the sake of providing a feasible example, here would be the code:
from pyomo.environ import ConcreteModel, Var, Constraint
model = ConcreteModel()
model.X = Var()
def constraint_rule(model):
return model.X <= 1
model.a_constraint = Constraint(rule=constraint_rule)
Now, let's try to work with the expression to evaluate:
# Let's define the expression in this way:
expression = constraint_rule(model)
# Let's show that the expression is what we expected:
print(str(expression))
The previous statement should print X <= 1.0.
Now, the tricky part is how to evaluate the expression.
if expression == True:
print("feasible")
else:
print("infeasible")
creates an TypeError Exception (TypeError: Cannot create an EqualityExpression where one of the sub-expressions is a relational expression: X <= 1.0).
The last example doesn't work because constraint_rule doesn't return a boolean but a Pyomo expression.
Finally, I know that something like
def evaluate_constraint_a_expression(model):
return value(model.X) <= 1
would work, but I can't assume that I will always know the content of my constraint expression, so I need a robust way of evaluating it.
Is there a clever way of achieving this? Like, evaluating the expression as a boolean and evaluating the left hand side and right hand side of the expression at the same time?
The solution is to use value function. Even if it says that it evaluates an expression to a numeric value, it also converts the expression to a boolean value if it is an equality/inequality expression, like the rule of a constraint.
Let's suppose that the model is defined the way it is in the question, then the rest of the code should be:
from pyomo.environ import value
if value(expression) == True:
print("feasible")
else:
print("infeasible")
where expression is defined as written in the question.
However, be advised that numeric precision in Python using this method can be different than the one provided by the solver. Therefore, it is possible that this method will show that a constraint is infeasible while it is just a matter of numeric imprecision of under 1e-10. So, while it is useful in finding if most constraints are feasible, it also generates some false positives.

Theano scan function

Example taken from: http://deeplearning.net/software/theano/library/scan.html
k = T.iscalar("k")
A = T.vector("A")
# Symbolic description of the result
result, updates = theano.scan(fn=lambda prior_result, A: prior_result * A,
outputs_info=T.ones_like(A),
non_sequences=A,
n_steps=k)
# We only care about A**k, but scan has provided us with A**1 through A**k.
# Discard the values that we don't care about. Scan is smart enough to
# notice this and not waste memory saving them.
final_result = result[-1]
# compiled function that returns A**k
power = theano.function(inputs=[A,k], outputs=final_result, updates=updates)
print power(range(10),2)
print power(range(10),4)
What is prior_result? More accurately, where is prior_result defined?
I have this same question for lot of the examples given on:http://deeplearning.net/software/theano/library/scan.html
For example,
components, updates = theano.scan(fn=lambda coefficient, power, free_variable: coefficient * (free_variable ** power),
outputs_info=None,
sequences=[coefficients, theano.tensor.arange(max_coefficients_supported)],
non_sequences=x)
Where is power and free_variables defined?
This is using a Python feature call "lambda". lambda are unnamed python function of 1 line. They have this forme:
lambda [param...]: code
In your example it is:
lambda prior_result, A: prior_result * A
This is a function that take prior_result and A as input. This function, is passed to the scan() function as the fn parameter. scan() will call it with 2 variables. The first one will be the correspondance of what was provided in the output_info parameter. The other is what is provided in the non_sequence parameter.

Is it possible to use User Defined Attributes to get values at runtime?

What I really would like to do is cache/memoize certain function arguments and results. I understand in d there's User Defined Attributes, but it appears theres no way to get runtime values with it. Am I mistaken? Is there another similar design pattern I could use here to get similar results?
#memoize("expensiveCalc")
int expensiveCalc(string foo){
///bar
}
So memoize is actually a function that gets called. However, it utilizes the value of my arguments to quickly hash parameters and call the actual function.
Similar to this:
def memoize(iden, time = 0, stale=False, timeout=30):
def memoize_fn(fn):
def new_fn(*a, **kw):
#if the keyword param _update == True, the cache will be
#overwritten no matter what
update = kw.pop('_update', False)
key = make_key(iden, *a, **kw)
res = None if update else memoizecache.get(key)
if res is None:
# okay now go and actually calculate it
res = fn(*a, **kw)
memoizecache.set(key, res, time=time)
return res
new_fn.memoized_fn = fn
return new_fn
return memoize_fn
For what you're trying to do, you'll want a wrapper template rather than a UDA. Phobos actually has one for memoization: http://dlang.org/phobos/std_functional.html#memoize
UDAs in D are used to add information to a function (or other symbol, types and variables too), but they don't actually modify it. The pattern is to have some other code read all the names with reflection, look at the UDAs, and generate the new code that way. If you want to get runtime values from a UDA, you'd write a function that reads it with compile time reflection, then returns the value. Calling that function at runtime gives the UDA there. If you'd like to know more, I can write it up, but I think std.functional.memoize will do what you want here. Remember, UDAs in D add information, they don't change or create code.

C++ methods overload in python

suppose a C++ class has several constructors which are overloaded according the number and type and sequences of their respective parameters, for example, constructor(int x, int y) and constructor(float x, float y, float z), I think these two are overloaded methods, which one to use depends on the parameters, right? So then in python, how could I create a constructor that can work like this? I notice that python has the def method(self, *args, **kwargs):, so can I use it like: def __init__(self, *args), then I check the length of *args, like if len(args) == 2:, then construct according to the 2-parameters constructor, if len(args) == 3, then use the 3-parameters constructor, etc. So, does that work? Or is there any better way to do it with python? Or should I think in other ways that could take the advantage of python feature itself? thanks~
Usually, you're fine with any combination of
slightly altered design
default arguments (def __init__(self, x = 0.0, y = 0.0, z = 0.0))
use of polymorphism (in a duck-typed language, you don't need an overload for SomeThing vs SomeSlightlyDifferentThing if neither inherits from the other one, as long as their interfaces are similar enough).
If that doesn't seem feasible, try harder ;) If it still doesn't seem feasible, look at David's link.
It really depends on what you want to do. The *args/**kwargs method works fairly well, as does the default arguments that delnan suggests.
The main difference between C++ and Python in this case is the what and why of what you are trying to do. If you have a class that needs floats, just try casting the arguments as floats. You can also rely on default arguments to branch your logic:
class Point(object):
def __init__(self, x=0.0, y=0.0, z=None):
# Because None is a singleton,
# it's like Highlander - there can be only one! So use 'is'
# for identity comparison
if z is None:
self.x = int(x)
self.y = int(y)
self.z = None
else:
self.x = float(x)
self.y = float(y)
self.z = float(z)
p1 = Point(3, 5)
p2 = Point(1.0, 3.3, 4.2)
p3 = Point('3', '4', '5')
points = [p1, p2, p3]
for p in points:
print p.x, p.y, p.z
You don't, of course, have to assign self.z = None, that was simply for the convenience of my example.
For the best advice about which pattern to use,
In [17]: import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
...
If your pattern is beautiful, explicit, and simple, it just may be the right one to use.
I think these two are overloaded methods, which one to use depends on the parameters, right?
Sorry, if I seem to be nitpicking, but just thought of bringing this difference out clearly.
The term parameters and arguments have very specific meaning in C++
argument: an expression in the comma-separated list bounded by the parentheses in a function call expression, a sequence of preprocessing tokens in the comma-separated list bounded by the parentheses in a function-like macro invocation, the operand of throw, or an expression, type-id or template-name in the commaseparated list bounded by the angle brackets in a template instantiation. Also known as an actual argument or actual parameter.
parameter: an object or reference declared as part of a function declaration or definition, or in the catch clause of an exception handler, that acquires a value on entry to the function or handler; an identifier from the commaseparated list bounded by the parentheses immediately following the macro name in a function-like macro definition; or a template-parameter. Parameters are also known as formal arguments or formal parameters
This article talks about how a multimethod decorator can be created in Python. I haven't tried out the code that they give, but the syntax that it defines looks quite nice. Here's an example from the article:
from mm import multimethod
#multimethod(int, int)
def foo(a, b):
...code for two ints...
#multimethod(float, float):
def foo(a, b):
...code for two floats...
#multimethod(str, str):
def foo(a, b):
...code for two strings...