wolffd@0
|
1 % ---
|
wolffd@0
|
2 % class ClipSimGraphMulti
|
wolffd@0
|
3 % Directed MultiGraph representing comparative clip similarities.
|
wolffd@0
|
4 % EACH pair of vertices has multiple directed edges 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 % Each edge thus represent a single (are nearer to each othen than)
|
wolffd@0
|
11 % expression
|
wolffd@0
|
12 % ---
|
wolffd@0
|
13
|
wolffd@0
|
14 classdef ClipSimGraphMulti < ClipSimGraph & handle
|
wolffd@0
|
15
|
wolffd@0
|
16
|
wolffd@0
|
17 properties
|
wolffd@0
|
18
|
wolffd@0
|
19 end
|
wolffd@0
|
20
|
wolffd@0
|
21 % ---
|
wolffd@0
|
22 % the methods
|
wolffd@0
|
23 % ---
|
wolffd@0
|
24 methods
|
wolffd@0
|
25
|
wolffd@0
|
26 % constructor of the graph
|
wolffd@0
|
27 function G = ClipSimGraphMulti(comparison, comparison_ids)
|
wolffd@0
|
28
|
wolffd@0
|
29 if nargin == 0
|
wolffd@0
|
30 % ---
|
wolffd@0
|
31 % empty constructor
|
wolffd@0
|
32 % ---
|
wolffd@0
|
33
|
wolffd@0
|
34 elseif nargin == 1
|
wolffd@0
|
35 % todo: copy graph if same class
|
wolffd@0
|
36
|
wolffd@0
|
37 % ---
|
wolffd@0
|
38 % this uses an imput grpaph
|
wolffd@0
|
39 % to create a new MD graph
|
wolffd@0
|
40 % ---
|
wolffd@0
|
41
|
wolffd@0
|
42 G = ClipSimGraphMulti();
|
wolffd@0
|
43
|
wolffd@0
|
44 % ---
|
wolffd@0
|
45 % Add the input graph to the empty one
|
wolffd@0
|
46 % ---
|
wolffd@0
|
47 G.add_graph(comparison);
|
wolffd@0
|
48
|
wolffd@0
|
49 elseif nargin == 2
|
wolffd@0
|
50
|
wolffd@0
|
51
|
wolffd@0
|
52 % ---
|
wolffd@0
|
53 % handle automatic or manual input
|
wolffd@0
|
54 % ---
|
wolffd@0
|
55 for i = 1:size(comparison,1)
|
wolffd@0
|
56
|
wolffd@0
|
57 % get clips and votes
|
wolffd@0
|
58 clips = comparison_ids(comparison(i,1:3));
|
wolffd@0
|
59 votes = comparison(i,4:6);
|
wolffd@0
|
60
|
wolffd@0
|
61 % for each triplet position create an edge reflecting the
|
wolffd@0
|
62 % absolute and relative voting for this position
|
wolffd@0
|
63
|
wolffd@0
|
64 % ---
|
wolffd@0
|
65 % NOTE: we index 0 - 2 to ease the mod
|
wolffd@0
|
66 % calculaton for the remaining indices
|
wolffd@0
|
67 % ---
|
wolffd@0
|
68 for v = 0:2
|
wolffd@0
|
69
|
wolffd@0
|
70 % ---
|
wolffd@0
|
71 % has at least one user voted this clip out?
|
wolffd@0
|
72 % If so, treat it as an outlier and determine score
|
wolffd@0
|
73 % ---
|
wolffd@0
|
74 if votes(v+1) > 0
|
wolffd@0
|
75
|
wolffd@0
|
76 a = mod(v+1, 3)+1;
|
wolffd@0
|
77 b = mod(v+2, 3)+1;
|
wolffd@0
|
78 c = v+1;
|
wolffd@0
|
79
|
wolffd@0
|
80
|
wolffd@0
|
81 % ---
|
wolffd@0
|
82 % every outlier vote results in two
|
wolffd@0
|
83 % dissimilarity equations, favored by
|
wolffd@0
|
84 % the people who voted for the outlier
|
wolffd@0
|
85 % ---
|
wolffd@0
|
86
|
wolffd@0
|
87 % edge 1
|
wolffd@0
|
88 add_edge(G, clips(a), clips(b), clips(c), votes(v+1));
|
wolffd@0
|
89
|
wolffd@0
|
90 % edge 2
|
wolffd@0
|
91 add_edge(G, clips(b), clips(a), clips(c), votes(v+1));
|
wolffd@0
|
92 end
|
wolffd@0
|
93 end
|
wolffd@0
|
94
|
wolffd@0
|
95 end
|
wolffd@0
|
96 end
|
wolffd@0
|
97
|
wolffd@0
|
98 % end constructor function
|
wolffd@0
|
99 end
|
wolffd@0
|
100
|
wolffd@0
|
101 function out = order(G)
|
wolffd@0
|
102
|
wolffd@0
|
103 out = sum(G.V);
|
wolffd@0
|
104 end
|
wolffd@0
|
105
|
wolffd@0
|
106 function out = num_edges_multi(G)
|
wolffd@0
|
107 out = sum(sum(G.E));
|
wolffd@0
|
108 end
|
wolffd@0
|
109
|
wolffd@0
|
110 function out = num_edges(G)
|
wolffd@0
|
111 out = sum(sum(G.E ~= 0));
|
wolffd@0
|
112 end
|
wolffd@0
|
113
|
wolffd@0
|
114
|
wolffd@0
|
115 % ---
|
wolffd@0
|
116 % NOTE: the weight explains the multiplicity of each
|
wolffd@0
|
117 % edge, to correctily describe this,
|
wolffd@0
|
118 % we just count the votes
|
wolffd@0
|
119 % ---
|
wolffd@0
|
120 function join_edge(G, a, b, c, weight)
|
wolffd@0
|
121
|
wolffd@0
|
122 if nargin == 5
|
wolffd@0
|
123 V1 = G.node(a, b);
|
wolffd@0
|
124 V2 = G.node(a, c);
|
wolffd@0
|
125 elseif nargin == 4
|
wolffd@0
|
126 V1 = a;
|
wolffd@0
|
127 V2 = b;
|
wolffd@0
|
128 weight = c;
|
wolffd@0
|
129 end
|
wolffd@0
|
130
|
wolffd@0
|
131 if G.edge(V1, V2) ~= 0
|
wolffd@0
|
132
|
wolffd@0
|
133 % set add number to Edge index
|
wolffd@0
|
134 G.E(V1, V2) = (G.E(V1, V2) + weight);
|
wolffd@0
|
135
|
wolffd@0
|
136 cprint(3, 'edge weight %d %d %d updated \n',a ,b , c) ;
|
wolffd@0
|
137 else
|
wolffd@0
|
138
|
wolffd@0
|
139 error 'nodes not found';
|
wolffd@0
|
140 end
|
wolffd@0
|
141 end
|
wolffd@0
|
142
|
wolffd@0
|
143 % ---
|
wolffd@0
|
144 % This eliminates any order-2 cycles,
|
wolffd@0
|
145 % by substracting opposing edge counts
|
wolffd@0
|
146 % ---
|
wolffd@0
|
147 function remove_cycles_length2(G)
|
wolffd@0
|
148
|
wolffd@0
|
149 G.E = max(0, G.E - G.E');
|
wolffd@0
|
150 end
|
wolffd@0
|
151 % ---
|
wolffd@0
|
152 % TODO: this back-and forth transform is a workaround
|
wolffd@0
|
153 % avoiding some costly other transformation which would
|
wolffd@0
|
154 % happen during the direct digraph call
|
wolffd@0
|
155 % ---
|
wolffd@0
|
156
|
wolffd@0
|
157 function [Gs, s, id] = connected_components(G, varargin)
|
wolffd@0
|
158 % ---
|
wolffd@0
|
159 % get all connected subgraphs:
|
wolffd@0
|
160 % ---
|
wolffd@0
|
161 G2 = DiGraph(G);
|
wolffd@0
|
162
|
wolffd@0
|
163 [GsDiGraph, s, id] = connected_components@DiGraph(G2, varargin{:});
|
wolffd@0
|
164
|
wolffd@0
|
165 for i = 1:numel(GsDiGraph)
|
wolffd@0
|
166 Gs(i) = ClipSimGraphMulti(GsDiGraph(i));
|
wolffd@0
|
167 end
|
wolffd@0
|
168 end
|
wolffd@0
|
169
|
wolffd@0
|
170
|
wolffd@0
|
171 end
|
wolffd@0
|
172
|
wolffd@0
|
173 methods (Hidden)
|
wolffd@0
|
174
|
wolffd@0
|
175 end
|
wolffd@0
|
176 end
|