10

我有一个应用程序,我需要在其中定义一个分段函数,IE,f(x) = g(x) for [x in some range], f(x)=h(x) for [x in some other range] , ... ETC。

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

似乎这种数学上友好的语言可能对此有一些功能,但文档没有以这种方式分段提及。希望其他人对此有所考虑,谢谢!

4

3 回答 3

4

使用 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,它会更优雅

于 2014-12-28T14:56:44.570 回答
2

我试图为 实现一个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
于 2015-11-01T09:51:45.080 回答
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

于 2016-04-02T17:30:54.337 回答