Collecting all my little matlab-like Maxima widgets in one place

Since I’ve been using Maxima (circa 2016), I’ve occasionally missed some little feature from matlab and coded up a replacement for maxima, with a corresponding blog piece here at the Maximalist.

Some examples are find(), diff(), pause(), size(), cumsum(), diag(), and a few list indexing utilities. Also a help() utility that mimics matlab.

Here’s a mac file with all of those in one easy-to-load place: matlabesque.mac

Its help() entry reads like this:

matlabesque.mac contains:
 find(exp)
 ithruj(L,i,j)
 indexby(L,indexlist)
 matlab_diff(L)
 pause([options])
 cumsum(l)
 size(M)
 diag(M)
 -
 -
 for any of the above functions,
 help(function_name) returns help lines for function_name

A MATLAB-like find() function for Maxima

In MATLAB, you can find the indices of array entries that match a user-supplied condition with the function find()

Here’s a similar function in Maxima.  This makes liberal use of the functions sublist_indices()lambda(),  and several functions from the stringproc package: sequal()eval_string(), and simplode().  Oh, and also the shameless hack of using ascii(32) as the space character 🙂

Here are some examples.  The code is included at the bottom.

find

find(exp):=block(
 oo:op(exp),
 if sequal(oo,"=") or sequal(oo,">") or sequal(oo,">=") or sequal(oo,"<") or sequal(oo,"<=") or sequal(oo,"#") then 
   sublist_indices(first(exp),lambda([x1],eval_string(simplode([x1,op(exp),last(exp)]))))
 else 
   if sequal(oo,"and") or sequal(oo,"or") then(
     e1:first(exp),
     e2:second(exp),
     sublist_indices(first(e1),lambda([x1],
       eval_string(simplode([x1,op(e1),last(e1),ascii(32),oo,ascii(32),x1,op(e2),last(e2)]))))
   )
)$

Two little list utilities for MATLAB-like array indexing

I grew up with MATLAB, where extracting a subset of a vector V was easy as feeding a vector of indices into a vector.  For example entries i thru j could be had with V(i:j) and an more complicated index scheme could be accomplished with a vector of indices i_index and then V(i_index).

In Maxima, first(), last(), firstn(), rest(), and most generally makelist() allows for all that and more but with a little more cumbersome calling protocols.  Here are one-liners that achieve something like the two canonical MATLAB examples above:

indexby

A pause() function for Maxima

In MATLAB, pause interrupts execution of a loop until the user strikes a key, and pause(<n>) pauses for <n> seconds before resuming execution.
Here’s my attempt at a pause() function for Maxima that works in a similar way to MATLAB.  It uses Maxima’s read() to stop everything and wait for user input, and it uses the lisp function sleep to stop for a fixed number of seconds.
**note that a lisp function
     (function-name argument)
can be called inside Maxima as
     ?function-name(argument)
I’m not happy that in order to resume after the pause, the user needs to enter a valid character (space or nothing results in an error) followed by CTRL-SHIFT.  I hope to either figure something else out or even better hear suggestions from other Maxima users!
pause([options]):=block([tsecs],
    tsecs:assoc('pausetime,options,0),
    if tsecs=0 then
       read("Execution Paused...enter any character then CTRL-ENTER")
    else(
        disp(sconcat("paused for ", tsecs," seconds")),
       ?sleep(tsecs)),
    return("")
);
call this either as
     pause();
or, for a three second pause
     pause(pausetime=3);

A Little Maxima Function to Find the Dimensions of a Matrix

**Update**  I didn’t find it it in documentation for quite a while, but there is a built-in Maxima function matrix_size()  in the package linearalgebra that does what this little one-liner does**

linearalgebrapackage

I really wanted a Maxima function that works something like MATLAB size() to easily determine the number of rows and columns for a matrix M.  In Maxima, length(M) gives the number of rows, and so length(transpose(M)) gives the number of columns.  I put those together in a little widget matsize() that returns the list [m,n] for an m \times n matrix M:

matsize

matsize(A):=[length(A),length(transpose(A))];