##Author: Xavier Baques Arcusa
##DCI A407

# Updating the path
import sys

# In next instruction, inside append you should put the path to the location of the cdi module in your computer
sys.path.append("/Users/XavierBaquesArcusa/Documents/FIB/CDI/Laboratori/CDI_Module/")

from cdi import *
from cdi_huffman import *
from math import *

##Auxiliary functions

''' Default f Function (from T5.9) '''
def f(x):
    return x**2 - x + 41

##Exercises


##1

'''
Define a funtion Y = RC(X,f) that implements residual coding of the numerical list X 
using the function f (defined for non-negative integers) as a model. Check it with the
example on page T5.9. Define also a function X = RD(Y,f) that implements the corresponding decoding.
'''

def RC(X,f):
    Y = []
    i = 1
    for x in X:
        Y += [x - f(i)]
        i += 1
    return Y
    

def RD(Y,f):
    X = []
    i = 1
    for y in Y:
        X += [y + f(i)]
        i += 1
    return X
    
#test 1
print('Ex1 Test 1')
X = [41,43,46,52,62,71,82,98,115,131]
Y = RC(X,f)
print ('Y = ', Y)
X = RD(Y,f)
print ('X = ', X)
print()

#test 2
print('Ex1 Test 2')
def f(x):
    return x**2 - x
    
X = [45,48,31,110,209,91,17,19,500]
Y = RC(X,f)
print ('Y = ', Y)
X = RD(Y,f)
print ('X = ', X)
print()


##2

'''
Define similar functions Y = PC(X) and X = PD(Y) (predictive coding and decoding), where
 yj = xj-(xj-2+xj-1)/2, with the convention that x-2=x-1=0. Test them with some suitable examples.
'''

def PC(X):
    Y = []
    for j in range (0, len(X)):
        if (j == 0): Y += [X[j]]
        elif (j == 1): Y += [X[j] - (X[j - 1])/2]
        else: Y += [X[j] - (X[j - 2] + X[j - 1])/2]
    return Y
    

def PD(Y):
    X = []
    for j in range (0, len(Y)):
        if (j == 0): X += [Y[j]]
        elif (j == 1): X += [Y[j] + (X[j -1])/2]
        else: X += [Y[j] + (X[j - 2] + X[j - 1])/2]
    return X
    
#test 1
print('Ex2 Test 1')
X = [41,43,46,52,62,71,82,98,115,131]
Y = PC(X)
print ('Y = ', Y)
X = PD(Y)
print ('X = ', X)
print()

#test 2
print('Ex2 Test 2')
X = [1,5,21,17,62,91,82,120,315,221,500,410,178,65,10,15,625,724,825,952,1024,102]
Y = PC(X)
print ('Y = ', Y)
X = PD(Y)
print ('X = ', X)
print()

#test 3
print('Ex2 Test 3')
X = [-1,-3,10,-20,14,-5,120,-200,0,1.5]
Y = PC(X)
print ('Y = ', Y)
X = PD(Y)
print ('X = ', X)
print()

