module stdlib_stats
  !! Provides support for various statistical methods. This includes currently
  !! descriptive statistics
  !! ([Specification](../page/specs/stdlib_stats.html))
  use stdlib_kinds, only: sp, dp, xdp, qp, &
      int8, int16, int32, int64
  implicit none
  private
  ! Public API
  public :: corr, cov, mean, median, moment, var

  interface corr
    !! version: experimental
    !!
    !! Pearson correlation of array elements
    !! ([Specification](../page/specs/stdlib_stats.html#corr-pearson-correlation-of-array-elements))
      module function corr_1_rdp_rdp(x, dim, mask) result(res)
        real(dp), intent(in) :: x(:)
        integer, intent(in) :: dim
        logical, intent(in), optional :: mask
        real(dp) :: res
      end function corr_1_rdp_rdp
      module function corr_1_cdp_cdp(x, dim, mask) result(res)
        complex(dp), intent(in) :: x(:)
        integer, intent(in) :: dim
        logical, intent(in), optional :: mask
        real(dp) :: res
      end function corr_1_cdp_cdp

      module function corr_1_iint32_dp(x, dim, mask) result(res)
        integer(int32), intent(in) :: x(:)
        integer, intent(in) :: dim
        logical, intent(in), optional :: mask
        real(dp) :: res
      end function corr_1_iint32_dp

      module function corr_mask_1_rdp_rdp(x, dim, mask) result(res)
        real(dp), intent(in) :: x(:)
        integer, intent(in) :: dim
        logical, intent(in) :: mask(:)
        real(dp) :: res
      end function corr_mask_1_rdp_rdp
      module function corr_mask_1_cdp_cdp(x, dim, mask) result(res)
        complex(dp), intent(in) :: x(:)
        integer, intent(in) :: dim
        logical, intent(in) :: mask(:)
        real(dp) :: res
      end function corr_mask_1_cdp_cdp

      module function corr_mask_1_iint32_dp(x, dim, mask) result(res)
        integer(int32), intent(in) :: x(:)
        integer, intent(in) :: dim
        logical, intent(in) :: mask(:)
        real(dp) :: res
      end function corr_mask_1_iint32_dp

      module function corr_2_rdp_rdp(x, dim, mask) result(res)
        real(dp), intent(in) :: x(:, :)
        integer, intent(in) :: dim
        logical, intent(in), optional :: mask
        real(dp) :: res(merge(size(x, 1), size(x, 2), mask = 1<dim)&
                            , merge(size(x, 1), size(x, 2), mask = 1<dim))
      end function corr_2_rdp_rdp
      module function corr_2_cdp_cdp(x, dim, mask) result(res)
        complex(dp), intent(in) :: x(:, :)
        integer, intent(in) :: dim
        logical, intent(in), optional :: mask
        complex(dp) :: res(merge(size(x, 1), size(x, 2), mask = 1<dim)&
                            , merge(size(x, 1), size(x, 2), mask = 1<dim))
      end function corr_2_cdp_cdp

      module function corr_2_iint32_dp(x, dim, mask) result(res)
        integer(int32), intent(in) :: x(:, :)
        integer, intent(in) :: dim
        logical, intent(in), optional :: mask
        real(dp) :: res(merge(size(x, 1), size(x, 2), mask = 1<dim)&
                        , merge(size(x, 1), size(x, 2), mask = 1<dim))
      end function corr_2_iint32_dp

      module function corr_mask_2_rdp_rdp(x, dim, mask) result(res)
        real(dp), intent(in) :: x(:, :)
        integer, intent(in) :: dim
        logical, intent(in) :: mask(:,:)
        real(dp) :: res(merge(size(x, 1), size(x, 2), mask = 1<dim)&
                            , merge(size(x, 1), size(x, 2), mask = 1<dim))
      end function corr_mask_2_rdp_rdp
      module function corr_mask_2_cdp_cdp(x, dim, mask) result(res)
        complex(dp), intent(in) :: x(:, :)
        integer, intent(in) :: dim
        logical, intent(in) :: mask(:,:)
        complex(dp) :: res(merge(size(x, 1), size(x, 2), mask = 1<dim)&
                            , merge(size(x, 1), size(x, 2), mask = 1<dim))
      end function corr_mask_2_cdp_cdp

      module function corr_mask_2_iint32_dp(x, dim, mask) result(res)
        integer(int32), intent(in) :: x(:, :)
        integer, intent(in) :: dim
        logical, intent(in) :: mask(:,:)
        real(dp) :: res(merge(size(x, 1), size(x, 2), mask = 1<dim)&
                            , merge(size(x, 1), size(x, 2), mask = 1<dim))
      end function corr_mask_2_iint32_dp

  end interface corr

  interface cov
    !! version: experimental
    !!
    !! Covariance of array elements
    !! ([Specification](../page/specs/stdlib_stats.html#cov-covariance-of-array-elements))
      module function cov_1_rdp_rdp(x, dim, mask, corrected) result(res)
        real(dp), intent(in) :: x(:)
        integer, intent(in) :: dim
        logical, intent(in), optional :: mask
        logical, intent(in), optional :: corrected
        real(dp) :: res
      end function cov_1_rdp_rdp
      module function cov_1_cdp_cdp(x, dim, mask, corrected) result(res)
        complex(dp), intent(in) :: x(:)
        integer, intent(in) :: dim
        logical, intent(in), optional :: mask
        logical, intent(in), optional :: corrected
        real(dp) :: res
      end function cov_1_cdp_cdp

      module function cov_1_iint32_dp(x, dim, mask, corrected) result(res)
        integer(int32), intent(in) :: x(:)
        integer, intent(in) :: dim
        logical, intent(in), optional :: mask
        logical, intent(in), optional :: corrected
        real(dp) :: res
      end function cov_1_iint32_dp

      module function cov_mask_1_rdp_rdp(x, dim, mask, corrected) result(res)
        real(dp), intent(in) :: x(:)
        integer, intent(in) :: dim
        logical, intent(in) :: mask(:)
        logical, intent(in), optional :: corrected
        real(dp) :: res
      end function cov_mask_1_rdp_rdp
      module function cov_mask_1_cdp_cdp(x, dim, mask, corrected) result(res)
        complex(dp), intent(in) :: x(:)
        integer, intent(in) :: dim
        logical, intent(in) :: mask(:)
        logical, intent(in), optional :: corrected
        real(dp) :: res
      end function cov_mask_1_cdp_cdp

      module function cov_mask_1_iint32_dp(x, dim, mask, corrected) result(res)
        integer(int32), intent(in) :: x(:)
        integer, intent(in) :: dim
        logical, intent(in) :: mask(:)
        logical, intent(in), optional :: corrected
        real(dp) :: res
      end function cov_mask_1_iint32_dp

      module function cov_2_rdp_rdp(x, dim, mask, corrected) result(res)
        real(dp), intent(in) :: x(:, :)
        integer, intent(in) :: dim
        logical, intent(in), optional :: mask
        logical, intent(in), optional :: corrected
        real(dp) :: res(merge(size(x, 1), size(x, 2), mask = 1<dim)&
                            , merge(size(x, 1), size(x, 2), mask = 1<dim))
      end function cov_2_rdp_rdp
      module function cov_2_cdp_cdp(x, dim, mask, corrected) result(res)
        complex(dp), intent(in) :: x(:, :)
        integer, intent(in) :: dim
        logical, intent(in), optional :: mask
        logical, intent(in), optional :: corrected
        complex(dp) :: res(merge(size(x, 1), size(x, 2), mask = 1<dim)&
                            , merge(size(x, 1), size(x, 2), mask = 1<dim))
      end function cov_2_cdp_cdp

      module function cov_2_iint32_dp(x, dim, mask, corrected) result(res)
        integer(int32), intent(in) :: x(:, :)
        integer, intent(in) :: dim
        logical, intent(in), optional :: mask
        logical, intent(in), optional :: corrected
        real(dp) :: res(merge(size(x, 1), size(x, 2), mask = 1<dim)&
                        , merge(size(x, 1), size(x, 2), mask = 1<dim))
      end function cov_2_iint32_dp

      module function cov_mask_2_rdp_rdp(x, dim, mask, corrected) result(res)
        real(dp), intent(in) :: x(:, :)
        integer, intent(in) :: dim
        logical, intent(in) :: mask(:,:)
        logical, intent(in), optional :: corrected
        real(dp) :: res(merge(size(x, 1), size(x, 2), mask = 1<dim)&
                            , merge(size(x, 1), size(x, 2), mask = 1<dim))
      end function cov_mask_2_rdp_rdp
      module function cov_mask_2_cdp_cdp(x, dim, mask, corrected) result(res)
        complex(dp), intent(in) :: x(:, :)
        integer, intent(in) :: dim
        logical, intent(in) :: mask(:,:)
        logical, intent(in), optional :: corrected
        complex(dp) :: res(merge(size(x, 1), size(x, 2), mask = 1<dim)&
                            , merge(size(x, 1), size(x, 2), mask = 1<dim))
      end function cov_mask_2_cdp_cdp

      module function cov_mask_2_iint32_dp(x, dim, mask, corrected) result(res)
        integer(int32), intent(in) :: x(:, :)
        integer, intent(in) :: dim
        logical, intent(in) :: mask(:,:)
        logical, intent(in), optional :: corrected
        real(dp) :: res(merge(size(x, 1), size(x, 2), mask = 1<dim)&
                            , merge(size(x, 1), size(x, 2), mask = 1<dim))
      end function cov_mask_2_iint32_dp
  end interface cov

  interface mean
    !! version: experimental
    !!
    !! Mean of array elements
    !! ([Specification](../page/specs/stdlib_stats.html#mean-mean-of-array-elements))
        module function mean_all_1_rdp_rdp (x, mask) result(res)
          real(dp), intent(in) :: x(:)
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function mean_all_1_rdp_rdp
        module function mean_all_2_rdp_rdp (x, mask) result(res)
          real(dp), intent(in) :: x(:,:)
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function mean_all_2_rdp_rdp
        module function mean_all_3_rdp_rdp (x, mask) result(res)
          real(dp), intent(in) :: x(:,:,:)
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function mean_all_3_rdp_rdp
        module function mean_all_4_rdp_rdp (x, mask) result(res)
          real(dp), intent(in) :: x(:,:,:,:)
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function mean_all_4_rdp_rdp
        module function mean_all_1_cdp_cdp (x, mask) result(res)
          complex(dp), intent(in) :: x(:)
          logical, intent(in), optional :: mask
          complex(dp) :: res
        end function mean_all_1_cdp_cdp
        module function mean_all_2_cdp_cdp (x, mask) result(res)
          complex(dp), intent(in) :: x(:,:)
          logical, intent(in), optional :: mask
          complex(dp) :: res
        end function mean_all_2_cdp_cdp
        module function mean_all_3_cdp_cdp (x, mask) result(res)
          complex(dp), intent(in) :: x(:,:,:)
          logical, intent(in), optional :: mask
          complex(dp) :: res
        end function mean_all_3_cdp_cdp
        module function mean_all_4_cdp_cdp (x, mask) result(res)
          complex(dp), intent(in) :: x(:,:,:,:)
          logical, intent(in), optional :: mask
          complex(dp) :: res
        end function mean_all_4_cdp_cdp

        module function mean_all_1_iint32_dp(x, mask) result(res)
          integer(int32), intent(in) :: x(:)
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function mean_all_1_iint32_dp
        module function mean_all_2_iint32_dp(x, mask) result(res)
          integer(int32), intent(in) :: x(:,:)
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function mean_all_2_iint32_dp
        module function mean_all_3_iint32_dp(x, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:)
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function mean_all_3_iint32_dp
        module function mean_all_4_iint32_dp(x, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:,:)
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function mean_all_4_iint32_dp

        module function mean_1_rdp_rdp(x, dim, mask) result(res)
          real(dp), intent(in) :: x(:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function mean_1_rdp_rdp
        module function mean_2_rdp_rdp(x, dim, mask) result(res)
          real(dp), intent(in) :: x(:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function mean_2_rdp_rdp
        module function mean_3_rdp_rdp(x, dim, mask) result(res)
          real(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function mean_3_rdp_rdp
        module function mean_4_rdp_rdp(x, dim, mask) result(res)
          real(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function mean_4_rdp_rdp
        module function mean_1_cdp_cdp(x, dim, mask) result(res)
          complex(dp), intent(in) :: x(:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          complex(dp) :: res
        end function mean_1_cdp_cdp
        module function mean_2_cdp_cdp(x, dim, mask) result(res)
          complex(dp), intent(in) :: x(:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          complex(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function mean_2_cdp_cdp
        module function mean_3_cdp_cdp(x, dim, mask) result(res)
          complex(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          complex(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function mean_3_cdp_cdp
        module function mean_4_cdp_cdp(x, dim, mask) result(res)
          complex(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          complex(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x,&
              & 3), size(x, 4), mask=3<dim))
        end function mean_4_cdp_cdp

        module function mean_1_iint32_dp(x, dim, mask) result(res)
          integer(int32), intent(in) :: x(:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function mean_1_iint32_dp
        module function mean_2_iint32_dp(x, dim, mask) result(res)
          integer(int32), intent(in) :: x(:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function mean_2_iint32_dp
        module function mean_3_iint32_dp(x, dim, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function mean_3_iint32_dp
        module function mean_4_iint32_dp(x, dim, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function mean_4_iint32_dp

        module function mean_mask_all_1_rdp_rdp(x, mask) result(res)
          real(dp), intent(in) :: x(:)
          logical, intent(in) :: mask(:)
          real(dp) :: res
          end function mean_mask_all_1_rdp_rdp
        module function mean_mask_all_2_rdp_rdp(x, mask) result(res)
          real(dp), intent(in) :: x(:,:)
          logical, intent(in) :: mask(:,:)
          real(dp) :: res
          end function mean_mask_all_2_rdp_rdp
        module function mean_mask_all_3_rdp_rdp(x, mask) result(res)
          real(dp), intent(in) :: x(:,:,:)
          logical, intent(in) :: mask(:,:,:)
          real(dp) :: res
          end function mean_mask_all_3_rdp_rdp
        module function mean_mask_all_4_rdp_rdp(x, mask) result(res)
          real(dp), intent(in) :: x(:,:,:,:)
          logical, intent(in) :: mask(:,:,:,:)
          real(dp) :: res
          end function mean_mask_all_4_rdp_rdp
        module function mean_mask_all_1_cdp_cdp(x, mask) result(res)
          complex(dp), intent(in) :: x(:)
          logical, intent(in) :: mask(:)
          complex(dp) :: res
          end function mean_mask_all_1_cdp_cdp
        module function mean_mask_all_2_cdp_cdp(x, mask) result(res)
          complex(dp), intent(in) :: x(:,:)
          logical, intent(in) :: mask(:,:)
          complex(dp) :: res
          end function mean_mask_all_2_cdp_cdp
        module function mean_mask_all_3_cdp_cdp(x, mask) result(res)
          complex(dp), intent(in) :: x(:,:,:)
          logical, intent(in) :: mask(:,:,:)
          complex(dp) :: res
          end function mean_mask_all_3_cdp_cdp
        module function mean_mask_all_4_cdp_cdp(x, mask) result(res)
          complex(dp), intent(in) :: x(:,:,:,:)
          logical, intent(in) :: mask(:,:,:,:)
          complex(dp) :: res
          end function mean_mask_all_4_cdp_cdp

        module function mean_mask_all_1_iint32_dp(x, mask) result(res)
          integer(int32), intent(in) :: x(:)
          logical, intent(in) :: mask(:)
          real(dp) :: res
        end function mean_mask_all_1_iint32_dp
        module function mean_mask_all_2_iint32_dp(x, mask) result(res)
          integer(int32), intent(in) :: x(:,:)
          logical, intent(in) :: mask(:,:)
          real(dp) :: res
        end function mean_mask_all_2_iint32_dp
        module function mean_mask_all_3_iint32_dp(x, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:)
          logical, intent(in) :: mask(:,:,:)
          real(dp) :: res
        end function mean_mask_all_3_iint32_dp
        module function mean_mask_all_4_iint32_dp(x, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:,:)
          logical, intent(in) :: mask(:,:,:,:)
          real(dp) :: res
        end function mean_mask_all_4_iint32_dp

        module function mean_mask_1_rdp_rdp(x, dim, mask) result(res)
          real(dp), intent(in) :: x(:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:)
          real(dp) :: res
        end function mean_mask_1_rdp_rdp
        module function mean_mask_2_rdp_rdp(x, dim, mask) result(res)
          real(dp), intent(in) :: x(:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function mean_mask_2_rdp_rdp
        module function mean_mask_3_rdp_rdp(x, dim, mask) result(res)
          real(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function mean_mask_3_rdp_rdp
        module function mean_mask_4_rdp_rdp(x, dim, mask) result(res)
          real(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:,:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function mean_mask_4_rdp_rdp
        module function mean_mask_1_cdp_cdp(x, dim, mask) result(res)
          complex(dp), intent(in) :: x(:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:)
          complex(dp) :: res
        end function mean_mask_1_cdp_cdp
        module function mean_mask_2_cdp_cdp(x, dim, mask) result(res)
          complex(dp), intent(in) :: x(:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:)
          complex(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function mean_mask_2_cdp_cdp
        module function mean_mask_3_cdp_cdp(x, dim, mask) result(res)
          complex(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:,:)
          complex(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function mean_mask_3_cdp_cdp
        module function mean_mask_4_cdp_cdp(x, dim, mask) result(res)
          complex(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:,:,:)
          complex(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x,&
              & 3), size(x, 4), mask=3<dim))
        end function mean_mask_4_cdp_cdp

        module function mean_mask_1_iint32_dp(x, dim, mask) result(res)
          integer(int32), intent(in) :: x(:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:)
          real(dp) :: res
        end function mean_mask_1_iint32_dp
        module function mean_mask_2_iint32_dp(x, dim, mask) result(res)
          integer(int32), intent(in) :: x(:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function mean_mask_2_iint32_dp
        module function mean_mask_3_iint32_dp(x, dim, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function mean_mask_3_iint32_dp
        module function mean_mask_4_iint32_dp(x, dim, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:,:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function mean_mask_4_iint32_dp

  end interface mean

  interface median
    !! version: experimental
    !!
    !! Median of array elements
    !! ([Specification](../page/specs/stdlib_stats.html#median-median-of-array-elements))
        module function median_all_1_iint32_dp (x, mask) result(res)
          integer(int32), intent(in) :: x(:)
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function median_all_1_iint32_dp
        module function median_all_2_iint32_dp (x, mask) result(res)
          integer(int32), intent(in) :: x(:,:)
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function median_all_2_iint32_dp
        module function median_all_3_iint32_dp (x, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:)
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function median_all_3_iint32_dp
        module function median_all_4_iint32_dp (x, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:,:)
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function median_all_4_iint32_dp
        module function median_all_1_rdp_dp (x, mask) result(res)
          real(dp), intent(in) :: x(:)
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function median_all_1_rdp_dp
        module function median_all_2_rdp_dp (x, mask) result(res)
          real(dp), intent(in) :: x(:,:)
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function median_all_2_rdp_dp
        module function median_all_3_rdp_dp (x, mask) result(res)
          real(dp), intent(in) :: x(:,:,:)
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function median_all_3_rdp_dp
        module function median_all_4_rdp_dp (x, mask) result(res)
          real(dp), intent(in) :: x(:,:,:,:)
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function median_all_4_rdp_dp

        module function median_1_iint32_dp(x, dim, mask) result(res)
          integer(int32), intent(in) :: x(:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function median_1_iint32_dp
        module function median_2_iint32_dp(x, dim, mask) result(res)
          integer(int32), intent(in) :: x(:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function median_2_iint32_dp
        module function median_3_iint32_dp(x, dim, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function median_3_iint32_dp
        module function median_4_iint32_dp(x, dim, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function median_4_iint32_dp
        module function median_1_rdp_dp(x, dim, mask) result(res)
          real(dp), intent(in) :: x(:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function median_1_rdp_dp
        module function median_2_rdp_dp(x, dim, mask) result(res)
          real(dp), intent(in) :: x(:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function median_2_rdp_dp
        module function median_3_rdp_dp(x, dim, mask) result(res)
          real(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function median_3_rdp_dp
        module function median_4_rdp_dp(x, dim, mask) result(res)
          real(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function median_4_rdp_dp

        module function median_all_mask_1_iint32_dp(x, mask) result(res)
          integer(int32), intent(in) :: x(:)
          logical, intent(in) :: mask(:)
          real(dp) :: res
        end function median_all_mask_1_iint32_dp
        module function median_all_mask_2_iint32_dp(x, mask) result(res)
          integer(int32), intent(in) :: x(:,:)
          logical, intent(in) :: mask(:,:)
          real(dp) :: res
        end function median_all_mask_2_iint32_dp
        module function median_all_mask_3_iint32_dp(x, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:)
          logical, intent(in) :: mask(:,:,:)
          real(dp) :: res
        end function median_all_mask_3_iint32_dp
        module function median_all_mask_4_iint32_dp(x, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:,:)
          logical, intent(in) :: mask(:,:,:,:)
          real(dp) :: res
        end function median_all_mask_4_iint32_dp
        module function median_all_mask_1_rdp_dp(x, mask) result(res)
          real(dp), intent(in) :: x(:)
          logical, intent(in) :: mask(:)
          real(dp) :: res
        end function median_all_mask_1_rdp_dp
        module function median_all_mask_2_rdp_dp(x, mask) result(res)
          real(dp), intent(in) :: x(:,:)
          logical, intent(in) :: mask(:,:)
          real(dp) :: res
        end function median_all_mask_2_rdp_dp
        module function median_all_mask_3_rdp_dp(x, mask) result(res)
          real(dp), intent(in) :: x(:,:,:)
          logical, intent(in) :: mask(:,:,:)
          real(dp) :: res
        end function median_all_mask_3_rdp_dp
        module function median_all_mask_4_rdp_dp(x, mask) result(res)
          real(dp), intent(in) :: x(:,:,:,:)
          logical, intent(in) :: mask(:,:,:,:)
          real(dp) :: res
        end function median_all_mask_4_rdp_dp

        module function  median_mask_1_iint32_dp(x, dim, mask) result(res)
          integer(int32), intent(in) :: x(:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:)
          real(dp) :: res
        end function median_mask_1_iint32_dp
        module function  median_mask_2_iint32_dp(x, dim, mask) result(res)
          integer(int32), intent(in) :: x(:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function median_mask_2_iint32_dp
        module function  median_mask_3_iint32_dp(x, dim, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function median_mask_3_iint32_dp
        module function  median_mask_4_iint32_dp(x, dim, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:,:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function median_mask_4_iint32_dp
        module function  median_mask_1_rdp_dp(x, dim, mask) result(res)
          real(dp), intent(in) :: x(:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:)
          real(dp) :: res
        end function median_mask_1_rdp_dp
        module function  median_mask_2_rdp_dp(x, dim, mask) result(res)
          real(dp), intent(in) :: x(:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function median_mask_2_rdp_dp
        module function  median_mask_3_rdp_dp(x, dim, mask) result(res)
          real(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function median_mask_3_rdp_dp
        module function  median_mask_4_rdp_dp(x, dim, mask) result(res)
          real(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:,:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function median_mask_4_rdp_dp

  end interface

  interface var
    !! version: experimental
    !!
    !! Variance of array elements
    !! ([Specification](../page/specs/stdlib_stats.html#var-variance-of-array-elements))

        module function var_all_1_rdp_rdp(x, mask, corrected) result(res)
          real(dp), intent(in) :: x(:)
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_all_1_rdp_rdp
        module function var_all_2_rdp_rdp(x, mask, corrected) result(res)
          real(dp), intent(in) :: x(:,:)
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_all_2_rdp_rdp
        module function var_all_3_rdp_rdp(x, mask, corrected) result(res)
          real(dp), intent(in) :: x(:,:,:)
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_all_3_rdp_rdp
        module function var_all_4_rdp_rdp(x, mask, corrected) result(res)
          real(dp), intent(in) :: x(:,:,:,:)
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_all_4_rdp_rdp
        module function var_all_1_cdp_cdp(x, mask, corrected) result(res)
          complex(dp), intent(in) :: x(:)
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_all_1_cdp_cdp
        module function var_all_2_cdp_cdp(x, mask, corrected) result(res)
          complex(dp), intent(in) :: x(:,:)
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_all_2_cdp_cdp
        module function var_all_3_cdp_cdp(x, mask, corrected) result(res)
          complex(dp), intent(in) :: x(:,:,:)
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_all_3_cdp_cdp
        module function var_all_4_cdp_cdp(x, mask, corrected) result(res)
          complex(dp), intent(in) :: x(:,:,:,:)
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_all_4_cdp_cdp

        module function var_all_1_iint32_dp(x, mask, corrected) result(res)
          integer(int32), intent(in) :: x(:)
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_all_1_iint32_dp
        module function var_all_2_iint32_dp(x, mask, corrected) result(res)
          integer(int32), intent(in) :: x(:,:)
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_all_2_iint32_dp
        module function var_all_3_iint32_dp(x, mask, corrected) result(res)
          integer(int32), intent(in) :: x(:,:,:)
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_all_3_iint32_dp
        module function var_all_4_iint32_dp(x, mask, corrected) result(res)
          integer(int32), intent(in) :: x(:,:,:,:)
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_all_4_iint32_dp

        module function var_1_rdp_rdp(x, dim, mask, corrected) result(res)
          real(dp), intent(in) :: x(:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_1_rdp_rdp
        module function var_2_rdp_rdp(x, dim, mask, corrected) result(res)
          real(dp), intent(in) :: x(:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function var_2_rdp_rdp
        module function var_3_rdp_rdp(x, dim, mask, corrected) result(res)
          real(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function var_3_rdp_rdp
        module function var_4_rdp_rdp(x, dim, mask, corrected) result(res)
          real(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function var_4_rdp_rdp
        module function var_1_cdp_cdp(x, dim, mask, corrected) result(res)
          complex(dp), intent(in) :: x(:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_1_cdp_cdp
        module function var_2_cdp_cdp(x, dim, mask, corrected) result(res)
          complex(dp), intent(in) :: x(:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function var_2_cdp_cdp
        module function var_3_cdp_cdp(x, dim, mask, corrected) result(res)
          complex(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function var_3_cdp_cdp
        module function var_4_cdp_cdp(x, dim, mask, corrected) result(res)
          complex(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function var_4_cdp_cdp

        module function var_1_iint32_dp(x, dim, mask, corrected) result(res)
          integer(int32), intent(in) :: x(:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_1_iint32_dp
        module function var_2_iint32_dp(x, dim, mask, corrected) result(res)
          integer(int32), intent(in) :: x(:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function var_2_iint32_dp
        module function var_3_iint32_dp(x, dim, mask, corrected) result(res)
          integer(int32), intent(in) :: x(:,:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function var_3_iint32_dp
        module function var_4_iint32_dp(x, dim, mask, corrected) result(res)
          integer(int32), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function var_4_iint32_dp

        module function var_mask_all_1_rdp_rdp(x, mask, corrected) result(res)
          real(dp), intent(in) :: x(:)
          logical, intent(in) :: mask(:)
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_mask_all_1_rdp_rdp
        module function var_mask_all_2_rdp_rdp(x, mask, corrected) result(res)
          real(dp), intent(in) :: x(:,:)
          logical, intent(in) :: mask(:,:)
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_mask_all_2_rdp_rdp
        module function var_mask_all_3_rdp_rdp(x, mask, corrected) result(res)
          real(dp), intent(in) :: x(:,:,:)
          logical, intent(in) :: mask(:,:,:)
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_mask_all_3_rdp_rdp
        module function var_mask_all_4_rdp_rdp(x, mask, corrected) result(res)
          real(dp), intent(in) :: x(:,:,:,:)
          logical, intent(in) :: mask(:,:,:,:)
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_mask_all_4_rdp_rdp
        module function var_mask_all_1_cdp_cdp(x, mask, corrected) result(res)
          complex(dp), intent(in) :: x(:)
          logical, intent(in) :: mask(:)
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_mask_all_1_cdp_cdp
        module function var_mask_all_2_cdp_cdp(x, mask, corrected) result(res)
          complex(dp), intent(in) :: x(:,:)
          logical, intent(in) :: mask(:,:)
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_mask_all_2_cdp_cdp
        module function var_mask_all_3_cdp_cdp(x, mask, corrected) result(res)
          complex(dp), intent(in) :: x(:,:,:)
          logical, intent(in) :: mask(:,:,:)
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_mask_all_3_cdp_cdp
        module function var_mask_all_4_cdp_cdp(x, mask, corrected) result(res)
          complex(dp), intent(in) :: x(:,:,:,:)
          logical, intent(in) :: mask(:,:,:,:)
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_mask_all_4_cdp_cdp

        module function var_mask_all_1_iint32_dp(x, mask, corrected) result(res)
          integer(int32), intent(in) :: x(:)
          logical, intent(in) :: mask(:)
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_mask_all_1_iint32_dp
        module function var_mask_all_2_iint32_dp(x, mask, corrected) result(res)
          integer(int32), intent(in) :: x(:,:)
          logical, intent(in) :: mask(:,:)
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_mask_all_2_iint32_dp
        module function var_mask_all_3_iint32_dp(x, mask, corrected) result(res)
          integer(int32), intent(in) :: x(:,:,:)
          logical, intent(in) :: mask(:,:,:)
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_mask_all_3_iint32_dp
        module function var_mask_all_4_iint32_dp(x, mask, corrected) result(res)
          integer(int32), intent(in) :: x(:,:,:,:)
          logical, intent(in) :: mask(:,:,:,:)
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_mask_all_4_iint32_dp

        module function var_mask_1_rdp_rdp(x, dim, mask, corrected) result(res)
          real(dp), intent(in) :: x(:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:)
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_mask_1_rdp_rdp
        module function var_mask_2_rdp_rdp(x, dim, mask, corrected) result(res)
          real(dp), intent(in) :: x(:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:)
          logical, intent(in), optional :: corrected
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function var_mask_2_rdp_rdp
        module function var_mask_3_rdp_rdp(x, dim, mask, corrected) result(res)
          real(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:,:)
          logical, intent(in), optional :: corrected
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function var_mask_3_rdp_rdp
        module function var_mask_4_rdp_rdp(x, dim, mask, corrected) result(res)
          real(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:,:,:)
          logical, intent(in), optional :: corrected
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function var_mask_4_rdp_rdp
        module function var_mask_1_cdp_cdp(x, dim, mask, corrected) result(res)
          complex(dp), intent(in) :: x(:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:)
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_mask_1_cdp_cdp
        module function var_mask_2_cdp_cdp(x, dim, mask, corrected) result(res)
          complex(dp), intent(in) :: x(:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:)
          logical, intent(in), optional :: corrected
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function var_mask_2_cdp_cdp
        module function var_mask_3_cdp_cdp(x, dim, mask, corrected) result(res)
          complex(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:,:)
          logical, intent(in), optional :: corrected
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function var_mask_3_cdp_cdp
        module function var_mask_4_cdp_cdp(x, dim, mask, corrected) result(res)
          complex(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:,:,:)
          logical, intent(in), optional :: corrected
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function var_mask_4_cdp_cdp

        module function var_mask_1_iint32_dp(x, dim, mask, corrected) result(res)
          integer(int32), intent(in) :: x(:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:)
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function var_mask_1_iint32_dp
        module function var_mask_2_iint32_dp(x, dim, mask, corrected) result(res)
          integer(int32), intent(in) :: x(:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:)
          logical, intent(in), optional :: corrected
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function var_mask_2_iint32_dp
        module function var_mask_3_iint32_dp(x, dim, mask, corrected) result(res)
          integer(int32), intent(in) :: x(:,:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:,:)
          logical, intent(in), optional :: corrected
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function var_mask_3_iint32_dp
        module function var_mask_4_iint32_dp(x, dim, mask, corrected) result(res)
          integer(int32), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: dim
          logical, intent(in) :: mask(:,:,:,:)
          logical, intent(in), optional :: corrected
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function var_mask_4_iint32_dp

  end interface var

  interface moment
    !! version: experimental
    !!
    !! Central moment of array elements
    !! ([Specification](../page/specs/stdlib_stats.html#moment-central-moments-of-array-elements))
        module function moment_all_1_rdp_rdp(x, order, center, mask) result(res)
          real(dp), intent(in) :: x(:)
          integer, intent(in) :: order
          real(dp), intent(in), optional :: center
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function moment_all_1_rdp_rdp
        module function moment_all_2_rdp_rdp(x, order, center, mask) result(res)
          real(dp), intent(in) :: x(:,:)
          integer, intent(in) :: order
          real(dp), intent(in), optional :: center
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function moment_all_2_rdp_rdp
        module function moment_all_3_rdp_rdp(x, order, center, mask) result(res)
          real(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: order
          real(dp), intent(in), optional :: center
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function moment_all_3_rdp_rdp
        module function moment_all_4_rdp_rdp(x, order, center, mask) result(res)
          real(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: order
          real(dp), intent(in), optional :: center
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function moment_all_4_rdp_rdp
        module function moment_all_1_cdp_cdp(x, order, center, mask) result(res)
          complex(dp), intent(in) :: x(:)
          integer, intent(in) :: order
          complex(dp), intent(in), optional :: center
          logical, intent(in), optional :: mask
          complex(dp) :: res
        end function moment_all_1_cdp_cdp
        module function moment_all_2_cdp_cdp(x, order, center, mask) result(res)
          complex(dp), intent(in) :: x(:,:)
          integer, intent(in) :: order
          complex(dp), intent(in), optional :: center
          logical, intent(in), optional :: mask
          complex(dp) :: res
        end function moment_all_2_cdp_cdp
        module function moment_all_3_cdp_cdp(x, order, center, mask) result(res)
          complex(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: order
          complex(dp), intent(in), optional :: center
          logical, intent(in), optional :: mask
          complex(dp) :: res
        end function moment_all_3_cdp_cdp
        module function moment_all_4_cdp_cdp(x, order, center, mask) result(res)
          complex(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: order
          complex(dp), intent(in), optional :: center
          logical, intent(in), optional :: mask
          complex(dp) :: res
        end function moment_all_4_cdp_cdp

        module function moment_all_1_iint32_dp(x, order, center, mask) result(res)
          integer(int32), intent(in) :: x(:)
          integer, intent(in) :: order
          real(dp), intent(in), optional :: center
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function moment_all_1_iint32_dp
        module function moment_all_2_iint32_dp(x, order, center, mask) result(res)
          integer(int32), intent(in) :: x(:,:)
          integer, intent(in) :: order
          real(dp), intent(in), optional :: center
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function moment_all_2_iint32_dp
        module function moment_all_3_iint32_dp(x, order, center, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:)
          integer, intent(in) :: order
          real(dp), intent(in), optional :: center
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function moment_all_3_iint32_dp
        module function moment_all_4_iint32_dp(x, order, center, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: order
          real(dp), intent(in), optional :: center
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function moment_all_4_iint32_dp

        module function moment_scalar_2_rdp_rdp(x, order, dim, center, mask) result(res)
          real(dp), intent(in) :: x(:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in) :: center
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function moment_scalar_2_rdp_rdp
        module function moment_scalar_3_rdp_rdp(x, order, dim, center, mask) result(res)
          real(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in) :: center
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function moment_scalar_3_rdp_rdp
        module function moment_scalar_4_rdp_rdp(x, order, dim, center, mask) result(res)
          real(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in) :: center
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function moment_scalar_4_rdp_rdp
        module function moment_scalar_2_cdp_cdp(x, order, dim, center, mask) result(res)
          complex(dp), intent(in) :: x(:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          complex(dp), intent(in) :: center
          logical, intent(in), optional :: mask
          complex(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function moment_scalar_2_cdp_cdp
        module function moment_scalar_3_cdp_cdp(x, order, dim, center, mask) result(res)
          complex(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          complex(dp), intent(in) :: center
          logical, intent(in), optional :: mask
          complex(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function moment_scalar_3_cdp_cdp
        module function moment_scalar_4_cdp_cdp(x, order, dim, center, mask) result(res)
          complex(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          complex(dp), intent(in) :: center
          logical, intent(in), optional :: mask
          complex(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x,&
              & 3), size(x, 4), mask=3<dim))
        end function moment_scalar_4_cdp_cdp

        module function moment_1_rdp_rdp(x, order, dim, center, mask) result(res)
          real(dp), intent(in) :: x(:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in), optional :: center
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function moment_1_rdp_rdp
        module function moment_2_rdp_rdp(x, order, dim, center, mask) result(res)
          real(dp), intent(in) :: x(:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in), optional :: center(merge(size(x, 1), size(x, 2), mask=1<dim))
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function moment_2_rdp_rdp
        module function moment_3_rdp_rdp(x, order, dim, center, mask) result(res)
          real(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in), optional :: center(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3),&
              & mask=2<dim))
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function moment_3_rdp_rdp
        module function moment_4_rdp_rdp(x, order, dim, center, mask) result(res)
          real(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in), optional :: center(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3),&
              & mask=2<dim), merge(size(x, 3), size(x, 4), mask=3<dim))
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function moment_4_rdp_rdp
        module function moment_1_cdp_cdp(x, order, dim, center, mask) result(res)
          complex(dp), intent(in) :: x(:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          complex(dp), intent(in), optional :: center
          logical, intent(in), optional :: mask
          complex(dp) :: res
        end function moment_1_cdp_cdp
        module function moment_2_cdp_cdp(x, order, dim, center, mask) result(res)
          complex(dp), intent(in) :: x(:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          complex(dp), intent(in), optional :: center(merge(size(x, 1), size(x, 2), mask=1<dim))
          logical, intent(in), optional :: mask
          complex(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function moment_2_cdp_cdp
        module function moment_3_cdp_cdp(x, order, dim, center, mask) result(res)
          complex(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          complex(dp), intent(in), optional :: center(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3),&
              & mask=2<dim))
          logical, intent(in), optional :: mask
          complex(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function moment_3_cdp_cdp
        module function moment_4_cdp_cdp(x, order, dim, center, mask) result(res)
          complex(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          complex(dp), intent(in), optional :: center(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3),&
              & mask=2<dim), merge(size(x, 3), size(x, 4), mask=3<dim))
          logical, intent(in), optional :: mask
          complex(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x,&
              & 3), size(x, 4), mask=3<dim))
        end function moment_4_cdp_cdp

        module function moment_scalar_2_iint32_dp(x, order, dim, center, mask) result(res)
          integer(int32), intent(in) :: x(:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp),intent(in) :: center
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function moment_scalar_2_iint32_dp
        module function moment_scalar_3_iint32_dp(x, order, dim, center, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp),intent(in) :: center
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function moment_scalar_3_iint32_dp
        module function moment_scalar_4_iint32_dp(x, order, dim, center, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp),intent(in) :: center
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function moment_scalar_4_iint32_dp

        module function moment_1_iint32_dp(x, order, dim, center, mask) result(res)
          integer(int32), intent(in) :: x(:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp),intent(in), optional :: center
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function moment_1_iint32_dp
        module function moment_2_iint32_dp(x, order, dim, center, mask) result(res)
          integer(int32), intent(in) :: x(:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp),intent(in), optional :: center(merge(size(x, 1), size(x, 2), mask=1<dim))
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function moment_2_iint32_dp
        module function moment_3_iint32_dp(x, order, dim, center, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp),intent(in), optional :: center(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3),&
              & mask=2<dim))
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function moment_3_iint32_dp
        module function moment_4_iint32_dp(x, order, dim, center, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp),intent(in), optional :: center(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3),&
              & mask=2<dim), merge(size(x, 3), size(x, 4), mask=3<dim))
          logical, intent(in), optional :: mask
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function moment_4_iint32_dp

        module function moment_mask_all_1_rdp_rdp(x, order, center, mask) result(res)
          real(dp), intent(in) :: x(:)
          integer, intent(in) :: order
          real(dp), intent(in), optional :: center
          logical, intent(in) :: mask(:)
          real(dp) :: res
        end function moment_mask_all_1_rdp_rdp
        module function moment_mask_all_2_rdp_rdp(x, order, center, mask) result(res)
          real(dp), intent(in) :: x(:,:)
          integer, intent(in) :: order
          real(dp), intent(in), optional :: center
          logical, intent(in) :: mask(:,:)
          real(dp) :: res
        end function moment_mask_all_2_rdp_rdp
        module function moment_mask_all_3_rdp_rdp(x, order, center, mask) result(res)
          real(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: order
          real(dp), intent(in), optional :: center
          logical, intent(in) :: mask(:,:,:)
          real(dp) :: res
        end function moment_mask_all_3_rdp_rdp
        module function moment_mask_all_4_rdp_rdp(x, order, center, mask) result(res)
          real(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: order
          real(dp), intent(in), optional :: center
          logical, intent(in) :: mask(:,:,:,:)
          real(dp) :: res
        end function moment_mask_all_4_rdp_rdp
        module function moment_mask_all_1_cdp_cdp(x, order, center, mask) result(res)
          complex(dp), intent(in) :: x(:)
          integer, intent(in) :: order
          complex(dp), intent(in), optional :: center
          logical, intent(in) :: mask(:)
          complex(dp) :: res
        end function moment_mask_all_1_cdp_cdp
        module function moment_mask_all_2_cdp_cdp(x, order, center, mask) result(res)
          complex(dp), intent(in) :: x(:,:)
          integer, intent(in) :: order
          complex(dp), intent(in), optional :: center
          logical, intent(in) :: mask(:,:)
          complex(dp) :: res
        end function moment_mask_all_2_cdp_cdp
        module function moment_mask_all_3_cdp_cdp(x, order, center, mask) result(res)
          complex(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: order
          complex(dp), intent(in), optional :: center
          logical, intent(in) :: mask(:,:,:)
          complex(dp) :: res
        end function moment_mask_all_3_cdp_cdp
        module function moment_mask_all_4_cdp_cdp(x, order, center, mask) result(res)
          complex(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: order
          complex(dp), intent(in), optional :: center
          logical, intent(in) :: mask(:,:,:,:)
          complex(dp) :: res
        end function moment_mask_all_4_cdp_cdp

        module function moment_mask_all_1_iint32_dp(x, order, center, mask) result(res)
          integer(int32), intent(in) :: x(:)
          integer, intent(in) :: order
          real(dp),intent(in), optional :: center
          logical, intent(in) :: mask(:)
          real(dp) :: res
        end function moment_mask_all_1_iint32_dp
        module function moment_mask_all_2_iint32_dp(x, order, center, mask) result(res)
          integer(int32), intent(in) :: x(:,:)
          integer, intent(in) :: order
          real(dp),intent(in), optional :: center
          logical, intent(in) :: mask(:,:)
          real(dp) :: res
        end function moment_mask_all_2_iint32_dp
        module function moment_mask_all_3_iint32_dp(x, order, center, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:)
          integer, intent(in) :: order
          real(dp),intent(in), optional :: center
          logical, intent(in) :: mask(:,:,:)
          real(dp) :: res
        end function moment_mask_all_3_iint32_dp
        module function moment_mask_all_4_iint32_dp(x, order, center, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: order
          real(dp),intent(in), optional :: center
          logical, intent(in) :: mask(:,:,:,:)
          real(dp) :: res
        end function moment_mask_all_4_iint32_dp

        module function moment_mask_scalar_2_rdp_rdp(x, order, dim, center, mask) result(res)
          real(dp), intent(in) :: x(:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in) :: center
          logical, intent(in) :: mask(:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function moment_mask_scalar_2_rdp_rdp
        module function moment_mask_scalar_3_rdp_rdp(x, order, dim, center, mask) result(res)
          real(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in) :: center
          logical, intent(in) :: mask(:,:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function moment_mask_scalar_3_rdp_rdp
        module function moment_mask_scalar_4_rdp_rdp(x, order, dim, center, mask) result(res)
          real(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in) :: center
          logical, intent(in) :: mask(:,:,:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function moment_mask_scalar_4_rdp_rdp
        module function moment_mask_scalar_2_cdp_cdp(x, order, dim, center, mask) result(res)
          complex(dp), intent(in) :: x(:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          complex(dp), intent(in) :: center
          logical, intent(in) :: mask(:,:)
          complex(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function moment_mask_scalar_2_cdp_cdp
        module function moment_mask_scalar_3_cdp_cdp(x, order, dim, center, mask) result(res)
          complex(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          complex(dp), intent(in) :: center
          logical, intent(in) :: mask(:,:,:)
          complex(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function moment_mask_scalar_3_cdp_cdp
        module function moment_mask_scalar_4_cdp_cdp(x, order, dim, center, mask) result(res)
          complex(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          complex(dp), intent(in) :: center
          logical, intent(in) :: mask(:,:,:,:)
          complex(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x,&
              & 3), size(x, 4), mask=3<dim))
        end function moment_mask_scalar_4_cdp_cdp

        module function moment_mask_1_rdp_rdp(x, order, dim, center, mask) result(res)
          real(dp), intent(in) :: x(:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in), optional :: center
          logical, intent(in) :: mask(:)
          real(dp) :: res
        end function moment_mask_1_rdp_rdp
        module function moment_mask_2_rdp_rdp(x, order, dim, center, mask) result(res)
          real(dp), intent(in) :: x(:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in), optional :: center(merge(size(x, 1), size(x, 2), mask=1<dim))
          logical, intent(in) :: mask(:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function moment_mask_2_rdp_rdp
        module function moment_mask_3_rdp_rdp(x, order, dim, center, mask) result(res)
          real(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in), optional :: center(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3),&
              & mask=2<dim))
          logical, intent(in) :: mask(:,:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function moment_mask_3_rdp_rdp
        module function moment_mask_4_rdp_rdp(x, order, dim, center, mask) result(res)
          real(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in), optional :: center(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3),&
              & mask=2<dim), merge(size(x, 3), size(x, 4), mask=3<dim))
          logical, intent(in) :: mask(:,:,:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function moment_mask_4_rdp_rdp
        module function moment_mask_1_cdp_cdp(x, order, dim, center, mask) result(res)
          complex(dp), intent(in) :: x(:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          complex(dp), intent(in), optional :: center
          logical, intent(in) :: mask(:)
          complex(dp) :: res
        end function moment_mask_1_cdp_cdp
        module function moment_mask_2_cdp_cdp(x, order, dim, center, mask) result(res)
          complex(dp), intent(in) :: x(:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          complex(dp), intent(in), optional :: center(merge(size(x, 1), size(x, 2), mask=1<dim))
          logical, intent(in) :: mask(:,:)
          complex(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function moment_mask_2_cdp_cdp
        module function moment_mask_3_cdp_cdp(x, order, dim, center, mask) result(res)
          complex(dp), intent(in) :: x(:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          complex(dp), intent(in), optional :: center(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3),&
              & mask=2<dim))
          logical, intent(in) :: mask(:,:,:)
          complex(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function moment_mask_3_cdp_cdp
        module function moment_mask_4_cdp_cdp(x, order, dim, center, mask) result(res)
          complex(dp), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          complex(dp), intent(in), optional :: center(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3),&
              & mask=2<dim), merge(size(x, 3), size(x, 4), mask=3<dim))
          logical, intent(in) :: mask(:,:,:,:)
          complex(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x,&
              & 3), size(x, 4), mask=3<dim))
        end function moment_mask_4_cdp_cdp

        module function moment_mask_scalar_2_iint32_dp(x, order, dim, center, mask) result(res)
          integer(int32), intent(in) :: x(:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in) :: center
          logical, intent(in) :: mask(:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function moment_mask_scalar_2_iint32_dp
        module function moment_mask_scalar_3_iint32_dp(x, order, dim, center, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in) :: center
          logical, intent(in) :: mask(:,:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function moment_mask_scalar_3_iint32_dp
        module function moment_mask_scalar_4_iint32_dp(x, order, dim, center, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in) :: center
          logical, intent(in) :: mask(:,:,:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function moment_mask_scalar_4_iint32_dp

        module function moment_mask_1_iint32_dp(x, order, dim, center, mask) result(res)
          integer(int32), intent(in) :: x(:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in), optional :: center
          logical, intent(in) :: mask(:)
          real(dp) :: res
        end function moment_mask_1_iint32_dp
        module function moment_mask_2_iint32_dp(x, order, dim, center, mask) result(res)
          integer(int32), intent(in) :: x(:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in), optional :: center(merge(size(x, 1), size(x, 2), mask=1<dim))
          logical, intent(in) :: mask(:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim))
        end function moment_mask_2_iint32_dp
        module function moment_mask_3_iint32_dp(x, order, dim, center, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in), optional :: center(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3),&
              & mask=2<dim))
          logical, intent(in) :: mask(:,:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim))
        end function moment_mask_3_iint32_dp
        module function moment_mask_4_iint32_dp(x, order, dim, center, mask) result(res)
          integer(int32), intent(in) :: x(:,:,:,:)
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in), optional :: center(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3),&
              & mask=2<dim), merge(size(x, 3), size(x, 4), mask=3<dim))
          logical, intent(in) :: mask(:,:,:,:)
          real(dp) :: res(merge(size(x, 1), size(x, 2), mask=1<dim), merge(size(x, 2), size(x, 3), mask=2<dim), merge(size(x, 3),&
              & size(x, 4), mask=3<dim))
        end function moment_mask_4_iint32_dp
  end interface moment

end module stdlib_stats


module statistics
  !! Provides routines for basic statistical methods.

  implicit none

  public :: factorial, mean, variance, standardDeviation, covariance

contains

pure integer function factorial(x) result(xfac)
  !! Returns the factorial of the scalar value \(\mathbf{x}\),
  !! $$ x! = n(n-1)(n-2)\cdots(3)(2)(1) $$

  integer, intent(in) :: x

  integer :: i

  xfac = 1
  if (x >= 0) then
     do i = x, 1, -1
        xfac = xfac * i
     end do
  end if

end function factorial

pure real function mean(x) result(mu)
  !! Returns the arithmatic mean of a vector \(\mathbf{x}\).
  !! $$ \mu = \frac{1}{n} \sum_{i=1}^n x_i $$

  implicit none

  real, allocatable, intent(in) :: x(:)

  real :: Sx
  integer :: n, i, l, u

  mu = 0.0
  Sx = 0.0

  if (allocated(x)) then
     n = size(x)
     l = lbound(x,1)
     u = ubound(x,1)

     do i = l, u
        Sx = Sx + x(i)
     end do

     mu = Sx / n
  end if
end function mean

pure real function median(x) result (xm)
  !! Returns the median of a vector. If the vector has an odd number
  !! of elements, the "mean of middle" two is returned.

  implicit none

  real, allocatable, intent(in) :: x(:)

  integer :: n, nd2
  real :: xmm1, xmp1

  n = size(x)
  nd2 = n/2

  if (mod(n,2) .eq. 0) then
     xm = x(nd2)
  else
     xmm1 = x(nd2-1)
     xmp1 = x(nd2+1)
     xm = (xmm1 + xmp1) / 2.0
  end if

end function median

pure real function variance(x) result(ss)
  !! Returns the sample variance of the vector \(\mathbf{x}\),
  !! $$ s^2 = \frac{1}{n-1} \sum_{i=1}^n \left(x_i - \mu_x \right)^2 $$

  implicit none

  real, allocatable, intent(in) :: x(:)

  integer :: n, i, l, u
  real :: xb

  n = size(x)

  xb = mean(x)
  ss = 0.0

  if (allocated(x)) then
     l = lbound(x,1)
     u = ubound(x,1)
     do i = l, u
        ss = ss + (x(i) - xb)**2
     end do

     ss = 1 / (n - 1) * ss
  end if

end function variance

pure real function standardDeviation(x) result(s)
  !! Returns the sample standard deviation of a vector \(\mathbf{x}\),
  !! $$ s = \sqrt{\frac{1}{n-1} \sum_{i=1}^n \left(x_i - \mu_x \right)^2} $$

  implicit none

  real, allocatable, intent(in) :: x(:)

  s = sqrt(variance(x))

end function standardDeviation

pure real function covariance(x, y) result(sigma)
  !! Returns the covariance of two vectors \(\mathbf{x}\) and \(\mathbf{y}\),
  !! $$ \sigma(x,y) =\frac{1}{n-1} \sum_{i=1}^n \left(x_i - \mu_x \right) \left(y_i-\mu_y\right) $$

  implicit none

  real, allocatable, intent(in) :: x(:), y(:)

  real :: Sx, Sy, xb, yb
  integer :: n, i, l, u

  !!@todo If x and y aren't same size, return error
  !!@todo Handle x and y not same bound start/end
  sigma = 0.0

  if (allocated(x).and. allocated(y)) then
    n = size(x)

    xb = mean(x)
    yb = mean(y)

    l = lbound(x,1)
    u = ubound(x,1)
    do i = l, u
      Sx = x(i) - xb
      Sy = y(i) - yb
      sigma = sigma + (Sx*Sy / n)
    end do
  end if

end function covariance

end module statistics


program main
    implicit none
    integer :: n, ans
    print "(a)", "Number n is "
    read *, n
    print "(a, i0)", "n! is ", factorial_f(n)
    call factorial_s(n, ans)
    print "(a, i0)", "n! is ", ans
contains
    recursive function factorial_f(i) result(answer)
        integer             :: answer
        integer, intent(in) :: i

        if (i == 0) then
            answer = 1
        else
            answer = i * factorial_f(i - 1)
        end if
    end function factorial_f

    recursive subroutine factorial_s(i, answer)
        integer, intent(in)    :: i
        integer, intent(inout) :: answer

        if (i == 0) then
            answer = 1
        else
            call factorial_s(i - 1, answer)
            answer = i * answer
        end if
    end subroutine factorial_s
end program main


program main

use euler

implicit none

        ! This one is done by a pen and paper reduction of the problem. I
        ! found that I could represent the right corner trivially as the
        ! number of what iteration of square it was, squared. The subsequent
        ! results were as follows;
        !
        ! S0 = n**2;
        ! S1 = n**2 - (n - 1);
        ! S2 = n**2 - 2(n - 1);
        ! S3 = n**2 - 3(n - 1);
        !
        ! Thus, our formula for the sum of all of these 'rings' in the square
        ! is subsequently: 4n**2 - 6(n-1). Note however, this solution is for
        ! n in reals > 1

        integer (int64), parameter :: MAX_N = 1001;
        integer (int64) :: sum_diag, n;

        sum_diag = 1;

        do n = 3, MAX_N, 2
                sum_diag = sum_diag + outer_spiral_sum(n);
        end do

        call printint(sum_diag);

contains

        pure function outer_spiral_sum(n)

                integer (int64), intent(in) :: n;
                integer (int64) :: outer_spiral_sum;

                outer_spiral_sum = (4 * n ** 2) - 6 * n + 6;

        end function outer_spiral_sum

end program main


! Created by EverLookNeverSee@GitHub on 6/8/20
! For more information see FCS/img/Exercise_09_b.png

program main
    implicit none
    ! declaring and initializing variables
    integer :: i, j, m, n
    real :: norm, tmp, sum_of_elements = 0.0
    real, allocatable, dimension(:,:) :: A
    ! getting shape of matrix from user input
    print *, "Enter the shape of matrix(rows, columns):"
    read *, m, n
    ! allocating mem space to matrix
    allocate(A(m, n))
    ! getting matrix elements from user input
    do i = 1, m
        do j = 1, n
            print *, "A(", i, j, "):"
            read *, A(i, j)
        end do
    end do
    ! sum of all squared elements in matrix
    do i = 1, m
        do j = 1, n
            tmp = (abs(A(i, j))) ** 2
            sum_of_elements = sum_of_elements + tmp
        end do
    end do
    ! square root of sum
    norm = sqrt(sum_of_elements)
    ! printing results
    print *, "Norm =", norm
end program main


!
!     Modified Date: 03/16/2018
!     Description: Adjust the function
!
MODULE wm
  IMPLICIT NONE
  PRIVATE
  PUBLIC :: IsThisALeapYear, days_passed_of_this_year
CONTAINS
  FUNCTION IsThisALeapYear(year) RESULT(leap_day)
    IMPLICIT NONE
    INTEGER :: year
    INTEGER :: leap_day

    IF(MOD(year,400) == 0) THEN
       leap_day = 1
    ELSE IF(MOD(year,100) == 0) THEN
       leap_day = 0
    ELSE IF (MOD(year,4) == 0) THEN
       leap_day = 1
    ELSE
       leap_day = 0
    END IF

  END FUNCTION IsThisALeapYear

  FUNCTION days_passed_of_this_year(year, month, day) RESULT(day_of_year)
    IMPLICIT NONE
    INTEGER  :: year, month, day
    INTEGER :: day_of_year
    INTEGER :: i
    day_of_year = day
    DO i = 1, month - 1
       SELECT CASE(i)
       CASE(1, 3, 5, 7, 8, 10, 12)
          day_of_year = day_of_year + 31
       CASE(4, 6, 9, 11)
          day_of_year = day_of_year + 30
       CASE(2)
          day_of_year = day_of_year + 28 + IsThisALeapYear(year)
       END SELECT
    END DO
  END FUNCTION days_passed_of_this_year
END MODULE wm
PROGRAM doy
  USE wm

  IMPLICIT NONE

  INTEGER    :: i, days_accumulated
  INTEGER    :: month_begin, day_begin, year_begin, &
       month_end, day_end, year_end
  WRITE (*,*)'This program caculates interval in days of 2 time'
  WRITE (*,*)'Begin date: month(1-12),day(1-31), year in that order'
  READ (*,*) month_begin, day_begin, year_begin
  WRITE (*,*)'End date: month(1-12),day(1-31), year in that order'
  READ (*,*) month_end, day_end, year_end

  IF (year_begin == year_end) THEN
     days_accumulated = days_passed_of_this_year(year_end, month_end, day_end)- &
                        days_passed_of_this_year(year_begin, month_begin,day_begin)
  ELSE
     days_accumulated = IsThisALeapYear(year_begin) + 365 - days_passed_of_this_year(year_begin, month_begin,day_begin)
     DO i = year_begin+1, year_end -1
        days_accumulated = days_accumulated + IsThisALeapYear(i)+365
     END DO
     days_accumulated = days_accumulated + days_passed_of_this_year(year_end, month_end, day_end)
  END IF

  WRITE (*,*)day_begin, month_begin, year_begin
  WRITE (*,*)day_end, month_end, year_end
  WRITE (*,*)'day passed =',days_accumulated
END PROGRAM doy


  subroutine inversep(a,c,n)
!============================================================
! Inverse matrix
! Method: Based on Doolittle LU factorization for Ax=b
! Alex G. December 2009
! This version does parallel processing, using OpenMP.
!
! Note: A and C are both double precision.
!-----------------------------------------------------------
! input ...
! a(n,n) - array of coefficients for matrix A
! n      - dimension
! output ...
! c(n,n) - inverse matrix of A
! comments ...
! the original matrix a(n,n) will be destroyed
! during the calculation
!===========================================================
use iso_c_binding

implicit none
integer n
real(8)	a(n,n), c(n,n)
real(8), allocatable :: L(:,:), U(:,:), b(:), d(:), x(:)
real(8)	coeff
integer	i, j, k

! step 0: initialization for matrices L and U and b
! Fortran 90/95 allows such operations on matrices

allocate (L(n,n))
allocate (U(n,n))
allocate (b(n))
allocate (d(n))
allocate (x(n))
L=0.0
U=0.0
b=0.0

! step 1: forward elimination

!$omp parallel default(private) shared(a,n,L)
!$omp do
do k=1, n-1
   do i=k+1,n
      coeff=a(i,k)/a(k,k)
      L(i,k) = coeff
      do j=k+1,n
         a(i,j) = a(i,j)-coeff*a(k,j)
      end do
   end do
end do
!$omp end do
!$omp end parallel

! Step 2: prepare L and U matrices
! L matrix is a matrix of the elimination coefficient
! + the diagonal elements are 1.0
do i=1,n
  L(i,i) = 1.0
end do
! U matrix is the upper triangular part of A
do j=1,n
  do i=1,j
    U(i,j) = a(i,j)
  end do
end do

! Step 3: compute columns of the inverse matrix C
!$omp parallel default(private) shared(U,L,n,c)
!$omp do
do k=1,n
  b(k)=1.0
  d(1) = b(1)
! Step 3a: Solve Ld=b using the forward substitution
  do i=2,n
    d(i)=b(i)
    do j=1,i-1
      d(i) = d(i) - L(i,j)*d(j)
    end do
  end do
! Step 3b: Solve Ux=d using the back substitution
  x(n)=d(n)/U(n,n)
  do i = n-1,1,-1
    x(i) = d(i)
    do j=n,i+1,-1
      x(i)=x(i)-U(i,j)*x(j)
    end do
    x(i) = x(i)/u(i,i)
  end do
! Step 3c: fill the solutions x(n) into column k of C
  do i=1,n
    c(i,k) = x(i)
  end do
  b(k)=0.0
end do
!$omp end do
!$omp end parallel
deallocate(L)
deallocate(U)
deallocate(b)
deallocate(d)
deallocate(x)
end subroutine inversep


program main
    implicit none

    integer :: required_divisors = 500
    integer :: num, i

    num = 0
    i = 0
    do while (count_divisors(num) < required_divisors)
        num = num + i
        i = i + 1
    end do

    print *, num

contains
function count_divisors(number)
        implicit none
        integer, intent(in) :: number
        integer :: count_divisors
        integer :: i

        count_divisors = 1
        do i = 2, number / 2
            if (mod(number, i) == 0) then
                count_divisors = count_divisors + 1
            end if
        end do

        count_divisors = count_divisors + 1

    end function count_divisors
end program main


module funcs
implicit none
contains

real(kind=8) function f(x)
   real(kind=8) x

   f = 2*sin(sinh(1/(sin(x)))**(-6))*(1/sin(x)) - 0.5
end function f

end module funcs


!**********************************************************************************************************
!
!                              C O N V E R S I O N   D E   T E M P E R A T U R A
!
!       Program:         fahtocel
!       Autor:           David Duran
!       Fecha:           28 de junio del 2021
!       Lenguaje:        Fortran-90
!       Versión:         0.3
!       Descripción:     Este programa convierte de Fahrenheit a Celsius y viceversa.
!
!**********************************************************************************************************

program fahtocel

    integer :: opcion
    integer:: fh
    real :: cl

    do

    print*, ""
    print*, "OPCIÓN 1: Convertir de Fahrenheit a Celsius."
    print*, "OPCIÓN 2: Convertir de Celsius a Fahrenheit."
    print*, ""
    print*, "Escriba la opción que prefiera, 1 o 2"
    print*, ""
    read*, opcion

    if (opcion == 1) then
        print*, ""
        print*, "********************************************************"
        print*, "Nota: Solo se aceptan valores entre -50 y 150 (inclusivo)"
        print*, "Ingrese la temperatura en Fahrenheit: "
        print*, "********************************************************"
        read*, fh

        if (-50 <= fh .AND. fh <= 150) then
            cl= (fh - 32) / 1.8
            print*, ""
            print*, "La temperatura en Celsius es: ", cl
        else
            print*, ""
            print*, "Valores no aceptados, intente nuevamente."
        end if
    else if(opcion == 2) then
        print*, ""
        print*, "**********************************"
        print*, "Ingrese la temperatura en Celsius: "
        print*, "**********************************"
        read*, cl
        fh= (cl*1.8)+32;
        print*, ""
        print*, "La temperatura en Fahrenheit es: ",fh
    else
        print*, "Opción inválida"
    end if

    end do

end program fahtocel


subroutine laplacegridfortran(n, top, bottom, left, right, tol, iter_max, &
    phi, err_max, iters)

    implicit none
    integer, parameter :: dp = kind(0.d0)

    ! inputs
    real(dp), intent(in) :: top, bottom, left, right, tol
    integer, intent(in) :: n, iter_max

    ! outputs
    real(dp), intent(out), dimension(n+1, n+1) :: phi
    real(dp), intent(out) :: err_max
    integer, intent(out) :: iters

    ! local
    integer :: i, j
    real(dp) :: phi_prev

    phi(1, :) = bottom
    phi(n+1, :) = top
    phi(:, 1) = left
    phi(:, n+1) = right

    iters = 0
    err_max = 1e6

    do while (err_max > tol .and. iters < iter_max)

        err_max = -1.0

        ! iterating over interior points
        do i = 2, n
            do j = 2, n

                ! save previous point
                phi_prev = phi(i, j)

                ! update point
                phi(i, j) = (phi(i-1,j) + phi(i+1,j) + phi(i,j-1) + phi(i,j+1))/4.0

                ! update maximum error
                err_max = max(err_max, abs(phi(i, j) - phi_prev))
            end do
        end do

        iters = iters + 1

    end do

end subroutine laplacegridfortran


c square matrix multiplication
      program matmul02
      integer n
      parameter (n=100)
      integer a(n,n), b(n,n), c(n,n), x
      integer i, j, k
      logical flg
      print *,n
C initialize the square matrices with ones
      do j=1, n
         do i=1, n
            a(i,j) = 1
            b(i,j) = 1
         enddo
      enddo
C multiply the two square matrices of ones
      do j=1, n
         do i=1, n
            x = 0
            do k=1, n
               x = x + a(i,k)*b(k,j)
            enddo
            c(i,j) = x
         enddo
      enddo
C The result should be a square matrice of n
      flg = .TRUE.
      do j=1, n
         do i=1, n
            flg = flg .AND. (c(i,j) .EQ. n)
         enddo
      enddo
      if (flg .EQV. .FALSE.) then
         print *, ("CHECK FAILED")
      else
         print *, ("CHECK SUCCEED")
      endif
      end


      MODULE funcs
	  		implicit none
	  CONTAINS
	  		FUNCTION xFunc(x)
	  		REAL :: xFunc
			REAL :: x
			xFunc = sin(x)/x
			RETURN
	  		END FUNCTION xFunc
	  END MODULE funcs

	  MODULE integration
	  		USE funcs
			CONTAINS
			  SUBROUTINE trapzd(a, b, s, n)
					  INTEGER n
					  REAL a, b, s
					  INTEGER it, j
					  REAL del, sum, tnm, x
					  if (n.eq.1) then
									s = 0.5*(b-a)*(xFunc(a) + xFunc(b))
					  else
									it = 2**(n-2)
									tnm=it
									del=(b-a)/tnm
									x=a+0.5*del
									sum = 0.
									do j = 1, it
														sum = sum + xFunc(x)
														x = x + del
									end do
									s = 0.5*(s+(b-a)*sum/tnm)
					  endif
					  return
			  END SUBROUTINE trapzd

			  SUBROUTINE qsimp(a, b, s)
					  INTEGER JMAX
					  REAL a, b, s, EPS
					  PARAMETER (EPS=1.e-6, JMAX=20)

					  INTEGER j
					  REAL os, ost, st
					  ost=-1.e30
					  os=-1.e30
					  do j = 1, JMAX
								call trapzd(a, b, st, j)
								s=(4.*st-ost)/3.
								jj: if (j.gt.5) then
									kk: if (abs(s-os).lt.EPS*abs(os)) then
											 return
									end if kk
									mm: if (s.eq.0 .and. olds.eq.0) then
											return
									end if mm
								end if jj
								os = s
								ost = st
					 end do
			 END SUBROUTINE qsimp
	  END MODULE integration

	  PROGRAM CalIntegrator
		  USE integration
		  implicit none
		  REAL a, b, s, pi
		  INTEGER n
		  pi = 3.141592654
		  a = pi/2
		  b = pi
		  CALL qsimp(a, b, s)
		  WRITE (*,*) s
	  END PROGRAM CalIntegrator


subroutine SphericalCapCoef(coef, theta, lmax)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
!	This routine will return the coefficients for a spherical
!	cap (located at the north pole) with angular radius theta,
!	using the geodesy 4-pi normalization.
!
!	Calling Parameters:
!		IN
!			theta	Angular radius of spherical cap in RADIANS.
!		OUT
!			coef	m=0 coefficients normalized according to the
!				geodesy convention, further normalized such
!				that the degree-0 term is 1. (i.e., function
!				has an average value of one over the entire
!				sphere).
!		OPTIONAL
!			lmax	Maximum spherical harmonic degree.
!
!	Dependencies: PlBar
!
!	Written by Mark Wieczorek
!
!	Copyright (c) 2005, Mark A. Wieczorek
!	All rights reserved.
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	use SHTOOLS, only: PlBar

	implicit none
	real*8, intent(out) ::	coef(:)
	real*8, intent(in) ::	theta
	integer, intent(in), optional ::	lmax
	real*8 ::	x, top, bot, pi
	real*8, allocatable ::	pl(:)
	integer ::	l, lmax2, astat

	pi = acos(-1.0d0)
	coef = 0.0d0
	x = cos(theta)

	if (present(lmax) ) then
		lmax2 = lmax
	else
		lmax2 = size(coef) - 1
	endif

	allocate(pl(lmax2+3), stat = astat)

	if(astat /=0) then
		print*, "Error --- SphericalCapCoef"
		print*, "Unable to allocate array pl", astat
		stop
	endif

	call PlBar(pl, lmax2+2, x)

	coef(1) = 1.0d0

	bot = pl(1) - pl(2) / sqrt(3.0d0)

	do l=1, lmax2
		top =  pl(l) / sqrt(dble(2*l-1)) -pl(l+2) / sqrt(dble(2*l+3))
		coef(l+1) = top / (bot * sqrt(dble(2*l+1)) )
	enddo

	deallocate (pl)

end subroutine SphericalCapCoef