## A324_dominguez

##  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 = RC(Y,f) that implements the corresponding 
    decoding.
'''
print("1.")
X = [41, 43, 46, 52, 62, 71, 82, 98, 115, 131]
print("Original X = " + str(X))

def f(x):
    return x**2 - x + 41

def RC(X, f):
    model = []
    for x in range(0, len(X)):
        model += [f(x + 1)]
        
    Y = []
    for i in range(0, len(X)):
        Y += [X[i] - model[i]]
    return Y
    
Y = RC(X, f)
    
print("Y = " + str(Y))

def RD(Y, f):
    model = []
    for x in range(0, len(Y)):
        model += [f(x + 1)]
        
    X = []
    for i in range(0, len(Y)):
        X += [Y[i] + model[i]]
    return X
    
X = RD(Y, f)

print("X = " + str(X))
print("\n")
    

##  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.
'''
print("2.")
X = [41, 43, 46, 52, 62, 71, 82, 98, 115, 131]
print("Original X = " + str(X))

def PC(X):
    Y = []
    for i in range(0, len(X)):
        if i == 0:
            Y += [X[i]]
        elif i == 1:
            Y += [X[i] - X[i - 1]/2]
        else: 
            Y += [X[i] - (X[i - 2] + X[i - 1])/2]
    return Y
    
Y = PC(X)
    
print("Y = " + str(Y))

def PD(Y):
    X = []
    for i in range(0, len(Y)):
        if i == 0:
            X += [int(Y[i])]
        elif i == 1:
            X += [int(Y[i] + Y[i - 1]/2)]
        else: 
            X += [int(Y[i] + (X[i - 2] + X[i - 1])/2)]
    return X
    
X = PD(Y)
    
print("X = " + str(X))
