Source code for openfisca_core.commons.rates

from typing import Optional

import numpy

from openfisca_core.types import ArrayLike, Array


[docs]def average_rate( target: Array[float], varying: ArrayLike[float], trim: Optional[ArrayLike[float]] = None, ) -> Array[float]: """Computes 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: :obj:`numpy.ndarray` of :obj:`float`: 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, .25] >>> average_rate(target, varying, trim) array([ nan, 0. , -0.5]) """ average_rate: Array[float] 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: Array[float], varying: Array[float], trim: Optional[ArrayLike[float]] = None, ) -> Array[float]: """Computes 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: :obj:`numpy.ndarray` of :obj:`float`: The marginal 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 = numpy.array([1, 2, 4]) >>> trim = [.25, .75] >>> marginal_rate(target, varying, trim) array([nan, 0.5]) """ marginal_rate: Array[float] 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