module utils use constants, only: dp implicit none private interface not_same module procedure not_same_scalar module procedure not_same_array module procedure not_same_matrix end interface public :: linspace, not_same contains subroutine linspace(a, b, n, x, include_endpoint) real(dp), intent(in) :: a, b integer, intent(in) :: n real(dp), dimension(:), intent(out) :: x logical, intent(in), optional :: include_endpoint real(dp) :: dx integer :: i if (n < 2) then print *, "Error in linspace: n must be at least 2." error stop end if if (size(x) < n) then print *, "Error in linspace: output array size must be at least n." error stop end if if (present(include_endpoint)) then if (include_endpoint) then dx = (b - a)/(n - 1) else dx = (b - a)/n end if else dx = (b - a)/(n - 1) end if do i = 1, n x(i) = a + (i - 1)*dx end do end subroutine linspace function not_same_scalar(scalar_1, scalar_2, reltol_in, abstol_in) use ieee_arithmetic, only: ieee_is_nan real(dp), intent(in) :: scalar_1, scalar_2 real(dp), intent(in), optional :: reltol_in, abstol_in logical :: not_same_scalar real(dp) :: reltol, abstol if (present(reltol_in)) then reltol = reltol_in else reltol = 0.0_dp end if if (present(abstol_in)) then abstol = abstol_in else abstol = reltol end if if (ieee_is_nan(scalar_1) .or. ieee_is_nan(scalar_2)) then not_same_scalar = .true. else not_same_scalar = abs(scalar_1 - scalar_2) > (reltol*abs(scalar_1) + abstol) end if end function not_same_scalar function not_same_array(array_1, array_2, reltol_in, abstol_in) real(dp), dimension(:), intent(in) :: array_1, array_2 real(dp), intent(in), optional :: reltol_in, abstol_in logical :: not_same_array real(dp) :: reltol, abstol if (present(reltol_in)) then reltol = reltol_in else reltol = 0.0_dp end if if (present(abstol_in)) then abstol = abstol_in else abstol = reltol end if if (contains_nan(array_1) .or. contains_nan(array_2)) then not_same_array = .true. else not_same_array = any(abs(array_1 - array_2) > & (reltol*abs(array_1) + abstol)) end if end function not_same_array function contains_nan(array) use ieee_arithmetic, only: ieee_is_nan implicit none real(dp), intent(in) :: array(:) logical :: contains_nan integer :: i contains_nan = .false. do i = 1, size(array) if (ieee_is_nan(array(i))) then contains_nan = .true. return end if end do end function contains_nan function not_same_matrix(matrix_1, matrix_2, reltol_in, abstol_in) real(dp), dimension(:, :), intent(in) :: matrix_1, matrix_2 real(dp), intent(in), optional :: reltol_in, abstol_in logical :: not_same_matrix real(dp) :: reltol, abstol integer :: rows_1, cols_1, col integer :: rows_2, cols_2 if (present(reltol_in)) then reltol = reltol_in else reltol = 0.0_dp end if if (present(abstol_in)) then abstol = abstol_in else abstol = reltol end if not_same_matrix = .false. rows_1 = size(matrix_1, 1) cols_1 = size(matrix_1, 2) rows_2 = size(matrix_2, 1) cols_2 = size(matrix_2, 2) if (rows_1 /= rows_2 .or. cols_1 /= cols_2) then print *, "Error in not_same_matrix: matrices must have the same dimensions." print *, "Matrix 1 dimensions: ", rows_1, "x", cols_1 print *, "Matrix 2 dimensions: ", rows_2, "x", cols_2 error stop end if do col = 1, cols_1 if (not_same_array(matrix_1(:, col), matrix_2(:, col), reltol, abstol)) then not_same_matrix = .true. return end if end do end function not_same_matrix end module utils