Ifort gives me a warning about array bounds

Hi all,
I am working through the “Introductions to Algorithms” book, and writing the various different sorts in Fortran. However, I get an error from ifort saying thus :

forrtl: severe (408): fort: (3): Subscript #1 of the array SORTED_ARRAY has value 0 which is less than the lower bound of 

Here is what I used to compile :

ifort -g -debug full -debug-parameters all -traceback -warn all,errors -stand f18 -standard-semantics -check all -ftrapuv -init=arrays,huge,snan sorting_modules.f90 insertion_sort_experiment.f90 -o insertion_sort_experiment_integer

My main program :

PROGRAM main
  USE,INTRINSIC :: ISO_FORTRAN_ENV,ONLY: int64
  USE sorting_algorithms,ONLY:&
       insertion_sort_integer_asc,insertion_sort_integer_dsc,does_integer_exist&
       ,find_integer,selection_sort_integer_asc,selection_sort_integer_dsc,&
       merge_sort_integer_asc,merge_sort_integer_dsc
  IMPLICIT NONE

  INTEGER :: number_of_elements
  INTEGER(KIND=int64),ALLOCATABLE :: integer_array(:)
  INTEGER(KIND=int64) :: number_to_search
  CHARACTER(LEN=1) :: choice

  WRITE(UNIT=*,FMT="(a)",ADVANCE="no") "Enter the number of elements "
  READ *, number_of_elements
  ALLOCATE(integer_array(number_of_elements))
  WRITE (UNIT=*,FMT="(a)",ADVANCE="no")&
       "Enter the elements (seperated by spaces) "
  READ *, integer_array

  PRINT *, " "
  PRINT ("(a)"), "Ascending "
  PRINT *, insertion_sort_integer_asc(integer_array)

  PRINT *, " "
  PRINT ("(a)"), "Ascending with selection sort "
  PRINT *, selection_sort_integer_asc(integer_array)

  PRINT *, " "
  PRINT ("(a)"), "Ascending with merge sort "
  PRINT *, merge_sort_integer_asc(integer_array)

  PRINT *, " "
  PRINT ("(a)"), "Descending "
  PRINT *, insertion_sort_integer_dsc(integer_array)

  PRINT *, " "
  PRINT ("(a)"), "Descending with selection sort "
  PRINT *, selection_sort_integer_dsc(integer_array)

  PRINT *, " "
  PRINT ("(a)"), "Descending with merge sort "
  PRINT *, merge_sort_integer_dsc(integer_array)

  DO WHILE(choice .NE. "n" .AND. choice .NE. "N")
     WRITE(UNIT=*,FMT="(a)",ADVANCE="no")&
          "Would you like to search for a number? "
     READ *, choice
     IF (choice .EQ. "y") THEN
        WRITE(UNIT=*,FMT="(a)",ADVANCE="no")&
             "Please enter the number you would like to search for "
        READ *, number_to_search
        IF (does_integer_exist(integer_array,number_to_search)) THEN
           PRINT "(a)", "The number exists in the original array at positions "
           PRINT *, find_integer(integer_array, number_to_search)
           PRINT "(a)", "The number exists in the ascending array at positions"
           PRINT *, find_integer(insertion_sort_integer_asc(integer_array),&
                number_to_search)
           PRINT *, "(a)",&
                "The number exists in the descending array at positions"
           PRINT *, find_integer(insertion_sort_integer_dsc(integer_array),&
                number_to_search)
        ELSE
           PRINT "(a)", "The number doesn't exist in the list given, sorry. "
        END IF
     END IF
  END DO

END PROGRAM main

The various sorts :

MODULE sorting_algorithms
  USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY: int64,real128
  IMPLICIT NONE
  PRIVATE

  REAL(KIND=real128),PARAMETER :: tolerance=5.0E-33

  PUBLIC :: insertion_sort_integer_asc, insertion_sort_integer_dsc,&
       insertion_sort_real_asc, insertion_sort_real_dsc,find_integer,&
       find_real,does_integer_exist,does_real_exist,selection_sort_integer_asc,&
       selection_sort_integer_dsc,merge_sort_integer_asc,&
       merge_sort_integer_dsc,merge_sort_real_asc,merge_sort_real_dsc, &
       selection_sort_real_asc,selection_sort_real_dsc

CONTAINS

  PURE FUNCTION insertion_sort_integer_asc(array) RESULT(sorted_array)
    INTEGER(KIND=int64),DIMENSION(:),INTENT(IN) :: array
    INTEGER(KIND=int64) :: sorted_array(SIZE(array))
    INTEGER(KIND=int64) :: key
    INTEGER(KIND=int64) :: i,j

    sorted_array = array

    DO i=2,SIZE(sorted_array)
       key = sorted_array(i)
       j = i-1
       DO WHILE (j .GT. 0 .AND. sorted_array(j) .GT. key)
          sorted_array(j+1) = sorted_array(j)
          j = j-1
       END DO
       sorted_array(j+1) = key
    END DO

  END FUNCTION insertion_sort_integer_asc

  PURE FUNCTION insertion_sort_integer_dsc(array) RESULT(sorted_array)
    INTEGER(KIND=int64),DIMENSION(:),INTENT(IN) :: array
    INTEGER(KIND=int64) :: sorted_array(SIZE(array))
    INTEGER(KIND=int64) :: key
    INTEGER(KIND=int64) :: i,j

    sorted_array = array

    DO i=2,SIZE(sorted_array)
       key = sorted_array(i)
       j = i-1
       DO WHILE(j .GT. 0 .AND. sorted_array(j) .LT. key)
          sorted_array(j+1) = sorted_array(j)
          j = j-1
       END DO
       sorted_array(j+1) = key
    END DO

  END FUNCTION insertion_sort_integer_dsc

  PURE FUNCTION selection_sort_real_asc(array) RESULT(sorted_array)
    REAL(KIND=real128),DIMENSION(:),INTENT(IN) :: array
    REAL(KIND=real128) :: sorted_array(SIZE(array,KIND=int64))
    REAL(KIND=real128) :: key
    INTEGER(KIND=int64) :: i

    sorted_array = array

    DO i=1,SIZE(array)

       key = sorted_array(MINLOC(sorted_array(i:SIZE(sorted_array)),&
            DIM=1, KIND=int64)+(i-1))

       sorted_array(MINLOC(sorted_array(i:SIZE(sorted_array)),&
            DIM=1, KIND=int64)+(i-1)) = sorted_array(i)

       sorted_array(i) = key

    END DO

  END FUNCTION selection_sort_real_asc

  PURE FUNCTION selection_sort_real_dsc(array) RESULT(sorted_array)
    REAL(KIND=real128),DIMENSION(:),INTENT(IN) :: array
    REAL(KIND=real128) :: sorted_array(SIZE(array,KIND=int64))
    REAL(KIND=real128) :: key
    INTEGER(KIND=int64) :: i

    sorted_array = array

    DO i=1,SIZE(array)

       key = sorted_array(MAXLOC(sorted_array(i:SIZE(sorted_array)),&
            DIM=1, KIND=int64)+(i-1))

       sorted_array(MAXLOC(sorted_array(i:SIZE(sorted_array)),&
            DIM=1, KIND=int64)+(i-1)) = sorted_array(i)

       sorted_array(i) = key

    END DO

  END FUNCTION selection_sort_real_dsc

  PURE FUNCTION selection_sort_integer_asc(array) RESULT(sorted_array)
    INTEGER(KIND=int64),DIMENSION(:),INTENT(IN) :: array
    INTEGER(KIND=int64) :: sorted_array(SIZE(array))
    INTEGER(KIND=int64) :: key
    INTEGER(KIND=int64) :: i

    sorted_array = array

    DO i=1,SIZE(array)

       key = sorted_array(MINLOC(sorted_array(i:SIZE(sorted_array)),&
            DIM=1, KIND=int64)+(i-1))

       sorted_array(MINLOC(sorted_array(i:SIZE(sorted_array)),&
            DIM=1, KIND=int64)+(i-1)) = sorted_array(i)

       sorted_array(i) = key

    END DO

  END FUNCTION selection_sort_integer_asc

  PURE FUNCTION selection_sort_integer_dsc(array) RESULT(sorted_array)
    INTEGER(KIND=int64),DIMENSION(:),INTENT(IN) :: array
    INTEGER(KIND=int64) :: sorted_array(SIZE(array))
    INTEGER(KIND=int64) :: key
    INTEGER(KIND=int64) :: i

    sorted_array = array

    DO i=1,SIZE(array)

       key = sorted_array(MAXLOC(sorted_array(i:SIZE(sorted_array)),&
            DIM=1, KIND=int64)+(i-1))

       sorted_array(MAXLOC(sorted_array(i:SIZE(sorted_array)),&
            DIM=1, KIND=int64)+(i-1)) = sorted_array(i)

       sorted_array(i) = key

    END DO

  END FUNCTION selection_sort_integer_dsc

  PURE RECURSIVE FUNCTION merge_sort_real_asc(array) RESULT(merged_array)
    REAL(KIND=real128),DIMENSION(:),INTENT(IN) :: array
    REAL(KIND=real128) :: merged_array(SIZE(array,KIND=int64))
    REAL(KIND=real128),ALLOCATABLE :: sub_array_left(:),sub_array_right(:)
    INTEGER(KIND=int64) :: i,j,k

    IF (MOD(SIZE(array,KIND=int64), INT(2, KIND=int64)) .EQ. 0) THEN
       ALLOCATE(sub_array_left(SIZE(array,KIND=int64)/INT(2, KIND=int64)))
       ALLOCATE(sub_array_right(SIZE(array,KIND=int64)/INT(2, KIND=int64)))
    ELSE
       ALLOCATE(sub_array_left(SIZE(array, KIND=int64)/INT(2, KIND=int64)))
       ALLOCATE(sub_array_right(SIZE(array, KIND=int64)&
            - SIZE(sub_array_left, KIND=int64)))
    END IF

    sub_array_left = array(1:SIZE(sub_array_left, KIND=int64))
    sub_array_right = &
         array(SIZE(sub_array_left, KIND=int64)+&
         INT(1, KIND=int64):SIZE(array, KIND=int64))

    IF (SIZE(sub_array_left, KIND=int64) .GE. INT(2, KIND=int64))&
         sub_array_left = merge_sort_real_asc(sub_array_left)
    IF (SIZE(sub_array_right, KIND=int64) .GE. INT(2, KIND=int64))&
         sub_array_right = merge_sort_real_asc(sub_array_right)

    i=INT(1, KIND=int64)
    j=INT(1, KIND=int64)
    k=INT(1, KIND=int64)

    DO WHILE (i .LE. SIZE(sub_array_left, KIND=int64) .AND. &
         j .LE. SIZE(sub_array_right, KIND=int64))
       IF (sub_array_left(i) .LT. sub_array_right(j) .OR. (sub_array_left(i) &
            .GT. (sub_array_right(j)-tolerance) .AND. sub_array_left(i) .LT. &
            (sub_array_right(j)+tolerance))) THEN
          merged_array(k) = sub_array_left(i)
          i = i + INT(1, KIND=int64)
       ELSE
          merged_array(k) = sub_array_right(j)
          j = j + INT(1, KIND=int64)
       END IF
       k = k + INT(1, KIND=int64)
    END DO

    DO WHILE(i .LE. SIZE(sub_array_left, KIND=int64))
       merged_array(k) = sub_array_left(i)
       i = i + INT(1, KIND=int64)
       k = k + INT(1, KIND=int64)
    END DO

    DO WHILE(j .LE. SIZE(sub_array_right, KIND=int64))
       merged_array(k) = sub_array_right(j)
       j = j + INT(1, KIND=int64)
       k = k + INT(1, KIND=int64)
    END DO

  END FUNCTION merge_sort_real_asc

  PURE RECURSIVE FUNCTION merge_sort_real_dsc(array) RESULT(merged_array)
    REAL(KIND=real128),DIMENSION(:),INTENT(IN) :: array
    REAL(KIND=real128) :: merged_array(SIZE(array,KIND=int64))
    REAL(KIND=real128),ALLOCATABLE :: sub_array_left(:),sub_array_right(:)
    INTEGER(KIND=int64) :: i,j,k

    IF (MOD(SIZE(array,KIND=int64), INT(2, KIND=int64)) .EQ. 0) THEN
       ALLOCATE(sub_array_left(SIZE(array,KIND=int64)/INT(2, KIND=int64)))
       ALLOCATE(sub_array_right(SIZE(array,KIND=int64)/INT(2, KIND=int64)))
    ELSE
       ALLOCATE(sub_array_left(SIZE(array, KIND=int64)/INT(2, KIND=int64)))
       ALLOCATE(sub_array_right(SIZE(array, KIND=int64)&
            - SIZE(sub_array_left, KIND=int64)))
    END IF

    sub_array_left = array(1:SIZE(sub_array_left, KIND=int64))
    sub_array_right = &
         array(SIZE(sub_array_left, KIND=int64)+&
         INT(1, KIND=int64):SIZE(array, KIND=int64))

    IF (SIZE(sub_array_left, KIND=int64) .GE. INT(2, KIND=int64))&
         sub_array_left = merge_sort_real_dsc(sub_array_left)
    IF (SIZE(sub_array_right, KIND=int64) .GE. INT(2, KIND=int64))&
         sub_array_right = merge_sort_real_dsc(sub_array_right)

    i=INT(1, KIND=int64)
    j=INT(1, KIND=int64)
    k=INT(1, KIND=int64)

    DO WHILE (i .LE. SIZE(sub_array_left, KIND=int64) .AND. &
         j .LE. SIZE(sub_array_right, KIND=int64))
       IF (sub_array_left(i) .GT. sub_array_right(j) .OR. (sub_array_left(i) &
            .GT. (sub_array_right(j)-tolerance) .AND. sub_array_left(i) .LT. &
            (sub_array_right(j)+tolerance))) THEN
          merged_array(k) = sub_array_left(i)
          i = i + INT(1, KIND=int64)
       ELSE
          merged_array(k) = sub_array_right(j)
          j = j + INT(1, KIND=int64)
       END IF
       k = k + INT(1, KIND=int64)
    END DO

    DO WHILE(i .LE. SIZE(sub_array_left, KIND=int64))
       merged_array(k) = sub_array_left(i)
       i = i + INT(1, KIND=int64)
       k = k + INT(1, KIND=int64)
    END DO

    DO WHILE(j .LE. SIZE(sub_array_right, KIND=int64))
       merged_array(k) = sub_array_right(j)
       j = j + INT(1, KIND=int64)
       k = k + INT(1, KIND=int64)
    END DO

  END FUNCTION merge_sort_real_dsc

  PURE RECURSIVE FUNCTION merge_sort_integer_asc(array) RESULT(merged_array)
    INTEGER(KIND=int64),DIMENSION(:),INTENT(IN) :: array
    INTEGER(KIND=int64) :: merged_array(SIZE(array,KIND=int64))
    INTEGER(KIND=int64),ALLOCATABLE :: sub_array_left(:),sub_array_right(:)
    INTEGER(KIND=int64) :: i,j,k

    IF (MOD(SIZE(array,KIND=int64), INT(2, KIND=int64)) .EQ. 0) THEN
       ALLOCATE(sub_array_left(SIZE(array,KIND=int64)/INT(2, KIND=int64)))
       ALLOCATE(sub_array_right(SIZE(array,KIND=int64)/INT(2, KIND=int64)))
    ELSE
       ALLOCATE(sub_array_left(SIZE(array, KIND=int64)/INT(2, KIND=int64)))
       ALLOCATE(sub_array_right(SIZE(array, KIND=int64)&
            - SIZE(sub_array_left, KIND=int64)))
    END IF

    sub_array_left = array(1:SIZE(sub_array_left, KIND=int64))
    sub_array_right = &
         array(SIZE(sub_array_left, KIND=int64)+&
         INT(1, KIND=int64):SIZE(array, KIND=int64))

    IF (SIZE(sub_array_left, KIND=int64) .GE. INT(2, KIND=int64))&
         sub_array_left = merge_sort_integer_asc(sub_array_left)
    IF (SIZE(sub_array_right, KIND=int64) .GE. INT(2, KIND=int64))&
         sub_array_right = merge_sort_integer_asc(sub_array_right)

    i=INT(1, KIND=int64)
    j=INT(1, KIND=int64)
    k=INT(1, KIND=int64)

    DO WHILE(i .LE. SIZE(sub_array_left, KIND=int64) .AND. &
         j .LE. SIZE(sub_array_right, KIND=int64))
       IF (sub_array_left(i) .LE. sub_array_right(j)) THEN
          merged_array(k) = sub_array_left(i)
          i = i + INT(1, KIND=int64)
       ELSE
          merged_array(k) = sub_array_right(j)
          j = j + INT(1, KIND=int64)
       END IF
       k = k + INT(1, KIND=int64)
    END DO

    DO WHILE(i .LE. SIZE(sub_array_left, KIND=int64))
       merged_array(k) = sub_array_left(i)
       i = i + INT(1, KIND=int64)
       k = k + INT(1, KIND=int64)
    END DO

    DO WHILE(j .LE. SIZE(sub_array_right, KIND=int64))
       merged_array(k) = sub_array_right(j)
       j = j + INT(1, KIND=int64)
       k = k + INT(1, KIND=int64)
    END DO

  END FUNCTION merge_sort_integer_asc

   PURE RECURSIVE FUNCTION merge_sort_integer_dsc(array) RESULT(merged_array)
     INTEGER(KIND=int64),DIMENSION(:),INTENT(IN) :: array
     INTEGER(KIND=int64) :: merged_array(SIZE(array,KIND=int64))
     INTEGER(KIND=int64),ALLOCATABLE :: sub_array_left(:),sub_array_right(:)
     INTEGER(KIND=int64) :: i,j,k

     IF (MOD(SIZE(array,KIND=int64), INT(2, KIND=int64)) .EQ. 0) THEN
        ALLOCATE(sub_array_left(SIZE(array,KIND=int64)/INT(2, KIND=int64)))
        ALLOCATE(sub_array_right(SIZE(array,KIND=int64)/INT(2, KIND=int64)))
     ELSE
        ALLOCATE(sub_array_left(SIZE(array, KIND=int64)/INT(2, KIND=int64)))
        ALLOCATE(sub_array_right(SIZE(array, KIND=int64)&
             - SIZE(sub_array_left, KIND=int64)))
     END IF

     sub_array_left = array(1:SIZE(sub_array_left, KIND=int64))
     sub_array_right = &
          array(SIZE(sub_array_left, KIND=int64)+&
          INT(1, KIND=int64):SIZE(array, KIND=int64))

     IF (SIZE(sub_array_left, KIND=int64) .GE. INT(2, KIND=int64))&
          sub_array_left = merge_sort_integer_dsc(sub_array_left)
     IF (SIZE(sub_array_right, KIND=int64) .GE. INT(2, KIND=int64))&
          sub_array_right = merge_sort_integer_dsc(sub_array_right)

     i=INT(1, KIND=int64)
     j=INT(1, KIND=int64)
     k=INT(1, KIND=int64)

     DO WHILE(i .LE. SIZE(sub_array_left, KIND=int64) .AND. &
          j .LE. SIZE(sub_array_right, KIND=int64))
        IF (sub_array_left(i) .GE. sub_array_right(j)) THEN
           merged_array(k) = sub_array_left(i)
           i = i + INT(1, KIND=int64)
        ELSE
           merged_array(k) = sub_array_right(j)
           j = j + INT(1, KIND=int64)
        END IF
        k = k + INT(1, KIND=int64)
     END DO

     DO WHILE(i .LE. SIZE(sub_array_left, KIND=int64))
        merged_array(k) = sub_array_left(i)
        i = i + INT(1, KIND=int64)
        k = k + INT(1, KIND=int64)
     END DO

     DO WHILE(j .LE. SIZE(sub_array_right, KIND=int64))
        merged_array(k) = sub_array_right(j)
        j = j + INT(1, KIND=int64)
        k = k + INT(1, KIND=int64)
     END DO

   END FUNCTION merge_sort_integer_dsc

  PURE LOGICAL FUNCTION does_integer_exist(array,number) RESULT(found)
    INTEGER(KIND=int64),DIMENSION(:),INTENT(IN) :: array
    INTEGER(KIND=int64),INTENT(IN) :: number
    INTEGER(KIND=int64) :: i

    DO i=1,SIZE(array)
       found = array(i) .EQ. number
       IF (found) EXIT
    END DO

  END FUNCTION does_integer_exist

  PURE FUNCTION find_integer(array,number) RESULT(positions_of_occurences)
    INTEGER(KIND=int64),DIMENSION(:),INTENT(IN) :: array
    INTEGER(KIND=int64),INTENT(IN) :: number
    INTEGER(KIND=int64),DIMENSION(:),ALLOCATABLE :: positions_of_occurences
    INTEGER(KIND=int64) :: i,j,number_of_occurences

    number_of_occurences = 0
    DO i=1,SIZE(array)
       IF (array(i) .EQ. number) number_of_occurences = number_of_occurences + 1
    END DO

    ALLOCATE(positions_of_occurences(number_of_occurences))

    j=1
    DO i=1,SIZE(array)
       IF (array(i) .EQ. number) THEN
          positions_of_occurences(j)=i
          j= j + 1
       END IF
    END DO

  END FUNCTION find_integer

  PURE FUNCTION insertion_sort_real_asc(array) RESULT(sorted_array)
    REAL(KIND=real128),DIMENSION(:),INTENT(IN) :: array
    REAL(KIND=real128) :: sorted_array(SIZE(array))
    REAL(KIND=real128) :: key
    INTEGER(KIND=int64) :: i,j

    sorted_array = array

    DO i=2,SIZE(sorted_array)
       key = sorted_array(i)
       j = i-1
       DO WHILE (j .GT. 1 .AND. sorted_array(j) .GT. key)
          sorted_array(j+1) = sorted_array(j)
          j = j-1
       END DO
       sorted_array(j+1) = key
    END DO

  END FUNCTION insertion_sort_real_asc

  FUNCTION insertion_sort_real_dsc(array) RESULT(sorted_array)
    REAL(KIND=real128),DIMENSION(:),INTENT(IN) :: array
    REAL(KIND=real128) :: sorted_array(SIZE(array))
    REAL(KIND=real128) :: key
    INTEGER(KIND=int64) :: i,j

    PRINT *, " Assigned "
    sorted_array = array

    PRINT *, "Entering the while loop "
    DO i=2,SIZE(sorted_array)
       key = sorted_array(i)
       j = i-1
       DO WHILE (j .GT. 0 .AND. sorted_array(j) .LT. key)
          PRINT *, " entered the while loop at ",j
          sorted_array(j+1) = sorted_array(j)
          j = j-1
       END DO

       sorted_array(j+1) = key

    END DO

  END FUNCTION insertion_sort_real_dsc

  PURE LOGICAL FUNCTION does_real_exist(array,number) RESULT(found)
    REAL(KIND=real128),DIMENSION(:),INTENT(IN) :: array
    REAL(KIND=real128),INTENT(IN) :: number
    INTEGER(KIND=int64) :: i

    DO i=1,SIZE(array)
       found = ABS(array(i)) .GT. (ABS(number)-tolerance) .AND. &
            ABS(array(i)) .LT. (ABS(number)+tolerance)
       IF(found) EXIT
    END DO

  END FUNCTION does_real_exist

  PURE FUNCTION find_real(array,number) RESULT(positions_of_occurences)
    REAL(KIND=real128),DIMENSION(:),INTENT(IN) :: array
    REAL(KIND=real128),INTENT(IN) :: number
    INTEGER(KIND=int64),DIMENSION(:),ALLOCATABLE :: positions_of_occurences
    INTEGER(KIND=int64) :: i,j,number_of_occurences

    number_of_occurences = 0

    DO i=1,SIZE(array)
       IF (ABS(array(i)) .GT. (ABS(number)-tolerance) .AND.&
            ABS(array(i)) .LT. (ABS(number)+tolerance))&
            number_of_occurences = number_of_occurences + 1
    END DO

    ALLOCATE(positions_of_occurences(number_of_occurences))

    j=1
    DO i=1,SIZE(array)
       IF (ABS(array(i)) .GT. (ABS(number)-tolerance)&
            .AND. ABS(array(i)) .LT. (ABS(number)+tolerance)) THEN
          positions_of_occurences(j) = i
          j=j+1
       END IF
    END DO

  END FUNCTION find_real

END MODULE sorting_algorithms

Various errors and output :

Enter the number of elements 4                                                                                             
Enter the elements (seperated by spaces) 5 7 11 22                                                                         
                                                                                                                           
Ascending                                                                                                                  
 5 7 11                                                                                                                    
 22                                                                                                                        
                                                                                                                           
Ascending with selection sort                                                                                              
 5 7 11                                                                                                                    
 22                                                                                                                        
                                                                                                                           
Ascending with merge sort                                                                                                  
 5 7 11                                                                                                                    
 22                                                                                                                        
                                                                                                                           
Descending                                                                                                                 
forrtl: severe (408): fort: (3): Subscript #1 of the array SORTED_ARRAY has value 0 which is less than the lower bound of 1
                                                                                                                           
Image              PC                Routine            Line        Source                                                 
insertion_sort_ex  0000000000422F6F  Unknown               Unknown  Unknown                                                
insertion_sort_ex  0000000000404C46  Unknown               Unknown  Unknown                                                
insertion_sort_ex  000000000041DE18  Unknown               Unknown  Unknown                                                
insertion_sort_ex  0000000000403862  Unknown               Unknown  Unknown                                                
libc.so.6          00007FCF5EC49510  Unknown               Unknown  Unknown                                                
libc.so.6          00007FCF5EC495C9  __libc_start_main     Unknown  Unknown                                                
insertion_sort_ex  0000000000403765  Unknown               Unknown  Unknown                                                
Enter the number of elements 4
Enter the elements (seperated by spaces) 22 11 7 5
  
Ascending 
forrtl: severe (408): fort: (3): Subscript #1 of the array SORTED_ARRAY has value 0 which is less than the lower bound of 1

Image              PC                Routine            Line        Source             
insertion_sort_ex  0000000000422F6F  Unknown               Unknown  Unknown
insertion_sort_ex  0000000000403FA8  Unknown               Unknown  Unknown
insertion_sort_ex  000000000041D0AA  Unknown               Unknown  Unknown
insertion_sort_ex  0000000000403862  Unknown               Unknown  Unknown
libc.so.6          00007F2855A5A510  Unknown               Unknown  Unknown
libc.so.6          00007F2855A5A5C9  __libc_start_main     Unknown  Unknown
insertion_sort_ex  0000000000403765  Unknown               Unknown  Unknown

Are you aware that Fortran rules do not require “short-circuit-evaluation” of the condition in the DO WHILE statement? The loop index J is decremented each time the loop is executed. After J is decremented from 1 to 0, the second part of the expression

j .GT. 0 .AND. sorted_array(j) .LT. key

causes a subscript error. The solution is to break the WHILE statement into two parts, the second of which is executed only when the first part of the expression is .TRUE.

You have another error: CHOICE is queried when it has not been defined yet.

1 Like

I did not know this !! :open_mouth:

When you say break the while loop into two parts, do you mean two while loops or a while and an if statement ?

Thank you for spotting this.

The latter; there is no need for two loops. You could replace

DO WHILE (j .GT. 0 .AND. sorted_array(j) .LT. key)

by

DO WHILE (j .GT. 0)
   if ( sorted_array(j) .GE. key) exit
2 Likes

This is my corrected code :
sorting modules :

MODULE sorting_algorithms
  USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY: int64,real128
  IMPLICIT NONE
  PRIVATE

  REAL(KIND=real128),PARAMETER :: tolerance=5.0E-33

  PUBLIC :: insertion_sort_integer_asc, insertion_sort_integer_dsc,&
       insertion_sort_real_asc, insertion_sort_real_dsc,find_integer,&
       find_real,does_integer_exist,does_real_exist,selection_sort_integer_asc,&
       selection_sort_integer_dsc,merge_sort_integer_asc,&
       merge_sort_integer_dsc,merge_sort_real_asc,merge_sort_real_dsc, &
       selection_sort_real_asc,selection_sort_real_dsc

CONTAINS

  PURE FUNCTION insertion_sort_integer_asc(array) RESULT(sorted_array)
    INTEGER(KIND=int64),DIMENSION(:),INTENT(IN) :: array
    INTEGER(KIND=int64) :: sorted_array(SIZE(array))
    INTEGER(KIND=int64) :: key
    INTEGER(KIND=int64) :: i,j

    sorted_array = array

    DO i=2,SIZE(sorted_array)
       key = sorted_array(i)
       j = i-1
       DO WHILE (j .GT. 0)
          IF (sorted_array(j) .GT. key) THEN
             sorted_array(j+1) = sorted_array(j)
             j=j-1
          ELSE
             EXIT
          END IF
       END DO
       sorted_array(j+1) = key
    END DO

  END FUNCTION insertion_sort_integer_asc

  PURE FUNCTION insertion_sort_integer_dsc(array) RESULT(sorted_array)
    INTEGER(KIND=int64),DIMENSION(:),INTENT(IN) :: array
    INTEGER(KIND=int64) :: sorted_array(SIZE(array))
    INTEGER(KIND=int64) :: key
    INTEGER(KIND=int64) :: i,j

    sorted_array = array

    DO i=2,SIZE(sorted_array)
       key = sorted_array(i)
       j = i-1
       DO WHILE (j .GT. 0)
          IF (sorted_array(j) .LT. key) THEN
             sorted_array(j+1) = sorted_array(j)
             j=j-1
          ELSE
             EXIT
          END IF
       END DO
       sorted_array(j+1) = key
    END DO

  END FUNCTION insertion_sort_integer_dsc

  PURE FUNCTION selection_sort_real_asc(array) RESULT(sorted_array)
    REAL(KIND=real128),DIMENSION(:),INTENT(IN) :: array
    REAL(KIND=real128) :: sorted_array(SIZE(array,KIND=int64))
    REAL(KIND=real128) :: key
    INTEGER(KIND=int64) :: i

    sorted_array = array

    DO i=1,SIZE(array)

       key = sorted_array(MINLOC(sorted_array(i:SIZE(sorted_array)),&
            DIM=1, KIND=int64)+(i-1))

       sorted_array(MINLOC(sorted_array(i:SIZE(sorted_array)),&
            DIM=1, KIND=int64)+(i-1)) = sorted_array(i)

       sorted_array(i) = key

    END DO

  END FUNCTION selection_sort_real_asc

  PURE FUNCTION selection_sort_real_dsc(array) RESULT(sorted_array)
    REAL(KIND=real128),DIMENSION(:),INTENT(IN) :: array
    REAL(KIND=real128) :: sorted_array(SIZE(array,KIND=int64))
    REAL(KIND=real128) :: key
    INTEGER(KIND=int64) :: i

    sorted_array = array

    DO i=1,SIZE(array)

       key = sorted_array(MAXLOC(sorted_array(i:SIZE(sorted_array)),&
            DIM=1, KIND=int64)+(i-1))

       sorted_array(MAXLOC(sorted_array(i:SIZE(sorted_array)),&
            DIM=1, KIND=int64)+(i-1)) = sorted_array(i)

       sorted_array(i) = key

    END DO

  END FUNCTION selection_sort_real_dsc

  PURE FUNCTION selection_sort_integer_asc(array) RESULT(sorted_array)
    INTEGER(KIND=int64),DIMENSION(:),INTENT(IN) :: array
    INTEGER(KIND=int64) :: sorted_array(SIZE(array))
    INTEGER(KIND=int64) :: key
    INTEGER(KIND=int64) :: i

    sorted_array = array

    DO i=1,SIZE(array)

       key = sorted_array(MINLOC(sorted_array(i:SIZE(sorted_array)),&
            DIM=1, KIND=int64)+(i-1))

       sorted_array(MINLOC(sorted_array(i:SIZE(sorted_array)),&
            DIM=1, KIND=int64)+(i-1)) = sorted_array(i)

       sorted_array(i) = key

    END DO

  END FUNCTION selection_sort_integer_asc

  PURE FUNCTION selection_sort_integer_dsc(array) RESULT(sorted_array)
    INTEGER(KIND=int64),DIMENSION(:),INTENT(IN) :: array
    INTEGER(KIND=int64) :: sorted_array(SIZE(array))
    INTEGER(KIND=int64) :: key
    INTEGER(KIND=int64) :: i

    sorted_array = array

    DO i=1,SIZE(array)

       key = sorted_array(MAXLOC(sorted_array(i:SIZE(sorted_array)),&
            DIM=1, KIND=int64)+(i-1))

       sorted_array(MAXLOC(sorted_array(i:SIZE(sorted_array)),&
            DIM=1, KIND=int64)+(i-1)) = sorted_array(i)

       sorted_array(i) = key

    END DO

  END FUNCTION selection_sort_integer_dsc

  PURE RECURSIVE FUNCTION merge_sort_real_asc(array) RESULT(merged_array)
    REAL(KIND=real128),DIMENSION(:),INTENT(IN) :: array
    REAL(KIND=real128) :: merged_array(SIZE(array,KIND=int64))
    REAL(KIND=real128),ALLOCATABLE :: sub_array_left(:),sub_array_right(:)
    INTEGER(KIND=int64) :: i,j,k

    IF (MOD(SIZE(array,KIND=int64), INT(2, KIND=int64)) .EQ. 0) THEN
       ALLOCATE(sub_array_left(SIZE(array,KIND=int64)/INT(2, KIND=int64)))
       ALLOCATE(sub_array_right(SIZE(array,KIND=int64)/INT(2, KIND=int64)))
    ELSE
       ALLOCATE(sub_array_left(SIZE(array, KIND=int64)/INT(2, KIND=int64)))
       ALLOCATE(sub_array_right(SIZE(array, KIND=int64)&
            - SIZE(sub_array_left, KIND=int64)))
    END IF

    sub_array_left = array(1:SIZE(sub_array_left, KIND=int64))
    sub_array_right = &
         array(SIZE(sub_array_left, KIND=int64)+&
         INT(1, KIND=int64):SIZE(array, KIND=int64))

    IF (SIZE(sub_array_left, KIND=int64) .GE. INT(2, KIND=int64))&
         sub_array_left = merge_sort_real_asc(sub_array_left)
    IF (SIZE(sub_array_right, KIND=int64) .GE. INT(2, KIND=int64))&
         sub_array_right = merge_sort_real_asc(sub_array_right)

    i=INT(1, KIND=int64)
    j=INT(1, KIND=int64)
    k=INT(1, KIND=int64)

    DO WHILE (i .LE. SIZE(sub_array_left, KIND=int64) .AND. &
         j .LE. SIZE(sub_array_right, KIND=int64))
       IF (sub_array_left(i) .LT. sub_array_right(j) .OR. (sub_array_left(i) &
            .GT. (sub_array_right(j)-tolerance) .AND. sub_array_left(i) .LT. &
            (sub_array_right(j)+tolerance))) THEN
          merged_array(k) = sub_array_left(i)
          i = i + INT(1, KIND=int64)
       ELSE
          merged_array(k) = sub_array_right(j)
          j = j + INT(1, KIND=int64)
       END IF
       k = k + INT(1, KIND=int64)
    END DO

    DO WHILE(i .LE. SIZE(sub_array_left, KIND=int64))
       merged_array(k) = sub_array_left(i)
       i = i + INT(1, KIND=int64)
       k = k + INT(1, KIND=int64)
    END DO

    DO WHILE(j .LE. SIZE(sub_array_right, KIND=int64))
       merged_array(k) = sub_array_right(j)
       j = j + INT(1, KIND=int64)
       k = k + INT(1, KIND=int64)
    END DO

  END FUNCTION merge_sort_real_asc

  PURE RECURSIVE FUNCTION merge_sort_real_dsc(array) RESULT(merged_array)
    REAL(KIND=real128),DIMENSION(:),INTENT(IN) :: array
    REAL(KIND=real128) :: merged_array(SIZE(array,KIND=int64))
    REAL(KIND=real128),ALLOCATABLE :: sub_array_left(:),sub_array_right(:)
    INTEGER(KIND=int64) :: i,j,k

    IF (MOD(SIZE(array,KIND=int64), INT(2, KIND=int64)) .EQ. 0) THEN
       ALLOCATE(sub_array_left(SIZE(array,KIND=int64)/INT(2, KIND=int64)))
       ALLOCATE(sub_array_right(SIZE(array,KIND=int64)/INT(2, KIND=int64)))
    ELSE
       ALLOCATE(sub_array_left(SIZE(array, KIND=int64)/INT(2, KIND=int64)))
       ALLOCATE(sub_array_right(SIZE(array, KIND=int64)&
            - SIZE(sub_array_left, KIND=int64)))
    END IF

    sub_array_left = array(1:SIZE(sub_array_left, KIND=int64))
    sub_array_right = &
         array(SIZE(sub_array_left, KIND=int64)+&
         INT(1, KIND=int64):SIZE(array, KIND=int64))

    IF (SIZE(sub_array_left, KIND=int64) .GE. INT(2, KIND=int64))&
         sub_array_left = merge_sort_real_dsc(sub_array_left)
    IF (SIZE(sub_array_right, KIND=int64) .GE. INT(2, KIND=int64))&
         sub_array_right = merge_sort_real_dsc(sub_array_right)

    i=INT(1, KIND=int64)
    j=INT(1, KIND=int64)
    k=INT(1, KIND=int64)

    DO WHILE (i .LE. SIZE(sub_array_left, KIND=int64) .AND. &
         j .LE. SIZE(sub_array_right, KIND=int64))
       IF (sub_array_left(i) .GT. sub_array_right(j) .OR. (sub_array_left(i) &
            .GT. (sub_array_right(j)-tolerance) .AND. sub_array_left(i) .LT. &
            (sub_array_right(j)+tolerance))) THEN
          merged_array(k) = sub_array_left(i)
          i = i + INT(1, KIND=int64)
       ELSE
          merged_array(k) = sub_array_right(j)
          j = j + INT(1, KIND=int64)
       END IF
       k = k + INT(1, KIND=int64)
    END DO

    DO WHILE(i .LE. SIZE(sub_array_left, KIND=int64))
       merged_array(k) = sub_array_left(i)
       i = i + INT(1, KIND=int64)
       k = k + INT(1, KIND=int64)
    END DO

    DO WHILE(j .LE. SIZE(sub_array_right, KIND=int64))
       merged_array(k) = sub_array_right(j)
       j = j + INT(1, KIND=int64)
       k = k + INT(1, KIND=int64)
    END DO

  END FUNCTION merge_sort_real_dsc

  PURE RECURSIVE FUNCTION merge_sort_integer_asc(array) RESULT(merged_array)
    INTEGER(KIND=int64),DIMENSION(:),INTENT(IN) :: array
    INTEGER(KIND=int64) :: merged_array(SIZE(array,KIND=int64))
    INTEGER(KIND=int64),ALLOCATABLE :: sub_array_left(:),sub_array_right(:)
    INTEGER(KIND=int64) :: i,j,k

    IF (MOD(SIZE(array,KIND=int64), INT(2, KIND=int64)) .EQ. 0) THEN
       ALLOCATE(sub_array_left(SIZE(array,KIND=int64)/INT(2, KIND=int64)))
       ALLOCATE(sub_array_right(SIZE(array,KIND=int64)/INT(2, KIND=int64)))
    ELSE
       ALLOCATE(sub_array_left(SIZE(array, KIND=int64)/INT(2, KIND=int64)))
       ALLOCATE(sub_array_right(SIZE(array, KIND=int64)&
            - SIZE(sub_array_left, KIND=int64)))
    END IF

    sub_array_left = array(1:SIZE(sub_array_left, KIND=int64))
    sub_array_right = &
         array(SIZE(sub_array_left, KIND=int64)+&
         INT(1, KIND=int64):SIZE(array, KIND=int64))

    IF (SIZE(sub_array_left, KIND=int64) .GE. INT(2, KIND=int64))&
         sub_array_left = merge_sort_integer_asc(sub_array_left)
    IF (SIZE(sub_array_right, KIND=int64) .GE. INT(2, KIND=int64))&
         sub_array_right = merge_sort_integer_asc(sub_array_right)

    i=INT(1, KIND=int64)
    j=INT(1, KIND=int64)
    k=INT(1, KIND=int64)

    DO WHILE(i .LE. SIZE(sub_array_left, KIND=int64) .AND. &
         j .LE. SIZE(sub_array_right, KIND=int64))
       IF (sub_array_left(i) .LE. sub_array_right(j)) THEN
          merged_array(k) = sub_array_left(i)
          i = i + INT(1, KIND=int64)
       ELSE
          merged_array(k) = sub_array_right(j)
          j = j + INT(1, KIND=int64)
       END IF
       k = k + INT(1, KIND=int64)
    END DO

    DO WHILE(i .LE. SIZE(sub_array_left, KIND=int64))
       merged_array(k) = sub_array_left(i)
       i = i + INT(1, KIND=int64)
       k = k + INT(1, KIND=int64)
    END DO

    DO WHILE(j .LE. SIZE(sub_array_right, KIND=int64))
       merged_array(k) = sub_array_right(j)
       j = j + INT(1, KIND=int64)
       k = k + INT(1, KIND=int64)
    END DO

  END FUNCTION merge_sort_integer_asc

   PURE RECURSIVE FUNCTION merge_sort_integer_dsc(array) RESULT(merged_array)
     INTEGER(KIND=int64),DIMENSION(:),INTENT(IN) :: array
     INTEGER(KIND=int64) :: merged_array(SIZE(array,KIND=int64))
     INTEGER(KIND=int64),ALLOCATABLE :: sub_array_left(:),sub_array_right(:)
     INTEGER(KIND=int64) :: i,j,k

     IF (MOD(SIZE(array,KIND=int64), INT(2, KIND=int64)) .EQ. 0) THEN
        ALLOCATE(sub_array_left(SIZE(array,KIND=int64)/INT(2, KIND=int64)))
        ALLOCATE(sub_array_right(SIZE(array,KIND=int64)/INT(2, KIND=int64)))
     ELSE
        ALLOCATE(sub_array_left(SIZE(array, KIND=int64)/INT(2, KIND=int64)))
        ALLOCATE(sub_array_right(SIZE(array, KIND=int64)&
             - SIZE(sub_array_left, KIND=int64)))
     END IF

     sub_array_left = array(1:SIZE(sub_array_left, KIND=int64))
     sub_array_right = &
          array(SIZE(sub_array_left, KIND=int64)+&
          INT(1, KIND=int64):SIZE(array, KIND=int64))

     IF (SIZE(sub_array_left, KIND=int64) .GE. INT(2, KIND=int64))&
          sub_array_left = merge_sort_integer_dsc(sub_array_left)
     IF (SIZE(sub_array_right, KIND=int64) .GE. INT(2, KIND=int64))&
          sub_array_right = merge_sort_integer_dsc(sub_array_right)

     i=INT(1, KIND=int64)
     j=INT(1, KIND=int64)
     k=INT(1, KIND=int64)

     DO WHILE(i .LE. SIZE(sub_array_left, KIND=int64) .AND. &
          j .LE. SIZE(sub_array_right, KIND=int64))
        IF (sub_array_left(i) .GE. sub_array_right(j)) THEN
           merged_array(k) = sub_array_left(i)
           i = i + INT(1, KIND=int64)
        ELSE
           merged_array(k) = sub_array_right(j)
           j = j + INT(1, KIND=int64)
        END IF
        k = k + INT(1, KIND=int64)
     END DO

     DO WHILE(i .LE. SIZE(sub_array_left, KIND=int64))
        merged_array(k) = sub_array_left(i)
        i = i + INT(1, KIND=int64)
        k = k + INT(1, KIND=int64)
     END DO

     DO WHILE(j .LE. SIZE(sub_array_right, KIND=int64))
        merged_array(k) = sub_array_right(j)
        j = j + INT(1, KIND=int64)
        k = k + INT(1, KIND=int64)
     END DO

   END FUNCTION merge_sort_integer_dsc

  PURE LOGICAL FUNCTION does_integer_exist(array,number) RESULT(found)
    INTEGER(KIND=int64),DIMENSION(:),INTENT(IN) :: array
    INTEGER(KIND=int64),INTENT(IN) :: number
    INTEGER(KIND=int64) :: i

    DO i=1,SIZE(array)
       found = array(i) .EQ. number
       IF (found) EXIT
    END DO

  END FUNCTION does_integer_exist

  PURE FUNCTION find_integer(array,number) RESULT(positions_of_occurences)
    INTEGER(KIND=int64),DIMENSION(:),INTENT(IN) :: array
    INTEGER(KIND=int64),INTENT(IN) :: number
    INTEGER(KIND=int64),DIMENSION(:),ALLOCATABLE :: positions_of_occurences
    INTEGER(KIND=int64) :: i,j,number_of_occurences

    number_of_occurences = 0
    DO i=1,SIZE(array)
       IF (array(i) .EQ. number) number_of_occurences = number_of_occurences + 1
    END DO

    ALLOCATE(positions_of_occurences(number_of_occurences))

    j=1
    DO i=1,SIZE(array)
       IF (array(i) .EQ. number) THEN
          positions_of_occurences(j)=i
          j= j + 1
       END IF
    END DO

  END FUNCTION find_integer

  PURE FUNCTION insertion_sort_real_asc(array) RESULT(sorted_array)
    REAL(KIND=real128),DIMENSION(:),INTENT(IN) :: array
    REAL(KIND=real128) :: sorted_array(SIZE(array))
    REAL(KIND=real128) :: key
    INTEGER(KIND=int64) :: i,j

    sorted_array = array

    DO i=2,SIZE(sorted_array)
       key = sorted_array(i)
       j = i-1
       DO WHILE (j .GT. 1 .AND. sorted_array(j) .GT. key)
          sorted_array(j+1) = sorted_array(j)
          j = j-1
       END DO
       sorted_array(j+1) = key
    END DO

  END FUNCTION insertion_sort_real_asc

  FUNCTION insertion_sort_real_dsc(array) RESULT(sorted_array)
    REAL(KIND=real128),DIMENSION(:),INTENT(IN) :: array
    REAL(KIND=real128) :: sorted_array(SIZE(array))
    REAL(KIND=real128) :: key
    INTEGER(KIND=int64) :: i,j

    PRINT *, " Assigned "
    sorted_array = array

    PRINT *, "Entering the while loop "
    DO i=2,SIZE(sorted_array)
       key = sorted_array(i)
       j = i-1
       DO WHILE (j .GT. 0 .AND. sorted_array(j) .LT. key)
          PRINT *, " entered the while loop at ",j
          sorted_array(j+1) = sorted_array(j)
          j = j-1
       END DO

       sorted_array(j+1) = key

    END DO

  END FUNCTION insertion_sort_real_dsc

  PURE LOGICAL FUNCTION does_real_exist(array,number) RESULT(found)
    REAL(KIND=real128),DIMENSION(:),INTENT(IN) :: array
    REAL(KIND=real128),INTENT(IN) :: number
    INTEGER(KIND=int64) :: i

    DO i=1,SIZE(array)
       found = ABS(array(i)) .GT. (ABS(number)-tolerance) .AND. &
            ABS(array(i)) .LT. (ABS(number)+tolerance)
       IF(found) EXIT
    END DO

  END FUNCTION does_real_exist

  PURE FUNCTION find_real(array,number) RESULT(positions_of_occurences)
    REAL(KIND=real128),DIMENSION(:),INTENT(IN) :: array
    REAL(KIND=real128),INTENT(IN) :: number
    INTEGER(KIND=int64),DIMENSION(:),ALLOCATABLE :: positions_of_occurences
    INTEGER(KIND=int64) :: i,j,number_of_occurences

    number_of_occurences = 0

    DO i=1,SIZE(array)
       IF (ABS(array(i)) .GT. (ABS(number)-tolerance) .AND.&
            ABS(array(i)) .LT. (ABS(number)+tolerance))&
            number_of_occurences = number_of_occurences + 1
    END DO

    ALLOCATE(positions_of_occurences(number_of_occurences))

    j=1
    DO i=1,SIZE(array)
       IF (ABS(array(i)) .GT. (ABS(number)-tolerance)&
            .AND. ABS(array(i)) .LT. (ABS(number)+tolerance)) THEN
          positions_of_occurences(j) = i
          j=j+1
       END IF
    END DO

  END FUNCTION find_real

END MODULE sorting_algorithms

my main program :

PROGRAM main
  USE,INTRINSIC :: ISO_FORTRAN_ENV,ONLY: int64
  USE sorting_algorithms,ONLY:&
       insertion_sort_integer_asc,insertion_sort_integer_dsc,does_integer_exist&
       ,find_integer,selection_sort_integer_asc,selection_sort_integer_dsc,&
       merge_sort_integer_asc,merge_sort_integer_dsc
  IMPLICIT NONE

  INTEGER :: number_of_elements
  INTEGER(KIND=int64),ALLOCATABLE :: integer_array(:)
  INTEGER(KIND=int64) :: number_to_search
  CHARACTER(LEN=1) :: choice

  WRITE(UNIT=*,FMT="(a)",ADVANCE="no") "Enter the number of elements "
  READ *, number_of_elements
  ALLOCATE(integer_array(number_of_elements))
  WRITE (UNIT=*,FMT="(a)",ADVANCE="no")&
       "Enter the elements (seperated by spaces) "
  READ *, integer_array

  PRINT *, " "
  PRINT ("(a)"), "Ascending "
  PRINT *, insertion_sort_integer_asc(integer_array)

  PRINT *, " "
  PRINT ("(a)"), "Ascending with selection sort "
  PRINT *, selection_sort_integer_asc(integer_array)

  PRINT *, " "
  PRINT ("(a)"), "Ascending with merge sort "
  PRINT *, merge_sort_integer_asc(integer_array)

  PRINT *, " "
  PRINT ("(a)"), "Descending "
  PRINT *, insertion_sort_integer_dsc(integer_array)

  PRINT *, " "
  PRINT ("(a)"), "Descending with selection sort "
  PRINT *, selection_sort_integer_dsc(integer_array)

  PRINT *, " "
  PRINT ("(a)"), "Descending with merge sort "
  PRINT *, merge_sort_integer_dsc(integer_array)

  WRITE(UNIT=*,FMT="(a)",ADVANCE="no") "Would you like to search for a number? "
  READ *, choice
  DO WHILE(choice .NE. "n" .AND. choice .NE. "N")
     IF (choice .EQ. "y") THEN
        WRITE(UNIT=*,FMT="(a)",ADVANCE="no")&
             "Please enter the number you would like to search for "
        READ *, number_to_search
        IF (does_integer_exist(integer_array,number_to_search)) THEN
           PRINT "(a)", "The number exists in the original array at positions "
           PRINT *, find_integer(integer_array, number_to_search)
           PRINT "(a)", "The number exists in the ascending array at positions"
           PRINT *, find_integer(insertion_sort_integer_asc(integer_array),&
                number_to_search)
           PRINT *, "(a)",&
                "The number exists in the descending array at positions"
           PRINT *, find_integer(insertion_sort_integer_dsc(integer_array),&
                number_to_search)
        ELSE
           PRINT "(a)", "The number doesn't exist in the list given, sorry. "
        END IF
     END IF
  END DO

END PROGRAM main

I forgot to say thank you ! :sweat_smile:

1 Like

@mecej4 I also forgot to ask, could you comment on my style of programming please.

  1. Can I improve anywhere ?
  2. Do you think I am making some mistakes ?

I think the code looks pretty good. A minor comment, an expression like INT(1, KIND=int64) is really just a longwinded way to say 1_int64. I expect the compiler converts it at compile time, not run time, so there should be no practical difference in the two.

These are all implemented as functions. I typically implement sorts as subroutines, and they work on the array in-place rather than making a separate copy. Part of this is habit because I began programming when fortran could not return an array result, and also when memory was precious, so you didn’t want to make extra copies of data by default. Times are different now, so I wonder what other programmers in general think of the function vs. subroutine choice for a sort operation. In an expression like

A = some_expression_with( sort(B) )

there are potentially three copies of the data at the same time: the original B, the function return result (which must be evaluated “as if” it is fully computed on the rhs of the equation, and then the final result in A. Of course, the compiler might eliminate one copy as an optimization step. With a subroutine interface, this would be

A = B
call sort(A)
A = some_expression_with(A)

which would help the compiler regarding the memory allocation issue.

And one other question I have, perhaps to the compiler writers, is what is the practical differences between returning a function result that is an automatic array vs. an allocatable array? Presumably one lives on the stack and the other in the heap. But in either case, the returned array lives only as long as the expression in the calling program, right?

3 Likes

Thanks for the feedback, I’ll keep your tip in mind :+1: