Penggunaan R dalam perhitungan presisi

Secara berkala, ada masalah, bahkan dalam kehidupan sehari-hari, ketika akurasi bit float64/ int64tidak cukup untuk mendapatkan jawaban dengan akurasi yang diperlukan. Bergegas mencari instrumen lain? Juga merupakan pilihan.


Atau Anda tidak dapat melakukan ini, tetapi ingin tahu dan temukan bahwa untuk penghitungan dengan akurasi sewenang-wenang, perpustakaan GNU MPFR telah lama dibuat dan ada pembungkus untuk hampir semua bahasa. Praktek menunjukkan bahwa sedikit orang yang akrab dengan perpustakaan ini, yang mungkin disebabkan oleh kekhasan program studi di universitas dan arus utama programmer berikutnya.


Perpustakaan itu baik dan layak untuk diperhatikan, setidaknya dalam kerangka memperluas wawasannya. Pada R untuk itu ada pembungkus Rmpfr . Di bawah ini saya akan memberikan contoh sederhana tentang masalah untuk anak sekolah (yah, jangan menyentuh data desain di bawah NDA) dan saya akan menyentuh sejumlah garu klasik, yang diserang segera.


Ini adalah kelanjutan dari publikasi sebelumnya .


Misalnya, ambil masalah No. 39 dari kompetisi tahun sekolah 2019/2020 di Quantum: Angka
positif x dan y sedemikian rupa sehingga dalam ketidaksamaan di bawah fraksi kiri lebih besar daripada kanan. Mana yang lebih besar: x atau y?


fraksi berantai


Secara alami, itu harus diselesaikan secara analitis (berganti-ganti ketimpangan), tetapi ini bukan alasan untuk tidak menggunakannya sebagai demonstrasi.


Kami menggambar kode sederhana untuk menghitung urutan fraksi. Anda dapat segera menetapkan nilai akhir, tetapi kemudian untuk demoscene mpfr, jadi kami bergerak dalam langkah-langkah kecil.


Kami menyelesaikannya dengan metode standar
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)

Dan ini adalah nasib buruk, sudah pada iterasi ke-14 (stop number = 29), akurasi tidak cukup bagi kita untuk membedakan antara pecahan. Dan Anda harus mempertimbangkan hingga 2019!


Kegagalan 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 . .


Kegagalan 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