Advertisement
Guest User

Final project class

a guest
May 25th, 2019
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.59 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Thu May 23 22:47:11 2019
  4.  
  5. @author: Rode
  6. """
  7.  
  8. import numpy as np
  9. import scipy.linalg as spl
  10. import matplotlib.pyplot as plt
  11. from mpl_toolkits import mplot3d
  12.  
  13. class Pendulum:
  14. def __init__(self, stepsize=0.2, Y_start = np.array([np.pi/2, 0, 0]), obst = -np.pi/6):
  15. self.stepsize = stepsize
  16. self.Y_points = np.array([Y_start])
  17. self.interpolvec = np.zeros((2,3))
  18. self.obst = obst
  19.  
  20. def __repr__(self):
  21. """
  22. Returns the angular position and speed of the pendulum, as well as current time.
  23. """
  24. return "Position: {} Speed: {} Time: {}".format(self.Y_points[-1][0], self.Y_points[-1][1], self.Y_points[-1][2])
  25.  
  26. def Eulerguess(self):
  27. """
  28. Makes a guess for next position and speed, using the explicit Euler method.
  29. """
  30. Y_guess = np.array([self.Y_points[-1][0] + self.stepsize*self.Y_points[-1][1],
  31. self.Y_points[-1][1] + -self.stepsize*9.82*np.sin(self.Y_points[-1][0])])
  32. return Y_guess
  33.  
  34. def Newton(self):
  35. Y_guess = self.Eulerguess()
  36. p = Y_guess[0]
  37. s = Y_guess[1]
  38. Y_delta = np.array([0,0])
  39. count = 0
  40. while 1e-10 < np.amax(Y_delta) or count < 5:
  41. count = count + 1
  42. J = np.array([ [1, -self.stepsize/2],
  43. [-np.cos(p)*self.stepsize/2, 1] ])
  44. U = np.array([p - self.Y_points[-1][0] - (self.stepsize/2)*(self.Y_points[-1][1] + s),
  45. s - self.Y_points[-1][1] + (self.stepsize/2)*9.82* (np.sin(self.Y_points[-1][0]) + np.sin(p) ) ])
  46. Y_delta = spl.solve(J,-U)
  47. p = p + Y_delta[0]
  48. s = s + Y_delta[1]
  49. t = self.Y_points[-1][2] + self.stepsize
  50. return np.array([p, s, t])
  51.  
  52. def goSteps(self, steps=1):
  53. for i in range(steps):
  54. self.Y_points = np.append(self.Y_points, [self.Newton()], axis=0)
  55. if 3 < len(self.Y_points):
  56. self.interpolvec = self.interpol3()
  57. if self.Y_points[-1,0] < self.obst:
  58. roots = np.roots([self.interpolvec[0,0], self.interpolvec[0,1], self.interpolvec[0,2] - self.obst])
  59. rootindex = np.where((self.Y_points[-1,2] <= roots) & (roots <= self.Y_points[-2,2]))
  60. print(rootindex)
  61. if len(rootindex) == 1:
  62. obsttime = roots[(rootindex)]
  63. print( obsttime)
  64. elif len(rootindex) == 2:
  65. obsttime = np.max(roots)
  66. return obsttime
  67.  
  68. return "Last step: Position: {} Speed: {} Time: {}".format(self.Y_points[-1][0], self.Y_points[-1][1],
  69. self.Y_points[-1][2])
  70.  
  71. def Lagrange(self,X,Y):
  72.  
  73. L = np.zeros((3,3))
  74. n = 3
  75. for j in range(n):
  76. Xj = np.delete(X,j)
  77. C = [X[j] - i for i in Xj]
  78. c = np.prod(C)
  79. polymult = [[1,-i] for i in Xj]
  80. J =polymult[0]
  81. for k in range(n-2):
  82. J = np.convolve(J, polymult[k+1])
  83. L[j] = J*Y[j]/c
  84. Poly = np.sum(L, axis=0)
  85. # Polyrev = [Poly[len(Poly) - 1 - i] for i in range(len(Poly))]
  86. return(Poly)
  87.  
  88. def interpol3(self):
  89. X = self.Y_points[-3:,0]
  90. Y = self.Y_points[-3:,1]
  91. Z = self.Y_points[-3:,2]
  92. Poly1 = self.Lagrange(Z,X)
  93. Poly2 = self.Lagrange(Z,Y)
  94. Polyvec = np.array([Poly1, Poly2])
  95. return Polyvec
  96.  
  97. def plot(self, choice):
  98. """
  99. What do you want to plot? Choose a number.
  100. 1. x = time, y = position
  101. 2. x = time, y = speed
  102. 3. x = position, y = speed
  103. 4. x = time, y1 = position (red), y2 = speed (blue)
  104. 5. x = position, y = speed, z = time - 3D
  105. """
  106. if choice == 1:
  107. plt.plot(self.Y_points[...,2], self.Y_points[...,0])
  108. elif choice == 2:
  109. plt.plot([self.Y_points[...,2]], [self.Y_points[...,1]])
  110. elif choice == 3:
  111. plt.plot(self.Y_points[...,0], 'r', self.Y_points[...,1], 'b')
  112. elif choice == 4:
  113. plt.plot(self.Y_points[...,2], self.Y_points[...,0], 'r')
  114. plt.plot(self.Y_points[...,2], self.Y_points[...,1], 'b')
  115. elif choice == 5:
  116. plt.axes(projection='3d').plot3D(self.Y_points[...,0], self.Y_points[...,1], self.Y_points[...,2])
  117. plt.show()
  118. return
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement