Skip to content

Commit b3517dc

Browse files
committed
part 3
1 parent 9974dbb commit b3517dc

File tree

5 files changed

+300
-0
lines changed

5 files changed

+300
-0
lines changed

Original Approach/cfg.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# coordinates of the projections of Mars on the ecliptic plane
2+
xMars = [-1.45297367276038, 1.195672782788594, 1.0738853142069973, -1.6323045900130566, -1.5537673314861347]
3+
yMars = [0.8655335301531039, -0.686856634618109, 1.051106927548351, -0.14854179871578327, 0.6248989852957586]
4+
5+
x2Mars = [0.39910431516406286, -0.29101951204595994, -0.7833937646297272, -0.9969302054095404, -0.8252535512519825, -0.057254869012341184, 0.9517725336021033, 0.6752324411578464, -0.04302706623321199, -0.6240752924965628, -0.9531154076579537, -0.9475455013657242]
6+
y2Mars = [0.9168436823883284, 0.9563575585908708, 0.6208484101394284, 0.07466793029864548, -0.564710366795997, -0.9980316866413974, -0.3043595904252963, 0.7376045179660177, 0.9988159644223529, 0.7808334890653823, 0.3014308227503241, -0.3192423211998812]
7+
z2Mars = [0.010649304298148211, 0.02622715643451466, 0.02900795005869142, 0.023555588020852912, 0.0076666667543403184, -0.025585785782483234, -0.03865596974309206, 0.0008517535642629537, 0.0227011186157881, 0.02879395160986412, 0.0266548078416554, 0.01555195153317052]
8+
9+
# radius of the best fit circle of the projections of Mars on the ecliptic plane
10+
r = 1.57732091444
11+
12+
# parameters a and b for the best fit Mars orbital plane defined by the equation
13+
# ax + by + z = 0
14+
a = 0.0236392428323
15+
b = -0.0221054030127

Original Approach/cfg.pyc

840 Bytes
Binary file not shown.
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
""" This module runs gradient descent on the locations of Mars on it's
2+
orbitalplane in order to find the best-fit elliptical orbit for Mars.
3+
"""
4+
5+
# Developed by Pulkit Singh, Niheshkumar Rathod & Rajesh Sundaresan
6+
# Copyright lies with the Robert Bosch Center for Cyber-Physical Systems,
7+
# Indian Institute of Science, Bangalore, India.
8+
9+
#----------------------------------------------------------------------------#
10+
11+
import numpy as np
12+
import math
13+
14+
#----------------------------------------------------------------------------#
15+
16+
def evaluateDistance(xMars, yMars, xFocus, yFocus, majorAxis):
17+
""" Computes the cost of fitting an ellipse with one focus at the sun,
18+
and the other at [xFocus, yFocus], given the locations of Mars and
19+
the length of the major axis.
20+
21+
Cost is caculated using the following formula:
22+
(sum of distances from focii - length of major axis)^2
23+
24+
Parameters:
25+
xMars (float): list of x-coordinates of Mars locations
26+
yMars (float): list of y-coordinates of Mars locations
27+
xFocus (float): x-coordinate of second focus
28+
yFocus (float): y-coordinate of second focus
29+
majorAxis (float): length of the major axis
30+
31+
Returns:
32+
squareDist (float): cost of fitting the ellipse (sum of square
33+
distances)
34+
35+
"""
36+
37+
# Finding the distance of each point from the origin
38+
dist = []
39+
40+
# calculating (distance to origin + distance to focus2
41+
# - major axis length)^2 for each (x, y) pair
42+
for i in range(len(xMars)):
43+
distOrigin = math.sqrt(math.pow(xMars[i], 2) + math.pow(yMars[i], 2))
44+
distFocus = math.sqrt(math.pow((xMars[i] - xFocus), 2)
45+
+ math.pow((yMars[i] - yFocus), 2))
46+
dist.append(math.pow((distOrigin + distFocus - majorAxis), 2))
47+
48+
# adding up all the square distances
49+
squareDist = sum(dist)
50+
return squareDist
51+
52+
#----------------------------------------------------------------------------#
53+
54+
def computeGradient(xMars, yMars, xFocus, yFocus, majorAxis):
55+
""" Computes the gradient vector with respect to the x-y coordinates of
56+
the second focus andthe length of the major axis.
57+
58+
gradient vector = [df/d(xFocus), df/d(yFocus), df/d(majorAxis)]
59+
60+
Parameters:
61+
xMars (float): list of x-coordinates of Mars locations
62+
yMars (float): list of y-coordinates of Mars locations
63+
xFocus (float): x-coordinate of second focus
64+
yFocus (float): y-coordinate of second focus
65+
majorAxis (float): length of the major axis
66+
67+
Returns:
68+
gradient (float list): list of required gradients
69+
70+
"""
71+
72+
dxFocus = []
73+
dyFocus = []
74+
dmajorAxis = []
75+
76+
# df/d(xFocus) = (-2 * (xMars - xFocus) * evaluateDistance) / distFocus
77+
# df/d(yFocus) = (-2 * (yMars - yFocus) * evaluateDistance) / distFocus
78+
# df/d(majorAxis) = -2 * evaluateDistance
79+
80+
# computing partial derivatives for each set of coordinates
81+
for i in range(len(xMars)):
82+
distOrigin = math.sqrt(math.pow(xMars[i], 2) + math.pow(yMars[i], 2))
83+
distFocus = math.sqrt(math.pow((xMars[i] - xFocus), 2)
84+
+ math.pow((yMars[i] - yFocus), 2))
85+
dist = distOrigin + distFocus - majorAxis
86+
87+
xDiff = xMars[i] - xFocus
88+
yDiff = yMars[i] - yFocus
89+
90+
dxFocus.append((-2 * xDiff * dist) / distFocus)
91+
dyFocus.append((-2 * yDiff * dist) / distFocus)
92+
dmajorAxis.append(-2 * dist)
93+
94+
# returning gradient vector
95+
gradient = [float(sum(dxFocus)),
96+
float(sum(dyFocus)),
97+
float(sum(dmajorAxis))]
98+
return gradient
99+
100+
#----------------------------------------------------------------------------#
101+
102+
# Takes x-y coordinate matrix of different Mars locations, x-y coordinates of
103+
# the second focus and the length of the major axis as input, and runs
104+
# gradient descent to find the best fit ellipse. Returns the x-y coordinates
105+
# of the found focus, and the length of the major axis of the ellipse.
106+
def findEllipse(xMars, yMars, xf, yf, axis):
107+
""" Finds the best-fit ellipse for the Mars Orbit using gradient
108+
descent. Returns the x-y coordinates of the found focus and the
109+
length of the major axis.
110+
111+
Parameters:
112+
xMars (float): list of x-coordinates of Mars locations
113+
yMars (float): list of y-coordinates of Mars locations
114+
xFocus (float): x-coordinate of second focus
115+
yFocus (float): y-coordinate of second focus
116+
majorAxis (float): length of the major axis
117+
118+
Returns:
119+
xf (float): x-coordinate of the found focus
120+
yf (float): y-coordinate of the found focus
121+
axis (float): length of the major axis
122+
cost (float list): list of costs in each gradient descent
123+
iteration.
124+
125+
"""
126+
127+
128+
# initialising alpha as the step value
129+
alpha = 0.001
130+
131+
# initialising array to keep track of cost values in gradient descent
132+
cost = []
133+
134+
# running gradient descent
135+
for i in range (10000):
136+
# finding cost for given parameters
137+
squareDist = evaluateDistance(xMars, yMars, xf, yf, axis)
138+
#print("square dist"), squareDist
139+
140+
# adding current cost to list of previous costs
141+
cost.append(squareDist)
142+
143+
# finding gradient with parameter values a & b
144+
delta = computeGradient(xMars, yMars, xf, yf, axis)
145+
146+
# updating parameter values
147+
xf = xf - (alpha * delta[0])
148+
yf = yf - (alpha * delta[1])
149+
axis = axis - (alpha * delta[2])
150+
151+
return xf, yf, axis, cost
152+
153+
#----------------------------------------------------------------------------#
3.71 KB
Binary file not shown.

Original Approach/mars3.py

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# E0 259: Data Analytics. Module 1: Mars Orbit. Question 3.
2+
# Pulkit Singh, July 20 2018
3+
4+
# importing required modules
5+
import math
6+
import numpy as np
7+
import matplotlib.pyplot as plt
8+
from mpl_toolkits.mplot3d import Axes3D
9+
from matplotlib.patches import Ellipse
10+
11+
# importing file containing required values calculated in other modules
12+
import cfg
13+
14+
# importing custom module to run gradient descent on elliptical mars orbit
15+
import ellipseGradientDescent
16+
17+
#-------------------------------------------------------------------------------#
18+
19+
# Part 1: Finding 5 different locations of Mars on it's orbital plane.
20+
21+
# retrieving x-y coordinates of mars computed in Part 1
22+
xMars, yMars = cfg.xMars, cfg.yMars
23+
24+
# x-y coordinates of Mars will be the same as the projections
25+
# to calculate z coordinates, we must use the formula as follows:
26+
# zMars = (-a * xMars) + (-b * yMars), where a and b are the parameters
27+
# of the best-fit plane calculated in Part 2.
28+
zMars = []
29+
for i in range(len(xMars)):
30+
zMars.append((-1 * cfg.a * xMars[i]) + (-1 * cfg.b * yMars[i]))
31+
32+
print("\nCalculating 5 different locations of Mars on it's orbital plane.\n")
33+
34+
#-------------------------------------------------------------------------------#
35+
36+
# Part 2: Finding the best fit circle on Mars's orbital plane
37+
38+
39+
# Finding the distance of each point from the origin
40+
rMars = []
41+
for i in range(len(xMars)):
42+
sqDist = math.pow(xMars[i], 2) + math.pow(yMars[i], 2) + math.pow(zMars[i], 2)
43+
rMars.append(math.sqrt(sqDist))
44+
45+
# Finding the average radius, which is the radius of the best fit circle
46+
r = sum(rMars) / len(rMars)
47+
48+
# Computing the sum of losses
49+
loss = 0.0
50+
for radius in rMars:
51+
loss = loss + math.pow((r - radius), 2)
52+
53+
print("Finding the best fit circle on the orbital plane.")
54+
print "Radius of circle", r
55+
print "Sum of losses =", loss
56+
print
57+
58+
59+
#-------------------------------------------------------------------------------#
60+
61+
# Part 3: Finding the best fit ellipse on Mars's orbital plane
62+
63+
# initialising parameters for x-y coordinates of focus and length of major axis
64+
xf1, yf1, axis1 = 0.0, 0.0, 0.0
65+
66+
# finding the best fit ellipse
67+
xf, yf, axis, cost = ellipseGradientDescent.findEllipse(xMars, yMars, xf1, yf1, axis1)
68+
69+
print "Finding best fit ellipse on the orbital plane:"
70+
print "Running gradient to find coordinates of second focus and length of major axis."
71+
print "x-coordinate of focus:", xf
72+
print "y-coordinate of focus:", yf
73+
print "Length of Major Axis:", axis
74+
print "Length of Semi-Major Axis", axis/2.0
75+
76+
77+
78+
# calculating distance between focii
79+
interFocii = math.sqrt(math.pow(xf, 2) + math.pow(yf, 2))
80+
print "Distance between Focii:", interFocii
81+
82+
83+
# calculating values to plot ellipse
84+
centerX = xf / 2.0
85+
centerY = yf / 2.0
86+
minorAxis = math.sqrt(math.pow(axis, 2) - math.pow(interFocii, 2))
87+
rotationAngle = 360 - math.degrees(math.atan(yf / abs(xf)))
88+
89+
# plotting cost as a function of number of iterations
90+
#plt.plot(cost)
91+
#plt.show()
92+
93+
# creating a plot
94+
fig, ax = plt.subplots()
95+
96+
# plotting mars locations and the focii
97+
ax.plot(xMars, yMars, "ro")
98+
ax.plot(xf, yf, "yo")
99+
ax.plot(0.0, 0.0, "yo")
100+
101+
# adding best fit circle
102+
fit_c = plt.Circle((0,0), r, color='c', fill=False)
103+
ax.add_artist(fit_c)
104+
105+
# adding best fit ellipse
106+
fit_e = Ellipse((centerX, centerY), axis, minorAxis, rotationAngle, color='b', fill=False)
107+
ax.add_artist(fit_e)
108+
109+
# setting dimensions of the plot
110+
ax.set_xlim(-2.2, 2.2)
111+
ax.set_ylim(-2.2, 2.2)
112+
ax.set_aspect('equal')
113+
114+
# updating legend
115+
ax.legend([fit_c, fit_e], ['Best-fit Circle', 'Best-fit Ellipse'], fontsize='x-small')
116+
117+
plt.show()
118+
119+
120+
#-------------------------------------------------------------------------------#
121+
122+
123+
124+
125+
126+
127+
128+
129+
130+
131+
132+

0 commit comments

Comments
 (0)