High precision expressions and functions
- To: mathgroup at smc.vnet.net
- Subject: [mg13749] High precision expressions and functions
- From: "Allan Hayes" <hay at haystack.demon.cc.uk>
- Date: Wed, 19 Aug 1998 01:38:36 -0400
- Sender: owner-wri-mathgroup at wolfram.com
The recent thread "High precision numbers and Plot", and the article
"Bending Plot to Your Needs" by Stan Wagon in Education and Research
Volume 7 No 2, Spring 1998 stimulated some experiments which resulted
in the following code
PrecisionExpression::usage = "PrecisionExpression[expr, {x1,x2..}, p]
for symbols x1,x2 and positive integer p gives an expression PEexpr
which, with x1=r1, x2 = r2,.., evaluates with working precision p,
starting with, xi = If[InexactNumberQ[vi], SetPrecision[vi, p], vi].
PrecisionExpression[expr, x, p], for a symbol x evaluates like
PrecisionExpression[expr, {x}, p] "
PrecisionExpression[expr_, x_, p_] :=
Function[x, #][##2] &[
expr /. r_?InexactNumberQ :> SetPrecision[r, p],
Sequence@@(
Switch[#,
_?InexactNumberQ, SetPrecision[#, p],
_?NumberQ, #
] &/@Flatten[{x}]
)
]
PrecisionFunction::usage = "PrecisionFunction[expr, {x1,x2..}, p] for
symbols x1,x2 and positive integer p gives a function FPexpr with
working precision p. PFexpr[v1,v2,..] becomes
PFexpr[If[InexactNumberQ[v1], SetPrecision[v1, p], vi] ,..].
PrecisionFunction[expr, x, p], for a symbol x evaluates like
PrecisionFunction[expr, {x}, p]. "
PrecisionFunction[expr_, x_, p_] :=
Function[x, Function[x, #][##2]] &[
expr /. r_?InexactNumberQ :> SetPrecision[r,p],
Sequence@@(
Switch[#,
_?InexactNumberQ, SetPrecision[#, p],
_?NumberQ, #
] &/@Flatten[{x}]
)
]
PrecisionExpression is the more flexible, but usually gives a slightly
slower result.
Examples:
(1)Speed
f1 = Normal[Series[Cos[x], {x, 0, 200}]];
expr = PrecisionExpression[f1, {x}, 30];
Block[{x = 1.2}, Do[expr, {50}] // Timing]
{6.26 Second, Null}
foo = PrecisionFunction[f1, {x}, 30];
Do[foo[1.2], {50}] // Timing
{4.56 Second, Null}
(2) Applications
f2= Log[1. - Erf[x]] + x^2;
Plot[#[x], {x, 0, 8}] &[PrecisionFunction[f2, x, 30]]
Plot[Evaluate[PrecisionExpression[{f2, Sin[x]-1.5}, x, 30]], {x, 0, 8}]
Plot3D[Evaluate[PrecisionExpression[f2 Sin[y], {x,y}, 30]], {x, 0,
8},{y,0,8}]
ContourPlot[Evaluate[PrecisionExpression[f2 Sin[y], {x,y}, 30]], {x, 0,
8},{y,0,8}]
Note: compiling is not used (it would spoil the precision), but we might
take the precaution of setting Compiled -> False. The (brief)time used
for checking if compiling is possible would also be save.
------------------------------------------------------------- Allan
Hayes
Training and Consulting
Leicester UK
http://www.haystack.demon.co.uk
hay at haystack.demon.co.uk
voice: +44 (0)116 271 4198
fax: +44(0)116 271 8642