How to get the sulution values for Pyomo named expressions? - expression

I defined a abstract pyomo model using named expressions (see "m.ElecDemand_kW" in the code below).
I wonder how to get the solution value for named expressions. They are also called Expression Objects.
from pyomo.environ import *
m = AbstractModel('TEST')
...
code
...
def Epr_elecDemand_kW_rule(m, b, sv, ts):
return (sum(m.Elec_Heater_kW_elec[b, sv, em, ts] for em in m.ELEC_HeaterModes)
+ sum(m.Hp_kW_elec[b, sv, hm, ts] for hm in m.HP_ALL))
m.ElecDemand_kW= Expression(m.BUILDtype, m.STOR_LiterVar, m.TS, rule=Epr_elecDemand_kW_rule)
def Obj_Funct_rule(m):
return sum(m.ElecDemand_kW[b, sv,ts] * m.t_step_seconds[ts] / 3600 / 1000 * m.ts_data["spotPrice_EpMWh",ts]
for b in m.BUILDtype
for sv in m.STOR_LiterVar
for ts in m.TS)
m.ObjectFunction = Objective(rule=Obj_Funct_rule)
instance = m.create_instance('GebaeudeV8.dat')
opt_results = opt.solve(instance, symbolic_solver_labels=True, keepfiles = True,
tee=True)
instance.solutions.store_to(opt_results)
At the moment I define after the solve command a new function
def Epr_elecDemand_kW_calc(m, b, sv, ts):
return (sum(instance.Elec_Heater_kW_elec[b, sv, em, ts].value
for em in instance.ELEC_HeaterModes.data())
+ sum(instance.Hp_kW_elec[b, sv, hm, ts]
for hm in instance.HP_ALL.data()))
to calculate the desired solution values and then copy it to a pandas dataframe and save it to Excel.
It there a easy way to get the sulution values of named expressions after solving the problem?
I just found out that value(Epr_elecDemand_kW_rule(instance, b, sv, ts))
works

The best way to do this is to use the value function on the Expression component itself instead of the rule:
value(instance.ElecDemand_kw[i,j,k])

Related

Cannot convert object of type 'list' to a numeric value

I am making a pyomo model, where i want to use random numbers for my two dimensional parameters. I put a small python script for random numbers that looks exactly what i wanted to see for my two dimensional parameter. I am getting a TypeError: Cannot convert object of type 'list'(value =[[....]] to a numeric value. in my objective function. Below is my objective function and random numbers script.
model.obj = Objective(expr=sum(model.C[v,l] * model.T[v,l] for v in model.V for l in model.L) + \
sum(model.OC[o,l] * model.D[o,l] for o in model.O for l in model.L), sense=minimize)
import random
C = [[] for i in range(7)]
for i in range(7):
for j in range(5):
C[i]+= [random.randint(100,500)]
model.C = Param(model.V, model.L, initialize=C)
Please let me know if someone can help fixing this.
You should initialize your parameter using a function instead of a nested list
def init_c(m, i, j):
return random.randint(100,500)
model.c = Param(model.V, model.L, initialize=init_c)

pymc and parameterize stochastic variables

I'm fairly new to python and pymc and wanted to try a problem out using pymc for learning purposes. I'm modeling a simple mendelian inheritence from grandparents down to son, but I don't understand how to reapply the same stochastic model multiple times. Any help is appreciated.
#py.stochastic
def childOf(value=1, d=0, m=0):
pdra=d/2
pmra=m/2
# now return likelihood
if (value==0):
return -np.log((1-pdra)*(1-pmra))
elif (value==1):
return -np.log((1-pdra)*(pmra)+(pdra)*(1-pmra))
else:
return -np.log((pdra*pmra))
p = [0.25,0.5,0.25]
gdd = py.Categorical("gdd", p, size=1)
gdm = py.Categorical("gdm", p, size=1)
gmd = py.Categorical("gmd", p, size=1)
gmm = py.Categorical("gmm", p, size=1)
gm=childOf('gm',d=gmm,m=gmd)
gd=childOf('gd',d=gdm,m=gdd)
gs=childOf('gs',d=gm,m=gd)
The error is a long string that ends with TypeError: 'numpy.ndarray' object is not callable on the first ChildOf
You are not using your Stochastic object correctly. childOf is a PyMC object itself, and not a constructor of PyMC objects as you are attempting to do in the last three lines. A better approach would be to specify a log-probability function and use this as the logp attribute for each object. For example:
import pymc as pm
import numpy as np
def childOf_logp(value=1, d=0, m=0):
pdra=d/2
pmra=m/2
# now return likelihood
if (value==0):
return -np.log((1-pdra)*(1-pmra))
elif (value==1):
return -np.log((1-pdra)*(pmra)+(pdra)*(1-pmra))
else:
return -np.log((pdra*pmra))
#pm.stochastic
def childOf_pm(value=1, d=gmm,m=gmd):
logp = childOf_logp

Real/imaginary part of sympy complex matrix

Here is my problem.
I'm using sympy and a complex matrix P (all elements of P are complex valued).
I wanna extract the real/imaginary part of the first row.
So, I use the following sequence:
import sympy as sp
P = sp.Matrix([ [a+sp.I*b,c-sp.I*d], [c-sp.I*d,a+sp.I*b] ])
Row = P.row(0)
Row.as_mutable()
Re_row = sp.re(Row)
Im_row = sp.im(Row)
But the code returns me the following error:
"AttributeError: ImmutableMatrix has no attribute as_coefficient."
The error occurs during the operation sp.re(Row) and sp.im(Row)...
Sympy tells me that Row is an Immutable matrix but I specify that I want a mutable one...
So I'm in a dead end, and I don't have the solution...
Could someone plz help me ?
thank you very much !
Most SymPy functions won't work if you just pass a Matrix to them directly. You need to use the methods of the Matrix, or if there is not such method (as is the case here), use applyfunc
In [34]: Row.applyfunc(re)
Out[34]: [re(a) - im(b) re(c) + im(d)]
In [35]: Row.applyfunc(im)
Out[35]: [re(b) + im(a) -re(d) + im(c)]
(I've defined a, b, c, and d as just ordinary symbols here, if you set them as real the answer will come out much simpler).

Granger Test (Python) Error message - TypeError: unsupported operand type(s) for -: 'str' and 'int'

I am trying to run a granger causality test on two currency pairs but I seem to get this error message in Shell whenever I try and test it. Can anyone please advise?
I am very new to programming and need this to run an analysis for my project. In shell, I am putting -
import ats15
ats15.grangertest('EURUSD', 'EURGBP', 8)
What is going wrong? I have copied the script below.
Thanks in advance.
Heading ##def grangertest(Y,X,maxlag):
"""
Performs a Granger causality test on variables (vectors) Y and X.
The null hypothese is: Does X cause Y ?
Returned value: pvalue, F, df1, df2
"""
# Create linear model involving Y lags only.
n = len(Y)
if n != len(X):
raise ValueError, "grangertest: incompatible Y,X vectors"
M = [ [0] * maxlag for i in range(n-maxlag)]
for i in range(maxlag, n):
for j in range(1, maxlag+1):
M[i-maxlag][j-1] = Y[i-j]
fit = ols(M, Y[maxlag:])
RSSr = fit.RSS
# Create linear model including X lags.
for i in range(maxlag, n):
xlagged = [X[i-j] for j in range(1, maxlag+1)]
M[i-maxlag].extend(xlagged)
fit = ols(M, Y[maxlag:])
RSSu = fit.RSS
df1 = maxlag
df2 = n - 2 * maxlag - 1
F = ((RSSr - RSSu)/df1)/(RSSu/df2)
pvalue = 1.0 - stats.f.cdf(F,df1,df2)
return pvalue, F, df1, df2, RSSr, RSSu
You didn't post the full traceback, but this error message:
TypeError: unsupported operand type(s) for -: 'str' and 'int'
means what it says. There's an operand - -- the subtraction operator -- and it doesn't know how to handle subtracting an integer from a string. Why would strings be involved? Well, you're calling the function with:
ats15.grangertest('EURUSD', 'EURGBP', 8)
and so you're giving grangertest two strings and an integer. But it seems like grangertest expects
def grangertest(Y,X,maxlag):
two sequences (lists, arrays, whatever) of numbers to use as Y and X, not strings. If EURUSD and EURGBP are names you've given to lists beforehand, then you don't need the quotes:
ats15.grangertest(EURUSD, EURGBP, 8)
but if not, then you should pass grangertest the lists under whatever name you've called them.
The input to the grangertest function must be two lists of numbers. grangertest doesn't know anything about currencies, so passing it currency strings won't work.
You have to fetch the exchange rate data somehow so that you can pass it to grangertest. If EURUSD and EURGBP are variables, then you don't put quotes around them when you pass them to a function (e.g. ats15.grangertest(EURUSD, EURGBP, 8)).

how to use units along function parameter values in Mathematica

I would like to pass the parameter values in meters or kilometers (both possible) and get the result in meters/second.
I've tried to do this in the following example:
u = 3.986*10^14 Meter^3/Second^2;
v[r_, a_] := Sqrt[u (2/r - 1/a)];
Convert[r, Meter];
Convert[a, Meter];
If I try to use the defined function and conversion:
a = 24503 Kilo Meter;
s = 10198.5 Meter/Second;
r = 6620 Kilo Meter;
Solve[v[r, x] == s, x]
The function returns the following:
{x -> (3310. Kilo Meter^3)/(Meter^2 - 0.000863701 Kilo Meter^2)}
which is not the user-friendly format.
Anyway I would like to define a and r in meters or kilometers and get the result s in meters/second (Meter/Second).
I would be very thankful if anyone of you could correct the given function definition and other statements in order to get the wanted result.
Here's one way of doing it, where you use the fact that Solve returns a list of rules to substitute a value for x into v[r, x], and then use Convert, which will do the necessary simplification of the resulting algebraic expression as well:
With[{rule = First#Solve[v[r,x]==s,x]
(* Solve always returns a list of rules, because algebraic
equations may have multiple solutions. *)},
Convert[v[r,x] /. rule, Meter/Second]]
This will return (10198.5 Meter)/Second as your answer.
You just need to tell Mathematica to simplify the expression assuming that the units are "possitive", which is the reason why it doesn't do the simplifications itself. So, something like
SimplifyWithUnits[blabla_, unit_List]:= Simplify[blalba, (#>0)&/#unit];
So if you get that ugly thing, you then just type %~SimplifyWithUnits~{Meter} or whatever.

Resources