我正在尝试求解二次方程facebookConnectPlugin.api("<user-id>/?fields=id,email,gender,birthday",["public_profile","user_birthday"],
function onSuccess (result) {
console.log("Result: ", result);
/* logs:
{
"id": "000000123456789",
"email": "myemail@example.com"
}
*/
}, function onError (error) {
console.error("Failed: ", error);
}
);
我的代码并非在所有情况下都给出正确的答案。
x**2 + b * x + c =0
测试功能:
def solve_quad(b, c):
b= float(b)
c= float(c)
import numpy as np
# definition of companion matrix A of the quadratic equation
A = np.array([[0,-c],
[1,-b]])
# roots of the quadratic equation are the eigen values of matrix A
from numpy.linalg import eig
e, v = eig(A)
return e
solve_quad(0,1)
某些答案为“ True”,而其他答案为from numpy import allclose
variants = [{'b': 4.0, 'c': 3.0},
{'b': 2.0, 'c': 1.0},
{'b': 0.5, 'c': 4.0},
{'b': 1e10, 'c': 3.0},
{'b': -1e10, 'c': 4.0},]
for var in variants:
x1, x2 = solve_quad(**var)
print(allclose(x1*x2, var['c']))
。是什么原因造成的?
因此,我尝试使用牛顿方法抛光根部,但是我不确定它是否可以那样工作。 将numpy导入为np
False
当b远大于c时,特征值存在数值误差 所以我们的想法是使用牛顿函数来抛光使用伴随矩阵方法得到的根 因此我们将A特征值的根作为迭代过程中真实根的第一近似值
def solve_quad(b, c):
b= float(b)
c= float(c)
# defining the given function
def f(x):
return x**2 + b*x + c
# first derivative of the given function
def f1(x):
return 2 * x + b
# definition of companion matrix A of the quadratic equation
A = np.array([[0,-c],
[1,-b]])
# roots of the quadratic equation are the eigen values of matrix A
from numpy.linalg import eigvals
e = eigvals(A)
答案 0 :(得分:0)
这可能被视为作弊,但是由于我们知道非零高值结果是根之一,因此我们可以将第二个值设为c/x1
def solve_quad(b, c):
b= float(b)
c= float(c)
import numpy as np
# definition of companion matrix A of the quadratic equation
A = np.array([[0,-c],
[1,-b]])
# roots of the quadratic equation are the eigen values of matrix A
from numpy.linalg import eigvals
#Used eigvals instead of eig because we are not using the vectors
e = eigvals(A)
#Checks for 0 roots where c is not zero, indicating a large root then forces the
#zero value root to be c/(large value root). This is also not accurate but should
#validate x1*x2 = c and returns non zero roots to avoid later on divisions
#or multiplications by zeroes.
if any(v == 0. for v in e) and c != 0.:
e[np.argwhere(e == 0)] = c/(e[np.nonzero(e)])
return e
使用代数进行计算的另一种更准确的方法是:
自(1 + eps)**n = 1 + n.eps
起,对于小型eps,我们可以重写:
def solve_quad(b, c):
b= float(b)
c= float(c)
import numpy as np
# definition of companion matrix A of the quadratic equation
A = np.array([[0,-c],
[1,-b]])
# roots of the quadratic equation are the eigen values of matrix A
from numpy.linalg import eigvals
#Used eigvals instead of eig because we are not using the vectors
e = eigvals(A)
# This is much more accurate although the results will appear to be the
#same and the multiplication is not exactly equal to c but the error
#here are due to the algebraic assumption we made and results are
#mathematical instead of forcing the result to be some value.
if any(v == 0. for v in e) and c != 0.:
eps = c/b
e[np.nonzero(e)] += eps
e[np.argwhere(e == 0)] = -eps
return e
答案 1 :(得分:0)
因此,我使用牛顿迭代法(Newton Iteration)来抛光从伴随矩阵中获得的根,并且代码如下所示
def solve_quad1(b, c):
"""Solve a quadratic equation, x**2 + bx + c = 0.
Parameters
----------
b, c : float
Coefficients
Returns
-------
x1, x2 : float or complex
Roots.
"""
b= float(b)
c= float(c)
# defining the given function
def f(x):
return x**2 + b*x + c
# first derivative of the given function
def f1(x):
return 2 * x + b
# definition of companion matrix A of the quadratic equation
A = np.array([[0,-c],
[1,-b]])
# roots of the quadratic equation are the eigen values of matrix A
from numpy.linalg import eigvals
e = eigvals(A)
#When b is extremely larger than c,there are numerical errors with the eigen
#values
#so the idea is to use Newton's function to polish the roots we got using the
#companion matrix method
#so we are taking the roots from the eigenvalues of A as the first
#approximations of our true roots
#for the iteration process
n_iter=0
eps= 1e-5
x_curr1=[]
for v in e:
x_curr= v
while n_iter < 20:
x_next = x_curr - f(x_curr)/ f1(x_curr)
if (abs(x_curr - x_next) < eps):
break
x_curr = x_next
n_iter += 1
x_curr1.append(x_curr)
return x_curr1
#Example
solve_quad1(1000000,3)