diff --git a/docs/_static/citations/chen2026-gmd.bib b/docs/_static/citations/chen2026-gmd.bib new file mode 100644 index 000000000..01d5c7451 --- /dev/null +++ b/docs/_static/citations/chen2026-gmd.bib @@ -0,0 +1,11 @@ +@Article{gmd-19-6545-2026, + author = {Chen, H. and Ullrich, P. A. and Panetta, J. and Marsico, D. and Hanke, M. and Jain, R. and Zhang, C. and Jacob, R. L.}, + title = {Accurate and robust geometric algorithms for regridding on the sphere}, + journal = {Geoscientific Model Development}, + volume = {19}, + year = {2026}, + number = {14}, + pages = {6545--6570}, + url = {https://gmd.copernicus.org/articles/19/6545/2026/}, + doi = {10.5194/gmd-19-6545-2026} +} diff --git a/docs/_static/citations/chen2026-siam.bib b/docs/_static/citations/chen2026-siam.bib new file mode 100644 index 000000000..e78d1dcec --- /dev/null +++ b/docs/_static/citations/chen2026-siam.bib @@ -0,0 +1,11 @@ +@Article{doi:10.1137/25M1737614, + author = {Chen, Hongyu and Ullrich, Paul A. and Panetta, Julian}, + title = {Fast and Accurate Intersections on a Sphere}, + journal = {SIAM Journal on Scientific Computing}, + volume = {48}, + number = {2}, + pages = {B208--B232}, + year = {2026}, + doi = {10.1137/25M1737614}, + url = {https://doi.org/10.1137/25M1737614} +} diff --git a/docs/_static/citations/dekker1971.bib b/docs/_static/citations/dekker1971.bib new file mode 100644 index 000000000..03c59f0c5 --- /dev/null +++ b/docs/_static/citations/dekker1971.bib @@ -0,0 +1,9 @@ +@Article{dekker1971, + author = {Dekker, T. J.}, + title = {A Floating-Point Technique for Extending the Available Precision}, + journal = {Numerische Mathematik}, + volume = {18}, + year = {1971}, + pages = {224--242}, + doi = {10.1007/BF01397083} +} diff --git a/docs/_static/citations/higham2002.bib b/docs/_static/citations/higham2002.bib new file mode 100644 index 000000000..4b92def38 --- /dev/null +++ b/docs/_static/citations/higham2002.bib @@ -0,0 +1,8 @@ +@Book{higham2002, + author = {Higham, N. J.}, + title = {Accuracy and Stability of Numerical Algorithms}, + edition = {2nd}, + publisher = {Society for Industrial and Applied Mathematics}, + year = {2002}, + doi = {10.1137/1.9780898718027} +} diff --git a/docs/_static/citations/jeannerod2013.bib b/docs/_static/citations/jeannerod2013.bib new file mode 100644 index 000000000..38cb44ad5 --- /dev/null +++ b/docs/_static/citations/jeannerod2013.bib @@ -0,0 +1,9 @@ +@Article{jeannerod2013, + author = {Jeannerod, C.-P. and Louvet, N. and Muller, J.-M.}, + title = {Further Analysis of Kahan's Algorithm for the Accurate Computation of 2 $\times$ 2 Determinants}, + journal = {Mathematics of Computation}, + volume = {82}, + year = {2013}, + pages = {2245--2264}, + doi = {10.1090/S0025-5718-2013-02679-8} +} diff --git a/docs/_static/citations/knuth1997.bib b/docs/_static/citations/knuth1997.bib new file mode 100644 index 000000000..5c37334c8 --- /dev/null +++ b/docs/_static/citations/knuth1997.bib @@ -0,0 +1,8 @@ +@Book{knuth1997, + author = {Knuth, D. E.}, + title = {The Art of Computer Programming, Volume 2: Seminumerical Algorithms}, + edition = {3rd}, + publisher = {Addison-Wesley}, + year = {1997}, + note = {Section 4.2.2, Theorem B} +} diff --git a/docs/_static/citations/rump2023.bib b/docs/_static/citations/rump2023.bib new file mode 100644 index 000000000..d18e82fa6 --- /dev/null +++ b/docs/_static/citations/rump2023.bib @@ -0,0 +1,8 @@ +@Article{rump2023, + author = {Rump, S. M.}, + title = {Fast and Accurate Computation of the Euclidean Norm of a Vector}, + journal = {Japan Journal of Industrial and Applied Mathematics}, + volume = {40}, + year = {2023}, + doi = {10.1007/s13160-023-00593-8} +} diff --git a/docs/_static/citations/shewchuk1997.bib b/docs/_static/citations/shewchuk1997.bib new file mode 100644 index 000000000..2debb4c89 --- /dev/null +++ b/docs/_static/citations/shewchuk1997.bib @@ -0,0 +1,9 @@ +@Article{shewchuk1997, + author = {Shewchuk, J. R.}, + title = {Adaptive Precision Floating-Point Arithmetic and Fast Robust Geometric Predicates}, + journal = {Discrete \& Computational Geometry}, + volume = {18}, + year = {1997}, + pages = {305--363}, + doi = {10.1007/PL00009321} +} diff --git a/docs/citation.rst b/docs/citation.rst index 4796688e9..9e2ce6929 100644 --- a/docs/citation.rst +++ b/docs/citation.rst @@ -27,3 +27,132 @@ For example: **UXarray Organization. (2021). UXarray (version 2025.06.0) [Software]. Project Raijin & Project SEATS. doi:10.5281/zenodo.15757812.** + +.. _algorithm-citations: + +Algorithm-Level Citations +-------------------------- + +.. note:: + + In addition to the package-level Zenodo citation, several spherical geometry and + regridding algorithms in UXarray implement methods from peer-reviewed publications. + If a result you report in an academic work (paper, thesis, preprint, technical + report) depends on one of these algorithms (e.g., latlon bounds, zonal-mean, + conservative remapping, computed face area), please also cite the corresponding + publication listed below, in addition to the UXarray software citation. This does + not apply to incidental use of these APIs in code that isn't producing a citable + scientific result (e.g., tutorials, internal tools, or software that merely + depends on UXarray). + +The definitions and geometric conventions for nodes, edges, and faces used +throughout UXarray are based on: + + |cite-gmd| + +Several of the intersection and geometry operators are additionally based on: + + |cite-siam| + +.. |cite-gmd| replace:: Chen, H., Ullrich, P. A., Panetta, J., Marsico, D., Hanke, M., Jain, R., + Zhang, C., and Jacob, R. L. (2026). "Accurate and Robust Geometric Algorithms for + Regridding on the Sphere." *Geoscientific Model Development*, 19(14), 6545-6570. + `doi:10.5194/gmd-19-6545-2026 `__ + (:download:`BibTeX <_static/citations/chen2026-gmd.bib>`) + +.. |cite-siam| replace:: Chen, H., Ullrich, P. A., and Panetta, J. (2026). "Fast and Accurate + Intersections on a Sphere." *SIAM Journal on Scientific Computing*, 48(2), B208-B232. + `doi:10.1137/25M1737614 `__ + (:download:`BibTeX <_static/citations/chen2026-siam.bib>`) + +.. |cite-shewchuk| replace:: Shewchuk, J. R. (1997). "Adaptive Precision Floating-Point + Arithmetic and Fast Robust Geometric Predicates." *Discrete & Computational Geometry*, + 18, 305-363. `doi:10.1007/PL00009321 `__ + (:download:`BibTeX <_static/citations/shewchuk1997.bib>`) + +.. |cite-knuth| replace:: Knuth, D. E. (1997). *The Art of Computer Programming, Volume 2: + Seminumerical Algorithms* (3rd ed.). Addison-Wesley, Section 4.2.2, Theorem B. + (:download:`BibTeX <_static/citations/knuth1997.bib>`) + +.. |cite-dekker| replace:: Dekker, T. J. (1971). "A Floating-Point Technique for Extending + the Available Precision." *Numerische Mathematik*, 18, 224-242. + `doi:10.1007/BF01397083 `__ + (:download:`BibTeX <_static/citations/dekker1971.bib>`) + +.. |cite-higham| replace:: Higham, N. J. (2002). *Accuracy and Stability of Numerical + Algorithms* (2nd ed.). Society for Industrial and Applied Mathematics. + `doi:10.1137/1.9780898718027 `__ + (:download:`BibTeX <_static/citations/higham2002.bib>`) + +.. |cite-jeannerod| replace:: Jeannerod, C.-P., Louvet, N., and Muller, J.-M. (2013). + "Further Analysis of Kahan's Algorithm for the Accurate Computation of 2 × 2 + Determinants." *Mathematics of Computation*, 82, 2245-2264. + `doi:10.1090/S0025-5718-2013-02679-8 `__ + (:download:`BibTeX <_static/citations/jeannerod2013.bib>`) + +.. |cite-rump| replace:: Rump, S. M. (2023). "Fast and Accurate Computation of the + Euclidean Norm of a Vector." *Japan Journal of Industrial and Applied Mathematics*, 40. + `doi:10.1007/s13160-023-00593-8 `__ + (:download:`BibTeX <_static/citations/rump2023.bib>`) + +Algorithm-to-Publication Mapping +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. list-table:: + :header-rows: 1 + :widths: 15 20 65 + + * - Documentation section + - API or implementation + - Required citation(s) + * - `Descriptors `__ + - :py:attr:`~uxarray.Grid.bounds` + + :py:attr:`~uxarray.Grid.face_bounds_lon` + + :py:attr:`~uxarray.Grid.face_bounds_lat` + - |cite-gmd| + * - `Zonal Average `__ + - All zonal-average remapping implementations (e.g. :py:meth:`~uxarray.UxDataArray.zonal_average`) + - |cite-siam| + * - `Spherical Geometry: Intersections `__ + - All spherical-intersection APIs in this section (:py:func:`~uxarray.grid.intersections.gca_gca_intersection`, :py:func:`~uxarray.grid.intersections.gca_const_lat_intersection`, :py:func:`~uxarray.grid.intersections.get_number_of_intersections`) + - **Cite both:** + + |cite-gmd| + + |cite-siam| + * - `Spherical Geometry: Arcs `__ + - :py:func:`~uxarray.grid.arcs.in_between` + + :py:func:`~uxarray.grid.arcs.point_within_gca` + - No new citation required. Expected to be removed in a future release. + * - `Spherical Geometry: Arcs `__ + - :py:func:`~uxarray.grid.arcs.extreme_gca_latitude` + - |cite-gmd| + * - `Spherical Geometry: Arcs `__ + - :py:func:`~uxarray.grid.arcs.orient3d_on_sphere` + + :py:func:`~uxarray.grid.arcs.on_minor_arc` + - |cite-shewchuk| + * - `Compensated Arithmetic `__ + - :py:func:`~uxarray.utils.computing.two_sum` + - |cite-knuth| + * - `Compensated Arithmetic `__ + - :py:func:`~uxarray.utils.computing.two_prod` + - |cite-dekker| + * - `Compensated Arithmetic `__ + - :py:func:`~uxarray.utils.computing.diff_of_products` + - **Cite both:** + + |cite-higham| + + |cite-jeannerod| + * - `Compensated Arithmetic `__ + - :py:func:`~uxarray.utils.computing.accucross` + + :py:func:`~uxarray.utils.computing.accucross_pair` + - |cite-gmd| + * - `Compensated Arithmetic `__ + - :py:func:`~uxarray.utils.computing.acc_sqrt_re` + - |cite-rump| diff --git a/uxarray/core/dataarray.py b/uxarray/core/dataarray.py index 8f41a1627..86e0a5a00 100644 --- a/uxarray/core/dataarray.py +++ b/uxarray/core/dataarray.py @@ -690,6 +690,12 @@ def zonal_mean(self, lat=(-90, 90, 10), conservative: bool = False, **kwargs): Conservative averaging preserves integral quantities and is recommended for physical analysis. Non-conservative averaging samples at latitude lines. + + References + ---------- + Chen, H., Ullrich, P. A., and Panetta, J. (2026). Fast and accurate + intersections on a sphere. SIAM Journal on Scientific Computing, 48(2), + B208-B232. https://doi.org/10.1137/25M1737614 """ if not self._face_centered(): raise DataCenteringError( @@ -807,7 +813,12 @@ def zonal_mean(self, lat=(-90, 90, 10), conservative: bool = False, **kwargs): ) def zonal_average(self, lat=(-90, 90, 10), conservative: bool = False, **kwargs): - """Alias of zonal_mean; prefer `zonal_mean` for primary API.""" + """Alias of zonal_mean; prefer `zonal_mean` for primary API. + + See Also + -------- + zonal_mean : Full docstring, including algorithm references. + """ return self.zonal_mean(lat=lat, conservative=conservative, **kwargs) def zonal_anomaly(self, lat=(-90, 90, 10), conservative: bool = False): @@ -838,6 +849,10 @@ def zonal_anomaly(self, lat=(-90, 90, 10), conservative: bool = False): -------- >>> uxds["var"].zonal_anomaly() >>> uxds["var"].zonal_anomaly(lat=(-60, 60, 5), conservative=True) + + See Also + -------- + zonal_mean : Underlying zonal averaging algorithm and references. """ if not self._face_centered(): raise DataCenteringError( diff --git a/uxarray/grid/arcs.py b/uxarray/grid/arcs.py index 2edc2c8a8..6cf76b036 100644 --- a/uxarray/grid/arcs.py +++ b/uxarray/grid/arcs.py @@ -214,6 +214,13 @@ def extreme_gca_latitude(gca_cart, gca_lonlat, extreme_type): ------ ValueError If `extreme_type` is not 'max' or 'min'. + + References + ---------- + Chen, H., Ullrich, P. A., Panetta, J., Marsico, D., Hanke, M., Jain, R., + Zhang, C., and Jacob, R. L. (2026). Accurate and robust geometric + algorithms for regridding on the sphere. Geoscientific Model + Development, 19(14), 6545-6570. https://doi.org/10.5194/gmd-19-6545-2026 """ # Validate extreme_type if (extreme_type != "max") and (extreme_type != "min"): @@ -465,6 +472,12 @@ def orient3d_on_sphere(a, b, q, tol=_PREDICATE_ZERO_TOL): int +1 if q is to the left of a->b, -1 if to the right, 0 if collinear within ``tol``. + + References + ---------- + Shewchuk, J. R. (1997). Adaptive precision floating-point arithmetic and + fast robust geometric predicates. Discrete & Computational Geometry, 18, + 305-363. https://doi.org/10.1007/PL00009321 """ v = _orient3d_on_sphere_value(a, b, q) if v > tol: @@ -500,6 +513,12 @@ def on_minor_arc(q, a, b, tol=_ON_MINOR_ARC_TOL): mask (not bool) so callers can multiply it into validity products. An attempt to implement a similar Python function that provides the same functionality as AccuSphGeom's ``on_minor_arc_tol_ptr``. + + References + ---------- + Shewchuk, J. R. (1997). Adaptive precision floating-point arithmetic and + fast robust geometric predicates. Discrete & Computational Geometry, 18, + 305-363. https://doi.org/10.1007/PL00009321 """ return _on_minor_arc_xyz(q[0], q[1], q[2], a[0], a[1], a[2], b[0], b[1], b[2], tol) diff --git a/uxarray/grid/grid.py b/uxarray/grid/grid.py index 27c65e183..e2c620986 100644 --- a/uxarray/grid/grid.py +++ b/uxarray/grid/grid.py @@ -1540,6 +1540,13 @@ def bounds(self) -> xr.DataArray: ------- bounds: :py:class:`xr.DataArray` An array of shape (:py:attr:`~uxarray.Grid.n_face`, `two`, `two`) + + References + ---------- + Chen, H., Ullrich, P. A., Panetta, J., Marsico, D., Hanke, M., Jain, R., + Zhang, C., and Jacob, R. L. (2026). Accurate and robust geometric + algorithms for regridding on the sphere. Geoscientific Model + Development, 19(14), 6545-6570. https://doi.org/10.5194/gmd-19-6545-2026 """ if "bounds" not in self._ds: _populate_face_bounds(self) @@ -1549,7 +1556,15 @@ def bounds(self) -> xr.DataArray: @property def face_bounds_lon(self): - """Longitude bounds for each face in degrees.""" + """Longitude bounds for each face in degrees. + + References + ---------- + Chen, H., Ullrich, P. A., Panetta, J., Marsico, D., Hanke, M., Jain, R., + Zhang, C., and Jacob, R. L. (2026). Accurate and robust geometric + algorithms for regridding on the sphere. Geoscientific Model + Development, 19(14), 6545-6570. https://doi.org/10.5194/gmd-19-6545-2026 + """ if "face_bounds_lon" not in self._ds: bounds = self.bounds.values @@ -1569,7 +1584,15 @@ def face_bounds_lon(self): @property def face_bounds_lat(self): - """Latitude bounds for each face in degrees.""" + """Latitude bounds for each face in degrees. + + References + ---------- + Chen, H., Ullrich, P. A., Panetta, J., Marsico, D., Hanke, M., Jain, R., + Zhang, C., and Jacob, R. L. (2026). Accurate and robust geometric + algorithms for regridding on the sphere. Geoscientific Model + Development, 19(14), 6545-6570. https://doi.org/10.5194/gmd-19-6545-2026 + """ if "face_bounds_lat" not in self._ds: bounds = self.bounds.values diff --git a/uxarray/grid/intersections.py b/uxarray/grid/intersections.py index c413e6686..e2269b219 100644 --- a/uxarray/grid/intersections.py +++ b/uxarray/grid/intersections.py @@ -432,6 +432,17 @@ def gca_gca_intersection(gca_a_xyz, gca_b_xyz): numpy.ndarray Intersection points, shape ``(2, 3)``, with unused rows filled with NaN (0, 1, or 2 valid rows). + + References + ---------- + Chen, H., Ullrich, P. A., Panetta, J., Marsico, D., Hanke, M., Jain, R., + Zhang, C., and Jacob, R. L. (2026). Accurate and robust geometric + algorithms for regridding on the sphere. Geoscientific Model + Development, 19(14), 6545-6570. https://doi.org/10.5194/gmd-19-6545-2026 + + Chen, H., Ullrich, P. A., and Panetta, J. (2026). Fast and accurate + intersections on a sphere. SIAM Journal on Scientific Computing, 48(2), + B208-B232. https://doi.org/10.1137/25M1737614 """ if gca_a_xyz.shape[1] != 3 or gca_b_xyz.shape[1] != 3: raise DimensionError("The two GCAs must be in the cartesian [x, y, z] format") @@ -664,6 +675,17 @@ def gca_const_lat_intersection(gca_cart, const_z): numpy.ndarray Intersection points, shape ``(2, 3)``, with unused rows filled with NaN (0, 1, or 2 valid rows). + + References + ---------- + Chen, H., Ullrich, P. A., Panetta, J., Marsico, D., Hanke, M., Jain, R., + Zhang, C., and Jacob, R. L. (2026). Accurate and robust geometric + algorithms for regridding on the sphere. Geoscientific Model + Development, 19(14), 6545-6570. https://doi.org/10.5194/gmd-19-6545-2026 + + Chen, H., Ullrich, P. A., and Panetta, J. (2026). Fast and accurate + intersections on a sphere. SIAM Journal on Scientific Computing, 48(2), + B208-B232. https://doi.org/10.1137/25M1737614 """ res = np.empty((2, 3)) res.fill(np.nan) @@ -727,6 +749,17 @@ def get_number_of_intersections(arr): ------- int Number of non-NaN intersection points (0, 1, or 2). + + References + ---------- + Chen, H., Ullrich, P. A., Panetta, J., Marsico, D., Hanke, M., Jain, R., + Zhang, C., and Jacob, R. L. (2026). Accurate and robust geometric + algorithms for regridding on the sphere. Geoscientific Model + Development, 19(14), 6545-6570. https://doi.org/10.5194/gmd-19-6545-2026 + + Chen, H., Ullrich, P. A., and Panetta, J. (2026). Fast and accurate + intersections on a sphere. SIAM Journal on Scientific Computing, 48(2), + B208-B232. https://doi.org/10.1137/25M1737614 """ row1_is_nan = np.all(np.isnan(arr[0])) row2_is_nan = np.all(np.isnan(arr[1])) diff --git a/uxarray/utils/computing.py b/uxarray/utils/computing.py index 80b661cad..aff800372 100644 --- a/uxarray/utils/computing.py +++ b/uxarray/utils/computing.py @@ -66,6 +66,12 @@ def two_sum(a, b): Rounded sum fl(a + b). e : float Rounding error term; s + e = a + b exactly. + + References + ---------- + Knuth, D. E. (1997). The Art of Computer Programming, Volume 2: + Seminumerical Algorithms (3rd ed.). Addison-Wesley, Section 4.2.2, + Theorem B. """ s = a + b bp = s - a @@ -151,6 +157,12 @@ def two_prod(a, b): Rounded product fl(a * b). e : float Rounding error term; p + e = a * b exactly. + + References + ---------- + Dekker, T. J. (1971). A floating-point technique for extending the + available precision. Numerische Mathematik, 18, 224-242. + https://doi.org/10.1007/BF01397083 """ return _two_prod_fma(a, b) @@ -174,6 +186,12 @@ def two_prod(a, b): Rounded product fl(a * b). e : float Rounding error term; p + e = a * b exactly. + + References + ---------- + Dekker, T. J. (1971). A floating-point technique for extending the + available precision. Numerische Mathematik, 18, 224-242. + https://doi.org/10.1007/BF01397083 """ return _two_prod_veltkamp(a, b) @@ -204,6 +222,17 @@ def diff_of_products(a, b, c, d): High-order part of the accurate result. lo : float Low-order correction term; hi + lo equals the accurate value. + + References + ---------- + Higham, N. J. (2002). Accuracy and Stability of Numerical Algorithms + (2nd ed.). Society for Industrial and Applied Mathematics. + https://doi.org/10.1137/1.9780898718027 + + Jeannerod, C.-P., Louvet, N., and Muller, J.-M. (2013). Further analysis + of Kahan's algorithm for the accurate computation of 2 × 2 determinants. + Mathematics of Computation, 82, 2245-2264. + https://doi.org/10.1090/S0025-5718-2013-02679-8 """ w, e_w = two_prod(c, d) x, e_x = two_prod(a, b) @@ -235,6 +264,13 @@ def accucross(a0, a1, a2, b0, b1, b2): ------- x_hi, y_hi, z_hi, x_lo, y_lo, z_lo : float High and low parts of each cross-product component. + + References + ---------- + Chen, H., Ullrich, P. A., Panetta, J., Marsico, D., Hanke, M., Jain, R., + Zhang, C., and Jacob, R. L. (2026). Accurate and robust geometric + algorithms for regridding on the sphere. Geoscientific Model + Development, 19(14), 6545-6570. https://doi.org/10.5194/gmd-19-6545-2026 """ x_hi, x_lo = diff_of_products(a1, b2, a2, b1) y_hi, y_lo = diff_of_products(a2, b0, a0, b2) @@ -336,6 +372,13 @@ def accucross_pair( ------- x_hi, y_hi, z_hi, x_lo, y_lo, z_lo : float Compensated cross-product components. + + References + ---------- + Chen, H., Ullrich, P. A., Panetta, J., Marsico, D., Hanke, M., Jain, R., + Zhang, C., and Jacob, R. L. (2026). Accurate and robust geometric + algorithms for regridding on the sphere. Geoscientific Model + Development, 19(14), 6545-6570. https://doi.org/10.5194/gmd-19-6545-2026 """ # x = (ay*bz) - (az*by), expanded over all four hi/lo cross-terms x_hi, x_lo = _cdp8( @@ -507,6 +550,12 @@ def acc_sqrt_re(value, error=0.0): Rounded sqrt, fl(sqrt(value)). correction : float Additive correction; root + correction ≈ sqrt(value + error) to ~1 ulp. + + References + ---------- + Rump, S. M. (2023). Fast and accurate computation of the Euclidean norm + of a vector. Japan Journal of Industrial and Applied Mathematics, 40. + https://doi.org/10.1007/s13160-023-00593-8 """ # Branch-free, matching AccuSphGeom acc_sqrt_re exactly. Negative value # yields nan via math.sqrt and root==0 yields nan via the 0/0 correction,