source: distools/checktr.m @ 89

Last change on this file since 89 was 10, checked in by bduin, 14 years ago
File size: 2.2 KB
Line 
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
30function [no,c] = checktr(d,nmax)
31d = +d;
32[n,m] = size(d);
33if nargin < 2
34        nmax = n; % check all
35end
36       
37prec = 1e-12;
38if ~issym(d,prec)
39  prwarning(1,'Distance matrix should be symmetric. It is made so by averaging.')
40end
41d = 0.5*(d+d');
42d(1:n+1:end) = 0;
43
44c = 0;
45ismetric = 1;
46
47no = 0;         % Number of disobeyed triangle inequalities
48if n > nmax     % take subset to speed up.
49        R = randperm(n);
50        R = R(1:nmax);
51        d = d(R,R);
52        n = nmax;
53end
54       
55prwaitbar(n,'check triangle inequalities');
56N = 0;
57for 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
81end
82no = no/N;
83prwaitbar(0);
84return;
Note: See TracBrowser for help on using the repository browser.