(* 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[]