Search code examples
listunits-of-measurementmaxima

Maxima ezunits: apply a unit to all elements of a list


Since I discovered the ezunits package I make extensive use of it in Maxima, but I could not find a satisfactory way to apply a unit to the elements of a list.

For example [1,2,3]`hour apparently works

a: [1,2,3]`hour;
>> [1,2,3] ` hour

(5`km)/a[2];
>> 5/2 ` km/hour

but I cannot loop through it

makelist((5`km)/x, x, [1,2,3]`hour);
>>> makelist: third argument must be a number or a list; found: [1.0,2.0,3.0] ` hour

whereas, if I apply manually the unit to each element of list, everything works:

makelist((5`km)/x, x, [1`hour,2`hour,3`hour]);
[5 ` km/hour,5/2 ` km/hour,5/3 ` km/hour]

Thanks in advance for any help you will be able to give.


Solution

  • tellsimp as suggested above is a good idea. Here is another which depends on the only-partially-documented distribute_over property:

    (%i7) :lisp (setf (get '$\` 'distribute_over) '(mlist $matrix mequal))
    (MLIST $MATRIX MEQUAL)
    (%i7) [1,2,3]`m;
    (%o7)                        [1 ` m, 2 ` m, 3 ` m]
    

    Be very careful with the punctuation! Distinguish the backtick from the single quote carefully.

    Note that I've made backtick distribute over lists, matrices, and equations, i.e.

    (a = b)`m
    

    simplifies to:

    a`m = b`m
    

    When I wrote the ezunits package, I thought about making backtick distribute over lists automatically, but decided against it. Do you have any comments on this topic? I'm interested to hear what users have to say about it.