Why are these two ways of writing the same integral giving me different results?
1 view (last 30 days)
Show older comments
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])
0 Comments
Answers (2)
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]
norm(x)
sqrt(sum(x .^ 2, 2))
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)
f2(1)
Fine. But:
f1([1, 2])
f2([1, 2])
% 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])
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.
0 Comments
See Also
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!