2014-12-27 13 views
8

Ich habe eine Anwendung, in der ich eine stückweise Funktion definieren muss IE, f (x) = g (x) für [x in einem Bereich], f (x) = h (x) für [x in einem anderen Bereich], ... etc.Definieren Sie stückweise Funktionen in Julia

Gibt es einen schönen Weg, dies in Julia zu tun? Ich würde lieber nicht, wenn-sonst, weil es scheint, dass ich jeden Bereich für große Werte von x überprüfen müsste. Die Art, wie ich dachte, war, ein Array von Funktionen und ein Array von Grenzen/Bereichen zu konstruieren, dann, wenn f (x) aufgerufen wird, eine binäre Suche nach den Bereichen durchzuführen, um den passenden Index zu finden und die entsprechende Funktion zu verwenden (IE, h (x), g (x) usw.

Es scheint, als ob eine solche mathematisch freundliche Sprache eine gewisse Funktionalität dafür hätte, aber die Dokumentation erwähnt nicht stückweise auf diese Art. Hoffentlich hat jemand anderes dies gegeben einige Gedanken, dank

+0

Sie könnten sich die Implementierung von [NumPy 'stückweise' Funktion] (http://docs.scipy.org/doc/numpy/reference/generated/numpy.piecewise.html) ansehen. – Jubobs

Antwort

1

mit einer Heaviside Funktion können Sie eine Intervallfunktion tun können:

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

und

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 

und ich denke, es ist auch ein Subtyp Interval implementieren könnte, wäre es viel eleganter sein

1

Ich habe versucht, eine piecewise Funktion für Julia zu implementieren, und das ist das Ergebnis:

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

Warum nicht so etwas?

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 ] 

Hier haben Sie eine Liste (sortiert) Haltepunkte, und Sie können die optimierte searchsortedfirst verwenden die erste Haltepunkt b größer als x zu finden. Der Randfall, wenn kein Unterbrechungspunkt größer als x ist, wird ebenfalls entsprechend behandelt, da length(breakpts)+1 zurückgegeben wird, so dass b der korrekte Index in den Vektor der Funktionen f ist.