# Why do I get Array indices must be positive integers or logical values?

5 views (last 30 days)
Mya on 27 Nov 2021
Commented: Walter Roberson on 27 Nov 2021
fs=8000; % Sampling frequency
t=0:1/fs:1; % Time range
x(n)=2*sin(2*pi*(n/fs)); % Signal in time spectrum
figure(1)
subplot(3,1,1);
plot(n,x);
xlabel('Time (s)');
ylabel('Amplitude');
X=fft(x);
N=1000; %not show many details, only 101 points
n = (0:1:N-1);
subplot(3,1,2)
plot(n,abs(X))
xlabel('Frequency (Hz)');
ylabel('Amplitude');
Mya on 27 Nov 2021
fs=8000; % Sampling frequency
n=0:1/fs:1; % Time range
x(n)=2*sin(2*pi*(n/fs)); % Signal in time spectrum
figure(1)
subplot(3,1,1);
plot(n,x);
xlabel('Time (s)');
ylabel('Amplitude');
X=fft(x);
N=1000; %not show many details, only 101 points
n = (0:1:N-1);
subplot(3,1,2)
plot(n,abs(X))
xlabel('Frequency (Hz)');
ylabel('Amplitude');
% I think supposed t should be replaced by n?

Walter Roberson on 27 Nov 2021
n=0:1/fs:1; % Time range
x(n)=2*sin(2*pi*(n/fs)); % Signal in time spectrum
You have confused two different concepts.
In mathematics, it is common to write something like f(x) = x^2 + 1, and to have that be defining a mathematical transformation between input values and output values. Some authors prefer to write something like to make it clear that you are defining a mapping. This notation is formula notation.
In programming, it is common to write something like f(5) = x^2 + 1, with the intention that the current value of x is squared, one is added, and that the result is to be stored in the vector f indexed at location 5. [Depending on the programming language, that might be the 5th element of f, or might be the 6th element of x, or might perhaps be at some other offset of f.]
In programming, writing f(x) = x^2 + 1 would typically be understood as using indexing notation -- that the current numeric value of x is to be looked up, x^2 + 1 calculated, and the result to be stored in vector f indexed at the locations whose offset is in x. But your x (n in your case) values are not integers, and not many programming languages allow you to index arrays at non-integer locations. Some programming languages allow you to index at 0 (or sometimes even a negative integer), but MATLAB does not permit that. Some programming language use [] notation for indexing -- as in f[5] = x^2 + 1.
So, in MATLAB, when you wrote
n=0:1/fs:1; % Time range
x(n)=2*sin(2*pi*(n/fs)); % Signal in time spectrum
you were asking to have MATLAB index a vector at locations 0, 1/fs, 2/fs, 3/fs and so on, and assign those locations the result of calculating 2*sin(2*pi*(n/fs)) with those definite fs values. But MATLAB does not permit indexing at 0 or non-integers.
In MATLAB, when you want to define a formula you should [usually] use anonymous functions, which would look like
x = @(n) 2*sin(2*pi*(n/fs));
This defines a formula -- and the @(n) says that inside the body of the formula, n should be replaced by whatever value is passed into the anonymous function at run time. Inside the @(n) definition, because n is inside the @(n) list, any value of n such as the n=0:1/fs:1 will be ignored.
But you should also consider just creating a vector:
x = 2*sin(2*pi*(n/fs));
This will take the current definite numeric values of n and calculate the sin and so on for them, and put the vector of values into x -- which will be an array not a formula.
There is one case where you can use f(x)=x^2+1 type of notation with MATLAB: if you are using symbolic variables.
syms x
f(x) = x^2+1
This requires x to have been defined as symbolic before the assignment. The result is a symbolic function, as if you had done
syms x
f = symfun(x^2+1, x);
Walter Roberson on 27 Nov 2021
No. Your x/fs is still (very likely) wrong, and you are still using a time coordinate to plot a frequency signal. You do not use n after you assign to it.
The code I posted handles frequency correctly (at least in the case where there is an odd number of points); see the first example in the fft() documentation for a better way to calculate frequency.