0001 function [bmidata]=pen2bmi(pen, name)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 if (nargin<=1)
0025 name='BMI2 from convertor pen2bmi2()';
0026 end
0027
0028
0029
0030 bmidata = [];
0031 bmidata.name = name;
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 if (~isfield(pen,'vars') || pen.vars<=0)
0043 error('Input: wrong or missing vars component in pen.');
0044 end
0045 bmidata.Nx = pen.vars;
0046 Nx = pen.vars;
0047
0048
0049 if (isfield(pen,'x0'))
0050 if (isempty(pen.x0) || ~isvector(pen.x0) || length(pen.x0)~=Nx)
0051 error('Input: starting point x0 is incompatible.');
0052 end
0053 bmidata.xinit = pen.x0;
0054 end
0055
0056
0057 if (isfield(pen,'fobj') && ~isempty(pen.fobj))
0058 bmidata.c = pen.fobj;
0059 end
0060
0061
0062 if (isfield(pen,'q_nzs') && ~isempty(pen.q_nzs) && pen.q_nzs>0)
0063 if (~isfield(pen,'q_row') || ~isfield(pen,'q_col') || ~isfield(pen,'q_val'))
0064 error('Input: incomplete quadratic part of the objective.');
0065 end
0066 H = sparse(pen.q_row+1, pen.q_col+1, pen.q_val,Nx,Nx,pen.Q_nzs);
0067
0068 bmidata.H = H + triu(H,1)';
0069 end
0070
0071
0072 if (isfield(pen,'constr') && ~isempty(pen.constr) && pen.constr>0)
0073 if (~isfield(pen,'bi_dim') || ~isfield(pen,'bi_idx') || ...
0074 ~isfield(pen,'bi_val') || ~isfield(pen,'ci'))
0075 error('Input: incomplete linear constraints Bx<=c.');
0076 end
0077 if (any(pen.bi_dim<0))
0078 error('Input: bi_dim has negative components.');
0079 end
0080
0081
0082 nnzB=sum(pen.bi_dim);
0083 brows=[];
0084 for idx=1:pen.constr
0085 brows=[brows;idx*ones(pen.bi_dim(idx),1)];
0086 end
0087 B = sparse(brows,pen.bi_idx+1,pen.bi_val,pen.constr,Nx,nnzB);
0088 bmidata.B = B;
0089 bmidata.ubg = pen.ci;
0090 end
0091
0092
0093 if (isfield(pen,'mconstr') && ~isempty(pen.mconstr) && pen.mconstr>0)
0094 if (~isfield(pen,'msizes') || any(pen.msizes<1))
0095 error('Input: msizes missing or wrong.');
0096 end
0097
0098
0099 if (isfield(pen,'ai_dim'))
0100 if (isempty(pen.ai_dim) || any(pen.ai_dim<0) || ...
0101 ~isfield(pen,'ai_idx') || ...
0102 ~isfield(pen,'ai_nzs') || any(pen.ai_nzs<0) || ...
0103 ~isfield(pen,'ai_val') || ~isfield(pen,'ai_col') || ...
0104 ~isfield(pen,'ai_row'))
0105 error('Input: incomplete linear matrix terms A_i^k.');
0106 end
0107 else
0108
0109 pen.ai_dim=zeros(pen.mconstr,1);
0110 pen.ai_idx=zeros(1,1);
0111 pen.ai_nzs=zeros(1,1);
0112 pen.ai_val=zeros(1,1);
0113 pen.ai_col=zeros(1,1);
0114 pen.ai_row=zeros(1,1);
0115 end
0116
0117
0118 if (isfield(pen,'ki_dim')) && max(pen.ki_dim)>0
0119 if (isempty(pen.ki_dim) || any(pen.ki_dim<0) || ...
0120 ~isfield(pen,'ki_idx') || ~isfield(pen,'kj_idx') || ...
0121 ~isfield(pen,'ki_nzs') || any(pen.ki_nzs<0) || ...
0122 ~isfield(pen,'ki_val') || ~isfield(pen,'ki_col') || ...
0123 ~isfield(pen,'ki_row'))
0124 error('Input: incomplete bilinear matrix terms K_ij^k.');
0125 end
0126 else
0127
0128 pen.ki_dim=zeros(pen.mconstr,1);
0129 pen.ki_idx=zeros(1,1);
0130 pen.kj_idx=zeros(1,1);
0131 pen.ki_nzs=zeros(1,1);
0132 pen.ki_val=zeros(1,1);
0133 pen.ki_col=zeros(1,1);
0134 pen.ki_row=zeros(1,1);
0135 end
0136
0137 bmidata.Na = pen.mconstr;
0138 bmidata.A = cell(pen.mconstr,1);
0139
0140
0141 midxAstart=1;
0142 midxKstart=1;
0143 idxA=1;
0144 idxK=1;
0145
0146 for k=1:pen.mconstr
0147 midxAend=midxAstart+pen.ai_dim(k)-1;
0148 midxKend=midxKstart+pen.ki_dim(k)-1;
0149 nnzAsum=sum(pen.ai_nzs(midxAstart:midxAend));
0150 nnzKsum=sum(pen.ki_nzs(midxKstart:midxKend));
0151
0152 bmidata.A{k} = copy_mconstr(pen.msizes(k),pen.ai_dim(k),pen.ki_dim(k),...
0153 pen.ai_idx(midxAstart:midxAend), ...
0154 pen.ki_idx(midxKstart:midxKend), pen.kj_idx(midxKstart:midxKend), ...
0155 pen.ai_nzs(midxAstart:midxAend), ...
0156 pen.ai_val(idxA:end), pen.ai_row(idxA:end), pen.ai_col(idxA:end),...
0157 pen.ki_nzs(midxKstart:midxKend), ...
0158 pen.ki_val(idxK:end), pen.ki_row(idxK:end), pen.ki_col(idxK:end));
0159
0160
0161
0162 midxAstart=midxAend+1;
0163 midxKstart=midxKend+1;
0164
0165 idxA = idxA+nnzAsum;
0166 idxK = idxK+nnzKsum;
0167 end
0168 end
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182 end
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199 function [Ak] = copy_mconstr(dim,nA,nK,A_idx,K_idx,K_jdx,...
0200 A_nnz,A_val,A_row,A_col,K_nnz,K_val,K_row,K_col)
0201
0202 if (nA==0 && nK==0)
0203 error('Input: neither linear nor bilinear matrices in this constraint.');
0204 end
0205
0206 if (nK==0)
0207 maxOrder = 1;
0208 Ak.midx = zeros(maxOrder,nA);
0209 Ak.midx(1,:) = A_idx(1:nA);
0210 else
0211 maxOrder = 2;
0212 Ak.midx = zeros(maxOrder,nA+nK);
0213 Ak.midx(1,1:nA) = A_idx(1:nA);
0214 Ak.midx(1,nA+1:end) = K_idx(1:nK);
0215 Ak.midx(2,nA+1:end) = K_jdx(1:nK);
0216 end
0217
0218 Ak.Q = cell(nA+nK,1);
0219
0220 idx = 1;
0221 for midx=1:nA
0222 idxend = idx+A_nnz(midx)-1;
0223 Qi = sparse(A_row(idx:idxend)+1, A_col(idx:idxend)+1, A_val(idx:idxend),...
0224 dim, dim, A_nnz(midx));
0225
0226 Qi = Qi + triu(Qi,1)';
0227
0228 Ak.Q{midx} = -Qi;
0229
0230 idx = idxend+1;
0231 end
0232
0233
0234 idx = 1;
0235 for midx=1:nK
0236 idxend = idx+K_nnz(midx)-1;
0237 Qi = sparse(K_row(idx:idxend)+1, K_col(idx:idxend)+1, K_val(idx:idxend),...
0238 dim, dim, K_nnz(midx));
0239
0240 Qi = Qi + triu(Qi,1)';
0241
0242 Ak.Q{nA+midx} = -Qi;
0243
0244 idx = idxend+1;
0245 end
0246
0247 end
0248
0249