2

consider the two arrays:

x = [0 .05 .1 .3 .32 .4 .55 .7 1 1.3 1.4 1.45 1.6 1.8 1.9 2 2.2 2.3 2.6 2.8 2.91 3];
y = x.^2;

I want to integrate y over x. So far, I have figured out that I can use the trapz() function in a for loop:

y1 = zeros(length(x));

for ii = 1:length(x)
    y1(ii) = trapz(x(1:ii), y(1:ii));
end

plot(x, y1, x, y);

However, I wondered if there is a canonical way to do this without using a for loop.

P.S.1. I suppose MATLAB/Octave are vectorized functions, and there should be predefined functions to take care of this sort of stuff.

P.S.2. I do not own a MATLAB license now, but the answer must be compatible with both MATLAB and Octave.

Foad S. Farimani
  • 12,396
  • 15
  • 78
  • 193

2 Answers2

4

Sounds like you want the cumtrapz( ) function:

y1 = zeros(length(x), 1);

y1 = cumtrapz(x, y)
plot(x, y1, x, y);
Foad S. Farimani
  • 12,396
  • 15
  • 78
  • 193
James Tursa
  • 2,242
  • 8
  • 9
  • It is just for the uniformly spaced data though. – Foad S. Farimani Feb 26 '21 at 20:17
  • 2
    No need to use `y1 = zeros(length(x), 1);` since you throw this away in the next line. See ["Ineffective Preallocation"](https://blogs.mathworks.com/steve/2016/08/01/ineffective-preallocation/) – Sardar Usama Feb 26 '21 at 20:47
  • 1
    @Foad `cumtrapz` works for non-uniform spacing too. Example: `x = linspace(0,3,1e4).^2; cumtrapz(x, exp(-x.^2/2)/sqrt(2*pi))` – Luis Mendo Feb 26 '21 at 22:04
1

You can use cumsum and diff:

y1 = [0 cumsum((y(1:end-1) + diff(y)/2) .* diff(x))];
rahnema1
  • 15,264
  • 3
  • 15
  • 27