CoCalc is a real-time collaborative commercial alternative to JupyterHub and Overleaf that provides Jupyter Notebooks, LaTeX documents, and SageMath.
CoCalc is a real-time collaborative commercial alternative to JupyterHub and Overleaf that provides Jupyter Notebooks, LaTeX documents, and SageMath.
| Download
Scientific Computing Midterm
Project: SCST-CS510-Fall2015
Views: 888import numpy as np1import pandas as pd2import matplotlib.pyplot as plt3from mpl_toolkits.mplot3d import Axes3D4#%matplotlib inline56class Attractor(object):7""" Here we begin by initializing our parameteres and store them as numpy arrays and/or setting8their default values. We also use these values to calculate the time increment (self.dt)."""9def __init__(self, s = 10.0, p = 28.0, b = 8.0/3.0, start = 0.0, end = 80.0, points = 10000):10inarr = np.array([s,p,b])11self.s = s12self.p = p13self.b = b14self.params = inarr15self.start = start16self.end = end17self.points = points18self.dt = ((self.end - self.start) / self.points)19self.t = np.linspace(self.start, self.end, self.points)20self.solution = pd.DataFrame()2122def given(self, arr):23""" This method was created in hindsight to simplfy code further on in this Attractor class.24As we can see, this is where we work with our given set of differential equations and25convert them into terms more suitable for coding purposes and return the resulting numpy26array.27"""28x0,y0,z0 = arr29s,p,b = self.params30x = s * (y0 - x0)31y = x0 * (p - z0) - y032z = x0 * y0 - b * z03334return np.array([x,y,z])3536def euler(self, arr):37""" The euler method here takes a numpy array of length three as an argument, proceedes to38calculate the the first order Euler increment of the differential equations from our given39method, and returns the desired k1 value.40"""4142k1 = arr + self.given(arr) * self.dt4344return k14546def rk2(self, arr):47""" Here we have the rk2 method which in large is very similar to the euler method, however,48this method calculates and returns the second order Runge-Kutta increment.49"""5051k1f = self.given(arr)52k2f = self.given(arr + k1f * self.dt / 2.0)5354k2 = arr + k2f * self.dt5556return k25758def rk4(self, arr):59""" Again, we have a near identical method here with the exception of how far we take the60incrementation. In rk4 we calculate and return the fourth order Runge-Kutta increment.61"""6263k1f = self.given(arr)64k2f = self.given(arr + k1f * self.dt / 2.0)65k3f = self.given(arr + k2f * self.dt / 2.0)66k4f = self.given(arr + k3f * self.dt)6768k4 = arr + self.dt / 6.0 * (k1f + 2 * k2f + 2 * k3f + k4f)6970return k47172def evolve(self, r0 = np.array([0.1, 0.0, 0.0]), order = 4):73""" This method, evolve, takes a numpy array of length three and an integer as parameters.74The initial values (x0, y0, and z0) are given default values of 0.1, 0.0, and 0.075respectively. The integer value order may take the quantities of 1, 2, or 4, defaulting76to 4, depending on which method is desired for incrementation. In this method we also77generate our pandas DataFrame and store it and return it as self.solution.78"""79if order == 1:80a = self.euler81elif order == 2:82a = self.rk283elif order == 4:84a = self.rk485else:86print "\n !!!Order was not 1, 2, or 4!!! \n"87return None8889dd = {b: np.zeros(self.points) for b in 'txyz'}90self.solution = pd.DataFrame(dd)91xyz = r092for i in range(self.points):93x, y, z = xyz94self.solution.loc[i] = [i * self.dt, x, y, z]95xyz = a(xyz)9697return self.solution9899def save(self, filename = None):100""" This is a very simple method to save our self.solution DataFrame to a CSV file on disk.101"""102filename = 'solution.csv'103self.solution.to_csv(filename)104105def plotx(self):106""" This method simply labels axes and plots out t variable by our x(t) variable.107"""108plt.xlabel('t')109plt.ylabel('x(t)')110plt.plot(self.solution['t'], self.solution['x'])111plt.show()112113def ploty(self):114""" This method simply labels axes and plots out t variable by our y(t) variable.115"""116plt.xlabel('t')117plt.ylabel('y(t)')118plt.plot(self.solution['t'], self.solution['y'])119plt.show()120121def plotz(self):122""" This method simply labels axes and plots out t variable by our z(t) variable.123"""124plt.xlabel('t')125plt.ylabel('z(t)')126plt.plot(self.solution['t'], self.solution['z'])127plt.show()128129def plotxy(self):130""" Now we keep on the same plotting track in this method except we plot our results131against one another. Namely, we're plotting x(t) vs y(t).132"""133plt.xlabel('x(t)')134plt.ylabel('y(t)')135plt.plot(self.solution['x'], self.solution['y'])136plt.show()137138def plotyz(self):139""" Here we plot y(t) against z(t).140"""141plt.xlabel('y(t)')142plt.ylabel('z(t)')143plt.plot(self.solution['y'], self.solution['z'])144plt.show()145146def plotzx(self):147""" This method plots x(t) by z(t).148"""149plt.xlabel('x(t)')150plt.ylabel('z(t)')151plt.plot(self.solution['x'], self.solution['z'])152plt.show()153154def plot3d(self):155""" And finally we have the plotting method to give a 3D representation of all three,156x(t), y(t), and z(t), against eachother.157"""158td = plt.gca(projection='3d')159plt.plot(self.solution['x'], self.solution['y'], self.solution['z'])160plt.show()161162