source: distools/dmstspm.m

Last change on this file was 79, checked in by bduin, 11 years ago
File size: 3.7 KB
Line 
1%DMSTSPM Find the Shortest Paths along K Minimum Spanning Trees
2%
3%   W = DMSTSPM (D,K,P)
4%
5% INPUT
6%   D   NxN Symmetric dissimilarity matrix or dataset
7%   K   Number of minimum spanning trees; (optional; default: 1)
8%   P   Object number, P = 1..N;
9%       (optional; default: P with the largest distances to all other objects)
10%
11% OUTPUT
12%   W   Mapping that determines the shortest paths
13%
14% DESCRIPTION
15% Determines the shortest paths along a neighborhood graph defined by K minimum
16% spanning trees. MSTs are found by the Prim's algorithm, starting from the
17% point P. The result, however, does not depend on P. New vertices are projected
18% on an edge of the existing neighborhood graph such that the distances
19% between a new object and the vertices of this edge are the smallest. Then,
20% the distances along the shortest paths are computed.
21%
22% DEFAULT
23% K = 1
24% P = max(dist)
25%
26% SEE ALSO
27% KMST, DSPATH, DSPATHS
28
29% Elzbieta Pekalska, ela.pekalska@googlemail.com
30% Faculty of EWI, Delft University of Technology, The Netherlands and
31% School of Computer Science, University of Manchester
32
33
34
35
36function W = dmstspm(D,K,p)
37
38if nargin < 3 | isempty(p),
39  [ss,p]= max(sum(+D));
40end
41if nargin < 2 | isempty(K),
42  K = 1;
43end
44if nargin < 1 | isempty(D)
45   W = prmapping(mfilename,{K,p});
46   W = setname(W,'dmstspm');
47   return
48end
49
50
51if isdataset(D) | isa(D,'double'),
52
53  if ismapping(K),
54    n_orig = getsize_in(K);
55    pars   = getdata(K);
56
57    L   = pars{1};    % list of edges in the MSTs
58    dm  = pars{2};    % weights of the edges
59    K   = pars{3};    % number of MSTs
60
61    W   = D;
62    D   = +D;
63    [m,n] = size(D);
64    if n ~= n_orig,
65      error('The number of columns in the test data does not match.')
66    end
67
68    is_porig = (m > n &  sum(diag(+D(1:n,:)))<=1e-16);
69    is_orig  = (m == n & sum(diag(+D))<=1e-16);
70
71    LL  = [L; L(:,[2 1])];
72    ddm = [dm; dm];
73    DD  = inf * ones(n_orig);
74    DD((LL(:,2)-1)*n_orig+LL(:,1)) = ddm;
75    DD(1:n_orig+1:end)=0;
76
77    if is_orig | is_porig,        % if (a part of) test data is the original distance matrix
78      Dp = dspaths(DD);
79    end
80
81    if ~is_orig,
82      if is_porig,
83        pos = n;
84        Dp  = [Dp; zeros(m-n,n)];
85      else
86        pos = 0;
87        Dp  = zeros(m,n);
88      end
89
90      dmn = zeros(m-pos,2);
91      dd  = zeros(m-pos,1);
92      Ln  = zeros(m-pos,2);
93      D = D(pos+1:m,:);
94
95      [dmin,I] = min(D,[],2);
96      LL = L(:);
97      for i=1:length(I)
98        J = find(LL == I(i));
99        [dd(i),z] = min(ddm(J));
100        Ln(i,1:2) = [I(i) LL(J(z))];
101      end
102
103      % Use the cosine law to determine the distances of the points
104      % projected onto the closest edge
105      X   = (dmin.^2 + dd.^2 - D(Ln(I,2)*(m-pos)+I).^2) ./(2*dd);
106      dmn = [X dd-X];
107      Z   = find(X < 0);  % make corrections if distances are negative
108      if ~isempty(Z)
109        dmn(Z,:) = [-X(Z) dd(Z)-X(Z)];
110      end
111      Z = find(X > dd); % make corrections if distances are too large
112      if ~isempty(Z)
113        dmn(Z,:) = [X(Z) -dd(Z)+X(Z)];
114      end
115
116      for i=1:length(I)
117        dnew = inf*ones(1,n);
118        dnew(Ln(i,:)) = dmn(i,:);
119        Q = dspaths([DD dnew'; dnew 0]);  % Floyd's algorithm is used, since it is fast in Matlab
120        Dp(pos+i,:) = Q(n+1,1:n);
121      end
122    end
123
124
125    if isdataset(W),
126      W = setdata(W,Dp);
127    else
128      W = Dp;
129    end
130    return;
131
132  else
133
134    D = +D;
135    [n,m] = size(D);
136    if n ~= m | ~issym(D,1e-12),
137      error('D should be symmetric.')
138    end
139    D = 0.5*(D+D');
140
141    [Lmst,d] = kdmst(D,K,p);
142    W = prmapping(mfilename,'trained',{Lmst,d,K},[],n,n);
143    W = setname(W,'dmstspm');
144  end
145end
146return;
Note: See TracBrowser for help on using the repository browser.