# optimizeR: High Precisione One-Dimensional Optimization In Rmpfr: R MPFR - Multiple Precision Floating-Point Reliable

## Description

`optimizeR` searches the intervalfrom `lower` to `upper` for a minimum of the function `f` with respect to its first argument.

## Usage

 ```1 2 3 4 5``` ```optimizeR(f, lower, upper, ..., tol = 1e-20, method = c("Brent", "GoldenRatio"), maximum = FALSE, precFactor = 2.0, precBits = -log2(tol) * precFactor, maxiter = 1000, trace = FALSE) ```

## Arguments

 `f` the function to be optimized. `f(x)` must work “in Rmpfr arithmetic” for `optimizer()` to make sense. The function is either minimized or maximized over its first argument depending on the value of `maximum`. `...` additional named or unnamed arguments to be passed to `f`. `lower` the lower end point of the interval to be searched. `upper` the upper end point of the interval to be searched. `tol` the desired accuracy, typically higher than double precision, i.e., `tol < 2e-16`. `method` `character` string specifying the optimization method.
 `maximum` logical indicating if f() should be maximized or minimized (the default). `precFactor` only for default `precBits` construction: a factor to multiply with the number of bits directly needed for `tol`. `precBits` number of bits to be used for `mpfr` numbers used internally. `maxiter` maximal number of iterations to be used. `trace` integer or logical indicating if and how iterations should be monitored; if an integer k, print every k-th iteration.

## Details

`"Brent"`:

Brent(1973)'s simple and robust algorithm is a hybrid, using a combination of the golden ratio and local quadratic (“parabolic”) interpolation. This is the same algorithm as standard R's `optimize()`, adapted to high precision numbers.

In smooth cases, the convergence is considerably faster than the golden section or Fibonacci ratio algorithms.

`"GoldenRatio"`:

The golden ratio method works as follows: from a given interval containing the solution, it constructs the next point in the golden ratio between the interval boundaries.

## Value

A `list` with components `minimum` (or `maximum`) and `objective` which give the location of the minimum (or maximum) and the value of the function at that point; `iter` specifiying the number of iterations, the logical `convergence` indicating if the iterations converged and `estim.prec` which is an estimate or an upper bound of the final precision (in x). `method` the string of the method used.

## Author(s)

`"GoldenRatio"` is based on Hans W Borchert's `golden_ratio`; modifications and `"Brent"` by Martin Maechler.

R's standard `optimize`; Rmpfr's `unirootR`.
 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59``` ```iG5 <- function(x) -exp(-(x-5)^2/2) curve(iG5, 0, 10, 200) o.dp <- optimize (iG5, c(0, 10)) #-> 5 of course oM.gs <- optimizeR(iG5, 0, 10, method="Golden") oM.Br <- optimizeR(iG5, 0, 10, method="Brent", trace=TRUE) oM.gs\$min ; oM.gs\$iter oM.Br\$min ; oM.Br\$iter (doExtras <- Rmpfr:::doExtras()) if(doExtras) {## more accuracy {takes a few seconds} oM.gs <- optimizeR(iG5, 0, 10, method="Golden", tol = 1e-70) oM.Br <- optimizeR(iG5, 0, 10, tol = 1e-70) } rbind(Golden = c(err = as.numeric(oM.gs\$min -5), iter = oM.gs\$iter), Brent = c(err = as.numeric(oM.Br\$min -5), iter = oM.Br\$iter)) ## ==> Brent is orders of magnitude more efficient ! ## Testing on the sine curve with 40 correct digits: sol <- optimizeR(sin, 2, 6, tol = 1e-40) str(sol) sol <- optimizeR(sin, 2, 6, tol = 1e-50, precFactor = 3.0, trace = TRUE) pi.. <- 2*sol\$min/3 print(pi.., digits=51) stopifnot(all.equal(pi.., Const("pi", 256), tolerance = 10*1e-50)) if(doExtras) { # considerably more expensive ## a harder one: f.sq <- function(x) sin(x-2)^4 + sqrt(pmax(0,(x-1)*(x-4)))*(x-2)^2 curve(f.sq, 0, 4.5, n=1000) msq <- optimizeR(f.sq, 0, 5, tol = 1e-50, trace=5) str(msq) # ok stopifnot(abs(msq\$minimum - 2) < 1e-49) ## find the other local minimum: -- non-smooth ==> Golden-section is used msq2 <- optimizeR(f.sq, 3.5, 5, tol = 1e-50, trace=10) stopifnot(abs(msq2\$minimum - 4) < 1e-49) ## and a local maximum: msq3 <- optimizeR(f.sq, 3, 4, maximum=TRUE, trace=2) stopifnot(abs(msq3\$maximum - 3.57) < 1e-2) }#end {doExtras} ##----- "impossible" one to get precisely ------------------------ ff <- function(x) exp(-1/(x-8)^2) curve(exp(-1/(x-8)^2), -3, 13, n=1001) (opt. <- optimizeR(function(x) exp(-1/(x-8)^2), -3, 13, trace = 5)) ## -> close to 8 {but not very close!} ff(opt.\$minimum) # gives 0 if(doExtras) { ## try harder ... in vain .. str(opt1 <- optimizeR(ff, -3,13, tol = 1e-60, precFactor = 4)) print(opt1\$minimum, digits=20) ## still just 7.99998038 or 8.000036655 {depending on method} } ```