function [coeff,evidence] = topregress(tops, base_coeffs, distances,rects,...
                                       sigma2,U)
%TOPREGRESS regression on the top points of a pruned binary image
%
%   COEFF = TOPREGRESS(TOPS,BASE_COEFFS, DISTANCES, RECTS) Where TOPS
%   is a binary image where the 1 values are the top extrema of
%   text. BASE_COEFFS is the coefficients of a previous regression
%   using the same quadratic model as COEFF described below for the
%   baseline. We will use BASE_COEFFS as a prior for this model's
%   regression. RECTS is an nx4 matrix containing the bounding
%   rectangles for each of the n words in our bottoms image. RECTS is
%   used to optimize the parameters for the regression formula.
%
%   It returns COEFF which is a vector containing [c b a], which are the
%   coefficients of the quadratic y = ax^2 + bx + c. This quadratic represents
%   the baseline of the binarized text. These coefficients are with respect to
%   the image coordinate system.
%
%
%   See also BOTTOMS, INITREGRESS, PARABOLICREGRESS, PRUNEREGRESS, REGRESS,
%   BASELINE.

% Copyright (c) 2012
% Jerod Weinman
% jerod@acm.org 

% $Id: topregress.m 595 2014-10-24 18:15:54Z weinman $
 
% Jerod Weinman, Zach Butler, Dugan Knoll, Alexander Turner, Yirong Jing
% jerod@acm.org
% Copyright 2011, 2012, 2013, 2014
 
%    This file is part of PIONEER WordNorm.
%
%    PIONEER WordNorm 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.
%
%    PIONEER WordNorm 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 PIONEER WordNorm.  If not, see <http://www.gnu.org/licenses/>.

evidence = -Inf;

deg = length(base_coeffs)-1;

[rows,cols] = find(tops);

avgheight = wmean(rects(:,4),rects(:,3)); % Mean height weighted by width

if nargin<5 || isempty(sigma2)
  sigma2 = [1 1e-6 1e-9];
end;

switch length(rows)
    case 1
      % Put the same-shaped curve through the point
      coeff = base_coeffs;
      if deg == 2
        coeff(1) = rows - dot(coeff(2:3), [cols cols^2]);
      else
        coeff(1) = rows - coeff(2)*cols;
      end
    case 0
      % Put a curve through rectangle tops
      cols = [rects(:,1) ; rects(:,1) + rects(:,3)];
      rows = [rects(:,2) ; rects(:,2)];

      if size(rects,1)>1 && deg == 2
        coeff = parabolicregress(cols,rows);
      else
        coeff = linearregress(cols,rows);
        coeff(3) = 0;
      end
    otherwise

      % Cluster distances
      [G,Z] = gmmemdistances(distances);

      Vx = -Inf;
      evidencex = -Inf;

      % Translate the points so that the origin is in the center.
      rowshift = mean(rows);
      colshift = mean(cols);
      rows = rows - rowshift;
      cols = cols - colshift;

      for k=1:size(Z,2)

        Z0 = [Z(:,k) 1-Z(:,k)];

        % Start with baseline coefficients
        coeff = base_coeffs; 
        coeff(1) = adjustoffsetweighted(cols+colshift,rows+rowshift,...
                                        Z0(:,1),coeff);

        % Translate the coeff so that it is relative to the new origin.
        coeff = translatequadratic(coeff, [-rowshift -colshift]);

        % Fit a quadratic to the data using priors
        [coeff,V,zz,evidence] = ...
            fitpoly1(deg, rows, cols, 0.5 ,...
                     [coeff ; ...
                      max([1, avgheight,sigma2(1)]) sigma2(2:(deg+1))]', ...
                     U, log(Z0));

        % Translate the curve back to the original image coordinate system.
        coeff = translatequadratic(coeff,[rowshift colshift]);
        
        if evidence > evidencex % V>Vx;
          coeffx = coeff;
          Vx = V;
          evidencex = evidence;
        end;
      end; % for k

      coeff = coeffx;
      evidence = evidencex;
end
