# Bunching Estimation¶

## API¶

### Fuzzing Bunching¶

function
frds.algorithms.bunching.fuzzy_bunching(X, X0, x_l, x_min, x_max, degree, friction=True, noise=True, fig=False)

Fuzzy bunching

See e.g., Kleven and Waseem (2013) for bunching estimation, and Alvero and Xiao (2020) for fuzzy bunching.

Note

This code is adapted from Xiao's Matlab code, available at his website.

Parameters
• X (np.ndarray) bunching sample
• X0 (Union[np.ndarray, None]) non-bunching sample if exists, skip otherwise by setting it to None.
• x_l (float) threshold
• x_min (float) excluded range lower bound
• x_max (float) excluded range upper bound
• degree (int) degree of polynomial for conterfactual density
• friction (bool, optional) whether to allow optimization friction. Defaults to True.
• noise (bool, optional) whether to allow noise in the data. Defaults to True.
• fig (bool, optional) whether to create a figure of CDF. Defaults to False.
Returns (Tuple[float, float])

(dx_hat, alpha_hat), where dx_hat is bunching range, $\Delta q$, and alpha_hat is non-optimizing share, $\alpha$.

Examples
>>> from frds.algorithms.bunching import fuzzy_bunching
>>> import numpy as np


Generate a sample.

>>> N = 1000
>>> x_l = 0.5
>>> dx = 0.1
>>> alpha = 0
>>> rng = np.random.RandomState(0)
>>> Z0 = rng.rand(N)
>>> Z = Z0.copy()
>>> Z[(Z0 > x_l) & (Z0 <= x_l + dx)] = x_l
>>> Z[: round(alpha * N)] = Z0[: round(alpha * N)]
>>> u = 0.0
>>> U = u * np.random.randn(N)
>>> X = np.add(Z, U)
>>> X0 = np.add(Z0, U)
>>> x_max = x_l + 1.1 * dx
>>> x_min = x_l * 0.99


Fuzzy bunching estimation

>>> fuzzy_bunching(X, X0, x_l, x_min, x_max, degree=5, friction=True, noise=True, fig=False)
(0.032179950901143374, 0.0)


References
• Alvero and Xiao (2020), Fuzzy bunching, SSRN.
• Kleven and Waseem (2013), Using notches to uncover optimization frictions and structural elasticities: Theory and evidence from pakistan, The Quarterly Journal of Ecnomics, 128(2), 669-723.
Todo
• Option to specify output plot path.
• Plot styling.

### Sharp Bunching¶

function
frds.algorithms.bunching.sharp_bunching(X, X0, x_l, x_min, x_max, degree, friction=True, noise=True, fig=False)

Sharp bunching

See e.g., Kleven and Waseem (2013) for bunching estimation, and Alvero and Xiao (2020) for fuzzy bunching.

Note

This code is adapted from Xiao's Matlab code, available at his website.

Parameters
• X (np.ndarray) bunching sample
• X0 (Union[np.ndarray, None]) non-bunching sample if exists, skip otherwise by setting it to None.
• x_l (float) threshold
• x_min (float) excluded range lower bound
• x_max (float) excluded range upper bound
• degree (int) degree of polynomial for conterfactual density
• friction (bool, optional) whether to allow optimization friction. Defaults to True.
• noise (bool, optional) whether to allow noise in the data. Defaults to True.
• fig (bool, optional) whether to create a figure of CDF. Defaults to False.
Returns (Tuple[float, float])

(dx_hat, alpha_hat), where dx_hat is bunching range, $\Delta q$, and alpha_hat is non-optimizing share, $\alpha$.

Examples
>>> from frds.algorithms.bunching import sharp_bunching
>>> import numpy as np


Generate a sample.

>>> N = 1000
>>> x_l = 0.5
>>> dx = 0.1
>>> alpha = 0
>>> rng = np.random.RandomState(0)
>>> Z0 = rng.rand(N)
>>> Z = Z0.copy()
>>> Z[(Z0 > x_l) & (Z0 <= x_l + dx)] = x_l
>>> Z[: round(alpha * N)] = Z0[: round(alpha * N)]
>>> u = 0.0
>>> U = u * np.random.randn(N)
>>> X = np.add(Z, U)
>>> X0 = np.add(Z0, U)
>>> x_max = x_l + 1.1 * dx
>>> x_min = x_l * 0.99


Sharpe bunching estimation

>>> sharp_bunching(X, X0, x_l, x_min, x_max, degree=5, friction=True, noise=True, fig=False)
(0.00984977111886289, -1.0)


References
• Alvero and Xiao (2020), Fuzzy bunching, SSRN.
• Kleven and Waseem (2013), Using notches to uncover optimization frictions and structural elasticities: Theory and evidence from pakistan, The Quarterly Journal of Ecnomics, 128(2), 669-723.
Todo
• Option to specify output plot path.
• Plot styling.

Last update: August 14, 2021
Back to top