JUK1
QPpassive.m
Go to the documentation of this file.
1 function [SERCsubnew,SERDnew]=...
2  QPpassive(bw,SERA,SERC,SERD,SERE,s,weightflag,...
3  auxflag,weightfactor,SERAsub,SERCsub,s2,s3,TOL);
4 %
5 % ======================================================
6 % = Routine: QPpassive.m =
7 % = Version 1.2 =
8 % = Last revised: 11.04.2007 =
9 % = Bjorn Gustavsen =
10 % = SINTEF Energy Research, N-7465 Trondheim, NORWAY =
11 % = bjorn.gustavsen@sintef.no =
12 % ======================================================
13 %
14 %function [SERCsubnew,SERDnew]=...
15 % QPpassive(bw,SERA,SERC,SERD,SERE,s,weightflag,...
16 % auxflag,weightfactor,SERAsub,SERCsub,s2,s3,TOL);
17 %
18 % PURPOSE : Modify elements in SERC and SERD of rational approximation
19 %
20 % N SERCijm
21 % Yij(s)=SUM(--------- ) +SERDij +s*SEREij ("ij" denotes element i,j)
22 % m=1 (s-SERAm)
23 %
24 % to enforce passivity at given frequency samples.
25 %
26 % =================================================
27 % INPUT :
28 % =================================================
29 %
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|
33 % etc.. |3 2 1 0|
34 % -----------------------------------------------------------------------------------
35 % LEAST SQUARES PART:
36 %
37 % SERA(N,1) : Poles
38 % SERC(Nc,Nc,N) : Residues
39 % SERD(Nc,Nc) : Constant term
40 % SERE(Nc,Nc) : Capacitive term
41 %
42 % s(1,Ns) : Frequency samples (jw [rad/sec])
43 %
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
46 % =3 --> weight=1/abs(Yijw) ; indvidual element weighting
47 % =4 --> weight=1/sqrt(norm(Yw)) ; common weighting for all matrix elements
48 % =5 --> weight=1/norm(Yw) ; common weighting for all matrix elements
49 %
50 % auxflag =1 --> Routine inserts additional samples for LS problem outside the
51 % fitting range. One sample at each pole location (SERAsub).
52 %
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.
56 % Default value: 1e-3
57 % -----------------------------------------------------------------------------------
58 % CONSTRAINT PART:
59 %
60 % SERAsub(Nsub,1) : Poles to be included in QP
61 % SERCsub(Nc,Nc,Nsub) : Associated residues
62 %
63 % s2(1,Ns2) (jw [rad/sec]) : List of frequencies. Will include in constraint problem
64 % eigenvalues which violate the passivity criterion at
65 % these frequencies
66 %
67 % s3(1,Ns3) (jw [rad/sec]) : List of frequencies. Will include in constraint problem
68 % all eigenvalues at these frequencies.
69 %
70 % =================================================
71 % OUTPUT :
72 % =================================================
73 % SERCnew(Nc,Nc,Nsub) : Updated residues
74 % SERDnew(Nc,Nc) : Updated constant term
75 %
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 % ***********************************************************************************
84 %
85 % This file is part of the QPpassive.zip toolbox
86 %
87 % ***********************************************************************************
88 %
89 % Bug fixes:
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 % ***********************************************************************************
94 
95 % 11.04.2007: Added option for using CPLEX over quadprog, see below.
96 %
97 
98 solver='quadprog';
99 %solver='cplex '; %Requires installment of CPLEX (http://tomopt.com/)
100 
101 
102 SERCsubnew=SERCsub; SERDnew=SERD; SEREnew=SERE;
103 
104 
105 N=length(SERA);
106 Nsub=length(SERAsub);
107 
108 bigA=sparse([]);
109 bigb=[];
110 bigB=[];
111 bigc=[];
112 Ns=length(s);
113 Ns2=length(s2);
114 Nc=length(SERD);
115 I=eye(Nc);
116 M2mat=[];
117 
118 
119 %=======================================================
120 % Finding out which poles are complex :
121 %=======================================================
122 % LS problem:
123 cindex=zeros(1,N);
124 for m=1:N
125  if imag(SERA(m))~=0
126  if m==1
127  cindex(m)=1;
128  else
129  if cindex(m-1)==0 | cindex(m-1)==2
130  cindex(m)=1; cindex(m+1)=2;
131  else
132  cindex(m)=2;
133  end
134  end
135  end
136 end
137 
138 % Constraint problem:
139 cindexsub=zeros(1,Nsub);
140 for m=1:Nsub
141  if imag(SERAsub(m))~=0
142  if m==1
143  cindexsub(m)=1;
144  else
145  if cindexsub(m-1)==0 | cindexsub(m-1)==2
146  cindexsub(m)=1; cindexsub(m+1)=2;
147  else
148  cindexsub(m)=2;
149  end
150  end
151  end
152 end
153 
154 %========================================
155 % LOOP FOR LEAST SQUARES PROBLEM:
156 %========================================
157 nnn=Nc;
158 for row=1:min(bw,Nc)
159  nnn=nnn+(Nc-row); %nnn is the number of elements in Y to be put in solution vector
160 end
161 
162 if weightflag==4 | weightflag==5
163  weightarr=ones(1,Ns);
164  for k=1:Ns
165  sk=s(k);
166  for row=1:Nc
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)));
170  end
171  end
172  if weightflag==4
173  weightarr(k)=1/sqrt(norm(Y));
174  elseif weightflag==5
175  weightarr(k)=1/norm(Y);
176  end
177  end %for k=1:Ns
178 end %if weightflag==4 | weightflag==5
179 
180 bigA=zeros(Ns*nnn,nnn*(Nsub+1));
181 for k=1:Ns
182  sk=s(k);
183  % Calculating matrix Mmat (coefficients for LS-problem)
184  tell=0;
185  offs=0;
186 
187  for row=1:Nc
188  ind2=0;
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)));
192  if weightflag==1
193  weight=1;
194  elseif weightflag==2
195  weight=1/sqrt(abs(y));
196  elseif weightflag==3
197  weight=1/abs(y);
198  elseif weightflag==4 | weightflag==5
199  weight=weightarr(k);
200  else
201  'ERROR!!!!!!!!!'
202  weight=1;
203  end
204 
205  if row==col
206  faktor1=weight*1;
207  else
208  faktor1=weight*sqrt(2);
209  end
210 
211  tell=tell+1;
212  for m=1:Nsub
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)') );
218  end
219  end %m
220  Mmat(tell,offs+Nsub+1)=faktor1*1;
221  offs=offs + (Nsub+1);
222  end %col
223  end %row
224 
225  bigA((k-1)*nnn+1:k*nnn,:)=Mmat;
226 
227 end %for k=1:Ns
228 bigb=zeros(length(bigA(:,1)),1);
229 
230 
231 %========================================
232 % INTRODUCING SAMPLES OUTSIDE LS REGION: ONE SAMPLE PER POLE (s4)
233 %========================================
234 if auxflag==1
235 s4=[];
236 tell=0;
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 ) )
240  tell=tell+1;
241  s4(tell)=j*abs(SERAsub(m));
242  end
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 ) )
245  tell=tell+1;
246  s4(tell)=j*abs(imag(SERAsub(m)));
247  end
248  end
249 end
250 Ns4=length(s4);
251 
252 
253 %Weighting:
254 if weightflag==4 | weightflag==5
255  weightarr4=ones(1,Ns4);
256  for k=1:Ns4
257  sk=s4(k);
258  for row=1:Nc
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)));
262  end
263  end
264  if weightflag==4
265  weightarr4(k)=1/sqrt(norm(Y));
266  elseif weightflag==5
267  weightarr4(k)=1/norm(Y);
268  end
269  end %for k=1:Ns4
270 end %if weightflag==4 | weightflag==5
271 
272 
273 
274 nnn=Nc;
275 for row=1:min(bw,Nc)
276  nnn=nnn+(Nc-row);
277 end
278 
279 bigA2=zeros(Ns4*nnn,nnn*(Nsub+1));
280 for k=1:Ns4
281  sk=s4(k);
282 
283  % Calculating matrix Mmat (coefficients for LS-problem)
284  tell=0;
285  offs=0;
286 
287  for row=1:Nc
288  ind2=0;
289  for col=row:min(row+bw,Nc)
290 
291  if weightflag==1
292  weight=1;
293  elseif weightflag==2
294  weight=1/sqrt(abs(y));
295  elseif weightflag==3
296  weight=1/abs(y);
297  elseif weightflag==4 | weightflag==5
298  weight=weightarr4(k);
299  else
300  'ERROR!!!!!!!!!'
301  weight=1;
302  end
303 
304  if row==col
305  faktor1=weight;
306  else
307  faktor1=weight*sqrt(2);
308  end
309  faktor1=weightfactor*faktor1;
310  tell=tell+1;
311  for m=1:Nsub
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)') ); %!!!!!
317  end
318  end %m
319  Mmat(tell,offs+Nsub+1)=faktor1*1;
320  offs=offs + (Nsub+1);
321 
322  end %col
323  end %row
324 
325  bigA2((k-1)*nnn+1:k*nnn,:)=Mmat;
326 
327 end %for k=1:Ns
328 bigA=[bigA;bigA2];
329 bigb=zeros(length(bigA(:,1)),1);
330 
331 end %if auxflag==1
332 
333 %========================================
334 % LOOP FOR CONSTRAINT PROBLEM, TYPE #1 (violating eigenvalues in s2):
335 %========================================
336 for k=1:Ns2
337  sk=s2(k);
338  for row=1:Nc
339  for col=1:Nc
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)));
342  end
343  end
344 
345  %Calculating eigenvalues and eigenvectors:
346  [V,Z] = eig(real(Y)); Z=diag(Z);
347  EE(:,k)=real(Z);
348  if min(real(Z))<0 %any violations
349 
350  % Calculating matrix M2mat; matrix of partial derivatives :
351  tell=0;
352  offs=0;
353 
354  for row=1:Nc
355  ind2=0;
356  for col=row:min(row+bw,Nc)
357  if row==col
358  faktor2=1;
359  else
360  faktor2=2;
361  end
362  tell=tell+1;
363  for m=1:Nsub
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)') );
369  end
370  end %m
371  Ndum=Nsub;
372  Mmat2(tell,offs+Ndum+1)=faktor2*1;
373  offs=offs + (Nsub+1);
374  end %col
375  end %row
376 
377  for n=1:Nc
378  tell=0;
379  V1=V(:,n);
380  for row=1:Nc
381  for col=row:min(row+bw,Nc)
382  if row==col
383  qij=V1(row)^2;
384  else
385  qij=V1(row)*V1(col);
386  end
387  tell=tell+1;
388  Q(n,tell)=qij;
389  end
390  end
391  end
392 
393 
394  B=Q*Mmat2;
395  delz=real(Z);
396  for n=1:Nc %ustabilitet?
397  if delz(n)<0
398  bigB=[bigB;B(n,:)];
399  bigc=[bigc;-TOL+delz(n)];
400  end
401  end
402 
403  end %if max(real(Z))>0 %any violations
404 
405 end %k
406 
407 
408 
409 %========================================
410 % LOOP FOR CONSTRAINT PROBLEM, TYPE #2: (all eigenvalues in s3):
411 %========================================
412 Ns3=length(s3);
413 for k=1:1:Ns3
414  sk=s3(k);
415  for row=1:Nc
416  for col=1:Nc
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)));
419  end
420  end
421  %Calculating eigenvalues and eigenvectors:
422  [V,Z] = eig(real(Y)); Z=diag(Z);
423  EE(:,k)=real(Z);
424 
425  % Calculating matrix M2mat; matrix of partial derivatives :
426  tell=0;
427  offs=0;
428 
429  for row=1:Nc
430  ind2=0;
431  for col=row:min(row+bw,Nc)
432  if row==col
433  faktor2=1;
434  else
435  faktor2=2;
436  end
437  tell=tell+1;
438  for m=1:Nsub
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)') );
444  end
445  end %m
446  Ndum=Nsub;
447  Mmat2(tell,offs+Ndum+1)=faktor2*1;
448  offs=offs + (Nsub+1);
449  end %col
450  end %row
451 
452  for n=1:Nc
453  tell=0;
454  V1=V(:,n);
455  for row=1:Nc
456  for col=row:min(row+bw,Nc)
457  if row==col
458  qij=V1(row)^2;
459  else
460  qij=V1(row)*V1(col);
461  end
462  tell=tell+1;
463  Q(n,tell)=qij;
464  end
465  end
466  end
467 
468 
469  B=Q*Mmat2;
470  delz=real(Z);
471  for n=1:Nc
472  bigB=[bigB;B(n,:)];
473  bigc=[bigc;-TOL+delz(n)];
474  end
475 
476 end %for k=1:1:Ns3
477 
478 if length(bigB)==0
479  return %No passivity violations
480 end
481 
482 
483 c=bigc;
484 
485 bigA=[real(bigA); imag(bigA)];
486 bigb=[real(bigb); imag(bigb)];
487 bigB=[real(bigB)];
488 bigA=sparse(bigA);
489 
490 
491 Acol=length(bigA(1,:));
492 for col=1:Acol
493  Escale(col)=norm(bigA(:,col),2);
494  bigA(:,col)=bigA(:,col)./Escale(col);
495  if length(bigB)>0
496  bigB(:,col)=bigB(:,col)./Escale(col);
497  end
498 end
499 
500 H=bigA.'*bigA;
501 ff=bigA.'*bigb;
502 H=full(H);
503 
504 
505 clear bigA;
506 
507 warning off
508 tic
509 
510 if solver=='quadprog'
511  disp('Starting quadprog...')
512  [dx,lambda]=quadprog(H,ff,-bigB,bigc,[],[],[],[],[],optimoptions('quadprog','MaxIterations',2e4));
513 elseif solver=='cplex '
514  c=0*ff;
515  H0=c.';
516 
517  %F=sparse(H);
518  A=-bigB;
519  H=sparse(H); %A=sparse(A);
520  x_0=zeros(length(H(:,1)));
521  b_U=bigc;
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);
525 
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
530  PriLev = 0;
531  Prob.PriLevOpt = 0;
532  [x, slack, v, rc, f_k] = cplex(c, A, x_L, x_U, b_L, b_U, ...
533  Prob.MIP.cpxControl, [], PriLev, Prob, [], [], [], [], ...
534  [], [], H);
535  dx=x;
536 
537 else
538  'ERROR: invalid value for solver'
539 end
540 
541 disp(['Elapsed time: ' num2str(toc) ' sec'])
542 warning on
543 
544 dx=dx./Escale.';
545 
546 
547 
548 %Converting dx so that the residues become complex:
549 tell=0;
550 for row=1:Nc
551  for col=row:min(row+bw,Nc)
552  for m=1:Nsub
553  tell=tell+1;
554  if cindexsub(m)==1
555  r1=dx(tell); r2=dx(tell+1);
556  dx(tell)=r1+i*r2; dx(tell+1)=r1-i*r2;
557  end
558  end %m
559  tell=tell+1; %Skip SERD
560  end %col
561 end %row
562 
563 
564 %Updating SERC, SERD:
565 tell=0;
566 for row=1:Nc
567  for col=row:min(row+bw,Nc)
568  Ndum=Nsub;
569  for m=1:Nsub
570  tell=tell+1;
571  SERCsubnew(row,col,m)=SERCsubnew(row,col,m)+dx(tell);
572  if row~=col
573  SERCsubnew(col,row,m)=SERCsubnew(col,row,m)+dx(tell);
574  end
575  end
576  SERDnew(row,col)=SERDnew(row,col)+dx(tell+1);
577  if row~=col
578  SERDnew(col,row)=SERDnew(col,row)+dx(tell+1);
579  end
580  tell=tell+1;
581  end
582 end
indvidual element weighting
Definition: QPpassive.m:45
solver
Definition: QPpassive.m:98
common weighting for all matrix elements
Definition: QPpassive.m:47
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
Definition: QPpassive.m:81
bw, SERA, SERC, SERD, SERE, s, weightflag,... % auxflag, weightfactor, SERAsub, SERCsub, s2, s3, TOL QPpassive()
PURPOSE j m
Definition: QPpassive.m:21
common weighting for all matrix elements auxflag
Definition: QPpassive.m:49
function[SERCsubnew, SERDnew]
Definition: QPpassive.m:1
if d time
Definition: comp.m:6
hold off
Definition: comp.m:12
Undo scaling of outgoing poles
Undo scaling of outgoing residues
Turn this into a matrix
Turn this into a with identical frequencies along the rows s
Find a complex rational model for freq domain data for a
for i
Check fit H
Definition: getResidues.m:64
for k
Definition: interch.m:15
for j
Definition: interch.m:13
end if abs(real(dotprod))>rstoerst rstoerst
Square sum(error) of solution aaa=0.0
disp("done")