%% compute uOpt
%
% This function computes uOpt,the optimal utility under nonlinear taxation
% for an individual with earnings zOld under linear taxation.
% In addition to zOld, its arguments are the elasticity el, and a structure 
% called data containing the tax parameters:
% data.zStar is the kink location, data.t0 is the tax  below the kink, and
% data.t1 the tax above.
%
% uFric is the utility associated with maintaining earnings z after the tax
% rate changes from the linear schedule with mtr t to the nonlinear
% schedule with the tax rate t0 below zStar and t1 above.
%
% Input notes:
%
% - el must always be a scalar.
% - zOld can be a vector of arbitrary length N, in which case data.t0,
%   data.t1, and data.zStar must all be scalars, and the function returns an
%   N by 1 vector.
% - if zOld is a scalar, then data.t0, data.t1, and data.zStar can be
%   vectors of any length, although they all must the same length N. In this
%   case the function returns an N by 1 vector.

function [u, z] = uOpt(zOld,el,data)
    
    % cutoff level of earnings for bunching
    %elVec = ones(length(data.zStar),1).*el;
    zBunch = data.zStar.*( (1-data.t0)./(1-data.t1) ).^el;

    % find new earnings. given by labor supply curve or kink, depending on
    % n.
    z = zOld                                    .*(zOld<=data.zStar) + ...
        data.zStar                              .*(zOld>data.zStar).*(zOld<=zBunch)+...
        zOld.*( (1-data.t1)./ (1-data.t0) ).^el .* (zOld>zBunch);
    
    % find consumption, accounting for nonlinear taxation.
    c = z - (data.t0.*z + (data.t1-data.t0).*(z-data.zStar).*(z>data.zStar));
    
    % find utility
    n = zOld ./(1-data.t0).^el;
    u = c - n./(1+1./el) .*(z./n).^(1+1./el);
        
end