My code is method of Euller for second ODE. I already try to do a function to define f this way
{def inicial():
global f
f=matrix(M,N)}
But I had problem in the same line. I don't know how to recognize my function in that line.
N=101
x_min = -10.0
x_max = 10.0;
dx = (x_max - x_min)/(N-1)
dt = 0.25*dx*dx
t=0
t_max = 1000
Q=1
j=0
M=2
f = [N , M]
def f_xx(i,t):
return ((f[i+1][t]-2*f[i][t]+f[i-1][t])/(dx*dx))
def guess(x):
return ((pi*Q/x_max)*x +(pi*Q))
for i in range (N):
for j in range(j):
x = x_min + i*dx
f[i][j] = guess(x)
for j in range(t_max+1):
for i in range(N-1):
x = x_min + i*dx
f[i][j+1] = f[i][j]+(f_xx(i,j)-sin(f[i][j]))*dt <<<error
for i in range (N-1):
f[i][j] = f[i][j+1]
What does mean 'int' object has no attribute getitem? Could anyone help fix it?
f is a list containing two ints. f[i] refers to the the i'th int; so f[i][j], will try and get the j'th value of an int, which cannot possibly work, whatever the value of j.
It's not clear what you are trying to do with this call, though.
You are trying to use f as a list of lists (i.e. like a 2-dimensional array), but it's really just one list: [101, 2].
I'm rusty on ODEs but I think you were trying to create a 101x2 grid of 0s. If so try f = [[0.0]*M for x in range(N)].
Related
I am used to write code in c++ but now I am trying to learn python. I came to know about the Python language and it is very popular among everyone. So I thought, let's give it a shot.
Currently I am preparing for companies interview questions and able to solve most of them in c++. Alongside which, I am trying to write the code for the same in Python. For the things which I am not familiar with, I do a google search or watch tutorials etc.
While I was writing code for my previously solved easy interview questions in python, I encountered a problem.
Code : Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Given an array of integers, print the indices of the two numbers such that they add up to a specific target.
def twoNum(*arr, t):
cur = 0
x = 0
y = 0
for i in range (len(arr) - 1):
for j in range (len(arr) - 1):
if(i == j):
break
cur = arr[i] + arr[j]
if(t == cur):
x = arr[i]
y = arr[j]
break
if(t == cur):
break
print(f"{x} + {y} = {x+y} ")
arr = [3, 5, -4, 8, 11, 1, -1, 6]
target = 10
twoNum(arr, t=target)
So here is the problem: I have defined x, y in function and then used x = arr[i] and y = arr[j] and I m printing those values.
output coming is : is 0 + 0 = 10 (where target is 10)
This is I guess probably because I am using x = 0 and y = 0 initially in the function and it seems x and y values are not updating then I saw outline section in VSCode there I saw x and y are declared twice, once at the starting of the function and second in for loop.
Can anyone explain to me what is going on here?
For reference, here is an image of the code I wrote in C++
Change this:
def twoNum(*arr, t):
to this:
def twoNum(arr, t):
* is used to indicate that there will be a variable number of arguments, see this. It is not for pointers as in C++.
Basically what you are trying to do is to write C code in python.
I would instead try to focus first on how to write python code in a 'pythonic' way first. But for your question - sloving it your way using brute force in python:
In [173]: def two_num(arr, t):
...: for i in arr:
...: for j in arr[i + 1: ]:
...: if i + j == t:
...: print(f"{i} + {j} = {t}")
...: return
Here's a way to implement a brute force approach using a list comprehension:
arr = [1,3,5,7,9]
target = 6
i,j = next((i,j) for i,n in enumerate(arr[:-1]) for j,m in enumerate(arr[i+1:],i+1) if n+m==target)
output:
print(f"arr[{i}] + arr[{j}] = {arr[i]} + {arr[j]} = {target}")
# arr[0] + arr[2] = 1 + 5 = 6
Perhaps even more pythonic would be to use iterators:
from itertools import tee
iArr = enumerate(arr)
i,j = next((i,j) for i,n in iArr for j,m in tee(iArr,1)[0] if n+m==target)
When you get to implementing an O(n) solution, you should look into dictionaries:
d = { target-n:j for j,n in enumerate(arr) }
i,j = next( (i,d[m]) for i,m in enumerate(arr) if m in d and d[m] != i )
The Problem occurs in line 29:
It is a Type Error
I can't figure out where I went wrong with my parameters. It should assign every a[i][k] with a value but it just ends up with the following error message:
a[i][k].append(g * m[i] * dr[k]/d3)
TypeError: 'int' object is not subscriptable
Here the full code:
import numpy as np
from numpy import absolute
from numpy import power
r = [[1,1,1],[1,1,1],[0,0,0]]
v = [[0,0,0],[0,0,0],[0,0,0]]
a = [[0,0,0],[0,0,0],[0,0,0]]
m = [1,1,1]
O = -1
N = 3
def beschleunigung(O, N, m, r, a):
i = 0
k = 0
dr = [0,0,0]
d3 = 0
g = 1
for k in range(1,3):
a[i][k] = 0
for i in range(1,N):
if i != O:
for k in range(1,3):
a = (r[i][k])
b = (r[0][k])
dr[k] = a - b
d3 = np.power(np.absolute(dr),3)
for k in range(1,3):
a[i][k].append(g * m[i] * dr[k]/d3)
beschleunigung(O,N,m,r,a)
print(a[1])
When your code executes the line a = (r[i][k]), a becomes an integer, rather than a list of lists as it was in the input to this function. This causes your append to fail as you cannot append to an integer.
I expect that you intended to create another variable to use in your subtraction with b - make sure to use a name that is not already defined in your scope.
I'm writing a program that evaluates the power series sum_{m=0}{oo} a[m]x^m, where a[m] is recursively defined: a[m]=f(a[m-1]). I am generating symbols as follows:
a = list(sympy.symbols(' '.join([('a%d' % i) for i in range(10)])))
for i in range(1, LIMIT):
a[i] = f_recur(a[i-1], i-1)
This lets me refer to the symbols a0,a1,...,a9 using a[0],a[1],...,a[9], and a[m] is a function of a[m-1] given by f_recur.
Now, I hope code up the summation as follows:
m, x, y = sympy.symbols('m x y')
y = sympy.Sum(a[m]*x**m, (m, 0, 10))
But, m is not an integer so a[m] throws an Exception.
In this situation, where symbols are stored in a list, how would you code the summation? Thanks for any help!
SymPy's Sum is designed as a sum with a symbolic index. You want a sum with a concrete index running through 0, ... 9. This could be Python's sum
y = sum([a[m]*x**m for m in range(10)])
or, which is preferable from the performance point of view (relevant issue)
y = sympy.Add(*[a[m]*x**m for m in range(10)])
In either case, m is not a symbol but an integer.
I have a work-around that does not use sympy.Sum:
x = sympy.symbols('x')
y = a[0]*x**0
for i in range(1, LIMIT):
y += a[i]*x**i
This does the job, but sympy.Sum is not used.
Use IndexedBase instead of Symbol:
>>> a = IndexedBase('a')
>>> Sum(x**m*a[m],(m,1,3))
Sum(a[m]*x**m, (m, 1, 3))
>>> _.doit()
a[1]*x + a[2]*x**2 + a[3]*x**3
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?
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
I have edited my question. Now I don't want to use loop in my function. The function is for defining initial position of an rotating object in 2-D. I would like to get the output format like this:
theta1 theta2 theta3
phi1 phi2 phi3
eta1 eta2 eta3
The definition of e inside the function must be something else (my opinion). Can anyone help me to get my desired output?
def randposi(N=500):
theta = 2*pi* rand()-pi
phi = arccos(1-2* rand())
eta = 2*pi*rand()-pi
r = random.rand(N)
e = 3*r*array()
return e
What about using a random numpy array ?
Something like that:
import numpy as np
N=500
#we create a random array 3xN
r = np.random.rand(3,N)
#tetha is row 0, phi row 1, eta row 2
#we apply the same treatment that is in the question to get the right range
#also note that np.pi is just a predefined float
r[0]=2*np.pi*r[0] -np.pi
r[1]=np.arccos(1-2*r[1])
r[2]=2*np.pi*r[2] -np.pi
print(r[0],r[1],r[2])
you can use list comprehension for this, for your case:
def randpos(N=500):
# your function code here
...
desired = 500
init_positions = [randpos() for i in range(desired)]
So if we make your function return a tuple:
def randpos():
theta = 2*pi* rand()-pi
if rand() < 12:
if phi < pi:
phi += pi
else:
phi -= pi
eta = 2*pi*rand()-pi
return (theta, phi, eta)
then call it 500 times and put the results in a list of tuples.
starting_pos = []
for x in xrange(500):
starting_pos.append(randpos)
And you have your solution.
So, you've defined your function f(x) called randpos, it seems this function doesn't accept any input. N is the variable you'll use to iterate over this function, you got few options here:
You can store your values in some list like this:
N = 10
random_positions = [randpos() for i in range(N)]
print random_positions
If you don't need to store values you just loop through them like this:
for i in range(N):
print randpos()
If you prefer instead, you just yield your values like this:
def my_iterator(N=500):
for i in range(N):
yield randpos()
for rand_pos in my_iterator(N):
print rand_pos