Support vector-valued UxDataArrays in vector calculus operations
Maintainer thường phản hồi trong vòng 4 ngày
@Sevans711 đang làm issue này rồi.
Từ ngày 6/11/2026.
Đánh giá
Issue này chưa được đánh giá.
Mô tả
Attempting to solve #1878 by implementing vector calculus methods into UxDataset directly from their current form raises lots of questions:
- gradient() outputs a UxDataset already, with "zonal_gradient" and "meridional_gradient" data vars. So:
- (1a) What should ds.gradient() look like?
- (1b) If ds has data vars "T", "P", should the result have twice as many vars, something like "T_zonal_gradient", "T_meridional_gradient", "P_zonal_gradient", "P_meridional_gradient"?
- (1c) Or, should the output be two UxDataArrays, one with zonal gradients and the other with meridional gradients?
- curl(), divergence(), and scalardotgradient() take the zonal and meridional components as separate input arrays. So:
- (2a) What would ds.curl() mean?
- (2b) Or, should the API look like u_ds.curl(v_ds) instead, where u_ds is a dataset of zonal components and v_ds is a dataset of meridional components?
- (2c) Should uxarray allow u_ds.curl(v) where v is a single UxDataArray, and/or u.curl(v_ds)?
- (2d) How can one unambiguously provide the scalar field
qinto a call to ds.scalardotgradient()?
Instead of answering these questions directly, this issue focuses on proposing a new option for existing vector calculus methods that would remove the need to ever answer most/all of these design questions in the first place.
Proposal
My proposed solution is to add an option throughout the UxDataArray vector calculus methods which allows utilizing arrays with zonal and meridional components are stacked together into a single array with a vector dimension, instead of forcing them to be treated separately. For example, one could provide a wind array stacked along a "component" dimension, instead of two separate arrays for wind_zonal and wind_meridional. This option could be implemented in a way which is fully backwards compatible; here is a rough sketch:
def gradient(self, scale_by_radius=True, *, vector_dim=None):
"""returns a UxDataset with "zonal_gradient" and "meridional_gradient" data vars.
If vector_dim is provided, instead return a UxDataArray,
with zonal and meridional results stacked along this dim."""
# ...
def curl(self, other=None, scale_by_radius=True, *, vector_dim="component"):
"""returns a UxDataArray telling curl(self, other).
If other is None, self must contain vector_dim with "zonal" and "meridional" coords;
zonal and meridional components will be inferred as self.sel({vector_dim: "zonal"})
and self.sel({vector_dim: "meridional"})."""
# ...
def divergence(self, other=None, scale_by_radius=True, *, vector_dim="component"):
# similar to curl()
For scalardotgradient, I would maybe not add an option like this at all, due to a bit of ambiguity / reduced benefits due to the additional scalar field input. Also, when utilizing the "stack along vector dimension" option, the arithmetic of the scalardotgradient functionality becomes an extremely simple one-liner anyway: wind.sel(component="zonal").scalardotgradient(wind.sel(component="meridional"), q) can be expressed simply as (wind * q.gradient()).sum("component").
This option would make it easy to add a UxDataset implementation in #1873 because it changes the inputs/outputs to always be a single UxDataArray, like "UxDataArray --> UxDataArray" for gradient, curl, and divergence. (As opposed to their current inputs/outputs, which look like "UxDataArray --> UxDataset" for gradient, and "(UxDataArray, UxDataArray) --> UxDataArray" for curl and divergence.)
Additional Benefits
I noticed these points of friction a while ago but hadn't created an issue report because they aren't necessarily convincing enough on their own to fully warrant maintaining a new feature / alternative syntax. But, they would come along with this new feature for free:
- Users who use vector_dim no longer need to remember the special names "zonal_gradient" and "meridional_gradient" for the data vars output by gradient()
- Users who use vector_dim no longer have any chance to accidentally swap the argument order for something like A.curl(B).
- It becomes easier to chain operators together, such as in the scalardotgradient example above. Another example could be a drop-in replacement for the Laplacian like
T.gradient(vector_dim="component").divergence(). The equivalent syntax users currently have available to them looks like:g = T.gradient(); g["zonal_gradient"].divergence(g["meridional_gradient"]).
Misc. notes
There is some xarray precedent for having a dimension be "the vector dimension" such as in xr.cross(a, b, dim=...) which computes cross products along a named component dimension which the inputs must be stacked along (e.g. a is really a_x, a_y, a_z stacked along dim).
Maybe some day the default for gradient() might shift to be to output a single UxDataArray along the vector_dim, and the default vector_dim could be component, but that would require a deprecation cycle, might not be desired, and is out of scope for this issue.
AI disclosure: The proposal here looks very close to my initial thoughts on the topic, but I did work through ideas extensively with Claude (Opus 5.5), including various possible alternatives and figuring out which pieces to highlight here, with the goal of narrowing in on a proposal that is most likely to be appealing to the uxarray dev team, based on my understanding of team preferences. I wrote up this issue report myself; it's long because there is a lot of content, not due to extra verbose AI rambling.
- Ngôn ngữ chính
- Python
- Star
- 232
- Fork
- 59
- Merge trung bình
- 5 ngày 21 giờ
- Pull request đã merge (30 ngày)
- 19
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của UXARRAY/uxarray
-
ux.open_dataset currently supports structured dataCó thể đã có người làm @Sevans711 đã nhận 9 ngày trước. Đang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
UXARRAY/uxarray#1854 · 2 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 4 ngày
-
developer experience
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 90/100
Maintainer thường phản hồi trong vòng 4 ngày
-
zonal_mean() and weighted_mean() should return the same type of objectCó thể làm lại được @Sevans711 đã nhận 47 ngày trước và không có pull request nào đang mở. Đang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
UXARRAY/uxarray#1733 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 4 ngày
-
documentation
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
Maintainer thường phản hồi trong vòng 4 ngày
-
Implement UxDataArray vector calculus methods on UxDatasetCó thể đã có người làm @Sevans711 đã nhận hôm nay. Đang mởnew feature
UXARRAY/uxarray#1878 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 4 ngày
Tất cả issue của UXARRAY/uxarray
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
aws-samples/sample-per-model-bedrock#795 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Pretalx reports older version to be the latest release than what is actually installed and availableĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
micropython/micropython#19906 ·
Maintainer thường phản hồi trong vòng 1 ngày