function [label_hat, energy] = crf_infer_gc(model, data, graph, label)
% labeling on CRF
% written by Jimei Yang @UCM, Oct 2011

% parameter parsing
w = full(model.w);
w = mat2cell(w,model.s,1);
w1 = w{1};
w2 = 2;%w{2};
w3 = w{3};


% compute the cost for graph cut
if w3==0 % no data dependent pairwise energy
    
    rows = graph.rows;
    cols = graph.cols;
    Dc = zeros(rows, cols, 2);
    score = w1'*data;
    score = reshape(score, rows, cols);
    Dc(:,:,1) = -score;
    Dc(:,:,2) = score;
    if nargin > 3 % margin rescaling for param learning
        label = reshape(label, rows, cols);
        Loss = zeros(size(Dc));
        Loss(:,:,1) = double(label~=1);
        Loss(:,:,2) = double(label~=-1);
        Dc = Dc - Loss;
        Dc = Dc+1;
    end
    
    % edge cost
    Sc = w2*(ones(2) - eye(2));

    if w2<0
        error('error');
    end

    gch = GraphCut('open', Dc, Sc);
    
else

    Dc = zeros(2, size(data,2));
    score = w1'*data;
    Dc(1,:) = -score;
    Dc(2,:) = score;

    if nargin > 3 % margin rescaling for param learning
        Loss = zeros(size(Dc));
        Loss(1,:) = double(label~=1);
        Loss(2,:) = double(label~=-1);
        Dc = Dc - Loss;
        Dc = Dc+1;
    end

    % edge cost
    Sc = w2*(ones(2) - eye(2));

    A = graph.A;
    D = graph.D;
    D(D>2) = 2;
    W = w3*(2-D);
    Ss = sparse(W.*A);

    if w2<0||w3<0
        error('error');
    end

    gch = GraphCut('open', Dc, Sc, Ss);
    
end
    
[gch label_hat] = GraphCut('expand',gch);
if nargout > 1
    [gch se de] = GraphCut('energy', gch);
    energy = se + de;
end
gch = GraphCut('close', gch);

label_hat = double(label_hat(:));
label_hat = label_hat + 1;
label_hat(label_hat==2) = -1;
