Using integral2 where fun is a function with vector norms and summations: getting "Matrix dimensions must agree" error.

3 views (last 30 days)
I am trying to double integrate the following function:
,
where , , , , and denotes the Euclidian norm.
More explicity, I want to numerically compute:
.
In MATLAB, I have the following function to describe the above:
function r = smoothFurthest(C,x,p)
g = zeros(length(C));
for i=1:length(C)
g(i) = sqrt(norm(x-C(i,:))^2+p^2);
end
e = exp(g/p);
r = p*log(sum(e));
r = r(1); % I am not sure why, but the ourput is a vector if I don't do this (the first value is correct though)???
end
where C is given as a n x 2 matrix.
Next, to integrate I wrote the following in my main script:
C = [1,2;
2,3;
1,4;
5,0;
0,0;
1,-1;
-2,3;
-4,3];
p = 0.01;
fun = @(x1,x2) smoothFurthest(C,[x1,x2],p);
integral2(fun,-10,10,-10,10,'Method','iterated','AbsTol',0,'RelTol',1e-10)
However, when I run this, I get the following output:
Group with properties:
Children: [2×1 Line]
Visible: on
HitTest: on
Show all properties
Matrix dimensions must agree.
Error in smoothFurthest (line 6)
g(i) = sqrt(norm(x-C(i,:))^2+p^2);
Error in test>@(x1,x2)smoothFurthest(C,[x1,x2],p) (line 29)
fun = @(x1,x2) smoothFurthest(C,[x1,x2],p);
Error in integral2Calc>@(y)fun(xi*ones(size(y)),y) (line 18)
@(y)fun(xi*ones(size(y)),y),y1i,y2i,opstruct.integralOptions), ...
Error in integralCalc/iterateScalarValued (line 314)
fx = FUN(t);
Error in integralCalc/vadapt (line 132)
[q,errbnd] = iterateScalarValued(u,tinterval,pathlen);
Error in integralCalc (line 75)
[q,errbnd] = vadapt(@AtoBInvTransform,interval);
Error in integral2Calc>@(xi,y1i,y2i)integralCalc(@(y)fun(xi*ones(size(y)),y),y1i,y2i,opstruct.integralOptions)
(line 17)
innerintegral = @(x)arrayfun(@(xi,y1i,y2i)integralCalc( ...
Error in
integral2Calc>@(x)arrayfun(@(xi,y1i,y2i)integralCalc(@(y)fun(xi*ones(size(y)),y),y1i,y2i,opstruct.integralOptions),x,ymin(x),ymax(x))
(line 17)
innerintegral = @(x)arrayfun(@(xi,y1i,y2i)integralCalc( ...
Error in integralCalc/iterateScalarValued (line 314)
fx = FUN(t);
Error in integralCalc/vadapt (line 132)
[q,errbnd] = iterateScalarValued(u,tinterval,pathlen);
Error in integralCalc (line 75)
[q,errbnd] = vadapt(@AtoBInvTransform,interval);
Error in integral2Calc>integral2i (line 20)
[q,errbnd] = integralCalc(innerintegral,xmin,xmax,opstruct.integralOptions);
Error in integral2Calc (line 7)
[q,errbnd] = integral2i(fun,xmin,xmax,ymin,ymax,optionstruct);
Error in integral2 (line 106)
Q = integral2Calc(fun,xmin,xmax,yminfun,ymaxfun,opstruct);
Error in test (line 30)
integral2(fun,-10,10,-10,10,'Method','iterated','AbsTol',0,'RelTol',1e-10)
Thank you for you time, and if I need to clearify anything let me know!

Answers (2)

jessupj
jessupj on 17 Feb 2022
you're calling your function with an argument [x1,x2] so 'x' is a vector.
inside your function, you have x-C(i,:))^2
I think you might need a .^2 to square that beast entry-wise
  2 Comments
jessupj
jessupj on 17 Feb 2022
Edited: jessupj on 17 Feb 2022
roger that. i somehow missed that.
1.) g= zeros(length(C)); is gonna be a square matrix, but you only fill up the first length(C) values of it. probably that should be zeros(size(C))
2.) From INSIDE the function called by integral2, I see that x appears to be a 1D set of point drawn from the interval (-10, 10).
That line is computing the norm of the difference between a 1x90 vector and a 1x2 vector. Part of the problem may be how you defined smoothFuthest, which depends on a single variable x but the integral2 function wants to pass two independent values to it.
I'd try making smoothfurthest take arguments C,x1,x2,p, and form x=[x1 (:) x2(:) ] from the arguments inside the function (and redefine 'fun' without the grouping around x1,x2).

Sign in to comment.


Walter Roberson
Walter Roberson on 17 Feb 2022
integral2 always passes in matrices for x and y and needs the results to be the same size.
You accept inputs that you expect to be scalar and compute values relative to a matrix, and use norm. But because the inputs are not the same size as you expect, you either produce an unexpected size of input to norm() or else you ask norm to deal with multidimensional data. norm() has no way of working with multidimensional data (at least not that would be useful here.) So norm() is collapsing your matrix to a single scalar instead of one per input x y.
You have two ways to proceed:
  • you can integral2 a function that accepts matrices and uses arrayfun to process one pair at a time through your function; or
  • you can rewrite your function to not call norm and instead use the Euclidean formula and pay attention to dimensions to get the right output size. This might involve reshaping c into the third or fourth dimension and sum() along the appropriate dimension.

Categories

Find more on Numerical Integration and Differential Equations in Help Center and File Exchange

Products


Release

R2020b

Community Treasure Hunt

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

Start Hunting!