# Create a function handle that is a sum of function handles

6 ビュー (過去 30 日間)
Riccardo Mari 2023 年 1 月 13 日
コメント済み: Bjorn Gustavsson 2023 年 1 月 14 日
Goodmorning everyone,
I have the following points
POINTS=[0.0194358127458200 0.0125146090698240 0.0120324235527160 0.00761174198214000 0.00660775699279100 0.00381485098617300 0.00195617023840500 0.000824508358196000 0.00121681256884900 0.000390389885216000 0.000444315057222000 0;
0 0.000452782917043000 0.000395689955442000 0.00121172812659200 0.000829869449880000 0.00195546440425700 0.00381482017361200 0.00661064156533300 0.00762496776011900 0.0120411026638820 0.0125098828784870 0.0189137987850580];
I need to create a function handle as follows.
I know that the center of the circumference that approximates better those points is function of R, and is found in the point [R,R]. The approximation error is then:
error=@(R) abs(norm([R-POINTS(1,i),R-POINTS(2,i)])-R));
This for every point.
I want to create the function handle that is the sum of all the errors like:
1) totdist=@(R) error1+error2+error3+...
I can create a single function function manually by summing every error like:
2) totdist=@(R) abs(norm([R-POINTS(1,1),R-POINTS(2,1)])-R))+abs(norm([R-POINTS(1,2),R-POINTS(2,2)])-R))+abs(norm([R-POINTS(1,3),R-POINTS(2,3)])-R))+...
However when the number of points become large, I would like to create the summing function 1) authomatically without manually summing 100 times as in 2).
The function must be used with "fminsearch" afterwards.
Is there a way to achieve this?
##### 1 件のコメント表示非表示 なし
Bjorn Gustavsson 2023 年 1 月 14 日
@Riccardo Mari: at least try to work through the suggestions to see what they do. Use simple test-cases.

サインインしてコメントする。

### 回答 (3 件)

Bjorn Gustavsson 2023 年 1 月 13 日
Your specification is a bit ambiguous to me, but if I interpret it such that you want to fit a function such that: (I've used the additional condition that and , but this one can be easily relaxed). You can make a general solution something like this:
f_x = @(R,theta,f_theta) R + f_theta(R,theta).*cos(theta);
f_y = @(R,theta,f_theta) R + f_theta(R,theta).*sin(theta);
err_fcn = @(R,X,Y,f_theta) sum( (X-f_x(R,atan2(Y-R,X-R),f_theta)).^2 + (Y-f_y(R,atan2(Y-R,X-R),f_theta)).^2);
f_theta = @(R,theta) R*ones(size(theta));
Rest = fminsearch(@(R) err_fcn(R,POINTS(1,:)',POINTS(2,:)',f_theta),20e-3);
This is a rather cumbersome way to make a simple circle-fitting-function, you will find multiple circle-fitting-functions on the file exchange: circle-fitting FEx contributions. If your circumference is a bit more complicated, even more complicated than an ellipse even, then you simply have to modify the f_theta function-handle accordingly. If the centre of the circumference is not exactly the same as the radius for example then you'll have to modify the above snippet a bit:
f_x = @(R,theta,f_theta) R(1) + f_theta(R(3),theta).*cos(theta);
f_y = @(R,theta,f_theta) R(2) + f_theta(R(3),theta).*sin(theta);
err_fcn = @(R,X,Y,f_theta) sum( (X-f_x(R,atan2(Y-R(2),X-R(1)),f_theta)).^2 + (Y-f_y(R,atan2(Y-R(2),X-R(1)),f_theta)).^2);
f_theta = @(R,theta) R*ones(size(theta));
Rest3 = fminsearch(@(R) err_fcn(R,POINTS(1,:)',POINTS(2,:)',f_theta),20e-3*[1 1 1]);
You can also allow for additional parameters to fit to, for example major and minor radius and angle of semi-major axis of an ellipse. But, this starts to become rather cluttered code for anonymous function-handles at this stage and somewhere here I tend to transition to proper matlab-functions in files, just to keep the code cleaner.
HTH
##### 2 件のコメント表示非表示 1 件の古いコメント
Bjorn Gustavsson 2023 年 1 月 13 日

That's what my first example does. For general circle-fitting functions follow the link to the good file-exchange contributions that solve that problem for the more general case.
HTH

サインインしてコメントする。

Matt J 2023 年 1 月 13 日
error=@(R) abs( vecnorm(POINTS-R) - R );
##### 1 件のコメント表示非表示 なし
Matt J 2023 年 1 月 13 日

I have to measure the error in the distance as error=@(R) abs(norm([R-POINTS(1,i),R-POINTS(2,i)])-R)) .... So I have to apply this to every point in the list.
No, you do not have to implement a separate error function for every Point(:,i). There are vectorized functions which calculate all errors at once, which is what my answer has given you.
I want to find the radius that minimizes the total error.
If you know the center [x0,y0] of the circle already, the minimizing R is just the average of the empricial distances. There is no need for fminsearch.
R = mean(vecnorm(POINTS-[x0;y0]))

サインインしてコメントする。

Riccardo Mari 2023 年 1 月 13 日
I'm sorry if I couldn't be clearer because I can't share too much abount the code and the project.
I used the solution proprosed here. To summarize, I did this:
N=length(POINTS);
f=cell(N,1);
for i=1:N
f{i}=@(R) abs(norm([R-POINTS(1,i),R-POINTS(2,i)])-R);
end
totdist=@(R) summer(f,R);
with:
function y=summer(f,R)
y=0;
for i=1:numel(f)
y=y+f{i}(R);
end
end
##### 1 件のコメント表示非表示 なし
Matt J 2023 年 1 月 13 日

It's a bad solution. Very slow and inefficient. I urge you to reconsider the other proposals.
POINTS=rand(2,100000); R=0;
tic;
N=length(POINTS);
f=cell(N,1);
for i=1:N
f{i}=@(R) abs(norm([R-POINTS(1,i),R-POINTS(2,i)])-R);
end
totdist=@(R) summer(f,R);
version1=totdist(R); %calculation
toc;
Elapsed time is 0.279596 seconds.
tic
errorFcn=@(R) norm( vecnorm(POINTS-R) - R ,1);
version2=errorFcn(R);%calculation
toc
Elapsed time is 0.006358 seconds.
version1,version2 %same result
version1 = 7.6622e+04
version2 = 7.6622e+04

サインインしてコメントする。

### カテゴリ

Find more on Array and Matrix Mathematics in Help Center and File Exchange

R2022a

### Community Treasure Hunt

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

Start Hunting!