我有一个应用程序,其中我需要定义一个分段函数,IE,f(x)= g(x)[x在某个范围内],f(x)= h(x)[x在某些范围内]其他范围],......等
在朱莉娅有这么好的办法吗?我宁愿不使用if-else,因为我似乎必须检查x的大值的每个范围。我想的方法是构造一个函数数组和一个边界/范围数组,然后当调用f(x)时,对范围进行二元搜索以找到适当的索引并使用相应的函数(IE, h(x),g(x)等
似乎这种数学友好的语言可能具有一些功能,但文档并没有以这种方式提及。希望其他人已经给了这个想法,谢谢!
答案 0 :(得分:1)
使用Heaviside函数可以执行区间函数:
function heaviside(t)
0.5 * (sign(t) + 1)
end
和
function interval(t, a, b)
heaviside(t-a) - heaviside(t-b)
end
function piecewise(t)
sinc(t) .* interval(t,-3,3) + cos(t) .* interval(t, 4,7)
end
我觉得它也可以实现一个子类型Interval,它会更优雅
答案 1 :(得分:1)
我尝试为piecewise
实现Julia
函数,结果就是这样:
function piecewise(x::Symbol,c::Expr,f::Expr)
n=length(f.args)
@assert n==length(c.args)
@assert c.head==:vect
@assert f.head==:vect
vf=Vector{Function}(n)
for i in 1:n
vf[i]=@eval $x->$(f.args[i])
end
return @eval ($x)->($(vf)[findfirst($c)])($x)
end
pf=piecewise(:x,:([x>0, x==0, x<0]),:([2*x,-1,-x]))
pf(1) # => 2
pf(-2) # => 2
pf(0) # => -1
答案 2 :(得分:1)
为什么不是这样的?
function piecewise(x::Float64, breakpts::Vector{Float64}, f::Vector{Function})
@assert(issorted(breakpts))
@assert(length(breakpts) == length(f)+1)
b = searchsortedfirst(breakpts, x)
return f[b](x)
end
piecewise(X::Vector{Float64}, bpts, f) = [ piecewise(x,bpts,f) for x in X ]
这里有一个(已排序的)断点列表,您可以使用优化的searchsortedfirst
来查找大于b
的第一个断点x
。由于返回x
,因此没有断点大于length(breakpts)+1
时的边缘情况也会得到适当处理,因此b
是函数f
向量的正确索引。