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

5 vues (au cours des 30 derniers jours)
Ignacio Ayerbe Pérez-Piñar
Modifié(e) : Jan le 24 Avr 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])

Réponses (2)

G A
G A le 24 Avr 2021
Modifié(e) : G A le 24 Avr 2021
Use the option 'ArrayValued',true
pot1=kappa*rho1*integral(f,0,pi,'ArrayValued',true);

Jan
Jan le 24 Avr 2021
Modifié(e) : Jan le 24 Avr 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.

Catégories

En savoir plus sur Programming dans Help Center et File Exchange

Produits

Community Treasure Hunt

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

Start Hunting!

Translated by