目录
序
在数字信号处理中,离散信号由序列表示,则离散信号的运算表现在序列上就是序列的各种运算,信号的基本运算包括加法、乘法、加权﹑移位、翻转、尺度变换、卷积等。
基本运算
一、加法
将两序列相加 x(n)= x1(n) + x2 (n),在 MATLAB 中可用 “+” 来实现,但是 x1(n)和 x2(n)的长度必须相同,如果序列长度不同,或者长度相同的序列而样本位置不同,也不能直接用算符+。首先必须对 x1(n)和 x2(n)扩大或延长以使它们具有相同位置的向量 n。我们有两种方法解决这个问题。下面利用一个简单的例子详细解释两种方法。
例一:已知序列: 。
。用 MATLAB 编程计算 y1=x1(n)+x 2 (n) 并画出其序列波形。
方法一:根据已知的条件,利用MATLAB数组的表达方式,直接将两信号中较短的信号延长至我们需要的信号,更为直接而简单。
MATLAB代码如下:
n1=0:10;
x1=n1.^2-n1;
n2=-5:15;
x2=-n2.^2+n2;
x3=[zeros(1,(min(n1)-min(n2))) x1 zeros(1,(max(n2)-max(n1)))];%利用zeros函数,将x1信号延长至和x2相同的长度
y=x3+x2;
subplot(3,1,1),stem(n2,x3);%画图
xlabel('n2');title('x3')
subplot(3,1,2),stem(n2,x2);
xlabel('n2');title('x2')
subplot(3,1,3),stem(n2,y);
xlabel('index');ylabel('sum');title('x1+x2')
效果如下:
方法二:自定义sigadd函数,实现输入任意两个离散信号,输出结果为两信号的相加和。然后在主函数中调用该函数。
MATLAB代码如下:
自定义函数:
function [y,n] = sigadd(x1,n1,x2,n2)
%实现序列相加
% 实现y(n)=x1(n)+x2(n)
% [y,n ]=sigadd(x1 ,n1,x2,n2)
n = min(min(n1),min(n2)):max(max(n1),max(n2));
y1 = zeros(1,length(n));
y2=y1;
y1 ( (n>=min (n1) ) & (n<=max (n1) )==1 )=x1 ;
y2 ( (n>=min (n2) ) & (n<=max (n2) )==1 )=x2 ;
y=y1+y2;
end
主函数:
n1=0:10;%定义信号x1
x1=n1.^2-n1;
n2=-5:15;%定义信号x2
x2=-n2.^2+n2;
[y,n]=sigadd(x1,n1,x2,n2);%调用函数sigadd
subplot(3,1,1),stem(n1,x1);%画图
xlabel('n1');title('x1')
subplot(3,1,2),stem(n2,x2);
xlabel('n2');title('x2')
subplot(3,1,3),stem(n2,y);
xlabel('index');ylabel('sum');title('x1+x2')
效果如下:
二、乘法
相乘 x(n)= x1(n)*x2 (n)
可用“.*”
实现,但是同样要注意两个信号需要长度和位置都相同
,对此我们只需要把之前的代码改动相加的那一部分即可
。
例二:已知序列:
;
。求y=x1*x2。
MATLAB代码如下:
自定义sigmult函数:
function [y,n] = sigmult(x1,n1,x2,n2)
%实现序列相加
% 实现y(n)=x1(n)+x2(n)
% [y,n ]=sigadd(x1 ,n1,x2,n2)
n = min(min(n1),min(n2)):max(max(n1),max(n2));
y1 = zeros(1,length(n));
y2=y1;
y1 ( (n>=min (n1) ) & (n<=max (n1) )==1 )=x1 ;
y2 ( (n>=min (n2) ) & (n<=max (n2) )==1 )=x2 ;
y=y1.*y2;
end
主函数:
n1=-10:30;
n2=-20:20;
w=pi/20;
a=1.05;
x1=sin(w.*n1);
x2=a.^n2;
y=sigmult(x1,n1,x2,n2);
subplot(3,1,1)
stem(x1);title('x1');
subplot(3,1,2)
stem(x2);title('x2');
subplot(3,1,3)
stem(n,y);xlabel('index');ylabel('mult');title('x1*x2');
效果如下:
三、 加权及尺度变换
加权就是在信号前面乘以一个常数,尺度变换则是对自变量n进行变换,通常是乘以一个常数。
MATLAB代码如下:
自定义sigdouble函数
function [y,n] = sigdouble(x1,n1,a,b)
%sigdouble 序列加权和尺度变换
% 在此运算中,每个采样值乘以一个常数a,每一个自变量乘以一个常数b。
% a{x(n)}= {ax(n)}
% x(n)->x(bn)
n=b*n1;
y=a*x1;
end
主函数:
n1=-5:15;
a=2;b=4;
x1=sin(n1);
[y,n]=sigdouble(x1,n1,a,b);
subplot(2,1,1);
plot(n1,x1),title('x1');grid on
subplot(2,1,2);
plot(n,y),title('y');grid on
效果如下:(注意横纵坐标的变化)
四、移位
顾名思义,移位就是将信号在时域上左右平移需要的位数。可以通过自定义函数sigshift实现。
MATLAB代码如下:
自定义sigshift函数:
function [y,n] = sigshift(x,m,n0)
%实现y(n)=x(n-n0)
%移位--在此运算中,x (n)的每一个样本都移动n0个周期,移位后的序列y (n)如下。
n=m+n0;
y=x;
end
主函数:
n1=-5:15;
a=10;
x1=sin(n1);
[y,n]=sigshift(x1,n1,a);
subplot(2,1,1);
plot(n1,x1),title('x1');grid on
subplot(2,1,2);
plot(n,y),title('y');grid on
效果如下:(注意横纵坐标的变化)
五、翻转
翻转就是y(n)=x1(-n) 。样本值可由函数 fliplr(x)
实现,翻转序列
y(n)
可由函数[y,n]=sigfold(x,n)实现。
MATLAB代码如下:
自定义sigfold函数:
function [y,n] = sigfold(x,n0)
%序列翻转运算
%在此运算中,x (n)的每个样本都对n=0翻转,得到一个折叠后的序列y(n)
%y(n)={x(-n)}
y=fliplr(x);
n=-max(n0):-min(n0);
end
主函数:
n1=-5:15;
x1=n1.^2+n;
[y,n]=sigfold(x1,n1);
subplot(2,1,1);
plot(n1,x1),title('x1');grid on
subplot(2,1,2);
plot(n,y),title('y');grid on
效果如下:
六、卷积运算
有限长序列卷积有两种形式:线性卷积和圆周卷积。时域圆周卷积在频域上为两序列的DFT 相乘,因而有限长序列的圆周卷积可以在时域直接计算,也可以在频域中计算。由于DFT 有快速算法
(FFT)
,当
N
很大时在频域计算的速度上具有很大优越性。然而现实中要解决的实际问题是要计算两个有限长序列的线性卷积,如信号通过线性系统,系统的输出 y(n)是输入信号 x(n)
与系统抽样响应
h(n)
的线性卷积:
y
(
n
)=
x
(
n
)*
h
(
n
)
。
卷积 y(n)= x1(n)*x2 (n)
可由函数
y=conv(x,h)
实现。这里要注意的是:
conv 函数默认两个序列都是从n=0 开始
。其简单扩展
conv_m
能完成任意位置序列的卷积。
这里我们主要研究信号的线性卷积(
圆周卷积后面会单独写一篇文章来介绍),下面举一个例子具体说明:
例三:若两序列:
,长度为3;
计算两序列的线性卷积。
MATLAB代码如下:
N1=3;N2=4;
n1=0:N1-1;n2=0:N2-1;
x1=zeros(1,N1);
x2=zeros(1,N2);
x1(2)=1+2; x1(3)=3; %根据题目要求定义出x1及x2
x2(1)=4; x2(2)=3+1; x2(3)=1;
y1=conv(x1,x2); %计算线性卷积
n01=min(n1)+min(n2);
n02=max(n1)+max(n2);
ny=(n01:n02);
subplot(311),stem(n1,x1,'.');title('x1(n)'); %绘制图像
subplot(312),stem(n2,x2,'.');title('x2(n)');
subplot(313),stem(ny,y1,'.');title('线性卷积');
效果如下: