wolffd@0
|
1 % ---
|
wolffd@0
|
2 % class ClipSimGraphMD
|
wolffd@0
|
3 % Directed graph representing comparative clip similarities.
|
wolffd@0
|
4 % EACH pair of vertices has just ONE directed edge connecting them
|
wolffd@0
|
5 %
|
wolffd@0
|
6 % each node represents a pair of clips,
|
wolffd@0
|
7 % an edge (a,b) -> (a,c) is present if there is at least one
|
wolffd@0
|
8 % users judging clip a more similar to clip b than to clip c
|
wolffd@0
|
9 %
|
wolffd@0
|
10 % The Edges thus represent the (are nearer to each othen than)
|
wolffd@0
|
11 % expression
|
wolffd@0
|
12 % ---
|
wolffd@0
|
13
|
wolffd@0
|
14 classdef ClipSimGraphMD < ClipSimGraph & handle
|
wolffd@0
|
15
|
wolffd@0
|
16
|
wolffd@0
|
17 properties
|
wolffd@0
|
18
|
wolffd@0
|
19 % ---
|
wolffd@0
|
20 % History of edge weights, is a nodes x nodes cell.
|
wolffd@0
|
21 %
|
wolffd@0
|
22 % E_hist(i,j) = m x 2 Matrix containing
|
wolffd@0
|
23 % Pair of information for each set [votes votes_complete]
|
wolffd@0
|
24 hE; % History of edge weights
|
wolffd@0
|
25 end
|
wolffd@0
|
26
|
wolffd@0
|
27 % ---
|
wolffd@0
|
28 % the methods
|
wolffd@0
|
29 % ---
|
wolffd@0
|
30 methods
|
wolffd@0
|
31
|
wolffd@0
|
32 % constructor of the graph
|
wolffd@0
|
33 function G = ClipSimGraphMD(comparison, comparison_ids)
|
wolffd@0
|
34
|
wolffd@0
|
35 if nargin == 0
|
wolffd@0
|
36 % ---
|
wolffd@0
|
37 % empty constructor
|
wolffd@0
|
38 % ---
|
wolffd@0
|
39
|
wolffd@0
|
40 elseif nargin == 1
|
wolffd@0
|
41 % todo: copy graph
|
wolffd@0
|
42
|
wolffd@0
|
43 elseif nargin == 2
|
wolffd@0
|
44
|
wolffd@0
|
45
|
wolffd@0
|
46 % ---
|
wolffd@0
|
47 % handle automatic or manual input
|
wolffd@0
|
48 % ---
|
wolffd@0
|
49 for i = 1:size(comparison,1)
|
wolffd@0
|
50
|
wolffd@0
|
51 % get clips and votes
|
wolffd@0
|
52 clips = comparison_ids(comparison(i,1:3));
|
wolffd@0
|
53 votes = comparison(i,4:6);
|
wolffd@0
|
54
|
wolffd@0
|
55 % for each triplet position create an edge reflecting the
|
wolffd@0
|
56 % absolute and relative voting for this position
|
wolffd@0
|
57
|
wolffd@0
|
58 % ---
|
wolffd@0
|
59 % NOTE: we index 0 - 2 to ease the mod
|
wolffd@0
|
60 % calculaton for the remaining indices
|
wolffd@0
|
61 % ---
|
wolffd@0
|
62 for v = 0:2
|
wolffd@0
|
63
|
wolffd@0
|
64 % ---
|
wolffd@0
|
65 % has at least one user voted this clip out?
|
wolffd@0
|
66 % If so, treat it as an outlier and determine score
|
wolffd@0
|
67 % ---
|
wolffd@0
|
68 if votes(v+1) > 0
|
wolffd@0
|
69
|
wolffd@0
|
70 a = mod(v+1, 3)+1;
|
wolffd@0
|
71 b = mod(v+2, 3)+1;
|
wolffd@0
|
72 c = v+1;
|
wolffd@0
|
73
|
wolffd@0
|
74
|
wolffd@0
|
75 % ---
|
wolffd@0
|
76 % every outlier vote results in two
|
wolffd@0
|
77 % dissimilarity equations, favored by
|
wolffd@0
|
78 % the people who voted for the outlier
|
wolffd@0
|
79 % ---
|
wolffd@0
|
80
|
wolffd@0
|
81 % edge 1
|
wolffd@0
|
82 add_edge(G, clips(a), clips(b), clips(c), votes(v+1), sum(votes));
|
wolffd@0
|
83
|
wolffd@0
|
84 % edge 2
|
wolffd@0
|
85 add_edge(G, clips(b), clips(a), clips(c), votes(v+1), sum(votes));
|
wolffd@0
|
86 end
|
wolffd@0
|
87 end
|
wolffd@0
|
88
|
wolffd@0
|
89 end
|
wolffd@0
|
90 end
|
wolffd@0
|
91
|
wolffd@0
|
92 % end constructor function
|
wolffd@0
|
93 end
|
wolffd@0
|
94
|
wolffd@0
|
95 % adds a node stating clip a is more near %
|
wolffd@0
|
96 % to clip b then clip c
|
wolffd@0
|
97 function Vid = add_node(G, a, b)
|
wolffd@0
|
98
|
wolffd@0
|
99 Vid = add_node@ClipSimGraph(G, a, b);
|
wolffd@0
|
100
|
wolffd@0
|
101 G.hE{Vid,Vid} = [];
|
wolffd@0
|
102
|
wolffd@0
|
103 end
|
wolffd@0
|
104
|
wolffd@0
|
105 function remove_node(G, a, b)
|
wolffd@0
|
106
|
wolffd@0
|
107 if nargin == 3
|
wolffd@0
|
108
|
wolffd@0
|
109 V1 = G.node(a, b);
|
wolffd@0
|
110 elseif nargin == 2
|
wolffd@0
|
111
|
wolffd@0
|
112 V1 = a;
|
wolffd@0
|
113 end
|
wolffd@0
|
114
|
wolffd@0
|
115 if ~isempty(Vid)
|
wolffd@0
|
116
|
wolffd@0
|
117 % ---
|
wolffd@0
|
118 % look for edges connected to Vid
|
wolffd@0
|
119 % and delete their histograms
|
wolffd@0
|
120 % ---
|
wolffd@0
|
121 G.hE(:,Vid) = [];
|
wolffd@0
|
122 G.hE(Vid,:) = [];
|
wolffd@0
|
123
|
wolffd@0
|
124 % ---
|
wolffd@0
|
125 % TODO: Efficiently Remove the actual node from the
|
wolffd@0
|
126 % GRAPH
|
wolffd@0
|
127 % ---
|
wolffd@0
|
128 G.Vclips(Vid,:) = [];
|
wolffd@0
|
129
|
wolffd@0
|
130 end
|
wolffd@0
|
131 end
|
wolffd@0
|
132
|
wolffd@0
|
133 % ---
|
wolffd@0
|
134 % add an edge saying sim(a,b) > sim(a,c)
|
wolffd@0
|
135 % ---
|
wolffd@0
|
136 function add_edge(G, a, b, c, votes, allvotes)
|
wolffd@0
|
137
|
wolffd@0
|
138 V1 = add_node(G, a, b);
|
wolffd@0
|
139 V2 = add_node(G, a, c);
|
wolffd@0
|
140
|
wolffd@0
|
141 % ---
|
wolffd@0
|
142 % save new weight values into histogram
|
wolffd@0
|
143 % ---
|
wolffd@0
|
144 if isempty(G.hE(V1, V2))
|
wolffd@0
|
145
|
wolffd@0
|
146 G.hE{V1,V2} = [votes allvotes];
|
wolffd@0
|
147 else
|
wolffd@0
|
148 G.hE{V1,V2} = [G.hE{V1,V2}; votes allvotes];
|
wolffd@0
|
149 end
|
wolffd@0
|
150
|
wolffd@0
|
151 % ---
|
wolffd@0
|
152 % update Edges
|
wolffd@0
|
153 % ---
|
wolffd@0
|
154 G.update_E(a, b, c);
|
wolffd@0
|
155
|
wolffd@0
|
156 end
|
wolffd@0
|
157
|
wolffd@0
|
158 function remove_edge(G, a, b, c)
|
wolffd@0
|
159
|
wolffd@0
|
160 if nargin == 4
|
wolffd@0
|
161
|
wolffd@0
|
162 V1 = G.node(a, b);
|
wolffd@0
|
163 V2 = G.node(a, c);
|
wolffd@0
|
164 elseif nargin == 3
|
wolffd@0
|
165
|
wolffd@0
|
166 V1 = a;
|
wolffd@0
|
167 V2 = b;
|
wolffd@0
|
168 end
|
wolffd@0
|
169
|
wolffd@0
|
170 if ~isempty(V1) && ~isempty(V2)
|
wolffd@0
|
171
|
wolffd@0
|
172 % set Edge to zero
|
wolffd@0
|
173 G.hE{V1, V2} = [];
|
wolffd@0
|
174 else
|
wolffd@0
|
175
|
wolffd@0
|
176 error 'nodes not found';
|
wolffd@0
|
177 end
|
wolffd@0
|
178 end
|
wolffd@0
|
179
|
wolffd@0
|
180 % ---
|
wolffd@0
|
181 % updates the edge weight given 3 clip ids or
|
wolffd@0
|
182 % two nodes, based on the edges history
|
wolffd@0
|
183 %
|
wolffd@0
|
184 % The specified (V1,V2) and the symmetric edges' (V2,V1) weights
|
wolffd@0
|
185 % are evaluated and the stronger edge will get
|
wolffd@0
|
186 % the excessive weight while the loosing edge
|
wolffd@0
|
187 % will be deleted
|
wolffd@0
|
188 % ---
|
wolffd@0
|
189 function update_E(G, a, b, c)
|
wolffd@0
|
190 % update_E(G, a, b, c)
|
wolffd@0
|
191 % update_E(G, V1, V2)
|
wolffd@0
|
192
|
wolffd@0
|
193 % determine the type of input parameters
|
wolffd@0
|
194 if nargin == 4
|
wolffd@0
|
195
|
wolffd@0
|
196 V1 = G.node(a, b);
|
wolffd@0
|
197 V2 = G.node(a, c);
|
wolffd@0
|
198 elseif nargin == 3
|
wolffd@0
|
199
|
wolffd@0
|
200 V1 = a;
|
wolffd@0
|
201 V2 = b;
|
wolffd@0
|
202 end
|
wolffd@0
|
203
|
wolffd@0
|
204 % ---
|
wolffd@0
|
205 % calculate weighted sum for specified edge
|
wolffd@0
|
206 % and for symmetric edge
|
wolffd@0
|
207 % ---
|
wolffd@0
|
208 thisw = unbal_edge_weight(G, V1, V2);
|
wolffd@0
|
209 symmw = unbal_edge_weight(G, V2, V1);
|
wolffd@0
|
210
|
wolffd@0
|
211 % ---
|
wolffd@0
|
212 % the two //competing// weights are now balanced
|
wolffd@0
|
213 % ---
|
wolffd@0
|
214 w = thisw - symmw;
|
wolffd@0
|
215
|
wolffd@0
|
216 % ---
|
wolffd@0
|
217 % set both edges
|
wolffd@0
|
218 % ---
|
wolffd@0
|
219 G.E(V1,V2) = max(w,0);
|
wolffd@0
|
220 G.E(V2,V1) = -min(w,0);
|
wolffd@0
|
221
|
wolffd@0
|
222 % if w >= 0
|
wolffd@0
|
223 % G.E(V1,V2) = w;
|
wolffd@0
|
224 % G.E(V2,V1) = 0;
|
wolffd@0
|
225 % elseif w < 0
|
wolffd@0
|
226 % G.E(V1,V2) = 0;
|
wolffd@0
|
227 % G.E(V2,V1) = -w;
|
wolffd@0
|
228 % end
|
wolffd@0
|
229 end
|
wolffd@0
|
230
|
wolffd@0
|
231 end
|
wolffd@0
|
232
|
wolffd@0
|
233 methods (Hidden)
|
wolffd@0
|
234
|
wolffd@0
|
235 % ---
|
wolffd@0
|
236 % This is the core function of this Graph.
|
wolffd@0
|
237 % it allows for the calculation of a single Edge,
|
wolffd@0
|
238 % before it is balanced with its symmetrical counteredge
|
wolffd@0
|
239 %
|
wolffd@0
|
240 % ---
|
wolffd@0
|
241 function thisw = unbal_edge_weight(G, V1, V2)
|
wolffd@0
|
242 % ---
|
wolffd@0
|
243 % trivial cases
|
wolffd@0
|
244 % ---
|
wolffd@0
|
245 if isempty(G.hE(V1, V2)) || isempty(G.hE{V1, V2})
|
wolffd@0
|
246 thisw = 0;
|
wolffd@0
|
247 return;
|
wolffd@0
|
248 end
|
wolffd@0
|
249
|
wolffd@0
|
250 % ---
|
wolffd@0
|
251 % Evaluate the single historical entries
|
wolffd@0
|
252 % and sum up
|
wolffd@0
|
253 % ---
|
wolffd@0
|
254 thisw = sum(G.hE{V1, V2},1);
|
wolffd@0
|
255
|
wolffd@0
|
256 % ---
|
wolffd@0
|
257 % now divide the single votes by the number of
|
wolffd@0
|
258 % votes totally made with the option to improve
|
wolffd@0
|
259 % this edge
|
wolffd@0
|
260 % ---
|
wolffd@0
|
261 thisw = thisw(1) / thisw(2);
|
wolffd@0
|
262
|
wolffd@0
|
263 end
|
wolffd@0
|
264 end
|
wolffd@0
|
265 end
|