Need help in converting MATLAB code to python

147 Views Asked by At

I've been trying to implement the MATLAB code of Prof.Selesnick's DWT implementation in Python for learning purposes.

function [lo, hi] = afb(x, af)

% [lo, hi] = afb(x, af)
%
% Analysis filter bank
% x -- N-point vector (N even); the resolution should be 2x filter length
%
% af  -- analysis filters
% af(:, 1): lowpass filter (even length)
% af(:, 2): highpass filter (even length)
%
% lo: Low frequency
% hi: High frequency
%

N = length(x);
L = length(af)/2;
x = cshift(x,-L);

% lowpass filter
lo = upfirdn(x, af(:,1), 1, 2);
lo(1:L) = lo(N/2+[1:L]) + lo(1:L);
lo = lo(1:N/2);

% highpass filter
hi = upfirdn(x, af(:,2), 1, 2);
hi(1:L) = hi(N/2+[1:L]) + hi(1:L);
hi = hi(1:N/2);

I'm specifically stuck at lo(1:L) = lo(N/2+[1:L]) + lo(1:L);

I attempted lo[np.arange(0,L)]=lo[N // 2 + np.concatenate([np.arange(0,L)])) + lo[np.arange(0,L)] but it seems not to be working. Will appreciate any help.

I have an input signal x with a size of 10,000, when I execute the code it stops right at that specific line and says index 5001 is out of bounds for axis 0 with size 5001. I seem to be out of bounds.

3

There are 3 best solutions below

2
Gustavo Alves On

The numpy library already have a bunch of itens that helps us with the slices.

When you need to take a slice of a numpy array, for example a = np.array([1,2,3,4,5,6,7,8,9,10]), you can slice with a[:n] and n will be the last element in the sequence. If n = 2 then a[:2] = [1,2]. Try this and you will write a clean code.

For your error of "out of bounds" i recommend you to check the indices and remember that Python count starts at 0.

For example (using our "a" array defined above):

a[0] = 1
a[-1] = 10 
a[9] = 10

Note that the last element is at indice 9. I believe this is your error, you must use foo[5000] instead of foo[5001].

I hope i helped you a little!

0
hpaulj On

In an Octave session:

>> lo = 1:10;
>> L=3; N=4;
>> N/2+[1:L]
ans =

   3   4   5

>> lo(N/2+[1:L])+lo(1:L)
ans =

   4   6   8

In numpy:

In [100]: lo = np.arange(1,11)
In [101]: L=3; N=4
In [102]: N/2+np.arange(0,L)
Out[102]: array([2., 3., 4.])
In [105]: lo[int(N/2)+np.arange(0,L)]+lo[:L]
Out[105]: array([4, 6, 8])

equivalently

In [106]: n=int(N/2); lo[n:n+L]+lo[:L]
Out[106]: array([4, 6, 8])
0
alle_meije On

I'm not familiar with the upfirdn function but it looks like your function applies one level of the forward DWT?

This answer contains the forward implementation of a (multi-level) DWT in Python. It is the venerable FWT recipe by Mallat, which may be slightly different to yours but based on the same principle:

  • forward FWT: level i -> filter -> downsample -> level i+1
  • inverse FWT: level i+1 -> upsample -> filter -> level i