Matlab 到 Python 代码转换 - 输出不匹配
Matlab to Python Code Conversion - Output isnot matching
我已成功将 MATLAB 源代码转换为 Python - 但绘图输出不匹配。我已经双重验证了 Python 和 Octave 中每个变量 bot 的值——它们也都相同。
倍频图输出:
Python Matplotlib 输出:
八度代码:
clear
N = 10^3; % number of symbols
am = 2*(rand(1,N)>0.5)-1 + j*(2*(rand(1,N)>0.5)-1); % generating random binary sequence
fs = 10; % sampling frequency in Hz
% defining the sinc filter
sincNum = sin(pi*[-fs:1/fs:fs]); % numerator of the sinc function
sincDen = (pi*[-fs:1/fs:fs]); % denominator of the sinc function
sincDenZero = find(abs(sincDen) < 10^-10);
sincOp = sincNum./sincDen;
sincOp(sincDenZero) = 1; % sin(pix/(pix) =1 for x =0
% raised cosine filter
alpha = 0.5;
cosNum = cos(alpha*pi*[-fs:1/fs:fs]);
cosDen = (1-(2*alpha*[-fs:1/fs:fs]).^2);
cosDenZero = find(abs(cosDen)<10^-10);
cosOp = cosNum./cosDen;
cosOp(cosDenZero) = pi/4;
gt_alpha5 = sincOp.*cosOp;
alpha = 1;
cosNum = cos(alpha*pi*[-fs:1/fs:fs]);
cosDen = (1-(2*alpha*[-fs:1/fs:fs]).^2);
cosDenZero = find(abs(cosDen)<10^-10);
cosOp = cosNum./cosDen;
cosOp(cosDenZero) = pi/4;
gt_alpha1 = sincOp.*cosOp;
% upsampling the transmit sequence
amUpSampled = [am;zeros(fs-1,length(am))];
amU = amUpSampled(:).';
% filtered sequence
st_alpha5 = conv(amU,gt_alpha5);
st_alpha1 = conv(amU,gt_alpha1);
% taking only the first 10000 samples
st_alpha5 = st_alpha5([1:10000]);
st_alpha1 = st_alpha1([1:10000]);
st_alpha5_reshape = reshape(st_alpha5,fs*2,N*fs/20).';
st_alpha1_reshape = reshape(st_alpha1,fs*2,N*fs/20).';
close all
figure;
st_alpha5_reshape
plot([0:1/fs:1.99],real(st_alpha5_reshape).','b');
title('eye diagram with alpha=0.5');
xlabel('time')
ylabel('amplitude')
axis([0 2 -1.5 1.5])
grid on
figure;
plot([0:1/fs:1.99],real(st_alpha1_reshape).','b');
title('eye diagram with alpha=1')
xlabel('time')
ylabel('amplitude')
axis([0 2 -1.5 1.5 ])
grid on
Python代码:
j = np.complex(0,1)
N = 10**3
#% number of symbols
am = 2.*(np.random.rand(1., N) > 0.5)-1.+np.dot(j, 2.*(np.random.rand(1., N) > 0.5)-1.)
#% generating random binary sequence
fs = 10.
#% sampling frequency in Hz
#% defining the sinc filter
sincNum = np.sin(np.dot(np.pi, np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs))))))
#% numerator of the sinc function
sincDen = np.dot(np.pi, np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs)))))
#% denominator of the sinc function
sincDenZero = np.where(abs(sincDen) < 10**-10);
sincOp=sincNum/sincDen
sincOp[int(sincDenZero[0])-1] = 1.
#% raised cosine filter
alpha = 0.5
cosNum = np.cos(np.dot(np.dot(alpha, np.pi), np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs))))))
cosDen = 1.-np.dot(2.*alpha, np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs)))))**2.
cosDenZero = np.where(abs(cosDen)<10**-10);
cosOp = cosNum/cosDen
cosOp[int(cosDenZero[0][0])-1] = np.pi/4.
cosOp[int(cosDenZero[0][1])-1] = np.pi/4.
gt_alpha5 = sincOp*cosOp
alpha = 1.
cosNum = np.cos(np.dot(np.dot(alpha, np.pi), np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs))))))
cosDen = 1.-np.dot(2.*alpha, np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs)))))**2.
cosDenZero = np.where(abs(cosDen)<10**-10);
cosOp = cosNum/cosDen
cosOp[int(cosDenZero[0][0])-1] = np.pi/4.
cosOp[int(cosDenZero[0][1])-1] = np.pi/4.
gt_alpha1 = sincOp*cosOp
#% upsampling the transmit sequence
#amUpSampled = np.array(np.vstack((np.hstack((am)), np.hstack((np.zeros((fs-1.), len(am)))))))
amUpSampled = np.append(am,np.zeros((fs-1,am.size)))
amU = amUpSampled.flatten(0)
#% filtered sequence
st_alpha5 = np.convolve(amU, gt_alpha5)
st_alpha1 = np.convolve(amU, gt_alpha1)
#% taking only the first 10000 samples
st_alpha5 = st_alpha5[0:10000:1]
st_alpha1 = st_alpha1[0:10000:1]
#st_alpha5_reshape = np.reshape(st_alpha5, (fs*2.), (np.dot(N, fs)/20.)).T
st_alpha5_reshape = np.reshape(st_alpha5, (-1,500)).T
#st_alpha1_reshape = np.reshape(st_alpha1, (fs*2.), (np.dot(N, fs)/20.)).T
st_alpha1_reshape = np.reshape(st_alpha1, (-1,500)).T
plt.close('all')
plt.figure(1)
plt.plot(np.array(np.hstack((np.arange(.1, (1.99)+(1./fs), 1./fs)))), np.real(st_alpha5_reshape).T, 'b')
plt.title('eye diagram with alpha=0.5')
plt.xlabel('time')
plt.ylabel('amplitude')
plt.axis(np.array(np.hstack((0., 2., -1.5, 1.5))))
plt.grid('on')
plt.figure(2)
plt.plot(np.array(np.hstack((np.arange(.1, (1.99)+(1./fs), 1./fs)))), np.real(st_alpha1_reshape).T, 'b')
plt.title('eye diagram with alpha=1')
plt.xlabel('time')
plt.ylabel('amplitude')
plt.axis(np.array(np.hstack((0., 2., -1.5, 1.5))))
plt.grid('on')
plt.show()
请让我知道问题出在哪里以及修复方法是什么 Python 仅限代码?
几件事。尽管您说的是 "I have doubly verified the values of each variables bot in Python and Octave - both of them are same also."——但事实并非如此。
首先,当您从 MATLAB 移植到 numpy 时,有 次需要从索引中减去 1,但您的代码没有这些。
所以到处都有这样的东西:
sincOp[int(sincDenZero[0])-1] = 1.
改为
sincOp[int(sincDenZero[0])] = 1
简而言之,这是因为 np.where
的输出已经是 0 索引的,所以当你减去 1 时,你就过度补偿了。
接下来,您到处都使用 np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs))))
,所以让我们创建一个变量并构建一次:
fsrange = np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs))))
但这只能是:
fsrange = np.arange(-fs, fs+(1./fs), 1./fs)
同样,这条巨大的线:
cosNum = np.cos(np.dot(np.dot(alpha, np.pi), np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs))))))
可以是:
cosNum = np.cos(alpha * np.pi * fsrange)
还有这一行:
amUpSampled = np.append(am,np.zeros((fs-1,am.size)))
应该只是(所以你不修改 am
,并正确指定 args 到 zeros
):
amUpSampled = np.vstack([ am, np.zeros([(fs-1.), am.size]) ])
您在此处指定了错误的展平顺序:
amU = amUpSampled.flatten(0)
应该使用 FORTRAN 命令(MATLAB 使用的命令)将其展平:
amU = amUpSampled.flatten('F')
整形时也是一样,需要指定FORTRAN顺序:
st_alpha5_reshape = np.reshape(st_alpha5, [(fs*2.), (N * fs / 20.)], 'F').T
st_alpha1_reshape = np.reshape(st_alpha1, [(fs*2.), (N * fs / 20.)], 'F').T
因此,您更正后的 python 代码应如下所示:
import numpy as np
import matplotlib.pyplot as plt
j = np.complex(0,1)
N = 10**3
#% number of symbols
am = 2.*(np.random.rand(1., N) > 0.5)-1.+np.dot(j, 2.*(np.random.rand(1., N) > 0.5)-1.)
#% generating random binary sequence
fs = 10.
fsrange = np.arange(-fs, fs+(1./fs), 1./fs)
#% sampling frequency in Hz
#% defining the sinc filter
sincNum = np.sin(np.dot(np.pi, fsrange))
#% numerator of the sinc function
sincDen = np.dot(np.pi, fsrange)
#% denominator of the sinc function
sincDenZero = np.where(np.abs(sincDen) < 10**-10);
sincOp=sincNum/sincDen
sincOp[int(sincDenZero[0])] = 1.
#% raised cosine filter
alpha = 0.5
cosNum = np.cos(alpha * np.pi * fsrange)
cosDen = 1.-np.dot(2.*alpha, fsrange)**2.
cosDenZero = np.nonzero(abs(cosDen)<10**-10);
cosOp = cosNum/cosDen
cosOp[int(cosDenZero[0][0])] = np.pi/4.
cosOp[int(cosDenZero[0][1])] = np.pi/4.
gt_alpha5 = sincOp*cosOp
alpha = 1.
cosNum = np.cos(alpha * np.pi * fsrange)
cosDen = 1.-np.dot(2.*alpha, fsrange)**2.
cosDenZero = np.where(abs(cosDen)<10**-10);
cosOp = cosNum/cosDen
cosOp[int(cosDenZero[0][0])] = np.pi/4.
cosOp[int(cosDenZero[0][1])] = np.pi/4.
gt_alpha1 = sincOp*cosOp
#% upsampling the transmit sequence
amUpSampled = np.vstack([ am, np.zeros([(fs-1.), am.size]) ])
amU = amUpSampled.flatten('F')
#% filtered sequence
st_alpha5 = np.convolve(amU, gt_alpha5)
st_alpha1 = np.convolve(amU, gt_alpha1)
#% taking only the first 10000 samples
st_alpha5 = st_alpha5[0:10000]
st_alpha1 = st_alpha1[0:10000]
st_alpha5_reshape = np.reshape(st_alpha5, [(fs*2.), (N * fs / 20.)], 'F').T
st_alpha1_reshape = np.reshape(st_alpha1, [(fs*2.), (N * fs / 20.)], 'F').T
plt.close('all')
X = np.arange(0,1.99, 1.0/fs)
plt.figure(1)
plt.plot(X, np.real(st_alpha5_reshape).T, 'b')
plt.title('eye diagram with alpha=0.5')
plt.xlabel('time')
plt.ylabel('amplitude')
plt.axis(np.array(np.hstack((0., 2., -1.5, 1.5))))
plt.grid('on')
plt.figure(2)
plt.plot(X, np.real(st_alpha1_reshape).T, 'b')
plt.title('eye diagram with alpha=1')
plt.xlabel('time')
plt.ylabel('amplitude')
plt.axis(np.array(np.hstack((0., 2., -1.5, 1.5))))
plt.grid('on')
plt.show()
生成您期望的数字。
旁注:
如果您在 MATLAB 中有一个 array/matrix(假设它被称为 varname
),您可以使用 save varname
(在 MATLAB 中)将其保存到 .mat 文件中。
然后您可以将 array/matrix 加载到 python 中:
import scipy.io
mat = scipy.io.loadmat("<path of .mat file>")
varname = mat[varname]
您也可以对整个 MATLAB 工作区执行此操作,只需使用 save
——在 python 中,mat
仍然只是一个由变量名称键入的字典,因此您d 像上面那样访问各个工作区变量。
您可以使用它来逐步验证 numpy 生成的内容与您期望的生成内容,并找出您做错了什么。
我已成功将 MATLAB 源代码转换为 Python - 但绘图输出不匹配。我已经双重验证了 Python 和 Octave 中每个变量 bot 的值——它们也都相同。
倍频图输出:
Python Matplotlib 输出:
八度代码:
clear
N = 10^3; % number of symbols
am = 2*(rand(1,N)>0.5)-1 + j*(2*(rand(1,N)>0.5)-1); % generating random binary sequence
fs = 10; % sampling frequency in Hz
% defining the sinc filter
sincNum = sin(pi*[-fs:1/fs:fs]); % numerator of the sinc function
sincDen = (pi*[-fs:1/fs:fs]); % denominator of the sinc function
sincDenZero = find(abs(sincDen) < 10^-10);
sincOp = sincNum./sincDen;
sincOp(sincDenZero) = 1; % sin(pix/(pix) =1 for x =0
% raised cosine filter
alpha = 0.5;
cosNum = cos(alpha*pi*[-fs:1/fs:fs]);
cosDen = (1-(2*alpha*[-fs:1/fs:fs]).^2);
cosDenZero = find(abs(cosDen)<10^-10);
cosOp = cosNum./cosDen;
cosOp(cosDenZero) = pi/4;
gt_alpha5 = sincOp.*cosOp;
alpha = 1;
cosNum = cos(alpha*pi*[-fs:1/fs:fs]);
cosDen = (1-(2*alpha*[-fs:1/fs:fs]).^2);
cosDenZero = find(abs(cosDen)<10^-10);
cosOp = cosNum./cosDen;
cosOp(cosDenZero) = pi/4;
gt_alpha1 = sincOp.*cosOp;
% upsampling the transmit sequence
amUpSampled = [am;zeros(fs-1,length(am))];
amU = amUpSampled(:).';
% filtered sequence
st_alpha5 = conv(amU,gt_alpha5);
st_alpha1 = conv(amU,gt_alpha1);
% taking only the first 10000 samples
st_alpha5 = st_alpha5([1:10000]);
st_alpha1 = st_alpha1([1:10000]);
st_alpha5_reshape = reshape(st_alpha5,fs*2,N*fs/20).';
st_alpha1_reshape = reshape(st_alpha1,fs*2,N*fs/20).';
close all
figure;
st_alpha5_reshape
plot([0:1/fs:1.99],real(st_alpha5_reshape).','b');
title('eye diagram with alpha=0.5');
xlabel('time')
ylabel('amplitude')
axis([0 2 -1.5 1.5])
grid on
figure;
plot([0:1/fs:1.99],real(st_alpha1_reshape).','b');
title('eye diagram with alpha=1')
xlabel('time')
ylabel('amplitude')
axis([0 2 -1.5 1.5 ])
grid on
Python代码:
j = np.complex(0,1)
N = 10**3
#% number of symbols
am = 2.*(np.random.rand(1., N) > 0.5)-1.+np.dot(j, 2.*(np.random.rand(1., N) > 0.5)-1.)
#% generating random binary sequence
fs = 10.
#% sampling frequency in Hz
#% defining the sinc filter
sincNum = np.sin(np.dot(np.pi, np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs))))))
#% numerator of the sinc function
sincDen = np.dot(np.pi, np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs)))))
#% denominator of the sinc function
sincDenZero = np.where(abs(sincDen) < 10**-10);
sincOp=sincNum/sincDen
sincOp[int(sincDenZero[0])-1] = 1.
#% raised cosine filter
alpha = 0.5
cosNum = np.cos(np.dot(np.dot(alpha, np.pi), np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs))))))
cosDen = 1.-np.dot(2.*alpha, np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs)))))**2.
cosDenZero = np.where(abs(cosDen)<10**-10);
cosOp = cosNum/cosDen
cosOp[int(cosDenZero[0][0])-1] = np.pi/4.
cosOp[int(cosDenZero[0][1])-1] = np.pi/4.
gt_alpha5 = sincOp*cosOp
alpha = 1.
cosNum = np.cos(np.dot(np.dot(alpha, np.pi), np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs))))))
cosDen = 1.-np.dot(2.*alpha, np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs)))))**2.
cosDenZero = np.where(abs(cosDen)<10**-10);
cosOp = cosNum/cosDen
cosOp[int(cosDenZero[0][0])-1] = np.pi/4.
cosOp[int(cosDenZero[0][1])-1] = np.pi/4.
gt_alpha1 = sincOp*cosOp
#% upsampling the transmit sequence
#amUpSampled = np.array(np.vstack((np.hstack((am)), np.hstack((np.zeros((fs-1.), len(am)))))))
amUpSampled = np.append(am,np.zeros((fs-1,am.size)))
amU = amUpSampled.flatten(0)
#% filtered sequence
st_alpha5 = np.convolve(amU, gt_alpha5)
st_alpha1 = np.convolve(amU, gt_alpha1)
#% taking only the first 10000 samples
st_alpha5 = st_alpha5[0:10000:1]
st_alpha1 = st_alpha1[0:10000:1]
#st_alpha5_reshape = np.reshape(st_alpha5, (fs*2.), (np.dot(N, fs)/20.)).T
st_alpha5_reshape = np.reshape(st_alpha5, (-1,500)).T
#st_alpha1_reshape = np.reshape(st_alpha1, (fs*2.), (np.dot(N, fs)/20.)).T
st_alpha1_reshape = np.reshape(st_alpha1, (-1,500)).T
plt.close('all')
plt.figure(1)
plt.plot(np.array(np.hstack((np.arange(.1, (1.99)+(1./fs), 1./fs)))), np.real(st_alpha5_reshape).T, 'b')
plt.title('eye diagram with alpha=0.5')
plt.xlabel('time')
plt.ylabel('amplitude')
plt.axis(np.array(np.hstack((0., 2., -1.5, 1.5))))
plt.grid('on')
plt.figure(2)
plt.plot(np.array(np.hstack((np.arange(.1, (1.99)+(1./fs), 1./fs)))), np.real(st_alpha1_reshape).T, 'b')
plt.title('eye diagram with alpha=1')
plt.xlabel('time')
plt.ylabel('amplitude')
plt.axis(np.array(np.hstack((0., 2., -1.5, 1.5))))
plt.grid('on')
plt.show()
请让我知道问题出在哪里以及修复方法是什么 Python 仅限代码?
几件事。尽管您说的是 "I have doubly verified the values of each variables bot in Python and Octave - both of them are same also."——但事实并非如此。
首先,当您从 MATLAB 移植到 numpy 时,有 次需要从索引中减去 1,但您的代码没有这些。
所以到处都有这样的东西:
sincOp[int(sincDenZero[0])-1] = 1.
改为
sincOp[int(sincDenZero[0])] = 1
简而言之,这是因为 np.where
的输出已经是 0 索引的,所以当你减去 1 时,你就过度补偿了。
接下来,您到处都使用 np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs))))
,所以让我们创建一个变量并构建一次:
fsrange = np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs))))
但这只能是:
fsrange = np.arange(-fs, fs+(1./fs), 1./fs)
同样,这条巨大的线:
cosNum = np.cos(np.dot(np.dot(alpha, np.pi), np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs))))))
可以是:
cosNum = np.cos(alpha * np.pi * fsrange)
还有这一行:
amUpSampled = np.append(am,np.zeros((fs-1,am.size)))
应该只是(所以你不修改 am
,并正确指定 args 到 zeros
):
amUpSampled = np.vstack([ am, np.zeros([(fs-1.), am.size]) ])
您在此处指定了错误的展平顺序:
amU = amUpSampled.flatten(0)
应该使用 FORTRAN 命令(MATLAB 使用的命令)将其展平:
amU = amUpSampled.flatten('F')
整形时也是一样,需要指定FORTRAN顺序:
st_alpha5_reshape = np.reshape(st_alpha5, [(fs*2.), (N * fs / 20.)], 'F').T
st_alpha1_reshape = np.reshape(st_alpha1, [(fs*2.), (N * fs / 20.)], 'F').T
因此,您更正后的 python 代码应如下所示:
import numpy as np
import matplotlib.pyplot as plt
j = np.complex(0,1)
N = 10**3
#% number of symbols
am = 2.*(np.random.rand(1., N) > 0.5)-1.+np.dot(j, 2.*(np.random.rand(1., N) > 0.5)-1.)
#% generating random binary sequence
fs = 10.
fsrange = np.arange(-fs, fs+(1./fs), 1./fs)
#% sampling frequency in Hz
#% defining the sinc filter
sincNum = np.sin(np.dot(np.pi, fsrange))
#% numerator of the sinc function
sincDen = np.dot(np.pi, fsrange)
#% denominator of the sinc function
sincDenZero = np.where(np.abs(sincDen) < 10**-10);
sincOp=sincNum/sincDen
sincOp[int(sincDenZero[0])] = 1.
#% raised cosine filter
alpha = 0.5
cosNum = np.cos(alpha * np.pi * fsrange)
cosDen = 1.-np.dot(2.*alpha, fsrange)**2.
cosDenZero = np.nonzero(abs(cosDen)<10**-10);
cosOp = cosNum/cosDen
cosOp[int(cosDenZero[0][0])] = np.pi/4.
cosOp[int(cosDenZero[0][1])] = np.pi/4.
gt_alpha5 = sincOp*cosOp
alpha = 1.
cosNum = np.cos(alpha * np.pi * fsrange)
cosDen = 1.-np.dot(2.*alpha, fsrange)**2.
cosDenZero = np.where(abs(cosDen)<10**-10);
cosOp = cosNum/cosDen
cosOp[int(cosDenZero[0][0])] = np.pi/4.
cosOp[int(cosDenZero[0][1])] = np.pi/4.
gt_alpha1 = sincOp*cosOp
#% upsampling the transmit sequence
amUpSampled = np.vstack([ am, np.zeros([(fs-1.), am.size]) ])
amU = amUpSampled.flatten('F')
#% filtered sequence
st_alpha5 = np.convolve(amU, gt_alpha5)
st_alpha1 = np.convolve(amU, gt_alpha1)
#% taking only the first 10000 samples
st_alpha5 = st_alpha5[0:10000]
st_alpha1 = st_alpha1[0:10000]
st_alpha5_reshape = np.reshape(st_alpha5, [(fs*2.), (N * fs / 20.)], 'F').T
st_alpha1_reshape = np.reshape(st_alpha1, [(fs*2.), (N * fs / 20.)], 'F').T
plt.close('all')
X = np.arange(0,1.99, 1.0/fs)
plt.figure(1)
plt.plot(X, np.real(st_alpha5_reshape).T, 'b')
plt.title('eye diagram with alpha=0.5')
plt.xlabel('time')
plt.ylabel('amplitude')
plt.axis(np.array(np.hstack((0., 2., -1.5, 1.5))))
plt.grid('on')
plt.figure(2)
plt.plot(X, np.real(st_alpha1_reshape).T, 'b')
plt.title('eye diagram with alpha=1')
plt.xlabel('time')
plt.ylabel('amplitude')
plt.axis(np.array(np.hstack((0., 2., -1.5, 1.5))))
plt.grid('on')
plt.show()
生成您期望的数字。
旁注:
如果您在 MATLAB 中有一个 array/matrix(假设它被称为 varname
),您可以使用 save varname
(在 MATLAB 中)将其保存到 .mat 文件中。
然后您可以将 array/matrix 加载到 python 中:
import scipy.io
mat = scipy.io.loadmat("<path of .mat file>")
varname = mat[varname]
您也可以对整个 MATLAB 工作区执行此操作,只需使用 save
——在 python 中,mat
仍然只是一个由变量名称键入的字典,因此您d 像上面那样访问各个工作区变量。
您可以使用它来逐步验证 numpy 生成的内容与您期望的生成内容,并找出您做错了什么。