Search code examples
casmaxima

let maxima display an exponentiation as a function instead of a caret


maxima accepts both a^b and a**b as input for exponentiation, and will always output the exponent with caret ^.

Is it also possible to get the output as a function, like pow(a,b)?


Solution

  • OK, as you said, you want to output Math.pow(a,b) for Javascript. The approach I'll suggest here is to replace a^b expressions in Maxima with Math.pow(a,b) expressions and output that.

    (%i1) e : sqrt(a) + b^(3/2) + 1/c + exp(d^f);
                                  f
                                 d    1    3/2
    (%o1)                      %e   + - + b    + sqrt(a)
                                      c
    (%i2) subst ("^"=lambda([a, b], Math.pow(a, b)), e);
                                             3                  1
    (%o2) Math . pow(c, - 1) + Math . pow(b, -) + Math . pow(a, -)
                                             2                  2
                                                 + Math . pow(%e, Math . pow(d, f))
    

    OK, so that's most of the work there. Some expressions are represented as "^" expressions even if they appear to be something else, for example, sqrt(a) is a^(1/2) and 1/c is c^(-1). If you need for those to be preserved as sqrt(a) and 1/c then we'll have to work on that.

    I'm guessing it's best to have floating point values instead of integer ratios. Also, we'll replace %e by its numerical value. If you want %e^x to be rendered as Math.exp(x), we can work on that. Or if you want Math.pow(Math.E, x), that's relatively simple; just evaluate subst(%e = Math.E, <your expression>).

    (%i3) float (%);
    (%o3) Math . pow(c, - 1.0) + Math . pow(b, 1.5) + Math . pow(a, 0.5)
                                  + Math . pow(2.718281828459045, Math . pow(d, f))
    

    Maxima considers x . y to mean noncommutative multiplication, but that doesn't come into play here so that's fine. By default it is displayed with a space on either side of the dot, but if you're willing to do a tiny amount of Lisp hacking we can remove the space. (I guess it doesn't matter to Javascript, right? Math . pow is equivalent to Math.pow, isn't it?)

    (%i4) :lisp (setf (get 'mnctimes 'dissym) '(#\.))
    (.)
    (%i4) %o3;
    (%o4) Math.pow(c, - 1.0) + Math.pow(b, 1.5) + Math.pow(a, 0.5)
                                      + Math.pow(2.718281828459045, Math.pow(d, f))
    

    OK, now we can output the expression.

    (%i5) grind (%o3);
    Math.pow(c,-1.0)+Math.pow(b,1.5)+Math.pow(a,0.5)
                    +Math.pow(2.718281828459045,Math.pow(d,f))$
    (%o5)                                done
    

    Is that the expected output?