"""
This file contains a method to get the new values with Fourier's coeffcients.
See FourierBasis.py or fda (R)

Marjorie Roscian CCI 2017-2018 based on Functional Data Analysis Ramsay and Silverman 2005
"""

import math
import numpy as np


def fouriervalues(nb_bases, coeff):
    """This function computes data to function created by passing in a Fourier basis. See FourierBasis.py
    #Input : data contains a vector of discrete points of a curve
    #        nb_bases is the number k of basis wanted to adjust Fourier series
    #Output : result is an array of the new data

    #Other : data verifies that the input data is a numpy.darray
             x is a new sequence of x values between 0 and 1
             seq is a list of the index values of each cell
             period is defined but can be changed
             t is the number of cos coefficient and the number of sin coefficient
             phi is the entire matrix containing all basis functions
             coeff contains the vector of coefficients
    """

    # Create sequence from 0 to 1
    x = np.array(np.linspace(0, 1, num=len(coeff)))

    # Create sequence from 0 to data size
    seq = np.array(np.arange(0, len(coeff)))

    # Verify the number of basis is odd
    if nb_bases % 2 == 0:
        print("Caution : number k of basis is even. k modified to k-1 ")
        nb_bases = nb_bases - 1

    # Choose the period
    period = 1

    # Define arrays for mathematical method
    t = np.array(np.arange(1, nb_bases/2))

    # Alternate sin and cos basis
    phi = np.zeros((len(coeff), nb_bases))
    for indiv in seq:
        num_coef = 1
        while num_coef < nb_bases:
            for elem in t:
                phi_sin = np.sin((2 * math.pi * x[indiv] * elem)/period)
                phi_cos = np.cos((2 * math.pi * x[indiv] * elem) / period)
                phi[indiv, 0] = 1
                phi[indiv, num_coef] = phi_sin
                num_coef += 1
                phi[indiv, num_coef] = phi_cos
                num_coef += 1

    # Verify coeff is ndarray
    coeff = np.array(coeff)

    # Compute the new values
    result = phi.dot(coeff)

    return result
