-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Description
#19239 concluded with generic map/broadcast over sparse arrays not storing numerical zeros in the result. But whether map!/broadcast! should do the same, or instead store some numerical zeros dependent on / reflecting the inputs' structures, wasn't settled. Hence this issue.
Originally (c. #19239) I thought map!/broadcast! should retain the inputs' structure. But working on #19371 changed my thinking: map!/broadcast! should either (1) store the same result as map/broadcast or (2) retain solely the output argument's structure, perhaps throwing an error where broadcast(f, inputargs...) does not fit within the output argument's structure. Primary reason:
What "retaining the inputs' structure" means is not well defined: Should broadcast!(f, C, A, B) retain A's structure, B's structure, the union of A's and B's structures, the union of A's, B's, and C's structures, or the intersection of C's structure with the union of A's and B's structures? What if either of A or B has a singleton dimension or is scalar?
Only the output argument seems logically privileged, hence proposal (2) above. (2) has a few possible variations: When broadcast(f, inargs...) contains a nonzero value outside the equivalent broadcast!'s output argument's structure, broadcast! could either (2a) error, (2b) ignore that nonzero, or (2c) grow the output argument's structure.
Some thoughts on proposals (1) and (2):
(1) has the advantages of ease of use (it always works) and strict consistency with map/broadcast.
(2a) behaves like broadcast!(f, S, args...) where S is a structured (e.g. Diagonal, Tridiagonal, etc) matrix: strictly non-allocating, but not as flexible / easy to use as (1).
(2b) is interesting: On the one hand, it requires iteration only over the parts of the input arguments' structure that intersect the output argument's structure, potentially enabling greater efficiency where the result's structure is known/predictable. In other words, this approach provides a form of escape hatch for exploiting known detailed zero-preserving behavior of the map/broadcast function (ref. discussion in #18590), and that escape hatch could be extended to map!/broadcast! for structured matrices. On the other hand, map/broadcast and map!/broadcast! could produce inconsistent results.
(2c) seems like a half measure with little if any advantage over either (1) or (2a).
Thoughts? Thanks and best!