Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm wondering if there are generalizations of the sqrt function in Maxima? In particular, I'd like to be able to control whether x^(a/b) displays as $x^{frac{a}{b}}$ or $sqrt[b]{x^{a}}$.

I searched the index of the documentation for root but didn't find anything that I could identify as relevant, and there weren't any links from the sqrtdispflag entry.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
3.6k views
Welcome To Ask or Share your Answers For Others

1 Answer

This is an interesting question, showing, once again, that Maxima could benefit from a more flexible TeX output system, but I digress. Here's a possible solution.

This uses pattern matching (in defmatch) to identify something-to-a-quotient expressions for further processing, pulling out the numerator and denominator of the quotient if the match is successful. The pattern matcher fails to identify stuff like b/c^2 -- this should probably be considered a bug in the pattern matcher.

The default TeX output function is a Lisp function named TEX-MEXPT. I wrote a line of Lisp code (admittedly obscure) to call it.

/* tex_mexpt.mac -- look for quotient in exponent
 * copyright 2021 by Robert Dodier
 * I release this work under terms of the GNU General Public License
 */

matchdeclare (aa, all);
matchdeclare (bb, "#"(1));
defmatch (matches_quotient, aa/bb);
defmatch (matches_minus_quotient, -aa/bb);

:lisp (defun $tex_mexpt_default (e) (let (lop rop) (apply 'concatenate 'string (tex-mexpt e nil nil))))

my_tex_mexpt_quotient (base, expt_num, expt_denom) :=
  if expt_num = 1
    then printf(false, "\sqrt[~a]{~a}", tex1 (expt_denom), tex1 (base))
    else printf(false, "\sqrt[~a]{~a}", tex1 (expt_denom), tex_mexpt_default (base^expt_num));

my_tex_mexpt_minus_quotient (base, expt_num, expt_denom) :=
  if expt_num = 1
    then printf(false, "\sqrt[~a]{{1}\over{~a}}", tex1 (expt_denom), tex1 (base))
    else printf(false, "\sqrt[~a]{~a}", tex1 (expt_denom), tex_mexpt_default (base^-expt_num));

my_tex_mexpt (e) :=
  if tex_mexpt_look_for_quotient
    then block ([base, expt],
                [base, expt]: args(e),
                if matches_quotient(expt) # false
                  then my_tex_mexpt_quotient (base, aa, bb)
                elseif matches_minus_quotient(expt) # false
                  then my_tex_mexpt_minus_quotient (base, aa, bb)
                  else tex_mexpt_default (e))
    else tex_mexpt_default (e);

/* examples */

stringdisp: true $

verbatim_and_equation (e) ::= printf (S, "\begin{verbatim}~%~a~%\end{verbatim}~%$$~a$$~%", string(e), tex1(e));

S: openw ("/tmp/foo.tex");
printf (S, "\documentclass{article}~%\begin{document}~%");

/* first without my_tex_mexpt at all */

verbatim_and_equation (a^(b/c));
verbatim_and_equation (a^-(b/c));
verbatim_and_equation (a^(-b/c));
verbatim_and_equation (a^(1/c));
verbatim_and_equation (a^-(1/c));
verbatim_and_equation (a^(-1/c));
verbatim_and_equation ((1 + (1 - x)^((y - z)/(y - w)))/((2*u - v)^(1/(n + 1))));

/* now enable my_tex_mexpt */

texput ("^", my_tex_mexpt);
tex_mexpt_look_for_quotient:true;

verbatim_and_equation (a^(b/c));
verbatim_and_equation (a^-(b/c));
verbatim_and_equation (a^(-b/c));
verbatim_and_equation (a^(1/c));
verbatim_and_equation (a^-(1/c));
verbatim_and_equation (a^(-1/c));
verbatim_and_equation ((1 + (1 - x)^((y - z)/(y - w)))/((2*u - v)^(1/(n + 1))));

/* verify disabled produces same output as originally */

tex_mexpt_look_for_quotient:false;

verbatim_and_equation (a^(b/c));
verbatim_and_equation (a^-(b/c));
verbatim_and_equation (a^(-b/c));
verbatim_and_equation (a^(1/c));
verbatim_and_equation (a^-(1/c));
verbatim_and_equation (a^(-1/c));
verbatim_and_equation ((1 + (1 - x)^((y - z)/(y - w)))/((2*u - v)^(1/(n + 1))));

printf (S, "\end{document}~%");
close(S);

As you can see I put a number of examples in there to verify the output a little bit. You can execute it via maxima --batch=foo.mac or whatever the name of the saved file is. It generates output in /tmp/foo.tex. I processed that with latex and then viewed it with xdvi.

For the record, here is the foo.tex output I get.

documentclass{article}
egin{document}
egin{verbatim}
a^(b/c)
end{verbatim}
$$a^{{{b}over{c}}}$$
egin{verbatim}
a^-(b/c)
end{verbatim}
$${{1}over{a^{{{b}over{c}}}}}$$
egin{verbatim}
a^((-b)/c)
end{verbatim}
$${{1}over{a^{{{b}over{c}}}}}$$
egin{verbatim}
a^(1/c)
end{verbatim}
$$a^{{{1}over{c}}}$$
egin{verbatim}
a^-(1/c)
end{verbatim}
$${{1}over{a^{{{1}over{c}}}}}$$
egin{verbatim}
a^((-1)/c)
end{verbatim}
$${{1}over{a^{{{1}over{c}}}}}$$
egin{verbatim}
(1+(1-x)^((y-z)/(y-w)))/(2*u-v)^(1/(n+1))
end{verbatim}
$${{left(1-x
ight)^{{{y-z}over{y-w}}}+1}over{left(2,u-v
ight)^{{{1}over{n+1}}}}}$$
egin{verbatim}
a^(b/c)
end{verbatim}
$$sqrt[c]{a^{b}}$$
egin{verbatim}
a^-(b/c)
end{verbatim}
$${{1}over{sqrt[c]{a^{b}}}}$$
egin{verbatim}
a^((-b)/c)
end{verbatim}
$${{1}over{sqrt[c]{a^{b}}}}$$
egin{verbatim}
a^(1/c)
end{verbatim}
$$sqrt[c]{a}$$
egin{verbatim}
a^-(1/c)
end{verbatim}
$${{1}over{sqrt[c]{a}}}$$
egin{verbatim}
a^((-1)/c)
end{verbatim}
$${{1}over{sqrt[c]{a}}}$$
egin{verbatim}
(1+(1-x)^((y-z)/(y-w)))/(2*u-v)^(1/(n+1))
end{verbatim}
$${{sqrt[y-w]{left(1-x
ight)^{y-z}}+1}over{sqrt[n+1]{2,u-v}}}$$
egin{verbatim}
a^(b/c)
end{verbatim}
$$a^{{{b}over{c}}}$$
egin{verbatim}
a^-(b/c)
end{verbatim}
$${{1}over{a^{{{b}over{c}}}}}$$
egin{verbatim}
a^((-b)/c)
end{verbatim}
$${{1}over{a^{{{b}over{c}}}}}$$
egin{verbatim}
a^(1/c)
end{verbatim}
$$a^{{{1}over{c}}}$$
egin{verbatim}
a^-(1/c)
end{verbatim}
$${{1}over{a^{{{1}over{c}}}}}$$
egin{verbatim}
a^((-1)/c)
end{verbatim}
$${{1}over{a^{{{1}over{c}}}}}$$
egin{verbatim}
(1+(1-x)^((y-z)/(y-w)))/(2*u-v)^(1/(n+1))
end{verbatim}
$${{left(1-x
ight)^{{{y-z}over{y-w}}}+1}over{left(2,u-v
ight)^{{{1}over{n+1}}}}}$$
end{document}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...