A very basic Haar Discrete Wavelet Transform for Python 1.4.0 to 3.8.0...

Hi guys and gals...
(Apologies for any typos, etc...)

Another code snippet mainly for the AMIGA but works from Python 1.4.0 to 3.8.0 on just about any platform, hence the first upload here. I will upload to the AMIGA community in a week or so to let the dust settle on here.

A Haar One Dimension Discrete Wavelet Transform.

OSX 10.14.6, the AMIGA and some Linux flavours does not have access to the PyWavelets module, (pywt) so this was created. I personally have a Two Dimension version too but from this you can create your own, Linux Mint 19 does not have it in their repository
To create this very basic 1D version, only floating point arithmetic is required.
This means that many languages could be used AND shells like ksh(93) and the now default zsh for OSX Mojave.
In this case I have used Python but I might translate to ksh(93) to put it alongside my DFT, Discrete Fourier Transform, using ksh(93)

I was considering using integer maths but I think, much like the DFT I was working on, this is not possible for large RADIX 2 data sizes.

This is in its simplest form and there is a URL in the code to check against your values, and, also a PDF learning reference too...

# DWT.py
#
# Basic Python 1D Haar DWT, Discrete Wavelet Transform, using internal default Python floating point maths only.
# Works on Python Versions 1.4.0 to 2.0.1 and 2.4.6, (for the AMIGA A1200), to 3.8.0rc1
# on other platforms without modification.
# Developed on OSX 10.12.x to 10.14.6, using Python Versions 2.6.x, 2.7.x, 3.5.2 and 3.8.0.
# Issued as CC0, Public Domain, B.walker, G0LCU, to https://www.unix.com first 12_03_2020.
#
# URL to check results against:
# https://www.unf.edu/~ddreibel/camp/wave8.html

# Integer values as floats used here for default DEMO 8 sample size.
# The 8 test samples; sample size must be a power of 2.
#
# DEMO 1:
# START:
# 56.0, 40.0, 8.0, 24.0, 48.0, 48.0, 40.0, 16.0
#
# STEPS IN BETWEEN:
# 48.0, 16.0, 48.0, 28.0, 8.0, -8.0, 0.0, 12.0
# 32.0, 38.0, 16.0, 10.0, 8.0, -8.0, 0.0, 12.0
#
# FINAL RESULT:
# 35.0, -3.0, 16.0, 10.0, 8.0, -8.0, 0.0, 12.0
# Works from Python 1.4.0 to Python 3.5.2.
#
# Learning reference here:
# https://www.math.aau.dk/digitalAssets/120/120646_r-2003-24.pdf
#
# LISTING=[56.0, 40.0, 8.0, 24.0, 48.0, 48.0, 40.0, 16.0]

# Transform creates genuine floating point values.
# DEMO 2:
# START:
# 6, 12, 15, 15, 14, 12, 120, 116
#
# FINAL RESULT:
# 38.75, -26.75, -3.0, -52.5, -3.0, 0.0, 1.0, 2.0
#
# LISTING=[6, 12, 15, 15, 14, 12, 120, 116]

# Basic transform.
# DEMO 3:
# START:
# 1, 2, 3, 4, 5, 6, 7, 8
#
# FINAL RESULT:
# 4.5, -2.0, -1.0, -1.0, -0.5, -0.5, -0.5, -0.5
#
# LISTING=[1, 2, 3, 4, 5, 6, 7, 8]

# Using padding of 0.0 for last three places.
# DEMO 4:
# START:
# 17.0, 3.0, 31.0, 213.0, 99.0, 0.0, 0.0, 0.0
#
# FINAL RESULT:
# 45.375, 20.625, -56.0, 24.75, 7.0, -91.0, 49.5, 0.0
#
LISTING=[17.0, 3.0, 31.0, 213.0, 99.0, 0.0, 0.0, 0.0]

print("Eight input values:")
print(LISTING)

# Haar 1D DWT function.
def DiscreteHaarWaveletTransform(DATA=[]):

    LENGTH=len(DATA)
    RESULT=[]
    while 1:
        TEMP=[0]*LENGTH

        for INDEX in range(0,LENGTH,2):
            MEAN_PAIR=(DATA[INDEX]+DATA[INDEX+1])/2.0
            DIFFERENCE=DATA[INDEX]-MEAN_PAIR
            TEMP[int(INDEX/2)]=MEAN_PAIR
            TEMP[int(LENGTH/2)+int(INDEX/2)]=DIFFERENCE

        DATA=TEMP
        RESULT=TEMP[int(LENGTH/2):]+RESULT
        LENGTH=int(LENGTH/2)

        if LENGTH==1:
            RESULT=TEMP[0:1]+RESULT
            return RESULT

# Obtain the results.
DWTDATA=DiscreteHaarWaveletTransform(LISTING)

print("DWT results:")
print(DWTDATA)

All constructive criticism welcome...
Enjoy.

2 Likes