/
deaprofitholder.jl
147 lines (124 loc) · 4.57 KB
/
deaprofitholder.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# This file contains functions for the Profit Efficiency Hölder DEA model
"""
ProfitHolderDEAModel
An data structure representing a profit SBM DEA model.
"""
struct ProfitHolderDEAModel <: AbstractProfitDEAModel
n::Int64
m::Int64
s::Int64
l::Union{Int64,Float64}
isweighted::Bool
monetary::Bool
dmunames::Union{Vector{String},Nothing}
eff::Vector
lambda::SparseMatrixCSC{Float64, Int64}
techeff::Vector
alloceff::Vector
normalization::Vector
Xtarget::Matrix
Ytarget::Matrix
end
"""
deaprofitholder(X, Y, W, P; l)
Compute profit efficiency using data envelopment analysis Hölder model for
inputs `X`, outputs `Y`, price of inputs `W`, and price of outputs `P`.
# Hölder norm `l` specification
- `1`.
- `2`.
- `Inf`.
# Optional Arguments
- `weigt=false`: set to `true` for weighted (weakly) Hölder distance function.
- `monetary=false`: decomposition in normalized terms. Monetary terms if `true`.
- `names`: a vector of strings with the names of the decision making units.
"""
function deaprofitholder(X::Union{Matrix,Vector}, Y::Union{Matrix,Vector},
W::Union{Matrix,Vector}, P::Union{Matrix,Vector};
l::Union{Int64,Float64}, weight::Bool = false, monetary::Bool = false,
names::Union{Vector{<: AbstractString},Nothing} = nothing,
optimizer::Union{DEAOptimizer,Nothing} = nothing)::ProfitHolderDEAModel
# Check parameters
nx, m = size(X, 1), size(X, 2)
ny, s = size(Y, 1), size(Y, 2)
nw, mw = size(W, 1), size(W, 2)
np, sp = size(P, 1), size(P, 2)
if nx != ny
throw(DimensionMismatch("number of rows in X and Y ($nx, $ny) are not equal"));
end
if nw != nx
throw(DimensionMismatch("number of rows in W and X ($nw, $nx) are not equal"));
end
if np != ny
throw(DimensionMismatch("number of rows in P and Y ($np, $ny) are not equal"));
end
if mw != m
throw(DimensionMismatch("number of columns in W and X ($mw, $m) are not equal"));
end
if sp != s
throw(DimensionMismatch("number of columns in P and Y ($sp, $s) are not equal"));
end
if l != 1 && l != 2 && l != Inf
throw(ArgumentError("l must by :1, :2, or :Inf"));
end
# Default optimizer
if optimizer === nothing
optimizer = DEAOptimizer(:LP)
end
# Get maximum profit targets and lambdas
n = nx
Xtarget, Ytarget, plambdaeff = deamaxprofit(X, Y, W, P, optimizer = optimizer)
# Profit, technical and allocative efficiency
maxprofit = sum(P .* Ytarget, dims = 2) .- sum(W .* Xtarget, dims = 2)
pefficiency = vec(maxprofit .- ( sum(P .* Y, dims = 2) .- sum(W .* X, dims = 2)))
if weight
if l == 1
normalization = maximum([(P .* Y) (W .* X)], dims = 2)
elseif l == 2
normalization = sqrt.(sum((P .* Y).^2, dims = 2) .+ sum((W .* X).^2, dims = 2))
elseif l == Inf
normalization = sum(P .* Y, dims = 2) .+ sum(W .* X, dims = 2)
end
else
if l == 1
normalization = maximum([P W], dims = 2)
elseif l == 2
normalization = sqrt.(sum(P.^2, dims = 2) .+ sum(W.^2, dims = 2))
elseif l == Inf
normalization = sum(P, dims = 2) .+ sum(W, dims = 2)
end
end
normalization = vec(normalization)
techefficiency = efficiency(deaholder(X, Y, l = l, weight = weight, orient = :Graph, rts = :VRS, slack = false, optimizer = optimizer))
if monetary
techefficiency = techefficiency .* normalization
else
pefficiency = pefficiency ./ normalization
end
allocefficiency = pefficiency - techefficiency
return ProfitHolderDEAModel(n, m, s, l, weight, monetary, names, pefficiency, plambdaeff, techefficiency, allocefficiency, normalization, Xtarget, Ytarget)
end
function Base.show(io::IO, x::ProfitHolderDEAModel)
compact = get(io, :compact, false)
n = nobs(x)
m = ninputs(x)
s = noutputs(x)
l = x.l
isweighted = x.isweighted
dmunames = names(x)
eff = efficiency(x)
techeff = efficiency(x, :Technical)
alloceff = efficiency(x, :Allocative)
if !compact
print(io, "Profit Hölder L", string(l), " DEA Model \n")
print(io, "DMUs = ", n)
print(io, "; Inputs = ", m)
print(io, "; Outputs = ", s)
print(io, "\n")
print(io, "Returns to Scale = VRS")
print(io, "\n")
if isweighted
print(io, "Weighted (weakly) Hölder distance function \n")
end
show(io, CoefTable(hcat(eff, techeff, alloceff), ["Profit", "Technical", "Allocative"], dmunames))
end
end