	-*- org -*-->  Emacs [Tab] key + [Org] menu; C-c C-o follows links
* Very Short Term
** TODO 61) Q: Why is quantile() so slow [hence summary() very slow!]?  A: because sort() |--> rank() is so slow (in C code!)
   l2x <- seqMpfr(mpfr(4, 1024), 513, by=1/16) # 8000 numbers of 1024 bits
   system.time(ql2x <- quantile(l2x, names=FALSE)) # user: 10.735 (nb-mm5, Nov.2020);  1.62 (v-lynne; Sep.2025)
*** quantile() -> sort(*, partial=.) -> xtfrm.default() -> rank(l2x) is so slow
*** Partial SOLUTION (not yet implemented):  use  is.unsorted(.) which is *fast* FALSE for sorted vetors (as 'l2x' above)
** TODO 55b) possibly more documentation on .mpfr* functions, e.g. .getSign(), at least *internally* (roxygen)
** TODO 31) Valgrind problems + leaks: Brian's e-mail 2014-06-19; ~/R/Pkgs/Rmpfr.Rcheck_valgrind/
** TODO 11) format() method for "mpfr", "mpfrArray" (and hence "mpfrMatrix") which nicely
    and correctly *jointly* formats (for "mpfr") and aligns columns !
    Then,  formatDec()  would be unnecessary.  drop0trailing is not really sensible there.
** TODO 19) outer() now works  always ? {as rep() now S3 dispatches
    ---> need systematic checks *AND* docu changes!
** TODO 17b) see 'Ops' in R/Arith.R  ,  Rmpfr:::.Math.codes,  and
     design a "test all Ops" with all combinations of "mpfr", "numeric","logical"
     (and possibly more).

* Short Term
** TODO add trigamma() where MPFR is new enough:
*** [MPFR] new function: trigamma -- 02 Dec 2024 17:09:18
*** To: mpfr@inria.fr  / Reply-To: Paul Zimmermann <Paul.Zimmermann@inria.fr>

* Short or Mid Term
*** TODO Split this section into  Short | Mid  (?)

** TODO 66) Improve pnorm(*, log.p=TRUE) using Abramowitz asymptotic formulas ==> 1st need Rmpfr'ified DPQ:pnormAsymp()
   Abramowitz and Stegun (1972), p.932, (26.2.12) and (26.2.13)   see also ~/R/Pkgs/DPQ/vignettes/qnorm-asymp.Rnw
*** TODO 66a) "mpfrify" pnormAsymp() and qnormAsymp() but in pkg {DPQmpfr} !!
** TODO 60) Should have *exact* as.bigq.mpfr(), i.e, "mpfr" --> "bigq". (R's "bigq" is C 'mpq')
** TODO 62) integrateR(): option 'all.sums=TRUE' --> R/integrate-Romberg.R
***  Inside the GMP library, have
# -- Function: void mpq_set_f (mpq_t ROP, const mpf_t OP)
#      Set ROP to the value of OP.  There is no rounding, this conversion is exact.
***  MPFR documents 'mpf2mpfr.h' after which you can compile any mpf_ program..
** TODO 53) plogis() {and dlogis, qlogis} are "easy": do use <R>/src/nmath/[dpq]logis.c, as they
 already use all the numerical tricks including R_Log1_Exp(x) .. :
 R_Log1_Exp(x) := ((x) > -M_LN2 ? log(-expm1(x)) : log1p(-exp(x)))
** TODO 54) zapsmall() would be nice, base::zapsmall() fails
** TODO 35) tests/bit-repr.R : Bits() fails to work with 2^k

** TODO 37) mpfrXport()/*Import() should work for arrays.  Test Windows-portability:
 -  as save() seems not portable; see ~/R/MM/Pkg-ex/Rmpfr/save-load-ex.R
** TODO 2) Now have working  "mpfrMatrix", dim(.) <- ..; t(), %*%, crossprod()...
 -  <mpfr> %*% <mpfr>    should work the same as with numeric vectors
 -  <mpfr> %*% t(<mpfr>)  ditto

  Note that matrix multiplication seems too slow --> ./Savicky-matrix-mult_tst.R

 -  <mpfr>[i] & <mpfrMatrix>[i]  work
    but   <mpfrMatrix> [i,j]  not yet

 -->  want things to work like
          which(<mpfrMatrix> == ., arr.ind = TRUE)  - ok

 [No longer sure if this is true :]
 For this, we must ensure that the methods are used, instead of the
 .Primitive  base functions :
 One way: --> see ~/R/MM/NUMERICS/bessel-large-x.R
                  --------------------------------
  ## really interesting is  bI(x., nu)  {for "mpfr" argument}:
  ## it uses outer(), but that needs to dispatch on, e.g. "^",
  ## i.e., not only look at "base"
  environment(outer) <- as.environment("package:Rmpfr")
  environment(dim) <- as.environment("package:Rmpfr")
  environment(dimnames) <- as.environment("package:Rmpfr")
  environment(`dim<-`) <- as.environment("package:Rmpfr")
  environment(`dimnames<-`) <- as.environment("package:Rmpfr")
  environment(which) <- as.environment("package:Rmpfr")

** TODO 5) have seqMpfr(), but would like seq() methods, but that seems currently impossible because of
   a "design infelicity" in base::seq.default  --- ???? E-mail to R-core ??
   --> R/mpfr.R
** TODO 6) It is "wrong" that the class "Mnumber" also extends "character", "list";
   but it's not clear we can find better definitions, see R/AllClasses.R

** TODO 7) Add tests for hypot() & atan2() to tests/special-fun-ex.R

** TODO 8) round(x, .) & signif(x, .) currently return "mpfr" numbers of the same precision.
   That *looks* ugly.
   Potentially add a swith 'keepPrec = FALSE' -- i.e. by default *reduce*
   precision to "match" 'digits' argument.

** TODO 16) psigamma(x, n)  {and  digamma(), trigamma() aliases}
    --> experiments in ~/R/MM/Pkg-ex/Rmpfr/psigamma.R )
    Note that since, MPFR 3.0.0, there is a digamma(); .. which we now interface to

** TODO 18) ifelse()  fails ... maybe I should mask it
             {or "fix it" via assign*() in base ?? -- they will love that!}
    or provide ifelse2() -- a fast simplified version ?


** TODO 24) Bernoulli(): we use builtin zeta(); alternatively, use *exact*
     rationals from 'gmp', using "bigq" (and "bigz") -- and R code from ~/R/Pkgs/copula/R/special-func.R
** TODO 26) (?) Revert the decision to *not* care about rounding mode in Ops/function,
    and rather expose that as in mpfr(), e.g., in R/Math.R  roundMpfr
    -- see  MPFR_RNDN in src/utils.c and others; --> use src/convert.c  R_rnd2MP()
    -- and all the SEXP functions get an additional   SEXP rnd_mode
       argument, the same as   SEXP d2mpfr1() in src/convert.c has already.
** TODO 29) Our sum() should use system mpfr_sum() :
   mpfr_sum (mpfr_t ROP, mpfr_ptr const TAB[], unsigned long int N, mpfr_rnd_t RND)
** TODO 32) Use ./LUP.R  to compute the lu() decomposition of an mpfrMatrix
    ---> solve() and use this for determinant() for larger (n >= 4 ?) dimensions!
** TODO 50) For *complex* arithmetic, build interface to the  "MPC" library
   ---> http://www.multiprecision.org/mpc -- which is LGPL and itself
   builds on MPFR and GMP.
   Ubuntu now has 'libmpc-dev' (!)  {but there's no '*-doc' package yet;
   	      	  	       	     on nb-mm, I've installed from source
				     --> Info comes along}
  One idea: Since the names are so much in parallel, try
      to take each src/*.c file and mechanically  s/mpfr/mpc/  producing a
      mpc version of that;
      then "the same" for the R interface code.

** TODO 51) Incomplete gamma, i.e. pgamma(), is being added to MPFR. -> do in Rmpfr!
  ~/F/IN-lists--2016-08 :
     From: paul zimmermann <Paul.Zimmermann@inria.fr>
      Subject: [MPFR] incomplete Gamma function
      Date: Mon, 18 Jan 2016 09:54:51 +0100

      zimmerma@tomate:~/mpfr/tests$ ./tgamma_inc 60 30 100
      1.3868299023788801161747839921242e80

*** Will be in MPFR 3.2.x (Oct.2016: current is 3.1.5)
*** MPFR-devel(svn): https://gforge.inria.fr/scm/viewvc.php/mpfr/trunk/src/gamma_inc.c?view=markup
    - get: --> http://mpfr.loria.fr/gforge.html explains:
    - svn checkout https://scm.gforge.inria.fr/anonscm/svn/mpfr/trunk mpfr


* Accomplished
** DONE 1) R: character -> mpfr   "3.14159265358979323846264" -> mpfr

** DONE 3) "Arith" and "Compare" methods currently ``lose dim + dimnames''
   for "mpfrArray" (& "mpfrMatrix")

  The solution is a bit tedious because the Ops do recycling pretty
  generously for vectors,
  but pretty stringently when one of the operands is a matrix.

  If the other part is a matrix their dim() must be identical,
  if just a vector, its length must be a divisor of  length(<matrix>)

** DONE 10b) a factorialMPFR() which automatically uses full precision for
    integer-valued argument, notably using MPFR's mpfr_fac_ui; see also end
    of man/mpfr-class.Rd

** DONE 13) all the NOT_YET in src/Ops.c are implemented, *apart* from trigamma()
    --> TODO 16)

** DONE 14) Want to *change*  'precBits' of existing MPFR numbers;
    MPFR has  mpfr_set_prec(X, PREC)  but that sets the value to NaN.
    Manual:  "In case you want to keep the previous value stored in X, use
               `mpfr_prec_round' instead."

   --> fulfilled via  roundMpfr(x, precBits)



** DONE 15) beta(.,.) and lbeta(.,.) .. using  my_mpfr_beta() in C.
   Interestingly, the speedup is not dramatical
    (50% for length 200; 300% for length 1)

** DONE 4) format() got more (optional) arguments, along the format.default()
   example.
   Note that an option to "round() after decimal" should not be needed,
   rather  format(round(..), digits= ., drop0trailing=TRUE) does work.


** DONE 12) crossprod(), tcrossprod() (and more?) methods for "mpfrMatrix".

** DONE 10) chooseMpfr(a,n) is now implemented --- *NOT* based on gamma(),
    but rather n.

** DONE 11b) No longer --- problem were missing  mpfr_clear() statements in src/utils.c :
    format(<mpfr>) --> .mpfr2str() -> C mpfr2str()  still suffers from a
    memory bug, inspite of my efforts in src/convert.c
    I think this is the MPFR library just allocating memory that's in use
    by R, but it seems hard to prove and or fix that.


** DONE 17a) as(1, "mpfr") & TRUE : no longer gives infinite recursion error

** DONE 17a) Write a 'Rmpfr-package' help page that mentions that we have *many*
     Math etc functions, including  gamma, digamma, ....  {which are not
     quickly visible on the help pages now}.


** DONE 20) integrateR( ... rel.tol, verbose= TRUE) :
    the precision of the output should be increased a bit,
    (still depending  on rel.tol !)

** DONE 21) What's the exponent range -- and possibly change it: R interface
   in R/mpfr.R via  .mpfr_erange()  [and .mpfr_erange(.) <- v ]
   to
   - Function: mpfr_exp_t mpfr_get_emin (void)
   - Function: mpfr_exp_t mpfr_get_emax (void)

   - Function: int mpfr_set_emin (mpfr_exp_t exp)
   - Function: int mpfr_set_emax (mpfr_exp_t exp)

   - Function: mpfr_exp_t mpfr_get_emin_min (void)
   - Function: mpfr_exp_t mpfr_get_emin_max (void)
   - Function: mpfr_exp_t mpfr_get_emax_min (void)
   - Function: mpfr_exp_t mpfr_get_emax_max (void)

** DONE 22) apply(<mpfrArray>, .) --> S4 method

** DONE 22x) *do* test rank(), sort(), order() : we claim they work in man/mpfr-class.Rd
    quantile() should work from R 2.15.1 (June 2012) on       ~~~~~~~~~~~~~~~~~

** DONE 23) quantile(<mpfr>)  does not work ---- but will from R 2.15.1 with better quantile.default()
    Reason: in stats::quantile.default(),
      ifelse(h == 0, qs[i], (1 - h) * qs[i] + h * x[hi[i]])
    produces a list of 'mpfr1' instead a real 'mpfr' vector.
    -> Fixed in ~/R/D/r-devel/R/src/library/stats/R/quantile.R

** DONE 23x) sumBinomMpfr()  accept  f.x

** DONE 28) determinant() and hence det() "fail" (with a reasonable error message).
    Easy: go via asNumeric(.) with a  warning() that can be suppressed
    Standard R uses LAPACK's  LU() decomposition.  Would be cool to have
    that in C (using MPFR).
    Alternatively, do it for 2x2 and via recursion mxm for small m.
    (but it is *really* inefficient: complexity  \propto  m! )

** DONE 30) pmin() and pmax(), for simple cases pmin(x,n) are now, 2013-02, quite "fast",
        (see also --> ~/R/MM/Pkg-ex/Rmpfr/SLOW-pmin.R)
** DONE 33) asNumeric(mpfr(10, 99)^500) gives 1.797693e+308 without warning. Should (warn or) give Inf
** DONE 36) got mpfrImport(), reading mpfrXport()
** DONE 38) Define a norm() method.  For expm(*, "Higham08") need  solve() !
** DONE 34) Can specify the rounding mode in mpfr() and roundMpfr(), since 2015-08-08
** DONE 9) median(<mpfr>) now works, as does mean(<mpfr>, trim = *) and quantile() w/o warning.
** DONE is.finite(.) etc: *Must* keep matrices -> src/utils.c
** DONE 52) No longer use 'representation' but rather 'slots' in  'setClass(..)'
** DONE 25) mpfr(<mpfr>, ...) should work: return argument unchanged *if* precision
    and rounding mode are ok; otherwise use roundMpfr() *BUT* that needs an
    additional rnd.mode  argument -- as mpfr
** DONE 27) Now have simple sapplyMpfr()
** DONE 57) Fix pnorm() bugs reported by Jerry Lewis (>> ~/R/MM/Pkg-ex/Rmpfr/pnorm-* )
** DONE 58) print(<large Matrix>) somehow fails to use max.digits = 9999 [print.mpfr(*, max.digits = ...)] ???
*** Why did we introduce 'max.digits' *and* allow  digits=NULL to use *all* digits before the decimal point?
**** I now think max.digits is almost superfluous if  digits=NULL behaved as promised:
    We have in R code comments  __digits = NULL : use as many digits "as needed"__ ,
    and in help man/formatMpfr.Rd
 __The default, \code{NULL}, uses enough digits to represent the full precision, often one or two digits more than you would expect.__
** DONE 56) Add regr.tests for new dgamma(<mpfr>) !!
** DONE 55a) .getPrec(), .mpfr_erange, .mpfr_erange_set, .mpfr_maxPrec, .mpfr_minPrec etc are documented now.

** DONE 59) *exact* dhyper(), phyper().. -> in package 'DPQmpfr' dhyperQ() etc exact via 'gmp' exact rationals

** DONE 63) R interface to mpfr's functions `mpfr_get_ld_2exp()` and `mpfr_frexp()`
   compatibly to DPQ's `ldexp(f, E)` and `frexp(x)`: -> frexpMpfr() and ldexpMpfr().
** DONE 64) formatMpfr(x, scientific=FALSE)  does *not* "work" e.g., for  `x <- Const("pi", 128) * 2^200`.
** DONE 64b) formatMpfr(x, scientific=FALSE) does *not* yet "work" for small x, i.e., x << 1;
   e.g.  `x <- Const("pi", 128) * 2^-(10:20)`.
   indeed we had the scipen = *penalize* scientific  wrong: *and* we used 'scientific' instead of 'scipen' !
** DONE 65) unirootR(): *update* with R's uniroot() enhancements:
     extendInt = c("no", "yes", "downX", "upX"), check.conv = FALSE,

** DONE 67) igamma() [incomplete gamma] always returns 53-bit

** DONE Change Macros  to  static  R_INLINE Functions 
    Tomas K: "Macros were outdated even when I was a CS student .."
