optimising variables that are dependent on other variables

I am trying to find best coordinates and angle of inclination of line that would give me the least sum of distance between stationary curve and a line.
The curve position remains fixed but the coordinates of line can change and lines inclination can change giving me the best position of line that will give me the least sum of distance (objective function)
Can anyone suggest or hint how to use inbuilt optimization function provided in matlab to approach this problem. This is a multi variable optimization problem where we need to find best value of x,y, theta.
Diagram and constraints are given below to understand problem. The concept will help me in my research work. I have written the code as well to provide initial position of line and curve and inclination of line but I donot understand how to use inbuilt function here directly since variables of objective funtion are dependent on other variables.
Example that shows initial position and next iteration
Constraints and problem defination
code for position staionary curve and initial position of line
clc,clear
r = 40; % arc length
R = 55; % radius of a circle
aa = 60*pi/180; % arc angle
ap = 0*pi/180; % arc position angle
t1 = linspace(0,aa)-aa/2+ap;
[x1,y1] = pol2cart(t1,r); % arc data
xcen=60;
ycen=10;
%Shifting arc lower end to (60,10) (stationary arc)
delx=xcen-x1(1);
dely=ycen-y1(1);
x1=x1+delx;
y1=y1+dely;
% defining the line with one end at (14,15)
L = linspace(0,10); % line segment lenth max is 5 and min is 0
theta = 60*pi/180; % initial angle of inclination
% starting point at (14,15)
x0=14;
y0=15;
x=x0+ L* cos(theta);
y=y0+L * sin(theta);
% for highlighting point at distance of L/4 from both ends
ind= [25 75];
x1_h=x(ind);
y1_h=y(ind);
plot (x1,y1)
hold on
plot(x,y)

 Réponse acceptée

Jon
Jon le 19 Nov 2020
If you have the optimization toolbox then you can use fmincon to solve this type of problem. https://www.mathworks.com/help/optim/ug/fmincon.html
You will need to write a function, in your case may not be simple, that in the end will give you values of your objective function Z as a function of xa, ya, and theta.

13 commentaires

I am actually not understanding how to use the fmincon in this case.
Each time line moves point 1 and point 2 change and then based on that point 3 and point 4 change as well.
I just need a hint how to approach this problem with fmincon.
So within your overall function that computes the objective function z as a function of xa, ya, and theta you should further break it down so for example:
find xa1 and ya1 and xa2 ya2 (points 1 and 2) as a function of xa,ya and theta.
find intersection of line with curve to get points xb1,yb1, xb2,yb2 (points 3 and 4)
compute Z as function of xa1,ya1,xa2,ya2,xb1,yb1,xb2,yb2
You will also have to write function nonlcon that expresses your constraints on the endpoints of the line to make sure it stays in the box. For this you would probably need to break it down into
find endpoints, lets call them xe1,ye1, xe2,ye2, of line as function of xa, ya, theta, and known length of line (I guess one end point is xe1 = xa, ye1 = ya so you know that right away)
express constraints on endpoints as for example
xe1 >= 0
xe1 =< 40
ye1 >= 0
ye1 =<a
etc
Note that since nonlcon specifies c(x) < = 0, you will have to rewrite the ones with >= a
so instead
-xe1 <= 0
-ye1 <=0
Ron Herman
Ron Herman le 21 Nov 2020
Modifié(e) : Ron Herman le 22 Nov 2020
Can you please check if this will do???
I am thinking of using x = fmincon(objfun , x0, A, b, Aeq, Beq, lb, ub)
I wrote the objective function as you instructed will this do??
Still bit confused with nonlcon because my constraints are linear in nature & instead of noncoln I used lb,ub
Kindly let me know if this approach is correct. I did as instructed
x0= [14;15;60] % bit doubtful on syntax regarding semi colon
A=[];
b=[];
Aeq=[];
Beq= [];
lb=[10,10,0];
ub=[40,40,2*pi];
[optival,fval] = fmincon(@objfun,x0,A,b,Aeq,Beq,lb,ub)
function [f]= objfun(xa,ya,theta) % Can we pass parameters seperately or all inside one array??
L = linspace(0,10); % line segment lenth max is 10 and min is 0
angle = theta*pi/180; % initial angle of inclination
% starting point at (xa,ya)
x=xa+ L* cos(angle);
y=ya+L * sin(angle);
% for highlighting point at distance of L/4 from both ends (point 1 and point 2)
ind= [25 75];
x_L=x(ind);
y_L=y(ind);
% Finding point 3 & point 4
% For finding point 3 & 4 I create another function called intersectfun
% which uses polyxpoly to find point 3 & 4
[x_34,y_34] = intersectfun (x_L,y_L)
D = hypot(x_L - x_34,y_L - y_34);
f= Sum(D)
end
Hi Ron,
I took a quick look at your code, I think you are on the right track. One question though before I can give you more detailed feedback.
What is the numerical value of L, the line segment length? I'm confused why you have it vary from 1 to 10 inside of your function.
I assume also that the entire, length L, line segment must remain inside of the bounding box. If so this is why I think you will have to provide a nonlinear constraint function. Note that you can constrain one end to be inside of the box, but depending upon the length L and angle theta the other end of the segment may be outside of the box.
Regarding passing additional parameters, there are a few ways to do it, please see https://www.mathworks.com/help/optim/ug/passing-extra-parameters.html, I found the nested function approach worked well for my typical applications.
Ron Herman
Ron Herman le 24 Nov 2020
Modifié(e) : Ron Herman le 24 Nov 2020
Regarding ( What is the numerical value of L, the line segment length? I'm confused why you have it vary from 1 to 10 inside of your function. )?? [I am answering it indirectly]
Concept used
1)Parametric form are used to define a geometry
2)Parametric form only gives a point
3)To form a geometry we need group of points (Here we use linspace to define group of points)
  • The orientation of group of points are decided by (dimesnion) or by (angle) as in circle
  • Ex for angle--> Circle where we use R cos(theta) and R sin(theta) & R is the dimension
For defining a quarter circle I use the following code below. The x and y store cordinates of the quarter circle and thus it can be plotted
R = 40; % circle radius
% coordinates of quarter circle
t = linspace(0,pi/2);
[x,y] = pol2cart(t,R); % circle data (circle in parametric form)
% x=R cos(t)
% y= R Sin(t)
Thus the quarter circle is formed by using parametric form (R cos (t) & R Sin(t)). In other words the quarter circle is represented by 100 points stored in x and y. In case of circle the radius remains constant and value of " t " varies between 0 to pi/2 in order to define a quarter circle.
I used the same analogy to define a line. In my case I needed to define a line segment of defined dimension in a given space. So I constructed a line segement by applying the above analogy for circle in following way where length was made to vary from 0 to 10
L = linspace(0,10); % line segment lenth max is 10 and min is 0
angle = theta*pi/180; % initial angle of inclination
% definining a line at angle of 60 degree from (0,0)
x=L* cos(angle);
y=L * sin(angle);
% parametric form of line has theta constant and varying L to define a line a line segement
% note i used the word line segment and not line
% shifiting the line segment to a new point (xa,ya)
x_p= xa + L* cos(angle); % This shifts all the x values by xa
y_p= ya + L * sin(angle); % This shifts all the yvalues by ya
%When we shift all the x of the points on line by xa & y of the points on line by ya
%The whole line shifts
The purpose of defining line in this manner was due to my requirement where I had to define two points at L/4 distance from both ends of he line.
Since x is an array that stores 100 values that define a line and same for y.
I use index of array ind= [25 75] to define point 1 & 2 as shown in figure by doing x(ind) & y(ind).
x(ind) & y (ind) hold information of point 1 & 2.
Kindly let me know if there is any other method or a better method for the approach. Since I am a beginner I maybe doing things in a ineffecient way.
In your code you determine the coordinates of 100 points along your line. Note that linspace by default makes a length 100 vector of points, so L = linspace(0,10) as you have in your code will have 100 elements, and so will x = L*cos(theta) and y = L*sin(theta). Unless at some point you need to use all of those 100 coordinate values I don't see any reason to calculate them in the first place. From your problem description it seems that you may only need to have coordinates for 4 points along the line (both ends, and then points 1 and 2).
I would suggest then to keep the nomeclature clearer I would keep the variable name L to be just a scalar value that specifies the length of your line, and then perhaps define a variable r to hold the radius corresponding to each of the 4 points so something like:
L = 10; % probably should put this up in top of your code somewhere with whatever other paramaters
% you want to define
angle = theta*pi/180; % angle in radians (theta is in degrees)
r = L*([0 1/4 3/4 1]) % define radius of endpoints and intermediate points 1 and 2
x = r*cos(theta)
y = r*sin(theta)
% now the coordinates of your 4 points are just x(1),x(2),x(3),x(4) and y(1),y(2),y(3),y(4)
% etc
Back then on looking at your code.
You must pass just one vector argument to objfun, something like:
function f = objfun(z)
% z = [xa,ya,theta]
% assign local variable name for readability
xa = z(1);
ya = z(2);
theta = z(3);
% etc
You will also need a nonlcon function to enforce constarints to ensure the endpoints of the line segment remain inside of the bounding box, so maybe something like
function [c,ceq] = confun(z)
% z = [xa,ya,theta]
% assign local variable name for readability
xa = z(1);
ya = z(2);
thetaDeg = z(3); % angle in degrees
% convert theta to radians
theta = deg2rad(thetaDeg);
% find end point of rotated line segment, whose length is L
xe = xa + L*cos(theta);
ye = ya + L*sin(theta);
% constraints c <= 0
% lb e.g. [0;0] ub e.g. [40 40] % lower and upper bounds on x an y
c(1) = lb(1) - xe;
c(2) = xe - ub(1);
c(3) = lb(2) - ye;
c(4) = ye - ub(2);
% constraints ceq = 0, you don't have any equality constraints, but
ceq = []; % I think you have to assign it, so just assign it an empty matrix
end
Note, there is a MATLAB function called angle, so it is better not to use that as a variable name.
Also, to pass L, lb, ub to confun and L and any other parameters to objfun you should define them as nested functions inside of a script or other function, where these values are defined. They will then be in scope (values will be known inside confun and objfun)
Ron Herman
Ron Herman le 29 Nov 2020
Modifié(e) : Ron Herman le 29 Nov 2020
Thanks Jon for your feed back . This really helped. I did learn something.
I'm glad. Thanks for letting me know. Good luck with your project.
Sorry for not clearing the doubts in one go. But I seem to be again stuck with a small doubt.
Also, to pass L, lb, ub to confun and L and any other parameters to objfun you should define them as nested functions inside of a script or other function, where these values are defined. They will then be in scope (values will be known inside confun and objfun)
You mean if this L , Lb, Ub is defined inside objfun() then the values will also be reflected inside confun() ?????? I actually didnot get your above satement.
I am not clear how to pass L,Ub, Lb into confun()??
Hi, I have attached a simple, self contained, example to show how you would pass parameters to a non-linear constrained optimization problem using nested functions. Hopefully you can adapt this technique to the specifics of your problem.
I have attached two files:
minsolve.m is a function which takes as arguments the additional parameter, and which calls fmincon. It has two nested functions within it to define the objective and constraint functions.
runmin.m is a script which you run from the command line to actually run the optimization. It calls minsolve. You can edit it to change the parameter values
Thank you Jon I am clear now. Thanks for the help.
Ron Herman
Ron Herman le 22 Déc 2020
Modifié(e) : Ron Herman le 22 Déc 2020
There is another thing that was on my mind. In the current question both end points of line should lie inside the region. Here xe and ye also need to line inside the prescribed range so we used confun() function.
Before we start optimization we always give an initial value . Suppose here we give initial value to xa, ya, theta in such a way that the line (xa,ya) cordinates are inside the desired region but point (xe,ye) mentioned inside confun() are outside the region. In this situation will optimization work?????
If I rephrase the question the parameters for optimization that I use are xa,ya,theta are all within the range during the 1st initialisation or x0 , but a part of line is outside the range and thus xe,ye lie outside. This xe,ye are used in confun().
So in short do I need to set initial condition in such a way that all constrains are satisifed from start???
For example given below
The red curve is set in intial postion (xo,yo) and a particular theta that makes arc in that postion as seen in left image and we want whole arc to follow constraint of Y lb < Y < Y ub & X lb < X < X ub. (Here havent shown X constraint as it is assumed xo, x1,x2 all lie within X lb & X ub)
Here it can be seen (xo,yo) satisfy constraint but point 1 and point 2 dont satisfy at initial position.
% Constraint for end points which we write inside confun()
% For point 1
c(1) = lb(1) - x1;
c(2) = x1 - ub(1);
c(3) = lb(2) - y1;
c(4) = y1 - ub(2);
% for point 2
c(5) = lb(1) - x2;
c(6) = x2 - ub(1);
c(7) = lb(2) - y2;
c(8) = y2 - ub(2);
But when we define (xo, yo) and theta for the red arc point 1 and point 2 lie outside UB and LB . In this case will optimization work and make the arc aquire desired positon as shown in right side of image on its own.

Connectez-vous pour commenter.

Plus de réponses (0)

Community Treasure Hunt

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

Start Hunting!

Translated by