Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function to translate linear equations into matrix form in R?

I was wondering whether there exist any packages or other pre-built solutions for R that are capable of translating sets of linear equations into matrix form (e.g. for solution via the Gauss Seidel algorithm), similar to the equationsToMatrix(eqns,vars) function in Matlab?

An example from Matlab:

[A, b] = equationsToMatrix([x - y == 0, x + 2*y == 3, [x, y])

A =
[ 1, -1]
[ 1, 2]

b =
  0
  3

Suggestions for building blocks would be very helpful, too.

like image 273
4 revs, 3 users 98% Avatar asked Nov 22 '14 11:11

4 revs, 3 users 98%


People also ask

How do you convert a linear equation into a matrix?

[ A , b ] = equationsToMatrix( eqns ) converts equations eqns to matrix form. eqns must be a linear system of equations in all variables that symvar finds in eqns . [ A , b ] = equationsToMatrix( eqns , vars ) converts eqns to matrix form, where eqns must be linear in vars .

How do you express an equation in a matrix form?

A matrix equation is an equation of the form Ax = b , where A is an m × n matrix, b is a vector in R m , and x is a vector whose coefficients x 1 , x 2 ,..., x n are unknown.


2 Answers

1) This is not exactly what you are asking for but maybe it will help anyways:

library(Ryacas)
x <- Sym("x")
y <- Sym("y")
Simplify(Solve(List(x - y == 0, x + 2*y == 3), List(x, y)))

giving:

expression(list(list(x - y == 0, y - 1 == 0)))

2) If we know these are linear equations exactly of the form shown in the question then try this. The two strapply calls perform matches of the regular expression against the components of args, capture the strings matched by the portions of the regular expressions within parentheses and call the function specified as the third argument with those captured strings as arguments. We combine the strapply outputs using rbind.fill and replace any NAs it generates with zero.

library(gsubfn) # strapply
library(plyr) # rbind.fill

eqn <- function(...) {
  args <- c(...)
  x2num <- function(x, y) { # determine coefficient value as a numeric
       z <- gsub(" ", "", x)
       setNames(if (z == "-") -1 else if (z == "") 1 else as.numeric(z), y)
  }
  lhs <- strapply(args, "(-? *\\d*)[ *]*([a-z])", x2num)
  lhs <- do.call(rbind.fill, lapply(lhs, function(x) as.data.frame(t(x))))
  lhs <- as.matrix(lhs)
  lhs[] <- ifelse(is.na(lhs), 0, lhs)
  list(lhs = lhs, rhs = strapply(args, "== *(\\d)", as.numeric, simplify = TRUE))
}

# test it out
eqn("x - y == 0", "2*y == 3")

giving:

$lhs
     x  y
[1,] 1 -1
[2,] 0  2

$rhs
[1] 0 3

Update: Generalized so that now not all variables need to be in each equation and also variables can be in different orders in different equations.

like image 196
G. Grothendieck Avatar answered Oct 05 '22 22:10

G. Grothendieck


Can't tell from your example whether you just want simple linear equation solving or a more general system solver. If the latter, take a look at the BB and nleqslv packages.

You might also be interested in a "wrapper" tool written by some seriously twisted mind :-) , in the package ktsolve . This last tool lets you set up an arbitrary set of equations and back-solve for any desired set of variables.

like image 22
Carl Witthoft Avatar answered Oct 05 '22 23:10

Carl Witthoft