From 14b061bdda3527e42fbc4690391abf5f963decaf Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Sun, 19 Dec 2021 19:12:23 -0500 Subject: [PATCH 1/2] new non rect periodic --- .gitignore | 1 + src/metrics.jl | 14 ++++++++++++++ test/test_dists.jl | 8 ++++++++ 3 files changed, 23 insertions(+) diff --git a/.gitignore b/.gitignore index 58549d07..807b2723 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ *.jl.*.cov *.jl.mem *.ji +.vscode/ benchmark/params.json Manifest.toml \ No newline at end of file diff --git a/src/metrics.jl b/src/metrics.jl index ec4de634..9859aaf7 100644 --- a/src/metrics.jl +++ b/src/metrics.jl @@ -394,6 +394,20 @@ weuclidean(a, b, w) = WeightedEuclidean(w)(a, b) s3 = min(s2, p - s2) abs2(s3) end + +function (pe::PeriodicEuclidean{<:AbstractMatrix})(a::AbstractVector, b::AbstractVector) + p = parameters(pe) + ndim = length(a) + @assert size(p,1) == size(p, 2) == length(b) == ndim # check dimension + s = p \ (a - b) # decompose to p-basis, a - b = sx x⃗ + sy y⃗ + ... + mindistance = Inf + s = mod.(s, 1) # move to first "quadrant" + @inbounds for k = 0:1<view(p,:,i) .* (k>>(i-1) & 1 == 0 ? s[i] : s[i]-1), 1:ndim) + mindistance = min(norm(loc), mindistance) + end + return mindistance +end eval_end(::PeriodicEuclidean, s) = sqrt(s) peuclidean(a, b, p) = PeriodicEuclidean(p)(a, b) diff --git a/test/test_dists.jl b/test/test_dists.jl index dfe66d2b..41398303 100644 --- a/test/test_dists.jl +++ b/test/test_dists.jl @@ -982,3 +982,11 @@ end end end =# + +@testset "periodic - non-rectangular" begin + # basis vectors: [10, 10], [0, 10] + p = PeriodicEuclidean([10 0.0; 10.0 10.0]) # each column is a basis vector. + @test p([10.1, 10.2], [-10.0, 0.0]) ≈ sqrt(0.1^2 + 0.2^2) + @test p([9.9, 10.2], [-10.0, 0.0]) ≈ sqrt(0.1^2 + 0.2^2) + @test p([9.9, 9.8], [-10.0, 0.0]) ≈ sqrt(0.1^2 + 0.2^2) +end \ No newline at end of file From eacf4f155a761b9466261e4d5d64b41ab761bd12 Mon Sep 17 00:00:00 2001 From: Jinguo Liu Date: Wed, 26 Jan 2022 14:32:45 -0500 Subject: [PATCH 2/2] Update src/metrics.jl Co-authored-by: Daniel Karrasch --- src/metrics.jl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/metrics.jl b/src/metrics.jl index 9859aaf7..4cd09206 100644 --- a/src/metrics.jl +++ b/src/metrics.jl @@ -395,10 +395,14 @@ weuclidean(a, b, w) = WeightedEuclidean(w)(a, b) abs2(s3) end -function (pe::PeriodicEuclidean{<:AbstractMatrix})(a::AbstractVector, b::AbstractVector) - p = parameters(pe) - ndim = length(a) - @assert size(p,1) == size(p, 2) == length(b) == ndim # check dimension +function _evaluate(dist::PeriodicEuclidean, a::AbstractVector, b::AbstractVector, p::AbstractMatrix) + ndim = LinearAlgebra.checksquare(p) + @boundscheck if length(a) != length(b) + throw(DimensionMismatch("first array has length $(length(a)) which does not match the length of the second, $(length(b)).")) + end + @boundscheck if length(a) != ndim + throw(DimensionMismatch("arrays have length $(length(a)) but basis vectors have length $ndim.")) + end s = p \ (a - b) # decompose to p-basis, a - b = sx x⃗ + sy y⃗ + ... mindistance = Inf s = mod.(s, 1) # move to first "quadrant"