0

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.

Nice Guy
  • 1
  • 1
  • 4
    FIrst thing you need to learn here is how to properly report problems. Show the actual error with traceback. Don't just say "doesn't work". That annoys us :) You need to put some effort into understanding the error. – hpaulj Aug 29 '21 at 23:41
  • Seems you’re making it much more complicated than it is. You don’t need `arange`, and there’s no concatenation in the MATLAB code. – Cris Luengo Aug 30 '21 at 00:42
  • Hello I'm sorry it's my first time posting in stackoverflow I just usually lurk around here. – Nice Guy Aug 30 '21 at 00:59

3 Answers3

0

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!

  • I would like to ask again if there is a way of adding a scalar value to every index to somehow shift it by that value. Like for a=np.array ([1,2,3,4,5,6,7,8,9,10]) , a[2:4] I would like to add a value of 2 from index 2 to 4 to move it to a[4:6]. Since I can't really figure out how to do that in Python. – Nice Guy Aug 30 '21 at 02:24
  • It is straightforward. For example, put "n" as your offset and you can do slices with a[ 2 +n : 4+n ]. – Gustavo Alves Aug 31 '21 at 02:09
0

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])
hpaulj
  • 221,503
  • 14
  • 230
  • 353
0

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
Dharman
  • 30,962
  • 25
  • 85
  • 135
alle_meije
  • 2,424
  • 1
  • 19
  • 40