416 lines
14 KiB
Mathematica
416 lines
14 KiB
Mathematica
|
|
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
|