I need to find a way to check if a patch object I created (a rectangle for example) exists within certain X-Y coordinates I specify. As an example, I am using the following code:
a = figure
b = axes('Parent',a,'Xlim',[0 100],'Ylim',[0 100])
x = [0 10 10 0];
y = [0 0 10 10];
patch(x,y,'red')
Now I would like to know if there is an object in the figure in the point with coordinates x=6 and y=3. Is there a way to check this?
Use the findall () and inpolygon function.
hPatches = findall(b, 'type', 'patch');
tgtX = 5; tgtY = 7;
inside = zeros (1, numel(hPatches));
for patchCtr = 1:numel(hPatches)
vert = get (hPatches(patchCtr), 'Vertices');
inside(patchCtr) = inpolygon (tgtX, tgtY, vert(:,1), vert(:,2));
end
You can use findobj to find the objects of interest, in this case patch objects, and access their 'XData' property, then check if it falls within some range. You can do the same with the YData property as well.
Here is an example:
clc
clear
close all
a=figure;
b=axes('Parent',a,'Xlim',[0 30],'Ylim',[0 30]);
x1 = [0 10 10 0];
y1 = [0 0 10 10];
x2 = [15 25 25 15];
y2= [10 10 20 20];
patch(x1,y1,'red')
patch(x2,y2,'blue')
hPatches = findall(a,'Type','patch') %// find patch objects
InfoPatches = get(hPatches); %// Get info about the objects. Check for the XData property.
XDataArray = zeros(4,numel(InfoPatches));
for k = 1:numel(InfoPatches)
XDataArray(:,k) = InfoPatches(k).XData; %// Access the XData property, or any you want.
end
XDataArray
Figure:
And XDataArray look like this:
XDataArray =
15 0
25 10
25 10
15 0
Now there would be the part in which you check whether an object is at some position but that's quite easy to implement. Hope that helps!
I don't know if you are familiar with toolboxes, but the mpt-toolbox could come in handy here (from my Uni).
After you have installed it, you could define the rectangle as a polytope and simply check if a point is within the rectangle.
For your code example above:
Vertices = [0,0;10,0;10,10;0,10];
Rectangle = Polyhedron(Vertices);
TestPoint = [6;3];
Within = Rectangle.contains(Testpoint);
Were Within is a boolean variable (1 if point within Rectangle, 0 otherwise)
EDIT
Of course, the toolbox also works for intersections between your original Rectangle polygon and say another polygon Intersect.
function A=obj(b,Y, YL, tempcyc, cyc, Yzero, age, agesq, educ, ageav, agesqav, educav, qv, year1, year2, year3, year4, year5, year6, year7, workregion1, workregion2, workregion3, workregion4, workregion5, workregion6, workregion7, workregion8, workregion9, workregion10, workregion11, workregion12, workregion13, workregion14, workregion15, workregion16, qw)
A=0;
for i=1:715
S=0;
for m=1:12
P=1;
for t=1:8
P=P*(normcdf((2*Y(i,t)-1)*(b(1)*YL(i,t)+b(2)*tempcyc(i,t)+b(3)*cyc(i,t)+b(4)*Yzero(i,t)+b(5)*age(i,t)+b(6)*agesq(i,t)+b(7)*educ(i,t)+b(8)*ageav(i,t)+b(9)*agesqav(i,t)+b(10)*educav(i,t)+b(11)*1+b(12)*sqrt(2)*qv(m,1)+b(13)*year1(i,t)+b(14)*year2(i,t)+b(15)*year3(i,t)+b(16)*year4(i,t)+b(17)*year5(i,t)+b(18)*year6(i,t)+b(19)*year7(i,t)+b(20)*workregion1(i,t)+b(21)*workregion2(i,t)+b(22)*workregion3(i,t)+b(23)*workregion4(i,t)+b(24)*workregion5(i,t)+b(25)*workregion6(i,t)+b(26)*workregion7(i,t)+b(27)*workregion8(i,t)+b(28)*workregion9(i,t)+b(29)*workregion10(i,t)+b(30)*workregion11(i,t)+b(31)*workregion12(i,t)+b(32)*workregion13(i,t)+b(33)*workregion14(i,t)+b(34)*workregion15(i,t)+b(35)*workregion16(i,t))));
end
S=S+qw(m,1)*P;
end
A=A+log(S/sqrt(pi));
A=-A;
end
This is my objective function I am minimizing (actually maximizing; I am minimizing -A) and the parameters I am estimating is b=[b(1)............b(35)]. Y, YL, tempcyc,.........., qw are matrices that I am imported as data. The objective function consists of a product(across t=1:8) nested within a sum (across m=1:12) that is in turn nested within a sum (across n=1:715). And below is my code using fminsearch for my unconstrained minimization.
% %% Minimization
start=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0];
iter=50000;
options=optimset('Display','iter','MaxIter',iter,'MaxFunEvals',100000);
[b, fval, exitflag, output]=fminsearch(#(b)obj(b,Y, YL, tempcyc, cyc, Yzero, age, agesq, educ, ageav, agesqav, educav, qv, year1, year2, year3, year4, year5, year6, year7, workregion1, workregion2, workregion3, workregion4, workregion5, workregion6, workregion7, workregion8, workregion9, workregion10, workregion11, workregion12, workregion13, workregion14, workregion15, workregion16, qw), start, options);%
%% Results
fprintf('[b] : % 1.4e % 1.4e %1.4e % 1.4e % 1.4e % 1.4e \n',...b(1),b(2),b(3),b(4), b(5),b(6),b(7),b(8), b(9),b(10),b(11),b(12), b(13),b(14),b(15),b(16), b(17),b(18),b(19),b(20), b(21),b(22),b(23),b(24), b(25),b(26),b(27),b(28), b(29),b(30),b(31),b(32), b(33),b(34), b(35));
end
The problem is that the optmization results do not show up even after 12+ hours (It is still reflecting, expanding, contracting inside, etc.) Could someone give me an idea on how to make the process faster?
Thank you.
This is not a complete answer to your question; this is a suggestion on how to better write your code, which is probably half the answer.
I would write your calling script something like this:
%% Minimization
b0 = zeros(1,35);
iter = 5e4;
options=optimset(...
'Display' , 'iter',...
'MaxIter' , iter,...
'MaxFunEvals', 1e5);
data = {...
YL, tempcyc, cyc, Yzero, age, agesq, educ, ageav, agesqav, educav, qv, ...
year1, year2, year3, year4, year5, year6, year7, ...
workregion1, workregion2, workregion3, workregion4, workregion5, ...
workregion6, workregion7, workregion8, workregion9, workregion10, ...
workregion11, workregion12, workregion13, workregion14, workregion15, ...
workregion16
};
[b, fval, exitflag, output] = fminsearch(#(b)obj(b, Y,data,qw), b0, options);
%% Print results
fprintf('[b]:');
fprintf('%1.4e', b);
fprintf('\n');
(actually, I would also wrap the data in cells instead of having 16 workregions and 7 years etc. But you may not be the creator of the data, so this may not always be possible)
You could re-write your objective function something like this:
function A = obj(b, Y, others, qw)
A = 0;
sPi = -0.5*log(pi);
bB = num2cell(b);
for ii = 1:715
P = prod( normcdf((2*Y(ii,1:8)-1) .* cellfun(#(x,y) x(ii,1:8).*y, others, bB)) );
S = sum( P*qw(1:12,1) );
A = A + log(S) + sPi;
end
A = -A;
end
Probably also the outer loop can be simplified into vectorized form. But I cannot test the correctness of all this (or whether it runs at all), because I don't have access to your data. But I trust you get the idea -- you can now at least read your code, and probably spot the error yourself.
Up to now, I used 3 loops to build a matrix, but it takes such a long time that I would like to vectorize it. But either it's not possible, or I took the wrong way to do it. Anyway, I am in front of a wall, and I need your help.
Here are the loops :
AngleList = [0 : 10 : 300]; % 31 elements
Fx_mat is a (1000,120,31) matrix, 31 is for the 31 elements corresponding to AngleList.
for Aaa = 1:Nb_loop1 % Nb_loop1 = 3
for Bbb = 1:Nb_loop2 % Nb_loop2 = 120
for Ccc = 1:Nb_loop3 % Nb_loop3 = 1000
Angle = rand()*300; % Then Angle is between 0 and 300
Fx_mat_interp(Aaa,Bbb,Ccc) = interp1(AngleList, Fx_mat(Ccc,Bbb,:), Angle);
end
end
end
What I first tried to do is to create matrix with my datas :
m_Angle = rand(Nb_loop3,Nb_loop2)*300 % 1000x120 matrix
m_AngleList = permute(reshape(repmat(AngleList,Nb_loop3,Nb_loop2),Nb_loop1,Nb_loop3,Nb_loop2),[1 3 2]);
% I repeat my AngleList vector in a 1000x120x31 matrix
for Aaa = 1:Nb_loop1
Fx_mat_interp(Aaa,:,:) = ?????(m_AngleList, Fx_mat(Nb_loop3,Nb_loop2,:), m_Angle);
end
I would like to replace ????? with the equivalent to interp1, but I can't find it.
Do you have any idea to help me please ?
P.S: And a lot of great thinks for all of you for this new year.
I have the code below.
for k=40:10:80
T(k)=273.15+k;
z=[0.2 0.2 0.2 0.4];
W_PR=0.245;
C=4;
omega=[0.344 0.467 0.578 0.789];
Tc=[600 700 500 570];
Pc=[50 70 58 76];
for c=1:C
x_PR(1,c)=z(c)/(1+W_PR*(K_PR(c)-1));
x_PR(2,c)=K_PR(c)*x_PR(1,c);
end
for c=1:C
kappa_PR=0.37464+1.54226.*omega(c)-0.26992.*omega(c).^2;
alpha_PR=(1+kappa_PR.*(1-sqrt(T(k)./Tc(c)))).^2;
a_PR(c,c)=0.45724.*R.^2.*Tc(c).^2./Pc(c).*alpha_PR;
b_PR(c)=0.07780*R.*Tc(c)./Pc(c);
end
for c=2:C
for n=1:(c-1)
a_PR(c,n)=sqrt(a_PR(c,c).*a_PR(n,n));
a_PR(n,c)=a_PR(c,n);
end
end
for c=1:C
A_PR(c,c)=a_PR(c,c).*P./(R.*T(k)).^2;
B_PR(c)=b_PR(c).*P./(R.*T(k));
end
for c=1:C
Z(c,c)=A_PR(c,c)./5;
V(c)=B_PR(c).*6;
end
end
Each time I run the code, I want result for Z and V at each T(k).
The code as it is only gives result for one T value though I want it to run the loop and give result for Z and V for all T(k).
You might want to define some of your parameters outside of your main loop to, at the very least, preallocate storage.
Z_store = ones(C,C,5); % if you want to use a 3d matrix
and
V_store = ones(5,C);
The new function:
function [Z_store V_store] = SO_test1()
z=[0.2 0.2 0.2 0.4];
W_PR=0.245;
C=4;
omega=[0.344 0.467 0.578 0.789];
Tc=[600 700 500 570];
Pc=[50 70 58 76];
R=8.314;
P=20;
Z_store = ones(C,C,5);
V_store = ones(5,C);
K_PR=[1.546e-2, 0.456, 1.432e2, 14.32];
iter = 0;
for k=40:10:80
T(k)=273.15+k;
for c=1:C
x_PR(1,c)=z(c)/(1+W_PR*(K_PR(c)-1));
x_PR(2,c)=K_PR(c)*x_PR(1,c);
kappa_PR=0.37464+1.54226.*omega(c)-0.26992.*omega(c).^2;
alpha_PR=(1+kappa_PR.*(1-sqrt(T(k)./Tc(c)))).^2;
a_PR(c,c)=0.45724.*R.^2.*Tc(c).^2./Pc(c).*alpha_PR;
b_PR(c)=0.07780*R.*Tc(c)./Pc(c);
end
for c=2:C
for n=1:(c-1)
a_PR(c,n)=sqrt(a_PR(c,c).*a_PR(n,n));
a_PR(n,c)=a_PR(c,n);
end
end
for c=1:C
A_PR(c,c)=a_PR(c,c).*P./(R.*T(k)).^2;
B_PR(c)=b_PR(c).*P./(R.*T(k));
Z(c,c)=A_PR(c,c)./5;
V(c)=B_PR(c).*6;
end
iter = iter + 1;
Z_store(:,:,iter) = Z;
V_store(iter,:) = V;
end
end
Your result matrices V and Z need to have higher dimension. From your code you only assign values to Z in the form
Z(c,c) = value
and V in the form
V(c) = value
thus it appears that your Z is simply a 2d matrix who only ever has diagonal entries defined and V is just a simple vector. Your iteration runs over all values of your loop variable k but each time you are overwriting the current values within these arrays. Consider making V a 2D array and Z a 3D array so that they have the capacity to store the results at a separate index for each value of the iteration variable k