function [x,lb,ub,msg] = checkbounds(xin,lbin,ubin,nvars)
%

%CHECKBOUNDS Verify that the bounds are valid with respect to initial point.
%
% This is a helper function.

%   [X,LB,UB,X,FLAG] = CHECKBOUNDS(X0,LB,UB,nvars)
%   checks that the upper and lower
%   bounds are valid (LB <= UB) and the same length as X (pad with -inf/inf
%   if necessary); warn if too short or too long.  Also make LB and UB vectors
%   if not already. Finally, inf in LB or -inf in UB throws an error.

%   Copyright 1990-2022 The MathWorks, Inc.

msg = [];
% Turn into column vectors
lb = lbin(:);
ub = ubin(:);
x = xin(:);

lenlb = length(lb);
lenub = length(ub);

% Check lb length
if lenlb > nvars
    warning(message('optimlib:checkbounds:IgnoringExtraLbs'));
    lb = lb(1:nvars);
elseif lenlb < nvars % includes empty lb case
    if lenlb > 0
        % lb is non-empty and length(lb) < nvars.
        warning(message('optimlib:checkbounds:PadLbWithMinusInf'));
    end
    lb = [lb; -Inf*ones(nvars-lenlb,1)];
end

% Check ub length
if lenub > nvars
    warning(message('optimlib:checkbounds:IgnoringExtraUbs'));
    ub = ub(1:nvars);
elseif lenub < nvars % includes empty ub case
    if lenub > 0
        % ub is non-empty and length(ub) < nvars.
        warning(message('optimlib:checkbounds:PadUbWithInf'));
    end
    ub = [ub; Inf*ones(nvars-lenub,1)];
end

% Check feasibility of bounds
if any(lb > ub)
    msg = getString(message('optimlib:checkbounds:Infeasible'));
end

% Check if -Inf in ub or Inf in lb
if any( ub == -Inf )
    error(message('optimlib:checkbounds:MinusInfUb'));
elseif any( lb == Inf )
    error(message('optimlib:checkbounds:PlusInfLb'));
elseif anynan(lb) || anynan(ub)
    error(message('optimlib:checkbounds:NanBounds'))
end


