Решение алгебраического уравнения

Я пытаюсь решить это уравнение: ((2300+1900*1)+(x+2300+1900*1)*0.002)/(600-400) =1

Есть ли способ сделать это с помощью R?

ПОПЫТКА с неверным решением:

      library(Ryacas)
eq <- "((2300+1900*1)+(x+2300+1900*1)*0.002)/(600-400) ==1 "
# simplify the equation:
library(glue)
yac_str(glue("Simplify({eq})"))
library(evaluate)
evaluate(eq,list(x=c(0,1,10,100,-100)))

evaluate()просто возвращает уравнение:

      "((2300+1900*1)+(x+2300+1900*1)*0.002)/(600-400) ==1 " 

Ответ уравнения равен −2004200.

5 ответов

Похоже, вы хотите Solve()для x, а не просто упростить...? Следующий код решает уравнение, удаляет x==из решения и вычисляет выражение:

      eq2 <- gsub("x==","",yac_str(glue("Solve({eq},x)")))
[1] "{(-0.80168e6)/0.4}"
eval(parse(text=eq2))
[1] -2004200

1) Ryacas Используйте Ryacasупаковка solveкак показано ниже. (Спасибо @mikldk за улучшение последней строки.)

      library(Ryacas)
eq <- "((2300+1900*1)+(x+2300+1900*1)*0.002)/(600-400) ==1 "  # from question

res <- solve(ysym(eq), "x")
as_r(y_rmvars(res))  # extract and convert to R
## [1] -2004200

если в нем есть переменные R, здесь hупоминается в eq2, затем используйте evalчтобы оценить результат.

      h <- 2300
eq2 <- "((h+1900*1)+(x+2300+1900*1)*0.002)/(600-400) ==1 "  # from question
res2 <- solve(ysym(eq2), "x")
eval(as_r(y_rmvars(res2)))
## [1] -2004200

2) Ryacas0 или с помощью eqсверху с Ryacas0упаковка:

      library(Ryacas0)

res <- Solve(eq, "x")
eval(Expr(res)[[1:3]]) # convert to R
## [1] -2004200

3a) Основание R В свете того факта, что это линейное уравнение и решение следующего, где A — наклон, а B — точка пересечения:

      A * x + B = 0

является

      x = - B / A

если мы заменим xс воображаемым 1iа затем переместите правую часть в левую, у нас есть это Bа также Aявляются реальной и мнимой частями этого выражения. Пакеты не используются.

      r <- eval(parse(text = sub("==", "-", eq)), list(x = 1i))
-Re(r) / Im(r)
## [1] -2004200

3b) Если мы переместим правую часть в левую, тогда B будет равна ей при x=0, а A будет равна производной по x, поэтому другим базовым решением R будет:

      e <- parse(text = sub("==", "-", eq))
- eval(e, list(x = 0)) / eval(D(e, "x"))
## [1] -200420

Если вы хотите что-то быстрое: rootSolveбиблиотека — ваш выбор.

      library(rootSolve)
func_ <- function(x) ((2300+1900*1)+(x+2300+1900*1)*0.002)/(600-400)-1
uniroot.all(func_, c(-1e9, 1e9))
[1] -2004200

Обратите внимание, что в большинстве случаев лучше уменьшить интервал.

Вот базовое решение R.
Перепишите уравнение в виде функции, используя curveполучить две конечные точки, где функция имеет разные знаки, и положить unirootработать.

      f <- function(x) ((2300+1900*1)+(x+2300+1900*1)*0.002)/(600-400) - 1
curve(f, -1e7, 1)
uniroot(f, c(-1e7, 1))
#$root
#[1] -2004200
#
#$f.root
#[1] 0
#
#$iter
#[1] 1
#
#$init.it
#[1] NA
#
#$estim.prec
#[1] 7995800

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

      f <- function(x, K = 1, params) {
  A <- with(params, rent + salary*workers)
  with(params, (A + (x + A)*capitalcost)/(price - unitcost) - K)
}

params <- list(
  rent = 2300, 
  salary = 1900, 
  workers = 1, 
  price = 600, 
  unitcost = 400, 
  capitalcost = 0.002
)
curve(f(x, params = params), -1e7, 1)
uniroot(f, c(-1e7, 1), params = params)

Если вы будете поддерживать ту же структуру, то в Base R вы можете сделать:

      solveX <- function(eq){
  U <- function(x)abs(eval(parse(text = sub("=+","-", eq)), list(x=x)))
  optim(0, U, method = "L-BFGS-B")$par
}
eq <- "((2300+1900*1)+(x+2300+1900*1)*0.002)/(600-400) ==1 "
solveX(eq)
[1] -2004200
Другие вопросы по тегам