Skip to content

Commit 35c6d0d

Browse files
eliascarvnalimilan
andauthored
Add MinkowskiMetric abstract type (#265)
Co-authored-by: Milan Bouchet-Valat <[email protected]>
1 parent 886ad02 commit 35c6d0d

File tree

5 files changed

+44
-11
lines changed

5 files changed

+44
-11
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "Distances"
22
uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7"
3-
version = "0.10.11"
3+
version = "0.10.12"
44

55
[deps]
66
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,14 +165,20 @@ At the top of this hierarchy is an abstract class **PreMetric**, which is define
165165
d(x, x) == 0 for all x
166166
d(x, y) >= 0 for all x, y
167167

168-
**SemiMetric** is a abstract type that refines **PreMetric**. Formally, a *semi-metric* is a *pre-metric* that is also symmetric, as
168+
**SemiMetric** is an abstract type that refines **PreMetric**. Formally, a *semi-metric* is a *pre-metric* that is also symmetric, as
169169

170170
d(x, y) == d(y, x) for all x, y
171171

172-
**Metric** is a abstract type that further refines **SemiMetric**. Formally, a *metric* is a *semi-metric* that also satisfies triangle inequality, as
172+
**Metric** is an abstract type that further refines **SemiMetric**. Formally, a *metric* is a *semi-metric* that also satisfies triangle inequality, as
173173

174174
d(x, z) <= d(x, y) + d(y, z) for all x, y, z
175175

176+
**MinkowskiMetric** is an abstract type that encompasses a family of metrics defined by the formula
177+
178+
d(x, y) = sum(w .* (x - y) .^ p) ^ (1 / p)
179+
180+
where the `p` parameter defines the metric and `w` is a potential weight vector (all 1's by default).
181+
176182
This type system has practical significance. For example, when computing pairwise distances
177183
between a set of vectors, you may only perform computation for half of the pairs, derive the
178184
values immediately for the remaining half by leveraging the symmetry of *semi-metrics*. Note

src/Distances.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export
99
PreMetric,
1010
SemiMetric,
1111
Metric,
12+
MinkowskiMetric,
1213

1314
# generic functions
1415
result_type,

src/generic.jl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,29 @@ abstract type SemiMetric <: PreMetric end
2121
#
2222
abstract type Metric <: SemiMetric end
2323

24+
"""
25+
MinkowskiMetric <: Metric
26+
27+
A Minkowski metric is a metric that is defined by the formula:
28+
29+
`d(x, y) = sum(w .* (x - y) .^ p) ^ (1 / p)`
30+
31+
where the `p` parameter defines the metric
32+
and `w` is a potential weight vector (all 1's by default).
33+
34+
Common Minkowski metrics:
35+
* `Cityblock`/`WeightedCityblock`: Minkowski metric with `p=1`;
36+
* `Euclidean`/`WeightedEuclidean`: Minkowski metric with `p=2`;
37+
* `Chebyshev`: Limit of `d` as `p` approaches infinity;
38+
* `Minkowski`/`WeightedMinkowski`: generic Minkowski metric for any `p`.
39+
40+
## Notes
41+
* The difference between `Minkowski`/`WeightedMinkowski` and `MinkowskiMetric`
42+
is that while the first are generic Minkowski metrics,
43+
the second is the parent type of these metrics.
44+
"""
45+
abstract type MinkowskiMetric <: Metric end
46+
2447
evaluate(dist::PreMetric, a, b) = dist(a, b)
2548

2649
# Generic functions

src/metrics.jl

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ abstract type UnionSemiMetric <: SemiMetric end
1212

1313
abstract type UnionMetric <: Metric end
1414

15+
abstract type UnionMinkowskiMetric <: MinkowskiMetric end
16+
1517
###########################################################
1618
#
1719
# Metric types
1820
#
1921
###########################################################
2022

21-
struct Euclidean <: UnionMetric
23+
struct Euclidean <: UnionMinkowskiMetric
2224
thresh::Float64
2325
end
2426

@@ -52,7 +54,7 @@ julia> pairwise(Euclidean(1e-12), x, x)
5254
"""
5355
Euclidean() = Euclidean(0)
5456

55-
struct WeightedEuclidean{W} <: UnionMetric
57+
struct WeightedEuclidean{W} <: UnionMinkowskiMetric
5658
weights::W
5759
end
5860

@@ -94,21 +96,21 @@ struct WeightedSqEuclidean{W} <: UnionSemiMetric
9496
weights::W
9597
end
9698

97-
struct Chebyshev <: UnionMetric end
99+
struct Chebyshev <: UnionMinkowskiMetric end
98100

99-
struct Cityblock <: UnionMetric end
100-
struct WeightedCityblock{W} <: UnionMetric
101+
struct Cityblock <: UnionMinkowskiMetric end
102+
struct WeightedCityblock{W} <: UnionMinkowskiMetric
101103
weights::W
102104
end
103105

104106
struct TotalVariation <: UnionMetric end
105107
struct Jaccard <: UnionMetric end
106108
struct RogersTanimoto <: UnionMetric end
107109

108-
struct Minkowski{T <: Real} <: UnionMetric
110+
struct Minkowski{T <: Real} <: UnionMinkowskiMetric
109111
p::T
110112
end
111-
struct WeightedMinkowski{W,T <: Real} <: UnionMetric
113+
struct WeightedMinkowski{W,T <: Real} <: UnionMinkowskiMetric
112114
weights::W
113115
p::T
114116
end
@@ -197,7 +199,7 @@ struct NormRMSDeviation <: PreMetric end
197199
# Union types
198200
const metrics = (Euclidean,SqEuclidean,PeriodicEuclidean,Chebyshev,Cityblock,TotalVariation,Minkowski,Hamming,Jaccard,RogersTanimoto,CosineDist,ChiSqDist,KLDivergence,RenyiDivergence,BrayCurtis,JSDivergence,SpanNormDist,GenKLDivergence)
199201
const weightedmetrics = (WeightedEuclidean,WeightedSqEuclidean,WeightedCityblock,WeightedMinkowski,WeightedHamming)
200-
const UnionMetrics = Union{UnionPreMetric,UnionSemiMetric,UnionMetric}
202+
const UnionMetrics = Union{UnionPreMetric,UnionSemiMetric,UnionMetric,UnionMinkowskiMetric}
201203

202204
###########################################################
203205
#
@@ -208,6 +210,7 @@ const UnionMetrics = Union{UnionPreMetric,UnionSemiMetric,UnionMetric}
208210
parameters(::UnionPreMetric) = nothing
209211
parameters(::UnionSemiMetric) = nothing
210212
parameters(::UnionMetric) = nothing
213+
parameters(::UnionMinkowskiMetric) = nothing
211214
parameters(d::PeriodicEuclidean) = d.periods
212215
for dist in weightedmetrics
213216
@eval parameters(d::$dist) = d.weights

0 commit comments

Comments
 (0)