Die Verwendung von R in Präzisionsberechnungen

Von Zeit zu Zeit gibt es Probleme, auch im Alltag, wenn die Bit - Genauigkeit float64/ int64nicht genug ist , eine Antwort mit der erforderlichen Genauigkeit zu erhalten. Auf der Suche nach einem anderen Instrument herumstürmen? Auch eine Option.


Oder Sie können dies nicht tun, aber seien Sie neugierig und finden Sie heraus, dass für die Berechnung mit beliebiger Genauigkeit die GNU MPFR- Bibliothek seit langem erstellt wurde, für die es Wrapper für fast alle Sprachen gibt. Die Praxis zeigt, dass nur wenige Menschen mit dieser Bibliothek vertraut sind, was wahrscheinlich auf die Besonderheiten von Studienprogrammen an Universitäten und den nachfolgenden Programmierer-Mainstream zurückzuführen ist.


Die Bibliothek ist gut und verdient Beachtung, zumindest im Rahmen der Erweiterung ihres Horizonts. Auf R gibt es einen Rmpfr- Wrapper . Im Folgenden werde ich ein einfaches Beispiel für Probleme für Schulkinder geben (berühren Sie nicht die Konstruktionsdaten unter der NDA) und eine Reihe klassischer Rechen, die fast sofort angegriffen werden.


Es ist eine Fortsetzung früherer Veröffentlichungen .


Nehmen Sie zum Beispiel Problem Nr. 39 aus dem Schuljahreswettbewerb 2019/2020 im Quantum: Die
positiven Zahlen x und y sind so, dass in der Ungleichung unter dem linken Bruch größer als der rechte ist. Was ist größer: x oder y?


Kettenfraktionen


Natürlich muss es analytisch gelöst werden (abwechselnde Ungleichung), aber dies ist kein Grund, es nicht als Demonstration zu verwenden.


Wir zeichnen einen einfachen Code, um die Folge von Brüchen zu berechnen. Sie können sofort den Endwert festlegen, dann aber die Demoszene für mpfr, sodass wir in kleinen Schritten vorgehen.


Wir lösen nach Standardmethoden
library(tidyverse)
library(magrittr)
options(digits=15)

frec <- function(stopval, n, x){
  res <- ifelse(n == stopval, 
                (stopval - 1) + stopval/(stopval + 1 + x), 
                (n - 1 ) + n / (frec(stopval, n + 2, x))
  )
  res
}

frec_wrap <- function(stopval, x){
  res <- frec(stopval = stopval, n = 1, x = x)
  print(glue::glue("{stopval}: {res}"))
  res
}

sol_df <- tibble(stopval = seq(1, 29, by = 2)) %>%
  mutate(val1 = purrr::map_dbl(stopval, frec_wrap, x = 1),
         val2 = purrr::map_dbl(stopval, frec_wrap, x = 5),
         delta = val1 - val2)

Und hier ist ein Pech, bereits bei der 14. Iteration (Stoppnummer = 29) reicht die Genauigkeit nicht aus, um zwischen Brüchen zu unterscheiden. Und Sie müssen bis 2019 berücksichtigen!


Fehler 1


? , Rmfpr. — float64 mpfr .


library(tidyverse)
library(magrittr)
library(Rmpfr)
frec2 <- function(stopval, n, x){
  if(n == stopval){
    (stopval - 1) + stopval/(stopval + 1 + x)} else {
      (n - 1 ) + n / (frec2(stopval, n + 2, x))
    }
}
frec2_wrap <- function(stopval, x){
  .precision <- 5000
  res <- frec2(stopval = mpfr(stopval, .precision), 
               n = mpfr(1, .precision), 
               x = mpfr(x, .precision)
  )
  print(glue::glue("{stopval}: {formatMpfr(res, drop0trailing = TRUE)}"))
  res
}

sol2_df <- tibble(stopval = seq(1, 29, by = 2)) %>%
  mutate(val1 = purrr::map(stopval, frec2_wrap, x = 1),
         val2 = purrr::map(stopval, frec2_wrap, x = 5))

. , tibble . .


Fehler 2


№1:
tibble , vctrs. ( mpfr S4 ) list-column. - .
, vctrs . , :


for(jj in 1:12){
  #   ,       
  flags_df[[glue("bp_2_{jj}_T")]] <- flags_df[[glue("bp_2_{jj}_in")]] &   flags_df[[glue("flag_2_{jj}")]]
  flags_df[[glue("bp_2_{jj}_F")]] <- flags_df[[glue("bp_2_{jj}_in")]] & ! flags_df[[glue("flag_2_{jj}")]]
}

№2:
list-column . mpfr list-column.


№3
rpfm . StackOverflow . . R?


? --! R, Python! !
. RTFM, .


  • №1. — tibble . data.frame.
  • №2. rpfm . , . data.frame .
  • №3. formatMpfr .

.


library(tidyverse)
library(magrittr)
library(Rmpfr)
#    
frec2 <- function(stopval, n, x){
  if(n == stopval){
    (stopval - 1) + stopval/(stopval + 1 + x)} else {
      (n - 1 ) + n / (frec2(stopval, n + 2, x))
    }
}
frec2_wrap <- function(stopval, x){
  # browser()
  .precision <- 5000
  res <- frec2(stopval = mpfr(stopval, .precision), 
               n = mpfr(1, .precision), 
               x = mpfr(x, .precision)
  )
  print(glue::glue("{stopval}: {formatMpfr(res, drop0trailing = TRUE)}"))
  res
}

sol_df <- data.frame(stopval = seq(111, 119, by = 2)) %>%
  #    mpfr   
  mutate(val1 = new("mpfr", unlist(purrr::map(stopval, frec2_wrap, x = 1))),
         val2 = new("mpfr", unlist(purrr::map(stopval, frec2_wrap, x = 5))),
         delta = val1 - val2)

sol_txt_df <- sol_df %$%
  tibble(stopval = stopval,
         val1_txt = formatMpfr(val1, drop0trailing = TRUE),
         val2_txt = formatMpfr(val2, drop0trailing = TRUE),
         delta_txt = formatMpfr(delta, drop0trailing = TRUE))

P.S. . , . , , GNU MPFR.


« R ?».


All Articles