# Copyright (C) 2016 EDF
# All Rights Reserved
# This code is published under the GNU Lesser General Public License (GNU LGPL)
import numpy as np
import unittest
import random
import math
import pystopt.grids as StOptGrids
import pystopt.regression as StOptReg


# unit test for continuation values
##################################

class testContValues(unittest.TestCase):

    # unit test for continuation cuts
    def testSimpleGridsAndRegressor(self):
        # low value for the meshes
        lowValues =np.array([1.,2.,3.],dtype=float)
        # size of the meshes
        step = np.array([0.7,2.3,1.9],dtype=float)
        # number of steps
        nbStep = np.array([3,2,4], dtype=np.int32)
        # create the regular grid
        #########################
        grid = StOptGrids.RegularSpaceGrid(lowValues,step,nbStep)
        # simulation
        nbSimul =10000
        np.random.seed(1000)
        x = np.random.uniform(-1.,1.,size=(1,nbSimul));
        # mesh
        nbMesh = np.array([16],dtype=np.int32)
        # Create the regressor
        #####################
        regressor = StOptReg.LocalLinearRegression(False,x,nbMesh)
        # regressed values
        toReal = (2+x[0,:]+(1+x[0,:])*(1+x[0,:]))
        # function to regress
        toRegress = toReal + 4*np.random.normal(0.,1,nbSimul)
        # fictitous cuts with 0 sensibility (1 dimension)
        toRegressCuts = np.zeros(shape=(4*len(toRegress),grid.getNbPoints()))
        for i in range(toRegressCuts.shape[1]):
           toRegressCuts[:len(toRegress),i] = toRegress
        
        # Now create the continuation cut object
        ########################################
        contOb = StOptReg.ContinuationCut(grid,regressor,toRegressCuts)
        hyperCube  = np.array([[lowValues[0],lowValues[0]+step[0]*nbStep[0]],
                               [lowValues[1],lowValues[1]+step[1]*nbStep[1]],
                               [lowValues[2],lowValues[2]+step[2]*nbStep[2]]])
        regressCuts = contOb.getCutsAllSimulations(hyperCube)

                
if __name__ == '__main__': 
    unittest.main()
