mmzc
mmzc

Reputation: 622

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

Upvotes: 0

Views: 470

Answers (2)

Robert Dodier
Robert Dodier

Reputation: 17577

OP asked about converting %e^x to exp(x). That's easy to do, but to make it stick, we have to disable simplification, i.e. the application of identities which Maxima uses to find a general representation of an expression. By default Maxima simplifies exp(x) to %e^x. We can replace %e^x by exp(x) but we need to disable simplification to prevent it from going back again.

(%i1) simp:false $
(%i2) matchdeclare (xx, all) $
(%i3) defrule (to_exp, %e^xx, Math.exp(xx));
                                   xx
(%o3)                   to_exp : %e   -> Math . exp(xx)
(%i4) apply1 (1 + %e^(x + %e^y), to_exp);
(%o4)                  1 + Math . exp(x + Math . exp(y))

Probably you only want to disable simplification (i.e. simp:false) when you are ready to output the expression. But I can imagine situations in which you would have it disabled, e.g. if it is important to output the expression exactly the way it was entered, e.g. x + x instead of 2*x.

I've used a different mechanism to do the replacement here, namely defrule which defines a pattern matching rule. Pattern matching is very useful, and I encourage you to take a look at defrule and matchdeclare in the Maxima documentation.

Upvotes: 1

Robert Dodier
Robert Dodier

Reputation: 17577

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?

Upvotes: 1

Related Questions