        MODULE functions    
      
        USE constants, ONLY : dp   ! double precision (i.e. accuracy)    
        IMPLICIT NONE
        
      
        !*..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..*
        !| .**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**. |
        !| |                                                                          | |
        !| |                                                                          | |
        !| |                 INFORMATION SUPPLIED BY THE USER:                        | | 
        !| |                                                                          | |               
        !| |                                                                          | |
        !| |    * Different PARAMETERS:                                               | |
        !| |                                                                          | |       
        !| |        - the optimality tolerance:       'user_eps'                      | |
        !| |                                                                          | |               
        !| |        - the initial opt. tolerance for inner iteration:   'user_delta'  | |
        !| |                                                                          | |       
        !| |        - the search control parameter:   'user_tau'                      | |   
        !| |                                                                          | |               
        !| |        - the search control parameter:   'user_c1'                       | |       
        !| |        - the line search parameter:      'user_c2'                       | |       
        !| |                                                                          | |       
        !| |        - the decrease parameter:      'user_sigma1'                      | |     
        !| |        - the decrease parameter:      'user_sigma2'                      | |     
        !| |                                                                          | |       
        !| |                                                                          | |       
        !| |                                                                          | |       
        !| |    * Computation of the value of the DC functions f_1 and f_2:           | |
        !| |        - f1(y, problem1)   the value of DC component f_1 at a point y    | |
        !| |        - f2(y, problem2)   the value of DC component f_2 at a point y    | |           
        !| |                                                                          | |               
        !| |                                                                          | |               
        !| |    * Computation of the subgradient of the DC components f_1 and f_2:    | |
        !| |        - subgradient_f1(y, problem1)    the subgradient of f_1 at y      | |
        !| |        - subgradient_f2(y, problem2)    the subgradient of f_2 at y      | |       
        !| |                                                                          | |
        !| |                                                                          | |
        !| |                                                                          | |
        !| .**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**. |
        !*..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..*
        
        
        !--------------------------------------------------------------------------------
        ! ----------------------------------------------------------------------------- |
        ! |                  INFORMATION ABOUT PARAMETERS:                            | |
        ! ----------------------------------------------------------------------------- |
        !--------------------------------------------------------------------------------       
  
            !****************** GLOBAL PARAMETERS *******************************************

  
        INTEGER, PARAMETER :: problem1 = 1                 ! Objective function selected for the DC component f1
        INTEGER, PARAMETER :: problem2 = 5                 ! Objective function selected for the DC component f2
        
        INTEGER, PARAMETER :: start_point = 1              ! Starting point of the problem  
        
      
        !-------------------------------------------------------------------------------------------------
      
        INTEGER, PARAMETER :: user_n = 100                ! The number of variables in the problem
        
        !__________________________________________________________________________________________
        !>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>>
        !****************** PARAMETRES NEEDED IN SUBGDC METHOD ********************

 
        !---------------------------------------------------------------------------------                                                           
        ! ** The stopping parameters **
        !---------------------------------------------------------------------------------
 
        ! ** The optimality tolerance **      
        REAL(KIND=dp), PARAMETER :: user_eps = (10.0_dp)**(-5)       ! If user_eps <= 0.0_dp then DEFAULT value (10.0_dp)**(-5)
                                                                         
        ! ** The initial optimality tolerance for inner iteration**      
        REAL(KIND=dp), PARAMETER :: user_delta = (10.0_dp)**(-5)     ! If user_delta <= 0.0_dp then DEFAULT value (10.0_dp)**(-5) 
        
        !---------------------------------------------------------------------------------                                                           
        ! ** The other parameters **
        !---------------------------------------------------------------------------------
        
        REAL(KIND=dp), PARAMETER :: user_tau = -1.0_dp               ! The initial value for the search control parameter tau 
                                                                     ! If user_tau <= 0.0_dp then DEFAULT value 2.0_dp is used if user_n<100
                                                                     !                                          10.0_dp is used if 100 <= user_n < 200
                                                                     !                                          50.0_dp otherwise
                                                                     
        REAL(KIND=dp), PARAMETER :: user_c1 = 0.2_dp                 ! The search control parameter 
                                                                     ! If user_c1 <= 0.0_dp or user_c1 > 1.0_dp then DEFAULT value 0.2_dp is used 

        REAL(KIND=dp), PARAMETER :: user_c2 = 0.05_dp                ! The line search parameter 
                                                                     ! If user_c2 <= 0.0_dp or user_c2 > user_c1 then DEFAULT value 0.25_dp*user_c1 is used 
        
 
        REAL(KIND=dp), PARAMETER :: user_sigma1 = 0.2_dp             ! The decrease parameter for TAU: If user_sigma1 <= 0.0_dp .OR. user_sigma1 > 1.0_dp 
                                                                     !                                 then DEFAULT value 0.2_dp is used
        
        REAL(KIND=dp), PARAMETER :: user_sigma2 = 1.0_dp             ! The decrease parameter for delta: If user_sigma2 <= 0.0_dp .OR. user_sigma2 > 1.0_dp 
                                                                     !                                   then DEFAULT value 0.99_dp is used
       
       
        !________________________________________________________________________________
        !>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<
        
        
        
        !*..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..*
        !| .**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**. |
        !| |                                                                          | |
        !| |     To EXECUTE the bundle algorithm DBDC the USER needs to DETERMINE:    | | 
        !| |                                                                          | |       
        !| |        f1(y, problem1)     - value of DC component f_1 at a point y      | |
        !| |        f2(y, problem2)     - value of DC component f_2 at a point y      | |
        !| |                                                                          | |
        !| |        subgradient_f1(y, problem1)   - subgradient of f_1 at y           | |
        !| |        subgradient_f2(y, problem2)   - subgradient of f_2 at y           | |
        !| |                                                                          | |
        !| |                                                                          | |       
        !| .**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**. |
        !*..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..*
    
        
        CONTAINS

        
        !********************************************************************************
        !                                                                               |
        !              FUNCTION VALUES OF THE DC COMPONENTS f_1 AND f_2                 |
        !                                                                               |
        !********************************************************************************

           FUNCTION f1(y, problem1, user_n) RESULT(f)        
                !
                ! Calculates the function value of the DC component f_1 at a point 'y'.
                ! Variable 'problem1' identifies the objective function used.
                ! 'user_n' is the dimension of the problem              
                !
                ! NOTICE: The dimension of 'y' has to be 'user_n'.
                !
                IMPLICIT NONE
                !**************************** NEEDED FROM USER *************************************
                REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: y    ! a point where the function value of the DC component f_1 is calculated
                INTEGER, INTENT(IN) :: problem1                 ! the objective function selected for the DC component f2
                INTEGER, INTENT(IN) :: user_n                   ! the dimension of the problem
                !**************************** OTHER VARIABLES **************************************
                REAL(KIND=dp) :: f                              ! the function value of the DC component f_1 at a point 'y'
                REAL(KIND=dp) :: apu, largest                   ! help varaible
                REAL(KIND=dp), PARAMETER :: zero=0.0_dp, one=1.0_dp
                REAL(KIND=dp), PARAMETER :: two=2.0_dp
                REAL(KIND=dp) :: x,z,v,w
                INTEGER :: i, j, ind                                    ! help variable
                
                INTEGER :: hit1, hit2                     ! Number of the active partial objective for f1 and for f2
                REAL(KIND=dp) :: f_sign1, f_sign2         ! sign of the active partial objective for f1 and for f2       
                REAL(KIND=dp), DIMENSION(3) :: f_k, a                
                REAL(KIND=dp), DIMENSION(user_n) :: f_i                
                
                SELECT CASE(problem1)
                
                   CASE(0)
                     f = 0.0_dp
                
                   !-------------------------------------
                   CASE(1)
                     apu = y(1)**2
                     DO i = 2, user_n
                       IF (apu < y(i)**2 ) THEN 
                          apu = y(i)**2
                       END IF
                     END DO
                     f = (user_n + 1.0_dp) * apu
                   !-------------------------------------

                   !-------------------------------------
                   !       Generalization of MAXQ
                   !-------------------------------------
                   CASE(2)  !
                     apu = y(1)**2
                     DO i = 2, user_n
                       IF (apu < y(i)**2 ) THEN 
                          apu = y(i)**2
                       END IF
                     END DO
                     f = apu
                   !-------------------------------------                   
                   
                   !-------------------------------------
                   CASE(3)
                     f = 0.0_dp
                     DO i = 1, user_n
                       f =  f + y(i)**2                             
                     END DO                    
                   !-------------------------------------
                   
                   !-------------------------------------
                   CASE(4)
                     apu = ABS(y(1))
                     DO i = 2, user_n
                       IF (apu < ABS(y(i)) ) THEN 
                          apu = ABS(y(i))
                       END IF
                     END DO
                     f = user_n * apu               
                   !-------------------------------------
                   
                   !-------------------------------------
                   CASE(5)
                     f = 0.0_dp
                     DO i = 1, user_n
                        f = f + ABS(y(i))                                   
                     END DO             
                   !-------------------------------------
                   
                   !-------------------------------------
                   CASE(6)
                     apu = ABS(summa(y,1,user_n)) 
                     DO j = 2, 20
                       IF (apu <= ABS(summa(y,j,user_n)) ) THEN 
                         apu = ABS(summa(y,j,user_n))
                       END IF
                     END DO
                     f = 20.0_dp * apu
                   !-------------------------------------
                   
                   !-------------------------------------
                   CASE(7)
                     f = 0.0_dp
                     DO j = 1, 20
                        f = f + ABS( summa(y,j,user_n) )
                     END DO 
                   !-------------------------------------
                   
                   !-------------------------------------
                   CASE(8)
                     f = 0.0_dp
                     DO i = 2, user_n
                         f = f + ABS( y(i) - y(i-1) )
                     END DO
                   !-------------------------------------
                   
                   !-------------------------------------
                   !       Generalization of MXHILB
                   !-------------------------------------                    
                   CASE(9)
                     f = 0.0_dp
                     hit1 = 1
                     DO j = 1,user_n
                       f = f + y(j)/REAL(j, KIND=dp)
                     END DO
                     f_sign1=SIGN(one,f)
                     f = ABS(f)
                     DO i = 2,user_n
                       x = zero
                          DO j = 1,user_n
                            x = x + y(j)/REAL(i+j-1, KIND=dp)
                          END DO
                       z = ABS(x)
                       IF (z > f) THEN
                         f=z
                         hit1=i
                         f_sign1=SIGN(one,x)
                       END IF
                     END DO
                   !------------------------------------
                    
                   !------------------------------------
                   !             Chained LQ
                   !------------------------------------                     
                   CASE(10)
                     f=zero
                     DO i=1,user_n-1
                       x = -y(i)-y(i+1)
                       z = -y(i)-y(i+1)+(y(i)*y(i)+y(i+1)*y(i+1)-one)
                       IF (x >= z) THEN
                         f=f+x
                       ELSE
                         f=f+z
                       END IF
                     END DO                   
                   !------------------------------------
                    
                   !------------------------------------
                   !           Chained CB3 I
                   !------------------------------------                     
                   CASE(11)
                     f=zero
                     DO i=1,user_n-1
                        z = y(i)*y(i)*y(i)*y(i)+y(i+1)*y(i+1)
                        v = (two-y(i))*(two-y(i))+ &
                            (two-y(i+1))*(two-y(i+1))
                        w = two*EXP(-y(i)+y(i+1))
                        x = MAX(z,v,w)
                        f = f+x
                     END DO                                     
                   !------------------------------------
                   
                   !------------------------------------
                   !           Chained CB3 II
                   !------------------------------------                     
                   CASE(12)
                     f=zero
                     f_k=zero 

                     DO i=1,user_n-1
                        f_k(1)=f_k(1)+y(i)*y(i)*y(i)*y(i)+y(i+1)*y(i+1)
                        f_k(2)=f_k(2)+(two-y(i))*(two-y(i))+ &
                            (two-y(i+1))*(two-y(i+1))
                        f_k(3)=f_k(3)+two*EXP(-y(i)+y(i+1))
                     END DO
                     f=MAX(f_k(1),f_k(2),f_k(3))
                   !------------------------------------   

                   !------------------------------------                     
                   CASE(13)
                     f = 0.0_dp

                     DO i = 1, user_n
                        f = f + ABS(y(i)) 
                        f = f + 10.0_dp * Max( 2.0_dp *(y(i)*y(i) - y(i) - 1.0_dp), 0.0_dp )
                     END DO                   

                   !------------------------------------                     

                   
                   !------------------------------------
                   CASE(14)
                     f = 0.0_dp
                     
                     apu = 0.0_dp
                     DO j =1, user_n
                        apu = apu + y(j)/(1+j-1.0_dp)
                     END DO
                     largest = ABS(apu) 
                     
                     DO i = 2, user_n
                        apu = 0.0_dp
                        DO j = 1, user_n
                          apu = apu + y(j)/(i+j-1.0_dp)
                        END DO
                        IF (ABS(apu) > largest) THEN 
                           largest = ABS(apu)
                        END IF
                     END DO
                     
                     f = user_n * largest 
                   !------------------------------------    

                   !------------------------------------
                   CASE(15)
                     f = 0.0_dp
                     
                     DO i = 1, user_n
                        apu = 0.0_dp
                        DO j = 1, user_n
                          apu = apu + y(j)/(i+j-1.0_dp)
                        END DO
                        f = f + ABS(apu)
                     END DO                   
                   !------------------------------------                   

                   !------------------------------------
                   CASE(16)
                     f = 0.0_dp
                     
                     DO i = 1, user_n-1
                         a(1) = y(i)**4 + y(i+1)**2
                         a(2) = (2.0_dp-y(i))**2 + (2.0_dp-y(i+1))**2
                         a(3) = 2.0_dp*EXP(-y(i)+y(i+1))
                         IF (a(1)>a(2)) THEN
                            IF (a(1)>a(3)) THEN
                              f_i(i) = a(1)
                            ELSE
                              f_i(i) = a(3)
                            END IF
                         ELSE
                            IF (a(2)>a(3)) THEN
                              f_i(i) = a(2)
                            ELSE
                              f_i(i) = a(3)
                            END IF      
                         END IF
                     END DO
                     
                     largest = f_i(1)
                     ind = 1
                     DO i =2, user_n-1
                         IF (f_i(i) > largest) THEN 
                            largest = f_i(i)
                            ind = i
                         END IF
                     END DO
                     
                     f = (user_n-1.0_dp)*largest                   
                   !------------------------------------   

                  !------------------------------------
                   CASE(17)
                     f = 0.0_dp
                     
                     apu = 0.0_dp
                     DO i = 1, user_n-1
                        apu = apu + y(i)**2 + (y(i+1)-1.0_dp)**2
                        apu = apu + y(i+1) -1.0_dp
                     END DO
                     
                    apu = 2.0_dp *apu
                    IF (apu > 0.0_dp) THEN
                       f = apu
                    END IF                   
                   !------------------------------------   

                   !------------------------------------
                   CASE(18)
                     f = 0.0_dp

                     DO i = 1, user_n-1
                        f = f + y(i)**2 + (y(i+1)-1.0_dp)**2
                        f = f + y(i+1) -1.0_dp
                     END DO                   
                   !------------------------------------                   
                END SELECT
                
           END FUNCTION f1      
           
           !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
           
           FUNCTION f2(y, problem2, user_n) RESULT(f)           
                !
                ! Calculates the function value of DC component f_2 at a point 'y'.
                ! Variable 'problem2' identifies the objective function used.
                ! 'user_n' is the dimension of the problem
                !
                ! NOTICE: The dimension of 'y' has to be 'user_n'.
                !
                IMPLICIT NONE
                !**************************** NEEDED FROM USER *************************************
                REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: y    ! a point where the function value of the DC component f_2 is calculated
                INTEGER, INTENT(IN) :: problem2                 ! the objective function selected for the DC component f2  
                INTEGER, INTENT(IN) :: user_n                   ! the dimension of the problem              
                !**************************** OTHER VARIABLES **************************************
                REAL(KIND=dp) :: f                              ! the function value of the DC component f_1 at a point 'y'
                REAL(KIND=dp) :: apu, largest                   ! help variable
                REAL(KIND=dp), PARAMETER :: zero=0.0_dp, one=1.0_dp
                REAL(KIND=dp), PARAMETER :: two=2.0_dp
                REAL(KIND=dp) :: x,z,v,w
                INTEGER :: i, j, ind                                    ! help variable
                
                INTEGER :: hit1, hit2                     ! Number of the active partial objective for f1 and for f2
                REAL(KIND=dp) :: f_sign1, f_sign2         ! sign of the active partial objective for f1 and for f2       
                REAL(KIND=dp), DIMENSION(3) :: f_k, a                   
                REAL(KIND=dp), DIMENSION(user_n) :: f_i                

                
                SELECT CASE(problem2)
                
                   CASE(0)
                     f = 0.0_dp
                     
                   !-------------------------------------
                   CASE(1)
                     apu = y(1)**2
                     DO i = 2, user_n
                       IF (apu < y(i)**2 ) THEN 
                          apu = y(i)**2
                       END IF
                     END DO
                     f = (user_n + 1.0_dp) * apu
                   !-------------------------------------

                   !-------------------------------------
                   !       Generalization of MAXQ
                   !-------------------------------------
                   CASE(2)  !
                     apu = y(1)**2
                     DO i = 2, user_n
                       IF (apu < y(i)**2 ) THEN 
                          apu = y(i)**2
                       END IF
                     END DO
                     f = apu
                   !-------------------------------------                   
                   
                   !-------------------------------------
                   CASE(3)
                     f = 0.0_dp
                     DO i = 1, user_n
                       f =  f + y(i)**2                             
                     END DO                    
                   !-------------------------------------
                   
                   !-------------------------------------
                   CASE(4)
                     apu = ABS(y(1))
                     DO i = 2, user_n
                       IF (apu < ABS(y(i)) ) THEN 
                          apu = ABS(y(i))
                       END IF
                     END DO
                     f = user_n * apu               
                   !-------------------------------------
                   
                   !-------------------------------------
                   CASE(5)
                     f = 0.0_dp
                     DO i = 1, user_n
                        f = f + ABS(y(i))                                   
                     END DO             
                   !-------------------------------------
                   
                   !-------------------------------------
                   CASE(6)
                     apu = ABS(summa(y,1,user_n)) 
                     DO j = 2, 20
                       IF (apu <= ABS(summa(y,j,user_n)) ) THEN 
                         apu = ABS(summa(y,j,user_n))
                       END IF
                     END DO
                     f = 20.0_dp * apu
                   !-------------------------------------
                   
                   !-------------------------------------
                   CASE(7)
                     f = 0.0_dp
                     DO j = 1, 20
                        f = f + ABS( summa(y,j,user_n) )
                     END DO 
                   !-------------------------------------
                   
                   !-------------------------------------
                   CASE(8)
                     f = 0.0_dp
                     DO i = 2, user_n
                         f = f + ABS( y(i) - y(i-1) )
                     END DO
                   !-------------------------------------
                   
                   !-------------------------------------
                   !       Generalization of MXHILB
                   !-------------------------------------                    
                   CASE(9)
                     f = 0.0_dp
                     hit1 = 1
                     DO j = 1,user_n
                       f = f + y(j)/REAL(j, KIND=dp)
                     END DO
                     f_sign1=SIGN(one,f)
                     f = ABS(f)
                     DO i = 2,user_n
                       x = zero
                          DO j = 1,user_n
                            x = x + y(j)/REAL(i+j-1, KIND=dp)
                          END DO
                       z = ABS(x)
                       IF (z > f) THEN
                         f=z
                         hit1=i
                         f_sign1=SIGN(one,x)
                       END IF
                     END DO
                   !------------------------------------
                    
                   !------------------------------------
                   !             Chained LQ
                   !------------------------------------                     
                   CASE(10)
                     f=zero
                     DO i=1,user_n-1
                       x = -y(i)-y(i+1)
                       z = -y(i)-y(i+1)+(y(i)*y(i)+y(i+1)*y(i+1)-one)
                       IF (x >= z) THEN
                         f=f+x
                       ELSE
                         f=f+z
                       END IF
                     END DO                   
                   !------------------------------------
                    
                   !------------------------------------
                   !           Chained CB3 I
                   !------------------------------------                     
                   CASE(11)
                     f=zero
                     DO i=1,user_n-1
                        z = y(i)*y(i)*y(i)*y(i)+y(i+1)*y(i+1)
                        v = (two-y(i))*(two-y(i))+ &
                            (two-y(i+1))*(two-y(i+1))
                        w = two*EXP(-y(i)+y(i+1))
                        x = MAX(z,v,w)
                        f = f+x
                     END DO                                     
                   !------------------------------------
                   
                   !------------------------------------
                   !           Chained CB3 II
                   !------------------------------------                     
                   CASE(12)
                     f=zero
                     f_k=zero 

                     DO i=1,user_n-1
                        f_k(1)=f_k(1)+y(i)*y(i)*y(i)*y(i)+y(i+1)*y(i+1)
                        f_k(2)=f_k(2)+(two-y(i))*(two-y(i))+ &
                            (two-y(i+1))*(two-y(i+1))
                        f_k(3)=f_k(3)+two*EXP(-y(i)+y(i+1))
                     END DO
                     f=MAX(f_k(1),f_k(2),f_k(3))
                   !------------------------------------   

                   !------------------------------------                     
                   CASE(13)
                     f = 0.0_dp

                     DO i = 1, user_n
                        f = f + ABS(y(i)) 
                        f = f + 10.0_dp * Max( 2.0_dp *(y(i)*y(i) - y(i) - 1.0_dp), 0.0_dp )
                     END DO                   

                   !------------------------------------                     
                   
                   !------------------------------------
                   CASE(14)
                     f = 0.0_dp
                     
                     apu = 0.0_dp
                     DO j =1, user_n
                        apu = apu + y(j)/(1+j-1.0_dp)
                     END DO
                     largest = ABS(apu) 
                     
                     DO i = 2, user_n
                        apu = 0.0_dp
                        DO j = 1, user_n
                          apu = apu + y(j)/(i+j-1.0_dp)
                        END DO
                        IF (ABS(apu) > largest) THEN 
                           largest = ABS(apu)
                        END IF
                     END DO
                     
                     f = user_n * largest 
                   !------------------------------------    

                   !------------------------------------
                   CASE(15)
                     f = 0.0_dp
                     
                     DO i = 1, user_n
                        apu = 0.0_dp
                        DO j = 1, user_n
                          apu = apu + y(j)/(i+j-1.0_dp)
                        END DO
                        f = f + ABS(apu)
                     END DO                   
                   !------------------------------------                   

                   !------------------------------------
                   CASE(16)
                     f = 0.0_dp
                     
                     DO i = 1, user_n-1
                         a(1) = y(i)**4 + y(i+1)**2
                         a(2) = (2.0_dp-y(i))**2 + (2.0_dp-y(i+1))**2
                         a(3) = 2.0_dp*EXP(-y(i)+y(i+1))
                         IF (a(1)>a(2)) THEN
                            IF (a(1)>a(3)) THEN
                              f_i(i) = a(1)
                            ELSE
                              f_i(i) = a(3)
                            END IF
                         ELSE
                            IF (a(2)>a(3)) THEN
                              f_i(i) = a(2)
                            ELSE
                              f_i(i) = a(3)
                            END IF      
                         END IF
                     END DO
                     
                     largest = f_i(1)
                     ind = 1
                     DO i =2, user_n-1
                         IF (f_i(i) > largest) THEN 
                            largest = f_i(i)
                            ind = i
                         END IF
                     END DO
                     
                     f = (user_n-1.0_dp)*largest                   
                   !------------------------------------   

                  !------------------------------------
                   CASE(17)
                     f = 0.0_dp
                     
                     apu = 0.0_dp
                     DO i = 1, user_n-1
                        apu = apu + y(i)**2 + (y(i+1)-1.0_dp)**2
                        apu = apu + y(i+1) -1.0_dp
                     END DO
                     
                    apu = 2.0_dp *apu
                    IF (apu > 0.0_dp) THEN
                       f = apu
                    END IF                   
                   !------------------------------------   

                   !------------------------------------
                   CASE(18)
                     f = 0.0_dp

                     DO i = 1, user_n-1
                        f = f + y(i)**2 + (y(i+1)-1.0_dp)**2
                        f = f + y(i+1) -1.0_dp
                     END DO                   
                   !------------------------------------                  
                
                
                END SELECT              
            


           END FUNCTION f2
           
           !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
           

        !********************************************************************************
        !                                                                               |
        !                SUBGRADIENTS OF THE DC COMPONENTS f_1 AND f_2                  |
        !                                                                               |       
        !********************************************************************************       
        
           FUNCTION subgradient_f1(y, problem1, user_n) RESULT(grad)
                !
                ! Calculates a subgradient of the DC component f_1 at a point 'y'.
                ! Variable 'problem1' identifies the objective function used.
                ! 'user_n' is the dimension of the problem              
                !
                ! NOTICE: * The dimension of 'y' has to be 'user_n'.
                !         * The dimension of 'grad' is also 'user_n'.
                !
                IMPLICIT NONE
                !**************************** NEEDED FROM USER *************************************
                REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: y    ! a point where the subgradient of the DC component f_1 is calculated
                INTEGER, INTENT(IN) :: problem1                 ! the objective function selected for the DC component f1                
                INTEGER, INTENT(IN) :: user_n                   ! the dimension of the problem
                !**************************** OTHER VARIABLES **************************************
                REAL(KIND=dp), DIMENSION(SIZE(y)) :: grad       ! the subgradient of the DC component f_1 at a point 'y'
                REAL(KIND=dp), PARAMETER :: zero=0.0_dp, one=1.0_dp
                REAL(KIND=dp), PARAMETER :: two=2.0_dp
                REAL(KIND=dp) :: x,z,v,w                
                REAL(KIND=dp) :: apu, f                             ! help variable
                REAL(KIND=dp) :: largest                            ! help variable
                INTEGER :: i, j, ind                                ! help variable
                
                INTEGER :: hit1, hit2                        ! Number of the active partial objective for f1 and for f2
                REAL(KIND=dp) :: f_sign1, f_sign2            ! sign of the active partial objective for f1 and for f2                  
                REAL(KIND=dp), DIMENSION(3) :: f_k, a                       
                REAL(KIND=dp), DIMENSION(user_n) :: abs_sign, f_i                      

                SELECT CASE(problem1)
                
                   CASE(0)
                      grad = 0.0_dp
                
                   !-------------------------------------
                   CASE(1)              
                     grad = 0.0_dp 
                     apu = y(1)**2
                     ind = 1
                     
                     DO i = 2, user_n
                        IF (apu < y(i)**2) THEN 
                          apu = y(i)**2
                          ind = i
                        END IF
                     END DO
                     grad(ind) = 2.0_dp * (user_n + 1.0_dp) * y(ind)
                   !-------------------------------------
                   
                   !-------------------------------------
                   !       Generalization of MAXQ
                   !-------------------------------------                   
                   CASE(2)              
                     grad = 0.0_dp 
                     apu = y(1)**2
                     ind = 1
                     
                     DO i = 2, user_n
                        IF (apu < y(i)**2) THEN 
                          apu = y(i)**2
                          ind = i
                        END IF
                     END DO
                     grad(ind) = 2.0_dp * y(ind)
                   !-------------------------------------                   
                   
                   !-------------------------------------
                   CASE(3)
                      grad = 2.0_dp * y                   
                   !-------------------------------------
                   
                   !-------------------------------------
                   CASE(4)
                     grad = 0.0_dp 
                     apu = ABS(y(1))
                     ind = 1
                
                     DO i = 2, user_n
                       IF (apu < ABS(y(i))) THEN 
                         apu = ABS(y(i))
                         ind = i
                       END IF
                     END DO
                
                     IF (y(ind) <= 0.0_dp) THEN 
                         grad(ind) = - user_n
                     ELSE 
                         grad(ind) = user_n
                    END IF                   
                   !-------------------------------------
                   
                   !-------------------------------------
                   CASE(5)
                   grad = 0.0_dp
                     DO i = 1, user_n
                       IF (y(i) <= 0.0_dp ) THEN 
                         grad(i) = -1.0_dp
                       ELSE
                         grad(i) = 1.0_dp
                       END IF
                     END DO
                     
                   !-------------------------------------
                   
                   !-------------------------------------
                   CASE(6)
                     grad = 0.0_dp 
                     apu = ABS(summa(y,1,user_n)) 
                     ind = 1

                     DO j = 2, 20
                       IF (apu <= ABS(summa(y,j,user_n)) ) THEN 
                         apu = ABS(summa(y,j,user_n))
                         ind = j
                       END IF
                     END DO

                     DO i = 1, user_n
                       grad(i) = (0.05_dp * ind)**(i-1)
                     END DO             
                
                     IF ( summa(y,ind,user_n) <= 0.0_dp ) THEN 
                         grad = -20.0_dp * grad
                     ELSE
                         grad = 20.0_dp * grad
                     END IF 
                   !-------------------------------------
                   
                   !-------------------------------------
                   CASE(7)
                     grad = 0.0_dp 

                     DO j = 1, 20
                      IF (summa(y,j,user_n) <= 0.0_dp) THEN 
                        DO i = 1, user_n
                            grad(i) = grad(i) - (0.05_dp * j)**(i-1)
                        END DO                  
                      ELSE 
                        DO i = 1, user_n
                            grad(i) = grad(i) + (0.05_dp * j)**(i-1)
                        END DO                   
                      END IF
                     END DO                   
                   !-------------------------------------
                   
                   !-------------------------------------
                   CASE(8)
                     grad = 0.0_dp
                
                     DO i = 2, user_n
                       IF ( y(i) - y(i-1) <= 0.0_dp) THEN
                         grad(i-1) = grad(i-1) + 1.0_dp 
                         grad(i) = grad(i) - 1.0_dp 
                       ELSE
                         grad(i-1) = grad(i-1) - 1.0_dp  
                         grad(i) = grad(i) + 1.0_dp     
                       END IF
                     END DO
                   !-------------------------------------
                   
                   !-------------------------------------
                   !       Generalization of MXHILB
                   !-------------------------------------                    
                   CASE(9)
                     f = 0.0_dp
                     hit1 = 1
                     DO j = 1,user_n
                       f = f + y(j)/REAL(j, KIND=dp)
                     END DO
                     f_sign1=SIGN(one,f)
                     f = ABS(f)
                     DO i = 2,user_n
                       x = zero
                          DO j = 1,user_n
                            x = x + y(j)/REAL(i+j-1, KIND=dp)
                          END DO
                       z = ABS(x)
                       IF (z > f) THEN
                         f=z
                         hit1=i
                         f_sign1=SIGN(one,x)
                       END IF
                     END DO
                     
                     DO i = 1,user_n
                        grad(i) = f_sign1/REAL(hit1+i-1, KIND=dp)
                     END DO                   
                   !-------------------------------------

                   !------------------------------------
                   !             Chained LQ
                   !------------------------------------                     
                   CASE(10)
                     grad(1) = zero
                     DO i=1,user_n-1
                        grad(i+1) = zero
                        x = -y(i)-y(i+1)
                        z = -y(i)-y(i+1)+(y(i)*y(i)+y(i+1)*y(i+1)-one)
                        IF (x >= z) THEN
                           grad(i) = grad(i)-one
                           grad(i+1) = -one
                        ELSE
                           grad(i) = grad(i)-one+two*y(i)
                           grad(i+1) = -one+two*y(i+1)
                        ENDIF
                     END DO                   
                   !------------------------------------
                    
                   !------------------------------------
                   !           Chained CB3 I
                   !------------------------------------                     
                   CASE(11)
                     grad(1) = zero
                     DO i=1,user_n-1
                       grad(i+1) = zero
                       z = y(i)*y(i)*y(i)*y(i)+y(i+1)*y(i+1)
                       v = (two-y(i))*(two-y(i))+ &
                            (two-y(i+1))*(two-y(i+1))
                       w = two*EXP(-y(i)+y(i+1))
                       x = MAX(z,v,w) 
                       IF (x == z) THEN
                          grad(i) = grad(i)+4.0_dp*y(i)*y(i)*y(i)
                          grad(i+1) = two*y(i+1)
                       ELSE IF (x == v) THEN
                          grad(i) = grad(i)+two*y(i)-4.0_dp
                          grad(i+1) = two*y(i+1)-4.0_dp
                       ELSE
                          grad(i) = grad(i) - w
                          grad(i+1) = w
                       END IF                   
                     END DO
                   !------------------------------------
                   
                   !------------------------------------
                   !           Chained CB3 II
                   !------------------------------------                     
                   CASE(12)
                   
                     f=zero
                     f_k=zero 

                     DO i=1,user_n-1
                        f_k(1)=f_k(1)+y(i)*y(i)*y(i)*y(i)+y(i+1)*y(i+1)
                        f_k(2)=f_k(2)+(two-y(i))*(two-y(i))+ &
                            (two-y(i+1))*(two-y(i+1))
                        f_k(3)=f_k(3)+two*EXP(-y(i)+y(i+1))
                     END DO
                     f=MAX(f_k(1),f_k(2),f_k(3))                   
                   
                     grad(1)=zero 
                     x = MAX(f_k(1),f_k(2),f_k(3))
                     IF (x == f_k(1)) THEN
                        DO i=1,user_n-1
                            grad(i) = grad(i)+4.0_dp*y(i)*y(i)*y(i)
                            grad(i+1) = two*y(i+1)
                        END DO 
                     ELSE IF (x == f_k(2)) THEN
                        DO i=1,user_n-1
                            grad(i) = grad(i)+two*y(i)-4.0_dp
                            grad(i+1) = two*y(i+1)-4.0_dp
                        END DO
                    ELSE
                        DO i=1,user_n-1
                           grad(i) = grad(i) - two*EXP(-y(i)+y(i+1))
                           grad(i+1) = two*EXP(-y(i)+y(i+1))
                        END DO
                    END IF

                   !------------------------------------                   
                   
                    !------------------------------------                     
                   CASE(13)
                     grad = 0.0_dp
                
                     DO i = 1, user_n
                        IF ( y(i) < 0.0_dp ) THEN 
                           grad(i) = -1.0_dp
                        ELSE
                           grad(i) = 1.0_dp
                        END IF 
                     
                        IF (2.0_dp*(y(i)*y(i)-y(i)-1.0_dp) > 0.0_dp) THEN
                           grad(i) = grad(i) + 20.0_dp*(2.0_dp*y(i)-1.0_dp )
                        END IF
                    END DO       
                   !------------------------------------                     
                   
                    !------------------------------------
                   CASE(14)
                     grad = 0.0_dp
                   
                     apu = 0.0_dp
                     DO j =1, user_n
                        apu = apu + y(j)/(1+j-1.0_dp)
                     END DO
                     IF (apu >= 0.0_dp) THEN 
                           abs_sign(1) = 1.0_dp
                     ELSE   
                           abs_sign(1) = -1.0_dp
                     END IF        
                     largest = ABS(apu) 
                     ind = 1
                     
                     DO i = 2, user_n
                        apu = 0.0_dp
                        DO j = 1, user_n
                          apu = apu + y(j)/(i+j-1.0_dp)
                        END DO
                        IF (apu >= 0.0_dp) THEN 
                           abs_sign(i) = 1.0_dp
                        ELSE   
                           abs_sign(i) = -1.0_dp
                        END IF
                        IF (ABS(apu) > largest) THEN 
                            largest = ABS(apu)
                            ind = i
                        END IF
                     END DO
                     
                     DO j = 1, user_n
                        grad(j) = abs_sign(ind) * user_n / (ind+j-1)
                     END DO   
                   !------------------------------------    

                   !------------------------------------
                   CASE(15)
                     grad = 0.0_dp
                     
                     DO i = 1, user_n
                        apu = 0.0_dp
                        DO j = 1, user_n
                          apu = apu + y(j)/(i+j-1.0_dp)
                        END DO
                        IF (apu >= 0.0_dp) THEN 
                           abs_sign(1) = 1.0_dp
                        ELSE   
                           abs_sign(1) = -1.0_dp
                        END IF
                        DO j = 1, user_n
                          grad(j) = grad(j) + abs_sign(1) / (i+j-1.0_dp)
                        END DO
                     END DO  
                   !------------------------------------                     

                   !------------------------------------
                   CASE(16)
                     grad = 0.0_dp
                     
                     DO i = 1, user_n-1
                         a(1) = y(i)**4 + y(i+1)**2
                         a(2) = (2.0_dp-y(i))**2 + (2.0_dp-y(i+1))**2
                         a(3) = 2.0_dp*EXP(-y(i)+y(i+1))
                         IF (a(1)>a(2)) THEN
                            IF (a(1)>a(3)) THEN
                              f_i(i) = a(1)
                            ELSE
                              f_i(i) = a(3)
                            END IF
                         ELSE
                            IF (a(2)>a(3)) THEN
                              f_i(i) = a(2)
                            ELSE
                              f_i(i) = a(3)
                            END IF      
                         END IF
                     END DO
                     
                     largest = f_i(1)
                     ind = 1
                     DO i =2, user_n-1
                         IF (f_i(i) > largest) THEN 
                            largest = f_i(i)
                            ind = i
                         END IF
                     END DO
                     
                         a(1) = y(ind)**4 + y(ind+1)**2
                         a(2) = (2.0_dp-y(ind))**2 + (2.0_dp-y(ind+1))**2
                         a(3) = 2.0_dp*EXP(-y(ind)+y(ind+1))
                         IF (a(1)>a(2)) THEN
                            IF (a(1)>a(3)) THEN
                              grad(ind) = 4.0_dp*y(ind)**3 
                              grad(ind+1) = 2.0_dp*y(ind+1)
                            ELSE
                              grad(ind) = -2.0_dp * EXP(-y(ind)+y(ind+1)) 
                              grad(ind+1) = 2.0_dp * EXP(-y(ind)+y(ind+1)) 
                            END IF
                         ELSE
                            IF (a(2)>a(3)) THEN
                              grad(ind) = -2.0_dp * (2.0_dp -y(ind))
                              grad(ind+1) = -2.0_dp * (2.0_dp -y(ind+1))
                            ELSE
                              grad(ind) = -2.0_dp * EXP(-y(ind)+y(ind+1)) 
                              grad(ind+1) = 2.0_dp * EXP(-y(ind)+y(ind+1)) 
                            END IF      
                         END IF                  
                     
                     grad = (user_n-1.0_dp)*grad
                   !------------------------------------    

                   !------------------------------------
                   CASE(17)
                     grad = 0.0_dp
                     
                     apu = 0.0_dp
                     DO i = 1, user_n-1
                        apu = apu + y(i)**2 + (y(i+1)-1.0_dp)**2
                        apu = apu + y(i+1) -1.0_dp
                     END DO
                     
                    apu = 2.0_dp *apu
                    IF (apu > 0.0_dp) THEN
                       DO i = 1, user_n-1
                          grad(i) = grad(i) + 4.0_dp *y(i)
                          grad(i+1) = grad(i+1) + 4.0_dp *(y(i+1)-1.0_dp) +2.0_dp
                       END DO
                    END IF
                   !------------------------------------  

                   !------------------------------------
                   CASE(18)
                     grad = 0.0_dp

                     DO i = 1, user_n-1
                        grad(i) = grad(i) + 2.0_dp * y(i) 
                        grad(i+1) = grad(i+1) + 2.0_dp * (y(i+1) -1.0_dp) +1.0_dp
                     END DO
                   !------------------------------------    

                   
                END SELECT                      
                
           END FUNCTION subgradient_f1      
           
           !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
           
           FUNCTION subgradient_f2(y, problem2, user_n) RESULT(grad)                
                !
                ! Calculate a subgradient of the DC component f_2 at a point 'y'.
                ! Variable 'problem1' identifies the objective function used.
                ! 'user_n' is the dimension of the problem              
                !
                ! NOTICE: * The dimension of 'y' has to be 'user_n'.
                !         * The dimension of 'grad' is also 'user_n'.
                !
                IMPLICIT NONE
                !**************************** NEEDED FROM USER *************************************
                REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: y    ! a point where the subgradient of the DC component f_2 is calculated
                INTEGER, INTENT(IN) :: problem2                 ! the objective function selected for the DC component f2
                INTEGER, INTENT(IN) :: user_n                   ! the dimension of the problem
                !**************************** OTHER VARIABLES **************************************
                REAL(KIND=dp), DIMENSION(SIZE(y)) :: grad       ! the subgradient of the DC component f_1 at a point 'y'
                REAL(KIND=dp), PARAMETER :: zero=0.0_dp, one=1.0_dp
                REAL(KIND=dp), PARAMETER :: two=2.0_dp
                REAL(KIND=dp) :: x,z,v,w                
                REAL(KIND=dp) :: apu, f                             ! help variable
                REAL(KIND=dp) :: largest                            ! help variable
                INTEGER :: i, j, ind                                ! help variable
                  
                INTEGER :: hit1, hit2                     ! Number of the active partial objective for f1 and for f2
                REAL(KIND=dp) :: f_sign1, f_sign2         ! sign of the active partial objective for f1 and for f2                  
                REAL(KIND=dp), DIMENSION(3) :: f_k                      
                REAL(KIND=dp), DIMENSION(3) :: a                       
                REAL(KIND=dp), DIMENSION(user_n) :: abs_sign                         
                REAL(KIND=dp), DIMENSION(user_n) :: f_i                             
                
                SELECT CASE(problem2)
                
                   CASE(0)
                     grad = 0.0_dp
                
                
                   !-------------------------------------
                   CASE(1)              
                     grad = 0.0_dp 
                     apu = y(1)**2
                     ind = 1
                     
                     DO i = 2, user_n
                        IF (apu < y(i)**2) THEN 
                          apu = y(i)**2
                          ind = i
                        END IF
                     END DO
                     grad(ind) = 2.0_dp * (user_n + 1.0_dp) * y(ind)
                   !-------------------------------------
                   
                   !-------------------------------------
                   !       Generalization of MAXQ
                   !-------------------------------------                   
                   CASE(2)              
                     grad = 0.0_dp 
                     apu = y(1)**2
                     ind = 1
                     
                     DO i = 2, user_n
                        IF (apu < y(i)**2) THEN 
                          apu = y(i)**2
                          ind = i
                        END IF
                     END DO
                     grad(ind) = 2.0_dp * y(ind)
                   !-------------------------------------                   
                   
                   !-------------------------------------
                   CASE(3)
                      grad = 2.0_dp * y                   
                   !-------------------------------------
                   
                   !-------------------------------------
                   CASE(4)
                     grad = 0.0_dp 
                     apu = ABS(y(1))
                     ind = 1
                
                     DO i = 2, user_n
                       IF (apu < ABS(y(i))) THEN 
                         apu = ABS(y(i))
                         ind = i
                       END IF
                     END DO
                
                     IF (y(ind) <= 0.0_dp) THEN 
                         grad(ind) = - user_n
                     ELSE 
                         grad(ind) = user_n
                    END IF                   
                   !-------------------------------------
                   
                   !-------------------------------------
                   CASE(5)
                   grad = 0.0_dp
                     DO i = 1, user_n
                       IF (y(i) <= 0.0_dp ) THEN 
                         grad(i) = -1.0_dp
                       ELSE
                         grad(i) = 1.0_dp
                       END IF
                     END DO
                   !-------------------------------------
                   
                   !-------------------------------------
                   CASE(6)
                     grad = 0.0_dp 
                     apu = ABS(summa(y,1,user_n)) 
                     ind = 1

                     DO j = 2, 20
                       IF (apu <= ABS(summa(y,j,user_n)) ) THEN 
                         apu = ABS(summa(y,j,user_n))
                         ind = j
                       END IF
                     END DO

                     DO i = 1, user_n
                       grad(i) = (0.05_dp * ind)**(i-1)
                     END DO             
                
                     IF ( summa(y,ind,user_n) <= 0.0_dp ) THEN 
                         grad = -20.0_dp * grad
                     ELSE
                         grad = 20.0_dp * grad
                     END IF 
                   !-------------------------------------
                   
                   !-------------------------------------
                   CASE(7)
                     grad = 0.0_dp 

                     DO j = 1, 20
                      IF (summa(y,j,user_n) <= 0.0_dp) THEN 
                        DO i = 1, user_n
                            grad(i) = grad(i) - (0.05_dp * j)**(i-1)
                        END DO                  
                      ELSE 
                        DO i = 1, user_n
                            grad(i) = grad(i) + (0.05_dp * j)**(i-1)
                        END DO                   
                      END IF
                     END DO                   
                   !-------------------------------------
                   
                   !-------------------------------------
                   CASE(8)
                     grad = 0.0_dp
                
                     DO i = 2, user_n
                       IF ( y(i) - y(i-1) <= 0.0_dp) THEN
                         grad(i-1) = grad(i-1) + 1.0_dp 
                         grad(i) = grad(i) - 1.0_dp 
                       ELSE
                         grad(i-1) = grad(i-1) - 1.0_dp  
                         grad(i) = grad(i) + 1.0_dp     
                       END IF
                     END DO
                   !-------------------------------------
                   
                   !-------------------------------------
                   !       Generalization of MXHILB
                   !-------------------------------------                    
                   CASE(9)
                     f = 0.0_dp
                     hit1 = 1
                     DO j = 1,user_n
                       f = f + y(j)/REAL(j, KIND=dp)
                     END DO
                     f_sign1=SIGN(one,f)
                     f = ABS(f)
                     DO i = 2,user_n
                       x = zero
                          DO j = 1,user_n
                            x = x + y(j)/REAL(i+j-1, KIND=dp)
                          END DO
                       z = ABS(x)
                       IF (z > f) THEN
                         f=z
                         hit1=i
                         f_sign1=SIGN(one,x)
                       END IF
                     END DO
                     
                     DO i = 1,user_n
                        grad(i) = f_sign1/REAL(hit1+i-1, KIND=dp)
                     END DO                   
                   !-------------------------------------

                   !------------------------------------
                   !             Chained LQ
                   !------------------------------------                     
                   CASE(10)
                     grad(1) = zero
                     DO i=1,user_n-1
                        grad(i+1) = zero
                        x = -y(i)-y(i+1)
                        z = -y(i)-y(i+1)+(y(i)*y(i)+y(i+1)*y(i+1)-one)
                        IF (x >= z) THEN
                           grad(i) = grad(i)-one
                           grad(i+1) = -one
                        ELSE
                           grad(i) = grad(i)-one+two*y(i)
                           grad(i+1) = -one+two*y(i+1)
                        ENDIF
                     END DO                   
                   !------------------------------------
                    
                   !------------------------------------
                   !           Chained CB3 I
                   !------------------------------------                     
                   CASE(11)
                     grad(1) = zero
                     DO i=1,user_n-1
                       grad(i+1) = zero
                       z = y(i)*y(i)*y(i)*y(i)+y(i+1)*y(i+1)
                       v = (two-y(i))*(two-y(i))+ &
                            (two-y(i+1))*(two-y(i+1))
                       w = two*EXP(-y(i)+y(i+1))
                       x = MAX(z,v,w) 
                       IF (x == z) THEN
                          grad(i) = grad(i)+4.0_dp*y(i)*y(i)*y(i)
                          grad(i+1) = two*y(i+1)
                       ELSE IF (x == v) THEN
                          grad(i) = grad(i)+two*y(i)-4.0_dp
                          grad(i+1) = two*y(i+1)-4.0_dp
                       ELSE
                          grad(i) = grad(i) - w
                          grad(i+1) = w
                       END IF                   
                     END DO
                   !------------------------------------
                   
                   !------------------------------------
                   !           Chained CB3 II
                   !------------------------------------                     
                   CASE(12)
                   
                     f=zero
                     f_k=zero 

                     DO i=1,user_n-1
                        f_k(1)=f_k(1)+y(i)*y(i)*y(i)*y(i)+y(i+1)*y(i+1)
                        f_k(2)=f_k(2)+(two-y(i))*(two-y(i))+ &
                            (two-y(i+1))*(two-y(i+1))
                        f_k(3)=f_k(3)+two*EXP(-y(i)+y(i+1))
                     END DO
                     f=MAX(f_k(1),f_k(2),f_k(3))                   
                   
                     grad(1)=zero 
                     x = MAX(f_k(1),f_k(2),f_k(3))
                     IF (x == f_k(1)) THEN
                        DO i=1,user_n-1
                            grad(i) = grad(i)+4.0_dp*y(i)*y(i)*y(i)
                            grad(i+1) = two*y(i+1)
                        END DO 
                     ELSE IF (x == f_k(2)) THEN
                        DO i=1,user_n-1
                            grad(i) = grad(i)+two*y(i)-4.0_dp
                            grad(i+1) = two*y(i+1)-4.0_dp
                        END DO
                    ELSE
                        DO i=1,user_n-1
                           grad(i) = grad(i) - two*EXP(-y(i)+y(i+1))
                           grad(i+1) = two*EXP(-y(i)+y(i+1))
                        END DO
                    END IF

                   !------------------------------------                   
                   
                    !------------------------------------                     
                   CASE(13)
                     grad = 0.0_dp
                
                     DO i = 1, user_n
                        IF ( y(i) < 0.0_dp ) THEN 
                           grad(i) = -1.0_dp
                        ELSE
                           grad(i) = 1.0_dp
                        END IF 
                     
                        IF (2.0_dp*(y(i)*y(i)-y(i)-1.0_dp) > 0.0_dp) THEN
                           grad(i) = grad(i) + 20.0_dp*(2.0_dp*y(i)-1.0_dp )
                        END IF
                    END DO       
                   !------------------------------------                     
                   
                   !------------------------------------
                   CASE(14)
                     grad = 0.0_dp
                   
                     apu = 0.0_dp
                     DO j =1, user_n
                        apu = apu + y(j)/(1+j-1.0_dp)
                     END DO
                     IF (apu >= 0.0_dp) THEN 
                           abs_sign(1) = 1.0_dp
                     ELSE   
                           abs_sign(1) = -1.0_dp
                     END IF        
                     largest = ABS(apu) 
                     ind = 1
                     
                     DO i = 2, user_n
                        apu = 0.0_dp
                        DO j = 1, user_n
                          apu = apu + y(j)/(i+j-1.0_dp)
                        END DO
                        IF (apu >= 0.0_dp) THEN 
                           abs_sign(i) = 1.0_dp
                        ELSE   
                           abs_sign(i) = -1.0_dp
                        END IF
                        IF (ABS(apu) > largest) THEN 
                            largest = ABS(apu)
                            ind = i
                        END IF
                     END DO
                     
                     DO j = 1, user_n
                        grad(j) = abs_sign(ind) * user_n / (ind+j-1)
                     END DO   
                   !------------------------------------    

                   !------------------------------------
                   CASE(15)
                     grad = 0.0_dp
                     
                     DO i = 1, user_n
                        apu = 0.0_dp
                        DO j = 1, user_n
                          apu = apu + y(j)/(i+j-1.0_dp)
                        END DO
                        IF (apu >= 0.0_dp) THEN 
                           abs_sign(1) = 1.0_dp
                        ELSE   
                           abs_sign(1) = -1.0_dp
                        END IF
                        DO j = 1, user_n
                          grad(j) = grad(j) + abs_sign(1)/(i+j-1.0_dp)
                        END DO
                     END DO  
                   !------------------------------------                     

                   !------------------------------------
                   CASE(16)
                     grad = 0.0_dp
                     
                     DO i = 1, user_n-1
                         a(1) = y(i)**4 + y(i+1)**2
                         a(2) = (2.0_dp-y(i))**2 + (2.0_dp-y(i+1))**2
                         a(3) = 2.0_dp*EXP(-y(i)+y(i+1))
                         IF (a(1)>a(2)) THEN
                            IF (a(1)>a(3)) THEN
                              f_i(i) = a(1)
                            ELSE
                              f_i(i) = a(3)
                            END IF
                         ELSE
                            IF (a(2)>a(3)) THEN
                              f_i(i) = a(2)
                            ELSE
                              f_i(i) = a(3)
                            END IF      
                         END IF
                     END DO
                     
                     largest = f_i(1)
                     ind = 1
                     DO i =2, user_n-1
                         IF (f_i(i) > largest) THEN 
                            largest = f_i(i)
                            ind = i
                         END IF
                     END DO
                     
                         a(1) = y(ind)**4 + y(ind+1)**2
                         a(2) = (2.0_dp-y(ind))**2 + (2.0_dp-y(ind+1))**2
                         a(3) = 2.0_dp*EXP(-y(ind)+y(ind+1))
                         IF (a(1)>a(2)) THEN
                            IF (a(1)>a(3)) THEN
                              grad(ind) = 4.0_dp*y(ind)**3 
                              grad(ind+1) = 2.0_dp*y(ind+1)
                            ELSE
                              grad(ind) = -2.0_dp * EXP(-y(ind)+y(ind+1)) 
                              grad(ind+1) = 2.0_dp * EXP(-y(ind)+y(ind+1)) 
                            END IF
                         ELSE
                            IF (a(2)>a(3)) THEN
                              grad(ind) = -2.0_dp * (2.0_dp -y(ind))
                              grad(ind+1) = -2.0_dp * (2.0_dp -y(ind+1))
                            ELSE
                              grad(ind) = -2.0_dp * EXP(-y(ind)+y(ind+1)) 
                              grad(ind+1) = 2.0_dp * EXP(-y(ind)+y(ind+1)) 
                            END IF      
                         END IF                  
                     
                     grad = (user_n-1.0_dp)*grad
                   !------------------------------------    

                   !------------------------------------
                   CASE(17)
                     grad = 0.0_dp
                     
                     apu = 0.0_dp
                     DO i = 1, user_n-1
                        apu = apu + y(i)**2 + (y(i+1)-1.0_dp)**2
                        apu = apu + y(i+1) -1.0_dp
                     END DO
                     
                    apu = 2.0_dp *apu
                    IF (apu > 0.0_dp) THEN
                       DO i = 1, user_n-1
                          grad(i) = grad(i) + 4.0_dp *y(i)
                          grad(i+1) = grad(i+1) + 4.0_dp *(y(i+1)-1.0_dp) +2.0_dp
                       END DO
                    END IF
                   !------------------------------------  

                   !------------------------------------
                   CASE(18)
                     grad = 0.0_dp

                     DO i = 1, user_n-1
                        grad(i) = grad(i) + 2.0_dp * y(i) 
                        grad(i+1) = grad(i+1) + 2.0_dp * (y(i+1) -1.0_dp) +1.0_dp
                     END DO
                   !------------------------------------                   
                
                END SELECT  

           END FUNCTION subgradient_f2
           
           !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -      
           
           
           FUNCTION summa(y, j, user_n) RESULT(f)           
                !
                ! Calculates the sum used in f_1 and f_2 for parameter t_j
                !
                ! NOTICE: The dimension of 'y' has to be 'n'. 'j' needs to be an integer from interval [1,20]
                !
                IMPLICIT NONE
                !**************************** NEEDED FROM USER *************************************
                REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: y    ! a point where the function value of the DC component f_2 is calculated
                INTEGER, INTENT(IN) ::  j    ! used to determines the parameter t_j
                INTEGER, INTENT(IN) :: user_n                   ! the dimension of the problem
                !**************************** OTHER VARIABLES **************************************
                REAL(KIND=dp) :: f, t, apu                          ! the function value of the sum used in f_1 and parameter t_j
                INTEGER :: i                                    ! help variable
                
                f = 0.0_dp
                apu = 1.0_dp/ user_n
                
                DO i = 1, user_n 
                    t = (0.05_dp * j )**(i-1)
                    f = f + (y(i)-apu)*t            
                END DO 
            
           END FUNCTION summa



           
      END MODULE functions     