Matlab: Inequality in If statement results in error - matlab

I apologize in advance, I'm sure the answer to this question is quite trivial, unfortunately I am just not sure what is going on.
I am trying to run the following code
a(1) = -2;
b(1) = 2;
c(1) = 0;
for i = 1:15
if cubicPoly(a(i))*cubicPoly(c(i)) < 0
a(i+1) = a(i);
b(i+1) = c(i);
else
a(i+1) = c(i);
b(i+1) = b(i);
end
end
but when I do I receive the error message
Index exceeds matrix dimensions.
Error in Assignment2 (line 31)
if cubicPoly(a(i))*cubicPoly(c(i)) < 0
If I evaluate my cubic polynomial function cubicPoly normally, everything works just fine. But inside the for/if loop when evaluated at the sequences a(i) and c(i) it results in an error.
Any help would be appreciated.

It doesn't look like you ever add more elements to c; when i = 2, you're trying to access c(2) in if cubicPoly(a(i))*cubicPoly(c(i)) < 0, which takes you out of bounds.
You might want to include something like c(i+1) = ... if you intend to add elements to c while looping.

Related

Avoid for-loop to increase performance

Is it possible to obtain the matrix A in a more efficient way than using a for loop?
a = 6; % constant
b = 2; % constant
s = 0.1; % possible to change
I = 12; % possible to change
A = zeros(a,I+1);
A(:,1) = rand(a,1); % some initial value
B = rand(b,I);
% possible to avoid for-loop to increase performance?
for i = 1:I
A(:,i+1) = fun(A(:,i),B(:,i), a, s);
end
The function fun is given as
function [AOut] = fun(AIn, B, a, s)
AOut = zeros(a,1);
AOut(1) = AIn(1) + AIn(4)*s*cos(AIn(3));
AOut(2) = AIn(2) + AIn(4)*s*sin(AIn(3));
AOut(3) = AIn(3) + AIn(4)*AIn(6)*s;
AOut(4) = AIn(4) + AIn(5)*s;
AOut(5) = AIn(5) + B(1);
AOut(6) = AIn(6) + B(2);
end
i dont think you can optimize the loop in regards to effiency as the last values are needed for calculating the next. #Tony Tannous showed you a nice way how to get rid of the loop in your code. For better performance at high values of I you can change fun() to:
function [AOut] = fun2(AIn, B, a, s)
AOut=AIn+ [AIn(4)*s*cos(AIn(3)) ;...
AIn(4)*s*sin(AIn(3)) ;...
AIn(4)*AIn(6)*s ;...
AIn(5)*s ; ...
B(1) ; ...
B(2)];
end
First of all, if a != n
You will get an error:
Subscripted assignment dimension mismatch.
So you must be cautious
And, to get rid of the loop you can do this:
EDIT:
Apparently i isn't getting modified on the right side. I'll try to fix it and reedit my answer.
anyway, to get rid of the loop you can still use A(:, i:1:I)
i = 1;
A(:, i:1:I) = fun(A(:,i),B(:,i), a, s);
If you have any further question, please ask!

MATLAB: Unit step function

For some reason when I try to create a simple unit step function I just receive a straight line. I am pretty sure this is correct, but my graph tells me otherwise. Is there something I am doing wrong?
function mone=myOne(t)
[n,~] = size(t);
mone=zeros(n,1);
for i=1:n,
if (t(i)>0),
mone(i) = 1;
end
end
in the command window I type,
t = [-5:0.01:5]
plot(t, myOne(t))
The error is your line:
[n,~] = size(t);
You only query the first dimension of t, which is 1 following
t = [-5:0.01:5]
size(t)
ans =
1 1001
You can either transpose t
t = [-5:0.01:5].';
size(t)
ans =
1001 1
or you length instead of size.
n = length(t);
Finally, a solution without the loop as proposed by #Dan is much faster.
I can't see anything wrong with the logic behind your function but your implementation is very long winded. In Matlab you can just do this:
function mone=myOne(t)
mone = t > 0;
end
or if you want to get a matrix of numbers and not logicals returned try
function mone=myOne(t)
mone = (t > 0)*1; %// Or if you prefer to cast explicitly:
%// double(t>0)
end
Also to add a shift parameter with default set to zero:
function mone=myOne(t, T)
if nargin < 2
T = 0;
end
mone = (t > T)*1;
end
usage:
t = [-5:0.01:5]
plot(t, myOne(t))
plot(t, myOne(t,3))

Plotting own function in scilab

Hey i have an issuse with plotting my own function in scilab.
I want to plot the following function
function f = test(n)
if n < 0 then
f(n) = 0;
elseif n <= 1 & n >= 0 then
f(n) = sin((%pi * n)/2);
else
f(n) = 1;
end
endfunction
followed by the the console command
x = [-2:0.1:2];
plot(x, test(x));
i loaded the function and get the following error
!--error 21
Invalid Index.
at line 7 of function lala called by :
plot(x, test(x))
Can you please tell me how i can fix this
So i now did it with a for loop. I don't think it is the best solution but i can't get the other ones running atm...
function f = test(n)
f = zeros(size(n));
t = length(n);
for i = 1:t
if n(i) < 0 then
f(i) = 0;
elseif n(i) <= 1 & n(i) >= 0
f(i) = sin((%pi * n(i)/2));
elseif n(i) > 1 then
f(i) = 1;
end
end
endfunction
I guess i need to find a source about this issue and get used with the features and perks matlab/scilab have to over :)
Thanks for the help tho
The original sin is
function f = test(n)
(...)
f(n) = (...)
(...)
endfunction
f is supposed to be the result of the function. Therefore, f(n) is not "the value that the function test takes on argument n", but "the n-th element of f". Scilab then handles this however it can; on your test case, it tries to access a non-integer index, which results in an error. Your loop solution solves the problem.
Replacing all three f(n) by f in your first formulation makes it into something that works... as long as the argument is a scalar (not an array).
If you want test to be able to accept vector arguments without making a loop, the problem is that n < 0 is a vector of the same size as n. My solution would use logical arrays for indexing each of the three conditions:
function f = test(n)
f = zeros(size(n));
negative = (n<0);//parentheses are optional, but I like them for readability
greater_than_1 = (n>1);
others = ~negative & ~greater_than_1;
f(isnegative)=0;
f(greater_than_1)=1;
f(others) = sin(%pi/2*n(others));
endfunction

Extremely strange for loop behavior in Matlab

When attempting to write a for loop to increment from 1 to the end of an array, Matlab throws an error saying that I attempted to access the 0th array element, which doesn't exist. Here's the snippet in question:
function [adjMatNew] = delete(obj, adjMat)
[~, n] = size(adjMat);
adjMatNew = adjMat;
for i = 1:n
if adjMat(obj.number, i) ~= 0
adjList(i) = i
end
end
for j = 1:numel(adjList)
for k = 1:numel(adjList)
if j ~= k
adjMatNew(adjList(k), adjList(j)) = 1;
end
end
end
adjMatNew(obj.number, :) = 0;
adjMatNew(:, obj.number) = 0;
end
I can't think of any possible reason why, in the for loops above, the loop would start at 0. Changing the beginning increment variable from 1 to 2 fixed the issue and the function worked as intended, but it doesn't seem like the right fix. Does anybody have an explanation for this?
Without any help or comments, it's not very clear what you're actually attempting to do; however, in the line
adjMatNew(adjList(k), adjList(j)) = 1;
you implicitly assume that adjList is never zero. Since that is apparently the case, you get the error.
As suggested in other comments/answers, the issue is where you construct adjList.
for i = 1:n
if adjMat(obj.number, i) ~= 0
adjList(i) = i
end
end
Let's consider what happens in three different situations where n = 3:
1) If all of adjMat(obj.number, 1:3) are ~=0, each loop
adjList(1) = 1;
adjList(2) = 2;
adjList(3) = 3;
output: adjList = [1,2,3];
This case shouldn't throw an error.
2) If adjMat(obj.number, 3) is zero:
adjList(1) = 1;
adjList(2) = 2;
% adjList(3) not set
output: adjList = [1,2];
No error here, either.
3) If adjMat(obj.number, 2) is zero:
adjList(1) = 1;
% adjList(2) not set
adjList(3) = 3;
Since adjList(2) is not set, when calling adjList(3) = 3;, MATLAB needs there to be some value for adjList(2). By default, this is handled by filling with zeros to make the matrix the right size:
output: adjList = [1 0 3];
This causes the error.
As suggested in the comments by Notlikethat, adjList = find(adjMat(obj.number,:)) would be good way of replacing this loop. In this case, it only returns the positions of the non zero elements, so in the third case above, the output would be adjList = [1 3].

MATLAB Loop error when adding noise function

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