Emulating MATLAB's ode15s in Python - python

I am working on translating a model from MATLAB to Python. The crux of the model lies in MATLAB's ode15s. In the MATLAB execution, the ode15s has standard options:
options = odeset()
[t P] = ode15s(#MODELfun, tspan, y0, options, params)
For reference, y0 is a vector (of size 98) as is MODELfun.
My Python attempt at an equivalent is as follows:
ode15s = scipy.integrate.ode(Model.fun)
ode15s.set_integrator('vode', method = 'bdf', order = 15)
ode15s.set_initial_value(y0).set_f_params(params)
dt = 1
while ode15s.successful() and ode15s.t < duration:
ode15s.integrate(ode15s.t+dt)
This though, does not seem to be working. Any suggestions, or an alternative?
Edit:
After looking at the output, the result I'm getting from the Python is either no change in some elements of y0 over time, or a constant change at each step for the rest of the y0. Any experience with something like this?

According to the SciPy wiki for Matlab Users, the right way for using the ode15s is
scipy.integrate.ode(f).set_integrator('vode', method='bdf', order=15)

One point to make clear is that, unlike Matlab's ode15s, the scipy integrator 'vode' does not support models with a mass matrix. So any recommendation should include this caveat.

Related

solve an equation (with max-statement) in python

i am seeking a solution for the following equation in Python.
345-0.25*t = 37.5 * x_a
'with'
t = max(0, 10-x_a)*(20-10) + max(0,25-5*x_a)*(3-4) + max(0,4-0.25*x_a)*(30-12.5)
'x_a = ??'
If there is more than one solution to the problem (I am not even sure, whether this can happen from a mathematical point of view?), I want my code to return a positive(!) value for x_a, that minimizes t.
With my previous knowledge in the Basics of Python, Pandas and NumPy I actually have no clue, how to tackle this problem. Can someone give me a hint?
For Clarification: I inserted some exemplary numbers in the equation to make it easier to gasp the problem. In my final code, there might of course be different numbers for different scenarios. However, in every scenario x_a is the only unknown variable.
Update
I thought about the problem again and came up with the following solution, which yields the same result as the calculations done by MichaƂ Mazur:
import itertools
from sympy import Eq, Symbol, solve
import numpy as np
x_a = Symbol('x_a')
possible_elements = np.array([10-x_a, 25-5*x_a, 4-0.25*x_a])
assumptions = np.array(list(itertools.product([True, False], repeat=3)))
for assumption in assumptions:
x_a = Symbol('x_a')
elements = assumption.astype(int) * possible_elements
t = elements[0]*(20-10) + elements[1]*(3-4) + elements[2]*(30-12.5)
eqn = Eq(300-0.25*t, 40*x_a)
solution = solve(eqn)
if len(solution)>2:
print('Warning! the code may suppress possible solutions')
if len(solution)==1:
solution = solution[0]
if (((float(possible_elements[0].subs(x_a,solution))) > 0) == assumption[0]) &\
(((float(possible_elements[1].subs(x_a,solution))) > 0) == assumption[1]) &\
(((float(possible_elements[2].subs(x_a,solution)))> 0) == assumption[2]):
print('solution:', solution)
Compared to the already suggested approach this may have an little advantage as it does not rely on testing all possible values and therefore can be used for very small as well as very big solutions without taking a lot of time (?). However, it probably only is useful as long as you don't have more complex functions for t (even having for example 5 max(...) statements and therefore (2^5=)32 scenarios to test seems quite cumbersome).
As far as I'm concerned, I just realized that my problem is even more complex as i thought. For my project the calculations needed to derive the value of "t" are pretty entangled and can not be written in just one equation. However it still is a function, that only relies on x_a. So I am still hoping for a Python-Solution similar to the proposed Solver in Excel... or I will stick to the approach of simply testing out all possible numbers.
If you are interested in a solution a bit different than the Python one, then I will give you a hand. Open up your Excel, with Solver extention and plug in
the data you are interested in cheking, as the following:
Into the E2 you plug the command I just have writen, into E4 you plug in
=300-0,25*E2
Into the F4 you plug:
=40*F2
Then you open up your Solver menu
Into the Set Objective you put the variable t, which you want to minimize.
Into Changing Variables you put the a.
Into Constraint Menu you put the equality of E4 and F4 cells.
You check the "Make Unconstarained Variables be non-negative" which will prevent your a variable to go below 0. Your method of computing is strictly non-linear, so you leave this option there.
You click solve. The computed value is presented in the screen.
The python approach I can think of:
minimumval=10100
minxa=10000
eps=0.01
for i in range(100000):
k=i/10000
x_a=k
t = max(0, 10-x_a)*(20-10) + max(0,25-5*x_a)*(3-4) + max(0,4-0.25*x_a)*(30-12.5)
val=abs(300-0.25*t-40*x_a)
if (val<eps):
if t<minimumval:
minimumval=t
minxa=x_a
It isn't direct solution, as in it only controls the error that you make in the equality by eps value. However, it gives solution.

High memory usage when doing direct transcription with sympy equations

I used sympy to derive, via lagrange, the equations of motion of my 3 link robot. The resultant equation of motion in the form (theta_dot_dot = f(theta, theta_dot)) turned out very complicated with A LOT of cos and sin. I then lambdified the functions to use with drake, replacing all the sympy.sin and sympy.cos with drake.sin, drake.cos.
The final function can be evaluated numerically (i.e. given theta, theta_dot, find theta_dot_dot) somewhat efficiently in the milliseconds range.
I then tried to use direct transcription to do trajectory optimization. Note I did not use the DirectTranscription library, instead manually added the necessary constraints.
The constraints are added roughly as follows:
for i in range(NUM_TIME_STEPS-1):
print("Adding constraints for t = " + str(i))
tau = mp.NewContinuousVariables(3, "tau_%d" % i)
next_state = mp.NewContinuousVariables(8, "state_%d" % (i+1))
for j in range(8):
mp.AddConstraint(next_state[j] <= (state_over_time[i] + TIME_INTERVAL*derivs(state_over_time[i], tau))[j])
mp.AddConstraint(next_state[j] >= (state_over_time[i] + TIME_INTERVAL*derivs(state_over_time[i], tau))[j])
state_over_time[i+1] = next_state
tau_over_time[i] = tau
The problem I'm facing right now is that on each iteration of adding constraints, I observe that my memory usage increases by around 70-100MB. This means that my number of time steps cannot go more than around 50 before the program crashes due to out of memory.
I'm wondering what I can do to make trajectory optimization work for my robot. Obviously I can try to simplify (by hand or otherwise) the equations of motions... but is there anything else I can try? Is it even normal that the constraints are taking up so much memory? Am I doing something very wrong here?
You're pushing drake's symbolic through your complex equations. Making that better is a good goal, but probably you want to avoid it by using the other overload for AddConstraint:
AddConstraint(your_method, lb, ub, vars)
https://drake.mit.edu/pydrake/pydrake.solvers.mathematicalprogram.html?highlight=addconstraint#pydrake.solvers.mathematicalprogram.MathematicalProgram.AddConstraint
That will use your python code as a function pointer, and should use autodiff instead of symbolic.

numpy: arange include endpoint

I need to transfer some Matlab code into P. I got stuck at a numpy.arange I use to set points continuously on the arc of circle with a given angle (in radians).
I got this far (example for points on x-axis):
def sensor_data_arc_x():
theta = np.arange(0, angle/2, 2*np.pi/360)
return np.multiply(radius, np.cos(np.transpose(theta)))
I know numpy.arange does not include the endpoint, although the Matlab equivalent does; the array is always one element short, which is messing up my further computations.
Is there an way to include the endpoint?
I recommend that you work through a tutorial on for loops -- the information you need is there, as well as other hints on using controlled iteration. To solve your immediate need, simply increase your upper bound by one loop increment:
inc = 2*np.pi/360
theta = np.arange(0, angle/2 + inc, inc)

Making a Qobj out of a picos variable

I need to write a semidefinite program that minimizes the trace of an operator, say R, subject to the constraint that tr_A(R)^{Tb} >>0 . That means that R represents a 3 qubit quantum system and the trace over the first system gives you an operator that represents the remaining 2 qubit systems. Taking the partial transpose with respect to one of the qubits, you get the partially transposed quantum state of the restricted 2 qubit system. It is this state that I want to make positive semidefinite.
I am using PICOS (to write the SDP) and qutip (to do the operations).
P = pic.Problem()
Rho = P.add_variable('Rho',(n,n),'hermitian')
P.add_constraint(pic.trace(Rho)==1)
P.add_constraint(Rho>>0)
RhoQOBJ = Qobj(Rho)
RhoABtr = ptrace(RhoQOBJ, [0,1])
RhoABqbj = partial_transpose(RhoABtr, [0], method='dense')
RhoAB = RhoABqbj.full()
Problem: I need to make Rho a Qobj, for qutip to be able to understand it, but Rho above is only an instance of the Variable class. Anyone has any idea on how to do this?
Also I looked here, http://picos.zib.de/tuto.html#variables , it became even more confusing as this function puts the instance in a dictionary and only gives you back a key.
You need to be able to output a numpy array or sparse matrix to convert to a Qobj. I could not find anything in the picos docs that discusses this option.
I am seeing this post very late, but maybe I can help... I am not sure what the function Qobj() is doing, can you please tell me more about it.
Otherwise, there is now a new partial_transpose() function in PICOS (version released today), which hopefully does what you need.
Best,
Guillaume.

Is there a Python equivalent to the smooth.spline function in R

The smooth.spline function in R allows a tradeoff between roughness (as defined by the integrated square of the second derivative) and fitting the points (as defined by summing the squares of the residuals). This tradeoff is accomplished by the spar or df parameter. At one extreme you get the least squares line, and the other you get a very wiggly curve which intersects all of the data points (or the mean if you have duplicated x values with different y values)
I have looked at scipy.interpolate.UnivariateSpline and other spline variants in Python, however, they seem to only tradeoff by increasing the number of knots, and setting a threshold (called s) for the allowed SS residuals. By contrast, the smooth.spline in R allows having knots at all the x values, without necessarily having a wiggly curve that hits all the points -- the penalty comes from the second derivative.
Does Python have a spline fitting mechanism that behaves in this way? Allowing all knots but penalizing the second derivative?
You can use R functions in Python with rpy2:
import rpy2.robjects as robjects
r_y = robjects.FloatVector(y_train)
r_x = robjects.FloatVector(x_train)
r_smooth_spline = robjects.r['smooth.spline'] #extract R function# run smoothing function
spline1 = r_smooth_spline(x=r_x, y=r_y, spar=0.7)
ySpline=np.array(robjects.r['predict'](spline1,robjects.FloatVector(x_smooth)).rx2('y'))
plt.plot(x_smooth,ySpline)
If you want to directly set lambda: spline1 = r_smooth_spline(x=r_x, y=r_y, lambda=42) doesn't work, because lambda has already another meaning in Python, but there is a solution: How to use the lambda argument of smooth.spline in RPy WITHOUT Python interprating it as lambda.
To get the code running you first need to define the data x_train and y_train and you can define x_smooth=np.array(np.linspace(-3,5,1920)). if you want to plot it between -3 and 5 in Full-HD-resolution.
Note that this code is not fully compatible with Jupyter-notebooks for the latest versions of rpy2. You can fix this by using !pip install -Iv rpy2==3.4.2 as described in NotImplementedError: Conversion 'rpy2py' not defined for objects of type '<class 'rpy2.rinterface.SexpClosure'>' only after I run the code twice
I've been looking for exactly the same thing, but would rather not have to translate the code to Python. The Splinter package seems like an option, however: https://github.com/bgrimstad/splinter
From research on google, I concluded that
By contrast, the smooth.spline in R allows having knots at all the x values, without necessarily having a wiggly curve that hits all the points -- the penalty comes from the second derivative.

Categories

Resources