MATLAB double inequality - matlab

I am having some trouble understand why this is wrong
if x<=-1
elseif pwres=1
elseif -1<x<=1
pwres=x.^2
else
pwres=x.^3
end
I have been told not to write -1 in line #3.
Does MATLAB not support double inequality?
Also is it supposed to be x.^2 or x^2?

When you attempt -1<x<=1, MATLAB first calculates -1<x and returns 0 or 1 depending on the result. The 0 or 1 you end up with then gets compared to 1 using the <= operation, which would always return 1.
Effectively, you'd end up with a result of 1 for any value of x.

Related

How to Implement Box Function in better way in Matlab?

This function in Matlab presents Box_Function:
output = 1 while sample n belongs to the range (-a, +a).
otherwise the output is 0 outside that range.
So how can I implement this function in Matlab in a better way to shift the plot in case of negative values of time, without assigning negative values to the array.
Thanks in Advance
function B_X = Box_Func(N,K,a)
if(N <= 0)||(K+a > N)
warning('Please Enter Valid Positive Integer !');
else
B_X = zeros([-N N]);
for i = -N : 1 : N
if (i >= K-a) && (i <= K+a)
B_X(i)=1;
end
end
end
end
Your question is unclear since it does not really explain what you want to do, and in one comment you state that you know where the error comes from. I suggest to read the docs (also in a comment), but here I'll show you my problems with your code, provide some simple ways of testing your code and I hope this helps to solve your problem and to understand how to ask better questions.
First, one remark to the lines
if(N <= 0)||(K+a > N) % if samples Number wrong, or shifting exceeds limit
% of Samples Print a warning.
warning('Please Enter Valid Positive Integer !');
I suggest to throw an error instead of a warning if the input parameters are wrong and will lead to an error anyway. Otherwise you could omit the test and let Matlab throw the respective error.
The next misunderstanding is
B_X = zeros([-N N])
What do you expect B_X to be after this line if, let's say, N=2? Test if the result is what you expect by simply entering this command in the command line directly:
>> zeros([-2 2])
ans =
0×2 empty double matrix
I guess that's not what you expect. As the docs state, zeros(N) will yield a square matrix with N rows and N columns; zeros(M,N) will yield a matrix with M rows and N columns. Look:
>> zeros(2)
ans =
0 0
0 0
>> zeros(2,1)
ans =
0
0
I do not know what you expect from zeros([-2 2]), but I guess that you are looking for one of the following:
>> N = 2;
>> zeros(2*N+1,1)
ans =
0
0
0
0
0
>> zeros(1,2*N+1)
ans =
0 0 0 0 0
>> zeros(2*N+1)
ans =
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
My guess is that somehow you expect the function zeros to operate on some range of indices you provide. Your misunderstanding might be that you expect zeros([-2 2]) to provide a vector of zeros into which you can index using -2:2 (that is, one of -2,-1,0,+1,+2). If you assume this, your assumption is wrong.
I guess this from the line
for i = -N : 1 : N
in your code. Due to this line, I'll first thought that
>> B_X = zeros(1, 2*N+1)
B_X =
0 0 0 0 0
is what you expect. However, from the comment
% if samples Number wrong, or shifting exceeds limit
I guessed that N might be just the number of data points in the result. This would mean
>> B_X = zeros(1, N)
B_X =
0 0
(which would not make much sense for N=2). So, for the next question you ask (or an edit to this question): Clearly explain the meaning of the function inputs!
Since later, you set the limits of your x-axes to [-N N], I'll keep my first assumption, thus the number of data points (and therefore the argument to zeros) should be 2*N+1.
The next argument to your function is K, you call it the shift. k only occurs in combination with the third input of the function, a. You do not provide any inforamtion about a.
From this line I guess that a is something that specifies a width:
if (i >= K-a) && (i <= K+a)
Now, slowly, if one also considers
B_X(i)=1;
and the usage of the word box (and heaviside, which is still in the comments), one can get a clue of what you want to do. Together with your comment that you want your function
to appear on the plotting shifted on X Axis, so it looks like that the center of the Box Function is in the negative area of X axis
Might this be your goal: I want to plot a vector from -N to N (in steps of 1) with zero values except for the region of -K±a, where I want it to be one?
If this is the case, one attempt would be as follows (it remains to you to put it into a function):
>> N=15;
>> K=7;
>> a = 3;
Get the x-values:
>> x = -N:N;
(-15, -14, ... 14, 15). Next, allocate B_X:
>> B_X = zeros(1, 2*N+1);
Last, use logical indexing (this might help to understand this) to set the values around -K±a to one:
>> B_X(x>(-K-a) & x<(-K+a)) = 1;
Eventually, plot the result:
plot(x,B_X);
and adjust the axis limits:
>> ax=gca;
>> ax.YLim = [-.2 1.2];
Result is:
function B_X = Box_Func(N,K,a)
% Box_Func This Function takes Number of Samples N,Count of shift K, and
% half of Box width a then it stem Them ,
% Note it works only for positive shifting
% that means K should be positive or Zero
if(N <= 0)||(K+a > N) % if samples Number wrong, or shifting exceeds limit
% of Samples Print a warning.
warning('Please Enter Valid Positive Integer !');
else % if The inputs are fine , then :
B_X = zeros([1 2*N+1]);
x = -N:N;
B_X(x>=(K-a) & x<=(K+a)) = 1;
end
%===========================================
% Plotting the Results
%===========================================
figure('Name','Box Function','NumberTitle','off');
stem(x,B_X)
hold on
xlabel('Samples')
ylabel('Box Shifeted Function')
xlim([-N N]) ;
ylim([-1 2]);
grid on
hold off
end

MATLAB: All combinations of sum of vectors

So I have this piece of code (in MATLAB)
% Define vectorfield
g1=[5,0,0];
g2=[0,3,0];
g3=[0,0,4];
% Define on-off
u=[0;1];
% Define set to make field symmetric
symm=[1;-1];
k=1;
%% Generate possible combinations of vector fields
for a=1:length(u)
for b=1:length(symm)
for c=1:length(u)
for d=1:length(symm)
for e=1:length(u)
for f=1:length(symm)
allvecfields(k,:)=u(a).*symm(b).*g1+u(c).*symm(d).*g2+u(e).*symm(f).*g3;
k=k+1;
end
end
end
end
end
end
realfields=transpose(unique(allvecfields,'rows'));
Each column of realfields is a unique positive, negative or zero combination of the g's. I need some help generalizing this. That is the size of each g can be n, and the number of g's can be m. The code should still return all the unique possible combinations of the g's. I have a feeling that recursion will have to be used but all my attempts have failed so far.
Also allvecfields(k,:) just means kth row, all columns. Even if your answer contains C/C++ or Java code (without any special functions from them) that is fine for me. I will translate it into MATLAB.
I have looked at combvec and the allcomb file but they don't do what I need. For example transpose(unique(combvec(g1,g2,g3,-g1,-g2,-g3)','rows')) returns a 6x63 matrix not the 3x27 that I want. Doing
vals=transpose(unique(combvec(g1,g2,g3)','rows'));
vals=[vals transpose(unique(combvec(-g1,g2,g3)','rows'))];
vals=[vals transpose(unique(combvec(g1,-g2,g3)','rows'))];
vals=[vals transpose(unique(combvec(g1,g2,-g3)','rows'))];
vals=[vals transpose(unique(combvec(g1,-g2,-g3)','rows'))];
vals=[vals transpose(unique(combvec(-g1,g2,-g3)','rows'))];
vals=[vals transpose(unique(combvec(-g1,-g2,g3)','rows'))];
vals=[vals transpose(unique(combvec(-g1,-g2,-g3)','rows'))];
vals=unique(vals','rows');
Does give what I want, but that does not help in generalizing.
EDIT: Fixed error in last line of first code block. The required output for this case is quite large (27 columns) but if we just had g1 and g2 then the output would be:
realfields =
-5 -5 -5 0 0 0 5 5 5
-3 0 3 -3 0 3 -3 0 3
0 0 0 0 0 0 0 0 0
EDIT: Based on a suggestion in the comments, I have been able to rewrite the above code as,
u=[-1,0,1];
k=1;
for a=1:length(u)
for b=1:length(u)
for c=1:length(u)
uMat(k,:)=[u(a) u(b) u(c)];
k=k+1;
end
end
end
g1=[5,0,0];
g2=[0,3,0];
g3=[0,0,4];
gMat=[g1' g2' g3'];
for a=1:size(uMat,1)
allvecfields(k,:)=sum(bsxfun(#times,gMat,uMat(a,:)),2);
end
realfields=transpose(unique(allvecfields,'rows'))
I think this is slightly more elegant but I am still stuck at how to dynamically generate uMat given the number of columns in gMat. I can't believe a function doesn't exist for this. Any help would be appreciated.
Here is the solution
g1=[5,0,0];
g2=[0,3,0];
g3=[0,0,4];
gMat=[g1' g2' g3'];
m=size(gMat',1);
allvecfields = zeros(3^m,m);
for k = 1:3^m
allvecfields(k,:) = double(dec2base(k-1,3,m)-'1');
end
realfields = (allvecfields*gMat')'
Credits to: Roger Stafford for this ingenious solution.

Function output contradicts function constraints

I wrote a function that takes as an imput a natural number 'n', and outputs a random walk, starting at 0, where each subsequent entry in the vector is obtained by adding or subtracting 1 to the previous entry. The random walk has to stop whenever it reaches n or -n.
The code is the following
function [N] = rand_walk2(n)
j=0; %J will be the outpur of the function
v=0; %Defines variable v.
i=2; %The following 'while' loop will start from the second entry of the vector.
while abs(j(i-1)) < n %This 'while' loop will continue running only if the previous entry is strictly between -n and n.
if rand >= 0.5 %This 'if' statement returns 1 or -1 with equal probability (it uses the uniform distribution with parameters [0,1]).
v = 1;
else v = -1;
end
j(i)=j(i-1)+v;
j = [j,j(i)];
i=i+1;
end
N = j;
end
The problem is that the output returns n or -n twice instead of only once, for example, if I evaluate rand_walk2(3) I get 0 -1 -2 -3 -3 instead of just o -1 -2 -3. Does anyone have any suggestions as to what I can change to fix this?
Line 10 pushes the current position into vector j
j(i)=j(i-1)+v;
and then line 11 concatenates that same value on to the end of the array
j = [j,j(i)];
Simply remove line 11.
As a usual side note, the symbols i and j are often used to produce imaginary numbers and often mistakenly as indexing variables. It is recommended by Mathworks:
Since i is a function, it can be overridden and used as a variable. However, it is best to avoid using i and j for variable names if you intend to use them in complex arithmetic.
In this case, it is not necessary, but I like to promote good programming practices when I can (also, I needed to force my brain to think through your code because of this practice).

indices must either be real positive integers or logicals. && Attempted to access f(0,0); index must be a positive integer or logical

I am new in matlab coming from c++ and trying to do 2d convolution. I have done dry run but nothing seems to go wrong but i dont know why this coming
My simple logic if value is lesser equal to zero then place zero. I am using this expression for solving that problem
i am facing 2 errors at
1)at f(q,p)=zeros(q,p);
2) at output_args(x,y)=output_args(x,y) + (W(s, t)* f(q,p));
function output_args = convo(img,k )
//skipped the portion of code---
z=s;i=t;
for x=1:row
for y=1:col
for s=s:a+2
% disp(s);
for t= t:b+2
q=z-s;
p=i-t;
if q<=0
if p <=0
f(q,p)=0; %// trying to place zero at index so help needed which is 1st error i have said
end
end
% disp(f(q,p));
output_args(x,y)=output_args(x,y) + (W(s, t)* f(q,p)); %//2nd error is comin (as i have told you above.
end
end
w=w+1;
end
z=z+1;
end
end
at console:(error occur when i apply
1) Subscript indices must either be real positive integers or logicals at f(q,p)=0
2) Attempted to access f(0,0); index must be a positive integer or logical. output_args(x,y)=output_args(x,y) + (W(s, t)* f(q,p));
so any idea?
if q<=0
if p <=0
f(q,p)=0; % p and q will always be invalid!
end
end
Well, that is begging for that error. In MATLAB, Indices must be greater than zero. While you can invert the if-condition to ensure that the index is positive, that will change the mending of your code.
if q > 0
if p > 0
f(q,p)=0; % p and q will always be valid.
end
end
If you need to index from -5 to 5 (for example) you could instead index from 1 to 11 instead. Just remember that you subtract 6 every time you display values. Alternatively, store the "real" indices in another vector.

Interplay of values between two vectors in Matlab

I have two vectors o and c of equal length:
o = [-1 -1 -1 0 0 0 1 1 0 0];
c = [-1 -1 -1 -1 0 1 1 1 0 -1];
o represents opening signals (neg or pos) and c represents closing signals, assuming an opening signal has preceeded it with opposite sign. Only one signal can be active at a time so consecuitive signals must be ignored. In the two vectors above, my first signal would be in o(1) and its corresponding closing signal would be found in c(6). This also means that the opening signals in o(2) and o(3) should be ignored and my next opening signal is found at o(7) with its corresponding close at c(10), consequently leading to a void signal at o(8)
I am trying to find a vectorized solution to identifying a correct sequence or indices of opened/closed signals to produce something along the lines of the following solution example:
o = [-1 0 0 0 0 0 1 0 0 0];
c = [ 0 0 0 0 0 1 0 0 0 -1];
I can obviously solve this by looping through each element in a for loop but since my dataset can be up to millions of elements and I find looping in Matlab can be rather 'expensive', I would greatly appreciate if someone has a solution to my problem that is more matrix-oriented, or through arrayfun or something equivalent that may make the code more efficient?
You can use diff, along with some logical operations to get your answer.
o=[-1,-1,-1,0,0,0,1,1,0,0];
oFinal=abs(diff([0,o])).*o;
oFinal=
-1 0 0 0 0 0 1 0 0 0
The trick is that the output of diff and your original vector o both have a non-zero value at the same index only for the first occurrence of the value in o (i.e., first occurrence in a chain). So, by multiplying it element-wise with o, you get your answer. The abs is to ensure that a sign change doesn't occur due to the output from diff.
The approach is similar for c, and I'll leave that for you to try :)
Usually looping is not more expensive as performing some other operation which just hiddes the loop behind another function (e.g. arrayfun). From your text it just sounds that you just chose the wrong algorithm. Your problem sounds very linear, that is O(n), but you write about loop in loop which means O(n^2). With millions of elements quadratic runtime is not so nice.
The algorithm you want is something like this:
open = 0;
for i=1:length(o)
if (open == 0)
open=o(i)
else
o(i) = 0;
end
if (c(i) ~= -open)
c(i) = 0;
else
open = 0;
end
end
It maybe needs some finetunig, as you didnt describe in detail e.g. what the order of the c and o signals are (e.g. if the same index opens and closes is first the open processed or the closed, my example code assumes open), or whether the order of the signals is always ok, or if there must be some error treatment - but I guess you get the idea of the single loop.