(*
This defines a Scale command, which is a fast way to get an
approximation to Log[10, Abs[x]].
*)
BeginPackage["Utilities`Scale`"];
Scale::usage = "Scale[x] gives a machine number approximation to Log[10, Abs[x]] for a number x."
Begin["`Private`"]
(* Machine numbers need a special case because Precision only refers
to $MachinePrecision, and significance is not kept. *)
Scale[x_?MachineNumberQ] := If[x == 0., -Infinity, Log[10., Abs[x]]];
(* In the developement version of Mathematica (after 4.2!),
Precision and Accuracy are no longer rounded. (Hooray!) *)
If[$VersionNumber <= 4.2,
Scale[x_Real?NumberQ] :=
Precision[x, Round->False] - Accuracy[x, Round->False],
Scale[x_Real?NumberQ] := Precision[x] - Accuracy[x]
];
(*
For x == a + I b, based on
Log[10, Sqrt[a^2 + b^2]] ==
(1/2) (Log[10, a^2 (1 + (b/a)^2)]) ==
Log[10,a] + (1/2) Log[10, 1 + 10^(2 Log[10, b/a])] ==
Scale[a] + (1/2) Log[10, 1 + 10^(2 (Scale[b] - Scale[a]))]
*)
Scale[x_Complex?NumberQ] := Module[{sr = Scale[Re[x]], si = Scale[Im[x]]},
If[sr == -Infinity,
si,
If[si == -Infinity,
sr,
sr + Log[10., 1 + 10.^(2.*(si - sr))]
]
]
];
(*
Since this is an approximation, we numericize exact numbers.
*)
Scale[x_?NumberQ] := Scale[N[x]];
End[(* Private *)]
EndPackage[]