问题是每个有效x都有y的2个值,并且在椭圆跨度x的范围之外没有(或虚数)y个解
下面是3.5代码,sympy 1.0应该可以,但是可以打印,列表组合可能无法向后兼容2.x
from numpy import linalg
from numpy import linspace
import numpy as np
from numpy import meshgrid
import random
import matplotlib.pyplot as plt
from scipy import optimize
from sympy import *
xs = [1.02, 0.95, 0.87, 0.77, 0.67, 0.56, 0.44, 0.30, 0.16, 0.01]
ys = [0.39, 0.32, 0.27, 0.22, 0.18, 0.15, 0.13, 0.12, 0.12, 0.15]
b = [i ** 2 for i in xs] # That is the list that contains the results that are given as x^2 from the equation.
def fxn(x, y): # That is the function that solves the given equation to find each parameter.
my_list = [] #It is the main list.
for z in range(len(x)):
w = [0] * 5
w[0] = y[z] ** 2
w[1] = x[z] * y[z]
w[2] = x[z]
w[3] = y[z]
w[4] = 1
my_list.append(w)
return my_list
t = linalg.lstsq(fxn(xs, ys), b)
def ysolv(coeffs):
x,y,a,b,c,d,e = symbols('x y a b c d e')
ellipse = a*y**2 + b*x*y + c*x + d*y + e - x**2
y_sols = solve(ellipse, y)
print(*y_sols, sep='\n')
num_coefs = [(a, f) for a, f in (zip([a,b,c,d,e], coeffs))]
y_solsf0 = y_sols[0].subs(num_coefs)
y_solsf1 = y_sols[1].subs(num_coefs)
f0 = lambdify([x], y_solsf0)
f1 = lambdify([x], y_solsf1)
return f0, f1
f0, f1 = ysolv(t[0])
y0 = [f0(x) for x in xs]
y1 = [f1(x) for x in xs]
plt.scatter(xs, ys)
plt.scatter(xs, y0, s=100, color = 'red', marker='+')
plt.scatter(xs, y1, s=100, color = 'green', marker='+')
plt.show()
在Spyder中运行以上命令时:
runfile('C:/Users/john/mypy/mySE_answers/ellipse.py', wdir='C:/Users/john/mypy/mySE_answers')
(-b*x - d + sqrt(-4*a*c*x - 4*a*e + 4*a*x**2 + b**2*x**2 + 2*b*d*x + d**2))/(2*a)
-(b*x + d + sqrt(-4*a*c*x - 4*a*e + 4*a*x**2 + b**2*x**2 + 2*b*d*x + d**2))/(2*a)
f0(0.1), f1(0.1)
Out[5]: (0.12952825130864626, 0.6411040771593166)
f0(2)
Traceback (most recent call last):
File "<ipython-input-6-9ce260237dcd>", line 1, in <module>
f0(2)
File "<string>", line 1, in <lambda>
ValueError: math domain error
In [7]:
域错误将需要尝试/执行才能“感觉”到有效的x范围或更多数学运算
像下面的try / except一样:(编辑为“关闭”图纸,重新注释)
def feeloutxrange(f, midx, endx):
fxs = []
x = midx
while True:
try: f(x)
except:
break
fxs.append(x)
x += (endx - midx)/100
return fxs
midx = (min(xs) + max(xs))/2
xpos = feeloutxrange(f0, midx, max(xs))
xnegs = feeloutxrange(f0, midx, min(xs))
xs_ellipse = xnegs[::-1] + xpos[1:]
y0s = [f0(x) for x in xs_ellipse]
y1s = [f1(x) for x in xs_ellipse]
ys_ellipse = y0s + y1s[::-1] + [y0s[0]] # add y start point to end to close drawing
xs_ellipse = xs_ellipse + xs_ellipse[::-1] + [xs_ellipse[0]] # added x start point
plt.scatter(xs, ys)
plt.scatter(xs, y0, s=100, color = 'red', marker='+')
plt.scatter(xs, y1, s=100, color = 'green', marker='+')
plt.plot(xs_ellipse, ys_ellipse)
plt.show()
ys_ellipse = y0s + y1s[::-1] + [y0s[0]] # add y start point to end to close drawing
xs_ellipse = xs_ellipse + xs_ellipse[::-1] + [xs_ellipse[0]] # added x start point