Simplex optimisation using fminsearch

28 views (last 30 days)
Ebube Ezi
Ebube Ezi on 23 Aug 2018
Edited: Bruno Luong on 23 Mar 2023
Please how can i use the simplex optimisation syntax called 'fminsearch' to optimise a circle fitted to a set of random points? I've tried using the equation of a circle as the function for the syntax but am not making any head way. I presume am not getting the function right.
  7 Comments
John D'Errico
John D'Errico on 22 Mar 2023
Why do you need to use fminsearch? This is a problem simply solved without recourse to fminsearch.

Sign in to comment.

Answers (2)

Walter Roberson
Walter Roberson on 24 Aug 2018
x = vector_of_x_coordinates;
y = vector_of_y_coordinates;
obj = @(xyr) sum( (x-xyr(1)).^2 + (y-xyr(2)).^2 - xyr(3).^2 );
xyr0 = [guess_x, guess_y, guess_r];
[XYR, residue] = fminsearch(obj, xyr0);
  8 Comments
Biraj Khanal
Biraj Khanal on 22 Mar 2023
Edited: Biraj Khanal on 22 Mar 2023
Shouldn't that be resolved when the absolute value of the sum is used?
Biraj Khanal
Biraj Khanal on 23 Mar 2023
So, this is my adaptation of a tutorial I found. The idea is to minimize the error as distance between the coordinates of guessed circle and the actual data points.
obj = @(hkr) sumerror(hkr,x,y);
[sol ,residue] = fminsearch(obj,[Guess_h, Guess_k, Guess_r]);
function E = sumerror(hkr,x,y)
t=linspace(0,2*pi,length(x));
xx=hkr(1) + hkr(3)*cos(t); % create x and y for the guess iteration
yy=hkr(2) + hkr(3)*sin(t);
Ex=sum((xx-x).^2);
Ey=sum((yy-y).^2);
E=(Ex+Ey)/2; %average of the eror in x and y coordinates
end
It seems to work for me. If anyone gets a simpler idea to do this, it would be great.

Sign in to comment.


John D'Errico
John D'Errico on 23 Mar 2023
Edited: John D'Errico on 23 Mar 2023
You are still looking for help on this?
There is ABSOLUTELY no need to use a simplex optimizer for this problem. NONE AT ALL. Let me make up some data.
n = 50;
XY = normalize(randn(n,2),2,'norm') + 2 + randn(n,2)/5;
plot(XY(:,1),XY(:,2),'.')
axis equal
The data is a circle, with center at [2,2], and a radius of 1.
[C,R,rmse] = circlefit(XY)
C = 1×2
2.0039 2.0386
R = 1.0565
rmse = 0.2043
theta = linspace(0,2*pi)';
XYhat = C + R*[cos(theta),sin(theta)];
hold on
plot(XYhat(:,1),XYhat(:,2),'r-')
plot(C(1),C(2),'gx')
hold off
So a circle at center pretty near the point [2,2], with radius estimated as also very close to 1.
Even if you have only half an arc of a circle, it still works.
k = XY(:,1) > 2;
plot(XY(k,1),XY(k,2),'.')
axis equal
[C,R,rmse] = circlefit(XY(k,:))
C = 1×2
2.1750 2.0898
R = 0.9377
rmse = 0.2168
theta = linspace(-pi/2,pi/2)';
XYhat = C + R*[cos(theta),sin(theta)];
hold on
plot(XYhat(:,1),XYhat(:,2),'r-')
plot(C(1),C(2),'gx')
hold off
As expected, the estimates are less good there, but that data is seriously noisy. Honestly, if someone gave me this data and asked to fit a circle to it, I would have guessed the data is almost useless to fit a circle.
I've attached circlefit to this answer. (circlefit also works on higher dimensional data, where it can fit a sphere to data in 3-d, etc.)
Circlefit uses an algebraic trick to remove the quadratic terms in the circle equations. This reduces the problem to finding the best intersection of many straight lines. But that is a problem easily solved using linear algebra. It can also use robustfit from the stats toolbox, if you have it.
Don't write your own code to solve problems like this.

Community Treasure Hunt

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

Start Hunting!