Skip to main content
  • Home
  • Development
  • Documentation
  • Donate
  • Operational login
  • Browse the archive

swh logo
SoftwareHeritage
Software
Heritage
Archive
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

  • b7953a0
  • /
  • deaboot.jl
Raw File Download
Permalinks

To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
Select below a type of object currently browsed in order to display its associated SWHID and permalink.

  • content
  • directory
content badge Iframe embedding
swh:1:cnt:486dec443818a7ff79d10765c32af773f75847fb
directory badge Iframe embedding
swh:1:dir:b7953a0181984616831ccdfbbba622e10eb82cca
Citations

This interface enables to generate software citations, provided that the root directory of browsed objects contains a citation.cff or codemeta.json file.
Select below a type of object currently browsed in order to generate citations for them.

  • content
  • directory
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
deaboot.jl
# This file contains functions for the Bootstrap Radial DEA model
"""
AbstractBootstrapDEAModel
An abstract type representing a bootstrap DEA model.
"""
abstract type AbstractBootstrapDEAModel <: AbstractTechnicalDEAModel end

"""
BootstrapRadialDEAModel
An data structure representing a bootstrap radial DEA model.
"""
struct BootstrapRadialDEAModel <: AbstractBootstrapDEAModel
    n::Int64
    m::Int64
    s::Int64
    orient::Symbol
    rts::Symbol
    disposX::Symbol
    disposY::Symbol
    dmunames::Union{Vector{AbstractString},Nothing}
    eff::Vector
    effref::Vector
    effbias::Vector
    effB::Matrix
    h::Float64
end

"""
    deaboot(X, Y)
Compute the bootstrap radial model using data envelopment analysis for inputs X and outputs Y.

# Optional Arguments
- `nreps=200`: number of bootstrap replications.
- `rng=default_rng()`: random number generator.
- `orient=:Input`: chooses the radially oriented input mode. For the radially oriented output model choose `:Output`.
- `rts=:CRS`: chooses constant returns to scale. For variable returns to scale choose `:VRS`.
- `Xref=X`: Identifies the reference set of inputs against which the units are evaluated.
- `Yref=Y`: Identifies the reference set of outputs against which the units are evaluated.
- `disposX=:Strong`: chooses strong disposability of inputs. For weak disposability choose `:Weak`.
- `disposY=:Strong`: chooses strong disposability of outputs. For weak disposability choose `:Weak`.
- `names`: a vector of strings with the names of the decision making units.
"""
function deaboot(X::Union{Matrix,Vector}, Y::Union{Matrix,Vector};
    nreps::Int = 200, rng::AbstractRNG = default_rng(), effref::Union{Vector,Nothing} = nothing,
    orient::Symbol = :Input, rts::Symbol = :CRS,
    Xref::Union{Matrix,Vector,Nothing} = nothing, Yref::Union{Matrix, Vector,Nothing} = nothing,
    disposX::Symbol = :Strong, disposY::Symbol = :Strong,
    names::Union{Vector{<: AbstractString},Nothing} = nothing,
    optimizer::Union{DEAOptimizer,Nothing} = nothing, progress::Bool = false)::BootstrapRadialDEAModel

    # Check parameters
    nx, m = size(X, 1), size(X, 2)
    ny, s = size(Y, 1), size(Y, 2)

    if Xref === nothing Xref = X end
    if Yref === nothing Yref = Y end

    nrefx, mref = size(Xref, 1), size(Xref, 2)
    nrefy, sref = size(Yref, 1), size(Yref, 2)

    if nx != ny
        throw(DimensionMismatch("number of rows in X and Y ($nx, $ny) are not equal"));
    end
    if nrefx != nrefy
        throw(DimensionMismatch("number of rows in Xref and Yref ($nrefx, $nrefy) are not equal"));
    end
    if m != mref
        throw(DimensionMismatch("number of columns in X and Xref ($m, $mref) are not equal"));
    end
    if s != sref
        throw(DimensionMismatch("number of columns in Y and Yref ($s, $sref) are not equal"));
    end

    if disposX != :Strong && disposX != :Weak
        throw(ArgumentError("`disposX` must be :Strong or :Weak"));
    end

    if disposY != :Strong && disposY != :Weak
        throw(ArgumentError("`disposY` must be :Strong or :Weak"));
    end

    # Default optimizer
    if optimizer === nothing 
        optimizer = DEAOptimizer(:LP)
    end

    # Radial DEA Model
    n = nx

    if isnothing(effref)
        effref = efficiency(dea(X, Y, orient = orient, rts = rts, slack = false, 
            Xref = Xref, Yref = Yref, disposX = disposX, disposY = disposY, optimizer = optimizer))
    end

    h = dea_bandwidth(effref, orient)

    if orient == :Input
        effi = 1 ./ deepcopy(effref)
    else
        effi = deepcopy(effref)
    end

    # Boostrap replications
    effB = SharedMatrix{Float64}(n, nreps)
    fill!(effB, 0.0)

    rng2 = deepcopy(rng)
    eff2m = [2 .- effi; effi]

    sampB = zeros(n, nreps)
    randB = zeros(n, nreps)
    for b in 1:nreps
        sampB[:, b] = sample(rng, eff2m, n, replace = true)
        randB[:, b] = rand(rng2, Normal(0, 1), n);
    end
    
    p = progressbarmeter(nreps, desc = "Computing Bootsrap Radial DEA Model...", progress = progress)

    @sync @distributed for b in 1:nreps
        # 1. Get a sample from the 2m set
        effn = sampB[:, b]

        # 2. Perturbate
        effn_star = effn + h .* randB[:,b]

        # 3. Refine and correct for the mean and variance of smoothed values
        effn_star = mean(effn) .+ (effn .- mean(effn)) ./ (sqrt( 1 + h^2 / var(eff2m)));

        # 4 .Reflect values
        effn_starr = effn_star
        effn_starr[effn_star .< 1] = 2 .- effn_star[effn_star .< 1]

        # Generate inefficient inputs or outputs and perform DEA
        if orient == :Input
            effn_starr = 1 ./ effn_starr
            Xrefb = repeat(effref ./ effn_starr, 1, m) .* Xref
            Yrefb = Yref
        else
            Xrefb = Xref
            Yrefb = repeat(effref ./ effn_starr, 1, s) .* Yref
        end

        effB[:, b] = efficiency(dea(X, Y, orient = orient, rts = rts, slack = false, 
            Xref = Xrefb, Yref = Yrefb, disposX = disposX, disposY = disposY, optimizer = optimizer))

        if orient == :Input
            effB[:, b] = 1 ./ effB[:, b]
        end

        next!(p)
    end

    # Bootstrap efficiency
    effbias = vec(mean(effB, dims = 2) .- effi)
    effbc = vec(effi .- effbias)

    # Invert if input oriented
    if orient == :Input
        effB = 1 ./ effB
        effbc = 1 ./ effbc
        effbias = effref .- effbc
    end

    return BootstrapRadialDEAModel(n, m, s, orient, rts, disposX, disposY, names, effbc, effref, effbias, effB, h)

end

function dea_bandwidth(x::Vector{Float64}, orient::Symbol)::Float64
    # Get only inefficient units
    effn = x[.! isapprox.(x, 1.0, atol = 1e-5)]

    n = length(x)
    m = length(effn)

    # Build the 2m set (reflected data)
    eff2m = [2 .- effn; effn]
    
    s2m = std(eff2m)
    r2m = iqr(eff2m)

    # Compute the optimmal bandwidth (After equation 3.24)
    hm = 0.9 * minimum([s2m, r2m ./ 1.349]) * (2 * m)^(-1/5);

    # Adjust bandwidth for scale and sample size (Equation 3.26) 
    if orient == :Input
        sx = std( 1 ./ x)
    else
        sx = std(x)
    end

    h = hm * ((2 * m) / n)^(1/5) * (sx / s2m ); 

    return h
end

"""
    confint(model::BootstrapRadialDEAModel; level::Real=0.95)
Compute confidence intervals for efficiency scores, with confidence level `level` (by default 95%).
"""
function confint(model::BootstrapRadialDEAModel; level::Real=0.95)
    n = nobs(model)
    orient = model.orient
    effref = model.effref
    effB = model.effB
    alpha = 1 - level

    effc = zeros(n, 2)
    for i in 1:n
        if orient == :Input
            effc[i, 1:2] = (1 ./ effref[i]) .+ quantile(( 1 ./ effref[i]) .- (1 ./ effB[i,:]), [0.5 * alpha, 1 - 0.5 * alpha])
        else
            effc[i, 1:2] = effref[i] .+ quantile(effref[i] .- effB[i,:], [0.5 * alpha, 1 - 0.5 * alpha])
        end
    end

    if orient == :Input
        effc = 1 ./ effc
        effc = effc[:, [2, 1]]
    end

    return effc
end

"""
    bandwidth(model::BootstrapRadialDEAModel)
Return the optimal bandwidth of a bootstrap DEA model.
"""
function bandwidth(model::BootstrapRadialDEAModel)
    return model.h
end

"""
    bias(model::BootstrapRadialDEAModel)
Return the bias from bootstrap DEA model.
"""
function bias(model::BootstrapRadialDEAModel)
    return model.effbias
end

function Base.show(io::IO, x::BootstrapRadialDEAModel)
    compact = get(io, :compact, false)

    n = nobs(x)
    m = ninputs(x)
    s = noutputs(x)
    disposX = x.disposX
    disposY = x.disposY
    dmunames = names(x)

    effref = x.effref
    eff = efficiency(x)
    effbias = bias(x)
    effc = confint(x, level = 0.95)
    effL = effc[:, 1]
    effU = effc[:, 2]

    if !compact
        print(io, "Bootstrap Radial DEA Model \n")
        print(io, "DMUs = ", n)
        print(io, "; Inputs = ", m)
        print(io, "; Outputs = ", s)
        print(io, "\n")
        print(io, "Orientation = ", string(x.orient))
        print(io, "; Returns to Scale = ", string(x.rts))
        print(io, "\n")
        print(io, "Bootstrap replications = ", size(x.effB, 2))
        print(io, "\n")
        if disposX == :Weak print(io, "Weak disposability of inputs \n") end
        if disposY == :Weak print(io, "Weak disposability of outputs \n") end

        show(io, CoefTable(hcat(effref, eff, effbias, effL, effU), ["Reference", "Corrected", "Bias", "Lower 95%", "Upper 95%"], dmunames))   
        
        print(io, "\nBandwidth = ", round(x.h, digits = 5))
    end

end

back to top

Software Heritage — Copyright (C) 2015–2025, The Software Heritage developers. License: GNU AGPLv3+.
The source code of Software Heritage itself is available on our development forge.
The source code files archived by Software Heritage are available under their own copyright and licenses.
Terms of use: Archive access, API— Contact— JavaScript license information— Web API