-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUKrig2.jl
82 lines (67 loc) · 2.21 KB
/
UKrig2.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
module UKrig2
using SpecialFunctions: besselk, gamma
import DynamicPolynomials: @polyvar, monomials
using FixedPolynomials
using LinearAlgebra
using Statistics
using Random
export Mnu, Gnu, generate_Gnu_krigY
tν𝒦t(t,ν) = t^ν * besselk(ν, t)
function Mnu(t, ν)::Float64
pt, pν, p0, p1 = promote(t, ν, Float64(0), Float64(1)) # note besselk always returns a Float64 apparently
return (pt==p0) ? p1 : tν𝒦t(√(2pν)*pt,pν) * 2^(1-pν) / gamma(pν)
end
# the const on the principle irregular term
scν(ν) = - (2ν)^ν * gamma(ν + 1//2) * gamma(1-ν) / gamma(2ν+1) / sqrt(π)
scν(ν::Int) = - 2 * (-2ν)^ν * gamma(ν + 1//2) / gamma(ν) / gamma(2ν+3) / sqrt(π)
function Gnu(t::T, ν::Int) where T<:Real
if t==0
return T(0)
end
return scν(ν) * t^(2ν) * log(t)
end
# Gnu(t::T, ν) where T<:Real = scν(ν) * t^(2ν)
function Gnu(t::T, ν) where T<:Real
return scν(ν) * t^(2ν)
end
"""
`generate_Gnu_krigY(;fdata, xdata, ν, σg, σε) -> (x::Array->krigY(x), x::Array->fp(x'), b, c)`
"""
function generate_Gnu_krigY(Ydata,Xdata1,Xdata2,Xdata3, ν)
m = 7
n₁ = length(Xdata1)
#kriging matrix F
@polyvar x y z
p = 1 + x + y + x^2 + y^2 + x * y + z
F = [t(x => vx,y => vy,z => vz) for (vx, vy,vz) in zip(Xdata1,Xdata2,Xdata3), t in p]
#distance matrix and Gnu
dist_mat = sqrt.(norm.( (Xdata1.-Xdata1') .^ 2 + (Xdata2 .- Xdata2') .^ 2) )
Gnu_mat = Gnu.(dist_mat, ν) |> Symmetric
#generat e the nullspace of F
Mᵀ = nullspace(F')
M = transpose(Mᵀ)
#pre-compute matrix
Mat₁ = Symmetric(M * Gnu_mat * Mᵀ)
Mat₂ = Symmetric(M * Mᵀ)
Ydata_M = M * Ydata
function KrigY(σg,σε,X1,X2,X3)
G₁₁ = (σg^2) .* Gnu_mat
Ξ = [
G₁₁ .+ σε^2*I(n₁) F
F' zeros(m,m)
]
cb = Ξ \ vcat(Ydata, zeros(m))
c = cb[1:length(Ydata)]
b = cb[length(Ydata)+1:end]
K= (σg^2) .* Gnu.( sqrt.(norm.( (X1 .- Xdata1') .^ 2 + (X2 .- Xdata2') .^ 2) ) , ν)
FF = [t(x => vx,y => vy,z => vz) for (vx,vy,vz) in zip(X1,X2,X3), t in p]
return K * c .+ FF * b
end
function loglike(σg,σε)
Σ₁ = σg ^ 2 * Mat₁ + σε ^ 2 * Mat₂
ch = cholesky(Σ₁)
return -1 / 2 * sum( (ch.L \ (Ydata_M)) .^ 2) - sum(log.(diag(ch.L)))
end
return KrigY, loglike
end
end