! This automatically generated Fortran wrapper file allows codes
! written in Fortran to be called directly from C and translates all
! C-style arguments into expected Fortran-style arguments (with
! assumed size, local type declarations, etc.).


MODULE C_MATRIX_MULTIPLICATION
USE ISO_FORTRAN_ENV , ONLY : RT => REAL32
  IMPLICIT NONE


CONTAINS


  
  SUBROUTINE C_GEMM(OP_A, OP_B, OUT_ROWS, OUT_COLS, INNER_DIM, AB_MULT, A_DIM_1, A_DIM_2, A, A_ROWS, B_DIM_1, B_DIM_2, B, B_ROWS, C&
&_MULT, C_DIM_1, C_DIM_2, C, C_ROWS) BIND(C)
    USE MATRIX_MULTIPLICATION, ONLY: GEMM
    IMPLICIT NONE
    CHARACTER, INTENT(IN) :: OP_A
    CHARACTER, INTENT(IN) :: OP_B
    INTEGER, INTENT(IN) :: OUT_ROWS
    INTEGER, INTENT(IN) :: OUT_COLS
    INTEGER, INTENT(IN) :: INNER_DIM
    REAL(KIND=RT), INTENT(IN) :: AB_MULT
    INTEGER, INTENT(IN) :: A_DIM_1
    INTEGER, INTENT(IN) :: A_DIM_2
    REAL(KIND=RT), INTENT(IN), DIMENSION(A_DIM_1,A_DIM_2) :: A
    INTEGER, INTENT(IN) :: A_ROWS
    INTEGER, INTENT(IN) :: B_DIM_1
    INTEGER, INTENT(IN) :: B_DIM_2
    REAL(KIND=RT), INTENT(IN), DIMENSION(B_DIM_1,B_DIM_2) :: B
    INTEGER, INTENT(IN) :: B_ROWS
    REAL(KIND=RT), INTENT(IN) :: C_MULT
    INTEGER, INTENT(IN) :: C_DIM_1
    INTEGER, INTENT(IN) :: C_DIM_2
    REAL(KIND=RT), INTENT(OUT), DIMENSION(C_DIM_1,C_DIM_2) :: C
    INTEGER, INTENT(IN) :: C_ROWS
  
    CALL GEMM(OP_A, OP_B, OUT_ROWS, OUT_COLS, INNER_DIM, AB_MULT, A, A_ROWS, B, B_ROWS, C_MULT, C, C_ROWS)
  END SUBROUTINE C_GEMM
  
END MODULE C_MATRIX_MULTIPLICATION


MODULE C_PLRM
USE ISO_FORTRAN_ENV , ONLY : RT => REAL32
USE MATRIX_MULTIPLICATION , ONLY : GEMM
  IMPLICIT NONE


  INTERFACE
    FUNCTION OMP_GET_MAX_THREADS()
      INTEGER :: OMP_GET_MAX_THREADS
    END FUNCTION OMP_GET_MAX_THREADS
  END INTERFACE

CONTAINS


  
  SUBROUTINE C_NEW_MODEL_CONFIG(MDI, MDO, MDS_PRESENT, MDS, MNS_PRESENT, MNS, MNE_PRESENT, MNE, MDE_PRESENT, MDE, NUM_THREADS_PRESE&
&NT, NUM_THREADS, CONFIG) BIND(C)
    USE PLRM, ONLY: NEW_MODEL_CONFIG
    USE PLRM, ONLY: MODEL_CONFIG
    IMPLICIT NONE
    INTEGER, INTENT(IN) :: MDI
    INTEGER, INTENT(IN) :: MDO
    LOGICAL, INTENT(IN) :: MDS_PRESENT
    INTEGER, INTENT(IN) :: MDS
    LOGICAL, INTENT(IN) :: MNS_PRESENT
    INTEGER, INTENT(IN) :: MNS
    LOGICAL, INTENT(IN) :: MNE_PRESENT
    INTEGER, INTENT(IN) :: MNE
    LOGICAL, INTENT(IN) :: MDE_PRESENT
    INTEGER, INTENT(IN) :: MDE
    LOGICAL, INTENT(IN) :: NUM_THREADS_PRESENT
    INTEGER, INTENT(IN) :: NUM_THREADS
    TYPE(MODEL_CONFIG), INTENT(OUT) :: CONFIG
  
    IF (MDS_PRESENT) THEN
      IF (MNS_PRESENT) THEN
        IF (MNE_PRESENT) THEN
          IF (MDE_PRESENT) THEN
            IF (NUM_THREADS_PRESENT) THEN
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MDS=MDS, MNS=MNS, MNE=MNE, MDE=MDE, NUM_THREADS=NUM_THREADS)
            ELSE
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MDS=MDS, MNS=MNS, MNE=MNE, MDE=MDE)
            END IF
          ELSE
            IF (NUM_THREADS_PRESENT) THEN
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MDS=MDS, MNS=MNS, MNE=MNE, NUM_THREADS=NUM_THREADS)
            ELSE
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MDS=MDS, MNS=MNS, MNE=MNE)
            END IF
          END IF
        ELSE
          IF (MDE_PRESENT) THEN
            IF (NUM_THREADS_PRESENT) THEN
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MDS=MDS, MNS=MNS, MDE=MDE, NUM_THREADS=NUM_THREADS)
            ELSE
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MDS=MDS, MNS=MNS, MDE=MDE)
            END IF
          ELSE
            IF (NUM_THREADS_PRESENT) THEN
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MDS=MDS, MNS=MNS, NUM_THREADS=NUM_THREADS)
            ELSE
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MDS=MDS, MNS=MNS)
            END IF
          END IF
        END IF
      ELSE
        IF (MNE_PRESENT) THEN
          IF (MDE_PRESENT) THEN
            IF (NUM_THREADS_PRESENT) THEN
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MDS=MDS, MNE=MNE, MDE=MDE, NUM_THREADS=NUM_THREADS)
            ELSE
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MDS=MDS, MNE=MNE, MDE=MDE)
            END IF
          ELSE
            IF (NUM_THREADS_PRESENT) THEN
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MDS=MDS, MNE=MNE, NUM_THREADS=NUM_THREADS)
            ELSE
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MDS=MDS, MNE=MNE)
            END IF
          END IF
        ELSE
          IF (MDE_PRESENT) THEN
            IF (NUM_THREADS_PRESENT) THEN
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MDS=MDS, MDE=MDE, NUM_THREADS=NUM_THREADS)
            ELSE
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MDS=MDS, MDE=MDE)
            END IF
          ELSE
            IF (NUM_THREADS_PRESENT) THEN
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MDS=MDS, NUM_THREADS=NUM_THREADS)
            ELSE
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MDS=MDS)
            END IF
          END IF
        END IF
      END IF
    ELSE
      IF (MNS_PRESENT) THEN
        IF (MNE_PRESENT) THEN
          IF (MDE_PRESENT) THEN
            IF (NUM_THREADS_PRESENT) THEN
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MNS=MNS, MNE=MNE, MDE=MDE, NUM_THREADS=NUM_THREADS)
            ELSE
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MNS=MNS, MNE=MNE, MDE=MDE)
            END IF
          ELSE
            IF (NUM_THREADS_PRESENT) THEN
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MNS=MNS, MNE=MNE, NUM_THREADS=NUM_THREADS)
            ELSE
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MNS=MNS, MNE=MNE)
            END IF
          END IF
        ELSE
          IF (MDE_PRESENT) THEN
            IF (NUM_THREADS_PRESENT) THEN
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MNS=MNS, MDE=MDE, NUM_THREADS=NUM_THREADS)
            ELSE
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MNS=MNS, MDE=MDE)
            END IF
          ELSE
            IF (NUM_THREADS_PRESENT) THEN
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MNS=MNS, NUM_THREADS=NUM_THREADS)
            ELSE
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MNS=MNS)
            END IF
          END IF
        END IF
      ELSE
        IF (MNE_PRESENT) THEN
          IF (MDE_PRESENT) THEN
            IF (NUM_THREADS_PRESENT) THEN
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MNE=MNE, MDE=MDE, NUM_THREADS=NUM_THREADS)
            ELSE
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MNE=MNE, MDE=MDE)
            END IF
          ELSE
            IF (NUM_THREADS_PRESENT) THEN
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MNE=MNE, NUM_THREADS=NUM_THREADS)
            ELSE
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MNE=MNE)
            END IF
          END IF
        ELSE
          IF (MDE_PRESENT) THEN
            IF (NUM_THREADS_PRESENT) THEN
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MDE=MDE, NUM_THREADS=NUM_THREADS)
            ELSE
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, MDE=MDE)
            END IF
          ELSE
            IF (NUM_THREADS_PRESENT) THEN
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG, NUM_THREADS=NUM_THREADS)
            ELSE
              CALL NEW_MODEL_CONFIG(MDI=MDI, MDO=MDO, CONFIG=CONFIG)
            END IF
          END IF
        END IF
      END IF
    END IF
  END SUBROUTINE C_NEW_MODEL_CONFIG
  

  
  SUBROUTINE C_INIT_MODEL(CONFIG, MODEL_DIM_1, MODEL, SEED_PRESENT, SEED) BIND(C)
    USE PLRM, ONLY: INIT_MODEL
    USE PLRM, ONLY: MODEL_CONFIG
    IMPLICIT NONE
    TYPE(MODEL_CONFIG), INTENT(IN) :: CONFIG
    INTEGER, INTENT(IN) :: MODEL_DIM_1
    REAL(KIND=RT), INTENT(IN), DIMENSION(MODEL_DIM_1) :: MODEL
    LOGICAL, INTENT(IN) :: SEED_PRESENT
    INTEGER, INTENT(IN) :: SEED
  
    IF (SEED_PRESENT) THEN
      CALL INIT_MODEL(CONFIG=CONFIG, MODEL=MODEL, SEED=SEED)
    ELSE
      CALL INIT_MODEL(CONFIG=CONFIG, MODEL=MODEL)
    END IF
  END SUBROUTINE C_INIT_MODEL
  

  
  SUBROUTINE C_RANDOM_UNIT_VECTORS(COLUMN_VECTORS_DIM_1, COLUMN_VECTORS_DIM_2, COLUMN_VECTORS) BIND(C)
    USE PLRM, ONLY: RANDOM_UNIT_VECTORS
    IMPLICIT NONE
    INTEGER, INTENT(IN) :: COLUMN_VECTORS_DIM_1
    INTEGER, INTENT(IN) :: COLUMN_VECTORS_DIM_2
    REAL(KIND=RT), INTENT(OUT), DIMENSION(COLUMN_VECTORS_DIM_1,COLUMN_VECTORS_DIM_2) :: COLUMN_VECTORS
  
    CALL RANDOM_UNIT_VECTORS(COLUMN_VECTORS)
  END SUBROUTINE C_RANDOM_UNIT_VECTORS
  

  
  SUBROUTINE C_UNPACK_EMBEDDINGS(CONFIG, EMBEDDINGS_DIM_1, EMBEDDINGS_DIM_2, EMBEDDINGS, INT_INPUTS_DIM_1, INT_INPUTS_DIM_2, INT_IN&
&PUTS, EMBEDDED_DIM_1, EMBEDDED_DIM_2, EMBEDDED) BIND(C)
    USE PLRM, ONLY: UNPACK_EMBEDDINGS
    USE PLRM, ONLY: MODEL_CONFIG
    IMPLICIT NONE
    TYPE(MODEL_CONFIG), INTENT(IN) :: CONFIG
    INTEGER, INTENT(IN) :: EMBEDDINGS_DIM_1
    INTEGER, INTENT(IN) :: EMBEDDINGS_DIM_2
    REAL(KIND=RT), INTENT(IN), DIMENSION(EMBEDDINGS_DIM_1,EMBEDDINGS_DIM_2) :: EMBEDDINGS
    INTEGER, INTENT(IN) :: INT_INPUTS_DIM_1
    INTEGER, INTENT(IN) :: INT_INPUTS_DIM_2
    INTEGER, INTENT(IN), DIMENSION(INT_INPUTS_DIM_1,INT_INPUTS_DIM_2) :: INT_INPUTS
    INTEGER, INTENT(IN) :: EMBEDDED_DIM_1
    INTEGER, INTENT(IN) :: EMBEDDED_DIM_2
    REAL(KIND=RT), INTENT(OUT), DIMENSION(EMBEDDED_DIM_1,EMBEDDED_DIM_2) :: EMBEDDED
  
    CALL UNPACK_EMBEDDINGS(CONFIG, EMBEDDINGS, INT_INPUTS, EMBEDDED)
  END SUBROUTINE C_UNPACK_EMBEDDINGS
  

  
  SUBROUTINE C_RESET_MIN_MAX(INPUT_MIN_DIM_1, INPUT_MIN, INPUT_MAX_DIM_1, INPUT_MAX, STATE_MIN_DIM_1, STATE_MIN_DIM_2, STATE_MIN, S&
&TATE_MAX_DIM_1, STATE_MAX_DIM_2, STATE_MAX) BIND(C)
    USE PLRM, ONLY: RESET_MIN_MAX
    IMPLICIT NONE
    INTEGER, INTENT(IN) :: INPUT_MIN_DIM_1
    REAL(KIND=RT), INTENT(INOUT), DIMENSION(INPUT_MIN_DIM_1) :: INPUT_MIN
    INTEGER, INTENT(IN) :: INPUT_MAX_DIM_1
    REAL(KIND=RT), INTENT(INOUT), DIMENSION(INPUT_MAX_DIM_1) :: INPUT_MAX
    INTEGER, INTENT(IN) :: STATE_MIN_DIM_1
    INTEGER, INTENT(IN) :: STATE_MIN_DIM_2
    REAL(KIND=RT), INTENT(INOUT), DIMENSION(STATE_MIN_DIM_1,STATE_MIN_DIM_2) :: STATE_MIN
    INTEGER, INTENT(IN) :: STATE_MAX_DIM_1
    INTEGER, INTENT(IN) :: STATE_MAX_DIM_2
    REAL(KIND=RT), INTENT(INOUT), DIMENSION(STATE_MAX_DIM_1,STATE_MAX_DIM_2) :: STATE_MAX
  
    CALL RESET_MIN_MAX(INPUT_MIN, INPUT_MAX, STATE_MIN, STATE_MAX)
  END SUBROUTINE C_RESET_MIN_MAX
  

  
  SUBROUTINE C_SET_MIN_MAX(CONFIG, MODEL_DIM_1, MODEL, X_DIM_1, X_DIM_2, X, XI_PRESENT, XI_DIM_1, XI_DIM_2, XI) BIND(C)
    USE PLRM, ONLY: SET_MIN_MAX
    USE PLRM, ONLY: MODEL_CONFIG
    IMPLICIT NONE
    TYPE(MODEL_CONFIG), INTENT(IN) :: CONFIG
    INTEGER, INTENT(IN) :: MODEL_DIM_1
    REAL(KIND=RT), INTENT(INOUT), DIMENSION(MODEL_DIM_1) :: MODEL
    INTEGER, INTENT(IN) :: X_DIM_1
    INTEGER, INTENT(IN) :: X_DIM_2
    REAL(KIND=RT), INTENT(IN), DIMENSION(X_DIM_1,X_DIM_2) :: X
    LOGICAL, INTENT(IN) :: XI_PRESENT
    INTEGER, INTENT(IN) :: XI_DIM_1
    INTEGER, INTENT(IN) :: XI_DIM_2
    INTEGER, INTENT(IN), DIMENSION(XI_DIM_1,XI_DIM_2) :: XI
  
    IF (XI_PRESENT) THEN
      CALL SET_MIN_MAX(CONFIG=CONFIG, MODEL=MODEL, X=X, XI=XI)
    ELSE
      CALL SET_MIN_MAX(CONFIG=CONFIG, MODEL=MODEL, X=X)
    END IF
  END SUBROUTINE C_SET_MIN_MAX
  

  
  SUBROUTINE C_CHECK_SHAPE(CONFIG, MODEL_DIM_1, MODEL, X_DIM_1, X_DIM_2, X, Y_DIM_1, Y_DIM_2, Y, XI_PRESENT, XI_DIM_1, XI_DIM_2, XI&
&, INFO) BIND(C)
    USE PLRM, ONLY: CHECK_SHAPE
    USE PLRM, ONLY: MODEL_CONFIG
    IMPLICIT NONE
    TYPE(MODEL_CONFIG), INTENT(IN) :: CONFIG
    INTEGER, INTENT(IN) :: MODEL_DIM_1
    REAL(KIND=RT), INTENT(IN), DIMENSION(MODEL_DIM_1) :: MODEL
    INTEGER, INTENT(IN) :: X_DIM_1
    INTEGER, INTENT(IN) :: X_DIM_2
    REAL(KIND=RT), INTENT(IN), DIMENSION(X_DIM_1,X_DIM_2) :: X
    INTEGER, INTENT(IN) :: Y_DIM_1
    INTEGER, INTENT(IN) :: Y_DIM_2
    REAL(KIND=RT), INTENT(IN), DIMENSION(Y_DIM_1,Y_DIM_2) :: Y
    LOGICAL, INTENT(IN) :: XI_PRESENT
    INTEGER, INTENT(IN) :: XI_DIM_1
    INTEGER, INTENT(IN) :: XI_DIM_2
    INTEGER, INTENT(IN), DIMENSION(XI_DIM_1,XI_DIM_2) :: XI
    INTEGER, INTENT(OUT) :: INFO
  
    IF (XI_PRESENT) THEN
      CALL CHECK_SHAPE(CONFIG=CONFIG, MODEL=MODEL, X=X, Y=Y, INFO=INFO, XI=XI)
    ELSE
      CALL CHECK_SHAPE(CONFIG=CONFIG, MODEL=MODEL, X=X, Y=Y, INFO=INFO)
    END IF
  END SUBROUTINE C_CHECK_SHAPE
  

  
  SUBROUTINE C_EVALUATE(CONFIG, MODEL_DIM_1, MODEL, X_DIM_1, X_DIM_2, X, XI_PRESENT, XI_DIM_1, XI_DIM_2, XI, Y_DIM_1, Y_DIM_2, Y, P&
&OSITIONS_PRESENT, POSITIONS_DIM_1, POSITIONS_DIM_2, POSITIONS_DIM_3, POSITIONS, EMBEDDINGS_PRESENT, EMBEDDINGS_DIM_1, EMBEDDINGS_D&
&IM_2, EMBEDDINGS_DIM_3, EMBEDDINGS, INFO) BIND(C)
    USE PLRM, ONLY: EVALUATE
    USE PLRM, ONLY: MODEL_CONFIG
    IMPLICIT NONE
    TYPE(MODEL_CONFIG), INTENT(IN) :: CONFIG
    INTEGER, INTENT(IN) :: MODEL_DIM_1
    REAL(KIND=RT), INTENT(IN), DIMENSION(MODEL_DIM_1) :: MODEL
    INTEGER, INTENT(IN) :: X_DIM_1
    INTEGER, INTENT(IN) :: X_DIM_2
    REAL(KIND=RT), INTENT(IN), DIMENSION(X_DIM_1,X_DIM_2) :: X
    LOGICAL, INTENT(IN) :: XI_PRESENT
    INTEGER, INTENT(IN) :: XI_DIM_1
    INTEGER, INTENT(IN) :: XI_DIM_2
    INTEGER, INTENT(IN), DIMENSION(XI_DIM_1,XI_DIM_2) :: XI
    INTEGER, INTENT(IN) :: Y_DIM_1
    INTEGER, INTENT(IN) :: Y_DIM_2
    REAL(KIND=RT), INTENT(OUT), DIMENSION(Y_DIM_1,Y_DIM_2) :: Y
    LOGICAL, INTENT(IN) :: POSITIONS_PRESENT
    INTEGER, INTENT(IN) :: POSITIONS_DIM_1
    INTEGER, INTENT(IN) :: POSITIONS_DIM_2
    INTEGER, INTENT(IN) :: POSITIONS_DIM_3
    INTEGER, INTENT(OUT), DIMENSION(POSITIONS_DIM_1,POSITIONS_DIM_2,POSITIONS_DIM_3) :: POSITIONS
    LOGICAL, INTENT(IN) :: EMBEDDINGS_PRESENT
    INTEGER, INTENT(IN) :: EMBEDDINGS_DIM_1
    INTEGER, INTENT(IN) :: EMBEDDINGS_DIM_2
    INTEGER, INTENT(IN) :: EMBEDDINGS_DIM_3
    REAL(KIND=RT), INTENT(OUT), DIMENSION(EMBEDDINGS_DIM_1,EMBEDDINGS_DIM_2,EMBEDDINGS_DIM_3) :: EMBEDDINGS
    INTEGER, INTENT(OUT) :: INFO
  
    IF (XI_PRESENT) THEN
      IF (POSITIONS_PRESENT) THEN
        IF (EMBEDDINGS_PRESENT) THEN
          CALL EVALUATE(CONFIG=CONFIG, MODEL=MODEL, X=X, Y=Y, INFO=INFO, XI=XI, POSITIONS=POSITIONS, EMBEDDINGS=EMBEDDINGS)
        ELSE
          CALL EVALUATE(CONFIG=CONFIG, MODEL=MODEL, X=X, Y=Y, INFO=INFO, XI=XI, POSITIONS=POSITIONS)
        END IF
      ELSE
        IF (EMBEDDINGS_PRESENT) THEN
          CALL EVALUATE(CONFIG=CONFIG, MODEL=MODEL, X=X, Y=Y, INFO=INFO, XI=XI, EMBEDDINGS=EMBEDDINGS)
        ELSE
          CALL EVALUATE(CONFIG=CONFIG, MODEL=MODEL, X=X, Y=Y, INFO=INFO, XI=XI)
        END IF
      END IF
    ELSE
      IF (POSITIONS_PRESENT) THEN
        IF (EMBEDDINGS_PRESENT) THEN
          CALL EVALUATE(CONFIG=CONFIG, MODEL=MODEL, X=X, Y=Y, INFO=INFO, POSITIONS=POSITIONS, EMBEDDINGS=EMBEDDINGS)
        ELSE
          CALL EVALUATE(CONFIG=CONFIG, MODEL=MODEL, X=X, Y=Y, INFO=INFO, POSITIONS=POSITIONS)
        END IF
      ELSE
        IF (EMBEDDINGS_PRESENT) THEN
          CALL EVALUATE(CONFIG=CONFIG, MODEL=MODEL, X=X, Y=Y, INFO=INFO, EMBEDDINGS=EMBEDDINGS)
        ELSE
          CALL EVALUATE(CONFIG=CONFIG, MODEL=MODEL, X=X, Y=Y, INFO=INFO)
        END IF
      END IF
    END IF
  END SUBROUTINE C_EVALUATE
  

  
  SUBROUTINE C_MINIMIZE_MSE(CONFIG, MODEL_DIM_1, MODEL, X_DIM_1, X_DIM_2, X, Y_DIM_1, Y_DIM_2, Y, STEPS, XI_PRESENT, XI_DIM_1, XI_D&
&IM_2, XI, SUM_SQUARED_ERROR, RECORD_PRESENT, RECORD_DIM_1, RECORD_DIM_2, RECORD, INFO) BIND(C)
    USE PLRM, ONLY: MINIMIZE_MSE
    USE PLRM, ONLY: MODEL_CONFIG
    IMPLICIT NONE
    TYPE(MODEL_CONFIG), INTENT(IN) :: CONFIG
    INTEGER, INTENT(IN) :: MODEL_DIM_1
    REAL(KIND=RT), INTENT(INOUT), DIMENSION(MODEL_DIM_1) :: MODEL
    INTEGER, INTENT(IN) :: X_DIM_1
    INTEGER, INTENT(IN) :: X_DIM_2
    REAL(KIND=RT), INTENT(IN), DIMENSION(X_DIM_1,X_DIM_2) :: X
    INTEGER, INTENT(IN) :: Y_DIM_1
    INTEGER, INTENT(IN) :: Y_DIM_2
    REAL(KIND=RT), INTENT(IN), DIMENSION(Y_DIM_1,Y_DIM_2) :: Y
    INTEGER, INTENT(IN) :: STEPS
    LOGICAL, INTENT(IN) :: XI_PRESENT
    INTEGER, INTENT(IN) :: XI_DIM_1
    INTEGER, INTENT(IN) :: XI_DIM_2
    INTEGER, INTENT(IN), DIMENSION(XI_DIM_1,XI_DIM_2) :: XI
    REAL(KIND=RT), INTENT(OUT) :: SUM_SQUARED_ERROR
    LOGICAL, INTENT(IN) :: RECORD_PRESENT
    INTEGER, INTENT(IN) :: RECORD_DIM_1
    INTEGER, INTENT(IN) :: RECORD_DIM_2
    REAL(KIND=RT), INTENT(OUT), DIMENSION(RECORD_DIM_1,RECORD_DIM_2) :: RECORD
    INTEGER, INTENT(OUT) :: INFO
  
    IF (XI_PRESENT) THEN
      IF (RECORD_PRESENT) THEN
        CALL MINIMIZE_MSE(CONFIG=CONFIG, MODEL=MODEL, X=X, Y=Y, STEPS=STEPS, SUM_SQUARED_ERROR=SUM_SQUARED_ERROR, INFO=INFO, XI=XI,&
& RECORD=RECORD)
      ELSE
        CALL MINIMIZE_MSE(CONFIG=CONFIG, MODEL=MODEL, X=X, Y=Y, STEPS=STEPS, SUM_SQUARED_ERROR=SUM_SQUARED_ERROR, INFO=INFO, XI=XI)
      END IF
    ELSE
      IF (RECORD_PRESENT) THEN
        CALL MINIMIZE_MSE(CONFIG=CONFIG, MODEL=MODEL, X=X, Y=Y, STEPS=STEPS, SUM_SQUARED_ERROR=SUM_SQUARED_ERROR, INFO=INFO, RECORD&
&=RECORD)
      ELSE
        CALL MINIMIZE_MSE(CONFIG=CONFIG, MODEL=MODEL, X=X, Y=Y, STEPS=STEPS, SUM_SQUARED_ERROR=SUM_SQUARED_ERROR, INFO=INFO)
      END IF
    END IF
  END SUBROUTINE C_MINIMIZE_MSE
  
END MODULE C_PLRM

