https://github.com/javierbarbero/DataEnvelopmentAnalysis.jl
Tip revision: 0b9c5e92e48d430ca014a0dcd24001cf1d12f5dc authored by Javier Barbero on 02 October 2019, 22:04:05 UTC
Add compatibility to project file
Add compatibility to project file
Tip revision: 0b9c5e9
deacost.jl
# This file contains functions for the Cost Efficiency DEA model
"""
CostDEAModel
An data structure representing a cost DEA model.
"""
struct CostDEAModel <: AbstractEconomicDEAModel
n::Int64
m::Int64
s::Int64
rts::Symbol
eff::Vector
lambda::SparseMatrixCSC{Float64, Int64}
techeff::Vector
alloceff::Vector
end
"""
deacost(X, Y, W)
Compute cost efficiency using data envelopment analysis for
inputs `X`, outputs `Y` and price of inputs `W`.
# Optional Arguments
- `rts=:CRS`: chooses variable returns to scale. For constant returns to scale choose `:CRS`.
# Examples
```jldoctest
julia> X = [5 3; 2 4; 4 2; 4 8; 7 9.0];
julia> Y = [7 4; 10 8; 8 10; 5 4; 3 6.0];
julia> W = [2 1; 2 1; 2 1; 2 1; 2 1.0];
julia> deacost(X, Y, W)
Cost DEA Model
DMUs = 5; Inputs = 2; Outputs = 2
Orientation = Input; Returns to Scale = VRS
──────────────────────────────────
Cost Technical Allocative
──────────────────────────────────
1 0.615385 0.75 0.820513
2 1.0 1.0 1.0
3 1.0 1.0 1.0
4 0.5 0.5 1.0
5 0.347826 0.375 0.927536
──────────────────────────────────
```
"""
function deacost(X::Matrix, Y::Matrix, W::Matrix; rts::Symbol = :VRS)::CostDEAModel
# Check parameters
nx, m = size(X)
ny, s = size(Y)
nw, mw = size(W)
if nx != ny
error("number of observations is different in inputs and outputs")
end
if nw != nx
error("number of observations is different in input prices and inputs")
end
if mw != m
error("number of input prices and intputs is different")
end
# Compute efficiency for each DMU
n = nx
Xefficient = zeros(n,m)
cefficiency = zeros(n)
clambdaeff = spzeros(n, n)
for i=1:n
# Value of inputs and outputs to evaluate
y0 = Y[i,:]
w0 = W[i,:]
# Create the optimization model
deamodel = Model(with_optimizer(GLPK.Optimizer))
@variable(deamodel, Xeff[1:m])
@variable(deamodel, lambda[1:n] >= 0)
@objective(deamodel, Min, sum(w0[j] .* Xeff[j] for j in 1:m))
@constraint(deamodel, [j in 1:m], sum(X[t,j] * lambda[t] for t in 1:n) <= Xeff[j])
@constraint(deamodel, [j in 1:s], sum(Y[t,j] * lambda[t] for t in 1:n) >= y0[j])
# Add return to scale constraints
if rts == :CRS
# No contraint to add for constant returns to scale
elseif rts == :VRS
@constraint(deamodel, sum(lambda) == 1)
else
error("Invalid returns to scale $rts. Returns to scale should be :CRS or :VRS")
end
# Optimize and return results
JuMP.optimize!(deamodel)
Xefficient[i,:] = JuMP.value.(Xeff)
clambdaeff[i,:] = JuMP.value.(lambda)
end
# Cost, technical and allocative efficiency
cefficiency = vec( sum(W .* Xefficient, dims = 2) ./ sum(W .* X, dims = 2) )
techefficiency = efficiency(dea(X, Y, orient = :Input, rts = rts, slack = false))
allocefficiency = cefficiency ./ techefficiency
return CostDEAModel(n, m, s, rts, cefficiency, clambdaeff, techefficiency, allocefficiency)
end
function deacost(X::Vector, Y::Matrix, W::Vector, rts::Symbol = :VRS)::CostDEAModel
X = X[:,:]
W = W[:,:]
return deacost(X, Y, W, rts = rts)
end
function deacost(X::Matrix, Y::Vector, W::Matrix; rts::Symbol = :VRS)::CostDEAModel
Y = Y[:,:]
return deacost(X, Y, W, rts = rts)
end
function deacost(X::Vector, Y::Vector, W::Vector; rts::Symbol = :VRS)::CostDEAModel
X = X[:,:]
W = W[:,:]
Y = Y[:,:]
return deacost(X, Y, W, rts = rts)
end
function Base.show(io::IO, x::CostDEAModel)
compact = get(io, :compact, false)
n = nobs(x)
m = ninputs(x)
s = noutputs(x)
eff = efficiency(x)
techeff = efficiency(x, :Technical)
alloceff = efficiency(x, :Allocative)
if !compact
print(io, "Cost DEA Model \n")
print(io, "DMUs = ", n)
print(io, "; Inputs = ", m)
print(io, "; Outputs = ", s)
print(io, "\n")
print(io, "Orientation = Input")
print(io, "; Returns to Scale = ", string(x.rts))
print(io, "\n")
show(io, CoefTable(hcat(eff, techeff, alloceff), ["Cost", "Technical", "Allocative"], ["$i" for i in 1:n]))
else
end
end