我试图将这个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
因为它不存在^关于SymPy.jl的{a1}和我对GitHub source code的刮擦从来没有提到过SymPyFun
我假设您正在跟随来自UIC的this PDF,这是我能找到的唯一引用该方法的东西
相关问题 更多 >
编程相关推荐