function [c] = mvn_bregmancentroid_skl(models, approx, lc, rc)
%MVN_BREGMANCENTROID_SKL    Compute the symmetric Kullback-Leibler (KL) centroid given mvn models.
%
%   [c] = MVN_BREGMANCENTROID_SKL(models) computes the SKL centroid 
%   for the given multivariate normals.
%
%   [c] = MVN_BREGMANCENTROID_SKL(models, 1) computes the SKL centroid 
%   mid-point approximation for the given multivariate normals.

%   (c) 2010-2011, Dominik Schnitzer, <dominik.schnitzer@ofai.at>
%   http://www.ofai.at/~dominik.schnitzer/mvn
%
%   This file is part of the MVN Octave/Matlab Toolbox
%   MVN is free software: you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation, either version 3 of the License, or
%   (at your option) any later version.
%
%   MVN is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You should have received a copy of the GNU General Public License
%   along with MVN.  If not, see <http://www.gnu.org/licenses/>.

    c = [];

    if (nargin < 3)
        if (length(models) < 1)
            return;
        end

        lc = mvn_bregmancentroid_kl_left(models);
        rc = mvn_bregmancentroid_kl_right(models);
    end
    
    % compute the mid-point approximation if requested.
    if ((nargin > 1) && (approx == 1))
        c = mvn_bregmancentroid_geodesic(0.5, lc, rc);
        return;
    end

    d = 0;
    d1 = 1;

    while ((d1 - d) > 0.00001)
        d2 = 0.5 * (d + d1);
        c = mvn_bregmancentroid_geodesic(d2, lc, rc);

        bisector = mvn_div_kl(c, lc) - mvn_div_kl(rc, c);
        if (bisector < 0)
            d1 = d2;
        else
            d = d2;
        end
    end
end
