【问题标题】:Converting MATLAB code to Python and received TypeError: 'numpy.ndarray' object is not callable error将 MATLAB 代码转换为 Python 并收到 TypeError: 'numpy.ndarray' object is not callable 错误
【发布时间】:2020-11-12 18:17:47
【问题描述】:

我正在努力将这个生成波形的 MATLAB 代码转换为 Python。对于上下文,这是对原子力显微镜的带激发响应的模拟(与代码错误无关)。这是MATLAB代码

%simulate BE response over a line scan

% define experimental parameters
IO_rate = 4E6; %[samples/sec]
N_pixels = 128; % number of pixels along a line scan
N_points_per_pixel = 2^13; % number of data points per pixel
w1 = 200E3; % lower edge of band
w2 = 400E3; % upper edge of band
noise_level = .1; %add noise to the signal

w_vec = -IO_rate/2: IO_rate/N_points_per_pixel : IO_rate/2-IO_rate/N_points_per_pixel; %frequency vector over a pixel

% vary A, wo, Q, and phase over pixels
p_vec = (0:N_pixels-1)/N_pixels;
A_vec = sin(2*pi*3*p_vec)+2; %amplitude
wo_vec = 250E3 + 100E3*p_vec; %resonance
Q_vec = 100 - 50*p_vec; % Q-factor
phi_vec = sign(p_vec-.5); % phase

% build drive signal, define in the Fourier domain
D_vec = zeros(size(w_vec));
D_vec( ((abs(w_vec)<w2) + (abs(w_vec)>w1)) == 2 ) = 1; % drive bins located within upper and lower band edges
band_ind = find( (((w_vec)<w2) + ((w_vec)>w1)) == 2 );

d_vec = fftshift(ifft(ifftshift(D_vec))); % find drive signal in the time domain

% build response at each pixel
R_mat = zeros(N_pixels,N_points_per_pixel);
r_mat = zeros(N_pixels,N_points_per_pixel);
for k1 = 1 : N_pixels
    H_vec = (A_vec(k1).*wo_vec(k1).^2).*exp(1i*phi_vec(k1))./(w_vec.^2 + 1i*wo_vec(k1)*w_vec/Q_vec(k1) - wo_vec(k1).^2); %cantilever transfer function
    R_mat(k1,:) = (H_vec.*D_vec); %response of the cantilever in the Fourier domain
    
    %determine response in the time domain (this is a little hokey, but it should work for simulation)    
    r_mat(k1,:) = fliplr((real((ifft(fftshift(R_mat(k1,:)))))));    
end

% build full response in the time domain;
r_vec = reshape(r_mat.',[ 1 N_pixels*N_points_per_pixel]);

% add noise
r_vec = r_vec + noise_level*2*(rand(size(r_vec))-.5);

%save response as a .mat (which can be read into python if needed)

这是我迄今为止将其转换为 python 代码的内容

#simulate BE response over a line scan

# define experimental parameters
IO_rate = 4E6; #[samples/sec]
N_pixels = 128; # number of pixels along a line scan
N_points_per_pixel = 8192; # number of data points per pixel
w1 = 200E3; # lower edge of band
w2 = 400E3; # upper edge of band
noise_level = .1; #add noise to the signal

w_vec = np.arange(-IO_rate/2, IO_rate/2-IO_rate/N_points_per_pixel + 1, IO_rate/N_points_per_pixel)
# vary A, wo, Q, and phase over pixels
p_vec = np.arange(0, N_pixels-1)/N_pixels
A_vec = np.sin(2*np.pi*3*p_vec)+2 #amplitude
wo_vec = 250E3 + 100E3*p_vec #resonance
Q_vec = 100 - 50*p_vec # Q-factor
phi_vec = np.sign(p_vec-.5) # phase

D_vec = np.zeros(np.size(w_vec))
ind = (abs(w_vec)<w2) & (abs(w_vec)>w1);
D_vec[ind] = 1; #assign those indices to 1.
band_ind = np.nonzero(((w_vec)<w2) & ((w_vec)>w1));

d_vec = np.fft.fftshift(np.fft.ifft(np.fft.ifftshift(D_vec))) #find drive signal in the time domain
R_mat = np.zeros((N_pixels,N_points_per_pixel))
r_mat = np.zeros((N_pixels,N_points_per_pixel))

for k1 in range(N_pixels):
    H_vec = ((A_vec(k1)*wo_vec(k1)**2)*np.exp(1j*phi_vec(k1))/(w_vec**2 + 1j*wo_vec(k1)*w_vec/Q_vec(k1) - wo_vec(k1)**2)); #cantilever transfer function

在执行到目前为止我在 for 循环中执行的操作后,我得到 TypeError: 'numpy.ndarray' object is not callable 所以我不确定我做错了什么?

【问题讨论】:

  • 你了解 MATLAB 和 python 在索引方面的区别吗? () 与 [] 的使用?你知道什么是回溯吗?以及如何识别问题所在的行和变量?

标签: python python-3.x matlab numpy numpy-ndarray


【解决方案1】:

循环中向量的索引存在问题。
代码应该是:

    H_vec = ((A_vec[k1]*wo_vec[k1]**2)*np.exp(1j*phi_vec[k1])/(w_vec**2 + 1j*wo_vec[k1]*w_vec/Q_vec[k1] - wo_vec[k1]**2)); #cantilever transfer function

循环中似乎也存在问题。 你的意思是写:

for k1 in range(N_pixels-1):
      

【讨论】:

  • 您为什么建议对除第一个和最后一个以外的所有元素进行 OP 循环? MATLAB 代码循环遍历整个数组。
  • @CrisLuengo 我如何编写它以便它循环整个数组?
  • @RyanF:你的for k1 in range(N_pixels): 是正确的。
【解决方案2】:
  1. 原因是您使用 () 运算符而不是 [] 来访问数组中的项目(即,您使用 MatLab 样式的元素引用而不是 Phytonian 样式)。
  2. 另外,在np.arrange() 中你应该传递N_pixels,否则你会得到一个IndexError: index 127 is out of bounds for axis 0 with size 127 错误。
  3. 由于 Python 使用缩进作为行间分隔符,因此无需在每行末尾添加 ;

这里是更正的版本:

import numpy as np
#simulate BE response over a line scan

# define experimental parameters
IO_rate = 4E6 #[samples/sec]
N_pixels = 128 # number of pixels along a line scan
N_points_per_pixel = 8192 # number of data points per pixel
w1 = 200E3 # lower edge of band
w2 = 400E3 # upper edge of band
noise_level = .1 #add noise to the signal

w_vec = np.arange(-IO_rate/2, IO_rate/2-IO_rate/N_points_per_pixel + 1, 
IO_rate/N_points_per_pixel)
# vary A, wo, Q, and phase over pixels
p_vec = np.arange(N_pixels)/N_pixels
A_vec = np.sin(2*np.pi*3*p_vec)+2 #amplitude
wo_vec = 250E3 + 100E3*p_vec #resonance
Q_vec = 100 - 50*p_vec # Q-factor
phi_vec = np.sign(p_vec-.5) # phase

D_vec = np.zeros(np.size(w_vec))
ind = (abs(w_vec)<w2) & (abs(w_vec)>w1)
D_vec[ind] = 1; #assign those indices to 1.
band_ind = np.nonzero(((w_vec)<w2) & ((w_vec)>w1))

d_vec = np.fft.fftshift(np.fft.ifft(np.fft.ifftshift(D_vec))) #find drive signal in the time domain
R_mat = np.zeros((N_pixels,N_points_per_pixel))
r_mat = np.zeros((N_pixels,N_points_per_pixel))

for k1 in range(N_pixels):
    H_vec = ((A_vec[k1]*wo_vec[k1]**2)*np.exp(1j*phi_vec[k1])/(w_vec**2 + 1j*wo_vec[k1]*w_vec/Q_vec[k1] - wo_vec[k1]**2)) #cantilever transfer function

干杯。

【讨论】:

    猜你喜欢
    • 2022-11-20
    • 2016-03-25
    • 1970-01-01
    • 2019-11-11
    • 2021-07-08
    • 1970-01-01
    • 2014-11-25
    • 1970-01-01
    • 2022-08-23
    相关资源
    最近更新 更多