def st_mod(x, y): """Modulo (modulus) function. Parameters ---------- x : float, int, MissingValue instance, or None y : float, int, MissingValue instance, or None Returns ------- x - y * int(x / y) if x and y are both non-missing and y > 0, MISSING (".") otherwise """ if isinstance(x, StataVarVals): if isinstance(y, StataVarVals): return StataVarVals([ mv if _is_missing(vx) or _is_missing(vy) or vy <= 0 else vx % vy for vx, vy in zip(x.values, y.values) ]) elif _is_missing(y) or y <= 0: return StataVarVals([mv for v in x.values]) else: return StataVarVals( [mv if _is_missing(v) else v % y for v in x.values]) if isinstance(y, StataVarVals): if _is_missing(x): return StataVarVals([mv for v in y.values]) else: return StataVarVals( [mv if _is_missing(v) or v <= 0 else x % v for v in y.values]) if _is_missing(x) or _is_missing(y) or y <= 0: return mv return x % y
def st_atan2(x, y): """Two-parameter inverse tangent function. This function considers the signs of both x and y when calculating angle. Parameters ---------- x : float, int, MissingValue instance, or None y : float, int, MissingValue instance, or None Returns ------- Inverse tangent of x/y (measured in radians) when x and y are both non-missing, MISSING (".") otherwise. """ if isinstance(x, StataVarVals): if isinstance(y, StataVarVals): return StataVarVals( [_atan2(vx, vy) for vx, vy in zip(x.values, y.values)]) elif _is_missing(y): return StataVarVals([mv for v in x.values]) else: return StataVarVals([_atan2(v, y) for v in x.values]) if isinstance(y, StataVarVals): if _is_missing(x): return StataVarVals([mv for v in y.values]) else: return StataVarVals([_atan2(x, v) for v in y.values]) return _atan2(x, y)
def st_reldif(x, y): """Relative difference function. Parameters ---------- x : float, int, MissingValue instance, or None y : float, int, MissingValue instance, or None Returns ------- If x and y are both non-missing, returns |x - y| / (|y| + 1). If x and y are both missing and correspond to the same MissingValue instance, returns 0. Otherwise, returns MISSING ("."). """ if isinstance(x, StataVarVals): if isinstance(y, StataVarVals): return StataVarVals( [_reldif(vx, vy) for vx, vy in zip(x.values, y.values)]) else: return StataVarVals([_reldif(v, y) for v in x.values]) if isinstance(y, StataVarVals): return StataVarVals([_reldif(x, v) for v in y.values]) return _reldif(x, y)
def st_comb(n, k): """Combinatorial function. Parameters ---------- n : float, int, MissingValue instance, or None k : float, int, MissingValue instance, or None Returns ------- n! / (k! (n-k)!) if n and k are non-missing and n < 1e+305, MISSING (".") otherwise """ if isinstance(n, StataVarVals): if isinstance(k, StataVarVals): return StataVarVals( [_comb(vn, vk) for vn, vk in zip(n.values, k.values)]) elif _is_missing(k): return StataVarVals([mv for v in n.values]) else: return StataVarVals([_comb(v, k) for v in n.values]) if isinstance(k, StataVarVals): if _is_missing(n): return StataVarVals([mv for v in k.values]) else: return StataVarVals([_comb(n, v) for v in k.values]) return _comb(n, k)
def st_invcloglog(x): """Inverse of the complementary log log function. Parameters ---------- x : float, int, MissingValue instance, or None Returns ------- 1 - exp(-exp(x)) if x is non-missing, MISSING (".") otherwise """ # This differs from Stata's invcloglog for x > 709 (Stata 13.1 on Win7), # where invcloglog(x) = . for x > 709. exp = math.exp if isinstance(x, StataVarVals): return StataVarVals([ mv if _is_missing(v) else 1.0 if v > 5 else 0.0 if v < -40 else 1.0 - exp(-exp(v)) for v in x.values ]) if _is_missing(x): return mv if x > 5: return 1.0 if x < -40: return 0.0 return 1.0 - exp(-exp(x))
def st_min(*args): """Min function. Parameters ---------- x : float, int, MissingValue instance, or None (2 or more such inputs allowed) Returns ------- min(x1, x2, ...) if any x is non-missing (with missing values ignored). Otherwise, MISSING (".") returned. """ if len(args) <= 1: raise TypeError("need at least 2 arguments") vectors = [a.values for a in args if isinstance(a, StataVarVals)] scalars = [ a for a in args if not isinstance(a, StataVarVals) and not _is_missing(a) ] if len(vectors) != 0: sca_min = min(scalars) if not len(scalars) == 0 else None return StataVarVals([_min(*v, sub_min=sca_min) for v in zip(*vectors)]) elif len(scalars) == 0: return mv return min(scalars)
def st_tanh(x): if isinstance(x, StataVarVals): return StataVarVals( [mv if _is_missing(v) else math.tanh(v) for v in x.values]) if _is_missing(x): return mv return math.tanh(x)
def st_exp(x): """Exponential function. Parameters ---------- x : float, int, MissingValue instance, or None Returns ------- Exponential of x (exp(x)) if x is non-missing and x <= 709, MISSING (".") otherwise. Note ---- The exponential of x can fall in Stata's missing range for non-missing x. For x greater than approximately 709 this function will return MISSING ("."). """ if isinstance(x, StataVarVals): return StataVarVals([ mv if _is_missing(v) or v > 709.09 else min(mv, math.exp(v)) for v in x.values ]) if _is_missing(x) or x > 709.09: return mv return min(mv, math.exp(x))
def st_round(x, y=1): """Rounding function. Parameters ---------- x : float, int, MissingValue instance, or None y : float, int, MissingValue instance, or None; y is optional, default value is 1 Returns ------- If both x and y are non-missing, returns x / y rounded to the nearest integer times y (but see notes below). If y is 1 or y is not specified, returns x rounded to the nearest integer (but see notes below). If y is zero, returns x. If y is missing, MISSING (".") is returned. If x is missing and y is non-missing, returns MissingValue corresponding to x. If both x and y are missing, returns MISSING ("."). Notes ----- Though Python 3 uses "banker's rounding" or "round half to even", this function uses "round half up". For example, with Python 3's `round` function, `round(3.5)` and `round(4.5)` are both 4, but `st_round(3.5)` is 4 and `st_round(4.5)` is 5. Keep in mind that floating point imprecision of inputs may affect the output. """ if isinstance(x, StataVarVals): if isinstance(y, StataVarVals): return StataVarVals( [_round(vx, vy) for vx, vy in zip(x.values, y.values)]) if y == 0: return StataVarVals([ get_missing(v) if _is_missing(v) and not isinstance(v, MissingValue) else v for v in x.values ]) else: return StataVarVals([_round(v, y) for v in x.values]) if isinstance(y, StataVarVals): return StataVarVals([_round(x, v) for v in y.values]) return _round(x, y)
def st_digamma(x): """Digamma (psi) function, the derivative of `st_lngamma`. Parameters ---------- x : float, int, MissingValue instance, or None Returns ------- Digamma of x if x is non-missing, not zero, and not a negative integer, MISSING (".") otherwise """ if isinstance(x, StataVarVals): return StataVarVals([_digamma(v) for v in x.values]) return _digamma(x)
def st_invlogit(x): """Inverse logit function. Parameters ---------- x : float, int, MissingValue instance, or None Returns ------- exp(x) / (1 + exp(x)) if x is non-missing, MISSING (".") otherwise """ if isinstance(x, StataVarVals): return StataVarVals([_invlogit(v) for v in x.values]) return _invlogit(x)
def st_logit(x): """Logit function. Parameters ---------- x : float, int, MissingValue instance, or None Returns ------- log(x / (1 - x)) if 0 < x < 1, MISSING (".") otherwise """ if isinstance(x, StataVarVals): return StataVarVals([_logit(v) for v in x.values]) return _logit(x)
def st_cloglog(x): """Complementary log log function. Parameters ---------- x : float, int, MissingValue instance, or None Returns ------- log(-log(1 - x)) if x is non-missing, MISSING (".") otherwise """ if isinstance(x, StataVarVals): return StataVarVals([_cloglog(v) for v in x.values]) return _cloglog(x)
def st_atan(x): """Inverse tangent function. Parameters ---------- x : float, int, MissingValue instance, or None Returns ------- Inverse tangent (measured in radians) when x is non-missing, MISSING (".") otherwise """ if isinstance(x, StataVarVals): return StataVarVals( [mv if _is_missing(v) else math.atan(v) for v in x.values]) if _is_missing(x): return mv return math.atan(x)
def st_abs(x): """Absolute value function. Parameters ---------- x : float, int, MissingValue instance, or None Returns ------- Absolute value of x when x is non-missing, MISSING (".") otherwise """ if isinstance(x, StataVarVals): return StataVarVals( [mv if _is_missing(v) else abs(v) for v in x.values]) if _is_missing(x): return mv return abs(x)
def st_floor(x): """Floor function. Parameters ---------- x : float, int, MissingValue instance, or None Returns ------- If x is non-missing, returns the largest int value <= x. If x is a float or int in Stata's missing value range, returns the corresponding MissingValue instance. If x is a MissingValue instance, returns x. If x is None, returns MISSING ("."). """ if isinstance(x, StataVarVals): return StataVarVals([_floor(v) for v in x.values]) return _floor(x)
def st_asinh(x): """Inverse hyperbolic sine function. Parameters ---------- x : float, int, MissingValue instance, or None Returns ------- Inverse hyperbolic sine when x is non-missing, MISSING (".") otherwise """ if isinstance(x, StataVarVals): return StataVarVals( [mv if _is_missing(v) else math.asinh(v) for v in x.values]) if _is_missing(x): return mv return math.asinh(x)
def st_int(x): """Integer truncation function. Parameters ---------- x : float, int, MissingValue instance, or None Returns ------- If x is non-missing, returns the int value between x and zero closest to x (equal to x if x is integer-valued). If x is a float or int in Stata's missing value range, returns the corresponding MissingValue instance. If x is a MissingValue instance, returns x. If x is None, returns MISSING ("."). """ if isinstance(x, StataVarVals): return StataVarVals([_int(v) for v in x.values]) return _int(x)
def st_sqrt(x): """Square root function. Parameters ---------- x : float, int, MissingValue instance, or None Returns ------- square root of x if x is non-missing and >= 0, MISSING (".") otherwise """ if isinstance(x, StataVarVals): return StataVarVals([ mv if _is_missing(v) or v < 0 else math.sqrt(v) for v in x.values ]) if _is_missing(x) or x < 0: return mv return math.sqrt(x)
def st_ln(x): """Natural log function. Parameters ---------- x : float, int, MissingValue instance, or None Returns ------- Natural log of x if x is non-missing, MISSING (".") otherwise """ if isinstance(x, StataVarVals): return StataVarVals([ mv if _is_missing(v) or v <= 0 else math.log(v) for v in x.values ]) if _is_missing(x) or x <= 0: return mv return math.log(x)
def st_asin(x): """Inverse sine function. Parameters ---------- x : float, int, MissingValue instance, or None Returns ------- Inverse sine (measured in radians) when -1 <= x <= 1, MISSING (".") otherwise """ if isinstance(x, StataVarVals): return StataVarVals([ mv if _is_missing(v) or not -1 <= v <= 1 else math.asin(v) for v in x.values ]) if _is_missing(x) or not -1 <= x <= 1: return mv return math.asin(x)
def st_sign(x): """Sign function. Parameters ---------- x : float, int, MissingValue instance, or None Returns ------- the sign of x (-1 if < 0; 0 if == 0; 1 if > 0) if x is non-missing, MISSING (".") otherwise """ if isinstance(x, StataVarVals): return StataVarVals([ mv if _is_missing(v) else 0 if v == 0 else -1 if v < 0 else 1 for v in x.values ]) if _is_missing(x): return mv return 0 if x == 0 else -1 if x < 0 else 1
def st_cosh(x): """Hyperbolic cosine function. Parameters ---------- x : float, int, MissingValue instance, or None Returns ------- Hyperbolic cosine of x if x is non-missing (see note below), MISSING (".") otherwise Note ---- The hyperbolic cosine of x can fall in Stata's missing range for non-missing x. For x outside of -709 < x < 709 (approximate) this function will return MISSING ("."). """ if isinstance(x, StataVarVals): return StataVarVals([_cosh(v) for v in x.values]) return _cosh(x)
def st_tan(x): """Tangent function. Parameters ---------- x : float, int, MissingValue instance, or None; angle in radians Returns ------- tangent of x if x is non-missing and -1e+18 <= x <= 1e+18, MISSING (".") otherwise """ if isinstance(x, StataVarVals): return StataVarVals([ mv if _is_missing(v) or not -1e+18 <= v <= 1e+18 else math.tan(v) for v in x.values ]) if _is_missing(x) or not -1e+18 <= x <= 1e+18: return mv return math.tan(x) # assuming tan does not get above ~ 1e17
def st_cos(x): """Cosine function. Parameters ---------- x : float, int, MissingValue instance, or None; angle in radians Returns ------- Cosine of x if -1e+18 <= x <= 1e+18, MISSING (".") otherwise """ if isinstance(x, StataVarVals): return StataVarVals([ mv if _is_missing(v) or not -1e+18 <= v <= 1e+18 else math.cos(v) for v in x.values ]) if _is_missing(x) or not -1e+18 <= x <= 1e+18: return mv return math.cos(x)
def st_lnfactorial(n): """Log of factorial function. Parameters ---------- x : float, int, MissingValue instance, or None Returns ------- log(x!) if x is integer-valued and x >= 0, MISSING (".") otherwise Note ---- The log factorial of x can fall in Stata's missing range for non-missing x. This occurs for inputs > 1.28e+305 (approximate). In these cases, MISSING (".") will be returned. """ if isinstance(n, StataVarVals): return StataVarVals([_lnfactorial(v) for v in n.values]) return _lnfactorial(n)
def st_lngamma(x): """Log gamma function. Parameters ---------- x : float, int, MissingValue instance, or None Returns ------- The log of the gamma function of x if x is non-missing, x > -2,147,483,648, and x is not a negative integer. Otherwise, MISSING (".") is returned. Note ---- The log of gamma of x can fall in Stata's missing range for non-missing x. This occurs for inputs > 1.28e+305 (approximate). In these cases, MISSING (".") will be returned. """ if isinstance(x, StataVarVals): return StataVarVals([_lngamma(v) for v in x.values]) return _lngamma(x)