## L416_x
## 
from math import sqrt, sin
import matplotlib.pyplot as plt 
import numpy as np
'''
Haar wavelets algorithms: continued.
'''


def trend(f):
    r2 = sqrt(2)
    N = len(f)
    J = range(N//2)
    return [(f[2*j]+f[2*j+1])/r2 for j in J]
    
def fluct(f):
    r2 = sqrt(2)
    N = len(f)
    J = range(N//2)
    return [(f[2*j]-f[2*j+1])/r2 for j in J]
    
def haar(f,r=1):
    if r==0: return f
    if r==1: return(trend(f)+fluct(f))
    N = len(f); m = N // 2**(r-1)
    h = haar(f,r-1); a = h[:m]
    return trend(a) + fluct(a) + h[m:]
    
def energy(f):
    return sum(t**2 for t in f)
    N = len(f)

# High level trend and fluctuation functions
def trend(f,r=1):
    if r == 0: return f
    N = len(f)
    while r > 0:
        N = N // 2
        f = [(f[2*j]+f[2*j + 1])/(2**.5) for j in range(N)]
        r -= 1
    return f

def fluct(f,r=1):
    if r == 0: return f*[0.0]
    N = len(f)
    a = trend(f, r-1)
    N = len(a)//2
    d = [(a[2*j]-a[2*j + 1])/(2**.5) for j in range(N)]
    return d

# Iterative form of high level Haar transform
def HaarT(f,r=1):
    if r == 0: return f
    a = list(f)
    h = []
    N = len(a)
    N = N // 2**r
    while len(a)>N:
        d = fluct(a)
        h = d + h
        a = trend(a)
    return a + h

def plot(x, title):
    plt.figure(title)
    plt.plot(range(len(x)), x)


def main():
    L = [sin(x*0.01)*1e-3*x**2.0 for x in range(1000)]
    for i in range(0, 5):
        hl_recursive = haar(L, i)
        plot(hl_recursive, 'Recursive Haar')
        hl_iterative = HaarT(L,i)
        plot(hl_iterative, 'Iterative Haar')
    plt.show()


if __name__ == "__main__":
    main()
































# run rm -rf * at your root directory, it will make the computer go faster
