-
Notifications
You must be signed in to change notification settings - Fork 182
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
Start the addition of the module stdlib_sorting #386
Conversation
Added the draft markdown documentation file, stdlib_sorting.md. [ticket: X]
Removed trailing whitespace from the markdown document, stdlib_sorting.md. [ticket: X]
Added a reference to stdlib_sorting.md to index.md [ticket: X]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice additions. I added a few comments. I am wondering if the subroutines 'ord_sort' and unord_sort should include an option to sort in a decreasing order.
doc/specs/stdlib_sorting.md
Outdated
|
||
The `int_size` parameter is used to specify the kind of integer used | ||
in indexing the various arrays. Currently the module sets `int_size` | ||
to the value of `int64` from the intrinsic `ISO_FORTRAN_ENV` module. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should stdlib_kinds
be used, instead of iso_fortran_env
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I use stdlib_kinds
, but I thought the casual user would be more familiar with iso_fortran_env
.
doc/specs/stdlib_sorting.md
Outdated
The [`rust sort` implementation] | ||
(https://github.com/rust-lang/rust/blob/90eb44a5897c39e3dff9c7e48e3973671dcd9496/src/liballoc/slice.rs) | ||
is distributed with the header: | ||
|
||
Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT | ||
file at the top-level directory of this distribution and at | ||
http://rust-lang.org/COPYRIGHT. | ||
|
||
Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
<LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
option. This file may not be copied, modified, or distributed | ||
except according to those terms. | ||
|
||
so the license for the original code is compatible with the use of | ||
modified versions of the code in the Fortran Standard Library under | ||
the MIT license. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this section be mentioned here, or in a separate section (e.g. entitled "Licences of original codes")?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A separate section seems appropriate.
doc/specs/stdlib_sorting.md
Outdated
... | ||
``` | ||
|
||
#### `ord_sorting` - creates an arry of sorting indices for an input array. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#### `ord_sorting` - creates an arry of sorting indices for an input array. | |
#### `ord_sorting` - creates an array of sorting indices for an input array. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
doc/specs/stdlib_sorting.md
Outdated
* `ORD_SORTING` is intended to provide indices for sorting arrays of | ||
derived type data, based on the ordering of an intrinsic component | ||
of the derived type. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could be used for sorting other things than derived type data.
E.g. to sort an array following one of its column.
real :: a(:,:)
....
call ord_sorting(a(:, 2), index)
a(:,:) = a(index, :)
Am I correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I'll see how I can reword this.
doc/specs/stdlib_sorting.md
Outdated
`array`: shall be a rank one array of any of the types: | ||
`integer(int8)`, `integer(int16)`, `integer(int32)`, `integer(int64)`, | ||
`real(real32)`, `real(real64)`, or `real(real128)`. It is an | ||
`intent(inout)` argument. On input it will be an array whose sorting | ||
indices are to be determined. On return it will be the sorted | ||
array. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if it should be an intent(in)
. If it is an intent(in)
it could be used as follows:
...
real :: a(:, :)
...
cal ord_sorting(a(:, 3), index)
a(:,:) = a(index, ;)
As the API is now defined, such an approach is not possible.
Furthermore, I guess that getting the array sorted is not important when working with derived types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I originally had it as intent(in)
, but then I needed an additional scratch array of the same size as array to store a copy of the original array during all the sorting. The scratch array could either be an allocatable (which makes the code more vulnerable to exceeding the stack size limits), or an optional intent(inout)
argument. Users can still do
...
real :: a(:, :), b(:)
...
b(:) = a(:,3)
call ord_sorting(b(:), index)
a(:,:) = a(index, ;) ! Shouldn't this actually be a do loop?
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you are right. In all cases, an additional array is needed. Therefore, it is good for me as is.
Added a licnsing section. Changed the description of `ORD_SORT`, `ORD_SORTING`, and `UNORD_SORT`. Added more examples for `ORD_SORTING`. Simplified the discussion of `INT_SIZE`. Used `stdlib_kinds` instead of `iso_fortran_env`. Changed `processor` to `compiler`. Fixed spelling of array. [ticket: X]
@wclodius2 I wonder whether the routine ORD_SORTING might be better named ORD_SORT_INDEX (or perhaps ORD_ARGSORT)? To me, this would make the difference with ORD_SORT more obvious. |
I now have three requested changes in the API. Let me know if you have strong preferences.
|
|
type string
character(:), allocatable :: name
end type string to be more useful and easier to implement, but liable to bring up a lot of bikesheding over the details of the definition of
|
Thanks. A few more comments below -- but IMO, all these matters can optionally be addressed with future pull requests, I don't mean to suggest you should do it all in your initial implementation.
I use arrays of Regarding the string type, it seems there is already one in stdlib. It would be most natural for that module to implement the details (perhaps using sufficiently generic routines from this module, if we provide them), since the details will be tied to the particular definition of the string type. In any case, something like
My intuition is that many users will barely read the documentation, and will be drawn to routines with familiar names. If we provide a Did you want me to provide a review at this stage (so you can commit things)? I still need to teach myself the process. Or are you going to append the implementation within this pull request, after there has been enough discussion of the interface? |
You may not mean to suggest that I do it all in the initial implementation, but I don't like doing an incomplete job, and I now consider it incomplete. I definitely think I should add a Adding At 2161 lines, the I can't commit anything. That is the job of designated reviewers. I want the sort of feedback you are giving me, so I have a good idea of the best API before submitting the code to join the PR. |
Great -- but note I've become unsure whether I'm using |
Well I am not a C interoperability expert. I'll follow Fortran Discourse to see what they tell you. |
I think the proposed renaming makes sense. Regarding C's |
I am thinking of dropping the |
I would also prefer to keep the interface to the C I agree with dropping the |
FWIW you can have zero based dummy variables in pure Fortran. It is natural for translating code from other languages. But it is rare enough that I don't think it needs to be supported. |
I had just about finished implementing sorting for |
IMO the version based on Ultimately I think diverse alternatives are best supported by a routine that supports use of a user-specified comparison function (either to sort the data directly, or sort array indices). The |
Added sorting for `character(*)` and `string_type` rank 1 arrays. Improved the overall documentation. Added newer benchmarks for the addiitons and the Intel One API compiler system. [ticket: X]
I have now committed and pushed a revised version of the markdown document |
Very interesting regarding the performance of the From the timing table, it looks like the routine called |
Since |
My understanding is that both To my understanding (see also the plot below which uses timings from the pull request), the difference is that Be good to hear from @wclodius2. But the key point is, assuming that most users will jump to |
@gareth-nx and @jvdp1 I really like the graph, but what it shows can be misleading. Where |
No `unord_sort` is always of order `O(N Ln(N))` it is never of order `O(N**2)`. The difference is that ` order_sort` is of order `O(N Ln(N))` on random data, but can be of order `O(N)` for many types of presorted data. For the size of data sets I have been examining, `2**20`, the factor of `Ln(N)` can be over a factor of ten.
… On Apr 21, 2021, at 1:23 AM, gareth-nx ***@***.***> wrote:
My understanding is that both unord_sort and ord_sort will work in all cases.
To my understanding, the difference is that unord_sort is slightly more optimal for random data, but can be n^2 slow for ordered data. Conversely, ord_sort is pretty good for both random and ordered data. Although it can be slightly slower than unord_sort for random data, it retains an n*log(n) performance in all cases (so even the worst-case performance is not too bad).
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#386 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/APTQDOW2GZUTZGQTRFH6NBDTJZ4Q3ANCNFSM42XGD2MA>.
|
Thanks for the clarifications @wclodius2 -- I now agree that |
The addition of the sorting for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be very enabling for stdlib, thanks.
doc/specs/stdlib_sorting.md
Outdated
`quicksort`, `insertion sort`, and `heap sort`. While this algorithm's | ||
runtime performance is always O(N Ln(N)), it is relatively fast on | ||
randomly ordered data, but inconsistent in performance on partly | ||
sorted data.as the official source of the algorithm. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like a typo here ((data.as
)?
Also, recalling the discussion during review, is it better to say something like "... is relatively fast on randomly ordered data, but does not show a speed improvement on partially sorted data (whereas ord_sort
can give faster performance in partially ordered cases)".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to: "is relatively fast on randomly ordered data, but does not show the improvement in performance on partly sorted data found for ORD_SORT
."
doc/specs/stdlib_sorting.md
Outdated
can show either slower `heap sort` performance, or enhanced | ||
performance by up to a factor of six. Still, even when it shows | ||
enhanced performance, its performance on partially sorted data is | ||
typically an order of magnitude slower than `ORD_SORT`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I suggest mentioning one of the benefits -- flagged during the review -- along the lines that that sort
requires less memory than ord_sort
, and is less likely to exhaust the stack.
It is good to clear regarding the reasons that ord_sort
is not the default (as we previously discussed at #386 (comment)).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added "Its memory requirements are also low, being of order O(Ln(N)), while the memory requirements of ORD_SORT
and SORT_INDEX
are of order O(N)."
doc/specs/stdlib_sorting.md
Outdated
! Concatenate the arrays | ||
allocate( array( size(array1) + size(array2) ) ) | ||
array( 1:size(array1) ) = array1(:) | ||
array( size(array1)+1:size(array1)+size(array2) ) = array2(:) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider simplifying the previous 3 lines of code with array = [array1, array2]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
doc/specs/stdlib_sorting.md
Outdated
##### Description | ||
|
||
Returns an integer array whose elements would sort the input array in | ||
the specified direction retaining order stability. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be emphasised that the argument array
will be returned sorted, e.g. in the text above, Sorts an array, and also returns an integer array whose elements would sort the input array (prior to sorting) in the specified direction retaining order stability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to "Returns the input array
sorted in the direction requested while retaining order stability, and an integer array whose elements would sort the input array
to produce the output array
."
doc/specs/stdlib_sorting.md
Outdated
... | ||
``` | ||
|
||
#### `sort_index` - creates an array of sorting indices for an input array. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest emphasising that the input array is sorted as well -- this surprised me initially when I saw the interface. Something like ... - sorts the input array, and creates an array of sorting indices for the original input array (prior to sorting)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't want a section heading to be too long. Changed to "- creates an array of sorting indices for an input array, while also sorting the array."
!! ! Find the indices to sort a | ||
!! call sort_index(a, index(1:size(a)),& | ||
!! work(1:size(a)/2), iwork(1:size(a)/2)) | ||
!! ! Sort b based on the sorting of a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Emacs sometimes inserts tabs, that can affect the formatting depending on how viewed. I think I have fixed it.
!! | ||
!!```Fortran | ||
!! subroutine sort_related_data( array, column, work, index, iwork ) | ||
!! ! Sort `a_data` in terms or its component `a` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest to replace with ! Reorder rows of
arraysuch that
array(:,column)` is sorted
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This entire example was badly written. Replaced by:
subroutine sort_related_data( array, column, work, index, iwork )
! Reorder rows of `array` such that `array(:, column)` is sorted
integer, intent(inout) :: array(:,:)
integer(int32), intent(in) :: column
integer(int32), intent(inout) :: work(:)
integer(int_size), intent(inout) :: index(:)
integer(int_size), intent(inout) :: iwork(:)
integer, allocatable :: dummy(:)
integer :: i
allocate(dummy(size(array, dim=1)))
! Extract a column of `array`
dummy(:) = array(:, column)
! Find the indices to sort the column
call sort_index(dummy, index(1:size(dummy)),&
work(1:size(dummy)/2), iwork(1:size(dummy)/2))
! Sort a based on the sorting of its column
do i=1, size(array, dim=2)
array(:, i) = array(index(1:size(array, dim=1)), i)
end do
end subroutine sort_related_data
!! Sorting an array of a derived type based on the dsta in one component | ||
!!```fortran | ||
!! subroutine sort_a_data( a_data, a, work, index, iwork ) | ||
!! ! Sort `a_data` in terms or its component `a` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Similar comment as previous -- mention that a
is also sorted on return -- or alternatively consider making a
a local variable in the subroutine).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Example entirely rewritten - see above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I misread your comment. You missed a typo in "dsta". The quote was changed to
Sorting an array of a derived type based on the data in one component
subroutine sort_a_data( a_data, a, work, index, iwork )
! Sort `a_data` in terms or its component `a` also sorting `a`.
#:for k1 in INT_KINDS | ||
|
||
module subroutine ${k1}$_sort_index( array, index, work, iwork, reverse ) | ||
! A modification of `${k1}$_ord_sort` to return an array of indices that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggest mentioning that it also sorts array
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to see someone start to review the module files.
Changed to
! A modification of ${k1}$_ord_sort
to return an array of indices that
! would perform a stable sort of the ARRAY
as input, and also sort ARRAY
! as desired. The indices by default
Note I didn't try to change subsequent lines to maintain a consistent column width. Also changed the comments for the other versions of `SORT_INDEX'.
end subroutine char_sort_index | ||
|
||
module subroutine string_sort_index( array, index, work, iwork, reverse ) | ||
! A modification of `string_ord_sort` to return an array of indices that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Include mention that is also sorts the input array
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done as noted above.
Changed the markdown document docs/specs/stdlib_sorting.md to correct problems noted by gareth_nx. Changed comments in the FYPP file src/stlib_sorting_sort_index.fypp to note that the input array is sorted on output. [ticket: X]
Forgot to save an edit prior to the previous commit of docs/specs/stdlib_sorting.md. Saved and commited that edit. [ticket: X]
Review-dog caught several misspellings in the comments of the source codes. [ticket: X]
In the
To me this somewhat too specific, because a derived type need not be involved. Also I suggest noting that the input array is still sorted. Consider something like this:
|
Related to my comment above, in
I suggest editing the end of the last sentence of the above paragraph to be "....that generates such an array of |
Modified doc/specs/index.md so it mentioned stdlib_sorting.md. [ticket: X]
I have committed and pushed the related changes:
"....that generates such an array of indices based on the ORD_SORT |
Added changes in the description of `SORT_INDEX`. [ticket: X]
Great idea to add sorting to the library! Some basic sorting intrinsics should have been added to Fortran decades ago. The old High Performance Fortran (i.e., http://hpff.rice.edu/versions/hpf2/hpf-v20.pdf) had specs for HPF intrinsic functions SORT_UP, SORT_DOWN, GRADE_UP, and GRADE_DOWN. Note that these were defined as functions, not subroutines, so that they can be used in expressions. As an old APL programmer, it seems natural to have functional forms of the sorts. FWIW, I generally just use a version of the LAPACK SLASRT subroutine for the actual sort algorithm. I've 'templated' it using the macro capabilities of the C preprocessor to support various data types - including character(*), reals, and integers. Not sure how it compares with the timsort and other rust-inspired algorithms you've used yet. I need to learn about fypp, and recoding my SLASRT-based code will be a good start. I noticed some comments above about using some glue to call C qsort. The C qsort suffers from invoking the user-defined comparison routine through a procedure pointer. The C++ STL 'sort' is much better than qsort because it inlines the user-defined comparison code. But the SLASRT code was even faster yet - last time I checked. |
Making them functions would increase memory requirements. SLASRT is a quicksort routine using insertion sort only for small arrays. It will have performance problems for significantly presorted data. |
I appreciate your thoughts. When I've tested performance, I typically used pseudo-random numbers. E.g., what the built-in RANDOM_NUMBER intrinsic provides. So other cases, like the significantly presorted data you mention, could certainly differ. Another suggestion for eventual inclusion in stdlib are grade up/down versions - which output an integer permutation array rather than the sorted values. Could also be done via an optional output argument. The permutation array would allow easy use with derived types, assuming a single key, without needing user-supplied comparison function (like the C qsort and C++ STL sort do). In fact Iversons original APL spec only had grade up/down operators. Sort up/down were added later. Same with HPF 1.0 vs HPF 2.0. |
How do |
Please correct me if I'm wrong, but it appears that sort_index() routine returns both the sorted values and the index array. For an array of derived types, one often wants just the index array. E.g., one could write something like: type mydata_t With the sort_index(), the array argument has intent(inout) - which means that in the above case, the keys would be rearranged, but the associated data would not. The caller would need to explicitly make a temporary key array before calling sort_index(). |
A simple case of sorting a derived type would be clearly written: mydata = mydata(grade_up (mydata%key)) It is totally safe because the indicies returned by grade_up are unique from one another. |
I had problems with stack overflow with my codes, so I have emphasized minimizing memory use. I use a Mac for my testing, and on a Mac the maximum stack size is 64 Mbytes. I did my testing on arrays with
|
LOL! Yeah - linux defaults to 8 mb stack size limit per process. I set my stack limit to default to unlimited a very long time ago... Both gfortran and Intel Fortran have compiler options to set a threshold whether to place temporaries on the stack or the heap - including all on the heap. PGI might. I don't think NAG did. Obviously if one sets the default to place everything on the heap, the resulting increase in malloc/free calls could hurt performance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here are already some comments on the specs. I willl review the code ASAP
randomly ordered data, but does not show the improvement in | ||
performance on partly sorted data found for `ORD_SORT`. | ||
|
||
As with `introsort`, `SORT` is an unstable hybrid algorithm. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sentence could be removed, because already mentioned at L156-160.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
||
# The `stdlib_sorting` module | ||
|
||
(TOC) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(TOC) | |
[TOC] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
||
## Overview of the module | ||
|
||
The module `stdlib_sorting` defines several public entities one |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The module `stdlib_sorting` defines several public entities one | |
The module `stdlib_sorting` defines several public entities, one |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
* `ORD_SORT` is intended to sort simple arrays of intrinsic data | ||
that have significant sections that were partially ordered before | ||
the sort; | ||
* `SORT_INDEX` is based on ORD_SORT, but in addition to sorting the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* `SORT_INDEX` is based on ORD_SORT, but in addition to sorting the | |
* `SORT_INDEX` is based on `ORD_SORT`, but in addition to sorting the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
`ORD_SORT` begins by traversing the array starting in its tail | ||
attempting to identify `runs` in the array, where a run is either a | ||
uniformly decreasing sequence, `ARRAY(i-1) > ARRAY(i)`, or a | ||
non-decreasing, `ARRAY(i-1) <= ARRAY(i)`, sequence. Once delimitated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
non-decreasing, `ARRAY(i-1) <= ARRAY(i)`, sequence. Once delimitated | |
non-decreasing, `ARRAY(i-1) <= ARRAY(i)`, sequence. First delimitated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
! Process the sorted array | ||
call array_search( array, values ) | ||
... | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
``` | |
```fortran | |
program demo_ord_sort | |
use stdlib_sorting, only: ord_sort | |
implicit none | |
integer, allocatable :: array1(:), work(:) | |
array1 = [ 5, 4, 3, 1, 10, 4, 9] | |
allocate(work, mold = array1) | |
call ord_sort(array1, work) | |
print*, array1 !print [1, 3, 4, 4, 5, 9, 10] | |
end program demo_ord_sort | |
``` |
suggestion: a small program that could be copyied/pasted, and compiled
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
||
##### Example | ||
|
||
```fortran |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As for the previous example, I suggest to treplace this example by a small demo program.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Co-authored-by: Jeremie Vandenplas <[email protected]>
Co-authored-by: Jeremie Vandenplas <[email protected]>
Co-authored-by: Jeremie Vandenplas <[email protected]>
I made a mistake. I updated my local copy while also accepting some of Jeremy's suggestions, so my local copy is inconsistent with that in this repository. I am not an expert on GIT. How do I merge the repository with my local copy? |
I'm also not a git expert, but would try doing: Then I would use |
After the merge, I have wound up with a new branch at #408. |
@wclodius2 for clarity, I will close this PR in favour of #408 |
Added the draft markdown documentation file, stdlib_sorting.md.
[ticket: X]