Storing Iteration Results in Matlab - 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

Related

Creating a number of matrices/vectors based on a number

I have a simple for loop that is used to simulated data,
for t=2:T;
Y_star(t,1,b)=[Y_star(t-1,1,b) X_1_star(t-1,1,b) X_2_star(t-1,1,b) 1]*beta(:,i)+w(t-1)*e(t-1,i);
X_1_star(t,1,b)=Theta(1,1)+Phi(1,:,1)*[X_1_star(t-1,1,b) ; X_2_star(t-1,1,b)]+w(t-1)*v(t-1,1,i);
X_2_star(t,1,b)=Theta(2,1)+Phi(2,:,1)*[X_1_star(t-1,1,b) ; X_2_star(t-1,1,b)]+w(t-1)*v(t-1,2,i);
end;
The issue I am having is this is fine when I have two X variables, however, I would like to write the code so that I can increase the number of variables to change each time, 4 say.
In this case, I would need X_1_star, X_2_star, X_3_star and X_4_star.
I can handle the Phi and Theta coefficients, as well as the w and v and e however I am struggling with creating the matrices for X's.
Any ideas would be greatly, I have tried storing the matrices within cells but I struggled to get this working.
Following the commnets, here is a simple example
%% Simple example
%-------------------------------------------------------------------------%
Phi = [0.9954 0.0195;
0.0012 0.9567];
Theta= [0.007;0.051];
beta = [0.06;-0.10;1.66;-0.88];
N = 1;
e = rand(370,1);
v = randn(370,2);
t = 371;
T = 371;
yy = rand(370,1);
X_1 = rand(370,1);
X_2 = rand(370,1);
B=50;
Y_star=zeros(T,N,B);
X_1_star=zeros(T,N,B);
X_2_star=zeros(T,N,B);
for b=1:B;
Y_star(1,:,b)=yy(1,:);
X_1_star(1,:,b)=X_1(1,:);
X_2_star(1,:,b)=X_2(1,:);
w=randn(T-1,1);
for t=2:T;
for i=1:N;
Y_star(t,i,b)=[Y_star(t-1,i,b) X_1_star(t-1,i,b) ...
X_2_star(t-1,i,b) 1]*beta(:,i)+w(t-1)*e(t-1,i);
X_1_star(t,i,b)=Theta(1,i)+Phi(1,:,i)*[X_1_star(t-1,i,b) ; ...
X_2_star(t-1,i,b)]+w(t-1)*v(t-1,1,i);
X_2_star(t,i,b)=Theta(2,i)+Phi(2,:,i)*[X_1_star(t-1,i,b) ; ...
X_2_star(t-1,i,b)]+w(t-1)*v(t-1,2,i);
end;
end;
disp(b);
end;
I ideally this to do the same thing but not be dependent upon writing X_1 and X_2, as I would like to increase this sometimes to a larger number.
I have tried reshaping as the commnets suggested but not sure how this would or could work in this example.
I think this problem is simply one of matrix algebra.
With the X variables it appears like you are simulating a small VAR model.
Instead of dynamic matrices as the answer above, I think it would make more sense to simulating the x data as a larger matrix instead of vectors.
Here is a simple example,
First, I show you a two variable case, both in the method you use, and by jointly simulating the data...
Then I show with a 3 variable case how to extend this...
All you have to do is take the size of the beta matrix (or alpha) as I guessing these are determined before the matrix...
%Simulating a small VAR model
%% 2 - variable case
rng('default')
b = [0.4 0.5;0.6 0.07];
a = [0.1 0.2];
v=randn(100,2);
x1 = zeros(100,1);
x2 = zeros(100,1);
xm=zeros(100,2);
T=100;
for t=2:T;
x1(t)=a(1)+b(1,:)*[x1(t-1) ; x2(t-1)]+v(t-1,1);
x2(t)=a(2)+b(2,:)*[x1(t-1) ; x2(t-1)]+v(t-1,2);
end;
for t=2:T;
xm(t,:)=a+xm(t-1,:)*b'+v(t-1,:)
end;
[xm x1 x2]
%% 3 - variable case
rng('default')
b = [0.4 0.5 0.1;0.6 0.07 0.1; 0.3 0.4 0.7];
a = [0.1 0.2 0.3];
v=randn(100,size(b,2));
xm=zeros(100,size(b,2));
for t=2:T;
xm(t,:)=a+xm(t-1,:)*b'+v(t-1,:)
end;
I generally find structure arrays more useful for this kind of dynamic indexing (where you don't know how many you'll have of X_1_star, X_2_star...)
I didn't try to reproduce the whole example, but it might go something like this if you're trying to get up to X_4_star:
...
nX=4;
for i=1:N
Y_star(t,i,b)=[Y_star(t-1,i,b) X_1_star(t-1,i,b) ...
X_2_star(t-1,i,b) 1]*beta(:,i)+w(t-1)*e(t-1,i);
for n=1:nX
X(n).star(t,i,b)=...
end
end

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);

Is there any special rules for nesting if-statement in for-loop in MATLAB?

I am trying to create a signal and then build a discrete-time signal by sampling the CT signal I create first. Until the last for-loop, things work out fine but I need to take N samples seperated by T. Without an if statement, I am getting an index out-of-bounds error and I had to limit sampling within the duration of the signal. For some reason, my code goes into if statement once and no more, and for debugging, I am printing out the values both in if and out of if. Although the logical operation should be true for more than one iteration(printing statements will show the values), it just does not print the statements inside the if-statement. What's wrong here?
function x = myA2D(b,w,p,T,N)
%MYA2D description: Takes in parameters to construct the CT-sampled DT signal
%b,w,p are Mx1 vectors and it returns Nx1 vector.
timeSpace = 0:0.001:3*pi;
xConstT = zeros(size(timeSpace));
%Construct Xc(t) signal
for k = 1:size(b,1)
temp = b(k) .* cos(w(k).*timeSpace + p(k));
xConstT = xConstT + temp;
end
plot(xConstT);
%Sampling CT-Signal to build DT-signal
disp(strcat('xConstT size',int2str(size(xConstT))));**strong text**
x = zeros(N,1);
sizeConstT = size(xConstT);
for i = 0:N-1
index = i .* T .* 1000 + 1;
disp(strcat('indexoo=',int2str(index)));
disp(strcat('xConstSizeeee',int2str(sizeConstT)));
if index <= sizeConstT
disp(strcat('idx=',int2str(index)));
disp(strcat('xSize',int2str(sizeConstT)));
%x(i+1,1) = xConstT(index);
end
end
end
sizeConstT = size(xConstT); creates an 1x2 array so you compare a float to an array, and your code enters the if loop only if comparison to each element of the array is successful. This example illustrates the issue:
if 1 <= [1 12]; disp('one'); end % <- prints 'one'
if 2 <= [1 12]; disp('two'); end % <- prints nothing
Your code will work with sizeConstT = length(xConstT);

MatLab: Large time inputting matix elements? Vectorization the solution?

I have some MatLab function which calculates a Wavelet Bispectrum. In this a matrix is initialised and values (complex) are put in it after they are calculated in nested for loops. However when I time the the entire function I see a third of the time (~1000s) is spent adding these values to the matrix.
The Matrix size is (1025 x 1025) and so about 1million values are input. If I generate random numbers and put them in a matrix in a similar way it takes less than I second. So why is it taking up so much time in my code?
Anyone able to help me out?
I've included a sample of the code. It is putting the million or so values into the Bisp Matrix that takes over 1000s. WT is a matrix containing complex values and freq is a vector containing all the values that match the 1st dimension of the WT matrix.
`
nfreq = 1025;
Bisp = nan(nfreq, nfreq);
Norm = nan(nfreq, nfreq);
for j = 1 : nfreq
for k = 1 : nfreq
f3 = freq(j) + freq(k);
if f3 <= freq(end)
idx3 = find(freq <= f3);
idx3 = idx3(end);
x = (WT(j, :) .* WT(k, :)) .* conj(WT(indx3, :));
bb = nansum(x);
norm1 = nansum(abs(WT(j, :) .* WT(k, :)).^2);
norm2 = nansum(abs(WT(idx3, :).^2));
a = sqrt(norm1 * norm2);
Norm(j, k) = a;
Bisp(j, k) = bb; **This takes about 1000seconds**
end
end
end
`

Vector using in a function in matlab

I have a problem about matlab code. I have a specific one variable function, and i want to assign a vector or array in this function as a x value. But i didn't reach success.
A part of my code is at below:
a=-5; b=10; n=20; %[a,b] interval range and n is number of interval
sz = (b-a)/n; %interval size
t=1; %iteration number
for i=1:n
I(i,:,t) = [a+(i-1)*sz a+i*sz]; %interval
x(i,:,t) = a+(i-0.5)*sz; %midpoint of interval
end
f= x.^2-3.*x+5; %my sample function
for i=1:n
if i==1
j=i+1;
neigbor(i,:,t) = I(j,:,t); %neigbor of interval I1's
h_f(i,:,t) =abs(f(x(i,:,t))-f(x(j,:,t))); %heuristic value
prob(i,:,t)=(ph(j,:,t).*h_f(i,:,t))./(ph(j,:,t).*h_f(i,:,t)); %probability
...
Other if conditions are following this code, but i check this below portion with sample i and j value, it gives error like this : "Subscript indices must either be real positive integers or logicals."
h_f(i,:,t) =abs(f(x(i,:,t))-f(x(j,:,t)));
What don't i know? What is my mistake? Can you suggest anything? If you need complete code, i can post.
Edit : Actually this function f returns value by using itself. But it doesn't return value in comment h_f(i,:,t)= abs((f(x(i,:,t)-x(j,:,t))
Solution Edit: After creating separate function m file, and calling in main function. Don't need to write x array in f.
In Matlab, you need to declare functions in a separate .m file. I created a separate file "f.m" and inserted the following code:
function return_val = f(x)
return_val = x.^2-3.*x+5; %my sample function
end
Then, in your main file, you can call this function as follows:
a=-5; b=10; n=20; %[a,b] interval range and n is number of interval
sz = (b-a)/n; %interval size
t=1; %iteration number
for i=1:n
I(i,:,t) = [a+(i-1)*sz a+i*sz]; %interval
x(i,:,t) = a+(i-0.5)*sz; %midpoint of interval
end
f = f(x)
Hope this helps.
As was posted you can create f as a function in a file but you can also inline the function with a handle. This is done as follows:
f = #(x) x.^2 - 3.*x + 5;
The f is the function handle with x as an input, see more information here: http://www.mathworks.com/help/matlab/matlab_prog/creating-a-function-handle.html.
This new f is then used as you would expect.
>> f(2)
ans =
3
>> f(5)
ans =
15
>> f(1:3)
ans =
3 3 5
>> f(4:10)
ans =
9 15 23 33 45 59 75