Найти общий множитель для преобразования списка чисел в список целых чисел в R - PullRequest
0 голосов
/ 21 октября 2019

В отношении этого поста , в котором описывается метод в Python, я пытаюсь сделать то же самое в R.

Однако сначала я боролся с выводом MASS::fractions(см. этот пост ), поскольку мне не было ясно, как обрабатывается точность.
Другой пользователь предложил обходной путь;позже я обнаружил, что numbers::ratFarey тоже добился цели.

Но потом я решил, что даже если мне удастся получить дроби с желаемым размером знаменателя, я не решу фундаментальную проблему, заключающуюся в том, что числа с плавающей запятой произвольное происхождение не сводится к рациональным числам вообще.

Я подозреваю, что только некоторые, если таковые имеются, исходные числа с плавающей запятой могут быть преобразованы в «правильные» целые числа путем нахождения их соответствующих знаменателей;остальное можно только аппроксимировать, поэтому не стоит даже пытаться найти чрезмерно большие знаменатели.

Я разработал очень простую функцию, которая берет вектор v чисел с плавающей запятой и выводит коэффициент, который,умноженное на v, выдает как можно больше целых чисел. Максимальный размер знаменателя, используемый при поиске дробей, составляет 1e6.

Я хотел бы услышать ваше мнение об этом / предложения о том, как это можно сделать лучше.

require(numbers)

f_int <- function(v) {
  v <- unique(abs(v))
  v <- v[!(trunc(v) == v)]
  v <- v[v != 0]
  if (length(v) == 0) return(1)
  f0 <- 10^(-trunc(log10(v)))
  r <- sapply(v*f0,function(x) (ratFarey(x,1.e6,upper=F)))
  denoms <- r[2,]
  nums <- r[1,]
  denoms <- f0*denoms
  res <- setNames(abs(nums/denoms-v),as.character(denoms))
  res <- res[!duplicated(names(res))]
  udt <- table(denoms)
  res <- res[match(names(udt),names(res))]
  udn <- as.numeric(names(udt))
  udnfp <- c(1,10*udn[res != 0])
  f0_udnfp <- 10^(trunc(log10(udnfp)))
  udn <- udn[res == 0]
  udt <- udt[res == 0]
  if (length(udn) == 0) return(1.e6*max(f0)) else return(mLCM(c(udn,max(f0_udnfp))))
}

РЕДАКТИРОВАТЬ : некоторые примеры данных для v

v <- c((1:10)/300,(1:10)/70,(1:10)/3900)

или

v <- c(0.1234567, 0.142857142857143, 0.0142857142857143, 0.00142857142857143, 0.333333333333333, 0.0333333333333333)

или

v <- c(0.0001234567, 0.142857142857143, 0.0142857142857143, 0.00142857142857143, 0.333333333333333, 0.0333333333333333)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...