code: def power_ttest2n(
      nx, ny, d=None, power=None, alpha=0.05, alternative="two-sided"
  ):
      """
      Evaluate power, effect size or  significance level of an independent two-samples T-test
      with unequal sample sizes.
  
      Parameters
      ----------
      nx, ny : int
          Sample sizes. Must be specified. If the sample sizes are equal, you should use the
          :py:func:`power_ttest` function instead.
      d : float
          Cohen d effect size
      power : float
          Test power (= 1 - type II error).
      alpha : float
          Significance level (type I error probability). The default is 0.05.
      alternative : string
          Defines the alternative hypothesis, or tail of the test. Must be one of "two-sided"
          (default), "greater" or "less".
  
      Notes
      -----
      Exactly ONE of the parameters ``d``, ``power`` and ``alpha`` must be passed as None, and that
      parameter is determined from the others.
  
      ``alpha`` has a default value of 0.05 so None must be explicitly passed if you want to compute
      it.
  
      This function is a Python adaptation of the `pwr.t2n.test` function implemented in the
      `pwr <https://cran.r-project.org/web/packages/pwr/pwr.pdf>`_ R package.
  
      Statistical power is the likelihood that a study will detect an effect when there is an effect
      there to be detected. A high statistical power means that there is a low probability of
      concluding that there is no effect when there is one. Statistical power is mainly affected by
      the effect size and the sample size.
  
      The first step is to use the Cohen's d to calculate the non-centrality parameter
      :math:`\\delta` and degrees of freedom :math:`v`.cIn case of two independent groups with
      unequal sample sizes, this is:
  
      .. math:: \\delta = d * \\sqrt{\\frac{n_i * n_j}{n_i + n_j}}
      .. math:: v = n_i + n_j - 2
  
      where :math:`d` is the Cohen d, :math:`n` the sample size,
      :math:`n_i` the sample size of the first group and
      :math:`n_j` the sample size of the second group,
  
      The critical value is then found using the percent point function of the T distribution with
      :math:`q = 1 - alpha` and :math:`v` degrees of freedom.
  
      Finally, the power of the test is given by the survival function of the non-central
      distribution using the previously calculated critical value, degrees of freedom and
      non-centrality parameter.
  
      :py:func:`scipy.optimize.brenth` is used to solve power equations for other variables (i.e.
      sample size, effect size, or significance level). If the solving fails, a nan value is
      returned.
  
      Results have been tested against GPower and the
      `pwr <https://cran.r-project.org/web/packages/pwr/pwr.pdf>`_ R package.
  
      Examples
      --------
      1. Compute achieved power of a T-test given ``d``, ``n`` and ``alpha``
  
      >>> from pingouin import power_ttest2n
      >>> print('power: %.4f' % power_ttest2n(nx=20, ny=15, d=0.5, alternative='greater'))
      power: 0.4164
  
      2. Compute achieved ``d`` given ``n``, ``power`` and ``alpha`` level
  
      >>> print('d: %.4f' % power_ttest2n(nx=20, ny=15, power=0.80, alpha=0.05))
      d: 0.9859
  
      3. Compute achieved alpha level given ``d``, ``n`` and ``power``
  
      >>> print('alpha: %.4f' % power_ttest2n(nx=20, ny=15, d=0.5, power=0.80, alpha=None))
      alpha: 0.5000
      """
      # Check the number of arguments that are None
      n_none = sum([v is None for v in [d, power, alpha]])
      if n_none != 1:
          raise ValueError(
              "Exactly one of d, power, and alpha must be None"
          )
  
      # Safety checks
      assert alternative in [
          "two-sided",
          "greater",
          "less",
      ], "Alternative must be one of 'two-sided' (default), 'greater' or 'less'."
      tside = 2 if alternative == "two-sided" else 1
      if d is not None and tside == 2:
          d = abs(d)
      if alpha is not None:
          assert 0 < alpha <= 1
      if power is not None:
          assert 0 < power <= 1
  
      if alternative == "less":
  
          def func(d, nx, ny, power, alpha):
              dof = nx + ny - 2
              nc = d * (1 / np.sqrt(1 / nx + 1 / ny))
              tcrit = stats.t.ppf(alpha / tside, dof)
              return stats.nct.cdf(tcrit, dof, nc)
  
      elif alternative == "two-sided":
  
          def func(d, nx, ny, power, alpha):
              dof = nx + ny - 2
              nc = d * (1 / np.sqrt(1 / nx + 1 / ny))
              tcrit = stats.t.ppf(1 - alpha / tside, dof)
              return stats.nct.sf(tcrit, dof, nc) + stats.nct.cdf(
                  -tcrit, dof, nc
              )
  
      else:  # Alternative = 'greater'
  
          def func(d, nx, ny, power, alpha):
              dof = nx + ny - 2
              nc = d * (1 / np.sqrt(1 / nx + 1 / ny))
              tcrit = stats.t.ppf(1 - alpha / tside, dof)
              return stats.nct.sf(tcrit, dof, nc)
  
      # Evaluate missing variable
      if power is None:
          # Compute achieved power given d, n and alpha
          return func(d, nx, ny, power=None, alpha=alpha)
  
      elif d is None:
          # Compute achieved d given sample size, power and alpha level
          if alternative == "two-sided":
              b0, b1 = 1e-07, 10
          elif alternative == "less":
              b0, b1 = -10, 5
          else:
              b0, b1 = -5, 10
  
          def _eval_d(d, nx, ny, power, alpha):
              return func(d, nx, ny, power, alpha) - power
  
          try:
              return brenth(
                  _eval_d, b0, b1, args=(nx, ny, power, alpha)
              )
          except ValueError:  # pragma: no cover
              return np.nan
  
      else:
          # Compute achieved alpha (significance) level given d, n and power
  
          def _eval_alpha(alpha, d, nx, ny, power):
              return func(d, nx, ny, power, alpha) - power
  
          try:
              return brenth(
                  _eval_alpha, 1e-10, 1 - 1e-10, args=(d, nx, ny, power)
              )
          except ValueError:  # pragma: no cover
              return np.nan
  
file_path: pingouin/pingouin/power.py
imports: import warnings
  import numpy
  from scipy import stats
  from scipy.optimize import brenth
label_desc: Use image node_id 2 for calling a global function with example usage: power_ttest2n(nx, ny, d, power, alpha, alternative) and returns: func, stats, unknown, stats, unknown, brenth, unknown, brenth, np, np