# Why are these two ways of writing the same integral giving me different results?

3 views (last 30 days)
Edited: Jan on 24 Apr 2021
function pot1 = potencial_viviani1(R,a)
kappa=8.9875e9;
rho1=3e-5;
f=@(t) R.*sqrt(1+cos(t).^2) ./ norm( [R*cos(t).^2-a(1), R*cos(t).*sin(t)-a(2), R*sin(t)-a(3)] ) ;
pot1=kappa*rho1*integral(f,0,pi);
end
And this alternative way
function pot2 = potencial_viviani2(R,a)
kappa=8.9875e9;
rho1=3e-5;
f= @(t) (R.*sqrt(1+cos(t).^2))./sqrt((R.*cos(t).^2 - a(1)).^2 + (R.*sin(t).*cos(t) -a(2)).^2 + (R.*sin(t) - a(3)).^2);
pot2=kappa*rho1*integral(f,0,pi);
end
I don't know why they're giving me different answers, when I call each function as follows:
potencial_viviani1(2,[2,3,4])
potencial_viviani2(2,[2,3,4])

G A on 24 Apr 2021
Edited: G A on 24 Apr 2021
Use the option 'ArrayValued',true
pot1=kappa*rho1*integral(f,0,pi,'ArrayValued',true);

Jan on 24 Apr 2021
Edited: Jan on 24 Apr 2021
integral() calls the function with a vector as input. Then norm() calcuates the matrix norm in the 1st function, while the 2nd function calculates the vector norm over the 2nd dimension.
x = [1, 2; 3, 4]
x = 2×2
1 2 3 4
norm(x)
ans = 5.4650
sqrt(sum(x .^ 2, 2))
ans = 2×1
2.2361 5.0000
But if you choose vecnorm instead, the difference is still there:
R = 2;
a = [2,3,4];
kappa = 8.9875e9;
rho1 = 3e-5;
% Omit the equal part: R .* sqrt(1 + cos(t) .^ 2)
f1 = @(t) vecnorm([R * cos(t) .^ 2 - a(1), ...
R * sin(t) .* cos(t) - a(2), ...
R * sin(t) - a(3)], 2, 2);
f2 = @(t) sqrt((R .* cos(t) .^ 2 - a(1)) .^ 2 + ...
(R .* sin(t) .* cos(t) - a(2)) .^ 2 + ...
(R .* sin(t) - a(3)) .^ 2);
f1(1)
ans = 3.4271
f2(1)
ans = 3.4271
Fine. But:
f1([1, 2])
ans = 5.7751
f2([1, 2])
ans = 1×2
3.4271 4.6483
% Better:
f1 = @(t) vecnorm([R * cos(t(:)) .^ 2 - a(1), ...
R * sin(t(:)) .* cos(t(:)) - a(2), ...
R * sin(t(:)) - a(3)], 2, 2);
f1([1, 2])
ans = 2×1
3.4271 4.6483
Now the values are equal, but the dimensions of intput and output differs, which confuses integral:
Error using integralCalc/finalInputChecks (line 526)
Output of the function must be the same size as the input. If FUN
is an array-valued integrand, set the 'ArrayValued' option to true.
So the output has to be adjusted to the size of the input:
f = @(t) reshape(R .* sqrt(1 + cos(t(:)) .^ 2) ./ ...
vecnorm([R * cos(t(:)) .^ 2 - a(1), ...
R * sin(t(:)) .* cos(t(:)) - a(2), ...
R * sin(t(:)) - a(3)], 2, 2), size(t));
This is ugly.
Setting the 'ArrayValued' option to true would solve the problem, because then the function is called with a scalar input onle. But you've asked for the reason of the difference. And with the modification, the integration is faster, because it can call f() with an array as input.