diff core/magnatagatune/ClipSimGraphMD.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/magnatagatune/ClipSimGraphMD.m	Tue Feb 10 15:05:51 2015 +0000
@@ -0,0 +1,265 @@
+% ---
+% class ClipSimGraphMD
+% Directed graph representing comparative clip similarities.
+% EACH pair of vertices has just ONE directed edge connecting them
+%
+% each node represents a pair of clips,
+% an edge (a,b) -> (a,c) is present if there is at least one
+% users judging clip a more similar to clip b than to clip c
+% 
+% The Edges thus represent the (are nearer to each othen than) 
+% expression
+% ---
+
+classdef ClipSimGraphMD < ClipSimGraph & handle
+
+    
+properties
+
+    % ---
+    % History of edge weights, is a nodes x nodes cell.
+    %
+    % E_hist(i,j) = m x 2 Matrix containing
+    % Pair of information for each set [votes votes_complete]
+    hE; % History of edge weights
+end
+
+% ---
+%  the methods
+% ---
+methods
+        
+% constructor of the graph
+function G = ClipSimGraphMD(comparison, comparison_ids)
+    
+    if nargin == 0
+        % ---
+        % empty constructor
+        % ---
+        
+    elseif nargin == 1
+        % todo: copy graph 
+        
+    elseif nargin == 2
+
+
+        % ---
+        % handle automatic or manual input
+        % ---
+        for i = 1:size(comparison,1)
+
+            % get clips and votes
+            clips = comparison_ids(comparison(i,1:3));
+            votes = comparison(i,4:6);
+
+            % for each triplet position create an edge reflecting the 
+            % absolute and relative voting for this position
+
+            % ---
+            % NOTE: we index 0 - 2 to ease the mod
+            % calculaton for the remaining indices
+            % ---
+            for v = 0:2
+
+                % ---
+                % has at least one user voted this clip out?
+                % If so, treat it as an outlier and determine score
+                % ---
+                if votes(v+1) > 0
+
+                    a = mod(v+1, 3)+1;
+                    b = mod(v+2, 3)+1;
+                    c = v+1;
+
+
+                    % ---
+                    % every outlier vote results in two
+                    % dissimilarity equations, favored by 
+                    % the people who voted for the outlier
+                    % ---
+
+                    % edge 1     
+                    add_edge(G, clips(a), clips(b), clips(c), votes(v+1), sum(votes));
+
+                    % edge 2
+                    add_edge(G, clips(b), clips(a), clips(c), votes(v+1), sum(votes));
+                end
+            end
+
+        end
+    end
+    
+% end constructor function
+end
+
+% adds a node stating clip a is more near %
+% to clip b then clip c
+function Vid = add_node(G, a, b)
+
+    Vid = add_node@ClipSimGraph(G, a, b);
+    
+    G.hE{Vid,Vid} = [];
+
+end
+
+function remove_node(G, a, b)
+	
+    if nargin == 3
+        
+        V1 = G.node(a, b);
+    elseif nargin == 2
+        
+        V1 = a;
+    end
+    
+    if ~isempty(Vid)
+
+        % ---
+        % look for edges connected to Vid
+        % and delete their histograms
+        % ---
+        G.hE(:,Vid) = [];
+        G.hE(Vid,:) = [];
+
+        % ---
+        % TODO: Efficiently Remove the actual node from the
+        % GRAPH
+        % ---
+        G.Vclips(Vid,:) = [];
+
+    end
+end
+
+% ---
+% add an edge saying sim(a,b) > sim(a,c)
+% ---
+function add_edge(G, a, b, c, votes, allvotes)
+    
+    V1 = add_node(G, a, b);
+    V2 = add_node(G, a, c);
+ 
+    % ---
+    % save new weight values into histogram
+    % ---
+    if isempty(G.hE(V1, V2))
+
+        G.hE{V1,V2} = [votes allvotes];
+    else
+        G.hE{V1,V2} = [G.hE{V1,V2}; votes allvotes];
+    end
+    
+    % ---
+    % update Edges
+    % ---
+    G.update_E(a, b, c);
+    
+end
+
+function remove_edge(G, a, b, c)
+
+    if nargin == 4
+        
+        V1 = G.node(a, b);
+        V2 = G.node(a, c);
+    elseif nargin == 3
+        
+        V1 = a;
+        V2 = b;
+    end
+    
+    if ~isempty(V1) && ~isempty(V2)
+
+        % set Edge to zero
+        G.hE{V1, V2} = [];
+    else
+
+        error 'nodes not found';
+    end
+end 
+
+% ---
+% updates the edge weight given 3 clip ids or 
+% two nodes, based on the edges history
+%
+% The specified (V1,V2) and the symmetric edges' (V2,V1) weights
+% are evaluated and the stronger edge will get 
+% the excessive weight while the loosing edge 
+% will be deleted
+% ---
+function update_E(G, a, b, c)
+%  update_E(G, a, b, c)
+%  update_E(G, V1, V2)
+    
+    % determine the type of input parameters
+    if nargin == 4
+        
+        V1 = G.node(a, b);
+        V2 = G.node(a, c);
+    elseif nargin == 3
+        
+        V1 = a;
+        V2 = b;
+    end
+    
+    % ---
+    % calculate weighted sum for specified edge
+    % and  for symmetric edge
+    % ---
+    thisw = unbal_edge_weight(G, V1, V2);
+    symmw = unbal_edge_weight(G, V2, V1);
+
+    % ---
+    % the two //competing// weights are now balanced
+    % ---
+    w = thisw - symmw;
+    
+    % ---
+    % set both edges
+    % ---
+    G.E(V1,V2) = max(w,0);
+    G.E(V2,V1) = -min(w,0);
+    
+%     if w >= 0
+%         G.E(V1,V2) = w;
+%         G.E(V2,V1) = 0;
+%     elseif w < 0
+%         G.E(V1,V2) = 0;
+%         G.E(V2,V1) = -w;
+%     end
+end
+
+end
+
+methods (Hidden)
+    
+    % ---
+    % This is the core function of this Graph. 
+    % it allows for the calculation of a single Edge,
+    % before it is balanced with its symmetrical counteredge
+    %
+    % ---
+    function thisw = unbal_edge_weight(G, V1, V2)
+        % ---
+        % trivial cases
+        % ---
+        if isempty(G.hE(V1, V2)) || isempty(G.hE{V1, V2})
+            thisw = 0;
+            return;
+        end
+        
+        % ---
+        % Evaluate the single historical entries 
+        % and sum up
+        % ---
+        thisw = sum(G.hE{V1, V2},1);
+        
+        % ---
+        % now divide the single votes by the number of
+        % votes totally made with the option to improve 
+        % this edge
+        % ---
+        thisw = thisw(1) /  thisw(2); 
+        
+    end
+end
+end