Решение алгебраического уравнения
Я пытаюсь решить это уравнение:
((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