Does ArrayValued Affect the Efficiency of Integral()

Suppose I want to numerically integrate a function of a scalar that returns a vector
f = @(x) [1 ; sin(1000*x)];
To integrate that function I use ArrayValued = true
y = integral(f,0,2,'ArrayValued',true)
y = 2×1
2.0000 0.0014
Presumably, the integration of the second element of f requires a much smaller step size than does the first. So does integral() choose the smallest step size based on evaluations of all components of f and then apply that same step to integrate all of f, even though the first element of f doesn't need such a small step? Or does it magically integrate each compoent of f separately with different step sizes (though it's not clear to me how it could do so)?

 Accepted Answer

Based on the tests below, it appears that integral() does not develop a separate mesh for each element of f. Otherwise, I would expect the final test to have nearly double the time of the first. Also, I would expect it to be an option to specify waypoints for every element of f individually, but the documentation does not indicate such an option.
f = @(x) [1 ; sin(1000*x)];
tic;
y = integral(f,0,2,'ArrayValued',true);
toc
Elapsed time is 0.099493 seconds.
f = @(x) [1 ; 1];
tic;
y = integral(f,0,2,'ArrayValued',true);
toc
Elapsed time is 0.013101 seconds.
f = @(x) [sin(1000*x) ; sin(1000*x)];
tic;
y = integral(f,0,2,'ArrayValued',true);
toc
Elapsed time is 0.101991 seconds.

2 Comments

Thanks Matt J. The timing results are persuasive, even if I find the waypoints point less so.
Do the results below suggest it's always best to break up the vector function into indvidual scalar functions?
f1 = @(x) ones(1,numel(x));
f2 = @(x) sin(1000*x);
f = @(x) [f1(x);f2(x)];
t1 = timeit(@() integral(f,0,2,'ArrayValued',true))
t1 = 0.0176
t2a = timeit(@() integral(f1,0,2));
t2b = timeit(@() integral(f2,0,2));
t2 = t2a + t2b
t2 = 0.0011
Do the results below suggest it's always best to break up the vector function into indvidual scalar functions?
No, because you only have two functions. If you had 100 or 1000, I speculate that it wouldn't be so advantageous to split them up.
e=ones(100,1)*1000;
f1 = @(x) sin(1000*x);
f = @(x) sin(e*x(:).');
t1 = numel(e) * timeit(@() integral(f1,0,2))
t1 = 0.1479
t2 = timeit(@() integral(f,0,2,'ArrayValued',true))
t2 = 0.0376

Sign in to comment.

More Answers (0)

Categories

Find more on MATLAB in Help Center and File Exchange

Products

Release

R2022a

Asked:

on 7 May 2022

Edited:

on 8 May 2022

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!