Error when ploting discrete time function

I defined an anonymous function as below
xn = @(n)[(n==-3),(n==-2),(n==-1),(n==0),(n==1),(n==2),(n==3)]*[3;2;1;0;1;2;3]
This functions means to describe a discrete signal
x[n]=[3 2 1 0 1 2 3]
^
However, when I attempted to plot a discrete figure for this signal using stem function:
n=[-3:3]
stem(n,xn(n))
Matlab gives the error message as following:
Error using *
Incorrect dimensions for matrix multiplication. Check that the number of columns in the first matrix matches
the number of rows in the second matrix. To perform elementwise multiplication, use '.*'.
Error in @(n)[(n==-3),(n==-2),(n==-1),(n==0),(n==1),(n==2),(n==3)]*[3;2;1;0;1;2;3]
I really don't know where goes wrong.
A big thanks to all that may drop by and leave your answer!

 Accepted Answer

Use element-wise multiplication (.*) instead of matrix multiplication (*).
Try this —
xn = @(n)[(n==-3),(n==-2),(n==-1),(n==0),(n==1),(n==2),(n==3)].*[3;2;1;0;1;2;3];
figure
n=[-3:3]
n = 1×7
-3 -2 -1 0 1 2 3
stem(n,xn(n))
.

8 Comments

This approach yields a matrix as a result, not a vector (as would represent a sequence):
xn = @(n)[(n==-3),(n==-2),(n==-1),(n==0),(n==1),(n==2),(n==3)].*[3;2;1;0;1;2;3];
size(xn(-3:3))
ans = 1×2
7 49
That is because the first element is a (1x6) vecttor and the second is a (6x1) vector, with automatic implicit expansion.
A more appropriate approach would be to create the first vector as logical, since this is likely what was originally intended anyway. This, along with transposing the second element gives:
xn = @(n)[(n==-3) | (n==-2) | (n==-1) | (n==0) | (n==1) | (n==2) | (n==3)].*[3;2;1;0;1;2;3].';
n=[-3:3]
n = 1×7
-3 -2 -1 0 1 2 3
CkeckSize = size(xn(n))
Ckeck = 1×2
1 7
figure
stem(n,xn(n))
And likely appears to be the desired result.
.
We won't really know the desired result until/if the OP provides some clarification. But I suspect that the OP wants a function that returns the elements of x for an input of sequence values, n, such as
xn([-1 2]);
The construction I always use for these functions is:
v = [3;2;1;0;1;2;3];
xn = @(n) (n==-3).*v(1) + (n==-2).*v(2) + (n==-1).*v(3) + (n==0).*v(4) + (n==1).*v(5) + (n==2).*v(6) + (n==3).*v(7);
x = [-1 2];
figure
stem(x, xn(x))
axis([-3 3 0 4])
That eliminates any ambiguities, and permits functions if the independent variable as the elements of ‘v’ when necessary. I have used this sort of construction for at least the last 9 years.
.
Do you use this approach if numel(v) is large?
Also, I'm sure you know this but it's worth pointing out anyway for others that might be reading this threat that if v changes after xn is defined, then xn has to be redefined to use the new v.
If numel(v) is large, then the construction can be adapted to use a loop. (I have never encountered that problem.)
If ‘v’ is to be redefined later, the function simply needs to incorporate ‘v’ as a second input to the original function. Then ‘v’ can change all it wants and the function will still work correctly with the new definition of ‘v’, (providing of course that the sizes match with the original construction, or that the loop could adapt to them).
xn = @(n,v) (n==-3).*v(1) + (n==-2).*v(2) + (n==-1).*v(3) + (n==0).*v(4) + (n==1).*v(5) + (n==2).*v(6) + (n==3).*v(7);
.
Really appreciate your answer!
I think this solves my problem perfectly.
Thx very much
As always, my pleasure!
.

Sign in to comment.

More Answers (1)

The function definition is implicitly assuming that the input, n, is a scalar. Looking at the first the term on its LHS:
n = 2;
[(n==-3),(n==-2),(n==-1),(n==0),(n==1),(n==2),(n==3)]
ans = 1×7 logical array
0 0 0 0 0 1 0
That returns what you expect. But with n a vector
n = 1:2;
[(n==-3),(n==-2),(n==-1),(n==0),(n==1),(n==2),(n==3)]
ans = 1×14 logical array
0 0 0 0 0 0 0 0 1 0 0 1 0 0
Each logical comparison is the same size as n, then each of those are concatenated together. Clearly this result can't be element-multiplied with -3:0:3.
Edit: I just realized that the function in the quesion was relying on matrix mulitplication, not element mulitplication. But the point still stands that terms being multiplied are incompatible.
Fortunately, this example can be expressed in closed form
x = @(n)(abs(n).*(abs(n)<=3)); % assumes x(n) is zero for abs(n) > 3
x(-3:3)
ans = 1×7
3 2 1 0 1 2 3
x([-1 2])
ans = 1×2
1 2
If you have a finite duration sequence that can't be expressed in closed form, you can always just use indexing, accounting for Matlab's 1-based indexing.
x = abs(-3:3); n = -3:3;
x([-1 2]+(1-n(1)))
ans = 1×2
1 2
You can wrap this up in a function if desired, where n defines the sequence and k defines the elements of the sequence you want to return
xn = @(k,x,n)(x(k+(1-n(1))));
xn([-1 2],x,n)
ans = 1×2
1 2
xn(-1:1,x,n)
ans = 1×3
1 0 1

7 Comments

Really appreciate your answer!
I've tried out the code and it works properly.
However, if I wish to construct an arbitrary discrete function (that may not be able to be defined by expressions), such method does not seem to work?
Can you provide a simple example that illustrates what doesn't work?
For example
xn = [1 0 0 3 4 0 0 6 ]
^
Actually what I wanted to do is to be able to define an arbitrary discrete signal using anonymous function.
As shown above:
xn = @(k,x,n)(x(k+(1-n(1))));
x = [1 0 0 3 4 0 0 6]; % the sequence
n = -3:4; % its indices
% examples
xn(-3:4,x,n)
ans = 1×8
1 0 0 3 4 0 0 6
xn([-3 -2],x,n)
ans = 1×2
1 0
xn([-3 0 1],x,n)
ans = 1×3
1 3 4
Of course, this approach does not gracefully handle the situation where the requested indices are outside the bounds of the defined sequence
xn(-4,x,n)
Array indices must be positive integers or logical values.

Error in solution (line 1)
xn = @(k,x,n)(x(k+(1-n(1))));
Ah, I see.
Sorry that I didn't fully understand what did you mean by 'indexing' when I posted the previous comment.
Thanks a lot for clarifying!
You can also wrap up the sequence in a structure to simplify things a bit:
x.vals = [1 0 0 3 4 0 0 6];
x.indices = -3:4;
xn = @(n,sequence)(sequence.vals(n+(1-sequence.indices(1))));
xn([-3 0 1],x)
ans = 1×3
1 3 4

Sign in to comment.

Categories

Find more on Mathematics in Help Center and File Exchange

Products

Release

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!