5
$\begingroup$

I have a numeric function f for which I would like the action of N to act only on the last two arguments (and more generally, on any chosen subset of a function's set of arguments).

More concretely, I'd like the following behavior

f[1, 1/2, 1/3, 1/4, 1/6] // N
(* f[2, 3, 4, 1/3, 0.25`, 0.1667`] *)

Neither SetAttributes[f, NHoldAll], SetAttributes[f, NHoldFirst], nor SetAttributes[f, NHoldRest] will do the job.


I've tried making the definitions the following definitions, the result of calling N[f[1, 1/2, 1/3, 1/4, 1/6]] is summarized after each definition.

(*1*) N[f[a_, b_, c_, d_, e_]] := f[a, b, c, N[d], N[e]];
      (* Leads to an infinite recursion, but output is correct *)

and

(*2*) SetAttributes[f,NHoldAll];
      N[f[a_, b_, c_, d_, e_]] := f[a, b, c, N[d], N[e]];
      (*Same behavior as 1*)

and

(*3*) HoldPattern[N[f[a_, b_, c_, d_, e_]]] := f[a, b, c, N[d], N[e]];
      (*N incorrectly applies to all arguments*)

and

(*4*) SetAttributes[f,NHoldAll];
      HoldPattern[N[f[a_, b_, c_, d_, e_]]] := f[a, b, c, N[d], N[e]];
      (*N fails to apply to any argument*)

Question How do I mock up a behavior of N such that it only applies only to a subset of its arguments?

$\endgroup$

1 Answer 1

3
$\begingroup$

One idea is to use f[{a, b, c}, d, e] with NHoldFirst. Or, you can try:

ClearAll[f];
SetAttributes[f, NHoldAll];

f/:N[f[a_,b_,c_,d_,e_], def_.] := Module[{new=N[{d,e}, def]},
    Replace[new, {x__} :> f[a,b,c,x]] /; new=!={d,e}
]

The condition prevents the infinite recursion.

$\endgroup$
1
  • $\begingroup$ This is excellent! I'm improving upon this by using the following: (1) No TagSetDelayed since assignments to N are anyway tagged to the inside symbol. (2) With instead of Module and (3) Apply anonymous Function f[a, b, c, #1, #2] & @@ new instead of replacement Replace[new, {x__} :> f[a,b,c,x]. (not sure about performance improvement on point 3 though). $\endgroup$
    – QuantumDot
    Jun 18, 2017 at 21:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.