Reputation: 11
I had the following problem on a test and my code didn't give me the exact results I needed, but I can't really find what went wrong.
We discovered a new comet whose elliptical orbit can be represented in a Cartesian $(x, y)$ coordinate system by the equation
$$ay^2+ bxy + cx + dy + e = x^2$$ Use a SciPy routine to solve the linear least squares problem to determine the orbital parameters a, b, c, >d, e, given the following observations of the comet’s position
Observation 1 2 3 4 5 6 7 8 9 10 x 1.02 0.95 0.87 0.77 0.67 0.56 0.44 0.3 0.16 0.01 y 0.39 0.32 0.27 0.22 0.18 0.15 0.13 0.12 0.13 0.15
I wrote this code, but when i plot the equation using matplotlib.contour
the curve doesn't match the data points.
def fit(x, y):
n = (np.shape(x)[0])
A = np.array([y**2, x * y, x, y, np.ones(n)]).T
b = x**2
return linalg.lstsq(A, b)[0]
obx = np.array([1.02, 0.95, 0.87, 0.77, 0.67, 0.56, 0.44, 0.3, 0.16, 0.01])
oby = np.array([0.39, 0.32, 0.27, 0.22, 0.18, 0.15, 0.13, 0.12, 0.13, 0.15])
fit(obx, oby)
Does somebody know what I am doing wrong here, should i maybe use curvefit
instead of lstsq
, or is my mistake in the plotting code?
Some follow-up clarification, the code I wrote gave this output for the constants a to e.
array([-2.63562548, 0.14364618, 0.55144696, 3.22294034, -0.43289427])
I plotted the result with this code
obx = np.array([1.02, 0.95, 0.87, 0.77, 0.67, 0.56, 0.44, 0.3, 0.16, 0.01])
oby = np.array([0.39, 0.32, 0.27, 0.22, 0.18, 0.15, 0.13, 0.12, 0.13, 0.15])
def data_plot(x, y, a, b, c, d, e):
def f(x, y):
return a * y**2 + b * x * y + c * x + d * y + e
plt.close()
size = 100
xrang = np.linspace(0,0.5, size)
yrang = np.linspace(0,90, size)
X, Y = np.meshgrid(xrang, yrang)
F = f(X, Y)
G = X**2
plt.contour( (F-G), [0])
plt.scatter(x, y)
plt.xlim([-0.5, 1.5])
plt.ylim([0, 0.5])
plt.xlabel('x-coordinate')
plt.ylabel('y-coordinate')
plt.show()
return None
data_plot(obx, oby, -2.63562548, 0.14364618, 0.55144696, 3.22294034, -0.43289427
)
which give this, obviously wrong, result.plot
Upvotes: 0
Views: 92
Reputation: 25364
Does somebody know what I am doing wrong here, should i maybe use curvefit instead of lstsq , or is my mistake in the plotting code?
I think it's a mistake in your plotting code. I plotted this in a different manner, and it agrees with the initial points.
from sympy import plot_implicit, symbols, Eq, And
from sympy.plotting.plot import List2DSeries
import numpy as np
obx = np.array([1.02, 0.95, 0.87, 0.77, 0.67, 0.56, 0.44, 0.3, 0.16, 0.01])
oby = np.array([0.39, 0.32, 0.27, 0.22, 0.18, 0.15, 0.13, 0.12, 0.13, 0.15])
x, y = symbols('x y')
a, b, c, d, e = -2.63562548, 0.14364618, 0.55144696, 3.22294034, -0.43289427
p1 = plot_implicit(Eq(a*y**2+ b*x*y + c*x + d*y + e, x**2), (x, -2, 2), (y, -2, 2), line_color='red')
p1.append(List2DSeries(obx, oby))
p1.show()
(Blue is initial points, red is the least-squares fit.)
Upvotes: 0