Dynamic-Calibration/utils/YALMIP-master/extras/gams2yalmip.m

416 lines
14 KiB
Mathematica
Raw Normal View History

2019-12-18 11:25:45 +00:00
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