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)))) );