stdlib_stats.fypp Source File


Source Code

#:include "common.fypp"
#:set RANKS = range(1, MAXRANK + 1)
#:set REDRANKS = range(2, MAXRANK + 1)
#:set RC_KINDS_TYPES = REAL_KINDS_TYPES + CMPLX_KINDS_TYPES
#:set IR_KINDS_TYPES_OUTPUT = list(zip(INT_KINDS,INT_TYPES, ['dp']*len(INT_KINDS))) + list(zip(REAL_KINDS, REAL_TYPES, REAL_KINDS))
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
  use stdlib_linalg_state, only: linalg_state_type
  implicit none
  private
  ! Public API
  public :: corr, cov, mean, median, moment, var
  public :: pca, pca_transform, pca_inverse_transform


  interface corr
    !! version: experimental
    !!
    !! Pearson correlation of array elements
    !! ([Specification](../page/specs/stdlib_stats.html#corr-pearson-correlation-of-array-elements))
    #:for k1, t1 in RC_KINDS_TYPES
      #:set RName = rname("corr",1, t1, k1)
      module function ${RName}$(x, dim, mask) result(res)
        ${t1}$, intent(in) :: x(:)
        integer, intent(in) :: dim
        logical, intent(in), optional :: mask
        real(${k1}$) :: res
      end function ${RName}$
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:set RName = rname("corr",1, t1, k1, 'dp')
      module function ${RName}$(x, dim, mask) result(res)
        ${t1}$, intent(in) :: x(:)
        integer, intent(in) :: dim
        logical, intent(in), optional :: mask
        real(dp) :: res
      end function ${RName}$
    #:endfor

    #:for k1, t1 in RC_KINDS_TYPES
      #:set RName = rname("corr_mask",1, t1, k1)
      module function ${RName}$(x, dim, mask) result(res)
        ${t1}$, intent(in) :: x(:)
        integer, intent(in) :: dim
        logical, intent(in) :: mask(:)
        real(${k1}$) :: res
      end function ${RName}$
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:set RName = rname("corr_mask",1, t1, k1, 'dp')
      module function ${RName}$(x, dim, mask) result(res)
        ${t1}$, intent(in) :: x(:)
        integer, intent(in) :: dim
        logical, intent(in) :: mask(:)
        real(dp) :: res
      end function ${RName}$
    #:endfor

    #:for k1, t1 in RC_KINDS_TYPES
      #:set RName = rname("corr",2, t1, k1)
      module function ${RName}$(x, dim, mask) result(res)
        ${t1}$, intent(in) :: x(:, :)
        integer, intent(in) :: dim
        logical, intent(in), optional :: mask
        ${t1}$ :: res(merge(size(x, 1), size(x, 2), mask = 1<dim)&
                            , merge(size(x, 1), size(x, 2), mask = 1<dim))
      end function ${RName}$
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:set RName = rname("corr",2, t1, k1, 'dp')
      module function ${RName}$(x, dim, mask) result(res)
        ${t1}$, 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 ${RName}$
    #:endfor

    #:for k1, t1 in RC_KINDS_TYPES
      #:set RName = rname("corr_mask",2, t1, k1)
      module function ${RName}$(x, dim, mask) result(res)
        ${t1}$, intent(in) :: x(:, :)
        integer, intent(in) :: dim
        logical, intent(in) :: mask(:,:)
        ${t1}$ :: res(merge(size(x, 1), size(x, 2), mask = 1<dim)&
                            , merge(size(x, 1), size(x, 2), mask = 1<dim))
      end function ${RName}$
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:set RName = rname("corr_mask",2, t1, k1, 'dp')
      module function ${RName}$(x, dim, mask) result(res)
        ${t1}$, 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 ${RName}$
    #:endfor

  end interface corr


  interface cov
    !! version: experimental
    !!
    !! Covariance of array elements
    !! ([Specification](../page/specs/stdlib_stats.html#cov-covariance-of-array-elements))
    #:for k1, t1 in RC_KINDS_TYPES
      #:set RName = rname("cov",1, t1, k1)
      module function ${RName}$(x, dim, mask, corrected) result(res)
        ${t1}$, intent(in) :: x(:)
        integer, intent(in) :: dim
        logical, intent(in), optional :: mask
        logical, intent(in), optional :: corrected
        real(${k1}$) :: res
      end function ${RName}$
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:set RName = rname("cov",1, t1, k1, 'dp')
      module function ${RName}$(x, dim, mask, corrected) result(res)
        ${t1}$, intent(in) :: x(:)
        integer, intent(in) :: dim
        logical, intent(in), optional :: mask
        logical, intent(in), optional :: corrected
        real(dp) :: res
      end function ${RName}$
    #:endfor

    #:for k1, t1 in RC_KINDS_TYPES
      #:set RName = rname("cov_mask",1, t1, k1)
      module function ${RName}$(x, dim, mask, corrected) result(res)
        ${t1}$, intent(in) :: x(:)
        integer, intent(in) :: dim
        logical, intent(in) :: mask(:)
        logical, intent(in), optional :: corrected
        real(${k1}$) :: res
      end function ${RName}$
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:set RName = rname("cov_mask",1, t1, k1, 'dp')
      module function ${RName}$(x, dim, mask, corrected) result(res)
        ${t1}$, intent(in) :: x(:)
        integer, intent(in) :: dim
        logical, intent(in) :: mask(:)
        logical, intent(in), optional :: corrected
        real(dp) :: res
      end function ${RName}$
    #:endfor

    #:for k1, t1 in RC_KINDS_TYPES
      #:set RName = rname("cov",2, t1, k1)
      module function ${RName}$(x, dim, mask, corrected) result(res)
        ${t1}$, intent(in) :: x(:, :)
        integer, intent(in) :: dim
        logical, intent(in), optional :: mask
        logical, intent(in), optional :: corrected
        ${t1}$ :: res(merge(size(x, 1), size(x, 2), mask = 1<dim)&
                            , merge(size(x, 1), size(x, 2), mask = 1<dim))
      end function ${RName}$
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:set RName = rname("cov",2, t1, k1, 'dp')
      module function ${RName}$(x, dim, mask, corrected) result(res)
        ${t1}$, 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 ${RName}$
    #:endfor

    #:for k1, t1 in RC_KINDS_TYPES
      #:set RName = rname("cov_mask",2, t1, k1)
      module function ${RName}$(x, dim, mask, corrected) result(res)
        ${t1}$, intent(in) :: x(:, :)
        integer, intent(in) :: dim
        logical, intent(in) :: mask(:,:)
        logical, intent(in), optional :: corrected
        ${t1}$ :: res(merge(size(x, 1), size(x, 2), mask = 1<dim)&
                            , merge(size(x, 1), size(x, 2), mask = 1<dim))
      end function ${RName}$
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:set RName = rname("cov_mask",2, t1, k1, 'dp')
      module function ${RName}$(x, dim, mask, corrected) result(res)
        ${t1}$, 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 ${RName}$
    #:endfor
  end interface cov


  interface mean
    !! version: experimental
    !!
    !! Mean of array elements
    !! ([Specification](../page/specs/stdlib_stats.html#mean-mean-of-array-elements))
    #:for k1, t1 in RC_KINDS_TYPES
      #:for rank in RANKS
        #:set RName = rname("mean_all",rank, t1, k1)
        module function ${RName}$ (x, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          logical, intent(in), optional :: mask
          ${t1}$ :: res
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:for rank in RANKS
      #:set RName = rname('mean_all', rank, t1, k1,'dp')
        module function ${RName}$(x, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in RC_KINDS_TYPES
      #:for rank in RANKS
      #:set RName = rname("mean",rank, t1, k1)
        module function ${RName}$(x, dim, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          ${t1}$ :: res${reduced_shape('x', rank, 'dim')}$
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:for rank in RANKS
        #:set RName = rname("mean",rank, t1, k1,'dp')
        module function ${RName}$(x, dim, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          real(dp) :: res${reduced_shape('x', rank, 'dim')}$
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in RC_KINDS_TYPES
      #:for rank in RANKS
        #:set RName = rname('mean_mask_all',rank, t1, k1)
        module function ${RName}$(x, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          logical, intent(in) :: mask${ranksuffix(rank)}$
          ${t1}$ :: res
          end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:for rank in RANKS
      #:set RName = rname('mean_mask_all',rank, t1, k1, 'dp')
        module function ${RName}$(x, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          logical, intent(in) :: mask${ranksuffix(rank)}$
          real(dp) :: res
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in RC_KINDS_TYPES
      #:for rank in RANKS
      #:set RName = rname('mean_mask',rank, t1, k1)
        module function ${RName}$(x, dim, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: dim
          logical, intent(in) :: mask${ranksuffix(rank)}$
          ${t1}$ :: res${reduced_shape('x', rank, 'dim')}$
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:for rank in RANKS
      #:set RName = rname('mean_mask',rank, t1, k1, 'dp')
        module function ${RName}$(x, dim, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: dim
          logical, intent(in) :: mask${ranksuffix(rank)}$
          real(dp) :: res${reduced_shape('x', rank, 'dim')}$
        end function ${RName}$
      #:endfor
    #:endfor

  end interface mean


  interface median
    !! version: experimental
    !!
    !! Median of array elements
    !! ([Specification](../page/specs/stdlib_stats.html#median-median-of-array-elements))
    #:for k1, t1, o1 in IR_KINDS_TYPES_OUTPUT
      #:for rank in RANKS
        #:set name = rname("median_all",rank, t1, k1, o1)
        module function ${name}$ (x, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          logical, intent(in), optional :: mask
          real(${o1}$) :: res
        end function ${name}$
      #:endfor
    #:endfor
  
    #:for k1, t1, o1 in IR_KINDS_TYPES_OUTPUT
      #:for rank in RANKS
        #:set name = rname("median",rank, t1, k1, o1)
        module function ${name}$(x, dim, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          real(${o1}$) :: res${reduced_shape('x', rank, 'dim')}$
        end function ${name}$
      #:endfor
    #:endfor
  
    #:for k1, t1, o1 in IR_KINDS_TYPES_OUTPUT
      #:for rank in RANKS
        #:set name = rname('median_all_mask',rank, t1, k1, o1)
        module function ${name}$(x, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          logical, intent(in) :: mask${ranksuffix(rank)}$
          real(${o1}$) :: res
        end function ${name}$
      #:endfor
    #:endfor
  
    #:for k1, t1, o1 in IR_KINDS_TYPES_OUTPUT
      #:for rank in RANKS
        #:set name = rname('median_mask',rank, t1, k1, o1)
        module function  ${name}$(x, dim, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: dim
          logical, intent(in) :: mask${ranksuffix(rank)}$
          real(${o1}$) :: res${reduced_shape('x', rank, 'dim')}$
        end function ${name}$
      #:endfor
    #:endfor

  end interface


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

    #:for k1, t1 in RC_KINDS_TYPES
      #:for rank in RANKS
        #:set RName = rname("var_all",rank, t1, k1)
        module function ${RName}$(x, mask, corrected) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(${k1}$) :: res
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:for rank in RANKS
        #:set RName = rname("var_all",rank, t1, k1, 'dp')
        module function ${RName}$(x, mask, corrected) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in RC_KINDS_TYPES
      #:for rank in RANKS
        #:set RName = rname("var",rank, t1, k1)
        module function ${RName}$(x, dim, mask, corrected) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(${k1}$) :: res${reduced_shape('x', rank, 'dim')}$
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:for rank in RANKS
        #:set RName = rname("var",rank, t1, k1, 'dp')
        module function ${RName}$(x, dim, mask, corrected) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: dim
          logical, intent(in), optional :: mask
          logical, intent(in), optional :: corrected
          real(dp) :: res${reduced_shape('x', rank, 'dim')}$
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in RC_KINDS_TYPES
      #:for rank in RANKS
        #:set RName = rname("var_mask_all",rank, t1, k1)
        module function ${RName}$(x, mask, corrected) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          logical, intent(in) :: mask${ranksuffix(rank)}$
          logical, intent(in), optional :: corrected
          real(${k1}$) :: res
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:for rank in RANKS
        #:set RName = rname("var_mask_all",rank, t1, k1, 'dp')
        module function ${RName}$(x, mask, corrected) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          logical, intent(in) :: mask${ranksuffix(rank)}$
          logical, intent(in), optional :: corrected
          real(dp) :: res
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in RC_KINDS_TYPES
      #:for rank in RANKS
        #:set RName = rname("var_mask",rank, t1, k1)
        module function ${RName}$(x, dim, mask, corrected) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: dim
          logical, intent(in) :: mask${ranksuffix(rank)}$
          logical, intent(in), optional :: corrected
          real(${k1}$) :: res${reduced_shape('x', rank, 'dim')}$
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:for rank in RANKS
        #:set RName = rname("var_mask",rank, t1, k1, 'dp')
        module function ${RName}$(x, dim, mask, corrected) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: dim
          logical, intent(in) :: mask${ranksuffix(rank)}$
          logical, intent(in), optional :: corrected
          real(dp) :: res${reduced_shape('x', rank, 'dim')}$
        end function ${RName}$
      #:endfor
    #:endfor

  end interface var


  interface moment
    !! version: experimental
    !!
    !! Central moment of array elements
    !! ([Specification](../page/specs/stdlib_stats.html#moment-central-moments-of-array-elements))
    #:for k1, t1 in RC_KINDS_TYPES
      #:for rank in RANKS
        #:set RName = rname("moment_all",rank, t1, k1)
        module function ${RName}$(x, order, center, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: order
          ${t1}$, intent(in), optional :: center
          logical, intent(in), optional :: mask
          ${t1}$ :: res
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:for rank in RANKS
        #:set RName = rname("moment_all",rank, t1, k1, 'dp')
        module function ${RName}$(x, order, center, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: order
          real(dp), intent(in), optional :: center
          logical, intent(in), optional :: mask
          real(dp) :: res
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in RC_KINDS_TYPES
      #:for rank in REDRANKS
        #:set RName = rname("moment_scalar",rank, t1, k1)
        module function ${RName}$(x, order, dim, center, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: order
          integer, intent(in) :: dim
          ${t1}$, intent(in) :: center
          logical, intent(in), optional :: mask
          ${t1}$ :: res${reduced_shape('x', rank, 'dim')}$
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in RC_KINDS_TYPES
      #:for rank in RANKS
        #:set RName = rname("moment",rank, t1, k1)
        module function ${RName}$(x, order, dim, center, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: order
          integer, intent(in) :: dim
          ${t1}$, intent(in), optional :: center${reduced_shape('x', rank, 'dim')}$
          logical, intent(in), optional :: mask
          ${t1}$ :: res${reduced_shape('x', rank, 'dim')}$
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:for rank in REDRANKS
        #:set RName = rname("moment_scalar",rank, t1, k1, 'dp')
        module function ${RName}$(x, order, dim, center, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp),intent(in) :: center
          logical, intent(in), optional :: mask
          real(dp) :: res${reduced_shape('x', rank, 'dim')}$
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:for rank in RANKS
        #:set RName = rname("moment",rank, t1, k1, 'dp')
        module function ${RName}$(x, order, dim, center, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp),intent(in), optional :: center${reduced_shape('x', rank, 'dim')}$
          logical, intent(in), optional :: mask
          real(dp) :: res${reduced_shape('x', rank, 'dim')}$
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in RC_KINDS_TYPES
      #:for rank in RANKS
        #:set RName = rname("moment_mask_all",rank, t1, k1)
        module function ${RName}$(x, order, center, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: order
          ${t1}$, intent(in), optional :: center
          logical, intent(in) :: mask${ranksuffix(rank)}$
          ${t1}$ :: res
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:for rank in RANKS
        #:set RName = rname("moment_mask_all",rank, t1, k1, 'dp')
        module function ${RName}$(x, order, center, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: order
          real(dp),intent(in), optional :: center
          logical, intent(in) :: mask${ranksuffix(rank)}$
          real(dp) :: res
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in RC_KINDS_TYPES
      #:for rank in REDRANKS
        #:set RName = rname("moment_mask_scalar",rank, t1, k1)
        module function ${RName}$(x, order, dim, center, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: order
          integer, intent(in) :: dim
          ${t1}$, intent(in) :: center
          logical, intent(in) :: mask${ranksuffix(rank)}$
          ${t1}$ :: res${reduced_shape('x', rank, 'dim')}$
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in RC_KINDS_TYPES
      #:for rank in RANKS
        #:set RName = rname("moment_mask",rank, t1, k1)
        module function ${RName}$(x, order, dim, center, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: order
          integer, intent(in) :: dim
          ${t1}$, intent(in), optional :: center${reduced_shape('x', rank, 'dim')}$
          logical, intent(in) :: mask${ranksuffix(rank)}$
          ${t1}$ :: res${reduced_shape('x', rank, 'dim')}$
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:for rank in REDRANKS
        #:set RName = rname("moment_mask_scalar",rank, t1, k1, 'dp')
        module function ${RName}$(x, order, dim, center, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in) :: center
          logical, intent(in) :: mask${ranksuffix(rank)}$
          real(dp) :: res${reduced_shape('x', rank, 'dim')}$
        end function ${RName}$
      #:endfor
    #:endfor

    #:for k1, t1 in INT_KINDS_TYPES
      #:for rank in RANKS
        #:set RName = rname("moment_mask",rank, t1, k1, 'dp')
        module function ${RName}$(x, order, dim, center, mask) result(res)
          ${t1}$, intent(in) :: x${ranksuffix(rank)}$
          integer, intent(in) :: order
          integer, intent(in) :: dim
          real(dp), intent(in), optional :: center${reduced_shape('x', rank, 'dim')}$
          logical, intent(in) :: mask${ranksuffix(rank)}$
          real(dp) :: res${reduced_shape('x', rank, 'dim')}$
        end function ${RName}$
      #:endfor
    #:endfor
  end interface moment


  interface pca
    !! version: experimental
    !!
    !! Principal Component Analysis (PCA)
    !! ([Specification](../page/specs/stdlib_stats.html#pca))
    #:for k1, t1, ri, cpp in REAL_KINDS_TYPES
      module subroutine pca_${k1}$(x, components, singular_values, x_mean, &
                                  method, overwrite_x, err)
        ${t1}$, intent(inout) :: x(:,:)
        ${t1}$, intent(out) :: components(:,:)
        ${t1}$, intent(out) :: singular_values(:)
        ${t1}$, intent(out), optional :: x_mean(:)
        character(*), intent(in), optional :: method
        logical, intent(in), optional :: overwrite_x
        type(linalg_state_type), intent(out), optional :: err
      end subroutine pca_${k1}$
    #:endfor
  end interface pca


  interface pca_transform
    !! version: experimental
    !!
    !! Projects data into the reduced dimensional space
    !! ([Specification](../page/specs/stdlib_stats.html#pca_transform))
    #:for k1, t1, ri, cpp in REAL_KINDS_TYPES
      module subroutine pca_transform_${k1}$(x, components, x_transformed, x_mean)
        ${t1}$, intent(in) :: x(:,:)
        ${t1}$, intent(in) :: components(:,:)
        ${t1}$, intent(out) :: x_transformed(:,:)
        ${t1}$, intent(in), optional :: x_mean(:)
      end subroutine pca_transform_${k1}$
    #:endfor
  end interface pca_transform


  interface pca_inverse_transform
    !! version: experimental
    !!
    !! Reconstructs original data from the reduced space
    !! ([Specification](../page/specs/stdlib_stats.html#pca_inverse_transform))
    #:for k1, t1, ri, cpp in REAL_KINDS_TYPES
      module subroutine pca_inverse_transform_${k1}$(x_reduced, components, x_reconstructed, x_mean)
        ${t1}$, intent(in) :: x_reduced(:,:)
        ${t1}$, intent(in) :: components(:,:)
        ${t1}$, intent(out) :: x_reconstructed(:,:)
        ${t1}$, intent(in), optional :: x_mean(:)
      end subroutine pca_inverse_transform_${k1}$
    #:endfor
  end interface pca_inverse_transform


end module stdlib_stats