信号的重建
1、原理
完成了时间轴的离散和幅值轴的量化后,这个问题貌似已经解决,但在实践过程中就会发现,即使按照信号采样定理完成信号的采样,信号显示的结果也可能会与原始信号相差甚远。这是为什么?有无办法改善这种巨大差异?当然,差异是可以改善的,否则采样定理就没用了,秘籍就是下面不算太复杂的公式。
x(t)=∑n=−∞+∞x(nΔ)sin((t−nΔ)1Δ)(t−nΔ)1Δx(t)=∑n=−∞+∞x(nΔ)sin((t−nΔ)1Δ)(t−nΔ)1Δ
上式中的tt是连续的量,将个采样点的离散值与连续量相乘就可重建原来的信号。
但由于计算机中只有离散和有限长的量,所以我们还要用间隔更小的时间离散量ykyk来代替连续时间量tt,要注意的是上式中xnxn是离散的量,而ykyk则是时间间隔更小的离散量,这个公式完成的运算就是从向量x⃗ x→转换到向量y⃗ y→,如何完成这样的转换呢?这就需要一个矩阵帮助实现这种变换,可以讨论一下矩阵的构造方法。
- 蛮力
在每个xkxk对应时间点都计算相应sincsinc值,费时费力 - 巧劲 不走重复路
只是计算一次,剩下的从第一次计算的值出发,延伸导出。
2、CSignal添加信号重构行为 蛮力方法
function ReConstruct(sig)
vec = sig.m_vec;
dFs = sig.m_dFs;
tStart = sig.m_tStart;
deltaT = 1/dFs;
dReFs = sig.m_dFs*50;
t = tStart + (0:length(vec)-1)*deltaT;
tRec = tStart:1/dReFs:((length(vec)-1)*deltaT);
vecRec = zeros(1,length(tRec));
figure(3)
for ind = 0:length(vec)-1
vecRecTmp = sinc((tRec - ind*deltaT)/deltaT);
vecRec = vecRec + vec(ind+1)*vecRecTmp;
plot(tRec, vecRec)
pause;
end
figure(2)
plot(t,vec, 'r:', tRec,vecRec, 'k-', 'linewidth', 2)
xlabel('Time s','fontsize', 14)
ylabel('Amplitude','fontsize', 14)
set(gca, 'fontsize', 14)
legend('²ÉÑù','ÖØ¹¹')
end
3、script程序 使用类
% sigProcess01.m
% signal process exercise
close all;
clc;
dFreq = 0.5;
dFs = 2.2*dFreq;
tStart = 0;
t = tStart:1/dFs:10;
vec = cos(2*pi*dFreq*t);
sig = CSignal(vec, dFs, tStart);
sig.ReConstruct;
4、新的成员函数
function [vecTRecnt, vecSigRecnt] = ReconstructSig(varargin)
if nargin == 1
obj = varargin{1};
nMultpRecnt = 10;
else
obj = varargin{1};
nMultpRecnt = varargin{2};
end
dFsRecnt = obj.m_dFs*nMultpRecnt;
vecTRecnt = 0:1/dFsRecnt:obj.m_dTime;% for calculate xtSinc
xtSinc = sinc(obj.m_dFs*vecTRecnt);
vecSigRecnt = zeros(1, length(vecTRecnt));
vecSig = obj.m_vecSig;
for ind = 1:length(obj.m_vecSig)
% calculate sinc only once
if ind == 1
vecSigRecntTmp = xtSinc;
else
indexXtSincPre = ((ind-1)*nMultpRecnt+1):-1:2;
indexXtSincPost = 1:(length(xtSinc)-(ind-1)*nMultpRecnt);
vecSigRecntTmp = [xtSinc(indexXtSincPre) xtSinc(indexXtSincPost)];
end
% % calculate sinc every loop
% vecSigRecntTmp = sinc(dFs*vecTRecnt - ind + 1);
vecSigRecnt = vecSigRecnt + vecSig(ind)*vecSigRecntTmp;
end
% correspond to the time vector of signal
vecTRecnt = obj.m_dTimeStart*ones(1,length(vecTRecnt)) + vecTRecnt;
vecOrig = obj.m_vecSig;
t_orig = (0:length(vecOrig)-1)/obj.m_dFs;
figure;
plot(vecTRecnt, vecSigRecnt, t_orig, vecOrig, 'linewidth',2)
xlabel('时间 S')
ylabel('信号')
legend('插值后','未插值')
end
5、新的SCRIPT程序
% Exer_SigProcess_xcript.m
close all;
strCurrentPath = cd;
addpath([strCurrentPath '\classdef']);
vecAmp=[1 3 5];
vecFreq = [1 2 3];
vecPhi = [0 pi/3 pi/4];
Fs = 4.3;
t = 0:1/Fs:2*pi;
xt = 0;
for ind = 1:1
xt = xt + vecAmp(ind)*cos(2*pi*vecFreq(ind)*t + vecPhi(ind));
end
sig = CSignal(Fs, xt);
sig.DispSigCurve;
[vecTRecnt, vecSigRecnt] = sig.ReconstructSig(20);
rmpath([strCurrentPath '\classdef']);
程序运行结果