Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.0k views
in Technique[技术] by (71.8m points)

tex - (wx)Maxima: general roots of numbers, beyond sqrt?

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...