$ontext ====================================================================
LAST MODIFIED: 7 February, 2005
FILENAME: square.gms
PURPOSE: Creates a solve square to compare solve/fail
results. User must input two tracefiles (one for each
solver).
Works for LP, RMIP, NLP, RMINLP, MIP, or MINLP type models.
Each trace file can have model/solve information for
only 1 solver. For example trace1.trc can have info
for all LPs in PerformanceLib for solver A, and trace2.trc
can have information for all LPs using solver B.
REQUIRED INPUTS:
--trace1: GAMS trace file of solver 1
--trace2: GAMS trace file of solver 2
--ntrace1: GENERIC data file 1
--ntrace2: GENERIC data file 2
Users cannot input two tracefile numbers of different type
with the same (n)trace number, i.e.
--trace1=... --ntrace1 is not allowed, only --trace1=... --ntrace2=...
OPTIONAL INPUTS:
--bnd: relative objective function difference. Prints
"optimal" solution in boldface for HTML output
for one solver if the relative objective function
difference is greater than --bnd. (default 1e-5)
--objmin: minimum obj. threshhold. If both solvers report
an obj. less than the threshhold, the objdiff
is computed as absolute difference, otherwise
use relative difference (default 0.1).
--outfile: root names of square output file (default is out
--> out_sqr.txt)
--modelfile: filename containing subset of models to consider.
Useful, if only a subset of models from the
tracefile are to be used in the solver square
comparison.
--resmin: minimum resource time threshold. If both solvers
report a resource time below --resmin, then no
ratio is reported. In this case, both solver times
are considered the same (default 0.05).
--topt4: trace option 4. If specified, then assumes tracefile
is traceopt=4 (default:none)
REMARKS: Each tracefile can contain information from only one (1)
solver for a given set of models. For example, tracefiles
containing solver A and solver B will cause error message
upon compilation.
Discrete and continous models cannot be mixed in an analysis.
Users cannot input two tracefile numbers of different type
with the same (n)trace number, i.e.
--trace1=... --ntrace1 is not allowed, only --trace1=... --ntrace2=...
$offtext ===================================================================
*=== Create trace reading routine (readtrace.gms)
$onecho > %gams.scrdir%readtrace.gms
$eolcom ,#
display '++++ TRACEOPT=3';
Set modelname, modeltype, solvername, nlpdef, mipdef;
Set col /julian, direction,eqnum,varnum,dvarnum,nz,nlnz, optfile,modelstat,solvestat,obj,objest,res,iter,dom,nodes/
Alias(u1,u2,u3,u4,u5,*);
Set domain(*,*,*,*,*);
Table tracedata(*,*,*,*,*,col)
$ondelim
modelname, modeltype, solvername, nlpdef, mipdef, julian, direction,eqnum,varnum,dvarnum,nz,nlnz, optfile,modelstat,solvestat,obj,objest,res,iter,dom,nodes
$offlisting
$include %tracefile%
$onlisting
$offdelim
;
domain(u1,u2,u3,u4,u5)$sum( col, tracedata(u1,u2,u3,u4,u5,col)) = yes;
loop(domain(u1,u2,u3,u4,u5),
modelname(u1) = yes;
modeltype(u2) = yes;
solvername(u3) = yes;
nlpdef(u4) = yes;
mipdef(u5) = yes;
);
*execute 'rm -f tracedata'
$offecho
*=== Convert non-GAMS data files to GAMS trace files
$onecho > %gams.scrdir%tconvawk
{print $1 "," $2 "," $3 ",none,none,-1", $4, "-1,-1,-1,-1,-1,-1," $5 "," $6 "," $7 ",-1," $8 "," $9 ",-1,-1,#"}
$offecho
$if set ntrace1 $call 'awk -F, -f "%gams.scrdir%tconvawk" %ntrace1% > %gams.scrdir%C_%ntrace1%'
$if set ntrace1 $set trace1 %ntrace1%
$if set ntrace2 $call 'awk -F, -f "%gams.scrdir%tconvawk" %ntrace2% > %gams.scrdir%C_%ntrace2%'
$if set ntrace2 $set trace2 %ntrace2%
*=== Error checks
$if not set trace1 $goto errors_notrace1
$if not set trace2 $goto errors_notrace2
$if not exist %trace1% $goto errors_trace1notexist
$if not exist %trace2% $goto errors_trace2notexist
*=== Set defaults
$if not set outfile $set outfile out
$if not set modelfile $goto nomodelfile
*== If only the subset of models as listed in "modelfile" is to be analyzed
Set m(*) the subset of models to consider /
$onempty
$include %modelfile%
$offempty
/;
$echo > %gams.scrdir%tracedata
$if not set ntrace1 $echo '$include %trace1%' >> %gams.scrdir%tracedata
$if not set ntrace2 $echo '$include %trace2%' >> %gams.scrdir%tracedata
$if set ntrace1 $echo '$include %gams.scrdir%C_%ntrace1%' >> %gams.scrdir%tracedata
$if set ntrace2 $echo '$include %gams.scrdir%C_%ntrace2%' >> %gams.scrdir%tracedata
$set tracefile %gams.scrdir%tracedata
$include %gams.scrdir%readtrace
$goto donemodelfile
*=== All models in trace files are to be analyzed
$label nomodelfile
$echo > %gams.scrdir%tracedata
$if not set ntrace1 $echo '$include %trace1%' >> %gams.scrdir%tracedata
$if not set ntrace2 $echo '$include %trace2%' >> %gams.scrdir%tracedata
$if set ntrace1 $echo '$include %gams.scrdir%C_%ntrace1%' >> %gams.scrdir%tracedata
$if set ntrace2 $echo '$include %gams.scrdir%C_%ntrace2%' >> %gams.scrdir%tracedata
$set tracefile %gams.scrdir%tracedata
$include %gams.scrdir%readtrace
Set m(*);
m(modelname) = yes;
$label donemodelfile
*=== Set default options
$if not set bnd $set bnd 1e-5
$if not set objmin $set objmin 1e-1
$if not set resmin $set resmin 5e-2
$if not set tsame $set tsame 10
$if not set tfaster $set tfaster 50
Set bool / no, yes /;
Parameter list_text /no 1, yes 2/;
Parameter list_html/no 1, yes 2/;
Parameter bound "relative objc func difference threshold"
/ %bnd% /
resourcemin "min resource time threshold for ratio"
/ %resmin%/
;
*=== Possible solver outcomes
Set all_results / opt "optimal",
lopt "locally optimal"
feas "feasible",
infeas "infeasible",
unbnd "unbounded",
f "fail"
nd "no data"
/;
Set result_cont(all_results) "possible results for cont. models"
result_disc (all_results) "possible results for discrete models"
;
result_cont(all_results) = yes;
result_disc(all_results) = yes;
result_disc("lopt") = no;
Parameter is_discrete/0/;
Set discrete_mods / MIP, MINLP/;
loop(modeltype,
is_discrete = sum(discrete_mods, sameas(modeltype, discrete_mods));
);
Set result(*), resultA(*), resultB(*);
if(is_discrete,
result(result_disc) = yes;
resultA(result_disc) = yes;
resultB(result_disc) = yes;
else
result(result_cont) = yes;
resultA(result_cont) = yes;
resultB(result_cont) = yes;
);
Alias(solvers,solvername)
Parameter square(*,*,*) GAMS solver results for square;
square(modelname,solvername,result) = 0;
Parameter modstat /0/;
Parameter solstat /0/;
Parameter mstat(*,*,*), sstat(*,*,*);
Parameter i /0/;
*=== Compute totals for square
loop( (modelname(m),modeltype,solvername,nlpdef,mipdef),
i = i+1;
modstat =
tracedata(modelname,modeltype,solvername,nlpdef,mipdef,'modelstat');
solstat =
tracedata(modelname,modeltype,solvername,nlpdef,mipdef,'solvestat');
*=== Assign DISCRETE model square only if data exists
if(is_discrete,
if (modstat and solstat,
if( (modstat=1 or modstat=15) and solstat=1,
square(modelname,solvername,"opt") = yes;
mstat(modelname,solvername,"opt") = modstat;
sstat(modelname,solvername,"opt") = solstat;
elseif(modstat=2),
square(modelname,solvername,"lopt") = yes;
mstat(modelname,solvername,"lopt") = modstat;
sstat(modelname,solvername,"lopt") = solstat;
elseif( (modstat=8 or modstat=16) and
(solstat=1 or solstat=2 or solstat=3 or solstat=4 or solstat=5)),
square(modelname,solvername,"feas") = yes;
mstat(modelname,solvername,"feas") = modstat;
sstat(modelname,solvername,"feas") = solstat;
elseif( (modstat=4 or modstat=5 or modstat=10 or modstat=19)and solstat=1),
square(modelname,solvername,"infeas") = yes;
mstat(modelname,solvername,"infeas") = modstat;
sstat(modelname,solvername,"infeas") = solstat;
elseif( (modstat=3 or modstat=18) and solstat=1 ),
square(modelname,solvername,"unbnd") = yes;
mstat(modelname,solvername,"unbnd") = modstat;
sstat(modelname,solvername,"unbnd") = solstat;
else
square(modelname,solvername,"f") = yes;
mstat(modelname,solvername,"f") = modstat;
sstat(modelname,solvername,"f") = solstat;
);
);
*=== Assign CONTINUOUS model square only if data exists
else
if (modstat and solstat,
if( (modstat=1 or modstat=15) and solstat=1,
square(modelname,solvername,"opt") = yes;
mstat(modelname,solvername,"opt") = modstat;
sstat(modelname,solvername,"opt") = solstat;
elseif( (modstat=2)),
square(modelname,solvername,"lopt") = yes;
mstat(modelname,solvername,"lopt") = modstat;
sstat(modelname,solvername,"lopt") = solstat;
elseif( (modstat=7 or modstat=16 or modstat=17) and
(solstat=1 or solstat=2 or solstat=3 or solstat=4 or solstat=5)),
square(modelname,solvername,"feas") = yes;
mstat(modelname,solvername,"feas") = modstat;
sstat(modelname,solvername,"feas") = solstat;
elseif( (modstat=4 or modstat=5 or modstat=19) and solstat=1),
square(modelname,solvername,"infeas") = yes;
mstat(modelname,solvername,"infeas") = modstat;
sstat(modelname,solvername,"infeas") = solstat;
elseif( (modstat=3 or modstat=18) and solstat=1),
square(modelname,solvername,"unbnd") = yes;
mstat(modelname,solvername,"unbnd") = modstat;
sstat(modelname,solvername,"unbnd") = solstat;
else
square(modelname,solvername,"f") = yes;
mstat(modelname,solvername,"f") = modstat;
sstat(modelname,solvername,"f") = solstat;
);
);
);
);
*=== Assign square for model/solver with no trace data
loop( (modelname,solvername),
if(not sum[(modeltype,nlpdef,mipdef),
tracedata(modelname,modeltype,solvername,nlpdef,mipdef,'modelstat')],
square(modelname,solvername,"nd") = yes;
);
);
*=== Compute result totals
parameter resulttotals(*,*) GAMS solver totals for square;
resulttotals(resultA, resultB) = 0;
Set solverA, solverB;
Parameter i;
i=1;
loop(solvername,
if(i eq 1,
solverA(solvername) = solvername(solvername);
i = 2;
elseif(i eq 2),
solverB(solvername) = solvername(solvername);
);
);
Set solversused(*);
solversused(solvername) = solverA(solvername) + solverB(solvername);
*=== Result totals for square
loop(resultA,
loop(resultB,
resulttotals(resultA, resultB) = sum((m,solverA,solverB),
square(m,solverA,resultA) and square(m, solverB,resultB) );
);
);
*==== Extract resource times
Parameter resA(*) "resource time of solver A",
resB(*) "resource time of solver B"
objA(*) "objective value using solver A"
objB(*) "objective value using solverB"
dir(*) "direction of optimization: 0=min 1=max"
modstatA(*) "model status of solver A"
solstatA(*) "solver status of solver A"
modstatB(*) "model status of solver B"
solstatB(*) "solver status of solver B";
loop( (modelname,modeltype,solverA,nlpdef,mipdef)$m(modelname),
modstat = tracedata(modelname,modeltype,solverA,nlpdef,mipdef,'modelstat');
solstat = tracedata(modelname,modeltype,solverA,nlpdef,mipdef,'solvestat');
if (modstat and solstat,
resA(modelname) =
tracedata(modelname,modeltype,solverA,nlpdef,mipdef,'res');
objA(modelname) =
tracedata(modelname,modeltype,solverA,nlpdef,mipdef,'obj');
dir(modelname) =
tracedata(modelname,modeltype,solverA,nlpdef,mipdef,'direction');
modstatA(modelname) =
tracedata(modelname,modeltype,solverA,nlpdef,mipdef,'modelstat');
solstatA(modelname) =
tracedata(modelname,modeltype,solverA,nlpdef,mipdef,'solvestat');
);
);
loop( (modelname,modeltype,solverB,nlpdef,mipdef)$m(modelname),
modstat = tracedata(modelname,modeltype,solverB,nlpdef,mipdef,'modelstat');
solstat = tracedata(modelname,modeltype,solverB,nlpdef,mipdef,'solvestat');
if (modstat and solstat,
resB(modelname) =
tracedata(modelname,modeltype,solverB,nlpdef,mipdef,'res');
objB(modelname) =
tracedata(modelname,modeltype,solverB,nlpdef,mipdef,'obj');
modstatB(modelname) =
tracedata(modelname,modeltype,solverB,nlpdef,mipdef,'modelstat');
solstatB(modelname) =
tracedata(modelname,modeltype,solverB,nlpdef,mipdef,'solvestat');
);
);
parameter solvernum /0/;
parameter doheader "dummy variable to check if header already written"
ratio "ratio of resource times"
objdiff(*) "relative difference in obj values";
*===========================================================================
*=== Output results to _sqr.htm file
*===========================================================================
file fhtm /%outfile%_sqr.htm/;
put fhtm;
*=== Output square
put / '
Solver Square Comparison - All Models'
/ ''
/ ''
put / 'Solver Square Comparison: Considers all models.
' /;
put / ''
/ ''
/ ' | Date / Time: | '
/ ' %system.date% %system.time% | '
/ '
'
/ '
'
/ '
';
put / 'Solver comparison utility.
'
/ 'Compares all solver return outcomes (for example optimal, '
'locally optimal, infeasible, unbounded,'
/ 'fail) of one solver with all return outcomes of '
'another solver. Interrupt'
/ 'denotes resource or iteration limit has been reached.' /;
solvernum = 0;
loop(solvers,
solvernum = solvernum+1;
put$(solvernum eq 1) / 'Solver ' solvers.tl:0 ' is represented on '
'the left (rows) and ';
put$(solvernum eq 2) / 'solver ' solvers.tl:0 ' on top (columns).'
/ 'See the solver return '
'definitions for return codes.'
);
put / '
'
/ 'Models having trace data only in one trace file are listed in'
/ 'the "no data" column of the other.';
put / '
'
/ ''
/ ' | Tracefile 1 : | '
'%trace1% |
'
/ ' | Tracefile 2 : | '
'%trace2% |
'
/ ' | Solvers used : | ';
solvernum = 0;
loop(solvers,
solvernum = solvernum+1;
put$(solvernum eq 1) '' solvers.tl:0
' |
';
put$(solvernum eq 2) / ' | '
solvers.tl:0 ' |
' /;
);
put / ' | Modeltype(s) | '
'';
loop(modeltype,
put '   ' modeltype.tl:0
);
put ' |
';
put / '
';
put '
' //;
scalar tmp/1/;
solvernum = 0;
put / ''
/ '';
loop(solvers,
solvernum = solvernum+1;
if(solvernum = 1,
put / ' | ';
loop(result,
put / ' ';
tmp=1;
loop(solvername,
if(tmp=2,
put solvername.tl:0 ': ';
else
tmp=tmp+1;
);
);
put / '' all_results.te(result):0
' | ';
);
put / ' total ' solvers.tl:0 ' | ';
);
);
put / '
';
loop(resultA,
put / ''
/ ' ';
solvernum = 1;
loop(solvername,
if(solvernum=1,
put solvername.tl:0 ': ';
);
solvernum=solvernum+1;
);
put '' all_results.te(resultA):0 ' | ';
loop(resultB,
put ' '
if(resulttotals(resultA,resultB),
put ''
resulttotals(resultA, resultB):0:0 '';
else
put '-';
);
put ' | ' /;
);
if ( sum(resultB, resulttotals(resultA, resultB ) ),
put ' '
sum(resultB, resulttotals(resultA, resultB ) ):0:0
' | ';
else
put ' - | ';
)
put / '
';
);
solvernum = 0;
loop(solvers,
solvernum = solvernum+1;
put$(solvernum eq 2) '' / ' | total '
solvers.tl:0 ' | ' ;
);
loop(resultB,
if ( sum(resultA, resulttotals(resultA, resultB ) ),
put / ' '
sum(resultA, resulttotals(resultA, resultB ) ):0:0
' | ';
else
put / ' - | ';
)
);
put / ' ' sum( (resultA,resultB),
resulttotals(resultA,resultB) ):0:0 ' | ' ;
put / '
'
/ '
' //;
put / '
'
put / ''
/ '';
if(is_discrete,
put / ' | Outcome | '
'Model Status | '
'Solver Status |
'
/ ' | optimal | 1 or 15 '
' | 1 |
'
/ ' | locally optimal | 2'
' | any |
'
/ ' | feasible | 8 or 16'
' | 1 or 2 or 3 or 4 or 5 |
'
/ ' | infeasible | '
' 4 or 5 or 10 or 19 | 1 |
'
/ ' | unbounded | 3 or 18'
' | 1 |
'
/ ' | fail | all other '
' | all other |
'
else
put / ' | Outcome | '
'Model Status | '
'Solver Status |
'
/ ' | optimal | 1 or 15'
' | 1 |
'
/ ' | locally optimal | 2'
' | any |
'
/ ' | feasible | '
'7 or 16 or 17 | 1 or 2 or 3 or 4 or 5 |
'
/ ' | infeasible | '
'4 or 5 or 19 | 1 |
'
/ ' | unbounded | '
'3 or 18 | 1 |
'
/ ' | fail | all other'
' | all other |
'
);
put / '
' //
put / '
'
*=== Output models
put / 'Solver Resource Times
'
/ ''
/ '- Models for each solver pair outcome. Listed are the '
/ 'solver resource times TIME(.) in seconds,'
/ 'as well as the ratio RATIO(./.) of'
/ 'resource times for the two solvers if both solved optimally.'
/ '
- Also listed are the objective values OBJ(.) using both solvers.'
/ 'The better solution found is listed in boldface. A solution'
/ 'is considered better, if the relative objective function '
/ 'difference is greater than ';
fhtm.nr = 2;
put / bound:0 '.';
put / 'If both solutions are less than %objmin%, we use the absolute'
/ 'difference.';
put / '
- Solver resource time ratios for a particular model are '
'listed only if one solver has resource greater than '
resourcemin:0 '.';
put / '
'
/ '
';
fhtm.nr = 1;
*=== Output square results for solver outcome pairs
loop( (resultA,resultB),
doheader = yes;
loop( (m(modelname),solverA,solverB),
if( square(modelname,solverA,resultA) and
square(modelname,solverB,resultB),
if(doheader,
put / '';
put / ''solverA.tl:0 ': '
all_results.te(resultA):>25 ' -- ';
put solverB.tl:0 ': '
all_results.te(resultB):>25
'    Back to top
'/;
put / '
'
put / ''
put / ' | Modelname | '
/ ' Time (' solverA.tl:0 ') | '
/ ' Time (' solverB.tl:0 ') | '
/ ' Ratio ('solverA.tl:0 '/'
solverB.tl:0 ') | '
if( not (sameas(resultA,"opt") or sameas(resultA,"lopt") or sameas(resultA,"feas") ),
put / ' Status ('solverA.tl:0
') | ';
elseif(sameas(resultA,"nd")),
put / ' -- | ';
else
put / ' Obj ('solverA.tl:0
') | ';
);
if( not ( sameas(resultB,"opt") or sameas(resultB,"lopt") or sameas(resultB,"feas") ),
put / ' Status ('solverB.tl:0
') | ';
elseif(sameas(resultB,"nd")),
put / ' -- | ';
else
put / ' Obj ('solverB.tl:0
') | ';
);
put / '
';
doheader = no;
);
if( resA(modelname) > 1e-5 and resB(modelname) < 1e-5,
ratio = inf;
elseif( resA(modelname) < 1e-5 and resB(modelname) < 1e-5),
ratio =1;
else
ratio = resA(modelname) / resB(modelname);
);
put / ''
/ ' | ' modelname.tl:0
' | ';
if (not sameas(resultA,"nd"),
put / ' ' resA(modelname):15:4
' | ';
else
put / ' -- | ';
)
if (not sameas(resultB,"nd"),
put / ' ' resB(modelname):15:4
' | ';
else
put / ' -- | ';
)
* === we compute relative objdiff if both obj > objmin,
* === otherwise use absolute difference
if( max( abs(objA(modelname)), abs(objB(modelname))) > %objmin%,
objdiff(modelname) = ( objA(modelname)-objB(modelname) )
/ max( abs(objA(modelname)), abs(objB(modelname)), %objmin%);
else
objdiff(modelname) = ( objA(modelname)-objB(modelname) );
);
* === Output ratios of resource times
if( (sameas(resultA,"opt") or sameas(resultA,"lopt") or sameas(resultA,"feas") ) and
(sameas(resultB,"opt") or sameas(resultB,"lopt") or sameas(resultB,"feas") ),
if( resA(modelname) < resourcemin
and resB(modelname) < resourcemin,
put / ' --- | ';
elseif (ratio = inf),
put / ' ' ratio:16 '.000 | ';
else
put / ' ' ratio:0:3 ' | ';
);
* === Output objective values (maximizing)
if( dir(modelname),
if (objdiff(modelname) > bound,
put / ' ' objA(modelname):40:8
' | '
/ ' ' objB(modelname):20:8
' | ';
elseif (-objdiff(modelname) > bound),
put / ' ' objA(modelname):40:8
' | '
/ ' ' objB(modelname):>20:8
' | ';
else
put / ' ' objA(modelname):40:8
' | '
/ ' ' objB(modelname):20:8
' | ' ;
);
* === Output objective values (minimizing)
else
if (-objdiff(modelname) > bound,
put / ' ' objA(modelname):40:8
' | '
/ ' ' objB(modelname):20:8
' | '/;
elseif (objdiff(modelname) > bound),
put / ' ' objA(modelname):40:8
' | '
/ ' ' objB(modelname):20:8
' | ';
else
put / ' ' objA(modelname):40:8
' | '
/ ' ' objB(modelname):20:8
' | ';
);
);
elseif( (sameas(resultA,"opt") or sameas(resultA,"lopt") or sameas(resultA,"feas") ) ),
put / ' --- | '
/ ' ' objA(modelname):0:8
' | ';
if( not sameas(resultB,"nd"),
put / ' mstat(' modstatB(modelname):2:0
') sstat(' solstatB(modelname):2:0 ') | ';
else
put / ' --- | ';
);
elseif( (sameas(resultB,"opt") or sameas(resultB,"lopt") or sameas(resultB,"feas") )),
put / ' --- | ';
if( not sameas(resultA,"nd"),
put / ' mstat(' modstatA(modelname):2:0
') sstat(' solstatA(modelname):2:0 ') | ';
else
put / ' --- | ';
);
put / ' ' objB(modelname):0:8 ' | ';
else
put / ' --- | ';
if(not sameas(resultA,"nd"),
put / ' mstat(' modstatA(modelname):2:0
') sstat(' solstatA(modelname):2:0 ') | ';
else
put / ' --- | ';
)
if(not sameas(resultB,"nd"),
put / ' mstat(' modstatB(modelname):2:0
') sstat(' solstatB(modelname):2:0 ') | ';
else
put / ' --- | ';
)
);
put / '
';
);
);
if(not doheader,
put / '
'
put / 'Back to top
'
put / '
' ///;
);
);
*=== Output result totals for solver A outcome
loop( resultA,
doheader = yes;
loop( (m(modelname),solverA),
if ( square(modelname,solverA,resultA),
if(doheader,
put / '' ;
put / ''solverA.tl:0 ': '
all_results.te(resultA):0 ':     '
'Back to top
'/;
put / '';
put / ''
put / ' | Modelname | '
/ ' Time (' solverA.tl:0 ') | '
if( not (sameas(resultA,"opt") or sameas(resultA,"lopt") or sameas(resultA,"feas")),
put / ' Status ('solverA.tl:0
') | ';
else
put / ' Obj ('solverA.tl:0
') | ';
);
put / '
';
doheader = no;
);
put / ''
/ ' | ' modelname.tl:0 ' | ';
if(sameas(resultA,"nd") or sameas(resultA,"infeas") or sameas(resultA,"f"),
put / ' -- | ';
else
put / ' ' resA(modelname):15:4
' | ';
);
if( sameas(resultA,"opt") or sameas(resultA,"lopt") or sameas(resultA,"feas"),
put / ' ' objA(modelname):0:8
' | ';
elseif( sameas(resultA,"nd")),
put / ' -- | ';
else
put / ' mstat(' modstatA(modelname):2:0
') sstat(' solstatA(modelname):2:0 ') | ';
);
put / '
';
);
);
if(not doheader,
put / '
'
put / 'Back to top
'
put / '
' ///;
);
);
*=== Output result totals for solver B outcome
display square, resB, objB;
loop( resultB,
doheader = yes;
loop( (m(modelname),solverB),
if ( square(modelname,solverB,resultB),
if(doheader,
put / '' ;
put / ''solverB.tl:0 ': '
all_results.te(resultB):0 ':     '
'Back to top
'/;
put / '';
put / ''
put / ' | Modelname | '
/ ' Time (' solverB.tl:0 ') | '
if( not (sameas(resultB,"opt") or sameas(resultB,"lopt") or sameas(resultB,"feas") ),
put / ' Status ('solverB.tl:0
') | ';
else
put / ' Obj ('solverB.tl:0
') | ';
);
put / '
';
doheader = no;
);
put / ''
/ ' | ' modelname.tl:0 ' | ';
if(sameas(resultB,"nd") or sameas(resultB,"infeas") or sameas(resultB,"f"),
put / ' -- | ';
else
put / ' ' resB(modelname):15:4
' | ';
);
if( sameas(resultB,"opt") or sameas(resultB,"lopt") or sameas(resultB,"feas"),
put / ' ' objB(modelname):0:8 ' | ';
elseif( sameas(resultB,"nd")),
put / ' -- | ';
else
put / ' mstat(' modstatB(modelname):2:0
') sstat(' solstatB(modelname):2:0 ') | ';
);
put / '
';
);
);
if(not doheader,
put / '
'
put / 'Back to top
'
put / '
' ///;
);
);
put / ''
/ '';
putclose fhtm;
$goto noerrors
*=== Error messages
$label errors_notrace1
$log --- ABORTING --trace1 or --ntrace1 option required: Trace file not specified..."
$abort "Aborting because --trace1 or --ntrace1 option not specified"
$label errors_notrace2
$log --- ABORTING --trace2 or --ntrace2 option required: Trace file not specified..."
$abort "Aborting because --trace2 or --ntrace2 option not specified"
$label errors_trace1notexist
$log "--- ABORTING --trace1 or --ntrace1 file not found..."
$abort "Aborting because trace or ntrace file 1 not found"
$label errors_trace2notexist
$log --- ABORTING --trace2 or --ntrace2 file not found...
$abort "Aborting because trace or ntrace file 2 not found"
$label noerrors
*=== Warning message if more than two solvers defined in trace file
file fput / "%gams.scrdir%solvers.txt" /;
put fput "--- ";
if (card(solvers) > 2,
loop(solvers,
put fput solvers.tl:0 " ";
);
putclose fput;
execute "echo ---"
execute "echo --- WARNING: more than two solvers defined in trace files."
execute "echo --- Results may not be what you intend."
execute "echo --- Solvers defined are:"
execute "head %gams.scrdir%solvers.txt"
execute "echo ---"
);
putclose fput;