Skip to content

Commit

Permalink
Add testsets (#83)
Browse files Browse the repository at this point in the history
add testsets
  • Loading branch information
wildart committed Dec 21, 2018
1 parent 924cb34 commit 26dd9d1
Show file tree
Hide file tree
Showing 10 changed files with 935 additions and 902 deletions.
90 changes: 47 additions & 43 deletions test/cmds.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,58 +2,62 @@ using MultivariateStats
using LinearAlgebra
using Test

## testing data
@testset "MDS" begin

function pwdists(X)
S = sum(abs2, X, dims=1)
D2 = S .+ S' - 2 * (X'X)
D2[diagind(D2)] .= 0.0
return sqrt.(D2)
end
## testing data

X0 = randn(3, 5)
G0 = X0'X0
D0 = pwdists(X0)
function pwdists(X)
S = sum(abs2, X, dims=1)
D2 = S .+ S' - 2 * (X'X)
D2[diagind(D2)] .= 0.0
return sqrt.(D2)
end

## conversion between dmat and gram
X0 = randn(3, 5)
G0 = X0'X0
D0 = pwdists(X0)

@assert issymmetric(D0)
@assert issymmetric(G0)
## conversion between dmat and gram

D = gram2dmat(G0)
@test issymmetric(D)
@test D D0
@assert issymmetric(D0)
@assert issymmetric(G0)

G = dmat2gram(D0)
@test issymmetric(G)
@test gram2dmat(G) D0
D = gram2dmat(G0)
@test issymmetric(D)
@test D D0

## classical MDS
G = dmat2gram(D0)
@test issymmetric(G)
@test gram2dmat(G) D0

X = classical_mds(D0, 3)
@test pwdists(X) D0
## classical MDS

#Test MDS embeddings in dimensions >= number of points
@test classical_mds([0 1; 1 0], 2, dowarn=false) == [-0.5 0.5; 0 0]
@test classical_mds([0 1; 1 0], 3, dowarn=false) == [-0.5 0.5; 0 0; 0 0]
X = classical_mds(D0, 3)
@test pwdists(X) D0

#Test MDS embeddings in dimensions >= number of points
@test classical_mds([0 1; 1 0], 2, dowarn=false) == [-0.5 0.5; 0 0]
@test classical_mds([0 1; 1 0], 3, dowarn=false) == [-0.5 0.5; 0 0; 0 0]

#10 - dmat2gram produces negative definite matrix
let D = [1.0 0.5 0.3181818181818182 0.38095238095238093 0.6111111111111112 0.36363636363636365 0.3333333333333333 0.4444444444444444 0.45454545454545453 0.38095238095238093
0.5 1.0 0.3333333333333333 0.4166666666666667 0.32 0.37037037037037035 0.35 0.38461538461538464 0.38461538461538464 0.4
0.3181818181818182 0.3333333333333333 1.0 0.38095238095238093 0.125 0.22727272727272727 0.47058823529411764 0.35294117647058826 0.2608695652173913 0.21052631578947367
0.38095238095238093 0.4166666666666667 0.38095238095238093 1.0 0.17391304347826086 0.2962962962962963 0.38095238095238093 0.45454545454545453 0.3076923076923077 0.5454545454545454
0.6111111111111112 0.32 0.125 0.17391304347826086 1.0 0.5 0.15 0.391304347826087 0.38095238095238093 0.3333333333333333
0.36363636363636365 0.37037037037037035 0.22727272727272727 0.2962962962962963 0.5 1.0 0.2857142857142857 0.44 0.4 0.3181818181818182
0.3333333333333333 0.35 0.47058823529411764 0.38095238095238093 0.15 0.2857142857142857 1.0 0.42105263157894735 0.45 0.23529411764705882
0.4444444444444444 0.38461538461538464 0.35294117647058826 0.45454545454545453 0.391304347826087 0.44 0.42105263157894735 1.0 0.5416666666666666 0.5555555555555556
0.45454545454545453 0.38461538461538464 0.2608695652173913 0.3076923076923077 0.38095238095238093 0.4 0.45 0.5416666666666666 1.0 0.4
0.38095238095238093 0.4 0.21052631578947367 0.5454545454545454 0.3333333333333333 0.3181818181818182 0.23529411764705882 0.5555555555555556 0.4 1.0],
Xt = [-0.27529104101488666 0.006134513718202863 0.33298809606740326 0.2608994458893664 -0.46185275796909575 -0.23734315039370618 0.29972782027671513 0.03827901455843394 -0.04096713097883363 0.07742518984640051
-0.08177061420820278 -0.0044504235228030225 -0.3271919093638943 0.28206254638779243 -0.0954706915166714 -0.07137742126520012 -0.30754933764853587 0.18582658369448027 -0.03715307349750036 0.45707434094053534]',
M = classical_mds(D, 2)'
@test M Xt .* cis.(angle.(sum(conj.(Xt) .* M, dims=1)))
end

#10 - test degenerate problem
@test classical_mds(zeros(10, 10), 3, dowarn=false) == zeros(3, 10)
#10 - dmat2gram produces negative definite matrix
let D = [1.0 0.5 0.3181818181818182 0.38095238095238093 0.6111111111111112 0.36363636363636365 0.3333333333333333 0.4444444444444444 0.45454545454545453 0.38095238095238093
0.5 1.0 0.3333333333333333 0.4166666666666667 0.32 0.37037037037037035 0.35 0.38461538461538464 0.38461538461538464 0.4
0.3181818181818182 0.3333333333333333 1.0 0.38095238095238093 0.125 0.22727272727272727 0.47058823529411764 0.35294117647058826 0.2608695652173913 0.21052631578947367
0.38095238095238093 0.4166666666666667 0.38095238095238093 1.0 0.17391304347826086 0.2962962962962963 0.38095238095238093 0.45454545454545453 0.3076923076923077 0.5454545454545454
0.6111111111111112 0.32 0.125 0.17391304347826086 1.0 0.5 0.15 0.391304347826087 0.38095238095238093 0.3333333333333333
0.36363636363636365 0.37037037037037035 0.22727272727272727 0.2962962962962963 0.5 1.0 0.2857142857142857 0.44 0.4 0.3181818181818182
0.3333333333333333 0.35 0.47058823529411764 0.38095238095238093 0.15 0.2857142857142857 1.0 0.42105263157894735 0.45 0.23529411764705882
0.4444444444444444 0.38461538461538464 0.35294117647058826 0.45454545454545453 0.391304347826087 0.44 0.42105263157894735 1.0 0.5416666666666666 0.5555555555555556
0.45454545454545453 0.38461538461538464 0.2608695652173913 0.3076923076923077 0.38095238095238093 0.4 0.45 0.5416666666666666 1.0 0.4
0.38095238095238093 0.4 0.21052631578947367 0.5454545454545454 0.3333333333333333 0.3181818181818182 0.23529411764705882 0.5555555555555556 0.4 1.0],
Xt = [-0.27529104101488666 0.006134513718202863 0.33298809606740326 0.2608994458893664 -0.46185275796909575 -0.23734315039370618 0.29972782027671513 0.03827901455843394 -0.04096713097883363 0.07742518984640051
-0.08177061420820278 -0.0044504235228030225 -0.3271919093638943 0.28206254638779243 -0.0954706915166714 -0.07137742126520012 -0.30754933764853587 0.18582658369448027 -0.03715307349750036 0.45707434094053534]',
M = classical_mds(D, 2)'
@test M Xt .* cis.(angle.(sum(conj.(Xt) .* M, dims=1)))
end

#10 - test degenerate problem
@test classical_mds(zeros(10, 10), 3, dowarn=false) == zeros(3, 10)

end
158 changes: 81 additions & 77 deletions test/fa.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,106 +4,110 @@ using Test
import Statistics: mean, cov, var
import Random

Random.seed!(34568)
@testset "Factor Analysis" begin

## FA with zero mean
Random.seed!(34568)

X = randn(5, 10)
Y = randn(3, 10)
## FA with zero mean

W = qr(randn(5, 5)).Q[:, 1:3]
Ψ = fill(0.1, 5)
M = FactorAnalysis(Float64[], W, Ψ)
X = randn(5, 10)
Y = randn(3, 10)

@test indim(M) == 5
@test outdim(M) == 3
@test mean(M) == zeros(5)
@test loadings(M) == W
@test var(M) == Ψ
W = qr(randn(5, 5)).Q[:, 1:3]
Ψ = fill(0.1, 5)
M = FactorAnalysis(Float64[], W, Ψ)

T = inv(I+W'*diagm(0 => 1 ./ var(M))*W)*W'*diagm(0 => 1 ./ var(M))
@test transform(M, X[:,1]) T * X[:,1]
@test transform(M, X) T * X
@test indim(M) == 5
@test outdim(M) == 3
@test mean(M) == zeros(5)
@test loadings(M) == W
@test var(M) == Ψ

R = cov(M)*W*inv(W'W)
@test reconstruct(M, Y[:,1]) R * Y[:,1]
@test reconstruct(M, Y) R * Y
T = inv(I+W'*diagm(0 => 1 ./ var(M))*W)*W'*diagm(0 => 1 ./ var(M))
@test transform(M, X[:,1]) T * X[:,1]
@test transform(M, X) T * X

R = cov(M)*W*inv(W'W)
@test reconstruct(M, Y[:,1]) R * Y[:,1]
@test reconstruct(M, Y) R * Y

## PCA with non-zero mean

mval = rand(5)
M = FactorAnalysis(mval, W, Ψ)
## PCA with non-zero mean

@test indim(M) == 5
@test outdim(M) == 3
@test mean(M) == mval
@test loadings(M) == W
@test var(M) == Ψ
mval = rand(5)
M = FactorAnalysis(mval, W, Ψ)

@test transform(M, X[:,1]) T * (X[:,1] .- mval)
@test transform(M, X) T * (X .- mval)
@test indim(M) == 5
@test outdim(M) == 3
@test mean(M) == mval
@test loadings(M) == W
@test var(M) == Ψ

@test reconstruct(M, Y[:,1]) R * Y[:,1] .+ mval
@test reconstruct(M, Y) R * Y .+ mval
@test transform(M, X[:,1]) T * (X[:,1] .- mval)
@test transform(M, X) T * (X .- mval)

@test reconstruct(M, Y[:,1]) R * Y[:,1] .+ mval
@test reconstruct(M, Y) R * Y .+ mval

## prepare training data

d = 5
n = 1000
## prepare training data

R = collect(qr(randn(d, d)).Q)
@test R'R Matrix(I, 5, 5)
rmul!(R, Diagonal(sqrt.([0.5, 0.3, 0.1, 0.05, 0.05])))
d = 5
n = 1000

X = R'randn(5, n) .+ randn(5)
mval = vec(mean(X, dims=2))
Z = X .- mval
R = collect(qr(randn(d, d)).Q)
@test R'R Matrix(I, 5, 5)
rmul!(R, Diagonal(sqrt.([0.5, 0.3, 0.1, 0.05, 0.05])))

# facm (default) & faem
fa_methods = [:cm, :em]
X = R'randn(5, n) .+ randn(5)
mval = vec(mean(X, dims=2))
Z = X .- mval

fas = FactorAnalysis[]
for method in fa_methods
let M = fit(FactorAnalysis, X, method=method, maxiter=5000),
P = projection(M),
W = loadings(M)
push!(fas,M)
# facm (default) & faem
fa_methods = [:cm, :em]

@test indim(M) == 5
@test outdim(M) == 4
@test mean(M) == mval
@test P'P Matrix(I, 4, 4)
@test all(isapprox.(cov(M), cov(X, dims=2), atol=1e-3))
fas = FactorAnalysis[]
for method in fa_methods
let M = fit(FactorAnalysis, X, method=method, maxiter=5000),
P = projection(M),
W = loadings(M)
push!(fas,M)

M = fit(FactorAnalysis, X; mean=mval, method=method)
@test loadings(M) W
@test indim(M) == 5
@test outdim(M) == 4
@test mean(M) == mval
@test P'P Matrix(I, 4, 4)
@test all(isapprox.(cov(M), cov(X, dims=2), atol=1e-3))

M = fit(FactorAnalysis, Z; mean=0, method=method)
@test loadings(M) W
M = fit(FactorAnalysis, X; mean=mval, method=method)
@test loadings(M) W

M = fit(FactorAnalysis, X; maxoutdim=3, method=method)
P = projection(M)
M = fit(FactorAnalysis, Z; mean=0, method=method)
@test loadings(M) W

@test indim(M) == 5
@test outdim(M) == 3
@test P'P Matrix(I, 3, 3)
M = fit(FactorAnalysis, X; maxoutdim=3, method=method)
P = projection(M)

@test indim(M) == 5
@test outdim(M) == 3
@test P'P Matrix(I, 3, 3)
end
end
end

# compare two algorithms
M1, M2 = fas
@test all(isapprox.(cov(M1), cov(M2), atol=1e-3)) # noise
LL(m, x) = (-size(x,2)/2)*(size(x,1)*log(2π) + log(det(cov(m))) + tr(inv(cov(m))*cov(x, dims=2)))
@test LL(M1, X) LL(M2, X) # log likelihood

# test that fit works with Float32 values
X2 = convert(Array{Float32,2}, X)
# Float32 input
M = fit(FactorAnalysis, X2; method=:cm, maxoutdim=3)
M = fit(FactorAnalysis, X2; method=:em, maxoutdim=3)

# views
M = fit(FactorAnalysis, view(X2, :, 1:100), method=:cm, maxoutdim=3)
M = fit(FactorAnalysis, view(X2, :, 1:100), method=:em, maxoutdim=3)
# compare two algorithms
M1, M2 = fas
@test all(isapprox.(cov(M1), cov(M2), atol=1e-3)) # noise
LL(m, x) = (-size(x,2)/2)*(size(x,1)*log(2π) + log(det(cov(m))) + tr(inv(cov(m))*cov(x, dims=2)))
@test LL(M1, X) LL(M2, X) # log likelihood

# test that fit works with Float32 values
X2 = convert(Array{Float32,2}, X)
# Float32 input
M = fit(FactorAnalysis, X2; method=:cm, maxoutdim=3)
M = fit(FactorAnalysis, X2; method=:em, maxoutdim=3)

# views
M = fit(FactorAnalysis, view(X2, :, 1:100), method=:cm, maxoutdim=3)
M = fit(FactorAnalysis, view(X2, :, 1:100), method=:em, maxoutdim=3)

end
Loading

0 comments on commit 26dd9d1

Please sign in to comment.