Skip to content

Commit

Permalink
v0.9.2 experimental spatial exp, internal changes, no varlink for not…
Browse files Browse the repository at this point in the history
…- var, rho parameters
  • Loading branch information
PharmCat committed May 29, 2021
1 parent 80161c6 commit 5327fc1
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 26 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Metida"
uuid = "a1dec852-9fe5-11e9-361f-8d9fde67cfa2"
authors = ["Vladimir Arnautov <[email protected]>"]
version = "0.9.1"
version = "0.9.2"

[deps]
CategoricalArrays = "324d7699-5711-5eae-9e2f-1d82baa6b597"
Expand Down
1 change: 1 addition & 0 deletions change.log
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
v0.9.2
* z matrix for random effect
* contain ddf
* Experimental Spatial Exponential repeated structure

v0.9.1
* update deps
Expand Down
5 changes: 5 additions & 0 deletions docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ Metida.HeterogeneousToeplitz
Metida.HeterogeneousToeplitzParameterized
```

### Metida.SpatialExponential
```@docs
Metida.SpatialExponential
```

### Metida.anova
```@docs
Metida.anova
Expand Down
6 changes: 4 additions & 2 deletions src/fit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,11 @@ function fit!(lmm::LMM{T};
end
else
initθ = sqrt(initvar(lmm.data.yv, lmm.mm.m)[1])/(length(lmm.covstr.random)+1)
θ .= initθ
#θ .= initθ
for i = 1:length(θ)
if lmm.covstr.ct[i] == :rho
if lmm.covstr.ct[i] == :var
θ[i] = initθ
elseif lmm.covstr.ct[i] == :rho
θ[i] = 1e-4
end
end
Expand Down
34 changes: 34 additions & 0 deletions src/rmat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ function rmat_base_inc_b!(mx, θ, zrv, covstr)
rmatp_toephp!(mx, θ, zrv, covstr.repeated.covtype.p)
elseif covstr.repeated.covtype.s == :FUNC
covstr.repeated.covtype.p.xmat!(mx, θ, zrv, covstr.repeated.covtype.p)
elseif covstr.repeated.covtype.s == :SPEXP
rmatp_spexp!(mx, θ, zrv, covstr.repeated.covtype.p)
end
end
################################################################################
Expand Down Expand Up @@ -161,3 +163,35 @@ function rmatp_toephp!(mx, θ, rz, p)
end
nothing
end
################################################################################
function edistance(i::AbstractVector{T1}, j::AbstractVector{T2}) where T1 where T2
sum = zero(promote_type(T1, T2))
for c = 1:length(i)
sum += (i[c]-j[c])^2
end
return sqrt(sum)
end
function edistance(mx::AbstractMatrix{T}, i::Int, j::Int) where T
sum = zero(T)
for c = 1:size(mx, 2)
sum += (mx[i,c] - mx[j,c])^2
end
return sqrt(sum)
end
################################################################################
function rmatp_spexp!(mx, θ, rz, p)
σ² = θ[1]^2
θ = exp(θ[2])
rn = size(mx, 1)
@inbounds @simd for i = 1:size(mx, 1)
mx[i, i] += σ²
end
if rn > 1
for m = 1:rn - 1
@inbounds @simd for n = m + 1:rn
mx[m, n] += σ² * exp(-edistance(rz, m, n) / θ)
end
end
end
nothing
end
10 changes: 6 additions & 4 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ function varlinkvecapply!(v, p; varlinkf = :exp, rholinkf = :sigm)
for i = 1:length(v)
if p[i] == :var
v[i] = vlink(v[i])
else
elseif p[i] == :rho
if rholinkf == :sigm
v[i] = rholinksigmoid(v[i])
elseif rholinkf == :atan
Expand All @@ -88,7 +88,7 @@ function varlinkrvecapply!(v, p; varlinkf = :exp, rholinkf = :sigm)
for i = 1:length(v)
if p[i] == :var
v[i] = vlinkr(v[i])
else
elseif p[i] == :rho
if rholinkf == :sigm
v[i] = rholinksigmoidr(v[i])
elseif rholinkf == :atan
Expand All @@ -107,7 +107,7 @@ function varlinkvecapply(v, p; varlinkf = :exp, rholinkf = :sigm)
for i = 1:length(v)
if p[i] == :var
s[i] = vlink(v[i])
else
elseif p[i] == :rho
if rholinkf == :sigm
s[i] = rholinksigmoid(v[i])
elseif rholinkf == :atan
Expand All @@ -117,6 +117,8 @@ function varlinkvecapply(v, p; varlinkf = :exp, rholinkf = :sigm)
elseif rholinkf == :psigm
s[i] = rholinkpsigmoid(v[i])
end
else
s[i] = v[i]
end
end
s
Expand All @@ -126,7 +128,7 @@ function m2logreml(lmm)
lmm.result.reml
end
function logreml(lmm)
-m2logreml(lmm)/2.
-m2logreml(lmm)/2
end
################################################################################

Expand Down
62 changes: 43 additions & 19 deletions src/varstruct.jl
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,27 @@ function HeterogeneousToeplitzParameterized(p::Int)
end
const TOEPHP(p) = HeterogeneousToeplitzParameterized(p)

"""
SpatialExponential()
!!! warning
Experimental
Spatian Exponential covariance structure. Used only for repeated effect.
```math
R_{i,j} = \\sigma^{2} * exp(-dist(i,j)/exp(\\theta))
```
where `dist` - Euclidean distance between row-vector of repeated effect matrix for subject `i` and `j`.
SPEXP = SpatialExponential()
"""
function SpatialExponential()
CovarianceType(:SPEXP)
end
const SPEXP = SpatialExponential()
#Spatial Power ?
#=
"""
Expand Down Expand Up @@ -311,37 +332,39 @@ CovarianceType(cm::AbstractCovmatMethod) = CovarianceType(:FUNC, cm)

#CovarianceType(cmg::AbstractCovmatMethod, cmr::AbstractCovmatMethod) = FullCovarianceType(CovarianceType(:FUNC, cmg), CovarianceType(:FUNC, cmr))

function covstrparam(ct::CovarianceType, t::Int, q::Int)::Tuple{Int, Int}
function covstrparam(ct::CovarianceType, t::Int, q::Int)
if ct.s == :SI
return (1, 0)
return (1, 0, 0)
elseif ct.s == :DIAG
return (t, 0)
elseif ct.s == :VC
return (q, 0)
return (t, 0, 0)
#elseif ct.s == :VC
# return (q, 0, q)
elseif ct.s == :AR
return (1, 1)
return (1, 1, 0)
elseif ct.s == :ARH
return (t, 1)
return (t, 1, 0)
elseif ct.s == :ARMA
return (1, 2)
return (1, 2, 0)
elseif ct.s == :CS
return (1, 1)
return (1, 1, 0)
elseif ct.s == :CSH
return (t, 1)
return (t, 1, 0)
elseif ct.s == :TOEP
return (1, t - 1)
return (1, t - 1, 0)
elseif ct.s == :TOEPH
return (t, t - 1)
return (t, t - 1, 0)
elseif ct.s == :TOEPP
return (1, ct.p - 1)
return (1, ct.p - 1, 0)
elseif ct.s == :TOEPHP
return (t, ct.p - 1)
return (t, ct.p - 1, 0)
elseif ct.s == :UN
return (t, t * (t + 1) / 2 - t)
return (t, t * (t + 1) / 2 - t, 0)
elseif ct.s == :ZERO
return (0, 0)
return (0, 0, 0)
elseif ct.s == :FUNC
return ct.p.nparamf(t, q)
elseif ct.s == :SPEXP
return (1, 0, 1)
else
error("Unknown covariance type!")
end
Expand Down Expand Up @@ -467,7 +490,7 @@ struct CovStructure{T} <: AbstractCovarianceStructure
ztemp = modelcols(MatrixTerm(schema[i]), data)
q[i] = size(ztemp, 2)
csp = covstrparam(random[i].covtype, q[i], random[i].p)
t[i] = csp[1] + csp[2]
t[i] = sum(csp)
z = hcat(z, ztemp)
fillur!(zrndur, i, q)
fillur!(tr, i, t)
Expand All @@ -488,7 +511,7 @@ struct CovStructure{T} <: AbstractCovarianceStructure
sn[end] = size(subjz[end], 2)
q[end] = size(rz, 2)
csp = covstrparam(repeated.covtype, q[end], repeated.p)
t[end] = csp[1] + csp[2]
t[end] = sum(csp)
tr[end] = UnitRange(sum(t[1:end-1]) + 1, sum(t[1:end-1]) + t[end])
updatenametype!(ct, rcnames, csp, schema[end], repeated.covtype.s)
#Theta length
Expand Down Expand Up @@ -544,7 +567,8 @@ end
function updatenametype!(ct, rcnames, csp, schema, s)
append!(ct, fill!(Vector{Symbol}(undef, csp[1]), :var))
append!(ct, fill!(Vector{Symbol}(undef, csp[2]), :rho))
append!(rcnames, rcoefnames(schema, csp[1]+csp[2], s))
if length(csp) == 3 append!(ct, fill!(Vector{Symbol}(undef, csp[3]), :theta)) end
append!(rcnames, rcoefnames(schema, sum(csp), s))
end
################################################################################
function rcoefnames(s, t, ve)
Expand Down
8 changes: 8 additions & 0 deletions test/test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -429,3 +429,11 @@ end
@test iA iAss atol=1E-6
@test iAs iAb atol=1E-6
end

@testset " Experimental " begin
lmm = Metida.LMM(@formula(response ~ 1), ftdf;
repeated = Metida.VarEffect(Metida.@covstr(response+time|subject), Metida.SPEXP),
)
Metida.fit!(lmm)
@test Metida.m2logreml(lmm) 1528.7150702624508 atol=1E-6
end

2 comments on commit 5327fc1

@PharmCat
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register

v0.9.2

  • z matrix for random effect
  • contain ddf experimental
  • Experimental Spatial Exponential repeated structure

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/39015

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.9.2 -m "<description of version>" 5327fc156afe6c3bbc76f6b591625d86d8442a99
git push origin v0.9.2

Please sign in to comment.