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