Reputation: 99
I'm defining a set of functions to convert from an Earth-centered reference frame to classical orbital elements. Here are my codes:
import numpy as np
import matplotlib.pyplot as plt
#converting r,v to orbital elements
u = 3.986*10e14 #gravitational parameter for Earth
list_r = [-2413.9, 6083.8, -1136.0]
r = np.array(list_r)
list_v= [-6.5461, -3.1365, -3.6385]
v = np.array(list_v)
def h(r,v):
return np.cross(r,v)
list_k = [0,0,1]
k = np.array(list)
def n(k,h):
return np.cross(k,h)
def e_vec(v,r):
vector = 1/u * (np.dot((np.linalg.norm(v))**2-u/np.linalg.norm(r),r)-np.dot(np.dot(r,v),v))
return vector
def p(h,u):
return (np.linalg.norm(h))**2/u
def a(p,e):
return p/(1-np.linalg.norm(e_vec)**2)
def i(h):
return np.arccos(np.dot(k,h(r,v))/np.linalg.norm(h(r,v)))
list_I = [1,0,0]
I = np.array(list_I)
def ohm(I,n):
nI = np.dot(n(h),I)
ohm = np.acos(nI/n)
return ohm
def w(n,e):
w = np.arccos(np.dot(n,e)/(np.linalg.norm(n)*np.linalg.norm(e)))
return w
def f(e,r):
f = np.arccos(np.dot(e_vec(v,r),r)/(np.linalg.norm(e_vec(v,r))*np.linalg.norm(r)))
return f
print(h(r,v))
print(e_vec(v,r))
print(p(h(r,v),u))
print(i(h(r,v)))
print(ohm(I,n))
print(w)
print(f)
I'm getting this error : TypeError: 'numpy.ndarray' object is not callable, for the function i(h). I don't know how I should fix this.
Upvotes: 1
Views: 9186
Reputation: 231315
While local variables can be short, single names, functions should be more informative. In particular you have defined a function h
, but you also use h
as a local variable. That confuses you (and us).
In several of the functions h
is a local variable, and an array (at least that's that np.cross
expects):
def n(k,h):
return np.cross(k,h)
Similarly for
def p(h,u):
return (np.linalg.norm(h))**2/u
But i
breaks that pattern:
def i(h):
return np.arccos(np.dot(k,h(r,v))/np.linalg.norm(h(r,v)))
Here h
only works if it is a function. But you haven't passed in r
, v
or k
.
def i(k,h):
return np.arccos(np.dot(k,h)/np.linalg.norm(h)
is more consistent with your other functions. It is also more consistent with
print(i(h(r,v)))
Upvotes: 1
Reputation: 14399
Your problem is you're getting confused by scoping.
h(r, v)
is the result of a function, and thus a numpy
array - while h
is the function itself. You're passing h(r, v)
to i
as h
, but still expecting h
in scope i
to be a function.
Also k
isn't in scope for i
, so that will also cause an error. you should probabaly define
def i(k, r, v):
return np.arccos(np.dot(k, h(r, v)) / np.linalg.norm(h(r, v)))
and pass i(k, r, v)
, or define:
def i(k, h):
return np.arccos(np.dot(k, h) / np.linalg.norm(h))
and pass i(k, h(r, v))
An even better method would be to wrap it all in a class
and keep all your variables in a self
scope so that it's easier to keep track, but the frontend work of object-oriented programming may be a step beyond what you want.
Upvotes: 0
Reputation: 434
You have a function named def h(r,v)
and you also name the argument as h
. This is a conflict. In the function i
's scope, name h
refers to the argument, that is, an numpy.ndarray, not the function. You should avoid using the same name.
Upvotes: 1