Apply `op` to every aligned pair of cells. The result tile carries the union of both coord sets.
(
schema: &ArraySchema,
a: &SparseTile,
b: &SparseTile,
op: BinaryOp,
)
| 31 | /// Apply `op` to every aligned pair of cells. The result tile carries |
| 32 | /// the union of both coord sets. |
| 33 | pub fn elementwise( |
| 34 | schema: &ArraySchema, |
| 35 | a: &SparseTile, |
| 36 | b: &SparseTile, |
| 37 | op: BinaryOp, |
| 38 | ) -> ArrayResult<SparseTile> { |
| 39 | let n_attrs = schema.attrs.len(); |
| 40 | let by_coord_a = index_rows(a); |
| 41 | let by_coord_b = index_rows(b); |
| 42 | let mut keys: BTreeMap<Vec<CoordKey>, ()> = BTreeMap::new(); |
| 43 | for k in by_coord_a.keys().chain(by_coord_b.keys()) { |
| 44 | keys.insert(k.clone(), ()); |
| 45 | } |
| 46 | |
| 47 | let mut builder = SparseTileBuilder::new(schema); |
| 48 | for key in keys.keys() { |
| 49 | let coord = decode_key(key); |
| 50 | let lhs = by_coord_a.get(key); |
| 51 | let rhs = by_coord_b.get(key); |
| 52 | let mut out = Vec::with_capacity(n_attrs); |
| 53 | for i in 0..n_attrs { |
| 54 | let l = lhs.map(|v| v[i].clone()).unwrap_or(CellValue::Null); |
| 55 | let r = rhs.map(|v| v[i].clone()).unwrap_or(CellValue::Null); |
| 56 | out.push(apply(&l, &r, op)); |
| 57 | } |
| 58 | builder.push(&coord, &out)?; |
| 59 | } |
| 60 | Ok(builder.build()) |
| 61 | } |
| 62 | |
| 63 | fn apply(l: &CellValue, r: &CellValue, op: BinaryOp) -> CellValue { |
| 64 | let (lf, rf) = match (to_f64(l), to_f64(r)) { |