在Julia中定义分段函数

时间:2014-12-27 06:09:18

标签: julia piecewise

我有一个应用程序,其中我需要定义一个分段函数,IE,f(x)= g(x)[x在某个范围内],f(x)= h(x)[x在某些范围内]其他范围],......等

在朱莉娅有这么好的办法吗?我宁愿不使用if-else,因为我似乎必须检查x的大值的每个范围。我想的方法是构造一个函数数组和一个边界/范围数组,然后当调用f(x)时,对范围进行二元搜索以找到适当的索引并使用相应的函数(IE, h(x),g(x)等

似乎这种数学友好的语言可能具有一些功能,但文档并没有以这种方式提及。希望其他人已经给了这个想法,谢谢!

3 个答案:

答案 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向量的正确索引。