一、时域中的离散时间信号:
1, 序列的产生
在Matlab中,可以用一个具有适当值的行向量来表示一个有限长序列。准确的表示x[n]需要有两个向量,分别表示x和n。例如序列:
n = [-3,-2,-1,0,1,2,3,4];x = [2,1,-1,0,1,4,3,7];
当样本的位置信息不要求、或不重要时(如序列在n=0开始时),可只用x向量表示。由于有限的存储空间限制,一个任意无限长序列不能用Matlab表示。
(1)单位样本序列:
在Matlab中,函数zeros(1,N)产生一个具有N个零的行向量,利用它可以实现在一个有限区间上的不过,逻辑关系式n==0也是实现
的一种好方法。
产生长度为N的单位样本序列:
u = [1 zeros(1,N-1)];
产生延时M个样本且长度为N的单位样本序列(M<N):
ud = [zeros(1,M) 1 zeros(1,N-M-1)];
或,在区间 上实现
(平移n_0个样本的单位样本序列)可使用如下函数:
function [x,n] = impseq(n0,n1,n2)
% Generates x(n) = delta(n-n0); n1 <= n <= n2
% ----------------------------------------------
n = [n1:n2];
x = [(n-n0) == 0];
例:产生并绘制一个单位样本序列。
% Generation of a Unit Sample Sequence
clf; %清空
% Generate a vector from -10 to 20 %产生一个从-10到20的向量
n = -10:20;
% Generate the unit sample sequence 产生单位样本序列
u = [zeros(1,10) 1 zeros(1,20)];
% Plot the unit sample sequence %绘制图像
stem(n,u); % stem(X,Y) 在 X 指定的值的位置绘制数据序列 Y。X 和 Y 输入必须是大小相同的向量或矩阵。另外,X 可以是行或列向量,Y 必须是包含 length(X) 行的矩阵。
xlabel('Time index n');ylabel('Amplitude');
title('Unit Sample Sequence');
axis([-10 20 0 1.2]);
注意:
(1)clear、close、clc、clf的用法
clear Clear variables and functions from memory. 清除工作空间的所有变量
close Close figure. 关闭当前的figure窗口
clc Clear command window. 清空命令行窗口
clf Clear current figure. 清除当前的figure窗口
(2)type和edit的区别:
Type List program file.
Edit Edit or create a file.
(3)单行注释:%
多行注释:%{ 和 %}必须各自在的一单独行才行。例如:
%{
This next block of code checks the
……
processing the data.
%}
(2)单位阶跃序列:
产生长度为N的单位阶跃序列:
S = [ones(1,N)];
或:
function [x,n] = stepseq(n0,n1,n2)
% Generates x(n) = u(n-n0); n1 <= n <= n2
% ------------------------------------------
n = [n1:n2]; x = [(n-n0) >= 0];
(3)指数序列:
Matlab中的exp函数可用来产生指数序列。如n = [0:10]; x = (0.9).^n;产生实指数序列,而n = [0:10]; x = exp((2+3j)*n);产生复指数序列。
例:产生一个复指数信号。
% Generation of a complex exponential sequence
clf;
c = -(1/12)+(pi/6)*i;
K = 2;
n = 0:40;
x = K*exp(c*n);
subplot(2,1,1); % subplot(m,n,p) 将当前图窗划分为 m×n 网格,并在 p 指定的位置创建坐标区。MATLAB® 按行号对子图位置进行编号。第一个子图是第一行的第一列,第二个子图是第一行的第二列,依此类推。如果指定的位置已存在坐标区,则此命令会将该坐标区设为当前坐标区。
stem(n,real(x)); %real()返回数组的实部
xlabel('Time index n');ylabel('Amplitude');
title('Real part');
subplot(2,1,2);
stem(n,imag(x)); %返回数组的虚部
xlabel('Time index n');ylabel('Amplitude');
title('Imaginary part');
例:产生一个实指数信号。
% Generation of a real exponential sequence
clf;
n = 0:35; a = 1.2; K = 0.2;
x = K*a.^n;
stem(n,x);
xlabel('Time index n');ylabel('Amplitude');
(4)正弦序列:
Matlab中的cos或sin函数可用于产生正弦序列,如n = [0:10]; x = 3*cos(0.1*pi*n+pi/3) + 2*sin(0.5*pi*n);
例:产生一个实正弦信号。
% Generation of a sinusoidal sequence
n = 0:40;
f = 0.1;
phase = 0;
A = 1.5;
arg = 2*pi*f*n - phase;
x = A*cos(arg);
clf; % Clear old graph
stem(n,x); % Plot the generated sequence
axis([0 40 -2 2]);
grid;
title('Sinusoidal Sequence');
xlabel('Time index n');
ylabel('Amplitude');
axis;
注意:连续时间信号与离散时间信号中“频率”的概念:
对于连续时间正弦信号
A1,对于每一个固定的频率值F,x(t)是周期的。
A2,具有不同频率的连续时间正弦信号是可以区分的。
A3,增大频率F会导致信号振荡速率增大,也即在给定的时间间隔内包含更多的周期。
对于离散时间正弦信号 :
B1,一个离散时间正弦信号当且仅当其频率f是有理数(两个整数的比值)时才是周期的。由于f=r/N,可以看出,较小的频率改变会导致周期的较大改变。例如,f1=31/60意味着N1=60,而f2=30/60导致N2=2。
B2,频率相差2π整数倍的离散时间正弦相同。
B3,当 或
时离散时间正弦的振荡速率最大。通常选择
或 称为基本范围(fundamental range)。
(5)随机信号:
产生一个长度为N的、在区间(0,1)中均匀分布的随机信号:
x = rand(1,N);
产生一个长度为N且具有零均值和单位方差的正态分布的随机信号:
x = randn(1,N);
(6)周期信号:
要从一个长度为N的序列x[n]产生P个周期,可将x[n]重复P次:
xtilde=[x,x,…,x];
或者,先产生包含x[n]值的P行矩阵,然后利用“:”将P行连成一个长的行向量。
x=rand(1,10);
xtilde = x' * ones(1,3)
xtilde = xtilde(:); % long column vector A(:) 将 A 中的所有元素重构成一个列向量。如果 A 已经是列向量,则此表达式没有任何作用。
xtilde = xtilde';
1, 序列的运算
(1)信号相加
如果两个序列长度不同,或者长度相同但采样位置不同,则不能直接相加。
function [y,n] = sigadd(x1,n1,x2,n2)
% implements y(n) = x1(n)+x2(n)
% -----------------------------
% y = sum sequence over n, which includes n1 and n2 (n上的求和序列,包括n1和n2)
% x1 = first sequence over n1 (n1上的第一个序列)
% x2 = second sequence over n2 (n2 can be different from n1) (n2上的第二个序列(n2可以不同于n1))
%
n = min(min(n1),min(n2)):max(max(n1),max(n2)); % duration of y(n)
(yn的持续时间)
y1 = zeros(1,length(n)); y2 = y1; % initialization
y1(find((n>=min(n1))&(n<=max(n1))==1))=x1; % x1 with duration of y (持续时间为y的x1)
y2(find((n>=min(n2))&(n<=max(n2))==1))=x2; %
x2 with duration of y (持续时间为y的x2)
y = y1+y2; % sequence addition
(2)信号相乘(乘积)
function [y,n] = sigmult(x1,n1,x2,n2)
% implements y(n) = x1(n)*x2(n)
% -----------------------------
% y = product sequence over n, which includes n1 and n2
% x1 = first sequence over n1
% x2 = second sequence over n2 (n2 can be different from n1)
n =
min(min(n1),min(n2)):max(max(n1),max(n2)); % duration of y(n)
y1 = zeros(1,length(n)); y2 = y1; %
y1(find((n>=min(n1))&(n<=max(n1))==1))=x1; % x1 with duration of y
y2(find((n>=min(n2))&(n<=max(n2))==1))=x2; % x2 with duration of y
y = y1 .* y2; % sequence multiplication
(3)移位/时移
将x[n]中的每一个样本都位移k得到y[n]=x[n-k],若令m=n-k,那么n=m+k,上述运算变为y[m+k]=x[m],所以这个运算对向量x没有影响,但向量n的每个元素都要改变即加k。
function [y,n] = sigshift(x,m,k)
% implements y(n) = x(n-k)
% -------------------------
n = m+k; y = x;
(4)反转
将x[n]中的每个样本都以n=0为中心翻转得到一个反转序列y[n]。在Matlab中,该运算对序列的样本值用函数filplr(x)实现,对样本位置用函数-fliplr(n)来实现:
function [y,n] = sigfold(x,n)
% implements y(n) = x(-n)
% -----------------------
y = fliplr(x); n = -fliplr(n);
(5)信号能量
在Matlab中,有限长序列x[n]的能量计算如下:
Ex = sum(x .* conj(x)); % one approach 一种方法
Ex = sum(abs(x) .^ 2); % another approach 另一种方法
注:上角标*代表复数共轭运算。在DSP中,符号*表示许多运算,通过其字体和位置来区分。
练习题:
1,产生复值序列 ,并分别画出它的幅度、相位、实部和虚部。
clc clear %表示 n = [-10:10]; alpha = -0.1 + 0.3j; x = exp(alpha*n); %绘制实部 subplot(2,2,1); stem(n,real(x),'filled'); title('real part'); xlabel('n'); ylim([-3,1.5]); %绘制虚部 subplot(2,2,2); stem(n,imag(x),'filled'); title('imaginary part'); xlabel('n'); %绘制幅值 subplot(2,2,3); stem(n,abs(x),'filled'); title('magnitude part'); xlabel('n'); %绘制相位 subplot(2,2,4); stem(n,(180/pi)*angle(x),'filled'); title('phase part'); xlabel('n');