1 | %CHECKTR Check whether Square Distance Matrix Obeys the Triangle Inequality |
---|
2 | % |
---|
3 | % [P,C] = CHECKTR(D,N) |
---|
4 | % |
---|
5 | % INPUT |
---|
6 | % D NxN symmetric distance matrix or dataset |
---|
7 | % |
---|
8 | % OUTPUT |
---|
9 | % P Total fraction of inequalities disobeying the triangle inequality |
---|
10 | % C Constant determined such that when added to all off-diagonal |
---|
11 | % values of D, makes D metric |
---|
12 | % |
---|
13 | % DESCRIPTION |
---|
14 | % Checks whether a symmetric distance matrix D obeys the triangle inequality. |
---|
15 | % If D is asymmetric, it is made symmetric by averaging. M is the total number |
---|
16 | % of disobeyed inequalities. Hence, for M = 0, the triangle inequality holds |
---|
17 | % for the distance matrix D. Additionally, a constant C is sought, which when |
---|
18 | % added to the off-diagonal elements of D will make D obey the triangle inequality: |
---|
19 | % C = max_{i,j,k} {abs(D_{ij} + D_{ik} - D_{jk})} |
---|
20 | % If C is zero, then D fulfills the condition. |
---|
21 | % |
---|
22 | % If N is given, a random NxN subset is taken to speed up and P is an |
---|
23 | % estimate. |
---|
24 | |
---|
25 | % Copyright: Elzbieta Pekalska, ela.pekalska@googlemail.com |
---|
26 | % Faculty EWI, Delft University of Technology and |
---|
27 | % School of Computer Science, University of Manchester |
---|
28 | |
---|
29 | |
---|
30 | function [no,c] = checktr(d,nmax) |
---|
31 | d = +d; |
---|
32 | [n,m] = size(d); |
---|
33 | if nargin < 2 |
---|
34 | nmax = n; % check all |
---|
35 | end |
---|
36 | |
---|
37 | prec = 1e-12; |
---|
38 | if ~issym(d,prec) |
---|
39 | prwarning(1,'Distance matrix should be symmetric. It is made so by averaging.') |
---|
40 | end |
---|
41 | d = 0.5*(d+d'); |
---|
42 | d(1:n+1:end) = 0; |
---|
43 | |
---|
44 | c = 0; |
---|
45 | ismetric = 1; |
---|
46 | |
---|
47 | no = 0; % Number of disobeyed triangle inequalities |
---|
48 | if n > nmax % take subset to speed up. |
---|
49 | R = randperm(n); |
---|
50 | R = R(1:nmax); |
---|
51 | d = d(R,R); |
---|
52 | n = nmax; |
---|
53 | end |
---|
54 | |
---|
55 | prwaitbar(n,'check triangle inequalities'); |
---|
56 | N = 0; |
---|
57 | for j=1:n-1 |
---|
58 | prwaitbar(n,j); |
---|
59 | r1 = d(:,j); |
---|
60 | r2 = d(j,j+1:n); |
---|
61 | % M checks the triangle ineqaulities; all elements of M are |
---|
62 | % positive or zero if this holds. |
---|
63 | M = repmat(r1,1,n-j) + d(:,j+1:n) - repmat(r2,n,1); |
---|
64 | |
---|
65 | % The elemnets of M should ideally be compared to 0. However, |
---|
66 | % due to numerical inaccuracies, a small negative number should |
---|
67 | % be used. Experiments indicate that -1e-13 works well. |
---|
68 | % Otherwise, one gets wrong results. |
---|
69 | tol = 1e-13; |
---|
70 | mm = sum(M(:) < -tol); |
---|
71 | |
---|
72 | N = N + (n-j)*n; |
---|
73 | no = no + mm; |
---|
74 | ismetric = ismetric & (mm == 0); |
---|
75 | if ~ismetric, |
---|
76 | cc = max(max(M)); |
---|
77 | if cc > c, |
---|
78 | c = cc; |
---|
79 | end |
---|
80 | end |
---|
81 | end |
---|
82 | no = no/N; |
---|
83 | prwaitbar(0); |
---|
84 | return; |
---|