I'm not sure why you want to avoid using the quad2d
function, but it's possible to split the 2D quadrature into two 1D nested quadratures (even if the function does not factorize).
Here is a way to process with the integration with two trapz
calls. The point is to generate the set of all the values in a big table and the use trapz
for both dimensions.
First, I define test values:
f= @(x,y) sin(x.*cos(y));
N = 1000;
Then, I define the grid for both the x and y directions (similar to your k2
and k3
):
xpts1d = linspace(0,1,N+1);
ypts1d = linspace(0,1,N+1);
I evaluate then the function f in all the pairs of points:
xpts = xpts1d'*ones(1,N+1);
ypts = ones(N+1,1)*ypts1d;
values = f(xpts,ypts);
Then, the integration can be done using two nested calls:
I = trapz(xpts1d,trapz(ypts1d,values,2),1);
This gives the correct answer.
In the first version of my answer, I had used the quad
function, which works with function handles directly. The "naive" idea is to simply nest the two calls, like:
I = quad( @(y) quad( @(x)f(x,y) ,0,1),0,1)
but this does not work actually. The point is that the inner quad
call does not work for vector valued functions while the outer call expects a vector values function.
To make it work, we simply need to change the inner call for the vector valued version of quad
, quadv
:
I = quad( @(y) quadv( @(x)f(x,y) ,0,1),0,1)
Now it should work and we can check that it actually gives the same answer as
I = quad2d( f, 0,1,0,1)
If you really want to use the trapz
function, I suggest that you build a function on top of trapz
that accepts a function handle and calls trapz
inside.