About matlab's LCP solver

Please don't post Bullet support questions here, use the above forums instead.
jiangwei
Posts: 23
Joined: Wed Nov 30, 2005 11:07 am
Location: China

About matlab's LCP solver

Post by jiangwei »

These is matlab's LCP solver used Lemke's agorithm,but i just don't understand this part :" else % otherwise pick among set of max d
theta=max(d(j));
lvindex=find(d(j)==theta);
lvindex=j(ceil(length(lvindex)*rand)); % if multiple choose randomly
end
"
why they must choose the max "d" when they had get a minimum ratio .
for degenerated problem??? I don't know ,who can tell me .
thanks!

matlab's LCP solver wrote:function [z,err] = lemke(M,q,z0)
% syntax: [z,err] = lemke(M,q,z0)
% LEMKE Solves linear complementarity problems (LCPs).
% An LCP solves
% Mz+q >=0, z>=0, z'(Mz+q)=0.
% The input z0 defines a starting basis; it can be either
% an initial guess of the solution or a vector of zeros and ones
% with ones representing those z(i) thought to be non-zero in the
% solution. For example, passing z=[1.5;0;2.2] has the same
% effect as passing z=[1;0;1].
% If z0 is omitted the origin is used as a starting basis.
% ERR returns an error condition:
% 0: Solution found
% 1: Maximum iterations exceeded
% 2: Unbounded ray termination
% If NARGOUT==1, a warning message is displayed instead.
%
% ALGORITHM
% Uses a modified Lemke's algorithm (complementary pivoting)
% with a covering ray of ones. The algorithm is modified to
% allow a user defined initial basis.

n = length(q);
zer_tol = 1e-5;
piv_tol = 1e-8;
maxiter = min([1000 25*n]);
err=0;

% Trivial solution exists
if all(q >= 0.)
z=zeros(n,1); return;
end
z = zeros(2*n,1);
j = zeros(n,1);

% Determine initial basis
if nargin<3
bas=(n+1:2*n)';
B = -speye(n);
else
bas=[find(z0>0);n+find(z0<=0)];
B = [sparse(M) -speye(n)];
B = B(:,bas);
end

% Determine initial values
x=-(B\q);

% Check if initial basis provides solution
if all(x>=0)
z(bas)=x; z=z(1:n);
return
end

t = 2*n+1; % Artificial variable
entering=t; % is the first entering variable

% Determine initial leaving variable
[tval,lvindex]=max(-x);
leaving=bas(lvindex);

bas(lvindex)=t; % pivot in the artificial variable
x=x+tval;
x(lvindex)=tval;
B(:,lvindex)=-B*ones(n,1);

% Main iterations begin here
for iter=1:maxiter
% Check if done; if not, get new entering variable
if (leaving == t) break
elseif (leaving <= n)
entering = n+leaving;
Be = sparse(leaving,1,-1.0,n,1);
else
entering = leaving-n;
Be = M(:,entering);
end
d = B\Be;

% Find new leaving variable
j=find(d>piv_tol); % indices of d>0
if isempty(j) % no new pivots - ray termination
err=2;
break
end
theta=min((x(j)+zer_tol)./d(j)); % minimal ratios, d>0
j=j(find((x(j)./d(j))<=theta)); % indices of minimal ratios, d>0
lvindex=find(bas(j)==t); % check if artificial among these
if ~isempty(lvindex) % Always use artifical if possible
lvindex=j(lvindex);
else % otherwise pick among set of max d
theta=max(d(j));
lvindex=find(d(j)==theta);
lvindex=j(ceil(length(lvindex)*rand)); % if multiple choose randomly
end
leaving=bas(lvindex);

% Perform pivot
ratio=x(lvindex)./d(lvindex);
x = x - ratio*d;
x(lvindex) = ratio;
B(:,lvindex) = Be;
bas(lvindex) = entering;
end % end of iterations
if iter>=maxiter & leaving~=t err=1; end

z(bas) = x; z = z(1:n);

% Display warning messages if no error code is returned
if nargout<2 & err(1)~=0
s='Warning: solution not found - ';
if err(1)==2
disp([s 'Unbounded ray']);
elseif err(1)==1
disp([f 'Iterations exceeded limit']);
end
end