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