Source code for openfisca_core.commons.rates

from __future__ import annotations

import numpy

from . import types as t


[docs] def average_rate( target: t.Array[numpy.float32], varying: t.Array[numpy.float32] | t.ArrayLike[float], trim: None | t.ArrayLike[float] = None, ) -> t.Array[numpy.float32]: """Compute the average rate of a target net income. Given a ``target`` net income, and according to the ``varying`` gross income. Optionally, a ``trim`` can be applied consisting of the lower and upper bounds of the average rate to be computed. Note: Usually, ``target`` and ``varying`` are the same size. Args: target: The targeted net income. varying: The varying gross income. trim: The lower and upper bounds of the average rate. Returns: ndarray[float32]: The average rate for each target. When ``trim`` is provided, values that are out of the provided bounds are replaced by :obj:`numpy.nan`. Examples: >>> target = numpy.array([1, 2, 3]) >>> varying = [2, 2, 2] >>> trim = [-1, 0.25] >>> average_rate(target, varying, trim) array([ nan, 0. , -0.5]) """ if not isinstance(varying, numpy.ndarray): varying = numpy.array(varying, dtype=numpy.float32) average_rate = 1 - target / varying if trim is not None: average_rate = numpy.where( average_rate <= max(trim), average_rate, numpy.nan, ) average_rate = numpy.where( average_rate >= min(trim), average_rate, numpy.nan, ) return average_rate
[docs] def marginal_rate( target: t.Array[numpy.float32], varying: t.Array[numpy.float32] | t.ArrayLike[float], trim: None | t.ArrayLike[float] = None, ) -> t.Array[numpy.float32]: """Compute the marginal rate of a target net income. Given a ``target`` net income, and according to the ``varying`` gross income. Optionally, a ``trim`` can be applied consisting of the lower and upper bounds of the marginal rate to be computed. Note: Usually, ``target`` and ``varying`` are the same size. Args: target: The targeted net income. varying: The varying gross income. trim: The lower and upper bounds of the marginal rate. Returns: ndarray[float32]: The marginal rate for each target. When ``trim`` is provided, values that are out of the provided bounds are replaced by :class:`numpy.nan`. Examples: >>> target = numpy.array([1, 2, 3]) >>> varying = numpy.array([1, 2, 4]) >>> trim = [0.25, 0.75] >>> marginal_rate(target, varying, trim) array([nan, 0.5]) """ if not isinstance(varying, numpy.ndarray): varying = numpy.array(varying, dtype=numpy.float32) marginal_rate = +1 - (target[:-1] - target[1:]) / (varying[:-1] - varying[1:]) if trim is not None: marginal_rate = numpy.where( marginal_rate <= max(trim), marginal_rate, numpy.nan, ) marginal_rate = numpy.where( marginal_rate >= min(trim), marginal_rate, numpy.nan, ) return marginal_rate
__all__ = ["average_rate", "marginal_rate"]