从Matlab到Python - 解决函数

5

我制作了一个Matlab函数,现在想将其转换为Python以便于在我的Web应用程序中使用。

我使用OMPC几乎将所有内容转换成了.py文件。但是,我无法使solve()函数正常工作(我正在使用sympy库)。

以下是Matlab代码:

SBC = solve(sqrt((xa-x)^(2)+(ya-y)^(2))-sqrt((xb-x)^(2)+(yb-y)^(2))-D12==0,sqrt((xa-x)^(2)+(ya-y)^(2))-sqrt((xc-x)^(2)+(yc-y)^(2))-D13==0,[x,y]);

以下是Python代码,其中xy是符号(通过x = Symbol('x')y = Symbol('y')定义):

sbc = solve(
            sqrt((xa - x) ** (2) + (ya - y) ** (2))
            - sqrt((xb - x) ** (2) + (yb - y) ** (2))
            - D12 == 0,
            sqrt((xa - x) ** (2) + (ya - y) ** (2))
            - sqrt((xc - x) ** (2) + (yc - y) ** (2))
            - D13 == 0,
            [x, y]
        )

用这段Python代码,我得到的结果是False(在Matlab代码中它很好用)。我是否漏掉了什么?
编辑:并且用这个,我得到的结果是[]
# -*- coding: utf-8 -*-

from sympy import *

def alg(xa=None, ya=None, za=None, Ta=None, xb=None, yb=None, zb=None, Tb=None, xc=None, yc=None, zc=None, Tc=None, xd=None, yd=None, zd=None, Td=None, RSSIA=None, RSSIB=None, RSSIC=None, RSSID=None, txPower=None, n=None):
    n = 2
    c = 3 * 10 ** 8
    TOA12 = Ta - Tb
    TOA13 = Ta - Tc
    TOA14 = Ta - Td

    D12 = TOA12 * c
    D13 = TOA13 * c
    D14 = TOA14 * c
    x, y = symbols('x y')

    eqs = [sqrt((xa - x) ** (2) + (ya - y) ** (2)) - sqrt((xb - x) ** (2) + (yb - y) ** (2)) - D12,
   sqrt((xa - x) ** (2) + (ya - y) ** (2)) - sqrt((xc - x) ** (2) + (yc - y) ** (2)) - D13]

    print solve(eqs, [x, y])

alg(3,1,0,21.8898790015,4,6,0,21.8898790005,10,4,0,21.88987900009,9,0.5,0,21.889879000105,23.9,23.85,23.9,23.95,24,1)
1个回答

5
只需要进行一个小小的更改就可以使它正常工作。你之所以会收到 False 是因为在函数定义中使用了 == 0。在sympy中,通常假设函数的值为 0。以下是从这里选取的一个例子:
如果你想解方程 x+5y=2, -3x+6y=15,那么你可以按照以下步骤进行:
from sympy import *
x, y  = symbols('x y')
solve([x + 5*y - 2, -3*x + 6*y - 15], [x, y])

这将为您提供

{x: -3, y: 1}

请注意,方程式传递的方式是它们被计算为0
如果您像之前一样运行它。
solve([x + 5*y - 2 == 0, -3*x + 6*y - 15 == 0], [x, y])

如果是False,则返回假。

因此,对于您的示例,以下内容将起作用:

from sympy import *

x, y, xa, xb, xc, ya, yb, yc, D12, D13 = symbols('x y xa xb xc ya yb yc D12 D13')

eqs = [sqrt((xa - x) ** (2) + (ya - y) ** (2)) - sqrt((xb - x) ** (2) + (yb - y) ** (2)) - D12,
       sqrt((xa - x) ** (2) + (ya - y) ** (2)) - sqrt((xc - x) ** (2) + (yc - y) ** (2)) - D13]

solve(eqs, [x, y])

很遗憾,在我的私人电脑上无法运行(我的Python被“杀死”;显然这很难解决),因此我只测试了一个更简单的版本来演示原理:

eqs2 = [sqrt(xa - x) - D12,
       (yc - y) ** (2) - D13]
solve(eqs2, [x, y])

然后它会给出您期望的输出:

[(-D12**2 + xa, -sqrt(D13) + yc), (-D12**2 + xa, sqrt(D13) + yc)]

希望你的机器能够更好地解决这些复杂的函数。但是这篇文章解释了为什么你会收到“False”结果。
编辑:
使用你修改后的代码,如果你减小参数 D12 和 D13 的精度,就可以得到一个解决方案。以下是你得到的解决方案:
[sqrt((-x + 3)**2 + (-y + 1)**2) - sqrt((-x + 4)**2 + (-y + 6)**2) - 0.3, sqrt((-x + 3)**2 + (-y + 1)**2) - sqrt((-x + 10)**2 + (-y + 4)**2) - 0.42]
[{x: 6.45543078993649, y: 3.14390310591109}, {x: 6.67962865117349, y: 2.61399193301427}]

这些是否与您收到的Matlab模拟数据相同?

以下是修改后的代码;请注意,我强制输出为字典形式并打印方程式(我将其四舍五入到两个小数点,但也适用于四个小数点;您可以自行尝试):

from sympy import *

def alg(xa=None, ya=None, za=None, Ta=None, xb=None, yb=None, zb=None, Tb=None, xc=None, yc=None, zc=None, Tc=None, xd=None, yd=None, zd=None, Td=None, RSSIA=None, RSSIB=None, RSSIC=None, RSSID=None, txPower=None, n=None):
    n = 2
    c = 3 * 10 ** 8
    TOA12 = Ta - Tb
    TOA13 = Ta - Tc
    TOA14 = Ta - Td

    D12 =  round(TOA12 * c, 2)
    D13 =  round(TOA13 * c, 2)
    # D14 = TOA14 * c
    # x, y, D12, D13 = symbols('x y D12 D13')
    x, y = symbols('x y')

    eqs = [sqrt((xa - x) ** (2) + (ya - y) ** (2)) - sqrt((xb - x) ** (2) + (yb - y) ** (2)) - D12,
   sqrt((xa - x) ** (2) + (ya - y) ** (2)) - sqrt((xc - x) ** (2) + (yc - y) ** (2)) - D13]

    print eqs

    print solve(eqs, x, y, dict=True)

alg(3,1,0,21.8898790015,4,6,0,21.8898790005,10,4,0,21.88987900009,9,0.5,0,21.889879000105,23.9,23.85,23.9,23.95,24,1)

哦,我明白了。谢谢您提供这个信息。我刚才看到这是写在Sympy文档的求解器部分的第一行 :( 然而,我仍然有问题,因为结果是[],而不是{x:…, y:…}。有什么想法吗? - Anthony
你能否编辑问题并添加给你 [] 的代码?按照目前的写法,我也没有得到结果,因为我的 Python 会话在几分钟后就被终止了;你试图解决的方程实在太难了... ;) - Cleb
完成! :) 我的会话没有被终止,但需要大约5秒钟才能“解决”。 - Anthony
好的,我已经更新了你的代码,现在它可以正常工作了。请检查一下是否与使用Matlab时得到的结果相同。 - Cleb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接