Skip to content

Commit 785aaab

Browse files
devmotionKristofferC
authored andcommitted
Total variation distance (#118)
* Add total variation distance * Add TotalVariation to README and benchmarks
1 parent 1d43a80 commit 785aaab

File tree

6 files changed

+22
-1
lines changed

6 files changed

+22
-1
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ This package also provides optimized functions to compute column-wise and pairwi
1515
* Euclidean distance
1616
* Squared Euclidean distance
1717
* Cityblock distance
18+
* Total variation distance
1819
* Jaccard distance
1920
* Rogers-Tanimoto distance
2021
* Chebyshev distance
@@ -136,6 +137,7 @@ Each distance corresponds to a distance type. The type name and the correspondin
136137
| Euclidean | `euclidean(x, y)` | `sqrt(sum((x - y) .^ 2))` |
137138
| SqEuclidean | `sqeuclidean(x, y)` | `sum((x - y).^2)` |
138139
| Cityblock | `cityblock(x, y)` | `sum(abs(x - y))` |
140+
| TotalVariation | `totalvariation(x, y)` | `sum(abs(x - y)) / 2` |
139141
| Chebyshev | `chebyshev(x, y)` | `max(abs(x - y))` |
140142
| Minkowski | `minkowski(x, y, p)` | `sum(abs(x - y).^p) ^ (1/p)` |
141143
| Hamming | `hamming(k, l)` | `sum(k .!= l)` |

benchmark/benchmarks.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ function create_distances(w, Q)
88
SqEuclidean(),
99
Euclidean(),
1010
Cityblock(),
11+
TotalVariation(),
1112
Chebyshev(),
1213
Minkowski(3.0),
1314
Hamming(),

benchmark/print_table.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ order = [
1111
:SqEuclidean,
1212
:Euclidean,
1313
:Cityblock,
14+
:TotalVariation,
1415
:Chebyshev,
1516
:Minkowski,
1617
:Hamming,

src/Distances.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export
2323
Euclidean,
2424
SqEuclidean,
2525
Cityblock,
26+
TotalVariation,
2627
Chebyshev,
2728
Minkowski,
2829
Jaccard,
@@ -61,6 +62,7 @@ export
6162
euclidean,
6263
sqeuclidean,
6364
cityblock,
65+
totalvariation,
6466
jaccard,
6567
braycurtis,
6668
rogerstanimoto,

src/metrics.jl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ struct SqEuclidean <: SemiMetric
1414
end
1515
struct Chebyshev <: Metric end
1616
struct Cityblock <: Metric end
17+
struct TotalVariation <: Metric end
1718
struct Jaccard <: Metric end
1819
struct RogersTanimoto <: Metric end
1920

@@ -99,7 +100,7 @@ struct RMSDeviation <: Metric end
99100
struct NormRMSDeviation <: Metric end
100101

101102

102-
const UnionMetrics = Union{Euclidean,SqEuclidean,Chebyshev,Cityblock,Minkowski,Hamming,Jaccard,RogersTanimoto,CosineDist,CorrDist,ChiSqDist,KLDivergence,RenyiDivergence,BrayCurtis,JSDivergence,SpanNormDist,GenKLDivergence}
103+
const UnionMetrics = Union{Euclidean,SqEuclidean,Chebyshev,Cityblock,TotalVariation,Minkowski,Hamming,Jaccard,RogersTanimoto,CosineDist,CorrDist,ChiSqDist,KLDivergence,RenyiDivergence,BrayCurtis,JSDivergence,SpanNormDist,GenKLDivergence}
103104

104105
"""
105106
Euclidean([thresh])
@@ -219,6 +220,13 @@ euclidean(a::Number, b::Number) = evaluate(Euclidean(), a, b)
219220
cityblock(a::AbstractArray, b::AbstractArray) = evaluate(Cityblock(), a, b)
220221
cityblock(a::T, b::T) where {T <: Number} = evaluate(Cityblock(), a, b)
221222

223+
# Total variation
224+
@inline eval_op(::TotalVariation, ai, bi) = abs(ai - bi)
225+
@inline eval_reduce(::TotalVariation, s1, s2) = s1 + s2
226+
eval_end(::TotalVariation, s) = s / 2
227+
totalvariation(a::AbstractArray, b::AbstractArray) = evaluate(TotalVariation(), a, b)
228+
totalvariation(a::T, b::T) where {T <: Number} = evaluate(TotalVariation(), a, b)
229+
222230
# Chebyshev
223231
@inline eval_op(::Chebyshev, ai, bi) = abs(ai - bi)
224232
@inline eval_reduce(::Chebyshev, s1, s2) = max(s1, s2)

test/test_dists.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ end
4747
test_metricity(SqEuclidean(), x, y, z)
4848
test_metricity(Euclidean(), x, y, z)
4949
test_metricity(Cityblock(), x, y, z)
50+
test_metricity(TotalVariation(), x, y, z)
5051
test_metricity(Chebyshev(), x, y, z)
5152
test_metricity(Minkowski(2.5), x, y, z)
5253

@@ -122,6 +123,7 @@ end
122123

123124
@test euclidean(a, b) == 1.0
124125
@test cityblock(a, b) == 1.0
126+
@test totalvariation(a, b) == 0.5
125127
@test chebyshev(a, b) == 1.0
126128
@test minkowski(a, b, 2) == 1.0
127129
@test hamming(a, b) == 1
@@ -140,6 +142,7 @@ end
140142
@test euclidean(x, y) == sqrt(57.0)
141143
@test jaccard(x, y) == 13.0 / 28
142144
@test cityblock(x, y) == 13.0
145+
@test totalvariation(x, y) == 6.5
143146
@test chebyshev(x, y) == 6.0
144147
@test braycurtis(x, y) == 1.0 - (30.0 / 43.0)
145148
@test minkowski(x, y, 2) == sqrt(57.0)
@@ -242,6 +245,8 @@ end #testset
242245
@test isa(euclidean(a, b), T)
243246
@test cityblock(a, b) == 0.0
244247
@test isa(cityblock(a, b), T)
248+
@test totalvariation(a, b) == 0.0
249+
@test isa(totalvariation(a, b), T)
245250
@test chebyshev(a, b) == 0.0
246251
@test isa(chebyshev(a, b), T)
247252
@test braycurtis(a, b) == 0.0
@@ -385,6 +390,7 @@ end
385390
test_colwise(SqEuclidean(), X, Y, T)
386391
test_colwise(Euclidean(), X, Y, T)
387392
test_colwise(Cityblock(), X, Y, T)
393+
test_colwise(TotalVariation(), X, Y, T)
388394
test_colwise(Chebyshev(), X, Y, T)
389395
test_colwise(Minkowski(2.5), X, Y, T)
390396
test_colwise(Hamming(), A, B, T)
@@ -459,6 +465,7 @@ end
459465
test_pairwise(SqEuclidean(), X, Y, T)
460466
test_pairwise(Euclidean(), X, Y, T)
461467
test_pairwise(Cityblock(), X, Y, T)
468+
test_pairwise(TotalVariation(), X, Y, T)
462469
test_pairwise(Chebyshev(), X, Y, T)
463470
test_pairwise(Minkowski(2.5), X, Y, T)
464471
test_pairwise(Hamming(), A, B, T)

0 commit comments

Comments
 (0)