 # RAPOSa ## Reformulation Algorithm for Polynomial Optimization - Santiago

### Requirements

You can use RAPOSa on the following operating systems:

• Ubuntu 22
• Ubuntu 20
• Ubuntu 18
• CentOS 7
• Windows, requires to have Visual C++ Redistributable for Visual Studio installed in the system (often preinstalled; if not, you can download them from here).
• macOS

### User options

The available options are: (1)

• V: Print the version of RAPOSa.
• boundtightening *string*: Type of bound tightening used (if the problem has integer variables, 'INT' prefix means that the OBBT solves the mixed-integer relaxation as well): NoBT ==> Do not perform bound tightening, OBBT ==> Perform OBBT at root node, FBBT ==> Perform FBBT at each node, OBBT+FBBT ==> Perform OBBT at root node and FBBT at each node, SOCPOBBT ==> Perform SOCP OBBT at root node, SOCPOBBT+FBBT ==> Perform SOCP OBBT at root node and FBBT at each node, SDPOBBT ==> Perform SDP OBBT at root node, SDPOBBT+FBBT ==> Perform SDP OBBT at root node and FBBT at each node (default: OBBT+FBBT). Possible values: NoBT, FBBT, OBBT, INTOBBT, OBBT+FBBT, INTOBBT+FBBT, SOCPOBBT, INTSOCPOBBT, SOCPOBBT+FBBT, INTSOCPOBBT+FBBT, SDPOBBT, SDPOBBT+FBBT.
• branchingconvex *double*: Strategy to choose the branching point. The following convex combination will be the branching value, whete t is the value of this option, opt is the optimal value and middle is the middle point of the interval: (1-t)*opt + t*middle (default: 0.25). Possible values: [0,1].
• branchingrule *string*: Branching rule: max ==> Use maximums of RLT violations, sum ==> Use sums of RLT violations, coeffs ==> Weigh RLT violations with the coefficients of the problem, dual ==> Weigh RLT violations with the dual values of the constraints, range ==> Weigh RLT violations with the range of the variables, density ==> Weigh RLT violations with the density of the variables (default: dual). Possible values: max, sum, coeffs, dual, range, density.
• branchingtol *double*: Tolerance for branching criterion (default: 0.0001). Possible values: [0,inf].
• condnumber *double*: Print a warning if the condition number of a linear problem is greater than this value (default: 0 [do not print]). Possible values: [0,inf].
• feastol *double*: Feasibility tolerance (default: 0.0001). Possible values: [0,inf].
• gurobifeastol *double*: Feasibility tolerance for gurobi when solving the linear relaxations (default: 1e-6). Possible values: [0,inf].
• gurobithreads *integer*: Number of threads gurobi will use (only for linsolver=gurobi) (default: 0 [automatic]). Possible values: [0,inf].
• help: Print the help.
• inls *double*: Frecuency to call the mixed-integer non linear solver: 0 ==> Do not call the non linear solver, negative number t ==> Call the solver every 2^(-t) nodes, positive number t ==> Call the solver every t seconds (default: 0). Possible values: [-inf,inf].
• inlsopts *string*: String with the options for the mixed-integer non linear solver.
• intnonlinsolver *string*: Mixed-integer nonlinear programming solver (the user needs to have the corresponding license and the corresponding executable of the solver in the path, except for bonmin which is freely available) (default: bonmin). Possible values: bonmin, knitro.
• lowerbound_threshold *double*: If the lowerbound is greater than this threshold, RAPOSa will stop (default: inf). Possible values: [-inf,inf].
• maxiter *integer*: Limit of iterations (default: inf). Possible values: [1,inf].
• maxtime *double*: Time limit (in seconds) (default: 300). Possible values: (0,inf].
• maxtime_intnonlinsolver *double*: Time limit (in seconds) for mixed-integer non linear solver (default: inf). Possible values: (0,inf].
• maxtime_nonlinsolver *double*: Time limit (in seconds) for non linear solver (not supported for minos) (default: inf). Possible values: (0,inf].
• nls *double*: Frecuency to call the non linear solver: 0 ==> Do not call the non linear solver, negative number t ==> Call the solver every 2^(-t) nodes, positive number t ==> Call the solver every t seconds (default: -1.5). Possible values: [-inf,inf].
• nlsopts *string*: String with the options for the non linear solver.
• nonlinsolver *string*: Nonlinear programming solver (the user needs to have the corresponding license and the corresponding executable of the solver in the path, except for ipopt which is freely available) (default: ipopt). Possible values: ipopt, knitro, minos, conopt.
• outlev *integer*: 0 ==> Only display solution, 1 ==> Display real time reporting (default: 0). Possible values: [0,1].
• output *string*: Name for the output file in json format (default: do not create an output file).
• repfreq *double*: Display report frequency (in seconds) (default: 30). Possible values: [0,inf].
• sdp: Add SDP constraints to relaxations.
• sdpcuts: Add SDP-based linear cuts to the linear relaxations.
• sdpsolver *string*: SDP solver (default: mosek if the user has a license). Possible values: mosek.
• socp: Add SOCP constraints to relaxations.
• socpsolver *string*: Second-order cone programming solver (default: gurobi if the user has a license, mosek otherwise (it also needs a license)). Possible values: gurobi, mosek.
• tolabs *double*: Absolute convergence tolerance (default: 0.001). Possible values: [0,inf].
• tolrel *double*: Relative convergence tolerance (default: 0.001). Possible values: [0,inf].
• upperbound *double*: Initial upper bound (default: inf). Possible values: [-inf,inf].
• upperbound_threshold *double*: If the upperbound is lower than this threshold, RAPOSa will stop (default: -inf). Possible values: [-inf,inf].
• varbound *double*: Bounds for all unbounded variables. Given a value v, lower bound will be -v and upper bound will be v for each unbounded variable (unstable and under development) (default: 100). Possible values: [0,inf].
• varboundcons *integer*: Add products of bound factors and constraints: 0 ==> Do not add anything, 1 ==> Add products prioritizing more in common variables, 2 ==> Add products prioritizing less in common variables (default: 2). Possible values: [0,2].
• wantsol *integer*: Solution report for AMPL: sum of 1 ==> write .sol file, 2 ==> print primal variable values, 4 ==> print dual variable values, 8 ==> do not print solution message (default: 0 [do not print anything]). Possible values: [0,8].
• warmstart *integer*: 0 ==> Do not use warmstart in linear solver, 1 ==> Use basis warmstart in linear solver, 2 ==> Use solution warmstart in linear solver, 3 ==> Use basis and solution warmstart in linear solver (only for linsolver=gurobi) (default: 1). Possible values: [0,3].

(1) Available options depend on the operating system. This list is for Ubuntu 22.

Not all options are compulsory. The correct way to pass the options is with "-" followed by the corresponding option and the corresponding value, as shown below:


raposa problem.nl -nonlinsolver knitro -output file.out -outlev 1 -repfreq 5 -maxtime 60


Another way to pass the options is through a file called "raposa.options" as shown below:


nonlinsolver knitro
output file.out
outlev 1
repfreq 5
maxtime 60


This file must be in the directory you are executing RAPOSa.

### Example of use

Consider the following polynomial programming problem with box-constrained variables: $$\begin{array}{rl} \text{min} & x^2 + y^2 + x\\ \text{s.t}. & xy\geq 1\\ & 1\leq x \leq 10\\ & 0\leq y \leq 8\\ \end{array}$$

We are going to explain how to solve it using AMPL, Pyomo, JuMP or GAMS. The user must have raposa executable in the system path

#### How to formulate the problem in AMPL and solve it using RAPOSa.

In AMPL, the problem would be written as follows:


var x >=1, <= 10;
var y >=0, <= 8;
minimize f: x^2 + y^2 + x;
subject to g: x*y >= 1;


If you want to solve this with RAPOSa, you have to add the following commands:


option solver raposa;
solve;


If you want to run RAPOSa with specific options, you have to add the following line before the "solve" command*:


option raposa_options 'outlev=1 maxtime=60';


*You can also pass options to RAPOSa using "raposa.options" files as we explained before

#### How to formulate the problem in Pyomo and solve it using RAPOSa.

In Pyomo, the problem would be written as follows:


from pyomo.environ import *
m = ConcreteModel()
m.x = Var(bounds=(1,10))
m.y = Var(bounds=(0,8))
def obj(m):
return (m.x*m.x + m.y*m.y + m.x)
def cons(m):
return (m.x * m.y >= 1)
m.obj = Objective(rule=obj)
m.cons = Constraint(rule=cons)


If you want to solve this with RAPOSa, you have to add the following commands:


opt = SolverFactory('raposa')
opt.solve(m, tee=True)


If you want to run RAPOSa with specific options, you have to add the following lines before the "opt.solve" command*:


opt.options["outlev"] = 1
opt.options["maxtime"] = 60


*You can also pass options to RAPOSa using "raposa.options" files as we explained before

#### How to formulate the problem in JuMP and solve it using RAPOSa.

In JuMP, the problem would be written as follows:


using JuMP, AmplNLWriter
m = Model()
@variable(m, 1 <= x <= 10 )
@variable(m, 0 <= y <= 8 )
@NLobjective(m, Min, x^2 + y^2 + x )
@NLconstraint(m, x*y >= 1.0 )


If you want to solve this with RAPOSa, you have to indicate it in the second line of the previous code:


using JuMP, AmplNLWriter
m = Model(() -> AmplNLWriter.Optimizer("raposa"))
@variable(m, 1 <= x <= 10 )
@variable(m, 0 <= y <= 8 )
@NLobjective(m, Min, x^2 + y^2 + x )
@NLconstraint(m, x*y >= 1.0 )
optimize!(m)


If you want to run RAPOSa with specific options, you have to indicate it in the second line of the previous code as follows*:


m = Model(() -> AmplNLWriter.Optimizer("./raposa",["-outlev=1","-maxtime=60"]))


*You can also pass options to RAPOSa using "raposa.options" files as we explained before

#### How to formulate the problem in GAMS and solve it using RAPOSa.

Unfortunately there is no way to directly solve a model written in GAMS using RAPOSa. However, you can convert the model to AMPL, Pyomo or JuMP by following the instructions in this link. After that, you can solve the problem with RAPOSa following the steps of the previous sections.

#### How to solve a problem in .nl format with RAPOSa

RAPOSa is also compatible with standard .nl files. Solve a problem in .nl format with RAPOSa is easy. You only need to run the following command:


./raposa problem.nl


and RAPOSa will be executed with default options.

If you want to run it with specific options, for example a time limit of 30 seconds and gurobi as linear solver, you should run the following command:


./raposa problem.nl -maxtime 30 -linsolver gurobi


If you want to know all available options, you should run the following command:


./raposa -help


In this case, if you run the command


./raposa problem.nl -outlev 1 -output output.json


you will obtain the following output:


_____             _____    ____    _____
|  __ \     /\    |  __ \  / __ \  / ____|
| |__) |   /  \   | |__) || |  | || (___    __ _
|  _  /   / /\ \  |  ___/ | |  | | \___ \  / _ |
| | \ \  / ____ \ | |     | |__| | ____) || (_| |
|_|  \_\/_/    \_\|_|      \____/ |_____/  \__,_|

===========================================================================================
RAPOSa v4.0.2 (2023.03.09)
This software is free for non-commercial purposes.
Full licence information can be found in the LICENSE.txt file.
Website: https://raposa.usc.es
To cite RAPOSa use: https://doi.org/10.1007/s10898-022-01229-w
===========================================================================================
Linear solver: gurobi
Nonlinear solver: ipopt
=====================================================================================================================
Iteration       Time (s)       Lower Bound       Upper Bound       Relative Gap     Absolute Gap       Feas error
1           0.03            3.0000            3.0000         0.00000000           0.0000       0.00000000

Global solution found after 1 iterations and 0.0268603 seconds.
Objective: 3


and the following "output.json" file:


{
"Total time": 0.0132397,
"Number of iterations": 1,
"Upper bound": 3,
"Lower bound": 3,
"Absolute gap": 1.14956e-08,
"Relative gap": 3.8306e-09,
"Feasilibity error": 0,
"Solution": {
"x" : 1,
"x" : 1
}
}
`