function M = optimalNLPredictor(ximage, yimage, partition, linearM)
% compute a piece-wise linear predictor yimage->ximage
% using the given partition of the image
% linearM is a set of coefficients for opt linear prediction without
% partition, used for comparison only

n = 1;
X = imageVectors(ximage,0);
Y = [ones([1 length(X)]); imageVectors(yimage,n,1)];

totalerr = 0;
M = zeros([(2*n+2)^2+1 max(max(partition))+1]);
M(n*(2*n+2)+n+2, :) = ones([1 max(max(partition))+1]);
for i=0:max(max(partition))
   mask = imageVectors([partition == i], 0);
   [v, ind] = find(mask);
   if(length(ind) > 10)
      Ypart = Y(:,ind);
      Xpart = X(ind);
      
      [M(:, i+1), err] = optimalLinearPredictor(Xpart, Ypart);
      errlin = err;
      if (nargin == 4)
         errlin = 1; %mean(mean((Xpart-linearM'*Ypart).^2));
      end
      
      totalerr = totalerr + err * length(ind);
      disp(sprintf('opt linear predictor cell %d (%d pixels) : err = %.3f, linerr = %.3f, impr = %.1f%',...
         i, length(Xpart), err, errlin, 100*(errlin-err)/(errlin+eps)));
   end
   
end

disp(sprintf('optimal NL predictor : avg error : %.3f', totalerr/length(Y)));



