Integrate a function that does not work directly by elements

Good morning / evening / evening

I am working on a Matlab script that includes calculating volume integrals of fourth-order tensors. Let H (r, theta, phi) be the function I want to integrate. Suppose that cannot be obtained by simple operations on r, theta and phi.

My problem is that in Matlab, as in any other code, I know:

All input functions must accept arrays and operate elementwise. The function FUN(X,Y,Z) must accept arrays X, Y, Z of the same size and return an array of corresponding values. 

This is from the implementation of the integ3 function from Matlab.

If I try to execute this simple function:

 fun = @(X,Y,Z) X.*Y.*Z 

There is no problem, and if I integrate it over [0,1] x [0,1] x [0,1], I get the correct result:

 integral3(fun,0,1,0,1,0,1) 

returns 0.125, which is correct.

The problem is that, as I said, I cannot do simple calculations with vectors to get H, and I am forced to do something more or less as follows:

 function [result] = fun(x,y,z) sz = length(x); result = zeros(1,sz); for i=1:sz result(i) = x(i)*y(i)*z(i); end end 

This function works on its own and returns exactly the same results as the previous one. However, when I try to use integer3, I get this error:

 Error using integral2Calc>integral2t/tensor (line 241) Integrand output size does not match the input size 

But from the definition of my function, it is clear that I specifically made this the size of the input.

I don’t understand what is wrong, and I’m not sure that I have a different solution for calculating this function than using this syntax.

Thank you very much for your time and help :)

+7
math matlab numerical-methods numerical-integration
source share
1 answer

You are on the right track, but you are building an array with the correct length but the wrong size. This is the subtle difference in Matlab. I assume that integral3 is passed in a column vector, but your function always returns a row vector. Column and row names have the same "lengths" sz , but different "sizes": the column vector [sz,1] and the row vector [1,sz] . The code below does what you want, because it uses size to ensure that all output sizes are the same as input and numel to cycle through the individual elements:

 function result = fun(x,y,z) sz = size(x); result = zeros(sz); for i = 1:numel(x) result(i) = x(i)*y(i)*z(i); end end 

A good rule of thumb is to use only size and numel and never use length , which is the contender for the worst function in Matlab.

+4
source share

All Articles