Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: improved Geometry.sort, for #191 #197

Merged
merged 12 commits into from
Apr 3, 2020
Merged

WIP: improved Geometry.sort, for #191 #197

merged 12 commits into from
Apr 3, 2020

Conversation

zerothi
Copy link
Owner

@zerothi zerothi commented Apr 1, 2020

This change allows very complicated sort calls.

  • ascending/descending along lattice vectors
  • ascending/descending along Cartesian coordinates
  • ascending/descending along a vector
  • external function to sort indices
  • species
  • group labelling
  • combinations (e.g. first species, then axes), this is particularly easy since Python >=3.6 uses ordered dicts for **kwargs, so sort should change interface to **kwargs
  • the above on a subset of atoms

All sorts are now chained (much like lexsort).
One can now do

geom.sort(axis=0, lattice=0, axis1=1)

to first sort Cartesian x, then for each subgroup in this
sort according to first lattice vector, then for each subgroup
sort according to Cartesian y.

Note how axis1 allows numeric flags to allow multiple same
sorting algorithms for the same (to achieve different order
of sort).
One can also add ascending/descending

geom.sort(axis=0, ascend=False, lattice=1, ascend=True, axis=1)

to ascend-sort x, descend-sort fa, ascend-sort y.

Also added preliminary support for sort in sgeom.

@tfrederiksen could you please have a look

@zerothi
Copy link
Owner Author

zerothi commented Apr 1, 2020

species/groups to come

@zerothi zerothi self-assigned this Apr 1, 2020
@zerothi zerothi mentioned this pull request Apr 1, 2020
6 tasks
@codecov
Copy link

codecov bot commented Apr 1, 2020

Codecov Report

Merging #197 into master will increase coverage by <.01%.
The diff coverage is 74.63%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #197      +/-   ##
==========================================
+ Coverage   85.23%   85.24%   +<.01%     
==========================================
  Files         120      120              
  Lines       19130    19338     +208     
==========================================
+ Hits        16306    16484     +178     
- Misses       2824     2854      +30
Impacted Files Coverage Δ
sisl/geometry.py 86.15% <74.63%> (-1.15%) ⬇️
sisl/physics/electron.py 88.75% <0%> (ø) ⬆️
sisl/orbital.py 98.39% <0%> (+1.51%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a0da8c8...7209fbd. Read the comment docs.

Copy link
Contributor

@tfrederiksen tfrederiksen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! I have only some minor comments on the documentation.

sisl/geometry.py Outdated Show resolved Hide resolved
sisl/geometry.py Show resolved Hide resolved
sisl/geometry.py Outdated
Comment on lines 1161 to 1168
A too high `atol` may have unexpected side-effects. This is because of the way
the sorting algorithm splits the sections for nested sorting.
So for coordinates with a continuous displacement the sorting may break and group
a large range into 1 group.

>>> a = np.arange(5) * 0.1
>>> (np.diff(a) > 0.05).nonzero()[0]
[0, 1, 2, 3]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I do not follow this example with the a array. Can you be more explicit how it relates to the atol discussion?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to add a more reasonable explanation...

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tfrederiksen does it make sense now?

sisl/geometry.py Outdated Show resolved Hide resolved
sisl/geometry.py Show resolved Hide resolved
@tfrederiksen
Copy link
Contributor

Note that in your opening comment this line

geom.sort(axis=0, ascend=False, lattice=1, ascend=True, axis=1)

has a clash of the repeated argument axis.

@zerothi
Copy link
Owner Author

zerothi commented Apr 2, 2020

Could you have a look again, the atol is a bit difficult to explain, for instance it would be really difficult for the sort algorithm to do a splitting of groups in twisted bilayers since there coordinates are continuous.
Using numpy lexsort forces values to be unique, my implementation does not impose this. The reason is that typically when rotating geometries one will get very tiny differences ~1e-15 which then breaks lexsort. I try to avoid this by not doing anything to coordinates that are continuously closer than atol.

For coordinates [0.1, 0.2, 0.3] and a tolerance of 0.05 one would have to split all into groups, whereas for 0.15 one could not split. One could then argue that one should split into either [0.1, 0.2] + [0.3] or [0.1] + [0.2, 0.3] but this is rather non-trivial...

@tfrederiksen
Copy link
Contributor

Why is sgeom in.xyz --sort "axis=2;axis=1" out.xyz allowed? It appears to me that it is not generating a clash of repeated argument?

Also, with sgeom in.xyz --sort "descend;axis=2;axis=1" out.xyz it seems that both axes are sorted descending (not just the first).

@zerothi
Copy link
Owner Author

zerothi commented Apr 2, 2020

Why is sgeom in.xyz --sort "axis=2;axis=1" out.xyz allowed? It appears to me that it is not generating a clash of repeated argument?

This is because I always append an integer to keywords (so users can do what you do ;))

Also, with sgeom in.xyz --sort "descend;axis=2;axis=1" out.xyz it seems that both axes are sorted descending (not just the first).

Yes, this is by design. Any keyword has precedence until changed. The updated documentation should reflect this. So one have to disable it again, if one does not want this.

@tfrederiksen
Copy link
Contributor

Very cool! Now I notice that indeed you write "sorting for all subsequent sorting methods" in the documentation. So the user can also do this in a script geom.sort(descend=True, axis=2, axis1=1) and achieve the same as in my sgeom command above.

@zerothi
Copy link
Owner Author

zerothi commented Apr 2, 2020

Very cool! Now I notice that indeed you write "sorting for all subsequent sorting methods" in the documentation. So the user can also do this in a script geom.sort(descend=True, axis=2, axis1=1) and achieve the same as in my sgeom command above.

Yes :)

@zerothi
Copy link
Owner Author

zerothi commented Apr 2, 2020

@tfrederiksen I have now added the remaining sortings, currently you cannot do the complicated groupings on the CLI, then one have to parse to a tuple...

You can however do the simple stuff, like doing sgeom ... --sort "group=Z", but not with optional arguments...

Copy link
Contributor

@tfrederiksen tfrederiksen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beautiful!

sisl/geometry.py Show resolved Hide resolved
sisl/geometry.py Outdated Show resolved Hide resolved
CHANGELOG Outdated Show resolved Hide resolved
sisl/geometry.py Show resolved Hide resolved
This change allows very complicated sort calls.
All sorts are now chained (much like lexsort).
One can now do

   geom.sort(axis=0, lattice=0, axis1=1)

to first sort Cartesian x, then for each subgroup in this
sort according to first lattice vector, then for each subgroup
sort according to Cartesian y.

Note how axis1 allows numeric flags to allow multiple same
sorting algorithms for the same (to achieve different order
of sort).
One can also add ascending/descending

   geom.sort(axis=0, ascend=False, lattice=1, ascend=True, axis=1)

to ascend-sort x, descend-sort fa, ascend-sort y.

Also added preliminary support for sort in sgeom.

Signed-off-by: Nick Papior <nickpapior@gmail.com>
Now users can sort along a projection vector.
This will generally not be equivalent to lattice sorting
for vectors equal to lattice vectors. Only when a lattice
vector is orthogonal to the others will this be true.

Signed-off-by: Nick Papior <nickpapior@gmail.com>
Mainly for clarity for users

Signed-off-by: Nick Papior <nickpapior@gmail.com>
Signed-off-by: Nick Papior <nickpapior@gmail.com>
Signed-off-by: Nick Papior <nickpapior@gmail.com>
Signed-off-by: Nick Papior <nickpapior@gmail.com>
Signed-off-by: Nick Papior <nickpapior@gmail.com>
…geometry

A user defined atom argument did not preserve all atoms in the geometry.
It now ensures that user requested atoms are sorting between them selves.
All others are left untouched. I.e. sorting atom=[0, 10] will either
swap 0 and 10, or do nothing.

Enabled user defined functions for sorting the geometry.

Signed-off-by: Nick Papior <nickpapior@gmail.com>
Signed-off-by: Nick Papior <nickpapior@gmail.com>
Sorting now allows grouping of atoms. There are 4 different
groupings, Z, tag, species, symbol.
This is controlled by group=str or group=(str, ...)

where str is one of the "groupings" and ... is a list
or list of lists with items that may be grouped together.
Optionally may one of these items be None in which case
it will be filled with the *rest* of the allowable searchable
items.

For instance

     geom.sort(group=('symbol', None, 'C'))

first groups all non C atoms, then all C atoms.

Signed-off-by: Nick Papior <nickpapior@gmail.com>
Signed-off-by: Nick Papior <nickpapior@gmail.com>
Signed-off-by: Nick Papior <nickpapior@gmail.com>
@zerothi zerothi merged commit fd7c041 into master Apr 3, 2020
@zerothi zerothi deleted the 191-sort branch April 3, 2020 12:07
@zerothi
Copy link
Owner Author

zerothi commented Apr 3, 2020

It is in ;)

@tfrederiksen tfrederiksen mentioned this pull request Apr 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants