diff --git a/src/api/quantile_mapping.cpp b/src/api/quantile_mapping.cpp index 2067fbcc..754b739d 100644 --- a/src/api/quantile_mapping.cpp +++ b/src/api/quantile_mapping.cpp @@ -3,7 +3,25 @@ using namespace gridpp; vec2 gridpp::quantile_mapping_curve(const vec& ref, const vec& fcst, vec quantiles) { + if(ref.size() != fcst.size()) + throw std::invalid_argument("ref and fcst must be of the same size"); + + if(quantiles.size() > 0) { + for(int i = 0; i < quantiles.size(); i++) { + float curr = quantiles[i]; + if(!gridpp::is_valid(curr) || curr > 1 || curr < 0) + throw std::invalid_argument("Quantiles must be >= 0 and <= 1"); + } + } vec2 curve(2); + if(ref.size() == 0) + return curve; + else if(ref.size() == 1) { + curve[0] = fcst; + curve[1] = ref; + return curve; + } + vec ref_sort = ref; std::sort(ref_sort.begin(), ref_sort.end()); vec fcst_sort = fcst; diff --git a/tests/quantile_mapping_test.py b/tests/quantile_mapping_test.py index 56678ded..66fd9fed 100644 --- a/tests/quantile_mapping_test.py +++ b/tests/quantile_mapping_test.py @@ -26,6 +26,41 @@ def test_negative(self): new_fcst = gridpp.apply_curve(fcst, curve, gridpp.OneToOne, gridpp.OneToOne) np.testing.assert_array_equal(np.sort(ref), new_fcst) + def test_quantiles(self): + ref = np.arange(11) + fcst = ref + 2 + quantiles = [0.1, 0.9] + curve = gridpp.quantile_mapping_curve(ref, fcst, quantiles) + np.testing.assert_array_equal([1, 9], curve[1]) + np.testing.assert_array_equal([3, 11], curve[0]) + + def test_single_point(self): + ref = [1] + fcst = [2] + curve = gridpp.quantile_mapping_curve(ref, fcst) + np.testing.assert_array_almost_equal(curve, [fcst, ref]) + + def test_dimension_mismatch(self): + ref = [1, 2] + fcst = [1, 2, 3] + with self.assertRaises(Exception) as e: + curve = gridpp.quantile_mapping_curve(ref, fcst) + with self.assertRaises(Exception) as e: + curve = gridpp.quantile_mapping_curve(ref, fcst, [0.1, 0.9]) + + def test_empty_curve(self): + ref = [] + fcst = [] + np.testing.assert_array_almost_equal([[],[]], gridpp.quantile_mapping_curve(ref, fcst)) + np.testing.assert_array_almost_equal([[],[]], gridpp.quantile_mapping_curve(ref, fcst, [0.1, 0.9])) + + def test_invalid_argument(self): + ref = np.arange(11) + fcst = ref + 2 + quantiles = [0.1, -1] + with self.assertRaises(Exception) as e: + curve = gridpp.quantile_mapping_curve(ref, fcst, quantiles) + if __name__ == '__main__': unittest.main()