I wish to display logarithms with different bases in the single-term rather than numerator/denominator form during output:
Log[17]/Log[2] -> Log2[17]
Log[13]/Log[10] -> Log10[13]
Log[99]/Log[11] -> Log[11, 99]
What is the best way to apply formatting rules like this?
Answer
One can use $PrePrint
and ReplaceAll
to effect this:
$PrePrint = # /. {
Log[n_]/Log[2] :> Defer @ Log2[n],
Log[n_]/Log[10] :> Defer @ Log10[n],
Log[n_]/Log[b_] :> Defer @ Log[b, n]
} &;
Or MakeBoxes
:
MakeBoxes[Log[n_]/Log[2], fmt_] := ToBoxes[Defer @ Log2[n], fmt]
MakeBoxes[Log[n_]/Log[10], fmt_] := ToBoxes[Defer @ Log10[n], fmt]
MakeBoxes[Log[n_]/Log[b_], fmt_] := ToBoxes[Defer @ Log[b, n], fmt]
It is also possible to use Format
but in this case it requires unprotecting Times
:
Unprotect[Times];
Format[Log[n_]/Log[2]] := Defer @ Log2[n]
Format[Log[n_]/Log[10]] := Defer @ Log10[n]
Format[Log[n_]/Log[b_]] := Defer @ Log[b, n]
Protect[Times];
These assignments are made to a special class of rules: FormatValues
. Because these are only used in formatting this should not slow down internal operations using Times
, unlike overloading UpValues
or DownValues
.
Each method relies on Defer
to prevent an infinite recursion yet allow evaluation of output when it is given as input.
Result:
Comments
Post a Comment