function - 针对关键字参数绘制函数会导致 Julia 出错
问题描述
我有一个涉及大量积分和复杂计算的函数,如下所示:
using HCubature
function func(v, x0, y0; rad=1.)
L = hcubature(r->r[1]*v(x0+r[1]*cos(r[2]), y0+r[1]*sin(r[2])), [0., π/2], [rad, π])[1]
R = hcubature(r->r[1]*v(x0+r[1]*cos(r[2]), y0+r[1]*sin(r[2])), [0., 0], [rad, π/2])[1]
return L, R
end
参数v
本身就是一个函数。当我尝试根据关键字参数绘制函数时rad
,我收到如下错误消息:
x0_, y0_ = 0, 0
rad_ = 0.:0.1:9.
func_array_L = [func(v, x0_, y0_; rad = radius)[1] for radius in rad_]
func_array_R = [func(v, x0_, y0_; rad = radius)[2] for radius in rad_]
plot(rad_, func_array_L)
plot!(rad_, func_array_R)
错误信息包括一个很长的错误信息:Internal error: encountered unexpected error in runtime:
然后是一长串目录,然后是以下内容:
MethodError: no method matching string(::Expr)
The applicable method may be too new: running in world age 3820, while current world is 26290.
Closest candidates are:
string(::Any...) at strings/io.jl:168 (method too new to be called from this world context.)
string(!Matched::String) at strings/substring.jl:152 (method too new to be called from this world context.)
string(!Matched::SubString{String}) at strings/substring.jl:153 (method too new to be called from this world context.)
...
我还尝试了其他方法,例如将另一个函数声明rad
为唯一的参数等,但它们都不起作用。如何解决问题?
解决方案
确实错误信息很奇怪,但原因很简单。您还没有定义函数v
。您应该先定义它,然后一切都应该按预期工作。
另外请注意,您的大小写错误using HCubature
(注意u
应该是小写)。此外,为了使绘图工作,您应该首先导入绘图包,例如通过using Plots
.
编辑
重现您的问题的基本代码是:
julia> using HCubature
julia> function func(v, x0, y0; rad=1.)
L = hcubature(r->r[1]*v(x0+r[1]*cos(r[2]), y0+r[1]*sin(r[2])), [0., π/2], [rad, π])[1]
R = hcubature(r->r[1]*v(x0+r[1]*cos(r[2]), y0+r[1]*sin(r[2])), [0., 0], [rad, π/2])[1]
return L, R
end
func (generic function with 1 method)
julia> v = (x,y) -> x
#27 (generic function with 1 method)
julia> x0_, y0_ = 0, 0
(0, 0)
julia> rad_ = 0.:0.1:9.
0.0:0.1:9.0
julia> func_array_L = [func(v, x0_, y0_; rad = radius)[1] for radius in rad_]
Internal error: encountered unexpected error in runtime:
MethodError(f=typeof(Base.string)(), args=(Expr(:<:, :t, :r),), world=0x0000000000000eec)
这似乎是一个错误。我在这里报告了。
一种解决方法
现在 - 解决它的方法是使v
类型稳定。有三种示例方法可以做到这一点。
选项1:将其定义为const
:
const v1 = v
并使用带v1
传递的理解而不是v
.
选项2:将其包装在let
块中:
func_array_L = let v=v
[func(v, x0_, y0_; rad = radius)[1] for radius in rad_]
end
选项 3:使用以下名称定义函数v
:
v2(x,y) = v(x,y)
并使用带v2
传递的理解而不是v
.
或者,您也可以制作x0_
或y0_
成为常量类型(修复其中一个就足够了)以使所有工作正常。例如这个
func_array_L = [func(v, 1, y0_; rad = radius) for radius in rad_]
按预期工作。
补充笔记
map
如果在 map 中使用匿名函数而不是理解,则会遇到类似的问题:
map(radius -> func(v, x0_, y0_; rad = radius)[1], rad_)
并且具有名称的普通函数也会产生相同的错误:
v3(radius) = func(v, x0_, y0_; rad = radius)[1]
map(v3, rad_)
但如果您将一个内部函数引入方法表中,它就会开始工作:
v3(radius) = (tmp(x...) = v(x...); func(tmp, x0_, y0_; rad = radius)[1])
现在map(v3, rad_)
按预期工作。
推荐阅读
- amazon-ecs - Pipeline 永远不会通过 codepipeline 完成 AWS ECS Fargate 任务的部署
- python - 使用带有 OpenCV 的颜色直方图重新识别人员
- javascript - 如何从 Vue 中的方法更新地图
- ruby-on-rails - 将临时站点部署到 AWS
- php - 给定 [address] 邮箱中的地址不符合 RFC 2822, 3.6.2
- reactjs - 过滤
- 通过自定义参数
- php - laravel 6.x 版本如何重定向不同用户查看不同页面
- c++ - mimalloc 推荐选项
- abap - OpenSQL中GROUP BY子句中的通配符?
- node.js - 我是否应该在本地计算机中拥有与我要部署到的环境版本相同的节点(例如:Firebase Cloud Functions)?