Solving simultaneous equation in R
Since you have 5 linear equations (rows of your matrix) and only 4 columns (variables), then your problem is overdetermined and in general it can't be solved. Consider a smaller example: x+y=1; x-2*y=2; 3*x-5=0
. Once you use the first two equations:
(1) x+y=1 → y=1-x
(2) x-2*(1-x)=2 → 3*x-2=2 → x=4/3 ## substitute (1) into second eq.
(3) → y=-1/3
you have a solution for x and y (x=4/3, y=-1/3), so the last equation is either redundant or makes your solution impossible (in this case, the latter: 3*x-5 = -1 != 5
).
On the other hand, if you have fewer rows than columns, then your system is underdetermined and you can't get a unique answer.
So the number of matrix rows must equal the number of columns → you can only do this with a square matrix. This is not a limitation of the R function, it's about the underlying math of linear equations ...
In your specific case the problem is that the sum of the first four rows of your matrix add up to zero, so these are redundant. As you found out, just dropping the last equation doesn't help. But if you drop one of the redundant rows you can get an answer.
solve(A[-4,],b[-4])
Note you get the same answer whether you drop row 1, 2, 3, or 4.
Solving simultaneous equations/inequalities
This can be solved using linear programming. There is nothing to optimize, you are just searching for a feasible solution.
library(lpSolve)
res=lp(
"min",
rep(0,ncol(A2)),
A2,
c(">=","<=","<=","==","==","=="),
b
)
res$solution
[1] 50 35 15 0 0 0 0 0 0
Solving a system of nonlinear equations in R
In a comment the poster specifically asks about using solve
and optim
so we show how to solve this (1) by hand, (2) using solve
, (3) using optim
and (4) a fixed point iteration.
1) by hand First note that if we write a = 5/b
based on the first equation and substitute that into the second equation we get sqrt(5/b * b^2) = sqrt(5 * b) = 10
so b = 20 and a = 0.25.
2) solve Regarding the use of solve
these equations can be transformed into linear form by taking the log of both sides giving:
log(a) + log(b) = log(5)
0.5 * (loga + 2 * log(b)) = log(10)
which can be expressed as:
m <- matrix(c(1, .5, 1, 1), 2)
exp(solve(m, log(c(5, 10))))
## [1] 0.25 20.00
3) optim Using optim
we can write this where fn
is from the question. fn2
is formed by subtracting off the RHS of the equations and using crossprod
to form the sum of squares.
fn2 <- function(x) crossprod( fn(x[1], x[2]) - c(5, 10))
optim(c(1, 1), fn2)
giving:
$par
[1] 0.2500805 19.9958117
$value
[1] 5.51508e-07
$counts
function gradient
97 NA
$convergence
[1] 0
$message
NULL
4) fixed point For this one rewrite the equations in a fixed point form, i.e. in the form c(a, b) = f(c(a, b)) and then iterate. In general, there will be several ways to do this and not all of them will converge but in this case this seems to work. We use starting values of 1 for both a
and b
and divide both side of the first equation by b
to get the first equation in fixed point form and we divide both sides of the second equation by sqrt(a)
to get the second equation in fixed point form:
a <- b <- 1 # starting values
for(i in 1:100) {
a = 5 / b
b = 10 / sqrt(a)
}
data.frame(a, b)
## a b
## 1 0.25 20
Is there a way to solve an equation in R?
Assuming b and t are scalars with known values (here we assume 1 for both) we can minimize the the square of the left hand side assuming the answer lies in the indicated interval and if it achieves zero (which it does below) we have solved it. Note that F means FALSE in R so we used FF for clarity.
fun <- function(FF, b, t) (FF - b * log(abs(1+ (FF/b))) - 0.05*t)^2
optimize(fun, c(-10, 10), b = 1, t = 1)
giving:
$minimum
[1] 0.3503927
$objective
[1] 7.525844e-12
Related Topics
Select Columns Based on Multiple Strings with Dplyr Contains()
Counting Non Nas in a Data Frame; Getting Answer as a Vector
Ggplot2 Axis Transformation by Constant Factor
Gantt Style Time Line Plot (In Base R)
Subsetting a Matrix by Row.Names
Row Operations in Data.Table Using 'By = .I'
How to Not Show All Labels on Ggplot Axis
How to Change Positions of X and Y Axis in Ggplot2
Print Pretty Data.Frames/Tables to Console
Issue with Ggplot2, Geom_Bar, and Position="Dodge": Stacked Has Correct Y Values, Dodged Does Not
An Na in Subsetting a Data.Frame Does Something Unexpected
Create a Ranking Variable with Dplyr
Converting Data Frame Column from Character to Numeric
R for Loop Skip to Next Iteration Ifelse