MATLAB Loop error when adding noise function - matlab

One of the tasks for my assignment is to add an appropriate noise function to the following equation:
x = A*(1+a1*E)*sin(w*(1+a2*E)*t+y)+ a3*E
We must then plot the noise function vs. time as well as the original function with the noise added. I have asked the professor if a random number generator between -1 and 1 will suffice and he has agreed. I have the following code so far:
t = 0:0.1:6.5;
A = 2;
a1 = 2;
a2 = 4;
a3 = 3;
w = 1;
y = 2;
for i=1:length(t)
E(i) = random('unif', -1, 1, 1, 1);
x(i) = A*(1+a1*E(i))*sin(w*(1+a2*E(i))*t+y)+ a3*E(i);
i=i+1;
end
plot(t,E)
figure
stem(t,x)
I keep getting the following error In an assignment A(I) = B, the number of elements in B and I must
be the same.
Error in Try1 (line 58)
x(i) = A*(1+a1*E(i))*sin(w*(1+a2*E(i))*t+y)+ a3*E(i);
I don't understand the error because the E is just one number.
Any help appreciated!! Thanks!!

You're correct that E is just one number, but you're multiplying by t, which is not just one number - it's an array. I think you meant to multiply by t(i).
here------v
x(i) = A*(1+a1*E(i))*sin(w*(1+a2*E(i))*t(i)+y)+ a3*E(i);

Related

Attempting Tridiagonal Gauss-Jordan Elimination Matlab

As you probably guessed from the title, I'm attempting to do tridiagonal GaussJordan elimination. I'm trying to do it without the default solver. My answers aren't coming out correct and I need some assistance as to where the error is in my code.
I'm getting different values for A/b and x, using the code I have.
n = 4;
#Range for diagonals
ranged = [15 20];
rangesd = [1 5];
#Vectors for tridiagonal matrix
supd = randi(rangesd,[1,n-1]);
d = randi(ranged,[1,n]);
subd = randi(rangesd,[1,n-1]);
#Creates system Ax+b
A = diag(supd,1) + diag(d,0) + diag(subd,-1)
b = randi(10,[1,n])
#Uses default solver
y = A/b
function x = naive_gauss(A,b);
#Forward elimination
for k=1:n-1
for i=k+1:n
xmult = A(i,k)/A(k,k);
for j=k+1:n
A(i,j) = A(i,j)-xmult*A(k,j);
end
b(i) = b(i)-xmult*b(k);
end
end
#Backwards elimination
x(n) = b(n)/A(n,n);
for i=n-1:-1:1
sum = b(i);
for j=i+1:n
sum = sum-A(i,j)*x(j);
end
x(i) = sum/A(i,i)
end
end
x
Your algorithm is correct. The value of y that you compare against is wrong.
you have y=A/b, but the correct syntax to get the solution of the system should be y=A\b.

Solve for independent variable between data points in MATLAB

I have many sets of data over the same time period, with a timestep of 300 seconds. Sets that terminate before the end of the observation period (here I've truncated it to 0 to 3000 seconds) have NaNs in the remaining spaces:
x = [0;300;600;900;1200;1500;1800;2100;2400;2700;3000];
y(:,1) = [4.65;3.67;2.92;2.39;2.02;1.67;1.36;1.07;NaN;NaN;NaN];
y(:,2) = [4.65;2.65;2.33;2.18;2.03;1.89;1.75;1.61;1.48;1.36;1.24];
y(:,3) = [4.65;2.73;1.99;1.49;1.05;NaN;NaN;NaN;NaN;NaN;NaN];
I would like to know at what time each dataset would reach the point where y is equal to a specific value, in this case y = 2.5
I first tried finding the nearest y value to 2.5, and then using the associated time, but this isn't very accurate (the dots should all fall on the same horizontal line):
ybreak = 2.5;
for ii = 1:3
[~, index] = min(abs(y(:,ii)-ybreak));
yclosest(ii) = y(index,ii);
xbreak(ii) = x(index);
end
I then tried doing a linear interpolation between data points, and then solving for x at y=2.5, but wasn't able to make this work:
First I removed the NaNs (which it seems like there must be a simpler way of doing?):
for ii = 1:3
NaNs(:,ii) = isnan(y(:,ii));
for jj = 1:length(x);
if NaNs(jj,ii) == 0;
ycopy(jj,ii) = y(jj,ii);
end
end
end
Then tried fitting:
for ii = 1:3
f(ii) = fit(x(1:length(ycopy(:,ii))),ycopy(:,ii),'linearinterp');
end
And get the following error message:
Error using cfit/subsasgn (line 7)
Can't assign to an empty FIT.
When I try fitting outside the loop (for just one dataset), it works fine:
f = fit(x(1:length(ycopy(:,1))),ycopy(:,1),'linearinterp');
f =
Linear interpolant:
f(x) = piecewise polynomial computed from p
Coefficients:
p = coefficient structure
But I then still can't solve f(x)=2.5 to find the time at which y=2.5
syms x;
xbreak = solve(f(x) == 2.5,x);
Error using cfit/subsref>iParenthesesReference (line 45)
Cannot evaluate CFIT model for some reason.
Error in cfit/subsref (line 15)
out = iParenthesesReference( obj, currsubs );
Any advice or thoughts on other approaches to this would be much appreciated. I need to be able to do it for many many datasets, all of which have different numbers of NaN values.
As you mention y=2.5 is not in your data set so the value of x which corresponds to this depends on the interpolation method you use. For linear interpolation, you could use something like the following
x = [0;300;600;900;1200;1500;1800;2100;2400;2700;3000];
y(:,1) = [4.65;3.67;2.92;2.39;2.02;1.67;1.36;1.07;NaN;NaN;NaN];
y(:,2) = [4.65;2.65;2.33;2.18;2.03;1.89;1.75;1.61;1.48;1.36;1.24];
y(:,3) = [4.65;2.73;1.99;1.49;1.05;NaN;NaN;NaN;NaN;NaN;NaN];
N = size(y, 2);
x_interp = NaN(N, 1);
for i = 1:N
idx = find(y(:,i) >= 2.5, 1, 'last');
x_interp(i) = interp1(y(idx:idx+1, i), x(idx:idx+1), 2.5);
end
figure
hold on
plot(x, y)
scatter(x_interp, repmat(2.5, N, 1))
hold off
It's worth keeping in mind that the above code is assuming your data is monotonically decreasing (as your data is), but this solution could be adapted for monotonically increasing as well.

Why does the one-dimensional variant of a 2-d random walk not work?

There is a two-dimensional random walk that one can find here which works perfectly in Octave. However, when I tried to write a one-dimensional random walk program, I got an error. Here is the program:
t=[];
x=[];
for i=1:100000
J=rand;
if J<0.5
x(i+1)=x(i)+1;
t(i+1)=t(i)+1;
else
x(i+1)=x(i)-1;
t(i+1)=t(i)+1;
end
end
plot(t,x)
Here is the error:
error: A(I): index out of bounds; value 1 out of bound 0
Thank you.
No need for a loop:
N = 100000;
t = 1:N;
x = cumsum(2*(rand(1,N)<.5)-1);
plot(t,x)
For the 2D case you could use the same approach:
N = 100000;
%// t = 1:N; it won't be used in the plot, so not needed
x = cumsum(2*(rand(1,N)<.5)-1);
y = cumsum(2*(rand(1,N)<.5)-1);
plot(x,y)
axis square
You get an error because you ask MATLAB to use x(1) in the first iteration when you actually defined x to be of length 0. So you need to either initialize x and t with the proper size:
x=zeros(1,100001);
t=zeros(1,100001);
or change your loop to add the new values at the end of the vectors:
x(i+1)=[x(i) x(i)+1];
Since t and x are empty, therefore, you cannot index them through x(i+1) and x(i).
I believe you should intialize x and t with all zeros.
In the first iteration, i = 1, you have x(2) = x(1) +or- 1 while x has dimension of zero. You should define the starting point for x and t, which is usually the origin, you can also change the code a little bit,
x = 0;
N = 100000;
t = 0 : N;
for i = 1 : N
x(i+1) = x(i) + 2 * round(rand) - 1;
end
plot(t,x)

Subscripted assignment dimension mismatch

So, I'm trying to do the Gauss-Seidel method in Matlab and I found a code that does this but when I apply it to my matrices I get the Subscripted assignment dimension mismatch. error. I will show you my code in order to get a better idea.
%size of the matrix
n = 10;
%my matrices are empty in the beginning because my professor wants to run the algorithm for n = 100
and n = 1000. A's diagonal values are 3 and every other value is -1. b has the constants and the
first and last value will be 2,while every other value will be 1.
A = [];
b = [];
%assign the values to my matrices
for i=1:n
for j=1:n
if i == j
A(i,j) = 3;
else
A(i,j) = -1;
end
end
end
for i=2:n-1
b(i) = 1;
end
%here is the Gauss-Seidel algorithm
idx = 0;
while max(error) > 0.5 * 10^(-4)
idx = idx + 1;
Z = X;
for i = 1:n
j = 1:n; % define an array of the coefficients' elements
j(i) = []; % eliminate the unknow's coefficient from the remaining coefficients
Xtemp = X; % copy the unknows to a new variable
Xtemp(i) = []; % eliminate the unknown under question from the set of values
X(i) = (b(i) - sum(A(i,j) * Xtemp)) / A(i,i);
end
Xsolution(:,idx) = X;
error = abs(X - Z);
end
GaussSeidelTable = [1:idx;Xsolution]'
MaTrIx = [A X b]
I get the error for the Xsolution(:,idx) = X; part. I don't know what else to do. The code posted online works though, and the only difference is that the matrices are hardcoded in the m-file and A is a 5x5 matrix while b is a 5x1 matrix.
I am unable to run your code because some variables are not initialised, at least error and X. I assume the Problem is caused because Xsolution is already initialised from a previous run with a different size. Insert a Xsolution=[] to fix this.
Besides removing the error I have some suggestions to improve your code:
Use Functions, there are no "left over" variables from a previous run, causing errors like you got here.
Don't use the variable name error or i. error is a build-in function to throw errors and i is the imaginary unit. Both can cause hard to debug errors.
Initialise A with A=-1*ones(n,n);A(eye(size(A))==1)=3;, it's faster not to use a for loop in this case. To initialise b you can simply write b(1)=0;b(2:n-1)=1;
Use preallocation
the first time you run the code, Xsolution(:,idx) = X will create a Xsolution with the size of X.
the second time you run it, the existing Xsolution does not fit the size of new X.
this is another reason why you always want to allocate the array before using it.

MATLAB Discretizing Sine Function with +/-

Hello I am relatively new to MATLAB and have received and assignment in which we could use any programming language. I would like to continue MATLAB and have decided to use it for this assignment. The questions has to do with the following formula:
x(t) = A[1+a1*E(t)]*sin{w[1+a2*E(t)]*t+y}(+/-)a3*E(t)
The first question we have is to develop an appropriate discretization of x(t) with a time step h. I think i understand how to do this using step but because there is a +/- in the end I am running into errors. Here is what I have (I have simplified the equation by assigning arbitrary values to each variable):
A = 1;
E = 1;
a1 = 1;
a2 = 2;
a3 = 3;
w = 1;
y = 0;
% ts = .1;
% t = 0:ts:10;
t = 1:1:10;
x1(t) = A*(1+a1*E)*sin(w*(1+a2*E)*t+y);
x2(t) = a3*E;
y(t) = [x1(t)+x2(t), x1(t)-x2(t)]
plot(y)
The problem is I keep getting the following error because of the +/-:
In an assignment A(I) = B, the number of elements in B and I must be the same.
Error in Try1 (line 21)
y(t) = [x1(t)+x2(t), x1(t)-x2(t)]
Any help?? Thanks!
You can remove the (t) from the left-hand side of all three assignments.
y = [x1+x2, x1-x2]
MATLAB knows what to do with vectors and matrices.
Or, if you want to write it out the long way, tell MATLAB there will be two columns:
y(t, 1:2) = [x1(t)'+x2(t)', x1(t)'-x2(t)']
or two rows:
y(1:2, t) = [x1(t)+x2(t); x1(t)-x2(t)]
But this won't work when you have fractional values of t. The value in parentheses is required to be the index, not a dependent variable. If you want the whole vector, just leave it out.