Julia 尝试将复杂函数传递到Simpson';时出现加载错误;s规则

Julia 尝试将复杂函数传递到Simpson';时出现加载错误;s规则,julia,simpsons-rule,Julia,Simpsons Rule,我写了一个用复合辛普森法则近似定积分的方法 #= f integrand a lower integration bound b upper integration bound n number of iterations or panels h step size =# function simpson(f::Function, a::Number, b::Number, n::Number) n % 2 == 0 || error("`n` must be even"

我写了一个用复合辛普森法则近似定积分的方法

#=
f  integrand
a  lower integration bound
b  upper integration bound
n  number of iterations or panels

h     step size
=#
function simpson(f::Function, a::Number, b::Number, n::Number)
   n % 2 == 0 || error("`n` must be even")
   h = (b - a) / n
   s = f(a) + f(b)
   s += 4*sum(f(a .+ collect(1:2:n) .* h))
   s += 2*sum(f(a .+ collect(2:2:n-1) .* h))
   return h/3 * s
end
对于像
e^(-x^2)
这样的“简单”函数,
simpson
函数可以工作

Input: simpson(x -> simpson(x -> exp.(-x.^2), 0, 5, 100)
Output: 0.8862269254513949
但是,对于更复杂的函数
f(x)

其中,
generator(θ,plotsol)
是一个函数,它接受以百分比表示的缺陷θ和布尔值
plotsol
(0或1),用于确定是否应绘制发电机,并返回发电机中某些点的磁化矢量

当我试图通过运行下面的代码来计算积分时

gArgs(x) = (30 .+ x, 0)
f(x) = exp.(-x.^2) .* maximum(generator.(gArgs.(x)...)[1])
println(simpson(x -> f(x), 0, 5, 10))

我遇到错误
MethodError:no方法匹配生成器(::Float64)
。由于
f(x)
的表达式略有变化,我遇到了不同的错误,如
维度不匹配(“数组无法广播以匹配目标”)
不精确错误:Bool(33.75)
。最后,我认为错误的原因归结为我无法正确地为被积函数
f(x)
输入表达式。有人能帮我弄清楚如何正确输入
f(x)
?如果我的问题不清楚,请告诉我。

给定一个数组
x
gArgs.(x)
返回一个元组数组
而您正试图通过元组数组进行广播。但是使用元组进行广播的行为有点不同。元组不被视为一个单独的元素,它们本身也会广播

julia> println.(gArgs.([0.5, 1.5, 2.5, 3.5, 4.5])...)
30.531.532.533.534.5
00000
这不是你所期望的,是吗

您还可以看到以下示例中的问题

julia> (2, 5) .!= [(2, 5)]
2-element BitArray{1}:
 true
 true
我相信
f
是一个函数,它实际上接受一个标量并返回一个标量。您不应该让
f
在阵列上工作,而应该将广播留给调用者。您很可能在实现
f
元素方面做得更好。这是一种更简单的做事方式,会让你的工作更轻松

也就是说,如果
generator
中没有错误,我相信您的实现应该可以进行以下修改

function simpson(f::Function, a::Number, b::Number, n::Number)
   n % 2 == 0 || error("`n` must be even")
   h = (b - a) / n
   s = f(a) + f(b)
   s += 4*sum(f.(a .+ collect(1:2:n) .* h)) # broadcast `f`
   s += 2*sum(f.(a .+ collect(2:2:n-1) .* h)) # broadcast `f`
   return h/3 * s
end

# define `gArg` and `f` element-wise and `generator`, too.
gArgs(x) = (30 + x, 0) # get rid of broadcasting dot. Shouldn't `0` be `false`?
f(x) = exp(-x^2) * maximum(generator(gArgs(x)...)[1]) # get rid of broadcasting dots
println(simpson(f, 0, 5, 10)) # you can just write `f`

您还应该定义
生成器
函数元素。

您可能应该添加
生成器
的准确签名,并确保实际错误不是由该函数引起的。
function simpson(f::Function, a::Number, b::Number, n::Number)
   n % 2 == 0 || error("`n` must be even")
   h = (b - a) / n
   s = f(a) + f(b)
   s += 4*sum(f.(a .+ collect(1:2:n) .* h)) # broadcast `f`
   s += 2*sum(f.(a .+ collect(2:2:n-1) .* h)) # broadcast `f`
   return h/3 * s
end

# define `gArg` and `f` element-wise and `generator`, too.
gArgs(x) = (30 + x, 0) # get rid of broadcasting dot. Shouldn't `0` be `false`?
f(x) = exp(-x^2) * maximum(generator(gArgs(x)...)[1]) # get rid of broadcasting dots
println(simpson(f, 0, 5, 10)) # you can just write `f`