www.gusucode.com > mbcdata 工具箱 matlab 源码程序 > mbcdata/@cgoptimrunner/private/pCreateLinearConstraintData.m

    function LinData = pCreateLinearConstraintData(obj, ConItemData,FullCopy)
%PCREATELINEARCONSTRAINTDATA Compute linear constraint matrices.
%
%   LINDATA = PCREATELINEARCONSTRAINTDATA(OBJ, CONITEMDATA) creates and
%   returns a structure that contains the information required to construct
%   the A and B linear constraint matrices during the running of the
%   optimization.  LINDATA will be a struct containing the fields A, b and
%   A2:  A*Xfree <= (b - A2*Xfixed).
%
%   LINDATA = PCREATELINEARCONSTRAINTDATA(..., false) specifies that linear
%   data should not be collected as the object is being used as an output.

%   Copyright 2005-2009 The MathWorks, Inc.


ConItems = ConItemData.Items;
isLin = cellfun(@isLinear, (ConItems));
if FullCopy && any(isLin)
    ConItems = ConItems(isLin);
    NConVals = ConItemData.OutputLengths(isLin);
    InputIdx = ConItemData.InputIndices(isLin);
    DSIndices =  ConItemData.Datasets(isLin);
    AllInputLen = obj.InputDataLengths;
    
    % Get the A and b matrices for each con item
    [Amats, bmats] = cellfun(@getLinearForm, ConItems, 'UniformOutput', false);
    
    % Initialise expanded matrices to the correct size.  The free and fixed
    % variables in A are split apart later on
    A = zeros(sum(NConVals), sum(AllInputLen));
    b = zeros(sum(NConVals), 1);
    
    % Loop over each conitem
    nEnd = 0;
    for n = 1:length(ConItems)
        nStart = nEnd+1;
        nEnd = nStart+NConVals(n)-1;
        % Check whether each variable is an input and if so, copy the A
        % values into the right places
        mEnd = 0;
        InputLen = AllInputLen;
        if DSIndices(n)
            DS = obj.DataSetData(DSIndices(n));
            %change input sizes to account for application data set
            InputLen(InputLen~=1) = size(DS.Data,1);
        end
        
        for m = 1:length(InputLen)
            mStart = mEnd+1;
            % should be defined by number of free variables and not data
            % set
            mEnd = mStart+AllInputLen(m)-1;
           
            % Find m'th variable in input list
            [isInput, idx] = ismember(m, InputIdx{n});
            if isInput
                nThisFreeA = size(Amats{n}, 1);
                nRep = round((nEnd - nStart + 1)/nThisFreeA);
                if InputLen(m)==1 && nRep*nThisFreeA == NConVals(n)
                    % Repmat linear constraint for scalar variable. Using
                    % repmat to cover cases where more than one
                    % constraint per point is returned.
                    Ainsert = ...
                        repmat(Amats{n}(:, idx), nRep, 1);
                elseif InputLen(m)==NConVals(n)
                    % Insert the coefficient in a diagonal submatrix
                    Ainsert = ...
                        diag(repmat(Amats{n}(:, idx), 1, InputLen(m))); 
                elseif InputLen(m)*nThisFreeA == NConVals(n)
                    ThisFreeA = {Amats{n}(:, idx)};
                    Ainsert = repmat(ThisFreeA, 1, InputLen(m));
                    Ainsert = blkdiag(Ainsert{:});
                else
                    % Linear constraints should not have mixed-length
                    % inputs as the matrix cannot support this situation
                    error(message('mbc:cgoptimrunner:InvalidState10'));
                end
                if DSIndices(n)
                    % post-multiply by interpolation matrix to give full
                    % linear matrix
                    Ainsert = multiplyMatrix(DS,Ainsert);
                end
                A(nStart:nEnd, mStart:mEnd) = Ainsert;
            end
        end
        
        % Copy b value
        NCON = size(bmats{n}, 1);
        if NCON
            NREP = (nEnd - nStart + 1)/NCON;
            b(nStart:nEnd) = repmat(bmats{n}(:), NREP, 1);
        end
    end
    
    % Split A matrix into Afree and Afixed.  The Afree needs to be in the
    % same order as the free variables are listed
    FreeIdx = zeros(1, sum(AllInputLen(obj.FreeVariableIndices)));
    FreeVarInd = obj.FreeVariableIndices;
    mEnd = 0;
    for m = 1:length(FreeVarInd)
        mStart = mEnd+1;
        mEnd = mStart+AllInputLen(FreeVarInd(m))-1;
        
        idxStart = sum(AllInputLen(1:(FreeVarInd(m)-1)))+1;
        FreeIdx(mStart:mEnd) = idxStart:(idxStart + AllInputLen(FreeVarInd(m)) - 1);       
    end
    
    Afree = A(:, FreeIdx);
    A(:, FreeIdx) = [];
    LinData = struct('A', Afree, 'b', b, 'A2', A);
    
else
    LinData = struct('A', [], 'b', [], 'A2', []);
end