Sunday, September 29, 2013

Ill-posed problem

A client was solving a (large, non-linear) problem and got as message back:

ill-posed problem, solution status is unknown

The manual at http://www.gams.com/dd/docs/solvers/mosek.pdf did not give any help. This message seems to indicate the modeler (me) did something wrong. However I am really sure the model is just fine: smooth and differentiable everywhere and even convex.

Solver messages are really important (they’ll help the user when they are in trouble), and I think many of these messages are not very good; they often seem to be made up after a long day of coding without too much thought. A good message would probably try to answer the obvious question: “And what now?”. If at all possible it should help the user fix the problem (may be even adding some information about which equations and variables are involved).

Instead of fixing the so-called ill-posed problem we used a newer version of the solver, and now we obtained an optimal solution.

Sometimes it can help to have different solvers available. In GAMS you can then automate:

option nlp=minos;
solve
mod1 minimizing z using nlp;
if
(mod1.modelstat > 2,
*   not optimal or locally optimal

  
option nlp=conopt;
  
solve
mod1 minimizing z using nlp;
);

Complex loop vs complex sum in GAMS

My original formulation was a sum. Ugly and complex but it works; unfortunately it took a long time 1616 seconds. After a few “grande dark roasts” I rewrote it as a loop. Much better: 0 seconds! I don’t understand exactly why.

* fast: 0 seconds
loop((TechYieldname,fpumap(fpuall,fpu),cropmap(cropAll,crop),cropjmap(crop,j),LandMap(LandAll,Land),tech,pt(p,t))$UserTechYieldDriver(TechYieldname,FpuAll,CropAll,LandAll,Tech,p),
   YldTechGRX00a(TechYieldname,j,fpu,land,tech,t) =
        UserTechYieldDriver(TechYieldname,FpuAll,CropAll,LandAll,Tech,p);
);


* slow: 1616 seconds

YldTechGRX00b(TechYieldname,j,fpu,land,tech,t) =
sum((fpumap(fpuall,fpu),cropmap(cropAll,crop),cropjmap(crop,j),LandMap(LandAll,Land),pt(p,t)),UserTechYieldDriver(TechYieldname,FpuAll,CropAll,LandAll,Tech,p));