From profjcn@@h @ending from gm@il@com  Tue Aug 14 00:44:15 2018
From: profjcn@@h @ending from gm@il@com (J C Nash)
Date: Mon, 13 Aug 2018 18:44:15 -0400
Subject: [Rd] trace in uniroot() ?
In-Reply-To: <CAF8bMcZBbNF74F-x-7G0gRW9Q6FA5GbGnouMMw9FD_FRefdXHQ@mail.gmail.com>
References: <941b7615-6075-6c74-537e-70ad0bc16652@gmail.com>
 <CAF8bMcZBbNF74F-x-7G0gRW9Q6FA5GbGnouMMw9FD_FRefdXHQ@mail.gmail.com>
Message-ID: <3babc515-ed8c-e990-3ede-0e80e845ebba@gmail.com>

Despite my years with R, I didn't know about trace(). Thanks.

However, my decades in the minimization and root finding game make me like having
a trace that gives some info on the operation, the argument and the current function value.
I've usually found glitches are a result of things like >= rather than > in tests etc., and
knowing what was done is the quickest way to get there.

This is, of course, the numerical software developer view. I know "users" (a far too vague
term) don't like such output. I've sometimes been tempted with my svd or optimization codes to
have a return message in bold-caps "YOUR ANSWER IS WRONG AND THERE'S A LAWYER WAITING TO
MAKE YOU PAY", but I usually just satisfy myself with "Not at a minimum/root".

Best, JN

On 2018-08-13 06:00 PM, William Dunlap wrote:
> I tend to avoid the the trace/verbose arguments for the various root finders and optimizers and instead use the trace
> function or otherwise modify the function handed to the operator.? You can print or plot the arguments or save them.? E.g.,
> 
>> trace(ff, print=FALSE, quote(cat("x=", deparse(x), "\n", sep="")))
> [1] "ff"
>> ff0 <- uniroot(ff, c(0, 10))
> x=0
> x=10
> x=0.0678365490630423
> x=5.03391827453152
> x=0.490045026724842
> x=2.76198165062818
> x=1.09760394309444
> x=1.92979279686131
> x=1.34802524899502
> x=1.38677998493585
> x=1.3862897003949
> x=1.38635073555115
> x=1.3862897003949
> 
> or
> 
>> X <- numeric()
>> trace(ff, print=FALSE, quote(X[[length(X)+1]] <<- x))
> [1] "ff"
>> ff0 <- uniroot(ff, c(0, 10))
>> X
> ?[1]? 0.00000000 10.00000000? 0.06783655
> ?[4]? 5.03391827? 0.49004503? 2.76198165
> ?[7]? 1.09760394? 1.92979280? 1.34802525
> [10]? 1.38677998? 1.38628970? 1.38635074
> [13]? 1.38628970
> 
> This will not tell you why the objective function is being called (e.g. in a line search
> or in derivative estimation), but some plotting or other postprocessing can ususally figure that out.
> 
> 
> Bill Dunlap
> TIBCO Software
> wdunlap tibco.com <http://tibco.com>
> 
> On Mon, Jul 30, 2018 at 11:35 AM, J C Nash <profjcnash at gmail.com <mailto:profjcnash at gmail.com>> wrote:
> 
>     In looking at rootfinding for the histoRicalg project (see gitlab.com/nashjc/histoRicalg
>     <http://gitlab.com/nashjc/histoRicalg>),
>     I thought I would check how uniroot() solves some problems. The following short example
> 
>     ff <- function(x){ exp(0.5*x) - 2 }
>     ff(2)
>     ff(1)
>     uniroot(ff, 0, 10)
>     uniroot(ff, c(0, 10), trace=1)
>     uniroot(ff, c(0, 10), trace=TRUE)
> 
> 
>     shows that the trace parameter, as described in the Rd file, does not seem to
>     be functional except in limited situations (and it suggests an
>     integer, then uses a logical for the example, e.g.,
>     ?## numerically, f(-|M|) becomes zero :
>     ? ? ?u3 <- uniroot(exp, c(0,2), extendInt="yes", trace=TRUE)
>     )
> 
>     When extendInt is set, then there is some information output, but trace alone
>     produces nothing.
> 
>     I looked at the source code -- it is in R-3.5.1/src/library/stats/R/nlm.R and
>     calls zeroin2 code from R-3.5.1/src/library/stats/src/optimize.c as far as I
>     can determing. My code inspection suggests trace does not show the iterations
>     of the rootfinding, and only has effect when the search interval is allowed
>     to be extended. It does not appear that there is any mechanism to ask
>     the zeroin2 C code to display intermediate work.
> 
>     This isn't desperately important for me as I wrote an R version of the code in
>     package rootoned on R-forge (which Martin Maechler adapted as unirootR.R in
>     Rmpfr so multi-precision roots can be found). My zeroin.R has 'trace' to get
>     the pattern of different steps. In fact it is a bit excessive. Note
>     unirootR.R uses 'verbose' rather than 'trace'. However, it would be nice to be
>     able to see what is going on with uniroot() to verify equivalent operation at
>     the same precision level. It is very easy for codes to be very slightly
>     different and give quite widely different output.
> 
>     Indeed, even without the trace, we see (zeroin from rootoned here)
> 
>     > zeroin(ff, c(0, 10), trace=FALSE)
>     $root
>     [1] 1.386294
> 
>     $froot
>     [1] -5.658169e-10
> 
>     $rtol
>     [1] 7.450581e-09
> 
>     $maxit
>     [1] 9
> 
>     > uniroot(ff, c(0, 10), trace=FALSE)
>     $root
>     [1] 1.38629
> 
>     $f.root
>     [1] -4.66072e-06
> 
>     $iter
>     [1] 10
> 
>     $init.it <http://init.it>
>     [1] NA
> 
>     $estim.prec
>     [1] 6.103516e-05
> 
>     >
> 
>     Is the lack of trace a bug, or at least an oversight? Being able to follow iterations is a
>     classic approach to checking that computations are proceeding as they should.
> 
>     Best, JN
> 
>     ______________________________________________
>     R-devel at r-project.org <mailto:R-devel at r-project.org> mailing list
>     https://stat.ethz.ch/mailman/listinfo/r-devel <https://stat.ethz.ch/mailman/listinfo/r-devel>
> 
>



[Rd] trace in uniroot() ?
J C Nash