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

У меня есть следующие четыре уравнения (a, b, c, d), с несколькими различными переменными (x, t, v, w, n, f).Моей целью было бы попытаться найти все наборы значений переменных, которые бы генерировали все положительные (и ненулевые) числа для уравнений (a, b, c, d).Обычный цикл будет просто проходить через каждый номер сгенерированной последовательности и систематически проверять, генерирует ли он положительное значение или нет.Я хочу, чтобы он выбирал случайные числа из каждой последовательности и проверял их на соответствие другим в R. Например, (x = 8, t = 2,1, v = 13, w = 1, n = 10, f = 1) возможнонабор комбинаций.

Пожалуйста, не предлагайте аналитическое решение для них, а затем выясняйте значения.Это просто представления уравнений, с которыми я имею дело.Уравнения, которые у меня есть, довольно сложные и содержат более 15 переменных.

#Equations
a <- x * t - 2*x
b <- v - x^2 
c <- x - w*t - t*t 
d <- (n - f)/t

x <- seq(from = 0.0001, to = 1000, by = 0.1)
t <- seq(from = 0.0001, to = 1000, by = 0.1)
v <- seq(from = 0.0001, to = 1000, by = 0.1)
w <- seq(from = 0.0001, to = 1000, by = 0.1)
n <- seq(from = 0.0001, to = 1000, by = 0.1)
f <- seq(from = 0.0001, to = 1000, by = 0.1)

Ответы [ 2 ]

0 голосов
/ 14 декабря 2018

Если каждое независимое значение может принимать одно и то же значение (например, seq(from = 0.0001, to = 1000, by = 0.1)), мы можем подходить к этому с гораздо большей строгостью и избегать возможности создания дубликатов.Сначала мы создаем masterFun, который по сути является оберткой для всех функций, которые вы хотите определить:

masterFun <- function(y) {
    ## y is a vector with 6 values
    ## y[1] -->> x
    ## y[2] -->> t
    ## y[3] -->> v
    ## y[4] -->> w
    ## y[5] -->> n
    ## y[6] -->> f

    fA <- function(x, t) {x * t - 2*x}
    fB <- function(v, x) {v - x^2}
    fC <- function(x, w, t) {x - w*t - t*t}
    fD <- function(n, f, t) {(n - f)/t}

    ## one can easily filter out negative
    ## results as @jdobres has done.

    c(a = fA(y[1], y[2]), b = fB(y[3], y[1]), 
      c = fC(y[1], y[4], y[2]), d = fD(y[5], y[6], y[2]))
}

Теперь, используя permuteSample, который способен генерировать случайные перестановки вектора и впоследствииПрименяя любую заданную пользователем функцию к каждой перестановке, из RcppAlgos (я являюсь автором), мы имеем:

## Not technically the domain, but this variable name
## is concise and very descriptive
domain <- seq(from = 0.0001, to = 1000, by = 0.1)

library(RcppAlgos)

          ## number of variables ... x, t, v, w, n, f
          ##           ||
          ##           \/
permuteSample(domain, m = 6, repetition = TRUE,
                 n = 3, seed = 123, FUN = masterFun)
[[1]]
            a              b              c              d 
218830.316100 -608541.146040 -310624.596670      -1.415869 

[[2]]
            a              b              c              d 
371023.322880 -482662.278860 -731052.643620       1.132836 

[[3]]
             a               b               c               d 
18512.60761001 -12521.71284001 -39722.27696002     -0.09118721

Короче говоря, основной алгоритм способен генерировать n th лексикографический результат, который позволяет нам применить отображение из 1 to "# of total permutations" к самим перестановкам.Например, учитывая перестановки вектора 1:3:

permuteGeneral(3, 3)
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    1    3    2
[3,]    2    1    3
[4,]    2    3    1
[5,]    3    1    2
[6,]    3    2    1

Мы можем легко сгенерировать 2 nd и 5 th приведенная выше перестановка без генерации первой перестановки или первых четырех перестановок:

permuteSample(3, 3, sampleVec = c(2, 5))
     [,1] [,2] [,3]
[1,]    1    3    2
[2,]    3    1    2

Это позволяет нам иметь более контролируемое и осязаемое понимание наших случайных выборок, как мы теперь можем думать оих более привычным способом (т. е. случайная выборка чисел).

Если вы действительно хотите увидеть, какие переменные использовались в приведенном выше расчете, мы просто отбрасываем аргумент FUN:

permuteSample(domain, m = 6, repetition = TRUE, n = 3, seed = 123)
         [,1]     [,2]     [,3]     [,4]     [,5]     [,6]
[1,] 780.7001 282.3001 951.5001 820.8001 289.1001 688.8001
[2,] 694.8001 536.0001  84.9001 829.2001 757.3001 150.1001
[3,] 114.7001 163.4001 634.4001  80.4001 327.2001 342.1001
0 голосов
/ 13 декабря 2018

Для начала, может быть лучше организовать ваши уравнения и значения ваших проб в списки:

set.seed(1222)

values <- list(x = x, t = t, v = v, w = w, n = n, f = f)

eqs <- list(
  a = expression(x * t - 2 * x),
  b = expression(v - x^2), 
  c = expression(x - w*t - t*t), 
  d = expression((n - f)/t)
)

Затем мы можем определить количество выборок, которые будут случайным образом отбирать из каждого вектора проб:

samples <- 3
values.sampled <- lapply(values, sample, samples)

$x
[1] 642.3001 563.1001 221.3001

$t
[1] 583.9001 279.0001 749.1001

$v
[1] 446.6001 106.7001   0.7001

$w
[1] 636.0001 208.8001 525.5001

$n
[1] 559.8001  28.4001 239.0001

$f
[1] 640.4001 612.5001 790.1001

Затем мы можем выполнить итерацию по каждому сохраненному уравнению, оценивая уравнение в «выборочной» среде:

results <- sapply(eqs, eval, envir = values.sampled)

            a          b         c          d
[1,] 373754.5 -412102.82 -711657.5 -0.1380373
[2,] 155978.8 -316975.02 -135533.2 -2.0935476
[3,] 165333.3  -48973.03 -954581.8 -0.7356827

Оттуда вы можете удалить любое значение, равное 0 или меньше:

results[results <= 0] <- NA
...