From 636ee622dba86f39bf8a68d0973b3fe6f564667c Mon Sep 17 00:00:00 2001 From: dehann Date: Sun, 19 May 2024 02:42:02 -0700 Subject: [PATCH 1/4] multidim optim of manellic and test --- src/services/ManifoldKernelDensity.jl | 28 ++++++++++++-------- test/manellic/testManellicTree.jl | 37 ++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/src/services/ManifoldKernelDensity.jl b/src/services/ManifoldKernelDensity.jl index 998f7c2..43d51c4 100644 --- a/src/services/ManifoldKernelDensity.jl +++ b/src/services/ManifoldKernelDensity.jl @@ -119,21 +119,27 @@ function manikde!_manellic( ) # Cost function to optimize - _cost(_pts, σ) = begin - # avoid rebuilding tree at each optim iteration!!! - # mtr = buildTree_Manellic!(M, _pts; kernel_bw=reshape(σ,manifold_dimension(M),1), kernel=MvNormalKernel) - entropy(mtree,reshape(σ,manifold_dimension(M),1)) - end + # avoid rebuilding tree at each optim iteration!!! + _cost(σ) = entropy(mtree,diagm(σ.^2)) # reshape(σ,manifold_dimension(M),1)) # optimize for best LOOCV bandwidth # FIXME switch to RLM (or other Manopt) techinque instead # set lower and upper bounds for Golden section optimization - lcov, ucov = getBandwidthSearchBounds(mtree) - res = Optim.optimize( - (s)->_cost(pts,[s^2;]), - lcov[1], ucov[1], Optim.GoldenSection() - ) - best_cov = [Optim.minimizer(res);;] + best_cov = if 1 === manifold_dimension(M) + lcov, ucov = getBandwidthSearchBounds(mtree) + res = Optim.optimize( + (s)->_cost([s;]), + lcov[1], ucov[1], Optim.GoldenSection() + ) + [Optim.minimizer(res);;] + else + res = Optim.optimize( + _cost, + bw, + Optim.NelderMead() + ) + diagm(Optim.minimizer(res)) + end # reuse (heavy lift parts of) earlier tree build # return tree with correct bandwidth diff --git a/test/manellic/testManellicTree.jl b/test/manellic/testManellicTree.jl index 93d3506..339e9f6 100755 --- a/test/manellic/testManellicTree.jl +++ b/test/manellic/testManellicTree.jl @@ -732,6 +732,8 @@ res = Optim.optimize( (s)->cost(pts,s^2), 0.05, 3.0, Optim.GoldenSection() ) + +@test res.ls_success best_cov = Optim.minimizer(res) @test isapprox(0.5, best_cov; atol=0.3) @@ -749,6 +751,8 @@ res = Optim.optimize( (s)->cost2(s^2), 0.05, 3.0, Optim.GoldenSection() ) + +@test res.ls_success @show best_cov = Optim.minimizer(res) @test isapprox(bcov_, best_cov; atol=1e-3) @@ -764,7 +768,9 @@ res = Optim.optimize( (s)->cost3(s^2), 0.05, 3.0, Optim.GoldenSection() ) -@show best_cov = Optim.minimizer(res) + +@test res.ls_success +best_cov = Optim.minimizer(res) @test isapprox(bcov_, best_cov; atol=1e-3) @@ -804,6 +810,35 @@ end end +@testset "Multidimensional LOOCV bandwidth optimization" begin +## + +M = TranslationGroup(2) +pts = [1*randn(2) for _ in 1:64] + +bw = [1.0; 1.0] +mtree = ApproxManifoldProducts.buildTree_Manellic!(M, pts; kernel_bw=bw,kernel=AMP.MvNormalKernel) + +cost4(σ) = begin + AMP.entropy(mtree, diagm(σ.^2)) +end + +# and optimize with "update" kernel bandwith cost +@time res = Optim.optimize( + cost4, + bw, + Optim.NelderMead() +); + +@test res.ls_success + +@show best_cov = Optim.minimizer(res) + +@test isapprox([0.5; 0.5], best_cov; atol=0.3) + +## +end + ## # # using GLMakie From ece9d8a1bc37ec099ee0e5cb674fd0621b9ff75c Mon Sep 17 00:00:00 2001 From: dehann Date: Sun, 19 May 2024 02:42:17 -0700 Subject: [PATCH 2/4] all content --- test/manellic/testManellicTree.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/manellic/testManellicTree.jl b/test/manellic/testManellicTree.jl index 339e9f6..7ab5fbb 100755 --- a/test/manellic/testManellicTree.jl +++ b/test/manellic/testManellicTree.jl @@ -836,6 +836,12 @@ end @test isapprox([0.5; 0.5], best_cov; atol=0.3) + +mkd = ApproxManifoldProducts.manikde!_manellic(M,pts) + +@test isapprox(best_cov, getBW(mkd); atol=1e-4) + + ## end From 5a4bfaac25cb7b4501ac91018478536ddfa4a497 Mon Sep 17 00:00:00 2001 From: dehann Date: Sun, 19 May 2024 11:28:21 -0700 Subject: [PATCH 3/4] manikde!_manellic for TranslationGroup(2) --- src/services/ManifoldKernelDensity.jl | 8 +++++--- test/manellic/testManellicTree.jl | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/services/ManifoldKernelDensity.jl b/src/services/ManifoldKernelDensity.jl index 43d51c4..49d0010 100644 --- a/src/services/ManifoldKernelDensity.jl +++ b/src/services/ManifoldKernelDensity.jl @@ -107,7 +107,7 @@ manikde!( function manikde!_manellic( M::AbstractManifold, pts::AbstractVector; - bw=ones(manifold_dimension(M),1), + bw=diagm(ones(manifold_dimension(M))), ) # @@ -120,7 +120,9 @@ function manikde!_manellic( # Cost function to optimize # avoid rebuilding tree at each optim iteration!!! - _cost(σ) = entropy(mtree,diagm(σ.^2)) # reshape(σ,manifold_dimension(M),1)) + _cost(σ::Real) = entropy(mtree,[σ^2;;]) # reshape(σ,manifold_dimension(M),1)) + _cost(σ::AbstractVector) = entropy(mtree,diagm(σ.^2)) # reshape(σ,manifold_dimension(M),1)) + _cost(σ::AbstractMatrix) = entropy(mtree,σ.^2) # reshape(σ,manifold_dimension(M),1)) # optimize for best LOOCV bandwidth # FIXME switch to RLM (or other Manopt) techinque instead @@ -135,7 +137,7 @@ function manikde!_manellic( else res = Optim.optimize( _cost, - bw, + diag(bw), # FIXME Optim API issue, if using bw::matrix then steps not PDMat (NelderMead) Optim.NelderMead() ) diagm(Optim.minimizer(res)) diff --git a/test/manellic/testManellicTree.jl b/test/manellic/testManellicTree.jl index 7ab5fbb..8f0df29 100755 --- a/test/manellic/testManellicTree.jl +++ b/test/manellic/testManellicTree.jl @@ -839,7 +839,7 @@ end mkd = ApproxManifoldProducts.manikde!_manellic(M,pts) -@test isapprox(best_cov, getBW(mkd); atol=1e-4) +@test isapprox([0.5 0; 0 0.5], getBW(mkd)[1]; atol=0.3) ## From c1b98cc151bc6d287b1a0e1781e70ea8f43f5cf9 Mon Sep 17 00:00:00 2001 From: dehann Date: Sun, 19 May 2024 11:44:14 -0700 Subject: [PATCH 4/4] fix testManellic univariate --- test/manellic/testManellicTree.jl | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/manellic/testManellicTree.jl b/test/manellic/testManellicTree.jl index 8f0df29..9c9c1e7 100755 --- a/test/manellic/testManellicTree.jl +++ b/test/manellic/testManellicTree.jl @@ -733,7 +733,6 @@ res = Optim.optimize( 0.05, 3.0, Optim.GoldenSection() ) -@test res.ls_success best_cov = Optim.minimizer(res) @test isapprox(0.5, best_cov; atol=0.3) @@ -752,7 +751,6 @@ res = Optim.optimize( 0.05, 3.0, Optim.GoldenSection() ) -@test res.ls_success @show best_cov = Optim.minimizer(res) @test isapprox(bcov_, best_cov; atol=1e-3) @@ -769,7 +767,6 @@ res = Optim.optimize( 0.05, 3.0, Optim.GoldenSection() ) -@test res.ls_success best_cov = Optim.minimizer(res) @test isapprox(bcov_, best_cov; atol=1e-3)