nloptr provides an R interface to NLopt, a free/open-source library for nonlinear optimization providing a common interface to a number of different optimization routines which can handle nonlinear constraints and lower and upper bounds for the controls.
While reading through WRE, I noticed that Rdefines.h is no longer maintained, and that is what @jyypma used in nloptr.c, so I figured we should bring nlopt.c more in line with the API. While going through the file I made some other changes (see the commit log for exact details). They include:
Import Rinternals.h instead of Rdefines.h and manually define the necessary coercion shortcuts.
Bugfix:ranseed was processed through the AS_INTEGER macro, which casts to int although nlopt_srand requires an unsigned long. It is now coerced to a double and then cast to the unsigned long retaining the full range of random seeds.
Convert loop variables to size_t where appropriate and declare them inside the for loops for safety.
Use more R-centric accessor functions where appropriate (e.g. asReal, asInteger).
Convert the huge nested if-else ladder in "find algorithm" to a switch statement based on an algorithm lookup table.
This should be more efficient as strcmp is now only called once. The table has the algorithms in lexicographical order, so bsearch can be used to find the proper case. If a new algorithm is added, it should be added in alphabetical order and the table updated.
Some minor efficiency in the gradient nested loops by calculating values which will be constants in the inner loop prior to entering the loop instead of each time through the inner loop.
Creating pointer variables outside of loops instead of continually calling the REAL or INTEGER macros inside the loops. See the section titled Accessing vector data by Hadley.
Minor cleanup of DESCRIPTION (Biarch is no longer needed, but NeedsCompilation and UseLTO should be set).
Declare and initialize variables on the same line where appropriate.
Use unsigned integers/size_t in structures where numbers < 0 make no sense.
Copy-edit comments.
block out some C code in nocov which cannot be tested either because they depend on NLopt functions which are not exposed or because they are completely guarded by is.nloptr.
Correction. Strcmp can be called more than once, but since it’s a bisection search on an ordered list, it should be called fewer times than the if-else ladder.
While reading through WRE, I noticed that Rdefines.h is no longer maintained, and that is what @jyypma used in
nloptr.c
, so I figured we should bringnlopt.c
more in line with the API. While going through the file I made some other changes (see the commit log for exact details). They include:Rinternals.h
instead ofRdefines.h
and manually define the necessary coercion shortcuts.ranseed
was processed through theAS_INTEGER
macro, which casts to int althoughnlopt_srand
requires an unsigned long. It is now coerced to a double and then cast to the unsigned long retaining the full range of random seeds.size_t
where appropriate and declare them inside the for loops for safety.asReal
,asInteger
).strcmp
is now only called once. The table has the algorithms in lexicographical order, sobsearch
can be used to find the proper case. If a new algorithm is added, it should be added in alphabetical order and the table updated.REAL
orINTEGER
macros inside the loops. See the section titled Accessing vector data by Hadley.Biarch
is no longer needed, butNeedsCompilation
andUseLTO
should be set).nocov
which cannot be tested either because they depend on NLopt functions which are not exposed or because they are completely guarded byis.nloptr
.