I am currently learning how to do differential equations on Python using SymPy.
def problem():
alpha, beta, t = symbols('alpha beta t', real=True)
s = Function('s')(t)
expr = Eq(s.diff(t), alpha*s**2 + beta*s)
print(expr)
print(sympy.dsolve(expr, simplify=True, ics={s(0): 1000}))
It always gives me TypeError: object 's' is not callable when putting the initial condition (it works and give me general solution with C1 when I remove ics)
Anyone can help with this?
I need to calculate the friction factor using the Colebrook-Equation, but unlike most cases it needs to be over a length, so the Reynolds number is a list, not a float.
I basically used what this guy this guy recommended (fixed point iteration), specially because it will be part of a bigger programm which wasn't very fast when I did it in Matlab.
For my interpretation of that code I oriented myself at the example of the fixed_point documentation, because there they also pass arguments in form of lists into the function (or actually the solver). v is a list with 1000 elements.
k = 0.000045
d = 0.03
reynolds = d/10**(-6)*v
def f(x, Re):
LHS = -2*np.log10((2.51/(Re*np.sqrt(x))) + (k/(3.71*d)))
return 1/LHS**2
x0 = [0.02]*1000
Re = np.array(reynolds)
result = fixed_point(f,x0, args = Re)
print(result)
I made sure that the starting value and the Reynolds-argument have the same length and I still get an error message.
File " ... ", line 72, in <module>
result = fixed_point(f,x0, args = Re)
...
TypeError: f() takes 2 positional arguments but 1001 were given
I feel like I'm missing something fundamentally here although I'm sitting on it longer than this problem should be taking me.
Thanks for you help,
I am trying to implement a cost function in a pydrake Mathematical program, however I encounter problems whenever I try to divide by a decision variable and use the abs(). A shortened version of my attempted implementation is as follows, I tried to include only what I think may be relevant.
T = 50
na = 3
nq = 5
prog = MathematicalProgram()
h = prog.NewContinuousVariables(rows=T, cols=1, name='h')
qd = prog.NewContinuousVariables(rows=T+1, cols=nq, name='qd')
d = prog.NewContinuousVariables(1, name='d')
u = prog.NewContinuousVariables(rows=T, cols=na, name='u')
def energyCost(vars):
assert vars.size == 2*na + 1 + 1
split_at = [na, 2*na, 2*na + 1]
qd, u, h, d = np.split(vars, split_at)
return np.abs([qd.dot(u)*h/d])
for t in range(T):
vars = np.concatenate((qd[t, 2:], u[t,:], h[t], d))
prog.AddCost(energyCost, vars=vars)
initial_guess = np.empty(prog.num_vars())
solver = SnoptSolver()
result = solver.Solve(prog, initial_guess)
The error I am getting is:
RuntimeError Traceback (most recent call last)
<ipython-input-55-111da18cdce0> in <module>()
22 initial_guess = np.empty(prog.num_vars())
23 solver = SnoptSolver()
---> 24 result = solver.Solve(prog, initial_guess)
25 print(f'Solution found? {result.is_success()}.')
RuntimeError: PyFunctionCost: Output must be of .ndim = 0 (scalar) and .size = 1. Got .ndim = 2 and .size = 1 instead.
To the best of my knowledge the problem is the dimensions of the output, however I am unsure of how to proceed. I spent quite some time trying to fix this, but with little success. I also tried changing np.abs to pydrake.math.abs, but then I got the following error:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-56-c0c2f008616b> in <module>()
22 initial_guess = np.empty(prog.num_vars())
23 solver = SnoptSolver()
---> 24 result = solver.Solve(prog, initial_guess)
25 print(f'Solution found? {result.is_success()}.')
<ipython-input-56-c0c2f008616b> in energyCost(vars)
14 split_at = [na, 2*na, 2*na + 1]
15 qd, u, h, d = np.split(vars, split_at)
---> 16 return pydrake.math.abs([qd.dot(u)*h/d])
17
18 for t in range(T):
TypeError: abs(): incompatible function arguments. The following argument types are supported:
1. (arg0: float) -> float
2. (arg0: pydrake.autodiffutils.AutoDiffXd) -> pydrake.autodiffutils.AutoDiffXd
3. (arg0: pydrake.symbolic.Expression) -> pydrake.symbolic.Expression
Invoked with: [array([<AutoDiffXd 1.691961398933386e-257 nderiv=8>], dtype=object)]
Any help would be greatly appreciated, thanks!
BTW, as Tobia has mentioned, dividing a decision variable in the cost function could be problematic. There are two approaches to avoid the problem
Impose a bound on your decision variable, and 0 is not included in this bound. For example, say you want to optimize
min f(x) / y
If you can impose a bound that y > 1, then SNOPT will not try to use y=0, thus you avoid the division by zero problem.
One trick is to introduce another variable as the result of division, and then minimize this variable.
For example, say you want to optimize
min f(x) / y
You could introduce a slack variable z = f(x) / y. And formulate this problem as
min z
s.t f(x) - y * z = 0
Some observations:
The kind of cost function you are trying to use does not need the use of a python function to be enforced. You can just say (even though it would raise other errors as is) prog.AddCost(np.abs([qd[t, 2:].dot(u[t,:])*h[t]/d])).
The argument of prog.AddCost must be a Drake scalar expression. So be sure that your numpy matrix multiplications return a scalar. In the case above they return a (1,1) numpy array.
To minimize the absolute value, you need something a little more sophisticated than that. In the current form you are passing a nondifferentiable objective function: solvers do not quite like that. Say you want to minimize abs(x). A standard trick in optimization is to add an extra (slack) variable, say s, and add the constraints s >= x, s >= -x, and then minimize s itself. All these constraints and this objective are differentiable and linear.
Regarding the division of the objective by an optimization variable. Whenever you can, you should avoid that. For example (I'm 90% sure) that solvers like SNOPT or IPOPT set the initial guess to zero if you do not provide one. This implies that, if you do not provide a custom initial guess, at the first evaluation of the constraints, the solver will have a division by zero and it'll crash.
Team Pyomo, I kindly need help with the above-stated error. I have done everything I could, but still can't get my model to work. Below is the formulation of my 'Objective Function', and the errors message. Thank you.
## Define Objective ##
def objective_rule(model):
s1=sum(1000*(model.fmax[j] - model.fmin[j])+ model.cmax[j] - model.cmin[j] for j in model.j)
s2=sum(model.x[i,k]*model.k*model.t[i] for k in model.k for i in model.i)
return s1 + 300 * s2
model.objective = Objective(expr=objective_rule, sense=minimize, doc='the objective function')
all the code that is before the objective function is fine (no errors). So, I will include below the code that comes after...it may be the one that caused the problem
## Display of the output ##
def pyomo_postprocess(options=None, instance=None, results=None):
instance.x.display()
writer = ExcelWriter("Data/output!G5:AJ27.csv")
df.to_excel(writer,index=False)
writer.save()
# pyomo command-line
if __name__ == '__main__':
# This emulates what the pyomo command-line tools does
from pyomo.opt import SolverFactory
import pyomo.environ
instance = model.create_instance()
instance.pprint()
opt = solvers.SolverFactory("cplex")
results = opt.solve(instance, tee=True)
# sends results to stdout
instance.solutions.load_from(results)
print("\nDisplaying Solution\n" + '-' * 60)
pyomo_postprocess(None, instance, results)
When I execute the program, I have the next error message:
ERROR: Constructing component 'objective' from data=None failed:
TypeError: Cannot treat the value '<function objective_rule at
0x0000000007C31D08>' as a constant because it has unknown type
'function'
The problem is that you're using the wrong keyword argument in your Objective component declaration. You should be using rule not expr:
model.objective = Objective(rule=objective_rule, sense=minimize, doc='the objective function')
The expr keyword is typically used when you have a very simple objective function expression and want to avoid writing a Python function to return the objective expression. You would use it like:
model.objective = Objective(expr=m.x**2+m.y**2, sense=minimize, doc='the objective function')
I am pretty new with Python and I am given a task to create a model in Python.
I have a problem with this formula:
density = p/(0.1921 * (T+273.1)).
It keeps saying: TypeError: can only concatenate tuple (not "float") to tuple.
Does anyone know the solution?
p = 0.699 * exp**(-0.00009 * h)
T = -23,4 - 0.00222 * h
rho = p/(0.1921 * (T+273.1))
The error came from the usage of the comma in the calculation of T:
T = -23,4 - 0.00222 * h
In the Python grammar definition the comma , character, among other things, is the value separator for collections like tuple, list, etc.. You should use the dot . charater instead to forge floats, as in the following:
T = -23.4 - 0.00222 * h