Matlab到Python代码转换-输出不匹配

Matlab到Python代码转换-输出不匹配,python,numpy,matplotlib,Python,Numpy,Matplotlib,我已经成功地将一个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

我已经成功地将一个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
清除
N=10^3;%符号数
am=2*(兰特(1,N)>0.5)-1+j*(2*(兰特(1,N)>0.5)-1);%生成随机二进制序列
fs=10;%采样频率(Hz)
%定义sinc滤波器
sincNum=sin(pi*[-fs:1/fs:fs]);%sinc函数的分子
sincDen=(pi*[-fs:1/fs:fs]);%sinc函数的分母
sincDenZero=find(abs(sincDen)<10^-10);
sincOp=sincNum./sincDen;
sincOp(sincDenZero)=1;%sin(pix/(pix)=1表示x=0
%升余弦滤波器
α=0.5;
cosNum=cos(alpha*pi*[-fs:1/fs:fs]);
cosDen=(1-(2*alpha*[-fs:1/fs:fs])。^2);

cosDenZero=find(abs(cosDen)有几件事。尽管你说“我已经用Python和Octave双重验证了每个变量的值——它们都是相同的。”——但事实并非如此

首先,当您从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(alpha * np.pi * fsrange) 
同样,这条巨大的线:

cosNum = np.cos(np.dot(np.dot(alpha, np.pi), np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs))))))
可以是:

fsrange = 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指定为
):

您在此处指定了错误的展平顺序:

amU = amUpSampled.flatten(0)
应使用FORTRAN顺序将其展平(MATLAB使用的顺序):

重塑形状时,同样需要指定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()
您也可以通过简单的
save
——在python中
mat
将仍然是一个由变量名键入的字典,因此您可以像上面一样访问各个工作区变量


你可以用它来一步一步地验证numpy产生了什么,而不是你期望它产生什么,并找出你做错了什么。

有几件事。尽管你说“我已经双重验证了Python和Octave中bot的每个变量的值——它们都是相同的。”——但事实并非如此

首先,当您从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(alpha * np.pi * fsrange) 
同样,这条巨大的线:

cosNum = np.cos(np.dot(np.dot(alpha, np.pi), np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs))))))
可以是:

fsrange = 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指定为
):

您在此处指定了错误的展平顺序:

amU = amUpSampled.flatten(0)
应使用FORTRAN顺序将其展平(MATLAB使用的顺序):

重塑形状时,同样需要指定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()
您也可以通过简单的
save
——在python中
mat
将仍然是一个由变量名键入的字典,因此您可以像上面一样访问各个工作区变量


你可以用它来一步一步地验证numpy产生了什么,而不是你期望它产生什么,并找出你做错了什么。

有几件事。尽管你说“我已经双重验证了Python和Octave中bot的每个变量的值——它们都是相同的。”——但事实并非如此

首先,当您从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(alpha * np.pi * fsrange) 
同样,这条巨大的线:

cosNum = np.cos(np.dot(np.dot(alpha, np.pi), np.array(np.hstack((np.arange(-fs, (fs)+(1./fs), 1./fs))))))
可以是:

fsrange = 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指定为
):

您在此处指定了错误的展平顺序:

amU = amUpSampled.flatten(0)
应使用FORTRAN顺序将其展平(MATLAB使用的顺序):

重塑形状时,同样需要指定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()
您也可以通过简单的
save
——在python中
mat
将仍然是一个由变量名键入的字典,因此您可以像上面一样访问各个工作区变量


你可以用它来一步一步地验证numpy产生了什么,而不是你期望它产生什么,并找出你做错了什么。

有几件事。尽管你说“我已经双重验证了Python和Octave中bot的每个变量的值——它们都是相同的。”——但事实并非如此

首先,时间是有的