尝试将复杂函数传递给辛普森规则时出现加载错误
Load Error when trying to pass complicated function into Simpson's 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")
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
对于 "simple" 函数,如 e^(-x^2)
,simpson
函数有效。
Input: simpson(x -> simpson(x -> exp.(-x.^2), 0, 5, 100)
Output: 0.8862269254513949
但是,对于更复杂的函数f(x)
gArgs(x) = (30 .+ x, 0)
f(x) = exp.(-x.^2) .* maximum(generator.(gArgs.(x)...)[1])
其中 generator(θ, plotsol)
是一个函数,它接受以百分比表示的缺陷 θ 和一个布尔值 plotsol
(0 或 1),以确定是否应该绘制生成器,并且 returns 发电机中某些点具有磁化强度的矢量。
当我尝试通过运行以下代码计算积分时
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 method matching generator(::Float64)
。 f(x)
的表达式略有不同,我 运行 会出现不同的错误,例如 DimensionMismatch("array could not be broadcast to match destination")
和 InexactError: Bool(33.75)
。最后,我认为错误的原因归结为我无法弄清楚如何正确输入被积函数 f(x)
的表达式。有人能帮我弄清楚如何正确输入 f(x)
吗?如果我的问题有任何不清楚的地方,请告诉我。
给定一个数组 x
, gArgs.(x)
returns 一个 Tuple
的数组,您正试图通过一个元组数组进行广播。但是使用元组进行广播的行为有点不同。元组不被视为单个元素,它们自己广播。
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
是一个实际上接受标量的函数,returns 是一个标量。不要让 f
在数组上工作,您应该将广播留给调用者。您很可能会更好地实现 f
元素。这是更 Julia 的做事方式,将使您的工作更加轻松。
就是说,我相信您的实施应该可以进行以下修改,如果您在 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`
您还应该按元素定义 generator
函数。
我已经写了一个方法,通过复合辛普森规则逼近定积分。
#=
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
对于 "simple" 函数,如 e^(-x^2)
,simpson
函数有效。
Input: simpson(x -> simpson(x -> exp.(-x.^2), 0, 5, 100)
Output: 0.8862269254513949
但是,对于更复杂的函数f(x)
gArgs(x) = (30 .+ x, 0)
f(x) = exp.(-x.^2) .* maximum(generator.(gArgs.(x)...)[1])
其中 generator(θ, plotsol)
是一个函数,它接受以百分比表示的缺陷 θ 和一个布尔值 plotsol
(0 或 1),以确定是否应该绘制生成器,并且 returns 发电机中某些点具有磁化强度的矢量。
当我尝试通过运行以下代码计算积分时
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 method matching generator(::Float64)
。 f(x)
的表达式略有不同,我 运行 会出现不同的错误,例如 DimensionMismatch("array could not be broadcast to match destination")
和 InexactError: Bool(33.75)
。最后,我认为错误的原因归结为我无法弄清楚如何正确输入被积函数 f(x)
的表达式。有人能帮我弄清楚如何正确输入 f(x)
吗?如果我的问题有任何不清楚的地方,请告诉我。
给定一个数组 x
, gArgs.(x)
returns 一个 Tuple
的数组,您正试图通过一个元组数组进行广播。但是使用元组进行广播的行为有点不同。元组不被视为单个元素,它们自己广播。
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
是一个实际上接受标量的函数,returns 是一个标量。不要让 f
在数组上工作,您应该将广播留给调用者。您很可能会更好地实现 f
元素。这是更 Julia 的做事方式,将使您的工作更加轻松。
就是说,我相信您的实施应该可以进行以下修改,如果您在 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`
您还应该按元素定义 generator
函数。