function options = initLPSolver(intcon,Aineq,bineq,Aeq,beq,lb,ub,options)
%

%initLPSolver Initialize LP and MILP solver objects for internal callers
%
%   This function takes the linear constraints from a problem along with an
%   internal options structure (i.e. options that have already been
%   pre-processed) and returns an instance of an optim.algorithm object for
%   an LP solver and one for an MILP solver as needed.
%
%   Specifics - this function adds 2 fields to the options structure:
%   - options.LPalg - an instance of optim.algorithm.LinprogDualSimplex
%   - options.MILPalg - an instance of optim.algorithm.IntlinprogBranchAndCut
%
%   These algorithm objects are initialized and ready to call using its
%   runNoChecks() method.

%   Copyright 2021 The MathWorks, Inc. 

% Check for non-empty problem 
nvars = max([numel(lb) numel(ub) size(Aineq,2) size(Aeq,2)]);

assert((nvars > 0) || ~(isempty(Aineq) && isempty(Aeq)), ...
    message('globaloptim:initLPSolver:EmptyProblem'));

% Create linprog algorithm object (LinprogDualSimplex)
options.LPalg = createAlgorithm(options.optionsLP);

% Call initialization method to get options sorted out
f = zeros(nvars,1);
options.LPalg = options.LPalg.initialize(f,Aineq,bineq,Aeq,beq,lb,ub);

if ~isempty(intcon)
    % Create intlinprog algorithm object (IntlinprogBranchAndCut)
    options.MILPalg = createAlgorithm(options.optionsIP);
    
    % Call initialization method for IntlinprogBranchAndCut to get options
    % sorted out
    options.MILPalg = options.MILPalg.initialize( ...
        f,intcon,Aineq,bineq,Aeq,beq,lb,ub,[]);
end
end