!*************************************************************************
!*                                                                       *
!*     SMDB - Splitting metrics diagonal bundle method for nonsmooth     *
!*     nonconvex optimization                                           *
!*                                                                       *
!*                                                                       *
!*     by Napsu Karmitsa 2016 (last modified 2016)                       *
!*                                                                       *
!*                                                                       *
!*     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 included in SMDB:
!* 
!*     tsmdb.f95            - mainprogram for SMDB (this file).
!*     initialization.f95   - user-specified initial values for parameters 
!*                            and starting point x.
!*     objfun.f95           - user-specified computation of the objective.
!*                            function value (and the subgradient).
!*     parameters.f95       - parameters.
!*     smdb.f95             - SMDB method.
!*     subpro.f95           - subprograms.
!*     Makefile             - makefile.
!*
!*     testps.f95           - large-scale nonsmooth test problems 
!*                            (includes also partially separable problems).
!*
!*     To use the software modify tsmdb.f95, initialization.f95 and 
!*     objfun.f95 as needed.
!*
!*
!*     References:
!*
!*     N. Karmitsa, M. Gaudioso and K. Joki: "Splitting Metrics Diagonal 
!*     Bundle Method for Large-Scale Nonconvex Nonsmooth Optimization"
!*
!*
!*************************************************************************
!*
!*     * PROGRAM tsmdb *
!*
!*     Main program for SMDB subroutine for unconstrained 
!*     nonsmooth optimization.
!*
!*************************************************************************

PROGRAM tsmdb

  USE r_precision, ONLY : prec      ! Precision for reals.
  USE initializat, ONLY : init_x,init_par,n,x  ! Initialization of x and parameters.
  USE exe_time, ONLY : getime       ! Execution time.
  USE smdb_mod, ONLY : init_smdb,smdb  ! SMDB
  USE problem_data, ONLY : next     ! Number of the problem 
                                    ! (remove this when you use your own problem).
  IMPLICIT NONE

! Scalar Arguments
  REAL(KIND=prec) :: f              ! Value of the objective function.

! Array Arguments
  INTEGER, DIMENSION(4) :: iout     ! Output integer parameters.
                                    !   iout(1)   Number of used iterations.
                                    !   iout(2)   Number of used function evaluations.
                                    !   iout(3)   Number of used subgradient evaluations.
                                    !   iout(4)   Cause of termination:
                                    !               1  - The problem has been solved
                                    !                    with desired accuracy.
                                    !               2  - Changes in function values < tolf in mtesf
                                    !                    subsequent iterations.
                                    !               3  - Changes in function value < 
                                    !                    tolf*small*MAX(|f_k|,|f_(k-1)|,1),
                                    !                    where small is the smallest positive number
                                    !                    such that 1.0 + small > 1.0.
                                    !               4  - Number of function calls > mfe.
                                    !               5  - Number of iterations > mit.
                                    !               6  - Time limit exceeded. 
                                    !               7  - f < tolb.
                                    !              -1  - Two consecutive restarts.
                                    !              -2  - Number of restarts > maximum number
                                    !                    of restarts.
                                    !              -3  - Failure in function or subgradient
                                    !                    calculations (assigned by the user).
                                    !              -4  - Failure in attaining the demanded
                                    !                    accuracy.
                                    !              -5  - Invalid input parameters.
                                    !              -6  - Unspecified error.

! Local Scalars
  INTEGER :: i,j
  REAL :: start,fini

  DO j=1,10  ! Loop for large-scale nonsmooth test problems
             ! (remove this if you use your own problem).

     next=j  ! Number of the test problem
             ! (remove this if you use your own problem).

     PRINT*,'next = ',next

! Initiation

     CALL init_x() 
     CALL init_par()


! CPU-time
    
     CALL getime(start)
     
! Solution

     CALL init_smdb(iout(4))  ! 
     IF (iout(4) /= 0) STOP 'Something wrong with the initial parameters.'

     CALL smdb(f,iout(1),iout(2),iout(3),iout(4),start)  

! CPU-time

     CALL getime(fini)


! Result (additional printout, remove ONLY -statement from USE initializat)
      
!     PRINT*
!     PRINT*,'next    = ',next
!     PRINT*,'iterm   = ',iout(4)
!     PRINT*
!     PRINT*,'f(x)    = ',f
!     PRINT*,'n       = ',n
!     PRINT*,'na      = ',na
!     PRINT*,'nit     = ',iout(1)
!     PRINT*,'nfe     = ',iout(2)
!     PRINT*,'nge     = ',iout(3)
!     PRINT*,'xmax    = ',xmax
!     PRINT*,'gam     = ',eta
!     PRINT*,'epsl    = ',epsl
!     PRINT*,'eps     = ',tolg
!     PRINT*,'scaling = ',iscale

!     PRINT*,x(1),x(2),x(3),x(4),x(5),x(6),x(7),x(8),x(9),x(10)
      
!     PRINT* 
!     PRINT*,'Used time = ',fini - start
!     PRINT* 

!     WRITE (6,FMT='(''SMDB'',1X,''n='',I7,2X,''Ni='',I7,1X,''Nf='',I7,1X, &
!          ''Ng='',I7,1X,''Nfg='',I7,1X,''f='',G15.8,2X,''Term='',I3,2X,''cpu='',F9.4,2X)') &
!          ,n,iout(1),iout(2),iout(3),iout(2)+iout(3),f,iout(4),fini - start
!     PRINT*
!      PRINT*

  100  CONTINUE
  END DO

  STOP

END PROGRAM tsmdb
      
