Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am just playing with python's scientific libraries expecially the examples from here: http://faculty1.coloradocollege.edu/~sburns/toolbox/ODE_II.html

I modified it by defining a "force function" and tried to make a simple (but non physical example) where the force depends on the x and y position of the object. Additionally I want to plot the force field with quiever. The problem is that I don't understand how to make the force function properly depend on (a function of) the x and y components of the position of the object, especially I get the error cited below.

from pylab import *
from scipy.integrate import odeint
import numpy as np

## set initial conditions and parameters
g = 9.81            # acceleration due to gravity
th = 91            # set launch angle
th = th * pi/180.   # convert launch angle to radians
v0 = 100           # set speed

x0=0                # specify initial conditions
y0=0
vx0 = v0*sin(th)
vy0 = v0*cos(th)



## define force Funktion

def F_func(x):
    F = zeros(2)
    F[0] = x[1] # 
    F[1] = x[0] #
    return F


## define function to compute f(X,t)
def f_func(state,time):
    f = zeros(4)    # create array to hold f vector
    f[0] = state[2] # f[0] = x component of velocity
    f[1] = state[3] # f[1] = x component of velocity
    f[2] = F_func(state[:2])[0]        # f[2] = acceleration in x direction
    f[3] = F_func(state[:2])[1]      # f[3] = acceleration in y direction
    return f

## set initial state vector and time array
X0 = [ x0, y0, vx0, vy0]        # set initial state of the system
t0 = 0.
tf = 10
tau = 0.1
#tf = input("Enter final time: ")
#tau = input("Enter time step: ")

# create time array starting at t0, ending at tf with a spacing tau
t = arange(t0,tf,tau)   

## solve ODE using odeint
X = odeint(f_func,X0,t) # returns an 2-dimensional array with the 
                        # first index specifying the time and the
                        # second index specifying the component of
                        # the state vector

print X
# putting ':' as an index specifies all of the elements for
# that index so x, y, vx, and vy are arrays at times specified 
# in the time array
x = X[:,0]  
y = X[:,1] 
vx = X[:,2] 
vy = X[:,3]


## plot the trajectory
fig = figure()
ax = fig.add_subplot(1,1,1)

## Enlarge Limits by en Percent
en = 0.05


#xMin,xMax = 0,10
xMin,xMax = min(x),max(x)
yMin,yMax = min(y),max(y)

xMin,xMax = xMin - (xMax-xMin)*en,xMax + (xMax-xMin)*en
yMin,yMax = yMin - (yMax-yMin)*en,yMax + (yMax-yMin)*en


#plot(x,y,[xMin,xMax],[yMin,yMax])
#plot(x,y,[0,10],[0,10])
ax.plot(x,y)
ax.axis('tight')
xlim([xMin,xMax])
ylim([yMin,yMax])


xG,yG = meshgrid(linspace(xMin,xMax,10),linspace(yMin,yMax,5))

ax.quiver(xG,yG,F_func(zip(xG,yG))[0],F_func(zip(xG,yG))[1],pivot='middle',minshaft=5,minlength=1,alpha=0.1)


xlabel('x')
ylabel('y')

show()

With this code I get the following error:

ValueError                                Traceback (most recent call last)
/usr/lib/python2.7/dist-packages/IPython/utils/py3compat.pyc in execfile(fname, *where)
    176             else:
    177                 filename = fname
--> 178             __builtin__.execfile(filename, *where)

/home/myuser/python/test.py in <module>()
     87 xG,yG = meshgrid(linspace(xMin,xMax,10),linspace(yMin,yMax,5))
     88 
---> 89 ax.quiver(xG,yG,F_func(zip(xG,yG))[0],F_func(zip(xG,yG))[1],pivot='middle',minshaft=5,minlength=1,alpha=0.1)
     90 
     91 

/home/myuser/python/test.py in F_func(x)
     20 def F_func(x):
     21     F = zeros(2)
---> 22     F[0] = x[1] #
     23     F[1] = x[0] #
     24     return F

ValueError: setting an array element with a sequence.

Can somebody explain this and how to fix it?

share|improve this question

1 Answer 1

up vote 1 down vote accepted

Try using

def F_func(x):
    F1 = x[1]
    F2 = x[0]
    return array([F1, F2])

instead of your F_func. And replace the invocation of quiver with

ax.quiver(xG,yG,F_func(array([xG,yG]))[0],F_func(array([xG,yG]))[1],pivot='middle',minshaft=5,minlength=1,alpha=0.1)

You can find out why numpy is giving you an error by placing a print x on the first line of your F_func.

F is just a two-element array and you are trying to assign arrays to each of its two elements (Hence the error "setting an array element with a sequence").

This happens because zip(xG, yG) does something you probably didn't intend it to do. (Try playing with it in ipython).

This is the resulting plot of the ODE solution I get when running your code:

share|improve this answer
    
Sorry, I forgot another modification. It should work if you also change the ax.quiver line (see above) –  ibab Feb 8 at 22:42

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.