4
$\begingroup$

I'm having trouble with a function which is supposed to work on another function. Simplified version:

one[x_] := 1 (* the argument *)
problem[f_] := Integrate[f[t], {t, 0, #}] & (* the function doing the work *)

Simple enough, right? But when I pass

problem[one] // InputForm (* to paste into se *)

I get

Integrate[one[t], {t, 0, #1}] &

and even

FullSimplify[problem[one]] // InputForm

just gives

Integrate[one[t], {t, 0, #1}] &

But I know that the function is there, since if I evaluate

problem[one][17]

it (properly) gives

17

How do I get Mathematica to substitute the function's definition for its name so it can simplify the result (in this case, evaluate the integral)?

(System details: 64-bit Mathematica 10.0.2.0, Windows 7 Pro SP1, i7-4770.)

$\endgroup$
  • $\begingroup$ So what you've defined with problem is what's called an anonymous or inline function. It's a function waiting to take arguments which will replace the #. That's why you don't get a result until you feed it the upper bound of your integral (17 in your example). Until then, it's just a function waiting for an argument to evaluate. What is it that you expect problem[one] to look like instead? $\endgroup$ – IPoiler Jul 30 '15 at 13:50
  • $\begingroup$ Try Evaluate @@ problem[one] $\endgroup$ – Dr. belisarius Jul 30 '15 at 13:54
  • $\begingroup$ Proposed duplicate: (41950). Also related: (30205) $\endgroup$ – Mr.Wizard Jul 31 '15 at 5:03
8
$\begingroup$

The problem is that the function name f is substituted into Function (&) which is HoldAll. This means f[t] will not be evaluated until the Function is evaluated, such as in the OP's example problem[one][17].

So the trick is to evaluate the integrand before inserting it into the Function. Here is one way.

one[x_] := 1 (*the argument*)
problem[f_] := With[{integrand = f[\[FormalT]]},
  Integrate[integrand, {\[FormalT], 0, #}] & 
  ]

problem[one]
(*  Integrate[1, {\[FormalT], 0, #1}] &  *)

Mathematica graphics

As @Guess who it is pointed out, the use of \[FormalT] or Esc$tEsc is safer way to define problem. If ones uses a simple t instead and t already has a value, say t = 2, then the evaluation of f[t] will substitute the value of t, and we would get f[2] for the integrand instead of a function of t. Since formal symbols cannot be assigned a value, this problem cannot occur with \[FormalT].

However, if for some reason the definition of f contained \[FormalT], say as a parameter, then we run into trouble. So maybe a better way is to use Module to localize t. This should offer even more protect at the expense of having a slightly unreadable module variable:

problem[f_] := Module[{t},
  With[{integrand = f[t]}, Integrate[integrand, {t, 0, #}] &]
  ]

problem[one]
(*  Integrate[1, {t$64741, 0, #1}] &  *)

Within one's own project, one should be able to pick a formal symbol that is never used as a parameter. So practically the first answer above should suffice.

$\endgroup$
  • 2
    $\begingroup$ Additional note: for full safety, one should consider using a formal symbol for the dummy variable. $\endgroup$ – J. M. will be back soon Jul 30 '15 at 14:06
  • $\begingroup$ @Guesswhoitis.: Can you explain how to do this? I recognized the (potential) problem of clashing variables but don't know how to handle this in Mathematica. (I can handle it in other languages, but my Math'ca isn't so good yet.) $\endgroup$ – Charles Jul 30 '15 at 14:54
  • 1
    $\begingroup$ @Charles, the idea is to use the formal symbols, \[FormalA] to \[FormalZ] (there are also upper-case versions, if needed) if you want to ensure that any dummy variable, as with sums and integrals, does not have a prior value that may have been set many cells ago. (They don't format nicely here on SE, but you should be able to see what they actually look like on the front end.) The keyboard shortcut for entering them in is Esc+\$+(letter here)+Esc. $\endgroup$ – J. M. will be back soon Jul 30 '15 at 15:05
  • $\begingroup$ @Charles I changed my answer to fit the comment. $\endgroup$ – Michael E2 Jul 30 '15 at 15:11
  • $\begingroup$ I noted a proposed duplicate in the comments above. I also note that this answer is more thorough than those. Would you review the case and give your recommendation? $\endgroup$ – Mr.Wizard Jul 31 '15 at 5:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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