Skip to content

Utilities

{{ task_disclaimer }}

utils

Classes

Context

Context(**kwargs)

Acts like a dictionary but allows for object-like attribute access while maintaining a history of key provenance for debugging and traceability.

Source code in calibrie/utils.py
def __init__(self, **kwargs):
    super().__setattr__('origin', KeyProvenance.from_stack(inspect.stack(), '').origin_str)
    super().__setattr__('key_history', {})
    super().__setattr__('container', dict(**kwargs))

Functions

color_from_filename

color_from_filename(filename: str) -> tuple[int, int, int, int]

Generate deterministic RGBA color from filename hash.

Source code in calibrie/utils.py
def color_from_filename(filename: str) -> tuple[int, int, int, int]:
    """Generate deterministic RGBA color from filename hash."""
    import colorsys
    import hashlib

    h = hashlib.md5(filename.encode()).hexdigest()
    hue = int(h[:4], 16) % 360
    sat = 0.6 + (int(h[4:6], 16) % 40) / 100
    val = 0.7 + (int(h[6:8], 16) % 30) / 100
    r, g, b = colorsys.hsv_to_rgb(hue / 360, sat, val)
    return (int(r * 255), int(g * 255), int(b * 255), 200)

logb

logb(x, base=10, **kwargs)

Compute log of x in base b.

Source code in calibrie/utils.py
def logb(x, base=10, **kwargs):
    """Compute log of x in base b."""
    return np.log(x, **kwargs) / np.log(base)

cubic_exp_fwd

cubic_exp_fwd(x, threshold, base, scale: float = 1)

cubic polynomial that goes through (0,0) and has same first and second derivative as the log (in given base) at the threshold. In other words, a spline that is log-like near the threshold.

Args: - x: input - threshold: the value at which the function should be log-like - base: the base of the logarithm - scale: a parameter to squeeze (<1) or stretch (>1) the function

Source code in calibrie/utils.py
def cubic_exp_fwd(x, threshold, base, scale: float = 1):
    """
    cubic polynomial that goes through (0,0) and has same first
    and second derivative as the log (in given base) at the threshold.
    In other words, a spline that is log-like near the threshold.

    Args:
    - x: input
    - threshold: the value at which the function should be log-like
    - base: the base of the logarithm
    - scale: a parameter to squeeze (<1) or stretch (>1) the function
    """
    logthresh = np.log(threshold)
    logbase = np.log(base)
    a = -0.5 * (3 - 2 * scale * logthresh) / (threshold**3 * logbase)
    b = -(-4 + 3 * scale * logthresh) / (threshold**2 * logbase)
    c = -0.5 * (5 - 6 * scale * logthresh) / (threshold * logbase)
    return a * x**3 + b * x**2 + c * x

cubic_exp_inv

cubic_exp_inv(y, threshold, base, scale: float)

inverse of cubic_exp_fwd (on [0,threshold])

Source code in calibrie/utils.py
def cubic_exp_inv(y, threshold, base, scale: float):
    """
    inverse of cubic_exp_fwd (on [0,threshold])
    """
    # used wolfram to solve for the analytical inverse
    lT, lB, cb2 = np.log(threshold), np.log(base), np.cbrt(2)
    T, T2, T3 = threshold, threshold**2, threshold**3
    A = T3 * (
        56
        + y * lB * (486 - 648 * scale * lT + 216 * scale**2 * lT**2)
        - 522 * scale * lT
        + 648 * scale**2 * lT**2
        - 216 * scale**3 * lT**3
    )
    B = np.sqrt(4 * (-19 * T2 + 12 * scale * T2 * lT) ** 3 + A**2)
    C = np.cbrt(A + B)
    D = -9 + 6 * scale * lT
    E = 2 * T * (-4 + 3 * scale * lT) / D
    F = cb2 * (-19 * T2 + 12 * scale * T2 * lT)
    return E - (F / (D * C)) + (C / (cb2 * D))

spline_biexponential

spline_biexponential(x, threshold: float = 100, base: int = 10, compression: float = 0.5)

bi-logarithm function with smooth transition to cubic polynomial between [-threshold, threshold]

Args: - x: input - threshold: when the function should transition between log and spline - base: the base of the logarithm - compression: a parameter to squeeze (<1) or stretch (>1) the function in the spline region

Source code in calibrie/utils.py
def spline_biexponential(x, threshold: float = 100, base: int = 10, compression: float = 0.5):
    """
    bi-logarithm function with smooth transition to cubic polynomial between [-threshold, threshold]

    Args:
    - x: input
    - threshold: when the function should transition between log and spline
    - base: the base of the logarithm
    - compression: a parameter to squeeze (<1) or stretch (>1) the function in the spline region
    """
    x = np.asarray(x)
    sign = np.sign(x)
    x = np.abs(x)
    diff = logb(threshold, base) * (1.0 - compression)
    x = np.where(
        x > threshold,
        logb(x, base, where=x > 0) - diff,
        cubic_exp_fwd(x, threshold, base=base, scale=compression),
    )
    return x * sign

inverse_spline_biexponential

inverse_spline_biexponential(y, threshold: float = 100, base: int = 10, compression: float = 0.5)

inverse of log_poly_log

Source code in calibrie/utils.py
def inverse_spline_biexponential(
    y, threshold: float = 100, base: int = 10, compression: float = 0.5
):
    """
    inverse of log_poly_log
    """
    y = np.asarray(y)
    sign = np.sign(y)
    y = np.abs(y)
    diff = logb(threshold, base) * (1.0 - compression)
    transformed_threshold = cubic_exp_fwd(threshold, threshold, base=base, scale=compression)
    y = np.where(
        y > transformed_threshold,
        base ** (y + diff),
        cubic_exp_inv(y, threshold, base=base, scale=compression),
    )
    return y * sign

logb_jax

logb_jax(x, base=10, **kwargs)

Compute log of x in base b.

Source code in calibrie/utils.py
def logb_jax(x, base=10, **kwargs):
    """Compute log of x in base b."""
    return jnp.log(x, **kwargs) / jnp.log(base)

cubic_exp_fwd_jax

cubic_exp_fwd_jax(x, threshold, base, scale=1)

cubic polynomial that goes through (0,0) and has same first and second derivative as the log function at the threshold it appears monotonically increasing for x in [0, threshold] although I haven't technically proven it

Source code in calibrie/utils.py
def cubic_exp_fwd_jax(x, threshold, base, scale=1):
    """
    cubic polynomial that goes through (0,0) and has same first
    and second derivative as the log function at the threshold
    it appears monotonically increasing for x in [0, threshold]
    although I haven't technically proven it
    """
    # assert base > 1 and scale > 0, 'Base must be > 1 and scale > 0'
    # assert (
    # 6 * logb(threshold, base) * scale > 5
    # ), 'Threshold too small for given scale (or vice versa)'

    logthresh = jnp.log(threshold)
    logbase = jnp.log(base)
    a = -0.5 * (3 - 2 * scale * logthresh) / (threshold**3 * logbase)
    b = -(-4 + 3 * scale * logthresh) / (threshold**2 * logbase)
    c = -0.5 * (5 - 6 * scale * logthresh) / (threshold * logbase)
    return a * x**3 + b * x**2 + c * x

cubic_exp_inv_jax

cubic_exp_inv_jax(y, threshold, base, scale)

inverse of cubic_exp_fwd (on [0,T])

Source code in calibrie/utils.py
def cubic_exp_inv_jax(y, threshold, base, scale):
    """
    inverse of cubic_exp_fwd (on [0,T])
    """
    # used wolfram to solve the analytical inverse
    lT, lB, cb2 = jnp.log(threshold), jnp.log(base), jnp.cbrt(2)
    T, T2, T3 = threshold, threshold**2, threshold**3
    A = T3 * (
        56
        + y * lB * (486 - 648 * scale * lT + 216 * scale**2 * lT**2)
        - 522 * scale * lT
        + 648 * scale**2 * lT**2
        - 216 * scale**3 * lT**3
    )
    B = jnp.sqrt(4 * (-19 * T2 + 12 * scale * T2 * lT) ** 3 + A**2)
    C = jnp.cbrt(A + B)
    D = -9 + 6 * scale * lT
    E = 2 * T * (-4 + 3 * scale * lT) / D
    F = cb2 * (-19 * T2 + 12 * scale * T2 * lT)
    return E - (F / (D * C)) + (C / (cb2 * D))

spline_biexponential_jax

spline_biexponential_jax(x, threshold=100, base=10, compression=1)

biexponential function with smooth transition to cubic polynomial between [-threshold, threshold]

Source code in calibrie/utils.py
@jit
def spline_biexponential_jax(x, threshold=100, base=10, compression=1):
    """
    biexponential function with smooth transition to cubic polynomial between [-threshold, threshold]
    """
    x = jnp.asarray(x)
    sign = jnp.sign(x)
    x = jnp.abs(x)
    diff = logb_jax(threshold, base) * (1.0 - compression)
    x = jnp.where(
        x > threshold,
        logb_jax(x, base) - diff,
        cubic_exp_fwd_jax(x, threshold, base=base, scale=compression),
    )
    return x * sign

inverse_spline_biexponential_jax

inverse_spline_biexponential_jax(y, threshold=100, base=10, compression=1)

inverse of spline_biexponential

Source code in calibrie/utils.py
@jit
def inverse_spline_biexponential_jax(y, threshold=100, base=10, compression=1):
    """
    inverse of spline_biexponential
    """
    y = jnp.asarray(y)
    sign = jnp.sign(y)
    y = jnp.abs(y)
    diff = logb_jax(threshold, base) * (1.0 - compression)
    transformed_threshold = cubic_exp_fwd_jax(threshold, threshold, base=base, scale=compression)
    y = jnp.where(
        y > transformed_threshold,
        base ** (y + diff),
        cubic_exp_inv_jax(y, threshold, base=base, scale=compression),
    )
    return y * sign

regression

regression(x, y, w, xbounds, resolution, degree, logspace=True, endpoint=True)

returns the stacked_poly params to best express y as a function of x

Source code in calibrie/utils.py
@partial(jax.jit, static_argnames=("resolution", "degree", "logspace", "endpoint"))
def regression(x, y, w, xbounds, resolution, degree, logspace=True, endpoint=True):
    """returns the stacked_poly params to best express y as a function of x"""
    if logspace:
        x, y = logtransform_jax(x), logtransform_jax(y)
        xbounds = logtransform_jax(xbounds)
    # params = fit_stacked_poly_uniform_spacing(x, y, w, *xbounds, resolution, degree, endpoint)
    quantiles = jnp.linspace(0.01, 0.99, resolution, endpoint=endpoint)
    params = fit_stacked_poly_at_quantiles(x, y, w, quantiles, degree)
    return params