Hey,
In Copulas.jl, I want to compute the measure a copula assignes to a hyperbox [u,v].
Basically, the following function is doing what i want :
using Copulas
# Based on Computing the {{Volume}} of {\emph{n}} -{{Dimensional Copulas}}, Cherubini & Romagnoli 2009
function measure(C::CT, u,v) where CT<: Copulas.Copula
# u and v should both have the same length as C;
# u[i] < v[i] for all i is also assumed.
for i in eachindex(u)
if u[i] >= v[i]
return 0.0
end
end
# We need to compute the value of the cdf at each corner of the hypercube [u,v]
eval_pt = similar(u)
d = length(C)
dgts = zeros(Int64,d)
r = zero(eltype(u))
for i in 1:2^d
k_i = 0
dgts .= digits(i-1,base=2,pad=d)
for k in 1:d
if dgts[k] == 1
eval_pt[k] = u[k]
else
eval_pt[k] = v[k]
k_i += 1
end
end
r += (-1)^k_i * Copulas.cdf(C,eval_pt)
end
return r
end
C= ClaytonCopula(4,7.0)
u = zeros(4).+0.25
v = ones(4).-0.25
measure(C,u,v)
But it is quite slow. The function has to loop through all binary sequences of length d
, corresponding to the numbers i
in the loops. I have a feeling the allocation of dgts
is not needed and that the loops can be made smarters. Basically the test if dgts[k] == 1
could be transform on a test directly on i
and k
but i cannot find the right expression.
Thoughts ?