Thank you for your comment. I've modifed the function according to your and
Richard Fateman's suggestions.
Error checking in not so elegant, I'm aware of that. I've implemented some
checks for most common errors, and I don't know if Maxima has separate
function to perform this task.
Stefano
subm ( _m, _rows, _cols ) := block([i,j,_x],
if not matrixp(_m) then
error("First input must be a matrix"),
if not listp(_rows) and not integerp(_rows) then
error("Second input must be a list of rows or a single integer"),
if not listp(_cols) and not integerp(_cols) then
error("Third input must be a list of columns or a single integer"),
if not listp(_rows) and integerp(_rows) then
_rows : [_rows],
if not listp(_cols) and integerp(_cols) then
_cols : [_cols],
for i in _rows do
if not integerp(i) or i<=0 then
error("Elements in rows list must be integers > 0"),
for i in _cols do
if not integerp(i) or i<=0 then
error("Elements in columns list must be integers > 0"),
for i in _rows do
if i>matrix_size(_m)[1] then
error("Row indices must be less or equal than the total number of
rows"),
for i in _cols do
if i>matrix_size(_m)[2] then
error("Column indices must be less or equal than the total
number of columns"),
_rows : sort(unique(_rows)),
_cols : sort(unique(_cols)),
return(genmatrix(lambda([i,j],_m[_rows[i],_cols[j]]),length(_rows),length(_cols)))
)$
2009/11/18 Leo Butler <l.butler at ed.ac.uk>
>
>
> On Sun, 15 Nov 2009, Stefano Ferri wrote:
>
> < I would like to expose some ideas about the submatrix function
> < implemented in Maxima.
> < While submatrix is really useful (I often use in my programs), it is a
> < function that deletes rows or columns and is different from the
> < definition everyone could have studied in an Algebra course, where a
> < submatrix is a matrix with elements to be taken, instead of rows or
> < columns to be deleted. In other words, given two lists of row and
> < column indices, by definition a submatrix is created taking all
> < elements of another matrix whose indices are the couples with the
> < first element in rows_list and the second in cols_list.
> < I don't know if such a function is already present in Maxima but I
> < miss it. Please excuse me if I'm missing something that's already
> < here!
> < I wrote a simple function to do that task. It needs 3 parameters: the
> < first one must be a matrix, the second one a list or rows or a single
> < integer, the third one a list of columns or a single integer.
> <
> < I would like to ask to the list if having two function to deal with
> < submatrices could be useful, above all because of a better alignement
> < with algebra definitions.
> <
> < Here's the function:
> <
> < subm ( _m, _rows, _cols ) := block([i,j,_x],
> < if not matrixp(_m) then
> < error("First input must be a matrix"),
> < if not listp(_rows) and not integerp(_rows) then
> < error("Second input must be a list of rows or a single integer"),
> < if not listp(_cols) and not integerp(_cols) then
> < error("Third input must be a list of columns or a single integer"),
> < if not listp(_rows) and integerp(_rows) then
> < _rows : makelist(_x,_x,_rows,_rows),
> < if not listp(_cols) and integerp(_cols) then
> < _cols : makelist(_x,_x,_cols,_cols),
> < for i in _rows do
> < if not integerp(i) or i<=0 then
> < error("Elements in rows list must be > 0"),
> < for i in _cols do
> < if not integerp(i) or i<=0 then
> < error("Elements in columns list must be > 0"),
> < for i in _rows do
> < if i>matrix_size(_m)[1] then
> < error("Row indices must be less or equal than the total number of
> rows"),
> < for i in _cols do
> < if i>matrix_size(_m)[2] then
> < error("Column indices must be less or equal than the total
> < number of columns"),
> <
> < _rows : sort(unique(_rows)),
> < _cols : sort(unique(_cols)),
> < _outm : zeromatrix(length(_rows),length(_cols)),
> < for i:1 thru length(_rows) do
> < for j:1 thru length(_cols) do
> < _outm[i,j] : _m[_rows[i],_cols[j]],
> < return(_outm)
> < )$
>
> I agree that 'submatrix' is a horrible name.
>
> I would suggest
>
>
> return(genmatrix(lambda([i,j],_m[_rows[i],_cols[j]]),length(_rows),length(_cols)));
>
> in place of the last 5 lines.
>
> To amplify RJF's comment...
> It would be nice if Maxima had a function devoted to argument checking
> (q: does it, and I am ignorant?), or even better, if it understood the
> syntax
>
> foo(x::list) := ....
>
> Leo
>
> --
> The University of Edinburgh is a charitable body, registered in
> Scotland, with registration number SC005336.
>
>