| (!******************************************************
   Mosel Example Problems
   ======================
   file inscribedsquare.mos 
   ````````````````````````
   Computes a maximal inscribing square for the curve 
   (sin(t)*cos(t), sin(t)*t), t in [-pi,pi]
   Source: https://www.minlplib.org/inscribedsquare01.html
   x2..x5 are the four values of the parameter t. 
   x6 and x7 are the (x,y) coordinates of the first corner of the square. 
   (x8, x9) is a vector pointing to a second vertex, all the other vertices 
   are given by a combination of these four values. 
   The length of the vector (x8,x9) is exactly the side length of the
   square, which we are maximizing, that is, the square of it, to keep it nicer.
   
   (c) 2023 Fair Isaac Corporation
       author: S. Heipcke, July 2023
*******************************************************!)
model "inscribedsquare"
 uses "mmxnlp"
 parameters
   ALG=1      ! Solver choice:  1: global, 2: SLP, 3: Knitro
 end-parameters
 declarations
   x2,x3,x4,x5,x6,x7,x8,x9: mpvar
 end-declarations
! Variable bounds
 x2 >= -3.14159265358979; x2 <= 3.14159265358979;
 x3 >= -3.14159265358979; x3 <= 3.14159265358979;
 x4 >= -3.14159265358979; x4 <= 3.14159265358979;
 x5 >= -3.14159265358979; x5 <= 3.14159265358979;
 x6 is_free
 x7 is_free
(! Optionally, set initial values:
 setinitval(x2, -3.14159265358979)
 setinitval(x3, -1.5707963267949)
 setinitval(x4, 1.5707963267949)
 setinitval(x5, 1.5707963267949)
 setinitval(x6, 1.22464679914735E-16)
 setinitval(x7, 3.84734138744358E-16)
 setinitval(x8, 1)
 setinitval(x9, 1)
!)
 Obj:= x8^2 + x9^2;
! Constraints
 E2:= sin(x2)*cos(x2) - x6 = 0;
 E3:= sin(x2)*x2 - x7 = 0;
 E4:= sin(x3)*cos(x3) - x6 - x8 = 0;
 E5:= sin(x3)*x3 - x7 - x9 = 0;
 E6:= sin(x4)*cos(x4) - x6 + x9 = 0;
 E7:= sin(x4)*x4 - x7 - x8 = 0;
 E8:= sin(x5)*cos(x5) - x6 - x8 + x9 = 0;
 E9:= sin(x5)*x5 - x7 - x8 - x9 = 0;
 setparam("XNLP_VERBOSE",true)        ! Uncomment to see detailed output
 case ALG of
  1: writeln("Using global solver")
  2: do
     writeln("Using SLP as local solver")
    ! Use multi-start heuristic 
     addmultistart("random points", XNLP_MSSET_INITIALVALUES, 100)
     setparam("XPRS_NLPSOLVER", 1)       ! Use a local NLP solver
     setparam("XNLP_SOLVER", 0)          ! Select SLP as local solver
   end-do
  3: do
     writeln("Using Knitro as local solver")
    ! Use multi-start heuristic 
     addmultistart("random points", XNLP_MSSET_INITIALVALUES, 100)
     setparam("XPRS_NLPSOLVER", 1)       ! Use a local NLP solver
     setparam("XNLP_SOLVER", 1)          ! Select Knitro as local solver
   end-do
 end-case
 maximize(Obj)
 writeln("Solution value: ", getobjval)
 writeln("Corner point: ", x6.sol, ",", x7.sol)
 writeln("Side vector: ", x8.sol, "  ", x9.sol)
 writeln("t=", x2.sol, "  ", x3.sol, "  ", x4.sol, "  ", x5.sol)
 
end-model
 | 
| (!******************************************************
   Mosel Example Problems
   ======================
   file inscribedsquare_graph.mos 
   ``````````````````````````````
   Computes a maximal inscribing square for the curve 
   (sin(t)*cos(t), sin(t)*t), t in [-pi,pi]
   Source: https://www.minlplib.org/inscribedsquare01.html
   x2..x5 are the four values of the parameter t. 
   x6 and x7 are the (x,y) coordinates of the first corner of the square. 
   (x8, x9) is a vector pointing to a second vertex, all the other vertices 
   are given by a combination of these four values. 
   The length of the vector (x8,x9) is exactly the side length of the
   square, which we are maximizing, that is, the square of it, to keep it nicer.
   
   - Graphical representation of results -
   
   (c) 2023 Fair Isaac Corporation
       author: S. Heipcke, July 2023
*******************************************************!)
model "inscribedsquare"
 uses "mmxnlp", "mmsvg"
 parameters
   ALG=1      ! Solver choice:  1: global, 2: SLP, 3: Knitro
 end-parameters
 declarations
   x2,x3,x4,x5,x6,x7,x8,x9: mpvar
 end-declarations
! Variable bounds
 x2 >= -3.14159265358979; x2 <= 3.14159265358979;
 x3 >= -3.14159265358979; x3 <= 3.14159265358979;
 x4 >= -3.14159265358979; x4 <= 3.14159265358979;
 x5 >= -3.14159265358979; x5 <= 3.14159265358979;
 x6 is_free
 x7 is_free
(! Optionally, set initial values:
 setinitval(x2, -3.14159265358979)
 setinitval(x3, -1.5707963267949)
 setinitval(x4, 1.5707963267949)
 setinitval(x5, 1.5707963267949)
 setinitval(x6, 1.22464679914735E-16)
 setinitval(x7, 3.84734138744358E-16)
 setinitval(x8, 1)
 setinitval(x9, 1)
!)
 Obj:= x8^2 + x9^2;
! Constraints
 E2:= sin(x2)*cos(x2) - x6 = 0;
 E3:= sin(x2)*x2 - x7 = 0;
 E4:= sin(x3)*cos(x3) - x6 - x8 = 0;
 E5:= sin(x3)*x3 - x7 - x9 = 0;
 E6:= sin(x4)*cos(x4) - x6 + x9 = 0;
 E7:= sin(x4)*x4 - x7 - x8 = 0;
 E8:= sin(x5)*cos(x5) - x6 - x8 + x9 = 0;
 E9:= sin(x5)*x5 - x7 - x8 - x9 = 0;
 setparam("XNLP_VERBOSE",true)        ! Uncomment to see detailed output
 case ALG of
  1: writeln("Using global solver")
  2: do
     writeln("Using SLP as local solver")
    ! Use multi-start heuristic 
     addmultistart("random points", XNLP_MSSET_INITIALVALUES, 100)
     setparam("XPRS_NLPSOLVER", 1)       ! Use a local NLP solver
     setparam("XNLP_SOLVER", 0)          ! Select SLP as local solver
   end-do
  3: do
     writeln("Using Knitro as local solver")
    ! Use multi-start heuristic 
     addmultistart("random points", XNLP_MSSET_INITIALVALUES, 100)
     setparam("XPRS_NLPSOLVER", 1)       ! Use a local NLP solver
     setparam("XNLP_SOLVER", 1)          ! Select Knitro as local solver
   end-do
 end-case
 maximize(Obj)
 writeln("Solution value: ", getobjval)
 writeln("Corner point: ", x6.sol, ",", x7.sol)
 writeln("Side vector: ", x8.sol, "  ", x9.sol)
 writeln("t=", x2.sol, "  ", x3.sol, "  ", x4.sol, "  ", x5.sol)
! **** Display the solution as user graph ****
 declarations
   RT,P: list of real
 end-declarations
! Set the size of the displayed graph
 svgsetgraphscale(100)
 svgsetgraphlabels("x","y")
 svgsetgraphviewbox(-1,0,2.5,2.5)
 
! Draw the graph of the curve
 svgaddgroup("G", "Enclosing graph") 
 STEP:=100
 OFFSET:=0.75    ! Translation offset to avoid negative coordinates in SVG
 forall(i in 0..STEP) RT+=[-M_PI+i/STEP*2*M_PI]
 svgaddline(sum(t in RT) [sin(t)*cos(t)+OFFSET, sin(t)*t])
! Draw the solution square
 svgaddgroup("S", "Square")
 P:=[x6.sol+OFFSET, x7.sol, x6.sol+x8.sol+OFFSET, x7.sol+x9.sol,
     x6.sol+x8.sol-x9.sol+OFFSET, x7.sol+x9.sol+x8.sol, x6.sol-x9.sol+OFFSET, x7.sol+x8.sol]
 (! Same as:
 P:=sum(t in [x2.sol,x3.sol,x5.sol,x4.sol]) [sin(t)*cos(t)+OFFSET, sin(t)*t] 
 !)
 writeln(P)
 svgaddpolygon(P)
 svgaddtext(0.15,2.25,"Solution with " + if(ALG=1, "Global", if(ALG=2, "SLP", "Knitro")) +
   ": "+textfmt(getobjval,6,5))
 svgsetstyle(svggetlastobj, SVG_COLOR, SVG_BLACK)
 svgsave("inscribedsq"+ALG+".svg")
 svgrefresh
 svgwaitclose("Close browser window to terminate model execution.", 1)
end-model
 |