!*************************************************************************
!*                                                                       *
!*     Computation of the value of the clusterwise linear regression     *
!*     problem and the corresbonding subgradient.                        *
!*     (last modified 15.07.2016).                                       *
!*                                                                       *
!*************************************************************************
!*
!*     Modules included:
!*
!*     obj_fun         !
!*

MODULE clrobjfun  ! Computation of the value and the subgradient of the
                  ! objective function.

    USE r_precision, ONLY : prec  ! Precision for reals.
    IMPLICIT NONE

    PUBLIC :: &
        myf,    &   ! Computation of the value of the objective.
        myg         ! Computation of the subgradient of the objective.

CONTAINS
    !************************************************************************
    !*                                                                      *
    !*     * SUBROUTINE myf *                                               *
    !*                                                                      *
    !*     Computation of the value of the objective.                       *
    !*                                                                      *
    !************************************************************************
     
    SUBROUTINE myf(n,x,f,iterm)

        USE param, ONLY : large    ! Parameters.
        USE initclr, ONLY : ns     ! Switch for auxiliary and real clustering problem.

        USE clrfunctionmod, ONLY : &
            auxfunc, &             ! S Computation of auxiliary clustering problem
            clrfunc, &                ! S Computation of clustering problem
            fvb

        IMPLICIT NONE

        ! Array Arguments
        REAL(KIND=prec), DIMENSION(n), INTENT(IN) :: &
            x  ! Vector of variables.

        ! Scalar Arguments
        REAL(KIND=prec), INTENT(OUT) :: f  ! Value of the function.
        INTEGER, INTENT(IN) :: n           ! Number of variables.
        INTEGER, INTENT(OUT) :: iterm      ! Cause of termination:
                                           !   0  - Everything is ok.
                                           !  -3  - Failure in function calculations

        iterm = 0

        ! Function evaluation
        IF (ns == 1) THEN  ! Auxiliary problem
            CALL auxfunc(x,f)
        ELSE IF (ns==3) THEN
            CALL fvb(x,f)
        ELSE  ! Clustering problem
            CALL clrfunc(x,f)
        END IF

        ! Error checking.
        !    IF (f > large) iterm = -3  !
        !    IF (f < -large) iterm = -3 !
        RETURN
      
    END SUBROUTINE myf

    !************************************************************************
    !*                                                                      *
    !*     * SUBROUTINE myg *                                               *
    !*                                                                      *
    !*     Computation of the subgradient of the objective function.        *
    !*                                                                      *
    !************************************************************************
     
    SUBROUTINE myg(n,x,g,iterm)

        USE initclr, ONLY : ns     ! Switch for auxiliary and real clustering problem.
        USE clrfunctionmod, ONLY : &
            fgrad, &
            fgrad1, &            ! S Computation of the subgradient of the
            fgrad2, &                !   clusterwise linear regression function
            gradient

        IMPLICIT NONE

        ! Array Arguments
        REAL(KIND=prec), DIMENSION(n), INTENT(IN) :: x  ! Vector of variables.
        REAL(KIND=prec), DIMENSION(n), INTENT(OUT) :: g ! Subgradient.

        ! Scalar Arguments
        INTEGER, INTENT(IN) :: n                        ! Number of variables.
        INTEGER, INTENT(OUT) :: iterm                   ! Cause of termination:
                                                        !   0  - Everything is ok.
                                                        !  -3  - Failure in subgradient calculations
                                                        !        (assigned by the user).
        ! Local variables
        REAL(KIND=prec), DIMENSION(n) :: g2             ! Auxiliary subgradient.


        iterm = 0

        ! Gradient evaluation.
        IF (ns == 3) THEN
            CALL gradient(x,g)
        ELSE
            CALL fgrad(x,g)
            !CALL fgrad1(x,g)
            !CALL fgrad2(x,g2)
            !g=g-g2
        END IF
        RETURN

    END SUBROUTINE myg

END MODULE clrobjfun
