Re: "f[x_]:= 2 x" vs. "f = 2 #&"
- To: mathgroup at smc.vnet.net
 - Subject: [mg16497] Re: [mg16365] "f[x_]:= 2 x" vs. "f = 2 #&"
 - From: "Allan Hayes" <hay at haystack.demon.co.uk>
 - Date: Tue, 16 Mar 1999 03:59:47 -0500
 - References: <7cd7qh$o8i@smc.vnet.net>
 - Sender: owner-wri-mathgroup at wolfram.com
 
Ersek, Ted R wrote in message <7cd7qh$o8i at smc.vnet.net>...
>Kevin Jaffe wrote:
snip
>-------------------------------
>Suppose you are writing a program with the form
>  func[x_]:= (*****algorithm*****)
>and (algorithm) has to make a function that will be used at later stages of
>(algorithm).
>
>It's illegal to use patterns on the right side of a definition.
>So (algorithm) can't make the function with the approach
>  f[x_]:= 2 x
>It also can't make the function with the approach
>  f[x_]= 2 x
>Instead (algorithm) must make the function with one of the following
>  f=2#&
>  f=Function[2#]
>  f=Function[x,2x]
>So when would you need to do this?
>One such case is the function below.  This function will plot a function
>using arbitrary precision arithmetic to sample the function.  This is
useful
>in special cases when a function must be sampled using arbitrary precision
>arithmetic.
>
>(***********)
>PrecisionPlot[f_,{x_,xmin_,xmax_},opts___?OptionQ]:=
> Module[{g,h},
>  (g=Function[f/.x->#];
>     h=(g[SetPrecision[#,17]]&);
>     Plot[h[x],{x,xmin,xmax},opts]
>   )
> ]
>(***********)
>
>As far as I can tell there was no way to get PrecisionPlot working without
>using a pure function as I do with   g=Function[f/.x->#]
Ted,
(1)------------------
We can use patterns on the right of definitions - but we do need to be
careful, and as you indicate, scoping can loom large.
For example
Clear["`*"]
func[x_] := (g[y_] := x + y)
func[a]
g[b]
    a + b
func2[y_] := (h[y_] := x + y)
RuleDelayed::"rhs": "Pattern \!\(y_\) appears on the right-hand side of rule
\
\!\(\(func2[y_]\) :> \(\(h[y_]\) := \(x + y\)\)\)."
Despite the warnings we get:
func2[a]
h[b]
    b + x
Some problems are shown by
func2[3]
Pattern::"patvar": "First element in pattern \!\(Pattern[\(3, _\)]\) is not
a \
valid pattern name."
and
func3[x_] := Block[{x, y}, x + y]
func3[y]
Block::"dup": "Duplicate local variable \!\(y\) found in local variable \
specification \!\({y, y}\)."
Block[{y, y}, y + y]
(2) -------------------------
Here is a ways of avoiding using a pure function in your PrecisePlot code
PrecisePlot2[f_, {x_, xmin_, xmax_}, opts___] :=
Module[{g}, g[x_] := f;
          Plot[ g[SetPrecision[x, 17]], {x, xmin, xmax},
         Compiled -> False, opts
      ]]
I'll  test this with
f1 = Sin[x]*10^x*Log[1 + 10^(-x)];
Plot does not do well with it
Plot[f1, {x, 15, 20}]
but try
PrecisePlot2[f1, {x, 15, 20}];
Two more versions - the first one  using a pure function-
PrecisePlot3[f_, {x_, xmin_, xmax_}, opts___] :=
 Plot[
      Function[x, f][SetPrecision[x, 17]],
     {x, xmin, xmax},
    Compiled -> False, opts]
PrecisePlot3[f1, {x, 15, 20}];
and
PrecisePlot4[f_, {x_, xmin_, xmax_}, opts___] :=
 Plot[
     Unevaluated[f] /. HoldPattern[x] :> SetPrecision[x, 17],
     {x, xmin, xmax},
    Compiled -> False, opts
    ]
PrecisePlot4[f1, {x, 15, 20}];
(3)------------------
Similar problems with precision have recently been discussed in
Mathematic in Education and Research:
Volume 7 No 2, Spring 1998, p 50
Volume 7 No 4, Fall 1998, p 64
Allan
---------------------
Allan Hayes
Mathematica Training and Consulting
Leicester UK
www.haystack.demon.co.uk
hay at haystack.demon.co.uk
Voice: +44 (0)116 271 4198
Fax: +44 (0)870 164 0565