    Subroutine Oversampling (X,Y,N,M)

!   integer, parameter :: nfeatures = 10  ! Number of features (modify as needed)
!   integer, parameter :: max_data = 1000 ! Maximum data points (modify as needed)

      Integer :: N,M
      Real, dimension(N,M)  :: X     ! Feature matrix
      Real, dimension(N)    :: Y     ! Target labels (0 or 1)
      integer, dimension(N) :: oversampled_count ! Count for oversampled data points per class

      integer :: i, j, k, minority_class, num_neighbors, n_oversample
      real, dimension(M) :: difference_vector, new_datapoint

! Sample data (replace with your actual data loading)

      ! Identify minority class
      minority_class = 0
      if (count(Y .eq. 1) < count(Y .eq. 0)) then
         minority_class = 1
      endif

      ! Set oversampling parameters (modify as needed)
      num_neighbors = 5
      n_oversample  = 2  ! Oversample each minority point by this factor

      ! Oversampling loop
      oversampled_count = 0
      do i = 1, N
         if (Y(i) .eq. minority_class) then
            do j = 1, n_oversample
               ! Randomly select k nearest neighbors
               ! (replace with your nearest neighbor finding function)
               call find_nearest_neighbors(X(i,:), num_neighbors, X, Y, neighbors)

               ! Randomly choose one neighbor
               k = random_int(1, num_neighbors)

               ! Calculate difference vector
               difference_vector = X(neighbors(k),:) - X(i,:)

               ! Generate random number between 0 and 1
               lambda = random_real()

               ! Create new data point
               new_datapoint = X(i,:) + lambda * difference_vector

               ! Add new data point and label
               N = N + 1
               X(N,:) = new_datapoint
               Y(N) = minority_class

               oversampled_count(minority_class) = oversampled_count(minority_class) + 1
            enddo
         endif
      enddo
   End Subroutine Oversampling
   !----------------------------------------------------------------------------
   subroutine find_nearest_neighbors(query_point, k, data, labels, neighbors)

      ! Define data types
      integer, parameter :: nfeatures = 10  ! Number of features (modify as needed)
      integer, parameter :: max_data = 1000 ! Maximum data points (modify as needed)

      real, dimension(nfeatures) :: query_point, datapoint, difference
      integer, dimension(max_data) :: labels, neighbors
      real, dimension(max_data) :: distances

      integer :: i, j, temp_index

      ! Calculate distances between query point and all data points
      do i = 1, max_data
         if (labels(i) .gt. 0) then ! Avoid calculating for empty data points
            datapoint = data(i,:)
            difference = query_point - datapoint
            distances(i) = sqrt(sum(difference**2)) ! Euclidean distance
         else
            distances(i) = real(huge) ! Set a very high distance for empty data points (for sorting)
         endif
      enddo

      ! Find k nearest neighbors using bubble sort (replace with more efficient algorithm for large datasets)
      do i = 1, max_data-1
         do j = 1, max_data-i
            if (distances(j) > distances(j+1)) then
               temp_index = neighbors(j)
               neighbors(j) = neighbors(j+1)
               neighbors(j+1) = temp_index

               temp_distance = distances(j)
               distances(j) = distances(j+1)
               distances(j+1) = temp_distance
            endif
         enddo
      enddo

      ! Select the top k nearest neighbors (excluding empty data points)
      k = min(k, count(labels .gt. 0)) ! Ensure k doesn't exceed the number of valid data points
      do i = 1, k
         neighbors(i) = neighbors(max_data - i + 1)
      enddo

    end subroutine find_nearest_neighbors

