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

1 view (last 30 days)
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])

Answers (2)

G A
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
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.

Categories

Find more on MATLAB in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!