2017-01-23 5 views
1

Во многих приложениях отображения (е, X), это помогает создать затворы, которые в зависимости от параметров применяются различные функции F в X. данныхУсловные замыкания в Джулии

я могу думать, по крайней мере, трех следующих способов сделать это (обратите внимание, что второй по какой-то причине не работает, ошибка?)

f0(x,y) = x+y 
f1(x,y,p) = x+y^p 

function g0(power::Bool,X,y) 
    if power 
    f = x -> f1(x,y,2.0) 
    else 
    f = x -> f0(x,y) 
    end 
    map(f,X) 
end 

function g1(power::Bool,X,y) 
    if power 
    f(x) = f1(x,y,2.0) 
    else 
    f(x) = f0(x,y) 
    end 
    map(f,X) 
end 

abstract FunType 
abstract PowerFun <: FunType 
abstract NoPowerFun <: FunType 

function g2{S<:FunType}(T::Type{S},X,y) 
    f(::Type{PowerFun},x) = f1(x,y,2.0) 
    f(::Type{NoPowerFun},x) = f0(x,y) 
    map(x -> f(T,x),X) 
end 

X = 1.0:1000000.0 

burnin0 = g0(true,X,4.0) + g0(false,X,4.0); 
burnin1 = g1(true,X,4.0) + g1(false,X,4.0); 
burnin2 = g2(PowerFun,X,4.0) + g2(NoPowerFun,X,4.0); 

@time r0true = g0(true,X,4.0); #0.019515 seconds (12 allocations: 7.630 MB) 
@time r0false = g0(false,X,4.0); #0.002984 seconds (12 allocations: 7.630 MB) 

@time r1true = g1(true,X,4.0); # 0.004517 seconds (8 allocations: 7.630 MB, 26.28% gc time) 
@time r1false = g1(false,X,4.0); # UndefVarError: f not defined 

@time r2true = g2(PowerFun,X,4.0); # 0.085673 seconds (2.00 M allocations: 38.147 MB, 3.90% gc time) 
@time r2false = g2(NoPowerFun,X,4.0); # 0.234087 seconds (2.00 M allocations: 38.147 MB, 60.61% gc time) 

Каков оптимальный способ сделать это в Джулию?

+0

Попробуйте 'burning0 = f1 (X, 4,0, 2,0) + f0 (X, 4,0)' – colinfang

+0

Btw лучше использовать 'константный X = 1,0..: 1000000.0' – colinfang

+0

Нет необходимости в 'const', поскольку он передает его как аргумент функции. –

ответ

8

Здесь нет необходимости использовать карту здесь. Использование закрытия не делает вещи проще или быстрее. Просто используйте "dot-broadcasting" применять функции непосредственно:

function g3(X,y,power=1) 
    if power != 1 
    return f1.(X, y, power) # or simply X .+ y^power 
    else 
    return f0.(X, y) # or simply X .+ y 
    end 
end