interp2 with for loop - matlab

%I_Phase [0 51.1111 102.2222 153.3333 204.4444 255.5556 306.6667 357.7778 408.8889 460]
%Theta [-45 -30 -15 0 15 30 45 60 75 90]
%Torque_Matrix [0 0 0 0 0 0 0 0 0 0
28.6989 35.9452 41.1581 43.8173 43.5092 40.0174 33.4011 24.0388 12.6221 0.0940
52.6956 67.7241 79.8022 87.4465 89.2066 84.0131 71.5044 52.2439 27.7582 0.3762
71.9900 95.3367 115.9323 130.8876 137.0923 131.9869 114.3100 84.6153 45.4083 0.8464
86.5822 118.7830 149.5483 174.1406 187.1661 183.9389 161.8178 121.1530 65.5724 1.5047
96.4722 138.0630 180.6504 217.2055 239.4282 239.8691 214.0278 161.8569 88.2505 2.3511
101.6600 153.1768 209.2385 260.0824 293.8785 299.7776 270.9400 206.7272 113.4425 3.3856
102.1456 164.1242 235.3126 302.7711 350.5170 363.6642 332.5544 255.7637 141.1486 4.6082
97.9289 170.9054 258.8727 345.2718 409.3438 431.5290 398.8711 308.9666 171.3687 6.0188
89.0100 173.5203 279.9188 387.5844 470.3588 503.3720 469.8900 366.3357 204.1028 7.6176]
I have two vectors (I_Phase1, Theta1) and one matrix (Torque_Matrix), I need to do a interpolation with interp2, but my fuction and loop when running interp2, Theta_Int and I_Phase_Int values ​​are only 90 and 460 respectively, so I only have a value for Torque_Value and I need values ​​at -45: 90 and 0: 460, I need to create a new array with Torque_Values ​​values. I need help, please.
surf(Theta1,I_Phase1,Torque_Matrix);
hold on
Matrix_int = zeros(100);
index_Theta = 0;
index_I = 0;
for Theta_Int = -45:90;
for I_Phase_Int = 0:460;
Torque_Value = interp2(Theta1,I_Phase1,Torque_Matrix,Theta_Int,I_Phase_Int);
end
end
surf(Theta_Int,I_Phase_Int,Torque_Value,'.r');

You can use the interp2 function with vectors, but if it helps for a beginner as yourself to see what is going on in each step, for loops will still work. You just need to create vectors for Theta_Int and I_Phase_Int. Then when you call interp2, you index Theta_Int(j) and I_Phase_Int(k), as well as store the values in Torque_Value(k,j). I swapped the for loops around so when you do the surf it will plot along the same axis as above.
Theta_Int = -45:90;
I_Phase_Int = 0:460;
for k = 1:length(I_Phase_Int)
for j = 1:length(Theta_Int)
Torque_Value(k, j) = interp2(Theta,I_Phase,Torque_Matrix,Theta_Int(j),I_Phase_Int(k));
end
end
figure();
surf(Theta_Int, I_Phase_Int, Torque_Value);
Also created a new figure so both of your plots will be shown. So just replace your for loop down with this code and it should work.

Related

Matlab Xcorr function returns NaNs for a large block of the return array

I have some synthetic signal data to cross correlate before moving on with real data but the xcorr function is returning an odd result.
I have added a delay onto either the start (delay =100) or end of the respective data sets which are the same size (2101 x 1 double) and put them through xcorr which has returned an array (4201 x 1 double).
The result has NaNs between rows 101 and 2205 and then a ring down effect after that start at an order of x10^5. I have now attached pictures of the result
Can anyone please offer some suggestions on how to correct what I am attempting to do? I am expecting to be able to plot the result and see a spike at the delay that I have set.
Thanks
EDIT:
Short example code
X = [-4.99 -0.298 4.95 12.06 15.76 18.86 19.00 17.82 14.35 11.77 6.71 0.80 -5.07 -11.79 -15.34 -18.60 -18.56 -19.31 -14.37 -11.51 -5.04];
Y = [14.13 18.48 7.53 -3.41 -8.41 -13.40 -15.37 -17.34 -16.83 -16.33 -12.21 -8.09 -8.80 -9.52 3.90 17.31 17.52 17.72 17.73 17.75 16.90];
N = length(X);
delay = 2;
% set up two new arrays which will have random noise at ends
Xx = zeros(N+delay,1);
Yx = zeros(N+delay,1);
for i=1:N+delay
if i<=delay
Xx(i) = rand;
elseif i>delay
Xx(i) = X(i-delay);
end
end
for i=1:N+delay
if i<=N
Yx(i) = Y(i);
elseif i>N
Yx(i) = rand;
end
end
C = xcorr(Xx,Yx);

Matlab finding if graphic object exist on figure on given coordinates

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.

fminsearch (matlab) taking too much time

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.

Vectorize the generation of a 3D matrix made within a loop up to now

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.

Storing Iteration Results in Matlab

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