-
Notifications
You must be signed in to change notification settings - Fork 0
/
ehqp_dual.m
94 lines (77 loc) · 2.89 KB
/
ehqp_dual.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
function [ lambdak ]= ehqp_dual(kl,y,h,Y);
% ehqp_dual computes the dual optimum (Lagrange multipliers for stage "kl",
% being given the primal optimum expressed in the Y basis.
% This function corresponds to Alg. 2 of the paper. The w_k^*
% is also computed.
%% Synopsis:
% lambda = ehqp_dual(kl,y,h,Y)
%% Input:
% kl id of the level for which the multipliers are computed.
% y is the primal optimum in the Y basis computed by ehqp_primal.
% h "h" structure storing all the HQP data.
% Y right basis of the HCOD.
%% Output:
% lambdak multipliers corresponding to the level "kl". The results is
% partitioned for each levels i=1:kl into a cell. w_kl^*
% corresponds to lambdak{kl}.
%
% This function corresponds to Alg. 2 of the paper "Hiearchical Quadratic
% Programming" (Part I).
%
% Copyright Nicolas Mansard -- LAAS/CNRS
% -- and Adrien Escande -- JRL/CNRS
% -- cf. LICENSE.txt
%
p=length(h);
nh=size(Y,2);
lambdak = {};
% Octave needs to know that y is a col vector.
if length(y)==1 y(2,1)=0; end
% ------------------------------------------------------------------------------
% 1. Compute rho: rho = Y'*J'*( e-J*x )
if kl>p
% 1. [Level p+1]: Try to minimize the norm of the solution: this case is explored
% in Sec. I-4.5.
rhobar = -y;
else
% 1. [Level k<=p]: Compute the slack w in the W basis:
% ===> W'*w = W'*A*x - b = M0*ybar - W0'b
massert( not(exist('hk')) ,'Error, hk should have been cleared.');
hk=h(kl);
iw=hk.iw; im=hk.im; r=hk.r; n=hk.n; ra=hk.ra; rp=hk.rp; m=hk.m;
im0 = im(1:n);
im1 = im(n+1:end);
M0 = hk.H(im0,1:rp);
W0 = hk.W(iw,im0);
b = hk.b( hk.activeb );
if size(b,2)==0 b=b'; end % Octave patch
rho = M0*y(1:rp) - W0'*b; % Alg 2#4
lambdak{kl} = W0*rho; % Alg 2#5
rhobar = -M0'*rho; % Alg 2#6
clear hk;
clear iw im r n ra rp m im0 im1 M0 W0 b;
end
% ------------------------------------------------------------------------------
% 2.a Compute for the first kl-1 levels the multipliers: lambda = W' [ML]^H rho
for k=kl-1:-1:1
massert( not(exist('hk')) ,'Error, hk should have been cleared.');
hk=h(k);
iw =hk.iw; im=hk.im; r=hk.r; n=hk.n; ra=hk.ra; rp=hk.rp; m=hk.m;
im0=im(1:n); im1=im(n+1:end);
if r>0
L = hk.H(im1,rp+1:ra);
M1 = hk.H(im1,1:rp);
W1 = hk.W(iw,im1);
rho = rhobar(rp+1:ra); % Alg 2#8
rhobar = rhobar(1:rp,1);
rho = L'\rho; % Alg 2#9
lambdak{k} = W1*rho; % Alg 2#10
if k>1
rhobar = rhobar - M1'*rho; % Alg 2#11
end
else
lambdak{k} = zeros(m,1);
end
clear hk;
clear iw im r n ra rp m im0 im1 M1 W1 ;
end