From 0bd66e53f25350d6c171efb8ad4992c90bb3e9b5 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Thu, 11 May 2023 20:26:13 +0200 Subject: [PATCH 1/6] Add extend method to grid API --- pineappl/src/grid.rs | 73 ++++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/pineappl/src/grid.rs b/pineappl/src/grid.rs index c7fcbea7..71552f6f 100644 --- a/pineappl/src/grid.rs +++ b/pineappl/src/grid.rs @@ -889,34 +889,11 @@ impl Grid { .indexed_iter_mut() .filter(|((_, _, _), subgrid)| !subgrid.is_empty()) { - let other_order = &other.orders[i]; - let other_entry = &other.lumi[k]; - - if !self - .orders - .iter() - .chain(new_orders.iter()) - .any(|x| x == other_order) - { - new_orders.push(other_order.clone()); - } - - if !self - .lumi - .iter() - .chain(new_entries.iter()) - .any(|y| y == other_entry) - { - new_entries.push(other_entry.clone()); - } - } - - if !new_orders.is_empty() || !new_entries.is_empty() || (new_bins != 0) { - self.increase_shape(&(new_orders.len(), new_bins, new_entries.len())); + new_orders.push(other.orders[i].clone()); + new_entries.push(other.lumi[k].clone()); } - self.orders.append(&mut new_orders); - self.lumi.append(&mut new_entries); + self.extend(&new_orders, &new_entries, new_bins); let bin_indices: Vec<_> = (0..other.bin_info().bins()) .map(|bin| { @@ -948,6 +925,50 @@ impl Grid { Ok(()) } + /// Extend subgrids array with the given `orders`, luminosity `entries`, and number of `bins`. + /// + /// Returns the inserted orders and entries, i.e. those not already present. + pub fn extend( + &mut self, + orders: &[Order], + entries: &[LumiEntry], + bins: usize, + ) -> (Vec, Vec) { + let mut new_orders: Vec = Vec::new(); + let mut new_entries: Vec = Vec::new(); + + for order in orders.iter() { + if !self + .orders + .iter() + .chain(new_orders.iter()) + .any(|x| x == order) + { + new_orders.push(order.clone()); + } + } + + for entry in entries.iter() { + if !self + .lumi + .iter() + .chain(new_entries.iter()) + .any(|y| y == entry) + { + new_entries.push(entry.clone()); + } + } + + if !new_orders.is_empty() || !new_entries.is_empty() || (bins != 0) { + self.increase_shape(&(new_orders.len(), bins, new_entries.len())); + } + + self.orders.append(&mut new_orders); + self.lumi.append(&mut new_entries); + + (new_orders, new_entries) + } + fn increase_shape(&mut self, new_dim: &(usize, usize, usize)) { let old_dim = self.subgrids.raw_dim().into_pattern(); let mut new_subgrids = Array3::from_shape_simple_fn( From 00471a29f204f0970c5fea9f445ee985f8bc6a83 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Fri, 12 May 2023 12:46:44 +0200 Subject: [PATCH 2/6] Treat bins on the some footing of orders and bins --- pineappl/src/grid.rs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/pineappl/src/grid.rs b/pineappl/src/grid.rs index 71552f6f..32f4a38c 100644 --- a/pineappl/src/grid.rs +++ b/pineappl/src/grid.rs @@ -851,12 +851,12 @@ impl Grid { /// TODO pub fn merge(&mut self, mut other: Self) -> Result<(), GridError> { let mut new_orders: Vec = Vec::new(); - let mut new_bins = 0; + let mut new_bin_limits = BinLimits::new(Vec::new()); let mut new_entries: Vec = Vec::new(); if self.bin_info() != other.bin_info() { let lhs_bins = self.bin_info().bins(); - new_bins = other.bin_info().bins(); + let rhs_bins = other.bin_info().bins(); let lhs_remapper = self.remapper_mut(); let rhs_remapper = other.remapper(); @@ -866,16 +866,17 @@ impl Grid { lhs.merge(rhs).map_err(GridError::MergeBinError)?; let a = u32::try_from(lhs_bins).unwrap_or_else(|_| unreachable!()); - let b = u32::try_from(lhs_bins + new_bins).unwrap_or_else(|_| unreachable!()); + let b = u32::try_from(lhs_bins + rhs_bins).unwrap_or_else(|_| unreachable!()); - self.bin_limits = BinLimits::new((0..=b).map(f64::from).collect()); + new_bin_limits = BinLimits::new((0..=b).map(f64::from).collect()); other.bin_limits = BinLimits::new((a..=b).map(f64::from).collect()); } else { // Return an error todo!(); } } else if rhs_remapper.is_none() { - self.bin_limits + new_bin_limits = self.bin_limits.clone(); + new_bin_limits .merge(&other.bin_limits) .map_err(GridError::InvalidBinLimits)?; } else { @@ -883,6 +884,9 @@ impl Grid { todo!(); } } + if new_bin_limits.bins() == 0 { + new_bin_limits = self.bin_limits.clone(); + } for ((i, _, k), _) in other .subgrids @@ -893,7 +897,7 @@ impl Grid { new_entries.push(other.lumi[k].clone()); } - self.extend(&new_orders, &new_entries, new_bins); + self.extend(&new_orders, &new_bin_limits, &new_entries); let bin_indices: Vec<_> = (0..other.bin_info().bins()) .map(|bin| { @@ -931,10 +935,11 @@ impl Grid { pub fn extend( &mut self, orders: &[Order], + bins: &BinLimits, entries: &[LumiEntry], - bins: usize, ) -> (Vec, Vec) { let mut new_orders: Vec = Vec::new(); + let new_bins = bins.bins() - self.bin_limits.bins(); let mut new_entries: Vec = Vec::new(); for order in orders.iter() { @@ -959,12 +964,13 @@ impl Grid { } } - if !new_orders.is_empty() || !new_entries.is_empty() || (bins != 0) { - self.increase_shape(&(new_orders.len(), bins, new_entries.len())); + if !new_orders.is_empty() || !new_entries.is_empty() || (new_bins != 0) { + self.increase_shape(&(new_orders.len(), new_bins, new_entries.len())); } self.orders.append(&mut new_orders); self.lumi.append(&mut new_entries); + self.bin_limits = bins.clone(); (new_orders, new_entries) } From 736ceeab05e0f56c98e18e0be7122507667c92f6 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Fri, 12 May 2023 20:39:04 +0200 Subject: [PATCH 3/6] Add a 'sensible' default value for BinLimits --- pineappl/src/grid.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pineappl/src/grid.rs b/pineappl/src/grid.rs index 32f4a38c..5705ca39 100644 --- a/pineappl/src/grid.rs +++ b/pineappl/src/grid.rs @@ -851,7 +851,7 @@ impl Grid { /// TODO pub fn merge(&mut self, mut other: Self) -> Result<(), GridError> { let mut new_orders: Vec = Vec::new(); - let mut new_bin_limits = BinLimits::new(Vec::new()); + let mut new_bin_limits = BinLimits::new(vec![0.]); let mut new_entries: Vec = Vec::new(); if self.bin_info() != other.bin_info() { From b0f8ce5c6f734c293bf919d0e290a303c2fc1cac Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Mon, 15 May 2023 17:53:30 +0200 Subject: [PATCH 4/6] Rearrange variable to reduce mutability --- pineappl/src/grid.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/pineappl/src/grid.rs b/pineappl/src/grid.rs index 5705ca39..7f6ea093 100644 --- a/pineappl/src/grid.rs +++ b/pineappl/src/grid.rs @@ -851,10 +851,9 @@ impl Grid { /// TODO pub fn merge(&mut self, mut other: Self) -> Result<(), GridError> { let mut new_orders: Vec = Vec::new(); - let mut new_bin_limits = BinLimits::new(vec![0.]); let mut new_entries: Vec = Vec::new(); - if self.bin_info() != other.bin_info() { + let new_bin_limits = if self.bin_info() != other.bin_info() { let lhs_bins = self.bin_info().bins(); let rhs_bins = other.bin_info().bins(); @@ -868,25 +867,25 @@ impl Grid { let a = u32::try_from(lhs_bins).unwrap_or_else(|_| unreachable!()); let b = u32::try_from(lhs_bins + rhs_bins).unwrap_or_else(|_| unreachable!()); - new_bin_limits = BinLimits::new((0..=b).map(f64::from).collect()); other.bin_limits = BinLimits::new((a..=b).map(f64::from).collect()); + BinLimits::new((0..=b).map(f64::from).collect()) } else { // Return an error todo!(); } } else if rhs_remapper.is_none() { - new_bin_limits = self.bin_limits.clone(); + let mut new_bin_limits = self.bin_limits.clone(); new_bin_limits .merge(&other.bin_limits) .map_err(GridError::InvalidBinLimits)?; + new_bin_limits } else { // Return an error todo!(); } - } - if new_bin_limits.bins() == 0 { - new_bin_limits = self.bin_limits.clone(); - } + } else { + self.bin_limits.clone() + }; for ((i, _, k), _) in other .subgrids From 55614df571a210524e49b8cd023c94eae8abc669 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Mon, 15 May 2023 18:06:18 +0200 Subject: [PATCH 5/6] Deduplicate unique function --- pineappl/src/grid.rs | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/pineappl/src/grid.rs b/pineappl/src/grid.rs index 7f6ea093..0224c30c 100644 --- a/pineappl/src/grid.rs +++ b/pineappl/src/grid.rs @@ -937,31 +937,24 @@ impl Grid { bins: &BinLimits, entries: &[LumiEntry], ) -> (Vec, Vec) { - let mut new_orders: Vec = Vec::new(); - let new_bins = bins.bins() - self.bin_limits.bins(); - let mut new_entries: Vec = Vec::new(); + fn unique(current: &[T], update: &[T]) -> Vec { + let mut new = Vec::new(); - for order in orders.iter() { - if !self - .orders - .iter() - .chain(new_orders.iter()) - .any(|x| x == order) - { - new_orders.push(order.clone()); + for el in update.iter() { + if !current + .iter() + .chain(new.iter()) + .any(|x| x == el) + { + new.push((*el).clone()); + } } + new } - for entry in entries.iter() { - if !self - .lumi - .iter() - .chain(new_entries.iter()) - .any(|y| y == entry) - { - new_entries.push(entry.clone()); - } - } + let mut new_orders = unique(&self.orders, &orders); + let new_bins = bins.bins() - self.bin_limits.bins(); + let mut new_entries = unique(&self.lumi, &entries); if !new_orders.is_empty() || !new_entries.is_empty() || (new_bins != 0) { self.increase_shape(&(new_orders.len(), new_bins, new_entries.len())); From aa59fc6b65492322991e4c1597e739b577fd48e8 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Mon, 15 May 2023 18:10:15 +0200 Subject: [PATCH 6/6] Add docs for internal function --- pineappl/src/grid.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pineappl/src/grid.rs b/pineappl/src/grid.rs index 0224c30c..bcb4b076 100644 --- a/pineappl/src/grid.rs +++ b/pineappl/src/grid.rs @@ -937,9 +937,14 @@ impl Grid { bins: &BinLimits, entries: &[LumiEntry], ) -> (Vec, Vec) { + /// Extend collection with non-duplicated elements. + /// + /// Notice that this function does not modify the order of elements. fn unique(current: &[T], update: &[T]) -> Vec { let mut new = Vec::new(); + // Since the order has to be preserved, this can't be achieved just by sorting and + // deduplicating. for el in update.iter() { if !current .iter()