2014-12-27 7 views
8

Bir parçalı fonksiyon tanımlamak zorunda olduğum bir uygulama var, IE, f (x) = g (x) için bazı aralıklarda [x], f (x) = h (x) için [x diğer bir aralıkta], ... vb.Julia'da Piecewise Fonksiyonlarını Tanımla

Bunu Julia'da yapmanın iyi bir yolu var mı? If-else kullanmamayı tercih ederim çünkü her bir aralığı x'in büyük değerleri için kontrol etmek zorundayım. Düşündüğüm yol, bir dizi fonksiyon ve bir dizi sınır/aralık oluşturmaktı, sonra f (x) çağrıldığında, uygun indeksi bulmak ve ilgili fonksiyonu kullanmak için aralıklar üzerinde bir ikili arama yapmak (IE, h (x), g (x), vb.

Böyle matematiksel olarak dost bir dilin bunun için bazı işlevlere sahip olabileceği düşünülüyor, ancak belgeler bu şekilde parçalara ayrılmıyor. bazı düşünce, teşekkürler bir aralık işlevini yapabileceği bir Heaviside fonksiyonu ile

+0

[Numpy'nin parçalama işlevi] 'nin uygulanmasına bakmak isteyebilirsiniz (http://docs.scipy.org/doc/numpy/reference/generated/numpy.piecewise.html). – Jubobs

cevap

1

:

function heaviside(t) 
    0.5 * (sign(t) + 1) 
end 

ve

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 

ve ben aynı zamanda bir alt türü Aralığı uygulamak düşünüyorum, ben Julia için piecewise işlevi uygulamak çalıştı

1

çok daha şık olurdu ve bu sonucudur:

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][email protected] $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 
1

Neden böyle bir şey değil?

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 ] 

Burada (sıralı) kırılma noktalarının bir listesi var ve sen x daha ilk kesme noktası b büyük bulmak için optimize searchsortedfirst kullanabilirsiniz. length(breakpts)+1 döndüğünden, herhangi bir kesme noktası x'dan büyük olduğunda kenar durumu da uygun şekilde işlenir, bu nedenle bf işlevlerinin vektörüne doğru dizindir.