Transpose(), described as a function in the info files, seems to have
special properties when it comes to TeX output.
A bit of Googling revealed that this problem is a long standing one, and
that some workarounds were developed.Something seems to have changed
recently (in the last 18 months), which disables these workaround. See
further comments after an example...
Commented transcript from a Maxima sesssion (maxima mode in emacs, I've
checked that execution in a terminal give the same results) :
Maxima 5.26.0 http://maxima.sourceforge.net
using Lisp GNU Common Lisp (GCL) GCL 2.6.7 (a.k.a. GCL)
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
/* First, check our logic on an "ordinary" case : use lcm, as in the
Maxima info files, but with another mechanism to replace it : */
/* Original output */
(%i1) tex(lcm(a,b));
$${\it lcm}\left(a , b\right)$$
(%o1) false
/* Replacement function (BTW, Maxima does not seem to accept a lambda
definition of the function? Why ? */
(%i2) lcmput(e):=block([foo],
foo:lambda([x],
if length(x)=1
then tex1(first(x))
else concat(tex1(first(x)), ",", foo(rest
(x)))),
concat("\\mathrm{lcm}\\left(",
foo(args(e)),
"\\right)"));
(%o2) lcmput(e) := block([foo], foo : lambda([x],
if length(x) = 1 then tex1(first(x)) else concat(tex1(first(x)), ",",
foo(rest(x)))), concat("\mathrm{lcm}\left(", foo(args(e)), "\right)"))
/* Hook it in place */
(%i3) texput(lcm, lcmput);
(%o3) lcmput
/* Test it */
(%i4) tex(lcm(a,b));
$$\mathrm{lcm}\left(a,b\right)$$
(%o4) false
/* Okay ... Let's try the very same trick with transpose */
/* Original result */
(%i5) tex(transpose(A));
$${\it transpose}\left(A\right)$$
(%o5) false
/* Replacement function */
(%i6) transposeput(e):=block([foo],
foo:lambda([x],
if length(x)=1
then tex1(first(x))
else concat(tex1(first(x)), ",",
foo(rest(x)))),
concat("\\mathrm{t}\\left(",
foo(args(e)),
"\\right)"));
(%o6) transposeput(e) := block([foo], foo :
lambda([x], if length(x) = 1 then tex1(first(x))
else concat(tex1(first(x)), ",", foo(rest(x)))),
concat("\mathrm{t}\left(", foo(args(e)), "\right)"))
/* Hook it in place */
(%i7) texput(transpose, transposeput);
(%o7) transposeput
/* Test it */
(%i8) tex(transpose(A));
$${\it transpose}\left(A\right)$$
(%o8) false
/* The original definition is still used. Putting debugging print()
statements in the function shows that it is never called... */
/* Trying another trick found through googling (Zbigniew Komarnicki on
this very list, dated 12 Jul 2010 21:54 */
(%i9) matchfix("transpose(", ")")$
(%i10) texput ("transpose(", [" (", ")^T"], matchfix)$
(%i11) texput(".", "", nary)$
/* test it */
(%i12) tex(transpose(A));
$${\it transpose}\left(A\right)$$
(%o12) false
/* AAAaaarghhh ! Still SOL. Something seems to have changed between then
and now : ZK claimed that his solution worked... */
The problem might be related to the fact that, when no "real" execution
of transpose is possible, this function returns a noun, which might
explain that the texput mechanism, which hooks a user-defined value|
function to a function|operator, is inefficient. From the info file :
-- Function: transpose (<M>)
Returns the transpose of <M>.
If <M> is a matrix, the return value is another matrix <N> such
that `N[i,j] = M[j,i]'.
If <M> is a list, the return value is a matrix <N> of `length (m)'
rows and 1 column, such that `N[i,1] = M[i]'.
************** Here is the important bit ! **************
Otherwise <M> is a symbol, and the return value is a noun
expression `'transpose (<M>)'.
*********************************************************
Does someone has a suggestion on how to trigger a user-defined function
in the TeXing of a noun ?
Sincerely yours,
Emmanuel Charpentier