Skip to content

Commit b20e644

Browse files
committed
Add pairwise distance computation in condensed form for symmetrical metrics.
1 parent 2b0ab92 commit b20e644

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,13 @@ R = pairwise(dist, X)
9393
```
9494

9595
This statement will result in an ``m-by-m`` matrix, where ``R[i,j]`` is the distance between ``X[:,i]`` and ``X[:,j]``.
96-
``pairwise(dist, X)`` is typically more efficient than ``pairwise(dist, X, X)``, as the former will take advantage of the symmetry when ``dist`` is a semi-metric (including metric).
96+
``pairwise(dist, X)`` is typically more efficient than ``pairwise(dist, X, X)``, as the former will take advantage of the symmetry when ``dist`` is a semi-metric (including metric). You can also compute symmetrical distances in a condensed vector representation:
97+
98+
```julia
99+
r = cond_pairwise(dist, X)
100+
```
101+
102+
This will return a vector ``r`` of length ``n * (n - 1) / 2``, containing the corresponding matrix elements arranged in the order ``(2,1), (3,1), ..., (m,1), (3,2), ..., (m,2), ..., (m,m–1)``.
97103

98104
#### Computing column-wise and pairwise distances inplace
99105

@@ -103,9 +109,10 @@ If the vector/matrix to store the results are pre-allocated, you may use the sto
103109
colwise!(r, dist, X, Y)
104110
pairwise!(R, dist, X, Y)
105111
pairwise!(R, dist, X)
112+
pairwise!(r, dist, X)
106113
```
107114

108-
Please pay attention to the difference, the functions for inplace computation are ``colwise!`` and ``pairwise!`` (instead of ``colwise`` and ``pairwise``).
115+
Please pay attention to the difference, the functions for inplace computation are ``colwise!`` and ``pairwise!`` (instead of ``colwise`` and ``pairwise``/``cond_pairwise``).
109116

110117

111118
## Distance type hierarchy

src/Distances.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export
1212
result_type,
1313
colwise,
1414
pairwise,
15+
cond_pairwise,
1516
colwise!,
1617
pairwise!,
1718
evaluate,

src/generic.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,25 @@ function pairwise(metric::PreMetric, a::AbstractMatrix)
126126
r = Matrix{result_type(metric, a, a)}(n, n)
127127
pairwise!(r, metric, a)
128128
end
129+
130+
# Generic pairwise evaluation to a condensed form, for symmetrical distances
131+
132+
function pairwise!(r::AbstractVector, metric::SemiMetric, a::AbstractMatrix)
133+
n = size(a, 2)
134+
length(r) == div((n * (n - 1)), 2) || throw(DimensionMismatch("Incorrect size of r."))
135+
k = 1
136+
for j = 1:n
137+
aj = view(a, :, j)
138+
for i = (j + 1):n
139+
@inbounds r[k] = evaluate(metric, view(a, :, i), aj)
140+
k += 1
141+
end
142+
end
143+
r
144+
end
145+
146+
function cond_pairwise(metric::SemiMetric, a::AbstractMatrix)
147+
n = size(a, 2)
148+
r = Vector{result_type(metric, a, a)}(div(n * (n - 1), 2))
149+
pairwise!(r, metric, a)
150+
end

0 commit comments

Comments
 (0)