        !*..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..*
        !| .**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**. |
        !| |                                                                                  | |
        !| |                                                                                  | |
        !| |      SUBGDC - THE AGGREGATE SUBGRADIENT METHOD FOR NONSMOOTH DC OPTIMIZATION     | | 
        !| |                                 (version 1)                                      | |
        !| |                                                                                  | |
        !| |                                                                                  | |
        !| |                                                                                  | |
        !| |                       by Kaisa Joki (last modified February 2019)                | |
        !| |                                                                                  | |
        !| |                                                                                  | |
        !| |                                                                                  | |
        !| |                                                                                  | |
        !| |     The software is free for academic teaching and research purposes but I       | |
        !| |     ask you to refer the reference given below, if you use it.                   | |
        !| |                                                                                  | |
        !| |                                                                                  | |
        !| .**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**. |
        !*..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..*     
        !|                                                                                      |
        !|                                                                                      |
        !| .**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**. |
        !*..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..*
        !|                                                                                      |
        !|                                                                                      |
        !|   Codes include:                                                                     |
        !|                                                                                      |
        !|   tsubgdc.f95        - Main program for SUBGDC (this file)                           |
        !|   constants.f95      - Double precision                                              |
        !|   functions.f95      - User-specified DC components f_1 and f_2 together with        |
        !|                        subgradients of DC components. Contains also user-specified   |
        !|                        initial values for parameters                                 |
        !|   subgdc.f95         - SUBGDC method                                                 |
        !|                                                                                      |
        !|   Makefile           - Makefile                                                      |
        !|                                                                                      |
        !|                                                                                      |
        !|                                                                                      |
        !|   To USE the software MODIFY   tsubgdc.f95 and functions.f95   as needed             |
        !|                                                                                      |
        !|                                                                                      |
        !|   References:                                                                        |
        !|                                                                                      |
        !|   [1] Adil M. Bagirov, Sona Taheri, Kaisa Joki, Napsu Karmitsa, Marko M. Mäkelä:     |
        !|       "A new subgradient based method for nonsmooth DC programming"                  |
        !|       TUCS Technical Report No. XXXX, Turku Centre for Computer Science,             | 
        !|       Turku, 2019.                                                                   |  
        !|                                                                                      |
        !|                                                                                      |
        !| .**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**. |
        !*..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..**..*       


      PROGRAM tsubgdc
      
         USE constants, ONLY : dp   ! double precision (i.e. accuracy)
         USE functions              ! INFORMATION from the USER
         USE subgdc                 ! SUBGDC method
         
        IMPLICIT NONE   
        
        ! 'user_n' is the number of variables in the problem (USER specifies this in functions.f95)
        REAL (KIND=dp), DIMENSION(user_n) :: x_0           ! The starting point in the SUBGDC method (specified by USER)
        REAL (KIND=dp), DIMENSION(user_n) :: x_solution    ! The solution obtained to the problem
        
        REAL(KIND=dp) :: f_solution         ! The objective function value at the solution 'x_solution'
        REAL(KIND=dp) :: f0                 ! The objective function value at the starting point 'x_0'
        
        REAL(KIND=dp) :: time               ! the CPU time
        REAL(KIND=dp) :: time_limit         ! the CPU time limit
        
        INTEGER, DIMENSION(6) :: counter    ! Contains the values of different counteres:
                                            !   counter(1) = serious_counter      the number of 'serious steps' executed
                                            !   counter(2) = iter_counter         the number of 'inner iterations' executed
                                            !   counter(3) = f_counter            the number of function values evaluated for DC component in the algorithm
                                            !   counter(4) = subgrad1_counter     the number of subgradients calculated for f_1 in the algorithm
                                            !   counter(5) = subgrad2_counter     the number of subgradients calculated for f_2 in the algortihm
                                            !   counter(6) = stop_cond_counter    the number of times tau is decreased 
 
    
        INTEGER :: iprint                   ! Variable that specifies print option (specified by USER): 
                                            !   iprint = 0 : print is suppressed
                                            !   iprint = 1 : basic print of final result 
                                            !   iprint = -1: basic print of final result (without the solution vector)
                                            !   iprint = 2 : extended print of final result 
                                            !   iprint = -2: extended print of final result (without the solution vector)
                                            !   iprint = 3 : basic print of intermediate results and extended print of final results
                                            !   iprint = -3: basic print of intermediate results and extended print of final results (without the solution vector)
                                            !   iprint = 4 : extended print of intermediate results and extended print of final results 
                                            !   iprint = -4: extended print of intermediate results and extended print of final results (without the solution vectors)
                                            !
                                            ! If 'iprint' <= -5 .OR. 'iprint' >= 5 then DEFAULT value 'iprint'=1 is used    
                                            
        
        INTEGER :: mit                      ! The maximum number of 'main iterations' (specified by USER).
                                            ! If 'mit' <=0 then DEFAULT value 'mit'=1000 is used

        INTEGER :: mrounds                  ! The maximum number of rounds during one 'main iteration' (specified by USER).
                                            ! If 'mrounds' <=0 then DEFAULT value 'mrounds'=5000 is used
                                            
        INTEGER :: termination              ! The reason for termination in SUBGDC:
                                            !   1 - the stopping condition satisfied
                                            !   2 - the biggest possible number of rounds executed in one 'inner iteration'
                                            !   3 - the biggest possible number of 'inner iterations' executed in the algorithm!
                                            !   4 - the CPU time limit is exceeded
                                            !   5 - the problem seems to be unbounded from below.
                                            !   6 - the difference in consecutive function values are small (the current point is compared to the one obtained 10 rounds ago).
                
        LOGICAL :: consecutive              ! .TRUE. if algorithm can be terminated if the difference between consecutive function values is small
        LOGICAL :: used_prob                ! .TRUE. if test problem is used
        
        INTEGER :: i

        
         
          mrounds = 100000           ! maximum number of rounds during one 'main iterations'
          mit = 100000               ! maximum number of 'main iteration'
          
          time_limit = 1800.0_dp     ! Time limit is 30 minutes
          
          consecutive = .TRUE.       ! If .TRUE. a stopping test comparing the difference between function values is used. 
                                     ! If .FALSE. then this extra stopping test is omitted.
          
          iprint = -2                ! basic print of intermediate results and extended print of final results
          

          
!--------------------------------------------------------------------------------------
          
! The starting points for the test problems   
        
        SELECT CASE(start_point)               
 
! Start point 1.  
! x_0 = (/ 1.0_dp, ... , 1.0_dp /)   
          CASE(1)
            x_0 = 1.0_dp
                      
! Start point 2.  
          CASE(2)
            DO i = 1, user_n/2
               x_0(i)  = 1.0_dp * i
            END DO
            DO i = (user_n/2 + 1), user_n
               x_0(i)  = -1.0_dp * i
            END DO  

            
! Start point 3.  
          CASE(3)
            x_0 = -1.0_dp
            DO i = 1,user_n, 2
              x_0(i) = 1.0_dp
            END DO  
          
          
! Start point 4.  
          CASE(4)
            x_0 = -1.5_dp
            DO i = 2, user_n, 2
               x_0(i) = 2.0_dp
            END DO

            
! Start point 5.  
          CASE(5)
            DO i = 1, user_n
               x_0(i)  =  i
            END DO  

            
          END SELECT
!--------------------------------------------------------------------------------------           
               

         WRITE(*,*) '------------------------------------------------------------------'
         WRITE(*,*) '** START ** START ** START ** START ** START ** START ** START **'  
         WRITE(*,*) '------------------------------------------------------------------'         
         WRITE(*,*) ' '

         
         
 
                     CALL SUBGDC_algorithm(x_0, x_solution, f_solution, f0, mit, mrounds, &
                            &  termination, counter, time, time_limit, iprint, &
                            &  consecutive )
                      

         
         WRITE(*,*) ' '
         WRITE(*,*) '------------------------------------------------------------------'
         WRITE(*,*) '** END ** END ** END ** END ** END ** END ** END ** END ** END **'  
         WRITE(*,*) '------------------------------------------------------------------'
         WRITE(*,*) ' '      

            
     
         CLOSE(45)   
         
         
      END PROGRAM tsubgdc






















