What is the best way to get double integral from discontinuous function? - python

I am using scipy.integrate.dblquad but got warning that says:
The maximum number of subdivisions (50) has been achieved.
If increasing the limit yields no improvement it is advised to analyze the integrand in order
to determine the difficulties.
If the position of a local difficulty can be determined (singularity, discontinuity) one
will probably gain from splitting up the interval and calling the integrator on the subranges.
Perhaps a special-purpose integrator should be use
Also tried nquad and set limit to 100 got the warning.
The integrand looks like THIS, where V-function is integrated over x and y.
IF NEEDED the code:
import numpy as np
import math
#from scipy.integrate import *
import scipy.optimize as optimize
from scipy.integrate import nquad
import matplotlib.pyplot as plt
def rotcoords(y, x, alpha):
X = x * np.cos(-alpha) + y * np.sin(-alpha)
Y = -y * np.sin(-alpha) + y * np.cos(-alpha)
return (X, Y)
def getcoords(y, x, dx, dy, alpha, r):
d = 2 * r
X, Y = rotcoords((y-dy), (x-dx), alpha)
#dX, dY = rotcoords(dy, dx, alpha)
#X = X - dX
#Y = Y - dY
X = np.abs(X - X // d * d) - r
Y = np.abs(Y - Y // d * d) - r
I = np.sqrt(X**2 + Y**2)
return I
def function_V(y, x, dx, dy, alpha, r):
v1=getcoords(y,x,0,0,0,r)
#v1=getcoords(y,x,dx,dy,alpha,r)
if v1>=r:
v1 = 0
v2=getcoords(y,x,dx,dy,alpha,r)
if v2>=r:
v2 = 0
V = np.max([v1, v2])
return V
def function_Al(y, x, dx, dy, alpha, r):
R1=getcoords(y,x,0,0,0,r)
#R1=getcoords(y,x,dx,dy,alpha,r)
if (R1<r/3) or (R1>r):
A1 = 1
else:
A1 = 0
R2=getcoords(y,x,dx,dy,alpha,r)
if (R2<r/3) or (R2>r):
A2 = 1
else:
A2 = 0
A = np.min([A1, A2])
return A
def function_Ah(y, x, dx, dy, alpha, r):
R1=getcoords(y,x,0,0,0,r)
#R1=getcoords(y,x,dx,dy,alpha,r)
if (R1<=r) and (R1>=2*r/3):
A1 = 1
else:
A1 = 0
R2=getcoords(y,x,dx,dy,alpha,r)
if (R2<=r) and (R2>=2*r/3):
A2 = 1
else:
A2 = 0
A = np.max([A1, A2])
return A
def intgrl_V(params):
dx, dy, alpha = params
r=0.5
d = 2 * r
w1 = 0
w2 = 3*d
h1 = 0
h2 = 3*d
# Integrate for V
#intgrl, abserr = dblquad(function_V, w1, w2, lambda x: h1, lambda x: h2, args=(dx, dy, alpha, r))
options = {'limit': 100}
intgrl, abserr = nquad(function_V, [[w1,w2],[h1,h2]], args=(dx, dy, alpha, r), opts=[options, options])
# Take average of the integral over the area
A = (w2 - w1) * (h2 - h1)
return -intgrl/A
def intgrl_Al(params):
dx, dy, alpha = params
r=0.5
d = 2 * r
w1 = 0
w2 = 3*d
h1 = 0
h2 = 3*d
# Integrate for A_low
#intgrl, abserr = dblquad(function_Al, w1, w2, lambda x: h1, lambda x: h2, args=(dx, dy, alpha, r))
options = {'limit': 100}
intgrl, abserr = nquad(function_Al, [[w1,w2],[h1,h2]], args=(dx, dy, alpha, r), opts=[options, options])
# Take average of the integral over the area
A = (w2 - w1) * (h2 - h1)
return intgrl/A
def intgrl_Ah(params):
dx, dy, alpha = params
r=0.5
d = 2 * r
w1 = 0
w2 = 3*d
h1 = 0
h2 = 3*d
# Integrate for A_low
#intgrl, abserr = dblquad(function_Ah, w1, w2, lambda x: h1, lambda x: h2, args=(dx, dy, alpha, r))
options = {'limit': 100}
intgrl, abserr = nquad(function_Ah, [[w1,w2],[h1,h2]], args=(dx, dy, alpha, r), opts=[options, options])
# Take average of the integral over the area
A = (w2 - w1) * (h2 - h1)
return -intgrl/A
def optfun(params):
return 1.9 * intgrl_V(params) + 7.6 * intgrl_Al(params) + intgrl_Ah(params)
initial_guess = [0.25, 0.4, 0]
result = optimize.minimize(optfun, initial_guess)
if result.success:
fitted_params = result.x
print(fitted_params)
else:
raise ValueError(result.message)

Related

Ellipse construction

I would like to construct an ellipse given the major/minor axes (or radii) and two points. I would like the line between the two points to be on the major axis. This just means that I would like the two points to lie on the major axis, and then construct the ellipse around the major axis. I originally constructed the ellipse at the origin and attempted to rotate and translate the ellipse, which didn't work. The unfinished code I have is listed below. How can I go about constructing an ellipse in this manner? Ideally, this would just return a list. Any insights would be greatly appreciated, and if you have any code for this please feel free to share.
import numpy
import matplotlib.pyplot as plt
import random
import math
from math import sin, cos
# Returns theta in [-pi/2, 3pi/2]
def generate_theta(a, b):
u = random.random() / 4.0
theta = numpy.arctan(b/a * numpy.tan(2*numpy.pi*u))
v = random.random()
if v < 0.25:
return theta
elif v < 0.5:
return numpy.pi - theta
elif v < 0.75:
return numpy.pi + theta
else:
return -theta
def radius(a, b, theta):
return a * b / numpy.sqrt((b*numpy.cos(theta))**2 + (a*numpy.sin(theta))**2)
def random_point(a, b, third_point, center=(0, 0)):
angle = None
if a > b:
random_theta = generate_theta(a, b)
max_radius = radius(a, b, random_theta)
random_radius = max_radius * numpy.sqrt(random.random())
f = round(random_radius * numpy.cos(random_theta))
s = round(random_radius * numpy.sin(random_theta))
angle = math.atan2(third_point[1], third_point[0]) - math.atan2(center[1], center[0])
else:
random_theta = generate_theta(b, a)
max_radius = radius(b, a, random_theta)
random_radius = max_radius * numpy.sqrt(random.random())
f = round(random_radius * numpy.cos(random_theta))
s = round(random_radius * numpy.sin(random_theta))
angle = math.atan2(third_point[1], third_point[0]) - math.atan2(center[1], center[0])
lio = rotate(center, (f, s), angle)
lio = (int(lio[0]), int(lio[1]))
return numpy.array([third, ward])
def rotate(origin, point, angle):
#Rotate a point counterclockwise by a given angle around a given origin.
#The angle should be given in radians.
x = origin[0] + cos(angle) * (point[0] - origin[0]) - sin(angle) * (point[1] - origin[1])
y = origin[1] + sin(angle) * (point[0] - origin[0]) + cos(angle) * (point[1] - origin[1])
return (x, y)
#height
a = 95
#length
b = 25
#rand_p = (-random.randint(300, 400), -random.randint(100, 300))
rand_p = (0, 0)
points = numpy.array([random_point(a, b, (100, 100), (-25, 0)) for _ in range(200)])
#rando = rotate((0, 0), right_most_point, angle)
iopoints = []
# t = x[0] - (int(centroid[0]) - 100)
# t2 = x[1] - (int(centroid[1]) - 100)
centroid = numpy.mean(points, axis=0)
print(centroid)
#plt.plot(rando[0], rando[1], 'ro')
plt.plot(rand_p[0], rand_p[1], 'ro')
plt.scatter(points[:,0], points[:,1])
plt.show()
class ELLIPSE:
def __init__(self, a, b, num_points, start, end):
self.a = a
self.b = b
self.num_points = num_points
self.start = start
self.end = end
self.angle_gen = math.atan2(self.end[1]-self.start[1], self.end[0]-self.start[0])
def generate_theta(self, a, b):
u = random.random() / 4.0
theta = np.arctan(self.b/self.a * np.tan(2*np.pi*u))
v = random.random()
if v < 0.25:
return theta
elif v < 0.5:
return np.pi - theta
elif v < 0.75:
return np.pi + theta
else:
return -theta
def radius(self, a, b, theta):
return self.a * self.b / np.sqrt((b*np.cos(theta))**2 + (a*np.sin(theta))**2)
def random_point(self, major_axis, minor_axis, center, qa):
random_theta = self.generate_theta(self.a, self.b)
max_radius = self.radius(self.a, self.b, random_theta)
random_radius = max_radius * np.sqrt(random.random())
f = round(random_radius * np.cos(random_theta))
s = round(random_radius * np.sin(random_theta))
lio = self.rotate((0, 0), (f, s), self.angle_gen)
return (int(lio[0]+center[0]), int(lio[1]+center[1]))
def rotate(self, origin, point, angle):
"""
Rotate a point counterclockwise by a given angle around a given origin.
The angle should be given in radians.
"""
ox, oy = origin
px, py = point
qx = ox + math.cos(angle) * (px - ox) - math.sin(angle) * (py - oy)
qy = oy + math.sin(angle) * (px - ox) + math.cos(angle) * (py - oy)
return qx, qy
def midpoint(self, p1, p2):
return ((p1[0]+p2[0])/2, (p1[1]+p2[1])/2)
def ret_list(self):
points = [self.random_point(self.a, self.b, self.midpoint(self.start, self.end), self.angle_gen) for _ in range(self.num_points)]
return points

Python not generating multiple polar curves

I am trying to produce one plot that contains multiple polar curves; however, only one polar curve is generating. This is my first time using polar plots in matplotlib, but I assumed generating multiple curves on the same plot would work the same as generating multiple lines on a regular graph. I have seen examples of code that demonstrate exactly what I need, and even though my code looks the same, only one curve generates. The curves are also not generating one at a time in separate plots. Only one plot generates.
I have made sure that plt.show() is outside of any while or for loops, and I have even tried moving the plotting functions to an entirely new method with no success. I am unsure of what I am doing wrong and would appreciate any help I could get.
Thank you.
CODE: (Plotting function towards the bottom)
import math
import numpy as np
import matplotlib.pyplot as plt
def rFuncA(a, ec, v):
# calculates current orbit radius from a, eccentricity, and angle
return a * (1 - ec ** 2) / (1 + ec * math.cos(v))
def wFunc(a, ec, v, u):
# calculates current orbit radius from a, eccentricity, and angle
block1 = a * (1 - ec ** 2)
block2 = 1 + ec * math.cos(v)
return (math.sqrt(u) / block1 ** (3 / 2)) * block2 ** 2
def VoFunc(ec, v, r, w):
return r * w * (ec * math.sin(v)) / (1 + ec * math.cos(v)), \
r * w
def dXFunc(Fl, Fd, Ft, gamma, alpha, u, r, m, Isp, Vr, Vv, g):
theta = alpha + gamma
dX1 = (Vv ** 2) / r + (Fl * math.cos(gamma) - Fd * math.sin(gamma) + Ft * math.sin(theta)) / m - u / (r ** 2)
dX2 = -(Vr * Vv / r + (Fl * math.sin(gamma) + Fd * math.cos(gamma) - Ft * math.cos(theta)) / m)
dX3 = Vr
dX4 = Vv / r
dX5 = -Ft / (g * Isp)
return dX1, dX2, dX3, dX4, dX5
def aFuncR(r, u, Vr, Vv):
block1 = 2 * u / r
block2 = Vr ** 2 + Vv ** 2
return u / (block1 - block2)
def ecFuncR(r, u, Vr, Vv):
return (r / u) * math.sqrt((Vv ** 2 - u / r) ** 2 + (Vv * Vr) ** 2)
class Properties:
def __init__(self):
# Preallocate
n = 1000000
self.ec = np.zeros([n])
self.a = np.zeros([n])
self.r = np.zeros([n])
self.gamma = np.zeros([n])
self.X = np.zeros([n, 5])
self.Tt = np.zeros([n])
self.v = np.zeros([n])
self.theta = np.zeros([n])
# Constants
self.Ft = 0.01 # Thrust Force, kN
self.Fl = 0 # Lift Force, kN
self.Fd = 0 # Drag Force, kN
self.g = 0.009806 # gravity, km/s^2
self.u = 3.986E5 # gravitational parameter, km^3/s^2
self.alpha = 0 # Angle of Attack (0 for ballistic trajectory), radians
self.Isp = 2000 # Specific impulse, sec
self.dt = 2000 # Iterator step size, sec
self.r_e = 6561 # Mean earth radius, km
self.r_a = 13200 # Apogee radius at final orbit, km
# Progressive variables initial values
self.a[0] = 8530
self.r[0] = rFuncA(self.a[0], self.ec[0], self.v[0]) # Changing radius, km
self.m = np.zeros([n])
self.m[0] = 1000 + 7.743 + 71.25 # Inital Mass
self.w = np.zeros([n])
self.w[0] = wFunc(self.a[0], self.ec[0], self.v[0], self.u) # Angular velocity, rad/s
Vo1, Vo2 = VoFunc(self.ec[0], self.v[0], self.r[0], self.w[0])
self.Vr = np.zeros([n]) # Creates array for radial velocities
self.Vv = np.zeros(([n])) # Creates array for tangential velocities
self.Vr[0] = Vo1 # Initial radial velocity, km/s
self.Vv[0] = Vo2 # Initial tangential velocity, km/s
# Plotting
self.pt = np.zeros([n])
self.pr = np.zeros([n])
self.cr = np.zeros([n])
self.cf = np.zeros([n])
self.i = 0
def runge_kutta(self):
self.i = 0
self.gamma[0] = math.atan(self.Vr[0] / self.Vv[0]) # Initial angle, rad
self.X[0][:] = np.array([self.Vr[0], self.Vv[0], self.r[0], self.v[0], self.m[0]])
while self.a[self.i] * (1 + self.ec[self.i]) < self.r_a:
# self.Tt[i+1] = self.Tt[0] + self.dt
dX1, dX2, dX3, dX4, dX5 = dXFunc(self.Fl, self.Fd, self.Ft, self.gamma[self.i], self.alpha, self.u, self.X[self.i][2],
self.X[self.i][4], self.Isp, self.X[self.i][0], self.X[self.i][1], self.g)
k1 = np.array([dX1, dX2, dX3, dX4, dX5])
X2 = self.X[self.i] + k1 * self.dt / 2
dX1, dX2, dX3, dX4, dX5 = dXFunc(self.Fl, self.Fd, self.Ft, self.gamma[self.i], self.alpha, self.u, X2[2],
X2[4], self.Isp, X2[0], X2[1], self.g)
k2 = np.array([dX1, dX2, dX3, dX4, dX5])
X3 = X2 + k2 * self.dt / 2
dX1, dX2, dX3, dX4, dX5 = dXFunc(self.Fl, self.Fd, self.Ft, self.gamma[self.i], self.alpha, self.u, X3[2],
X3[4], self.Isp, X3[0], X3[1], self.g)
k3 = np.array([dX1, dX2, dX3, dX4, dX5])
X4 = X3 + k3 * self.dt
dX1, dX2, dX3, dX4, dX5 = dXFunc(self.Fl, self.Fd, self.Ft, self.gamma[self.i], self.alpha, self.u, X4[2],
X4[4], self.Isp, X4[0], X4[1], self.g)
k4 = np.array([dX1, dX2, dX3, dX4, dX5])
self.X[self.i+1][:] = self.X[self.i][:] + (1 / 6) * (k1 + k2 + k3 + k4 * self.dt)
self.a[self.i+1] = aFuncR(self.X[self.i+1][2], self.u, self.X[self.i+1][0], self.X[self.i+1][1])
self.ec[self.i+1] = ecFuncR(self.X[self.i+1][2], self.u, self.X[self.i+1][0], self.X[self.i+1][1])
self.i += 1
print(self.X[self.i][:]) # Final Values for Vr, Vv, r, v, and m
def plot(self):
i = self.i - 1
k = 0
# Orbit period
while self.pt[k] < 2 * math.pi:
self.pt[k+1] = self.pt[k] + (2 * math.pi / i)
k += 1
# Orbit location
for j in range(i):
# Transferring Orbit
self.pr[j] = self.a[j] * (1 + self.ec[j] ** 2) / (1 + self.ec[j] * math.cos(self.pt[j]))
# Low Earth Orbit
self.cr[j] = self.a[0]
plt.polar(self.pt[:i], self.pr[:i], 'r')
plt.polar(self.pt[:i], self.cr[:i], 'g',)
plt.show()
def main():
P = Properties()
P.runge_kutta()
P.plot()
if __name__ == '__main__':
main()
Plot:
First polar curve
Second polar curve (only generates when first plot is commented out)
Upon further investigation, I was using an older version of Matplotlib, and updating Matplotlib via reinstallation fixed the issue.
pip uninstall matplotlib
pip install matplotlib

How can I use numba's jit in my program which contains only Numpy arrays?

My program evaluates error in solving a linear differential equation. It uses only numpy arrays. When I try to use numba's jit decorator for the functions I define, I just get errors. Can you please help me use it properly?
My code:
import numpy as np
from numba import jit
def rk4(t_prev, x_prev, derivs, dt):
k1 = dt * derivs(t_prev, x_prev)
k2 = dt * derivs(t_prev + 1/2*dt, x_prev + 1/2*k1)
k3 = dt * derivs(t_prev + 1/2*dt, x_prev + 1/2*k2)
k4 = dt * derivs(t_prev + dt, x_prev + k3)
x_next = x_prev + 1/6*k1 + 1/3*k2 + 1/3*k3 + 1/6*k4
return x_next
global k, x_0, v_0, t_0, t_f
k = 1
x_0 = 0
v_0 = np.sqrt(k)
t_0 = 0
t_f = 10
dtList = np.logspace(0, -5, 1000)
def derivs(t, X):
deriv = np.zeros([2])
deriv[0] = X[1]
deriv[1] = -k * X[0]
return deriv
def err(dt):
tList = np.arange(t_0, t_f + dt, dt)
N = tList.shape[0]
XList = np.zeros([N,2])
XList[0][0], XList[0][1] = x_0, v_0
for i in range(N-1):
XList[i+1] = rk4(tList[i], XList[i], derivs, dt)
error = np.abs(XList[-1][0] - np.sin(10))
return error
print(err(.001))
The following works for me:
import numpy as np
from numba import jit
#jit(nopython=True)
def rk4(t_prev, x_prev, derivs, dt):
k1 = dt * derivs(t_prev, x_prev)
k2 = dt * derivs(t_prev + 1/2*dt, x_prev + 1/2*k1)
k3 = dt * derivs(t_prev + 1/2*dt, x_prev + 1/2*k2)
k4 = dt * derivs(t_prev + dt, x_prev + k3)
x_next = x_prev + 1/6*k1 + 1/3*k2 + 1/3*k3 + 1/6*k4
return x_next
global k, x_0, v_0, t_0, t_f
k = 1
x_0 = 0
v_0 = np.sqrt(k)
t_0 = 0
t_f = 10
dtList = np.logspace(0, -5, 1000)
#jit(nopython=True)
def derivs(t, X):
deriv = np.zeros(2)
deriv[0] = X[1]
deriv[1] = -k * X[0]
return deriv
#jit(nopython=True)
def err(dt):
tList = np.arange(t_0, t_f + dt, dt)
N = tList.shape[0]
XList = np.zeros((N,2))
XList[0][0], XList[0][1] = x_0, v_0
for i in range(N-1):
XList[i+1] = rk4(tList[i], XList[i], derivs, dt)
error = np.abs(XList[-1][0] - np.sin(10))
return error
print(err(.001))
Note, the only two changes I made to your code was to replace the calls to np.zeros that passed in lists to either a tuple in the 2d case, or just the bare integer in the 1d case. See the following issue for an explanation of why this is:
https://github.com/numba/numba/issues/3993

Calculate nolinear model of vibration control

I am studding automatic and have a matlab/SIMULINK model of nonlinear vibration. I am trying to resolve the same problem using python instead.
Here we have a schema. The black frame is a part that I have already. I also have a Model tłumnika MR (eng. Magnetorheological Damper). Just I don't know how to connect it together?
There are welcome any suggestion how to resolve this including modifying model.
Code for part 1 (black frame) [just pseudo code ]
def rms(v): # ROOT MEAN SQRT
return np.sqrt(np.mean(np.square(v)))
def transmissibility(_in, _out):
# Transmissibility (T) = output/input
return rms(_out) / rms(_in)
def q(ss, t, Ampituda, freqs):
y2 = []
for f in freqs:
u = Ampituda * np.sin(2 * np.pi * f * t) # wektor wejscia
t1, y1, x1 = signal.lsim(ss, u, t) # wyliczenie modelu w dziedzinie czasu
y2.append(transmissibility(u, y1))
return y2
vec_c = np.arange(1000, 6000 , 1000)
for c in vec_c:
A = [[0, 1], [-(k/m), -(c/m)]]
B = [[-c/m], [(k/m) - (c/m)**2]]
C = [1, 0]
D = 0
ss = signal.StateSpace(A,B,C,D) # State Space model
y2 = q(ss, t, Ampituda, freqs)
plt.plot(freqs, y2, label=r'$c = {} \frac{}{} $'.format(c, "{Ns}", "{m}"), linewidth=2.0)
plt.legend()
Code for MR (Model tłumnika MR) [copy paste example]
from scipy import signal
import numpy as np
def I(to_intagrate, dt, y0=0):
i = [y0]
for v in to_intagrate:
i.append(i[-1] + v * dt)
del i[0]
return i
def MR(v, i, dt):
""" #v -- prędkość (z' -w') wektor przyśpieszeń
#i -- natężenie prądu w amperach
return Siła generowan przez tłumnik w N
Slajd 18
http://home.agh.edu.pl/~jastrzeb/images/SSD/SSD_2DOF_v1.pdf
"""
b1 = 3415.7
b2 = 93.324
b3 = 74.487
F0 = b1 * (i**2) + b2 * i + b3
b4 = 2534.1
b5 = 19.55
b6 = 643.1
C1 = b4 * (i**2) + b5*i + b6
beta = 50
p1 = 4
p2 = 0.2
x = I(v, dt)
Ft = []
for x1, v1 in zip(x, v):
part1 = F0 * np.tanh( beta * (v1 + (p1 * x1)))
part2 = C1 * (v1 + (p2 * x1))
Ft.append(part1 + part2)
return Ft, x
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (20, 16)
plt.rcParams['font.size'] = 18
for f in [2, 5]: # wybrane częstotliwości
# f = 5
i = 0.2
# x_sin wektor wartości x dla wymuszenia sinusoidalnego 201 pkt
# na każdy okres sinusa. Rozpoczęcie pkt pracy w -0.2
x_sin = np.linspace(-np.pi/2, (np.pi * f) - np.pi/2, num=201 * f)
u = np.sin(x_sin) * 0.2 # przeskalowanie przyśpieszenia
dt = 1/(f*201)
ft, x = MR(u, i, dt) # sila
plt.plot(u, ft, label='Freq = {}Hz, I={}A'.format(f, i))
plt.legend()
plt.grid()
plt.show()

What is wrong with my Implementation of 4th Order runge kutta in python for nonholonomic constraints?

I am trying to implement 4th order Runge Kutta for nonholonomic motion for car-like robots.
I don't know what I am doing wrong,essentially I am passing +-Pi/4 to calculate hard left and right turns to get different trajectories.
But no matter if I pass +pi/4 or -pi/4 to it, I get the same answer.
I cannot figure out what I am doing wrong.
The constraint equations that I am using are:
thetadot = (s/L)*tan(phi)
xdot = s*cos(theta)
ydot = s*sin(theta)
Where s is the speed and L is the length of the car like robot.
#! /usr/bin/env python
import sys, random, math, pygame
from pygame.locals import *
from math import sqrt,cos,sin,atan2,tan
import numpy as np
import matplotlib.pyplot as plt
XDIM = 640
YDIM = 480
WINSIZE = [XDIM, YDIM]
PHI = 45
s = 0.5
white = 255, 240, 200
black = 20, 20, 40
red = 255, 0, 0
green = 0, 255, 0
blue = 0, 0, 255
cyan = 0,255,255
pygame.init()
screen = pygame.display.set_mode(WINSIZE)
X = XDIM/2
Y = YDIM/2
THETA = 45
def main():
nodes = []
nodes.append(Node(XDIM/2.0,YDIM/2.0,0.0))
plt.plot(runge_kutta(nodes[0], (3.14/4))) #Hard Left turn
plt.plot(runge_kutta(nodes[0], 0)) #Straight ahead
plt.plot(runge_kutta(nodes[0], -(3.14/4))) #Hard Right turn
plt.show()
class Node:
x = 0
y = 0
theta = 0
distance=0
parent=None
def __init__(self,xcoord, ycoord, theta):
self.x = xcoord
self.y = ycoord
self.theta = theta
def rk4(f, x, y, n):
x0 = y0 = 0
vx = [0]*(n + 1)
vy = [0]*(n + 1)
h = 0.8
vx[0] = x = x0
vy[0] = y = y0
for i in range(1, n + 1):
k1 = h*f(x, y)
k2 = h*f(x + 0.5*h, y + 0.5*k1)
k3 = h*f(x + 0.5*h, y + 0.5*k2)
k4 = h*f(x + h, y + k3)
vx[i] = x = x0 + i*h
vy[i] = y = y + (k1 + k2 + k2 + k3 + k3 + k4)/6
print "1"
print vy
return vy
def fun1(x,y):
x = (0.5/2)*tan(y)
print "2"
print x
return x
def fun2(x,y):
x = 0.5*cos(y)
print "3"
print x
return x
def fun3(x,y):
x = 0.5*sin(y)
print "4"
print x
return x
def runge_kutta(p, phi):
x1 = p.x
y1 = p.y
theta1 = p.theta
fi = phi
for i in range(0,5):
x2 = rk4(fun2, x1, theta1, 5)
y2 = rk4(fun3, y1, theta1, 5)
theta2 = rk4(fun1, theta1 ,fi, 5)
theta1 = theta2
print "5"
print zip(x2,y2)
return zip(x2,y2)
# if python says run, then we should run
if __name__ == '__main__':
main()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
I can't really say much about the algorithm, but the way you set up our rk4 function, the x, and y arguments will never have any effect:
def rk4(f, x, y, n):
x0 = y0 = 0 # x0 and y0 will both be 0 after this
vx = [0]*(n + 1)
vy = [0]*(n + 1)
h = 0.8
vx[0] = x = x0 # now x will be 0
vy[0] = y = y0 # and y will be 0 too
...
The rest of the function will use x=0 and y=0 in any case.
Also, I don't know if that's intentional, but the other functions fun1, fun2 and fun3 don't ever use the parameter passed as x, they only use y. They change x locally, but that won't reflect outside the function.

Categories

Resources