nleqslv, R, нелинейная система уравнений

У меня есть следующая нелинейная система уравнений:

r1*r2*(0.25*0.6061-0.5)+r1+(0.25*r2) = 0.6061
r1*r2*(0.25*0.6429-0.5)+r1+(0.25*r2) = 0.6429

Мне нужно найти r1 и r2. Их решение должно быть равно:

r1 = 0.5754
r2 = 0.6201

который появился на Fortran.
Я не знаю, как мне найти решения, используя пакет nleqslv.

Я буду признателен, если кто-нибудь может мне помочь.

Спасибо.


person Amir Aliakbari    schedule 29.04.2018    source источник
comment
Вы уверены в этих решениях? Я получаю значения, близкие к c(r1, r2) == c(1, 4).   -  person Rui Barradas    schedule 29.04.2018
comment
Решение получено с помощью NAG (C05PBF), программы на Фортране. Кстати, я не мог понять, как вы выполнили якобиан   -  person Amir Aliakbari    schedule 29.04.2018
comment
Решения, которые вы дали, неверны. Попробуйте решить второе уравнение с решениями, которые у вас есть. Они не работают.   -  person Onyambu    schedule 29.04.2018


Ответы (1)


Способ использования nleqslv состоит в том, чтобы определить функцию, возвращающую 2-мерный вектор, точно так же, как c(r1, r2).
Эта функция принимает 2-мерный аргумент x. Я заменил r1 и r2 на x[1] и x[2] соответственно.
Я также заменил вашу константу 1-го уравнения (0.25*0.6061-0.5) ее значением, -0.348475. А во втором уравнении (0.25*0.6429-0.5) на -0.339275.
Что касается начальных значений, я сначала попробовал c(0, 0), но это не сработало. Если вы запустите приведенный ниже код с начальными значениями c(0.5, 0.5), вы получите такое же решение с точностью до плавающей запятой.

fn <- function(x){
    c(-0.348475*x[1]*x[2] + x[1] + 0.25*x[2] - 0.6061,
      -0.339275*x[1]*x[2] + x[1] + 0.25*x[2] - 0.6429)
}

nleqslv(c(1, 1), fn)
#$`x`
#[1] 1.000000 3.999999
#
#$fvec
#[1] 4.773959e-14 4.607426e-14
#
#$termcd
#[1] 1
#
#$message
#[1] "Function criterion near zero"
#
#$scalex
#[1] 1 1
#
#$nfcnt
#[1] 2
#
#$njcnt
#[1] 1
#
#$iter
#[1] 2

Обратите внимание, что $fvec близко к нулю, а $termcd равно 1. Это означает, что алгоритм сошелся. Чтобы иметь только решение, которое вы можете запустить

sol <- nleqslv(c(1, 1), fn)
sol$x
#[1] 1.000000 3.999999

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

jacfn <- function(x) {
    n <- length(x)
    Df <- matrix(numeric(n*n), n, n)
    Df[1,1] <- -0.348475*x[2] + 1
    Df[1,2] <- -0.348475*x[1] + 0.25
    Df[2,1] <- -0.339275*x[2] + 1
    Df[2,2] <- -0.339275*x[1] + 0.25

    Df
}

sol2 <- nleqslv(c(1, 1), fn, jac = jacfn)
sol2$x
#[1] 1 4

Решение такое же.

person Rui Barradas    schedule 29.04.2018
comment
Решение получено с помощью NAG (C05PBF), программы на Фортране. Кстати, я не мог понять, как вы выполнили якобиан. - person Amir Aliakbari; 29.04.2018
comment
@AmirAliakbari Якобиан прост: создайте матрицу размерности, равную length(x), затем заполните ее частными производными целевой функции. Что касается вашего решения, попробуйте его в уравнении. fn(c(r1, r2)) выводит [1] -1.281055e-05 -3.353020e-02, далеко не ноль. - person Rui Barradas; 30.04.2018