function [A, l, u] = linear_constraints(om)
%LINEAR_CONSTRAINTS  Builds and returns the linear constraints
%   [A, l, u] = linear_constraints(om)
%
%   l <= A * x <= u

%   MATPOWER
%   $Id: linear_constraints.m,v 1.4 2009/11/04 15:58:44 ray Exp $
%   by Ray Zimmerman, PSERC Cornell
%   Copyright (c) 2008 by Power System Engineering Research Center (PSERC)
%   See http://www.pserc.cornell.edu/matpower/ for more info.


%% initialize A, l and u
nnzA = 0;
for k = 1:om.lin.NS
    nnzA = nnzA + nnz(om.lin.data.A.(om.lin.order{k}));
end
A = sparse([], [], [], om.lin.N, om.var.N, nnzA);
u = Inf * ones(om.lin.N, 1);
l = -u;

%% fill in each piece
for k = 1:om.lin.NS
    name = om.lin.order{k};
    N = om.lin.idx.N.(name);
    if N                                %% non-zero number of rows to add
        Ak = om.lin.data.A.(name);          %% A for kth linear constrain set
        i1 = om.lin.idx.i1.(name);          %% starting row index
        iN = om.lin.idx.iN.(name);          %% ending row index
        vsl = om.lin.data.vs.(name);        %% var set list
        kN = 0;                             %% initialize last col of Ak used
        Ai = sparse(N, om.var.N);
        for v = 1:length(vsl)
            j1 = om.var.idx.i1.(vsl{v});    %% starting column in A
            jN = om.var.idx.iN.(vsl{v});    %% ending column in A
            k1 = kN + 1;                    %% starting column in Ak
            kN = kN + om.var.idx.N.(vsl{v});%% ending column in Ak
            Ai(:, j1:jN) = Ak(:, k1:kN);
        end

        A(i1:iN, :) = Ai;        
        l(i1:iN) = om.lin.data.l.(name);
        u(i1:iN) = om.lin.data.u.(name);
    end
end
