function varargout = gams2yalmip(fileName,filenameOut); % GAMS2YALMIP Converts GAMS model to YALMIP % % [F,h] = GAMS2YALMIP(gamsfile,yalmipfile) converts the GAMS model in % the file 'gamsfile' to a YALMIP mpodel % % Input % GAMSFILE : Char with filename for GAMS model % YALMIPFILE : Char with filename for YALMIP model (optional) % % Output % F : LMI object with constraints (optional) % h : SDPVAR object with objective (optional) % Author Based on original implementation by M. Kojima (readGMS.m) writetofile = (nargout == 0) | (nargin>1); fileName = [fileName '.gms']; fileName = strrep(fileName,'.gms.gms','.gms'); % Reading the GAMs file "fileName" fileIDX = fopen(fileName,'r'); if fileIDX==-1 error('File not found') end if writetofile if nargin == 2 filenameOut = [filenameOut '.m']; filenameOut = strrep(filenameOut,'.m.m','.m'); else filenameOut = strrep(fileName,'.gms','.m'); end fileOUT = fopen(filenameOut,'wb'); if fileOUT==-1 error('Could not create output-file') end end statusSW = 1; noOfEquations = 0; pp = 1; posVarNames = []; negVarNames = []; lastline = ''; while statusSW == 1 [statusSW,oneLine] = getOneLine(fileIDX); if statusSW == 1 lastline = oneLine; [keyword,oneLine] = strtok(oneLine); if strcmp('Variables',keyword) varNames = []; p = 0; [varNames,p,moreSW] = getListOfNames(oneLine,varNames,p); while moreSW == 1 [statusSW,oneLine] = getOneLine(fileIDX); [varNames,p,moreSW] = getListOfNames(oneLine,varNames,p); end noOfVariables = size(varNames,2); lbd = -inf* ones(1,noOfVariables); ubd = inf* ones(1,noOfVariables); fixed = lbd; elseif strcmp('Positive',keyword) [keyword,oneLine] = strtok(oneLine); if strcmp('Variables',keyword) p = 0; [posVarNames,p,moreSW] = getListOfNames(oneLine,posVarNames,p); while moreSW == 1 [statusSW,oneLine] = getOneLine(fileIDX); [posVarNames,p,moreSW] = getListOfNames(oneLine,posVarNames,p); end end elseif strcmp('Negative',keyword) [keyword,oneLine] = strtok(oneLine); if strcmp('Variables',keyword) p = 0; [negVarNames,p,moreSW] = getListOfNames(oneLine,negVarNames,p); while moreSW == 1 [statusSW,oneLine] = getOneLine(fileIDX); [negVarNames,p,moreSW] = getListOfNames(oneLine,negVarNames,p); end end elseif strcmp('Equations',keyword) equationNames = []; p = 0; [equationNames,p,moreSW] = getListOfNames(oneLine,equationNames,p); while moreSW == 1 [statusSW,oneLine] = getOneLine(fileIDX); [equationNames,p,moreSW] = getListOfNames(oneLine,equationNames,p); end noOfEquations = size(equationNames,2); listOfEquations = []; elseif pp <= noOfEquations if strcmp(strcat(equationNames{pp},'..'),keyword) oneLinetmp = oneLine; % to remove blank around * while ~isempty(strfind(oneLinetmp,' *')) | ~isempty(strfind(oneLinetmp,'* ')) if ~isempty(strfind(oneLinetmp, ' *')) loca = strfind(oneLinetmp,' *'); loca = loca -1; oneLinetmp=strcat(oneLinetmp(1:loca),oneLinetmp(loca+2:size(oneLinetmp,2))); elseif ~isempty(strfind(oneLinetmp, '* ')) loca = strfind(oneLinetmp,'* '); oneLinetmp=strcat(oneLinetmp(1:loca),oneLinetmp(loca+2:size(oneLinetmp,2))); end end oneLine = oneLinetmp; listOfEquations{pp} = oneLine; pp = pp+1; end elseif (0 < noOfEquations) & (noOfEquations < pp) goon = 1; while goon [oneVarName,bound] = strtok(keyword,'. '); for i=1:noOfVariables if strcmp(oneVarName,varNames{i}) asciiVal = strtok(oneLine,' =;'); if strcmp(bound,'.lo') %| strcmp(bound,'.l') lbd(1,i) = str2num(asciiVal); elseif strcmp(bound,'.up') %| strcmp(bound,'.u') ubd(1,i) = str2num(asciiVal); elseif strcmp(bound,'.fx') fixed(1,i) = str2num(asciiVal); end end end if strfind(oneLine,';') oneLine = oneLine(min(strfind(oneLine,';'))+1:end); [keyword,oneLine] = strtok(oneLine); goon = ~isequal('',keyword); else goon = 0; end end end end end % Figure out objective from last line minimize = 1; dirstart = strfind(lastline,'minimizing '); obj = '[]'; if ~isempty(dirstart) [aux,obj] = strtok(lastline(dirstart:end)); else dirstart = strfind(lastline,'maximizing '); if ~isempty(dirstart) [aux,obj] = strtok(lastline(dirstart:end)); minimize = -1; else minimize = 0; end end obj = strrep(strrep(obj,';',''),' ',''); objective_in_equations = 0; for i = 1:length(listOfEquations) % If the objective variable is found in several equations, we define it % as a variable, and add all constraints, instead of assigninging it % from the typical objvar + f(x) =E= 0 expression if ~isempty(strfind(listOfEquations{i},obj)) objective_in_equations = objective_in_equations +1; end end if objective_in_equations>1 treat_obj_as_var = 1; else treat_obj_as_var = 0; end if writetofile fprintf(fileOUT,['%% Model generated from ' fileName '\n']); [d] = yalmip('ver'); fprintf(fileOUT,['%% Created ' datestr(now) ' using YALMIP R' d '\n\n']); fprintf(fileOUT,'%% Setup a clean YALMIP environment \n'); fprintf(fileOUT,'yalmip(''clear'') \n\n'); %fprintf(fileOUT,'%% Define non-standard operators \n'); %fprintf(fileOUT,'sqr = @(x) x.*x;\n\n'); % Define all variables, except objvar fprintf(fileOUT,'%% Define all variables \n'); end for i = 1:length(varNames) eval([varNames{i} ' = sdpvar(1);']); if writetofile & (~isequal(varNames{i},obj) | treat_obj_as_var) fprintf(fileOUT,[varNames{i} ' = sdpvar(1);\n']); end end if writetofile fprintf(fileOUT,'\n'); end if minimize if ~treat_obj_as_var if writetofile & objective_in_equations<=1 fprintf(fileOUT,'%% Define objective function \n'); end % find objvar + ... == 0 for i = 1:length(listOfEquations) if strfind(listOfEquations{i},obj) %objeq = strrep(listOfEquations{i},'=E=','=='); objeqL = listOfEquations{i}(1:strfind( listOfEquations{i},'=E=')-1); objeqR = listOfEquations{i}(strfind( listOfEquations{i},'=E=')+3:end); objeqR = strrep(objeqR,';',''); % put objective on left side if strfind(objeqR,obj) temp = objeqL; objeqL = objeqR; objeqR = objeqL; end k = strfind(objeqL,obj); prevplus = strfind(objeqL(1:k-1),'+'); prevminus = strfind(objeqL(1:k-1),'-'); if isempty(prevplus) & isempty(prevminus) thesign = 1; else prevsign = objeqL(max([prevplus prevminus])); if isequal(prevsign,'+') thesign = 1; else thesign = -1; end end thesign = thesign*minimize; obj = [strrep(objeqL,obj,'0') '-( ' objeqR ')']; obj = strrep(obj,'**','^'); obj = strrep(obj,'sqrt(','sqrtm('); obj = strrep(obj,'errorf(','erf('); % obj = strrep(strrep(strrep(obj,'( 0)','0'),'0 -0','0'),'+ 0 ',''); % obj = strrep(strrep(strrep(obj,'( 0)','0'),'0 -0','0'),'+ 0)',''); obj = strrep(obj,' + ','+'); obj = strrep(obj,'+0)',')'); obj = strrep(obj,'POWER','power'); obj(obj==' ') = ''; if writetofile if thesign == -1 fprintf(fileOUT,['objective = ' obj ';\n']); else obj = ['-(' obj ')']; obj = strrep(obj,'+0)',')'); obj = strrep(obj,'- ','-'); fprintf(fileOUT,['objective = ' obj ';\n']); end end objsdp = (-thesign)*eval(obj); listOfEquations = {listOfEquations{1:i-1},listOfEquations{i+1:end}}; break end end if writetofile fprintf(fileOUT,'\n'); end end end % Convert to YALMIP syntax for i = 1:length(listOfEquations) listOfEquations{i} = strrep(listOfEquations{i},'=E=','=='); listOfEquations{i} = strrep(listOfEquations{i},'=L=','<='); listOfEquations{i} = strrep(listOfEquations{i},'=G=','>='); end % Add variable bounds for i = 1:length(varNames) if any(strcmp(varNames{i},posVarNames)) lbd(i) = 0; end if any(strcmp(varNames{i},negVarNames)) ubd(i) = 0; end if ~isequal(varNames{i},obj) | treat_obj_as_var string = ''; if ~isinf(fixed(i)) string = [string num2str(fixed(i)) ' == ' varNames{i}]; elseif ~isinf(lbd(i)) string = [string num2str(lbd(i)) ' <= ' varNames{i}]; if ~isinf(ubd(i)) string = [string ' <= ' num2str(ubd(i))]; end elseif ~isinf(ubd(i)) string = [string varNames{i} ' <= ' num2str(ubd(i)) ]; end if ~isequal(string,'') listOfEquations{end+1} = string; end end end if length(listOfEquations)>0 if writetofile fprintf(fileOUT,'%% Define constraints \n'); end F = ([]); if writetofile fprintf(fileOUT,['F = ([]);' '\n']); end for i = 1:length(listOfEquations) listOfEquations{i} = strrep(listOfEquations{i},';',''); % string = ['F = F + (' listOfEquations{i} ',' '''' listOfEquations{i} '''' ');']; string = ['F = [F, ' strtrim(listOfEquations{i}) '];']; string = strrep(string,'**','^'); string = strrep(string,'sqrt(','sqrtm('); string = strrep(string,'errorf(','erf('); string = strrep(string,'+',' + '); string = strrep(string,' ',''); string = strrep(string,' ',''); string = strrep(string,' - ','-'); string = strrep(string,'POWER','power'); string = strtrim(string); string(string==' ') = ''; eval(string); if writetofile fprintf(fileOUT,[string '\n']); end end if writetofile fprintf(fileOUT,'\n'); end else F = ([]); if writetofile fprintf(fileOUT,'%% Define constraints \n'); end if writetofile fprintf(fileOUT,['F = ([]);' '\n']); end end if writetofile fprintf(fileOUT,'%% Solve problem\n'); if treat_obj_as_var fprintf(fileOUT,'sol = solvesdp(F,objvar,sdpsettings(''solver'',''bmibnb'',''allownonconvex'',1));\n'); else fprintf(fileOUT,'sol = solvesdp(F,objective,sdpsettings(''solver'',''bmibnb'',''allownonconvex'',1));\n'); end fprintf(fileOUT,'mbg_assertfalse(sol.problem)\n'); fprintf(fileOUT,'mbg_asserttolequal(double(objective), , 1e-2);'); fclose(fileOUT); end if nargout > 0 varargout{1} = F; if nargout > 1 varargout{2} = objsdp; end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [statusSW,oneLine] = getOneLine(dataFID); flowCTRL = 0; oneLine = ''; while (feof(dataFID)==0) & (flowCTRL== 0) inputLine = fgetl(dataFID); % inputLine len = length(inputLine); if (len > 0) & (inputLine(1)~='*') p=1; while (p<=len) & (inputLine(p)==' ') p = p+1; end if (p<=len) % & (inputLine(p) ~= '*') % oneLine % inputLine % Kojima 11/06/04; to meet MATLAB 5.2 if isempty(oneLine) oneLine = inputLine(p:len); else oneLine = strcat(oneLine,inputLine(p:len)); end % Kojima 11/06/04; to meet MATLAB 5.2 % temp = strfind(inputLine,';'); temp = findstr(inputLine,';'); if isempty(temp) == 0 flowCTRL=1; end end end end if flowCTRL==0 oneLine = ''; statusSW = -1; else statusSW = 1; end return %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [varNames,p,moreSW] = getListOfNames(oneLine,varNames,p); while (length(oneLine) > 0) [oneName,remLine] = strtok(oneLine,' ,'); if length(oneName) > 0 p = p+1; varNames{p} = oneName; end oneLine = remLine; end lenLastVar = length(varNames{p}); if varNames{p}(lenLastVar) == ';' moreSW = 0; if lenLastVar == 1 p = p-1; else varNames{p} = varNames{p}(1:lenLastVar-1); end else moreSW = 1; end return