L'utilisation de R dans les calculs de précision

PĂ©riodiquement, il y a des problĂšmes, mĂȘme au quotidien, lorsque la prĂ©cision du bit float64/ int64n'est pas suffisante pour obtenir une rĂ©ponse avec la prĂ©cision requise. Se prĂ©cipiter Ă  la recherche d'un autre instrument? Aussi une option.


Ou vous ne pouvez pas le faire, mais soyez curieux et découvrez que pour calculer avec une précision arbitraire, la bibliothÚque GNU MPFR a longtemps été créée avec des wrappers pour presque toutes les langues. La pratique montre que peu de gens connaissent cette bibliothÚque, ce qui est probablement dû aux particularités des programmes d'études dans les universités et au programmeur traditionnel.


La bibliothĂšque est bonne et mĂ©rite qu'on y prĂȘte attention, du moins dans le cadre de l'Ă©largissement de ses horizons. Sur R, il y a un wrapper Rmpfr . Ci-dessous, je vais donner un exemple simple sur les problĂšmes des Ă©coliers (eh bien, ne touchez pas aux donnĂ©es de conception en vertu de la NDA) et touchez un certain nombre de rĂąteaux classiques, qui sont attaquĂ©s presque immĂ©diatement.


Il s'agit d'une continuation de publications antérieures .


Par exemple, prenons le problÚme n ° 39 du concours de l' année scolaire 2019/2020 dans le Quantum:
les nombres positifs x et y sont tels que dans l'inégalité en dessous de la fraction de gauche est plus grande que la droite. Quel est le plus grand: x ou y?


fractions de chaĂźne


Naturellement, elle doit ĂȘtre rĂ©solue analytiquement (alternance d'inĂ©galitĂ©s), mais ce n'est pas une raison pour ne pas l'utiliser comme dĂ©monstration.


Nous dessinons un code simple pour calculer la séquence des fractions. Vous pouvez immédiatement définir la valeur finale, mais ensuite la demoscene pour mpfr, nous nous déplaçons donc par petites étapes.


Nous résolvons par des méthodes standard
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)

Et voici une malchance, dĂ©jĂ  Ă  la 14e itĂ©ration (nombre d'arrĂȘt = 29), la prĂ©cision ne nous suffit pas pour distinguer les fractions. Et vous devez tenir compte jusqu'en 2019!


Échec 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 . .


Échec 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