function output = callsdplr(interfacedata) % Author Johan Löfberg % $Id: callsdplr.m,v 1.8 2005/12/15 13:21:16 joloef Exp $ % Retrieve needed data options = interfacedata.options; F_struc = interfacedata.F_struc; c = interfacedata.c; K = interfacedata.K; ub = interfacedata.ub; lb = interfacedata.lb; lowrankdetails = interfacedata.lowrankdetails; % Create the parameter structure pars = options.sdplr; pars.printlevel = options.verbose; % ********************************************* % Bounded variables converted to constraints % N.B. Only happens when caller is BNB % ********************************************* if ~isempty(ub) [F_struc,K] = addbounds(F_struc,K,ub,lb); end % rmfield is slow... Knew.l = K.l; Knew.s = K.s; K = Knew; if options.savedebug save sdplrdebug F_struc c K pars -V6 end % ********************************************* %FIND LOW RANK STRUCTURES % ********************************************* problem = 0; lrA = []; if ~isempty(lowrankdetails) | (options.sdplr.maxrank>0 & (K.s(1)>0)) showprogress('Detecting low rank data',options.showprogress); sdploc = K.l+cumsum([1 K.s.^2]); k = 1; % FIX : Lazy code copy... [ix,jx,sx] = find(F_struc); if isempty(lowrankdetails) % Okay, this means we have to go through everything... % Get all data in F_struc for later for lmiid = 1:length(K.s) removethese = zeros(1,size(F_struc,2)-1); for i = 1:size(F_struc,2)-1 Fi = reshape(F_struc(sdploc(lmiid):sdploc(lmiid+1)-1,i+1),K.s(lmiid),K.s(lmiid)); if nnz(Fi)>0 [D,V] = getfactors(Fi); if length(D) <= options.sdplr.maxrank lrA(k).cons = i; lrA(k).start = sdploc(lmiid); lrA(k).D = D; lrA(k).V = V; k = k+1; removethese(i) = 1; end end end removethese = find(removethese); if ~isempty(removethese) these = find((sdploc(lmiid+1)-1>= ix) & (ix>=sdploc(lmiid)) & ismember(jx,1+removethese)); sx(these) = 0; end end else % Just check those constraints declared low-rank by user for lrdef = 1:length(lowrankdetails) for lrconstraint = 1:length(lowrankdetails{lrdef}.id) lmiid = lowrankdetails{lrdef}.id(lrconstraint); removethese = zeros(1,size(F_struc,2)-1); checkthese = lowrankdetails{lrdef}.variables; if isempty(checkthese) checkthese = 1:size(F_struc,2)-1; end for i = checkthese Fi = reshape(F_struc(sdploc(lmiid):sdploc(lmiid+1)-1,i+1),K.s(lmiid),K.s(lmiid)); if nnz(Fi)>0 [D,V] = getfactors(Fi); if (options.sdplr.maxrank == 0) | (options.sdplr.maxrank ~= 0 & (length(D) <= options.sdplr.maxrank)) lrA(k).cons = i; lrA(k).start = sdploc(lmiid); lrA(k).D = D; lrA(k).V = V; k = k+1; removethese(i) = 1; end end end removethese = find(removethese); if ~isempty(removethese) these = find((sdploc(lmiid+1)-1>= ix) & (ix>=sdploc(lmiid)) & ismember(jx,1+removethese)); sx(these) = 0; %F_struc(sdploc(lmiid):sdploc(lmiid+1)-1,1+removethese) = 0; end end end F_struc = sparse(ix,jx,sx,size(F_struc,1),size(F_struc,2)); end end % ********************************************* % CALL SDPLR % ********************************************* if options.showprogress;showprogress(['Calling ' interfacedata.solver.tag],options.showprogress);end solvertime = clock; if isempty(lrA) [x_s,y_s,info] = sdplr(F_struc(:,2:end),c,F_struc(:,1),K,pars); else [x_s,y_s,info] = sdplr(F_struc(:,2:end),c,F_struc(:,1),K,pars,lrA); end solvertime = etime(clock,solvertime); % YALMIP format D_struc = x_s; x = -y_s; % No error codes currently... problem = 0; infostr = yalmiperror(problem,interfacedata.solver.tag); % Save ALL data sent to solver if options.savesolverinput solverinput.A = F_struc(:,2:end); solverinput.c = F_struc(:,1); solverinput.b = c; solverinput.K = K; solverinput.pars = pars; else solverinput = []; end % Save ALL data from the solution? if options.savesolveroutput solveroutput.x = x_s; solveroutput.y = y_s; solveroutput.info = info; else solveroutput = []; end % Standard interface output.Primal = x(:); output.Dual = D_struc; output.Slack = []; output.problem = problem; output.infostr = infostr; output.solverinput = solverinput; output.solveroutput= solveroutput; output.solvertime = solvertime; function [D,V] = getfactors(Fi) if nnz(Fi)>0 [v,d] = eig(full(Fi)); d = diag(d); keep = find(abs(d)>1e-6); V = v(:,keep); D = d(keep); % lrA(k).cons = i; % lrA(k).start = sdploc(j); % lrA(k).D = D; % lrA(k).V = V; % k = k+1; else D = []; V = []; end