Functions with functions as arguments

Hi everyone. This doubt of mine does seem stupid, but I can’t seem to figure it out.

I’m 100% sure that I’ve wrote this simple (working) code for the usage of Simpson’s rule before, on a Numerical Analysis project, like the following

simpson[f_, nos_] := 
 Block[{h = nos[[2]] - nos[[1]], 
   n = Length[nos]}, (h/3) (f[nos[[1]]] + f[nos[[n]]] + 
     4 Sum[f[nos[[2 k]]], {k, (n - 1)/2}] + 
     2 Sum[f[nós[[2 k + 1]]], {k, (n - 3)/2}])]

Bare in mind that “nos” is the vector with nodal values for x, i.e. the x_i’s.
However, I’ve started using Mathematica again for another course, and this code right now isn’t working as before (I thinkkkk).

I thought of doing something like

function[ff_,a_]:=Block[{f},
    f[x_]:=ff;
    f[a]]

which also used to work for me before, but running " function[x,3] " also yields “x”.
Can anyone help me with this? There must be something stupid I’m doing. I’ll add that, interestingly enough, using f for integration does work on these kinds of functions; the problem seems to happen only when I need to evaluate the argument on a given point ( i.e. obtain f[x] ).

Finally, what would be your preferred ways of handling functions with other functions as arguments?

Thank you all. :slight_smile:

EDIT:

An even simpler example, running this code

function[f_]:=f[3]
function[x]

yields the result “x[3]”, however, my goal is to be able to obtain “3” with it. How could I do it?

You are using n = Length[nos], but in Simpson’s rule n should be the number of intervals, not the number of nodes.

Hi Gustavo

This works fine for me.

function[f_]:=f[3]
function[x]
(* x[3] *)

If the result for you is x, most likely you have x[3] = x defined. Try again after evaluating ClearAll[x, f, function]

Yes, thank you about that, but my actual problem is about being able to evaluate the argument (i.e. be able to use f[x] and such) inside the function.

Indeed, it yields “x[3]”, that’s my bad, however, this code

ClearAll[x, f, function]
function[ff_] := Block[{f},
  f[x_] := ff;
  f[3]]
function[x]

is yielding “x”. How could I write my function as to be able to obtain “3” (i.e. f evaluated at 3)?

Not sure what you are trying to accomplish. x is the result of f evaluated at 3. The function f[x_] := ff does not depend on x, it evaluates to ff no matter what argument it is passed. So function evaluates to whatever argument it is passed.

Basically, I’m trying to understand how to create a function which can receive the explicit form of another function, such that I can use it inside the original function.
i.e. create “result[f_]” where “f” is a function of x, for example, and be able to work with “f[x]” inside the code of “result”.

I mean, how else would you define (for example) a function “trapezoidal” which applies the trapezoidal method for integrating a given function “f” numerically in the interval [a,b] ?

Something like this?

integrate[func_, range_] := Integrate[func[x], {x, Splice@range}]

integrate[Sin, {0, Pi}]
(* 2 *)

integrate[Cos, {0, Pi/2}]
(* 1 *)

Something unexpected happens when you write f[x_]:=ff inside Block:

function[ff_] := Block[{f}, f[x_] := ff;
  f[3]]
function[x] // Trace

You will see that f[x_] becomes f[x$_]. This way the symbol x in function[x] does not match the pattern x$_ . To get the expected result you have to use x$ in your input:

In[5]:= function[x$]

Out[5]= 3

There is probably a good reason for this behaviour, but I am not an expert.

Nice. I guess I’ll be using “$” then.

In the meantime, I’ve discovered another way to do what I wanted

in another discussion ( How do I fix this trapezoidal rule input? ).
Note that the important part of that code for this discussion is "func /. var → " ).