1 function [SERCsubnew,SERDnew]=...
2 QPpassive(bw,SERA,SERC,SERD,SERE,
s,weightflag,...
3 auxflag,weightfactor,SERAsub,SERCsub,s2,s3,TOL);
5 % ======================================================
8 % = Last revised: 11.04.2007 =
10 % = SINTEF Energy Research, N-7465 Trondheim, NORWAY =
11 % = bjorn.gustavsen@sintef.
no =
12 % ======================================================
15 %
QPpassive(bw,SERA,SERC,SERD,SERE,
s,weightflag,...
16 %
auxflag,weightfactor,SERAsub,SERCsub,s2,s3,TOL);
18 % PURPOSE : Modify
elements in SERC and SERD of rational approximation
21 % Yij(
s)=SUM(--------- ) +SERDij +
s*SEREij ("ij" denotes element
i,
j)
24 % to enforce passivity at given frequency samples.
26 % =================================================
28 % =================================================
30 % bw =0 --> Will modify elements on the diagonal of Rm, D |0 1 2 3|
31 % =1 --> will modify elements on diagonal plus 1 band on each side |1 0 1 2|
32 % =2 --> will modify elements on diagonal plus 2 bands on each side |2 1 0 1|
34 % -----------------------------------------------------------------------------------
38 % SERC(Nc,Nc,N) : Residues
39 % SERD(Nc,Nc) : Constant term
40 % SERE(Nc,Nc) : Capacitive term
42 % s(1,Ns) : Frequency samples (jw [rad/sec])
44 % weightflag=1 --> weight=1 for all elements in Least Squares problem, at all freq.
45 % =2 --> weight=1/sqrt(
abs(Yijw)); indvidual element
weighting
50 %
auxflag =1 --> Routine inserts additional samples for LS problem outside the
51 % fitting range. One sample at each pole location (SERAsub).
53 % weightfactor : Factor defining the total weighting of additional samples outside
54 % the fitting range, relative to the total weighting of samples in the
55 % fitting range. Is only used if auxflag=1.
57 % -----------------------------------------------------------------------------------
60 % SERAsub(Nsub,1) : Poles to be included in QP
61 % SERCsub(Nc,Nc,Nsub) : Associated residues
63 % s2(1,Ns2) (jw [rad/sec]) : List of frequencies. Will include in constraint problem
64 % eigenvalues which violate the passivity criterion at
67 % s3(1,Ns3) (jw [rad/sec]) : List of frequencies. Will include in constraint problem
68 % all eigenvalues at these frequencies.
70 % =================================================
72 % =================================================
73 % SERCnew(Nc,Nc,Nsub) : Updated residues
74 % SERDnew(Nc,Nc) : Updated constant term
76 % ***********************************************************************************
77 % NOTE: This program is in the public domain and may be used by anyone. If the *
78 % program code (or
a modified version) is used in a scientific work or *
79 % in a commercial program, then reference should be made to the following: *
80 % B. Gustavsen and A. Semlyen, "Enforcing Passivity for Admittance Matrices *
81 % Approximated by Rational Functions, IEEE Trans. Power Systems, *
82 % vol. 16, no. 1, pp. 97-104, Feb. 2001. *
83 % ***********************************************************************************
85 % This file is part of the QPpassive.zip toolbox
87 % ***********************************************************************************
90 % 21.10.2004 - Several bugs related to usage of cindexsub corrected.
91 % 11.03.07 - Input parameter weighfactor correcctly included in the code.
92 % - Proper dimensioning of array bigA2
93 % ***********************************************************************************
95 % 11.04.2007: Added option for using CPLEX over quadprog, see below.
99 %
solver=
'cplex '; %Requires installment of CPLEX (http:
102 SERCsubnew=SERCsub; SERDnew=SERD; SEREnew=SERE;
106 Nsub=length(SERAsub);
119 %=======================================================
120 % Finding out which
poles are complex :
121 %=======================================================
129 if cindex(
m-1)==0 | cindex(
m-1)==2
130 cindex(
m)=1; cindex(
m+1)=2;
138 % Constraint problem:
139 cindexsub=zeros(1,Nsub);
141 if imag(SERAsub(
m))~=0
145 if cindexsub(
m-1)==0 | cindexsub(
m-1)==2
146 cindexsub(
m)=1; cindexsub(
m+1)=2;
154 %========================================
155 % LOOP FOR LEAST SQUARES PROBLEM:
156 %========================================
159 nnn=nnn+(Nc-row); %nnn is the number of
elements in Y to be put in solution vector
162 if weightflag==4 | weightflag==5
163 weightarr=ones(1,Ns);
167 for col=row:min(row+bw,Nc)
168 Y(row,col)=SERD(row,col)+sk*SERE(row,col);
169 Y(row,col)=Y(row,col)+
sum(squeeze(SERC(row,col,1:N))./(
s(
k)-SERA(1:N)));
173 weightarr(
k)=1/sqrt(norm(Y));
175 weightarr(
k)=1/norm(Y);
178 end %
if weightflag==4 | weightflag==5
180 bigA=zeros(Ns*nnn,nnn*(Nsub+1));
183 % Calculating
matrix Mmat (coefficients
for LS-problem)
189 for col=row:min(row+bw,Nc)
190 y=SERD(row,col)+sk*SERE(row,col);
191 y=y+
sum(squeeze(SERC(row,col,1:N))./(
s(
k)-SERA(1:N)));
195 weight=1/sqrt(
abs(y));
198 elseif weightflag==4 | weightflag==5
208 faktor1=weight*sqrt(2);
213 if cindexsub(
m)==0 %real pole
214 Mmat(tell,offs+
m)=faktor1*1/(sk-SERAsub(
m));
215 elseif cindexsub(
m)==1 %complex pole, 1st part
216 Mmat(tell,offs+
m)= faktor1* (1/(sk-SERAsub(
m)) + 1/(sk-SERAsub(
m)') );
217 Mmat(tell,offs+
m+1)=faktor1* (
i/(sk-SERAsub(
m)) -
i/(sk-SERAsub(
m)') );
220 Mmat(tell,offs+Nsub+1)=faktor1*1;
221 offs=offs + (Nsub+1);
225 bigA((
k-1)*nnn+1:
k*nnn,:)=Mmat;
228 bigb=zeros(length(bigA(:,1)),1);
231 %========================================
232 % INTRODUCING SAMPLES OUTSIDE LS REGION: ONE SAMPLE PER POLE (s4)
233 %========================================
237 for m=1:length(SERAsub)
238 if cindexsub(
m)==0 %real pole
239 if ( (
abs(SERAsub(
m))>
s(Ns)/
j ) | (
abs(SERAsub(
m))<
s(1)/
j ) )
241 s4(tell)=
j*
abs(SERAsub(
m));
243 elseif cindexsub(
m)==1 %complex pole, first part
244 if ( (
abs(imag(SERAsub(
m)))>
s(Ns)/
j ) | (
abs(imag(SERAsub(
m)))<
s(1)/
j ) )
246 s4(tell)=
j*
abs(imag(SERAsub(
m)));
254 if weightflag==4 | weightflag==5
255 weightarr4=ones(1,Ns4);
259 for col=row:min(row+bw,Nc)
260 Y(row,col)=SERD(row,col)+sk*SERE(row,col);
261 Y(row,col)=Y(row,col)+
sum(squeeze(SERC(row,col,1:N))./(
s(
k)-SERA(1:N)));
265 weightarr4(
k)=1/sqrt(norm(Y));
267 weightarr4(
k)=1/norm(Y);
270 end %
if weightflag==4 | weightflag==5
279 bigA2=zeros(Ns4*nnn,nnn*(Nsub+1));
283 % Calculating
matrix Mmat (coefficients
for LS-problem)
289 for col=row:min(row+bw,Nc)
294 weight=1/sqrt(
abs(y));
297 elseif weightflag==4 | weightflag==5
298 weight=weightarr4(
k);
307 faktor1=weight*sqrt(2);
309 faktor1=weightfactor*faktor1;
312 if cindexsub(
m)==0 %real pole
313 Mmat(tell,offs+
m)=faktor1*1/(sk-SERAsub(
m));
314 elseif cindexsub(
m)==1 %complex pole, 1st part
315 Mmat(tell,offs+
m)= faktor1* (1/(sk-SERAsub(
m)) + 1/(sk-SERAsub(
m)') );
316 Mmat(tell,offs+
m+1)=faktor1* (
i/(sk-SERAsub(
m)) -
i/(sk-SERAsub(
m)') ); %!!!!!
319 Mmat(tell,offs+Nsub+1)=faktor1*1;
320 offs=offs + (Nsub+1);
325 bigA2((
k-1)*nnn+1:
k*nnn,:)=Mmat;
329 bigb=zeros(length(bigA(:,1)),1);
333 %========================================
334 % LOOP FOR CONSTRAINT PROBLEM, TYPE #1 (violating eigenvalues in s2):
335 %========================================
340 Y(row,col)=SERD(row,col)+sk*SERE(row,col);
341 Y(row,col)=Y(row,col)+
sum(squeeze(SERC(row,col,1:N))./(sk-SERA(1:N)));
345 %Calculating eigenvalues and eigenvectors:
346 [V,Z] = eig(real(Y)); Z=diag(Z);
348 if min(real(Z))<0 %any violations
350 % Calculating
matrix M2mat;
matrix of partial derivatives :
356 for col=row:min(row+bw,Nc)
364 if cindexsub(
m)==0 %real pole
365 Mmat2(tell,offs+
m)=faktor2*1/(sk-SERAsub(
m));
366 elseif cindexsub(
m)==1 %complex pole, 1st part
367 Mmat2(tell,offs+
m)= faktor2* (1/(sk-SERAsub(
m)) + 1/(sk-SERAsub(
m)') );
368 Mmat2(tell,offs+
m+1)=faktor2* (
i/(sk-SERAsub(
m)) -
i/(sk-SERAsub(
m)') );
372 Mmat2(tell,offs+Ndum+1)=faktor2*1;
373 offs=offs + (Nsub+1);
381 for col=row:min(row+bw,Nc)
396 for n=1:Nc %ustabilitet?
399 bigc=[bigc;-TOL+delz(n)];
403 end %
if max(real(Z))>0 %any violations
409 %========================================
410 % LOOP FOR CONSTRAINT PROBLEM, TYPE #2: (all eigenvalues in s3):
411 %========================================
417 Y(row,col)=SERD(row,col)+sk*SERE(row,col);
418 Y(row,col)=Y(row,col)+
sum(squeeze(SERC(row,col,1:N))./(sk-SERA(1:N)));
421 %Calculating eigenvalues and eigenvectors:
422 [V,Z] = eig(real(Y)); Z=diag(Z);
425 % Calculating
matrix M2mat;
matrix of partial derivatives :
431 for col=row:min(row+bw,Nc)
439 if cindexsub(
m)==0 %real pole
440 Mmat2(tell,offs+
m)=faktor2*1/(sk-SERA(
m));
441 elseif cindexsub(
m)==1 %complex pole, 1st part
442 Mmat2(tell,offs+
m)= faktor2* (1/(sk-SERAsub(
m)) + 1/(sk-SERAsub(
m)') );
443 Mmat2(tell,offs+
m+1)=faktor2* (
i/(sk-SERAsub(
m)) -
i/(sk-SERAsub(
m)') );
447 Mmat2(tell,offs+Ndum+1)=faktor2*1;
448 offs=offs + (Nsub+1);
456 for col=row:min(row+bw,Nc)
473 bigc=[bigc;-TOL+delz(n)];
479 return %No passivity violations
485 bigA=[real(bigA); imag(bigA)];
486 bigb=[real(bigb); imag(bigb)];
491 Acol=length(bigA(1,:));
493 Escale(col)=norm(bigA(:,col),2);
494 bigA(:,col)=bigA(:,col)./Escale(col);
496 bigB(:,col)=bigB(:,col)./Escale(col);
511 disp(
'Starting quadprog...')
512 [dx,lambda]=quadprog(
H,ff,-bigB,bigc,[],[],[],[],[],optimoptions(
'quadprog',
'MaxIterations',2e4));
519 H=sparse(H); %A=sparse(A);
520 x_0=zeros(length(H(:,1)));
522 b_L = -inf*ones(length(b_U),1);
523 x_L = -inf*ones(length(x_0),1);
524 x_U = inf*ones(length(x_0),1);
526 disp('Starting CPLEX...
')
527 Prob = qpAssign(H,c,A,b_L,b_U,x_L,x_U,x_0,'dust
');
528 Prob.MIP.cpxControl.QPMETHOD = 4;
529 Prob.MIP.cpxControl.BARALG = 2; %2
532 [x, slack, v, rc, f_k] = cplex(c, A, x_L, x_U, b_L, b_U, ...
533 Prob.MIP.cpxControl, [], PriLev, Prob, [], [], [], [], ...
538 'ERROR: invalid value
for solver'
541 disp(['Elapsed
time:
' num2str(toc) ' sec
'])
548 %Converting dx so that the
residues become complex:
551 for col=row:min(row+bw,Nc)
555 r1=dx(tell); r2=dx(tell+1);
556 dx(tell)=r1+
i*r2; dx(tell+1)=r1-
i*r2;
559 tell=tell+1; %Skip SERD
564 %Updating SERC, SERD:
567 for col=row:min(row+bw,Nc)
571 SERCsubnew(row,col,
m)=SERCsubnew(row,col,
m)+dx(tell);
573 SERCsubnew(col,row,
m)=SERCsubnew(col,row,
m)+dx(tell);
576 SERDnew(row,col)=SERDnew(row,col)+dx(tell+1);
578 SERDnew(col,row)=SERDnew(col,row)+dx(tell+1);
indvidual element weighting
common weighting for all matrix elements
common weighting for all matrix elements relative to the total weighting of samples in the fitting range Is only used if then reference should be made to the Enforcing Passivity for Admittance Matrices *Approximated by Rational IEEE Trans Power no
bw, SERA, SERC, SERD, SERE, s, weightflag,... % auxflag, weightfactor, SERAsub, SERCsub, s2, s3, TOL QPpassive()
common weighting for all matrix elements auxflag
function[SERCsubnew, SERDnew]
Undo scaling of outgoing poles
Undo scaling of outgoing residues
Turn this into a with identical frequencies along the rows s
Find a complex rational model for freq domain data for a
end if abs(real(dotprod))>rstoerst rstoerst
Square sum(error) of solution aaa=0.0