code: def f_mway_rm(
      data,
      factor_levels,
      effects="all",
      correction=False,
      return_pvals=True,
  ):
      """Compute M-way repeated measures ANOVA for fully balanced designs.
  
      Parameters
      ----------
      data : ndarray
          3D array where the first two dimensions are compliant
          with a subjects X conditions scheme where the first
          factor repeats slowest::
  
                          A1B1 A1B2 A2B1 A2B2
              subject 1   1.34 2.53 0.97 1.74
              subject ... .... .... .... ....
              subject k   2.45 7.90 3.09 4.76
  
          The last dimensions is thought to carry the observations
          for mass univariate analysis.
      factor_levels : list-like
          The number of levels per factor.
      effects : str | list
          A string denoting the effect to be returned. The following
          mapping is currently supported (example with 2 factors):
  
              * ``'A'``: main effect of A
              * ``'B'``: main effect of B
              * ``'A:B'``: interaction effect
              * ``'A+B'``: both main effects
              * ``'A*B'``: all three effects
              * ``'all'``: all effects (equals 'A*B' in a 2 way design)
  
          If list, effect names are used: ``['A', 'B', 'A:B']``.
      correction : bool
          The correction method to be employed if one factor has more than two
          levels. If True, sphericity correction using the Greenhouse-Geisser
          method will be applied.
      return_pvals : bool
          If True, return p-values corresponding to F-values.
  
      Returns
      -------
      F_vals : ndarray
          An array of F-statistics with length corresponding to the number
          of effects estimated. The shape depends on the number of effects
          estimated.
      p_vals : ndarray
          If not requested via return_pvals, defaults to an empty array.
  
      See Also
      --------
      f_oneway
      f_threshold_mway_rm
  
      Notes
      -----
      .. versionadded:: 0.10
      """
      out_reshape = (-1,)
      if (
          data.ndim == 2
      ):  # general purpose support, e.g. behavioural data
          data = data[:, :, np.newaxis]
      elif data.ndim > 3:  # let's allow for some magic here
          out_reshape = data.shape[2:]
          data = data.reshape(
              data.shape[0], data.shape[1], np.prod(data.shape[2:])
          )
  
      effect_picks, _ = _map_effects(len(factor_levels), effects)
      n_obs = data.shape[2]
      n_replications = data.shape[0]
  
      # put last axis in front to 'iterate' over mass univariate instances.
      data = np.rollaxis(data, 2)
      fvalues, pvalues = [], []
      for c_, df1, df2 in _iter_contrasts(
          n_replications, factor_levels, effect_picks
      ):
          y = np.dot(data, c_)
          b = np.mean(y, axis=1)[:, np.newaxis, :]
          ss = np.sum(np.sum(y * b, axis=2), axis=1)
          mse = (np.sum(np.sum(y * y, axis=2), axis=1) - ss) / (
              df2 / df1
          )
          fvals = ss / mse
          fvalues.append(fvals)
          if correction:
              # sample covariances, leave off "/ (y.shape[1] - 1)" norm because
              # it falls out.
              v = np.array([np.dot(y_.T, y_) for y_ in y])
              v = np.array([np.trace(vv) for vv in v]) ** 2 / (
                  df1 * np.sum(np.sum(v * v, axis=2), axis=1)
              )
              eps = v
  
          df1, df2 = np.zeros(n_obs) + df1, np.zeros(n_obs) + df2
          if correction:
              # numerical imprecision can cause eps=0.99999999999999989
              # even with a single category, so never let our degrees of
              # freedom drop below 1.
              df1, df2 = (
                  np.maximum(d[None, :] * eps, 1.0) for d in (df1, df2)
              )
  
          if return_pvals:
              pvals = stats.f(df1, df2).sf(fvals)
          else:
              pvals = np.empty(0)
          pvalues.append(pvals)
  
      # handle single effect returns
      return [
          np.squeeze(np.asarray([v.reshape(out_reshape) for v in vv]))
          for vv in (fvalues, pvalues)
      ]
  
file_path: mne-python/mne/stats/parametric.py
imports: from functools import reduce
  from string import ascii_uppercase
  import numpy
  from scipy import stats
  from scipy.signal import detrend
  from ..utils import _check_option
label_desc: Use image node_id 8 for calling a global function with example usage: f_mway_rm(data, factor_levels, effects, correction, return_pvals) and returns: unknown