以Lorenz为例(JuliaDiffEq github)
function lorenz(t,u,du)
du[1] = 10.0*(u[2]-u[1])
du[2] = u[1]*(28.0-u[3]) - u[2]
du[3] = u[1]*u[2] - (8/3)*u[3]
end
如果我必须在循环中生成方程式,我会尝试在循环中连接字符串,然后将它们转换为函数。使用Matlab可以实现(str2func)。朱莉娅,我迷路了(这实际上是我在朱莉娅尝试的第一件事)。 我的第一次尝试是:
function lorenz(t,u,du)
Ex = :(du[1] = 10.0*(u[2]-u[1]))
eval(ex)
du[2] = u[1]*(28.0-u[3]) - u[2]
du[3] = u[1]*u[2] - (8/3)*u[3]
end
不起作用(未定义;后面跟着可能来自prob = ODEProblem(lorenz,u0,tspan)
中使用此函数的错误行
有人可以指出我正确的方向。
第一个问题是我无法找到函数进入ODEProblem
时会发生什么。有人请指导我到哪里可以找到朱莉娅的功能。
EDIT1
我刚试过
ex = quote
function lorenz(t,u,du)
du[1] = 10.0*(u[2]-u[1])
du[2] = u[1]*(28.0-u[3]) - u[2]
du[3] = u[1]*u[2] - (8/3)*u[3]
end
end
eval(ex)
这很有效。所以我知道这种方法有效。但是我担心我可能偶然发现了'某种方式';不是首选的方式。如果有人更熟悉Julia
,请发表评论。
<小时/>
EDIT2
需要解决的方程组的一个例子:
du[1] = u[1] + v[1] + U
dv[1] = v[1] + U
du[2] = u[2] + v[2] + U
dv[2] = v[2] + U
...
此处U
是u[i]
的总和(我从1到M
;应该可以在变量中设置M
的值。)
答案 0 :(得分:0)
在MATLAB中,你应该尽量避免循环。在Julia中,优化了这种环境中的循环,因此没有理由避免它。编写此函数的简便方法是:
function f(t,u,du)
U = sum(u)
for i in eachindex(u)
du[i] = u[i] + v[i] + U
dv[i] = v[i] + U
end
end
请注意,这甚至不需要对长度的引用,因此它适用于任何大小u
和du
。因此,创建ODEProblem(f,u0,tspan)
,其中u0
是您的大小M
数组,并且您将会很好。
我们可以使用一些性能宏来进一步优化这一点。 @inbounds
关闭边界检查,所以做起来很不错
function f(t,u,du)
U = sum(u)
@inbounds for i in eachindex(u)
du[i] = u[i] + v[i] + U
dv[i] = v[i] + U
end
end
在某些情况下,如果循环足够长,我们可能需要强制@simd
:
function f(t,u,du)
U = sum(u)
@simd for i in eachindex(u)
@inbounds du[i] = u[i] + v[i] + U
@inbounds dv[i] = v[i] + U
end
end
或者如果真的很长,多线程:
function f(t,u,du)
U = sum(u)
Threads.@threads for i in eachindex(u)
@inbounds du[i] = u[i] + v[i] + U
@inbounds dv[i] = v[i] + U
end
end
(当然,请确保enable threading)。