#-------------------------------------------------------------------------
function calculatekernelmatrix(X, Y, k, hyper)
#-------------------------------------------------------------------------

    K = zeros(length(X), length(Y))

    calculatekernelmatrix!(K, X, Y, k, hyper)

    return K

end

#-------------------------------------------------------------------------
function calculatekernelmatrix!(K, X, Y, k, hyper)
#-------------------------------------------------------------------------
    @assert(size(K, 1) == length(X))
    @assert(size(K, 2) == length(Y))

    # calculate kernel matrix
    for (i, xᵢ) in enumerate(X), (j, xⱼ) in enumerate(Y)
        @inbounds K[i,j] = k(xᵢ, xⱼ, hyper) + ((i==j) ? 1e-12 : 0.0)
    end
end


#-------------------------------------------------------------------------
function calculatekernelmatrix!(K, dist2, k, hyper)
#-------------------------------------------------------------------------
    @assert(size(K, 1) == size(dist2, 1))
    @assert(size(K, 2) == size(dist2, 2))

    copyto!(K, k(dist2, hyper))

    nothing
end



#-------------------------------------------------------------------------
function rbf(xᵢ, xⱼ, hyper)
#-------------------------------------------------------------------------
    makepos(hyper[1]) * exp(-0.5 * makepos(hyper[2]) * (xᵢ-xⱼ)^2)
end

#-------------------------------------------------------------------------
function rbf(dist2, hyper)
#-------------------------------------------------------------------------
    makepos(hyper[1]) .* exp.(-0.5 .* makepos(hyper[2]) .* dist2)
end



#-------------------------------------------------------------------------
function OU(xᵢ, xⱼ, hyper)
#-------------------------------------------------------------------------
    makepos(hyper[1]) * exp(-0.5 * makepos(hyper[2]) * abs(xᵢ-xⱼ))
end

#-------------------------------------------------------------------------
function OU(dist2, hyper)
#-------------------------------------------------------------------------
    makepos(hyper[1]) .* exp.(-0.5 .* makepos(hyper[2]) .* sqrt.(dist2))
end


#-------------------------------------------------------------------------
function makepos(x)
#-------------------------------------------------------------------------
    exp(x)
end
