Python:两个方程的交集

时间:2018-08-07 20:43:22

标签: python math precision

我有以下等式:

sqrt((x0 - x)^2 + (y0 - y)^2) - sqrt((x1 - x)^2 + (y1 - y)^2) = c1
sqrt((x3 - x)^2 + (y3 - y)^2) - sqrt((x4 - x)^2 + (y4 - y)^2) = c2

我想找到路口。我尝试使用fsolve,并将方程式转换为线性f(x)函数,但它适用于小数。我正在处理大量数字,并且为解决线性方程式,需要执行大量计算,特别是计算达到减法的平方根,并且当处理大量数字时,精度损失了,并且左操作数小于右操作数尝试求解负数的平方根时遇到数学值域错误。

我正在尝试以不同的方式解决此问题:

  1. 尝试使用更大的精度浮点数。使用numpy.float128尝试过,但fsolve不允许使用它。
  2. 当前正在搜索一个允许求解非线性方程组的库,但到目前为止还没有运气。

任何帮助/指导/提示,我将不胜感激!! 谢谢!

3 个答案:

答案 0 :(得分:0)

您可能会在SymPy中找到一些用处,这是Python中的符号代数操作。

在其主页上:

  

SymPy是用于符号数学的Python库。它旨在成为功能齐全的计算机代数系统(CAS),同时保持代码尽可能的简单,以便于理解和易于扩展。 SymPy完全用Python编写。

答案 1 :(得分:0)

由于您有一个非线性方程,您需要某种优化器来解决它。可能您可以使用scipy.optimize(https://docs.scipy.org/doc/scipy/reference/tutorial/optimize.html)之类的东西。但是,由于我对scipy函数没有经验,因此只能为您提供张量流库的梯度下降方法的解决方案。您可以在此处找到一份简短指南:https://learningtensorflow.com/lesson7/(查看“梯度下降”指标)。与此处描述的方法类似,您可以执行以下操作:

# These arrays are pseudo code, fill in your values for x0,x1,y0,y1,...
x_array = [x0,x1,x3,x4]
y_array = [y0,y1,y3,y4]
c_array = [c1,c2]

# Tensorflow model starts here
x=tf.placeholder("float")
y=tf.placeholder("float")
z=tf.placeholder("float")

# the array [0,0] are initial guesses for the "correct" x and y that solves the equation
xy_array = tf.Variable([0,0], name="xy_array")

x0 = tf.constant(x_array[0], name="x0")
x1 = tf.constant(x_array[1], name="x1")
x3 = tf.constant(x_array[2], name="x3")
x4 = tf.constant(x_array[3], name="x4")

y0 = tf.constant(y_array[0], name="y0")
y1 = tf.constant(y_array[1], name="y1")
y3 = tf.constant(y_array[2], name="y3")
y4 = tf.constant(y_array[3], name="y4")

c1 = tf.constant(c_array[0], name="c1")
c2 = tf.constant(c_array[1], name="c2")

# I took your first line and subtracted c1 from it, same for the second line, and introduced d_1 and d_2
d_1 = tf.sqrt(tf.square(x0 - xy_array[0])+tf.square(y0 - xy_array[1])) - tf.sqrt(tf.square(x1 - xy_array[0])+tf.square(y1 - xy_array[1])) - c_1
d_2 = tf.sqrt(tf.square(x3 - xy_array[0])+tf.square(y3 - xy_array[1])) - tf.sqrt(tf.square(x4 - xy_array[0])+tf.square(y4 - xy_array[1])) - c_2

# this z_model should actually be zero in the end, in that case there is an intersection
z_model = d_1 - d_2

error = tf.square(z-z_model)

# you can try different values for the "learning rate", here 0.01
train_op = tf.train.GradientDescentOptimizer(0.01).minimize(error)

model = tf.global_variables_initializer()

with tf.Session() as session:
    session.run(model)

    # here you are creating a "training set" of size 1000, you can also make it bigger if you like
    for i in range(1000):
        x_value = np.random.rand()
        y_value = np.random.rand()

        d1_value = np.sqrt(np.square(x_array[0]-x_value)+np.square(y_array[0]-y_value)) - np.sqrt(np.square(x_array[1]-x_value)+np.square(y_array[1]-y_value)) - c_array[0]
        d2_value = np.sqrt(np.square(x_array[2]-x_value)+np.square(y_array[2]-y_value)) - np.sqrt(np.square(x_array[3]-x_value)+np.square(y_array[3]-y_value)) - c_array[1]

        z_value = d1_value - d2_value
        session.run(train_op, feed_dict={x: x_value, y: y_value, z: z_value})

     xy_value = session.run(xy_array)
     print("Predicted model: {a:.3f}x + {b:.3f}".format(a=xy_value[0], b=xy_value[1]))

但是请注意:这段代码可能会运行一段时间...这就是为什么没有对其进行测试的原因... 另外,我目前不确定如果没有交叉路口会怎样。可能您获得了距离最近的函数的坐标...

如果您还没有使用过Tensorflow,可能会有些困难,但是值得学习,因为您还可以将其用于任何深度学习应用程序(该库的实际目的)。

答案 2 :(得分:0)

听取所有建议后,我结束了使用如下代码:

对于系统:

0 = x + y-8

0 = sqrt((-6-x)^ 2 +(4-y)^ 2)-sqrt((1- x)^ 2 + y ^)-5

from math import sqrt
import numpy as np
from scipy.optimize import fsolve


def f(x):
    y = np.zeros(2)
    y[0] = x[1] + x[0] - 8
    y[1] = sqrt((-6 - x[0]) ** 2 + (4 - x[1]) ** 2) - sqrt((1 - x[0]) ** 2 + x[1] ** 2) - 5
    return y


x0 = np.array([0, 0])
solution = fsolve(f, x0)
print "(x, y) = (" + str(solution[0]) + ", " + str(solution[1]) + ")"

注意:行x0 = np.array([0, 0])对应于该方法在fsolve中用于获取解决方案的种子。重要的是要找到一个解决之道的种子。

提供的示例有效:)