理解并将此代码转换为Python

2024-06-01 03:38:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图将这个Julia代码,一个多元牛顿-拉斐逊方法的实现,翻译成Python,并扩展它以接受四个变量中的四个方程组

守则:

using SymPy
x, y = Sym("x, y")
function SymPyDerivatives(f::String, g::String)
    #
    # Returns the string representations of all
    # partial derivatives of the expression in x and y,
    # given in the strings f and g.
    #
    formf = parse(f)
    evalformf = eval(formf)
    fx = diff(evalformf, x)
    fy = diff(evalformf, y)
    formg = parse(g)
    evalformg = eval(formg)
    gx = diff(evalformg, x)
    gy = diff(evalformg, y)
    return [string(fx) string(fy); string(gx) string(gy)]
end

function NewtonStep(fun::Array{SymPy.Sym,1},
    jac::Array{SymPy.Sym,2},
    x0::Float64, y0::Float64)
    #
    # Runs one step with Newton’s method
    #
    valfun = -SymPyFun(fun, x0, y0)
    nfx = norm(valfun)
    valmat = SymPyMatrixEvaluate(jac, x0, y0)
    update = valmat\valfun
    ndx = norm(update)
    x1 = x0 + update[1]
    y1 = y0 + update[2]
    sfx = @sprintf("%.2e", nfx)
    sdx = @sprintf("%.2e", ndx)
    sx1 = @sprintf("%.16e", x1)
    sy1 = @sprintf("%.16e", y1)
    println(" $sfx $sdx $sx1 $sy1 ")
    return [x1, y1]
end

function main()
#
# Prompts the user for expressions in x and y,
# calls SymPy to take the derivatives with respect
# to x and y of the two given expressions.
#
    println("Reading two expressions, hit enter for examples")
    print("Give a first expression in x and y : ")
    one = readline(STDIN)
    if one == ""
        one = "exp(x) - y"
        two = "x*y - exp(x)"
        x0, y0 = 0.9, 2.5
    else
        print("Give a second expression in x and y : ")
        two = readline(STDIN)
        print("Give a value for x0 : ")
        x0 = parse(Float64(readline(STDIN)))
        print("Give a value for y0 : ")
        y0 = parse(Float64(readline(STDIN)))
    end
    derivatives = SymPyDerivatives(one, two)
    println("The Jacobian matrix :")
    println(derivatives)
    fx = derivatives[1,1]
    fy = derivatives[1,2]
    gx = derivatives[2,1]
    gy = derivatives[2,2]
    jacmat = SymPyMatrix(fx, fy, gx, gy)
    valmat = SymPyMatrixEvaluate(jacmat, x0, y0)
    vecfun = SymPyExpressions(one, two)
    for i=1:5
        xsol, ysol = NewtonStep(vecfun, jacmat, x0, y0)
        x0, y0 = xsol, ysol
    end
end

main()

我的问题是,我实际上从未使用过Julia,虽然我对牛顿的方法理解得相当好,但我并不完全遵循这段代码

以下是到目前为止我得到的信息:

内部function NewtonStep()

不确定这里发生了什么:valfun = -SymPyFun(fun, x0, y0)

我们取该矩阵的范数nfx = norm(valfun)

不确定这里发生了什么:valmat = SympPyMatrixEvaluate(jax,c, x0, y0)

更新矩阵:

update = valmat\valfun
ndx = norm(update)

不知道后来发生了什么。为什么function SymPyDerivatives()从未被使用过?肯定是有什么原因

我不太清楚function SymPyDerivatives()里面发生了什么,在偏导数的线之外

更新:

只是试着一块一块地把它拆开,这就是我到目前为止所做的:

from sympy import symbols, diff
import numpy as np

class Localize:

    receivers: list

    def jacobian(f, g, h, k):
        x, y, z = symbols('x y z', real=True)

        fx = diff(f, x);    gx = diff(g, x)
        fy = diff(f, y);    gy = diff(g, y)

        hx = diff(h, x);    kx = diff(k, x)
        hy = diff(h, y);    ky = diff(k, y)

    def newtonStep(x0, x1):

        # Magic happens

        x1 = x0 + update[1]
        y1 = y0 + update[2]

似乎找不到关于SymPyFun()的任何文档,这很奇怪

编辑:

根据我自己和@steamsy的研究,似乎SymPyFun()不存在,这很奇怪。也许有人知道这是为了实现什么,以及在Python中会是什么样子?我不太清楚它在这里应该做什么

更新:

我能找到function SymPyFun()

function SymPyFun(fun::Array{SymPy.Sym,1},
                  xval::Float64,yval::Float64)
#
# Given an array of SymPy expressions,
# evaluates the expressions at (xval, yval).
#
    result1 = Float64(subs(subs(fun[1], x, xval), y, yval))
    result2 = Float64(subs(subs(fun[2], x, xval), y, yval))
    return [result1; result2]
end

Tags: andthediffupdatefunctiononeendsympy
1条回答
网友
1楼 · 发布于 2024-06-01 03:38:42

Can't seem to find any documentation on SymPyFun(), which is bizarre.

因为它不存在^关于SymPy.jl的{a1}和我对GitHub source code的刮擦从来没有提到过SymPyFun

我假设您正在跟随来自UIC的this PDF,这是我能找到的唯一引用该方法的东西

相关问题 更多 >