Anon Emouse - 1 year ago 65

Python Question

So I have coded a function for Euler's method. However, I want it to be able to use initial conditions with arbitrary dimensions. So for example, currently my functions works using this:

`>>>Euler(f, x0, t0, h, N)`

where x0 is a float. However I want it to be able to use this:

`>>>Euler(f, [x0], t0, h, N)`

where x0 is now a list of floats. (making it multidimensional)

f = function, x0 = initial conditions at time t0,

t0 = initial time, h = step size, N = number of steps.

I have tried using a for loop:

`def Euler(f,x0,t0,h,N):`

t = t0

y = x0

z = []

v = []

for i in y:

while t <= N:

xval = t

yval = [y]

t += h

y += h * f(t,y[i]) #i have also tried y+= h*f(t, i)

z.append(xval)

v.append(yval)

return z, v

The error I get is TypeError: list indices must be integers or slices, not float. Which I understand, meaning I have to index the y, like using y[0], y[1], etc...but when I do

y+= h* f(t, y[:])

It gives me an error regarding my other function in the file : f = >

`TypeError: a float is required`

line 22, in <module> vv = -x**3 - x + sin(t)

When I also try

`y += h * f(t, y[0])`

and I enter

`>>>Euler(f, [0., 1.], 0., 1, 10)`

line 15, in <module>

y += h * f(t,y[0])

builtins.TypeError: 'float' object is not iterable

I essentially want to return 2 lists, first list is the z, where it returns a list of the time values, and the second list v, where it returns a list of list of each of the results during each step. So far it has worked where I used a float but not a list. So what code am I missing?

Answer Source

Try this:

```
def Euler(f,x0,t0,h,N):
t = t0
z = []
v = []
for y in x0:
while t <= N:
xval = t
yval = [y]
t += h
y += h * f(t,y) #i have also tried y+= h*f(t, i)
z.append(xval)
v.append(yval)
return z, v
```

I don't know if this is the intended method seeing as `y += h * f(t,y)`

is dead code and is not used anywhere else

I believe the error is due to not paying attention to the types of your variables. `y`

was a list when you did `y = x0`

.

Fast-forward to this line `y += h * f(t,y[i])`

. In here you try to use the `+=`

operator on `y`

and what this does is to append the contents of another iterable to `y`

.

In the same statement, you try to index into `y`

using `i`

. To index into a list, you need to use an integer, but since `i`

is an element of `y`

(which is an array of floats), `i`

cannot be used to index into the list, and this is why you can the error:

TypeError: list indices must be integers or slices, not float.

Also when you do this `y+= h* f(t, y[:])`

, you get the error:

TypeError: a float is required

Because `y[:]`

creates a new list with all the elements of `y`

, thus you are still passing a list to your function.

Finally when you do this `y += h * f(t, y[0])`

, you get the error:

builtins.TypeError: 'float' object is not iterable

Because as I mentioned before, `y`

is a list and `+=`

on a list appends the contents of another iterable to the current list. The way it does this is to "iterate" over the second list and append the items in that second list to the first. Since the value `h * f(t, y[0])`

is not a list, and is not an iterable either, you get the error