This PR changes the internal storage of the pixel boundaries from double to single precision. I made sure everything still uses double precision for all calculations, so there isn't too much loss of precision in the various places.
This is most important when the sides may add 1 to their positions depending on which side of the square they are on. If these are done in single precision, there is more loss of precision. Probably still acceptable, TBH, but it seems prudent to do as much as possible in double precision nonetheless.
Anyway, only one test ended up needing to be relaxed in its precision, and I dug into it and convinced myself that it is unavoidable. Basically, it's when we first apply the tree rings to all the boundaries, then go back and calculate areas. This necessarily passes through float storage, so it only ends up accurate at rtol=2e-8. That seems completely fine to me.
This PR changes the internal storage of the pixel boundaries from double to single precision. I made sure everything still uses double precision for all calculations, so there isn't too much loss of precision in the various places.
This is most important when the sides may add 1 to their positions depending on which side of the square they are on. If these are done in single precision, there is more loss of precision. Probably still acceptable, TBH, but it seems prudent to do as much as possible in double precision nonetheless.
Anyway, only one test ended up needing to be relaxed in its precision, and I dug into it and convinced myself that it is unavoidable. Basically, it's when we first apply the tree rings to all the boundaries, then go back and calculate areas. This necessarily passes through float storage, so it only ends up accurate at rtol=2e-8. That seems completely fine to me.