From ffa4b78fd8c1466be616627a0d7faa94bf79b76c Mon Sep 17 00:00:00 2001 From: Andrew Hearin Date: Fri, 30 Mar 2018 06:41:13 -0500 Subject: [PATCH 1/2] Added bijective_distribution_matching function to utils --- CHANGES.rst | 2 + docs/function_usage/utility_functions.rst | 2 + halotools/utils/distribution_matching.py | 38 ++++++++++++++++++- .../utils/tests/test_distribution_matching.py | 15 ++++++++ 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index a85ddb83c..895577189 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -17,6 +17,8 @@ - Added new bin-free implementation of `conditional_abunmatch`. +- Added new utils function `bijective_distribution_matching` + 0.6 (2017-12-15) ---------------- diff --git a/docs/function_usage/utility_functions.rst b/docs/function_usage/utility_functions.rst index 2aeece071..1ecdfe8d6 100644 --- a/docs/function_usage/utility_functions.rst +++ b/docs/function_usage/utility_functions.rst @@ -39,6 +39,7 @@ Matching one distribution to another distribution_matching_indices resample_x_to_match_y + bijective_distribution_matching Rotations, dot products, and other operations in 3d space =============================================================== @@ -46,6 +47,7 @@ Rotations, dot products, and other operations in 3d space .. autosummary:: elementwise_dot + elementwise_norm angles_between_list_of_vectors vectors_between_list_of_vectors rotation_matrices_from_angles diff --git a/halotools/utils/distribution_matching.py b/halotools/utils/distribution_matching.py index a94f0d5f4..a96777cb1 100644 --- a/halotools/utils/distribution_matching.py +++ b/halotools/utils/distribution_matching.py @@ -5,7 +5,8 @@ from astropy.utils.misc import NumpyRNGContext -__all__ = ('distribution_matching_indices', 'resample_x_to_match_y') +__all__ = ('distribution_matching_indices', 'resample_x_to_match_y', + 'bijective_distribution_matching') def distribution_matching_indices(input_distribution, output_distribution, @@ -123,3 +124,38 @@ def resample_x_to_match_y(x, y, bins, seed=None): indices = np.empty_like(x).astype(int) indices[idx_sorted_x] = idx[idx_sorted_xnew] return indices + + +def bijective_distribution_matching(x_in, x_desired): + """ Replace the values in ``x_in`` with ``x_desired``, + preserving the rank-order of ``x_in`` + + Parameters + ---------- + x_in : ndarray + Numpy array of shape (npts, ) + + x_desired : ndarray + Numpy array of shape (npts, ) + + Returns + ------- + x_out : ndarray + Numpy array of shape (npts, ) + + Examples + -------- + >>> npts = int(1e5) + >>> x_in = np.random.normal(loc=0, scale=0.5, size=npts) + >>> x_desired = np.random.normal(loc=2, scale=1, size=npts) + >>> x_out = bijective_distribution_matching(x_in, x_desired) + """ + x_in = np.atleast_1d(x_in) + x_desired = np.atleast_1d(x_desired) + x_out = np.zeros_like(x_in) + idx_sorted = np.argsort(x_in) + x_out[idx_sorted] = np.sort(x_desired) + return x_out + + + diff --git a/halotools/utils/tests/test_distribution_matching.py b/halotools/utils/tests/test_distribution_matching.py index 94e3ead58..3927c9f37 100644 --- a/halotools/utils/tests/test_distribution_matching.py +++ b/halotools/utils/tests/test_distribution_matching.py @@ -4,6 +4,8 @@ from astropy.utils.misc import NumpyRNGContext from ..distribution_matching import distribution_matching_indices, resample_x_to_match_y +from ..distribution_matching import bijective_distribution_matching + __all__ = ('test_distribution_matching_indices1', ) @@ -50,3 +52,16 @@ def test_resample_x_to_match_y(): assert np.allclose(result, correct_result, atol=0.02) except TypeError: pass + + +def test_bijective_distribution_matching(): + npts = int(1e5) + with NumpyRNGContext(fixed_seed): + x_in = np.random.normal(loc=0, scale=0.5, size=npts) + x_desired = np.random.normal(loc=2, scale=1, size=npts) + + x_out = bijective_distribution_matching(x_in, x_desired) + assert np.allclose(np.sort(x_out), np.sort(x_desired)) + + idx_x_in_sorted = np.argsort(x_in) + assert np.all(np.diff(x_out[idx_x_in_sorted])>=0) From 53522d92d4b81c9662eae1a037f0fdef6410ef4c Mon Sep 17 00:00:00 2001 From: Andrew Hearin Date: Fri, 30 Mar 2018 06:58:08 -0500 Subject: [PATCH 2/2] Added demo figure to docstring of bijective_distribution_matching --- .../bijective_distribution_matching_demo.png | Bin 0 -> 16687 bytes halotools/utils/distribution_matching.py | 9 +++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 docs/_static/bijective_distribution_matching_demo.png diff --git a/docs/_static/bijective_distribution_matching_demo.png b/docs/_static/bijective_distribution_matching_demo.png new file mode 100644 index 0000000000000000000000000000000000000000..58b07c84b7afd6f22d49ca9f45879e85b23bea53 GIT binary patch literal 16687 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 literal 0 HcmV?d00001 diff --git a/halotools/utils/distribution_matching.py b/halotools/utils/distribution_matching.py index a96777cb1..4bc08eaae 100644 --- a/halotools/utils/distribution_matching.py +++ b/halotools/utils/distribution_matching.py @@ -127,8 +127,7 @@ def resample_x_to_match_y(x, y, bins, seed=None): def bijective_distribution_matching(x_in, x_desired): - """ Replace the values in ``x_in`` with ``x_desired``, - preserving the rank-order of ``x_in`` + """ Replace the values in ``x_in`` with ``x_desired``, preserving the rank-order of ``x_in`` Parameters ---------- @@ -149,6 +148,12 @@ def bijective_distribution_matching(x_in, x_desired): >>> x_in = np.random.normal(loc=0, scale=0.5, size=npts) >>> x_desired = np.random.normal(loc=2, scale=1, size=npts) >>> x_out = bijective_distribution_matching(x_in, x_desired) + + In the figure below, the left hand panel shows that the output distribution + is in exact agreement with the desired distribution. The right hand panel + shows that the rank-order of the input distribution is preserved. + + .. image:: /_static/bijective_distribution_matching_demo.png """ x_in = np.atleast_1d(x_in) x_desired = np.atleast_1d(x_desired)