In a previous post, I included my little coding project to implement a general** backsolve()** function to use with the built-in maxima matrix function **echelon()**, producing an easy-to-call matrix solver **matsolve(A,b)**. The result is meant to solve a general matrix vector equation , including cases when is non-square and/or non-invertible.

Here’s a quicker approach — convert the matrix into an explicit system of equations using a vector of dummy variables, feed the result into the built-in Maxima function** linsolve()**, and then extract the right hand sides of the resulting solutions and put them into a column vector.

The two methods often behave identically, but here’s an example that breaks the **linsolve()** method, where the **backsolve()** method gives a correct solution:

*Note, I’ve found that the symbol rhs is a very popular thing for users to call their problem-specific vectors or functions. Maxima’s “all symbols are global” bug/feature generally wouldn’t cause a problem with a function call to **rhs()**, but the function **map(rhs,*** list of equations***)** ignores that **rhs()** is a function and uses user-defined rhs. For that reason I protect that name in the block declarations so that **rhs()** works as expected in the **map()** line at the bottom. I think I could have done the same thing with a quote: map(‘rhs, *list of equations*).

matsolve2(A,b):=block(
[rhs,inp,sol,Ax,m,n,vars],
[m,n]:[length(A),length(transpose(A))],
vars:makelist(xx[i],i,1,n,1),
Ax:A.vars,
inp:makelist(part(Ax,i,1)=b[i],i,1,n,1),
sol:linsolve(inp,vars),
expand(transpose(matrix(map(rhs,sol))))
);