Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
aab4469
added argsort function and tests
Oct 1, 2023
95ce904
added argsort function and tests
Oct 1, 2023
9344b04
Merge branch '777-Implement_argsort' of https://github.com/helmholtz-…
Oct 4, 2023
ba90f48
fixed small issue in test
Oct 4, 2023
23828d6
Merge branch 'main' into 777-Implement_argsort
mrfh92 Oct 5, 2023
67b27b9
Merge branch 'main' into 777-Implement_argsort
mrfh92 Oct 11, 2023
ec223e6
Merge branch 'main' into 777-Implement_argsort
mrfh92 Oct 13, 2023
3742fc8
Merge branch 'main' into 777-Implement_argsort
ClaudiaComito Jan 22, 2024
6169f75
Merge remote-tracking branch 'origin/main' into 777-Implement_argsort
Berkant03 Jul 14, 2026
2854dd2
- Changed Sort and Argsort to mirror numpy api.
Berkant03 Jul 16, 2026
6861852
Fixed Split Advanced indexing error on the argsort test
Berkant03 Jul 16, 2026
2108319
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 16, 2026
c3aa612
- added warning for ignored arguments instead of ignoring.
Berkant03 Jul 20, 2026
909517d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 20, 2026
122d3d0
added ignore warning to argsort
Berkant03 Jul 21, 2026
100c377
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 21, 2026
3c92d55
Merge branch 'main' into 777-Implement_argsort
Berkant03 Jul 22, 2026
f23bcf3
Apply suggestion from @brownbaerchen
brownbaerchen Jul 27, 2026
09063e8
Added info for ignored parameters in the docstring of `sort` and `arg…
Berkant03 Jul 27, 2026
8a6ae4d
Merge branch 'main' into 777-Implement_argsort
Berkant03 Jul 27, 2026
aafd823
changed first portion of `argsort` tests to use random data
Berkant03 Jul 28, 2026
2f5f7c6
Merge branch 'main' into 777-Implement_argsort
Berkant03 Jul 28, 2026
df9ca0a
Added test for `sort, and added more parameter combinations for `sort…
Berkant03 Jul 29, 2026
0cff903
Merge branch 'main' into 777-Implement_argsort
Berkant03 Jul 29, 2026
1d759ec
- Created own class for sorting testing.
Berkant03 Aug 3, 2026
bbfee73
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 3, 2026
c174bb6
Merge branch 'main' into 777-Implement_argsort
Berkant03 Aug 3, 2026
937d551
Use version class on str for comparison
Berkant03 Aug 3, 2026
02e5982
- Removed descending parameter check.
Berkant03 Aug 3, 2026
12bd457
- Changed chosen device to the one described by the environmental var…
Berkant03 Aug 3, 2026
5ea6dd9
Changed device selection
Berkant03 Aug 3, 2026
125a3da
Update tests/core/test_sorting.py
Berkant03 Aug 3, 2026
c79c8f2
Changed descending keyword behaviour in older numpy versions.
Berkant03 Aug 3, 2026
cb89eb0
Merge branch 'main' into 777-Implement_argsort
Berkant03 Aug 4, 2026
91802fd
removed specific test for `argsort`
Berkant03 Aug 4, 2026
a186796
Merge branch 'main' into 777-Implement_argsort
Berkant03 Aug 4, 2026
e3072e3
Merge branch 'main' into 777-Implement_argsort
brownbaerchen Aug 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 97 additions & 3 deletions heat/core/manipulations.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from . import _operations

__all__ = [
"argsort",
"balance",
"broadcast_arrays",
"broadcast_to",
Expand Down Expand Up @@ -65,6 +66,69 @@
]


def argsort(
a: DNDarray,
axis: int = -1,
kind: str | None = None,
order: str | list[str] | None = None,
*,
stable: bool | None = None,
descending: bool | None = None,
) -> DNDarray:
"""
Returns the indices that would sort an array. This is the distributed equivalent of `np.argsort`.
The sorting is not stable which means that equal elements in the result may have a different ordering than in the
original array.
Sorting where `axis==a.split` needs a lot of communication between the processes of MPI.
Comment thread
brownbaerchen marked this conversation as resolved.
Outdated

Parameters
----------
a : DNDarray
Input array to be sorted.
axis : int, optional
The dimension to sort along.
Default is the last axis.
kind : str, optional
Sorting algorithm. Gets ignored.
order : str, list[str], optional
Used in numpy for array with fields, which are not possible in HeAT. Gets ignored.
Comment thread
Berkant03 marked this conversation as resolved.
Outdated
stable : bool, optional
Sort stability, currenty not supported.
descending : bool, optional
If set to `True`, indices are sorted in descending order.

Raises
------
ValueError
If `axis` is not consistent with the available dimensions.

Examples
--------
>>> x = ht.array([[4, 1], [2, 3]], split=0)
>>> x.shape
(1, 2)
(1, 2)
>>> y = ht.argsort(x, axis=0)
>>> y
(array([[1, 0],
[0, 1]]))
>>> ht.argsort(x, descending=True)
(array([[0, 1],
[1, 0]]))
"""
_, indices = sort(
a=a,
axis=axis,
kind=kind,
order=order,
stable=stable,
descending=descending,
out=None,
return_sort_indices=True,
)
return indices


def balance(array: DNDarray, copy=False) -> DNDarray:
"""
Out of place balance function. More information on the meaning of balance can be found in
Expand Down Expand Up @@ -2549,7 +2613,17 @@ def shape(a: DNDarray) -> Tuple[int, ...]:
return a.gshape


def sort(a: DNDarray, axis: int = -1, descending: bool = False, out: Optional[DNDarray] = None):
def sort(
a: DNDarray,
axis: int = -1,
kind: str | None = None,
order: str | list[str] | None = None,
*,
stable: bool | None = None,
descending: bool | None = False,
out: Optional[DNDarray] = None,
return_sort_indices: bool | None = None,
):
"""
Sorts the elements of `a` along the given dimension (by default in ascending order) by their value.
The sorting is not stable which means that equal elements in the result may have a different ordering than in the
Expand All @@ -2564,11 +2638,20 @@ def sort(a: DNDarray, axis: int = -1, descending: bool = False, out: Optional[DN
axis : int, optional
The dimension to sort along.
Default is the last axis.
kind : str, optional
Sorting algorithm. Gets ignored.
order : str, list[str], optional
Used in numpy for array with fields, which are not possible in HeAT. Gets ignored.
stable : bool, optional
Sort stability, currenty not supported.
Comment thread
Berkant03 marked this conversation as resolved.
Outdated
descending : bool, optional
If set to `True`, values are sorted in descending order.
out : DNDarray, optional
A location in which to store the results. If provided, it must have a broadcastable shape. If not provided
or set to `None`, a fresh array is allocated.
return_sort_indices: bool, optional
Wether to return the indices by which the array was sorted.
If ``out`` is provided, returns the indices if ``True``, otherwise ``None``.

Raises
------
Expand Down Expand Up @@ -2597,6 +2680,13 @@ def sort(a: DNDarray, axis: int = -1, descending: bool = False, out: Optional[DN
)
stride_tricks.sanitize_axis(a.shape, axis)

if axis is None:
a = flatten(a)
axis = 0

descending = descending or False
return_sort_indices = return_sort_indices or False
Comment thread
brownbaerchen marked this conversation as resolved.
Outdated

if not a.is_distributed() or axis != a.split:
# sorting is not affected by split -> we can just sort along the axis
final_result, final_indices = torch.sort(a.larray, dim=axis, descending=descending)
Expand Down Expand Up @@ -2807,12 +2897,16 @@ def sort(a: DNDarray, axis: int = -1, descending: bool = False, out: Optional[DN
)
if out is not None:
out.larray = final_result
return return_indices
if return_sort_indices:
return return_indices
return None
else:
tensor = factories.array(
final_result, dtype=a.dtype, is_split=a.split, device=a.device, comm=a.comm
)
return tensor, return_indices
if return_sort_indices:
return tensor, return_indices
return tensor


def split(x: DNDarray, indices_or_sections: Iterable, axis: int = 0) -> List[DNDarray, ...]:
Expand Down
5 changes: 3 additions & 2 deletions heat/core/statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -1543,7 +1543,8 @@ def _create_sketch(

# create a random sample of indices
indices = manipulations.sort(
randint(0, a.shape[axis], sketch_size, device=a.device, dtype=types.int64)
randint(0, a.shape[axis], sketch_size, device=a.device, dtype=types.int64),
return_sort_indices=True,
)[0]
sketch = a.swapaxes(0, axis)
sketch = a[indices, ...].resplit_(None)
Expand Down Expand Up @@ -1697,7 +1698,7 @@ def _create_sketch(
)

# sort data
sorted_x, _ = manipulations.sort(x, axis=axis)
sorted_x, _ = manipulations.sort(x, axis=axis, return_sort_indices=True)
del _
sorted_x = sorted_x.astype(output_dtype)

Expand Down
4 changes: 3 additions & 1 deletion heat/utils/data/matrixgallery.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,9 @@ def random_known_rank(
raise RuntimeError("rank must not exceed matrix dimensions.")

singular_values = rand(r, dtype=dtype, comm=comm, device=device)
singular_values = sort(quantile_function(singular_values), descending=True)[0]
singular_values = sort(
quantile_function(singular_values), descending=True, return_sort_indices=True
)[0]

return random_known_singularvalues(
m, n, singular_values, split=split, device=device, comm=comm, dtype=dtype
Expand Down
Loading
Loading