<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Approximatrix Forums — Merge Sort Routine]]></title>
	<link rel="self" href="https://forums.approximatrix.com/extern.php?action=feed&amp;tid=791&amp;type=atom" />
	<updated>2020-12-22T14:19:55Z</updated>
	<generator>PunBB</generator>
	<id>https://forums.approximatrix.com/viewtopic.php?id=791</id>
		<entry>
			<title type="html"><![CDATA[Re: Merge Sort Routine]]></title>
			<link rel="alternate" href="https://forums.approximatrix.com/viewtopic.php?pid=3656#p3656" />
			<content type="html"><![CDATA[<p>Frank,</p><p>I keep meaning to spend some time trying this out!&nbsp; Sorry I&#039;ve been quiet!</p>]]></content>
			<author>
				<name><![CDATA[jeff]]></name>
				<uri>https://forums.approximatrix.com/profile.php?id=2</uri>
			</author>
			<updated>2020-12-22T14:19:55Z</updated>
			<id>https://forums.approximatrix.com/viewtopic.php?pid=3656#p3656</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Merge Sort Routine]]></title>
			<link rel="alternate" href="https://forums.approximatrix.com/viewtopic.php?pid=3653#p3653" />
			<content type="html"><![CDATA[<p>Revised and updated FPSort that&#039;s faster than the previous post using pointers and reducing the size of the working array during the search.&nbsp; FPSort can sort in both ascending and descending order.</p><p>Happy Holidays,<br />Dr.Frank</p><p>Fortran Listing:</p><p>&nbsp; &nbsp; MODULE FPSort_module<br />&nbsp; &nbsp; IMPLICIT NONE</p><p>&nbsp; &nbsp; PRIVATE</p><p>&nbsp; &nbsp; PUBLIC :: FPSort</p><p>&nbsp; &nbsp; INTERFACE FPSort<br />&nbsp; &nbsp; &nbsp; &nbsp; MODULE PROCEDURE FPSort<br />&nbsp; &nbsp; END INTERFACE</p><p>&nbsp; &nbsp; CONTAINS</p><p>&nbsp; &nbsp; FUNCTION FPSort( Array, bFlag ) RESULT( sorted )<br />&nbsp; &nbsp; &nbsp; &nbsp; !---------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; !---&nbsp; &nbsp; FPSort version 2.0<br />&nbsp; &nbsp; &nbsp; &nbsp; !---&nbsp; &nbsp; (Four-times faster than a bubble sort of random numbers)<br />&nbsp; &nbsp; &nbsp; &nbsp; !---<br />&nbsp; &nbsp; &nbsp; &nbsp; !---&nbsp; &nbsp; Developed by F.W. Perrella, Ph.D.&nbsp; December 13, 2020<br />&nbsp; &nbsp; &nbsp; &nbsp; !---&nbsp; &nbsp; Silver Spring, Maryland U.S.A.<br />&nbsp; &nbsp; &nbsp; &nbsp; !---------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; ! NAME:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;FPSort<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; ! PURPOSE:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;Sorts a numeric array in ascending or descending order.<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; ! MODULE:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;nrType: Definition for kind variable types.<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;INTEGER, PARAMETER :: I4B = KIND(9)<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;INTEGER, PARAMETER :: DP = SELECTED_REAL_KIND(15, 200)<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !---------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; CALLING SEQUENCE:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; Result = FPSort( Array,bFlag )<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; INPUT ARGUMENTS:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; Array: Real array of numbers to sort<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; TYPE:&nbsp; REAL( KIND = Double )<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; bFlag: .TRUE.= Ascending sort, .FALSE.= Descending sort<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; TYPE:&nbsp; LOGICAL<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; FUNCTION RESULT:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; TYPE:&nbsp; &nbsp; Real( Double )<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; RESULT: Real array of values sorted (Ascending,Descending)<br />&nbsp; &nbsp; &nbsp; &nbsp; !---------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; FPSort:<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; Random numbers =521<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; average time=&nbsp; &nbsp;0.0000<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; Random numbers =1034<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; average time=&nbsp; &nbsp;0.0000<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; Random numbers =2059<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; average time=&nbsp; &nbsp;0.001563<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; Random numbers =4108<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; average time=&nbsp; &nbsp;0.004688<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; Random numbers =8205<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; average time=&nbsp; &nbsp;0.02656&nbsp; &nbsp; (x3.9 faster than Bubble Sort)<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; Random numbers =16398<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; average time=&nbsp; 0.1016&nbsp; &nbsp; &nbsp; (x4.1 faster than Bubble Sort)<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; Random numbers =32783<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; average time=&nbsp; 0.3906&nbsp; &nbsp; &nbsp; (x4.4 faster than Bubble Sort)<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; Random numbers =65552<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; average time=&nbsp; &nbsp;1.4547&nbsp; &nbsp; &nbsp;(x4.1 faster than Bubble Sort)<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !---------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; USE nrtype<br />&nbsp; &nbsp; &nbsp; &nbsp; IMPLICIT NONE<br />&nbsp; &nbsp; &nbsp; &nbsp; LOGICAL(LGT), INTENT(IN)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :: bFlag<br />&nbsp; &nbsp; &nbsp; &nbsp; REAL(DP), DIMENSION(:), INTENT(IN)&nbsp; :: Array<br />&nbsp; &nbsp; &nbsp; &nbsp; REAL(DP), DIMENSION(1:SIZE(Array))&nbsp; :: sorted</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Local working array<br />&nbsp; &nbsp; &nbsp; &nbsp; TYPE :: Data_Type<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; REAL(DP) :: rval<br />&nbsp; &nbsp; &nbsp; &nbsp; END TYPE Data_Type<br />&nbsp; &nbsp; &nbsp; &nbsp; TYPE (Data_Type), DIMENSION(:), ALLOCATABLE, TARGET :: Array2</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Pointer to local working array<br />&nbsp; &nbsp; &nbsp; &nbsp; TYPE :: BOX<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TYPE (Data_Type), POINTER :: Ptr<br />&nbsp; &nbsp; &nbsp; &nbsp; END TYPE BOX<br />&nbsp; &nbsp; &nbsp; &nbsp; !--- A()%Ptr is a pointer to Data_Type.<br />&nbsp; &nbsp; &nbsp; &nbsp; TYPE (BOX), DIMENSION(:), ALLOCATABLE :: A</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Local variables<br />&nbsp; &nbsp; &nbsp; &nbsp; INTEGER(I4B)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :: i, j<br />&nbsp; &nbsp; &nbsp; &nbsp; INTEGER(I4B)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :: n, n0</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Number of values to sort<br />&nbsp; &nbsp; &nbsp; &nbsp; n = SIZE( Array )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Save n in n0<br />&nbsp; &nbsp; &nbsp; &nbsp; n0 = n</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Allocate working arrays<br />&nbsp; &nbsp; &nbsp; &nbsp; ALLOCATE( Array2(1:n), A(1:n) )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Array too small to be sorted<br />&nbsp; &nbsp; &nbsp; &nbsp; IF ( n == 1 ) THEN<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sorted(:) = Array(:)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GO TO 900<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !return<br />&nbsp; &nbsp; &nbsp; &nbsp; END IF</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Save data in working array<br />&nbsp; &nbsp; &nbsp; &nbsp; Array2(:)%rval = Array(:)</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Pointer to working array<br />&nbsp; &nbsp; &nbsp; &nbsp; FORALL (i=1:n) A(i)%Ptr =&gt; Array2(i)</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Initialize variables<br />&nbsp; &nbsp; &nbsp; &nbsp; sorted = 0.0<br />&nbsp; &nbsp; &nbsp; &nbsp; i = 0<br />&nbsp; &nbsp; &nbsp; &nbsp; j = 0</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Begin sorting 1 to n element array<br />&nbsp; &nbsp; &nbsp; &nbsp; DO WHILE( n &gt; 0 )<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Find maximum value in the array<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; j = MAXLOC( Array2(:n)%rval, 1 )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Save the maximum values in the sorted array<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i = i + 1<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sorted(i) = A(j)%Ptr%rval</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Assign last array element to current maximum location<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Array2(j)%rval = A(n)%Ptr%rval</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Reduce the size of the working array<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- eliminating the last element.<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; n = n - 1<br />&nbsp; &nbsp; &nbsp; &nbsp; END DO</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Ascending (.true.) or Descending (.false.) Sort Order<br />&nbsp; &nbsp; &nbsp; &nbsp; IF (bFlag) THEN<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Ascending Order Sort<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Reverse the order of elements in descending order array<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sorted = sorted(n0:1:-1)<br />&nbsp; &nbsp; &nbsp; &nbsp; ELSE !--- Descending Order Sort<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CONTINUE<br />&nbsp; &nbsp; &nbsp; &nbsp; END IF</p><p>900&nbsp; &nbsp; &nbsp;CONTINUE</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Deallocate working array<br />&nbsp; &nbsp; &nbsp; &nbsp; DEALLOCATE( Array2 )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; RETURN<br />&nbsp; &nbsp; END FUNCTION FPSort</p><p>&nbsp; &nbsp; END MODULE FPSort_module</p>]]></content>
			<author>
				<name><![CDATA[drfrank]]></name>
				<uri>https://forums.approximatrix.com/profile.php?id=223</uri>
			</author>
			<updated>2020-12-13T15:38:17Z</updated>
			<id>https://forums.approximatrix.com/viewtopic.php?pid=3653#p3653</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Merge Sort Routine]]></title>
			<link rel="alternate" href="https://forums.approximatrix.com/viewtopic.php?pid=3652#p3652" />
			<content type="html"><![CDATA[<p>Here is a revised Floating Point sort (FPSORT) routine that sorts x2.5 faster than the previously posted sort routine and sorts in ascending or descending order. It utilizes MAXLOC and reduces the size (PACK) of the searched working array as the sort progresses.</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- FPSort ROUTINE:<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Function FPSort(array,bflag) Result(sorted)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;bFlag = .true.<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;n0 = SIZE( array )<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;n = n0<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;n1 = n / 40<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;unsorted = array<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sorted = 0.0<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;c = -HUGE(1.0)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;vecMax = c<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;i = 0</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DO WHILE( ANY(unsorted(:n) &gt; c) )<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;j = MAXLOC( unsorted(:n), 1 )<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;vecMax = unsorted(j)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;unsorted(j) = c<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;i = i + 1<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sorted(i) = vecMax<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IF ( (n &gt; 400).AND.(MODULO(i, n1) == 0) ) &amp;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;unsorted = PACK(unsorted(:n), unsorted(:n) /= c)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;n = SIZE( unsorted )<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;End Do</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;If (bFlag) Then<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;!--- Reverse order Ascending Order Sort<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sorted = sorted(n0:1:-1)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;End If<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; End Function FPSort</p><p>The complete listing is shown below.</p><p>Happy Holidays,<br />Frank</p><p>&nbsp; &nbsp; Module FPSort_module<br />&nbsp; &nbsp; Implicit None</p><p>&nbsp; &nbsp; PRIVATE</p><p>&nbsp; &nbsp; PUBLIC :: FPSort</p><p>&nbsp; &nbsp; INTERFACE FPSort<br />&nbsp; &nbsp; &nbsp; &nbsp; MODULE PROCEDURE FPSort<br />&nbsp; &nbsp; END INTERFACE</p><p>&nbsp; &nbsp; CONTAINS</p><p>&nbsp; &nbsp; Function FPSort( array,bFlag ) Result( sorted )<br />&nbsp; &nbsp; &nbsp; &nbsp; !---------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; !---&nbsp; &nbsp; FPSort version 2.0<br />&nbsp; &nbsp; &nbsp; &nbsp; !---&nbsp; &nbsp; (x4 Faster than a Bubble sort routine)<br />&nbsp; &nbsp; &nbsp; &nbsp; !---<br />&nbsp; &nbsp; &nbsp; &nbsp; !---&nbsp; &nbsp; Developed by F.W. Perrella, Ph.D.&nbsp; December 7, 2020<br />&nbsp; &nbsp; &nbsp; &nbsp; !---&nbsp; &nbsp; Silver Spring, Maryland U.S.A.<br />&nbsp; &nbsp; &nbsp; &nbsp; !---------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; ! NAME:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;FPSort<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; ! PURPOSE:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;Sorts a numeric array in ascending or descending order.<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; ! MODULE:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;nrType: Definition for kind variable types.<br />&nbsp; &nbsp; &nbsp; &nbsp; !---------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; CALLING SEQUENCE:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;Result = FPSort( array,bFlag )<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; INPUT ARGUMENTS:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;array: Real array of numbers to sort<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;TYPE:&nbsp; REAL( KIND = Double )<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;bFlag: .TRUE.= Ascending sort, .FALSE.= Descending sort<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;TYPE:&nbsp; LOGICAL<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; FUNCTION RESULT:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;TYPE:&nbsp; &nbsp; Real( Double )<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;RESULT: Real array of values sorted (Ascending,Descending)<br />&nbsp; &nbsp; &nbsp; &nbsp; !---------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; use nrtype<br />&nbsp; &nbsp; &nbsp; &nbsp; implicit none<br />&nbsp; &nbsp; &nbsp; &nbsp; logical(LGT), intent(in)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :: bFlag<br />&nbsp; &nbsp; &nbsp; &nbsp; real(DP), dimension(:), intent(in)&nbsp; &nbsp;:: array<br />&nbsp; &nbsp; &nbsp; &nbsp; real(DP), dimension(1:size(array)) :: sorted</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Local working array<br />&nbsp; &nbsp; &nbsp; &nbsp; real(DP), allocatable, dimension(:) :: unsorted</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Local variables<br />&nbsp; &nbsp; &nbsp; &nbsp; integer(I4B)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :: i, j<br />&nbsp; &nbsp; &nbsp; &nbsp; integer(I4B)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :: n, n0, n1<br />&nbsp; &nbsp; &nbsp; &nbsp; real(DP)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :: vecMax<br />&nbsp; &nbsp; &nbsp; &nbsp; real(DP), parameter&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:: c = -HUGE(1.0)</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Number of values to sort<br />&nbsp; &nbsp; &nbsp; &nbsp; n = SIZE( array )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Allocate working array<br />&nbsp; &nbsp; &nbsp; &nbsp; IF (ALLOCATED( unsorted )) DEALLOCATE( unsorted )<br />&nbsp; &nbsp; &nbsp; &nbsp; ALLOCATE( unsorted(1:n) )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Save n to n0<br />&nbsp; &nbsp; &nbsp; &nbsp; n0 = n</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Array too small to be sorted<br />&nbsp; &nbsp; &nbsp; &nbsp; IF ( n0 == 1 ) THEN<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sorted = array<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GO TO 900<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !return<br />&nbsp; &nbsp; &nbsp; &nbsp; END IF</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Initialize variable<br />&nbsp; &nbsp; &nbsp; &nbsp; sorted = array<br />&nbsp; &nbsp; &nbsp; &nbsp; vecMax = c<br />&nbsp; &nbsp; &nbsp; &nbsp; n = n0<br />&nbsp; &nbsp; &nbsp; &nbsp; n1 = n<br />&nbsp; &nbsp; &nbsp; &nbsp; i = 0</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Working array size reduction factor<br />&nbsp; &nbsp; &nbsp; &nbsp; n1 = n0 / 40</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Working array<br />&nbsp; &nbsp; &nbsp; &nbsp; unsorted(:n) = sorted(:n)</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Begin sorting array<br />&nbsp; &nbsp; &nbsp; &nbsp; !--- Sort 1 to n element array<br />&nbsp; &nbsp; &nbsp; &nbsp; DO WHILE( ANY(unsorted(:n) &gt; c) )<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Find maximum value in the array<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; j = MAXLOC( unsorted(:n), 1 )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Maximum value<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vecMax = unsorted(j)</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Replace array maximum with a huge negative number<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; unsorted(j) = c</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Save the maximum values in the array<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i = i + 1<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sorted(i) = vecMax</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Reduce the size of the working array<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IF ( (n &gt; 400).AND.(MODULO(i, n1) == 0) ) &amp;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; unsorted = PACK(unsorted(:n), unsorted(:n) /= c)</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Revised working array size<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; n = SIZE( unsorted )<br />&nbsp; &nbsp; &nbsp; &nbsp; END DO</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Ascending (.true.) or Descending (.false.) Sort Order<br />&nbsp; &nbsp; &nbsp; &nbsp; IF (bFlag) THEN<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Ascending Order Sort<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Reverse the order of elements in descending order array<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sorted = sorted(n0:1:-1)<br />&nbsp; &nbsp; &nbsp; &nbsp; ELSE !--- Descending Order Sort<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CONTINUE<br />&nbsp; &nbsp; &nbsp; &nbsp; END IF</p><p>900&nbsp; &nbsp; &nbsp;CONTINUE</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Deallocate working array<br />&nbsp; &nbsp; &nbsp; &nbsp; Deallocate( unsorted )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; RETURN<br />&nbsp; &nbsp; End Function FPSort</p><p>&nbsp; &nbsp; End Module FPSort_module</p>]]></content>
			<author>
				<name><![CDATA[drfrank]]></name>
				<uri>https://forums.approximatrix.com/profile.php?id=223</uri>
			</author>
			<updated>2020-12-07T15:36:13Z</updated>
			<id>https://forums.approximatrix.com/viewtopic.php?pid=3652#p3652</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Merge Sort Routine]]></title>
			<link rel="alternate" href="https://forums.approximatrix.com/viewtopic.php?pid=3651#p3651" />
			<content type="html"><![CDATA[<p>MergSort Update:</p><p>The following revised sort routine is x2 faster than the previously posted routine.<br />I realize that it&#039;s simple, but it works fairly well.</p><p>Frank</p><p>&nbsp; &nbsp; &nbsp; &nbsp; REVISED BASIC MERGSORT ROUTINE:<br />&nbsp; &nbsp; &nbsp; &nbsp; --------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Function MergSort(array) Result(sorted)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;n = SIZE( array )<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;unsorted = array<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sorted = 0.0<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;c = 123456789.0<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;vecMin = c<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;i = 0<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Do While( ANY(unsorted &lt; c) )<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;j = MINLOC( unsorted, 1 )<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;vecMin = unsorted(j)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;unsorted(j) = c<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;i = i + 1<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sorted(i) = vecMin<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;End Do<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;End Function</p><p> Listing of the Revised MergSort Module below:</p><p>&nbsp; &nbsp; Module MSort<br />&nbsp; &nbsp; USE nrtype<br />&nbsp; &nbsp; Implicit None</p><p>&nbsp; &nbsp; PRIVATE</p><p>&nbsp; &nbsp; PUBLIC :: MergSort</p><p>&nbsp; &nbsp; INTERFACE MergSort<br />&nbsp; &nbsp; &nbsp; &nbsp; MODULE PROCEDURE MergSort<br />&nbsp; &nbsp; END INTERFACE</p><p>&nbsp; &nbsp; CONTAINS</p><p>&nbsp; &nbsp; function MergSort( array ) result( sorted )<br />&nbsp; &nbsp; &nbsp; &nbsp; !---------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; !---&nbsp; &nbsp; MergSort version 1.1<br />&nbsp; &nbsp; &nbsp; &nbsp; !---<br />&nbsp; &nbsp; &nbsp; &nbsp; !---&nbsp; &nbsp; Developed by F.W. Perrella, Ph.D.&nbsp; November 28, 2020<br />&nbsp; &nbsp; &nbsp; &nbsp; !---&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Silver Spring, Maryland U.S.A.<br />&nbsp; &nbsp; &nbsp; &nbsp; !---------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; ! NAME:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;MergSort<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; ! PURPOSE:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;Program to sort a numeric array in ascending order.<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; ! MODULE:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;nrType: Definition for kind variable types.<br />&nbsp; &nbsp; &nbsp; &nbsp; !---------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; CALLING SEQUENCE:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;Result = MergSort( array )<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; INPUT ARGUMENTS:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;array:&nbsp; &nbsp; &nbsp; Real array of numbers to sort.<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;TYPE:&nbsp; &nbsp; &nbsp; &nbsp;REAL( KIND = Double )<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; FUNCTION RESULT:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;TYPE:&nbsp; &nbsp; Real( double )<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;RESULT: A real array of values sorted in ascending order.<br />&nbsp; &nbsp; &nbsp; &nbsp; !---------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; !---<br />&nbsp; &nbsp; &nbsp; &nbsp; !--- Execution Time: 0.003 sec. to sort 2000 random numbers<br />&nbsp; &nbsp; &nbsp; &nbsp; !---<br />&nbsp; &nbsp; &nbsp; &nbsp; use nrtype<br />&nbsp; &nbsp; &nbsp; &nbsp; implicit none<br />&nbsp; &nbsp; &nbsp; &nbsp; real(dp), dimension(:), intent(in)&nbsp; :: array<br />&nbsp; &nbsp; &nbsp; &nbsp; real(dp), dimension(1:size(array))&nbsp; :: sorted</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Local orking arrays<br />&nbsp; &nbsp; &nbsp; &nbsp; real(dp), allocatable, dimension(:) :: unsorted</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Local variables<br />&nbsp; &nbsp; &nbsp; &nbsp; integer(I4B)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :: i, j, n<br />&nbsp; &nbsp; &nbsp; &nbsp; real(dp)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :: vecMin<br />&nbsp; &nbsp; &nbsp; &nbsp; real(dp), parameter&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:: c = 123456789.0</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Number of values to sort<br />&nbsp; &nbsp; &nbsp; &nbsp; n = SIZE( array )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Array too small to be sorted<br />&nbsp; &nbsp; &nbsp; &nbsp; if ( n == 1 ) then<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sorted = array<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return<br />&nbsp; &nbsp; &nbsp; &nbsp; endif</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Begin sorting array<br />&nbsp; &nbsp; &nbsp; &nbsp; unsorted = array<br />&nbsp; &nbsp; &nbsp; &nbsp; sorted = 0.0<br />&nbsp; &nbsp; &nbsp; &nbsp; vecMin = c<br />&nbsp; &nbsp; &nbsp; &nbsp; i = 0</p><p>&nbsp; &nbsp; &nbsp; &nbsp; DO WHILE( ANY(unsorted &lt; c) )<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Find minimum value in array<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; j = MINLOC( unsorted, 1 )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Minimum value<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vecMin = unsorted(j)</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Replace array minimum with a very large number.<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; unsorted(j) = c</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Save the minimum values in array<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i = i + 1<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sorted(i) = vecMin<br />&nbsp; &nbsp; &nbsp; &nbsp; END DO</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Deallocate working arrays<br />&nbsp; &nbsp; &nbsp; &nbsp; Deallocate( unsorted )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; return<br />&nbsp; &nbsp; end function MergSort</p><p>&nbsp; &nbsp; End Module MSort</p>]]></content>
			<author>
				<name><![CDATA[drfrank]]></name>
				<uri>https://forums.approximatrix.com/profile.php?id=223</uri>
			</author>
			<updated>2020-11-29T01:43:23Z</updated>
			<id>https://forums.approximatrix.com/viewtopic.php?pid=3651#p3651</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Merge Sort Routine]]></title>
			<link rel="alternate" href="https://forums.approximatrix.com/viewtopic.php?pid=3650#p3650" />
			<content type="html"><![CDATA[<p>Hi Jeff,</p><p>While in lock-down and to keep my mind active, I&#039;ve written a sorting routine for real arrays. I&#039;m posting the sort routine here.&nbsp; Although it&#039;s far from being the fastest sort routine, it&#039;s simple. I&#039;ve sorted up to 65,000 random numbers with the routine with no problem. However, speed wise, it&#039;s more practical in the range of 3 to 4000 numbers (e.g., Random numbers =1034, t = 0.04 sec.; Random numbers =4108, t = 0.4 sec.).&nbsp; Like many routines, sometimes we learn that similar logic has been applied before and are not aware of it. The program is self explanatory and can be compiled as is and run with SimplyFortran.</p><p>I would welcome any constructive suggestions from forum members on how to improve the routine.</p><p>Thanks,<br />Frank</p><br /><p>&nbsp; &nbsp; !-------------------------------------------------------------------<br />&nbsp; &nbsp; !----------------- Start of MergSort Routine -----------------------<br />&nbsp; &nbsp; !-------------------------------------------------------------------<br />&nbsp; &nbsp; MODULE nrtype<br />&nbsp; &nbsp; &nbsp; &nbsp; IMPLICIT NONE</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Listing valid kind parameters types<br />&nbsp; &nbsp; &nbsp; &nbsp; INTEGER, PARAMETER :: I1B = KIND(2)<br />&nbsp; &nbsp; &nbsp; &nbsp; INTEGER, PARAMETER :: I2B = KIND(4)<br />&nbsp; &nbsp; &nbsp; &nbsp; INTEGER, PARAMETER :: I4B = KIND(9)</p><p>&nbsp; &nbsp; &nbsp; &nbsp; INTEGER, PARAMETER :: SP = KIND(1.0E0)<br />&nbsp; &nbsp; &nbsp; &nbsp; INTEGER, PARAMETER :: DP = SELECTED_REAL_KIND(15, 200)<br />&nbsp; &nbsp; &nbsp; &nbsp; INTEGER, PARAMETER :: QP = SELECTED_REAL_KIND(2*PRECISION(1.0_DP))</p><p>&nbsp; &nbsp; &nbsp; &nbsp; INTEGER, PARAMETER :: LGT = KIND(.TRUE.)<br />&nbsp; &nbsp; END MODULE nrtype</p><p>&nbsp; &nbsp; !-------------------------------------------------------------------<br />&nbsp; &nbsp; Module MSort<br />&nbsp; &nbsp; &nbsp; &nbsp; USE nrtype<br />&nbsp; &nbsp; &nbsp; &nbsp; Implicit None</p><p>&nbsp; &nbsp; &nbsp; &nbsp; PRIVATE</p><p>&nbsp; &nbsp; &nbsp; &nbsp; PUBLIC :: MergSort</p><p>&nbsp; &nbsp; &nbsp; &nbsp; INTERFACE MergSort<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MODULE PROCEDURE MergSort<br />&nbsp; &nbsp; &nbsp; &nbsp; END INTERFACE</p><p>&nbsp; &nbsp; !-------------------------------------------------------------------<br />&nbsp; &nbsp; CONTAINS<br />&nbsp; &nbsp; !-------------------------------------------------------------------</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !---------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; FUNCTION MergSort( array ) RESULT( sorted )<br />&nbsp; &nbsp; &nbsp; &nbsp; !---------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; !---&nbsp; &nbsp; MergSort version 1.0<br />&nbsp; &nbsp; &nbsp; &nbsp; !---<br />&nbsp; &nbsp; &nbsp; &nbsp; !---&nbsp; &nbsp; Developed by F.W. Perrella, Ph.D.&nbsp; November 27, 2020<br />&nbsp; &nbsp; &nbsp; &nbsp; !---&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Silver Spring, Maryland U.S.A.<br />&nbsp; &nbsp; &nbsp; &nbsp; !---------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; ! NAME:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;MergSort<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; ! PURPOSE:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;Program to sort a numeric array in ascending order.<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; ! MODULE:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;nrType: Definition for kind variable types.<br />&nbsp; &nbsp; &nbsp; &nbsp; !---------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; CALLING SEQUENCE:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;Result = MergSort( array )<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; INPUT ARGUMENTS:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;array:&nbsp; &nbsp; &nbsp; Real array of numbers to sort.<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;TYPE:&nbsp; &nbsp; &nbsp; &nbsp;REAL( KIND = Double )<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; FUNCTION RESULT:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;TYPE:&nbsp; &nbsp; Real( double )<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;RESULT: A real array of values sorted in ascending order.<br />&nbsp; &nbsp; &nbsp; &nbsp; !---------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; !<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp;BASIC MERGSORT ROUTINE:<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp;Function MergSort(array) Result(sorted)<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;c = 123456789.0<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;unsorted = array<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;sorted = 0.0<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;Do i = 1, n<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;j = MINLOC(unsorted,1)<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;vecMin = unsorted(j)<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;unsorted = MERGE(unsorted,c,MASK=(unsorted /= vecMin))<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sorted(i) = vecMin<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp; &nbsp;End Do<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; &nbsp;End Function<br />&nbsp; &nbsp; &nbsp; &nbsp; !---------------------------------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; use nrtype<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; implicit none<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; real(DP), dimension(:), intent(in) :: array<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; real(DP), dimension(1:size(array)) :: sorted</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Local orking arrays<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; real(DP), allocatable, dimension(:) :: unsorted<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; real(DP), allocatable, dimension(:) :: c</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Local variables<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; real(DP)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :: vecMin<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; integer(I4B)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :: i, j, n</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Number of values to sort<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; n = SIZE( array )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Array too small to be sorted<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ( n == 1 ) then<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sorted = array<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; endif</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Allocate working arrays<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; allocate( unsorted(n), c(n) )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Large number array place holder<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c = 123456789.0</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Begin sorting array<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; unsorted = array<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sorted = 0.0</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; do i = 1, n<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Find minimum value in array<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; j = MINLOC( unsorted, 1 )<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vecMin = unsorted(j)</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Merge array eliminating minimum value<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; unsorted = MERGE( unsorted, c, MASK=(unsorted /= vecMin) )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Save the minimum values in array<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sorted(i) = vecMin<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end do</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Deallocate working arrays<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Deallocate( unsorted, c )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return<br />&nbsp; &nbsp; &nbsp; &nbsp; End Function MergSort</p><p>&nbsp; &nbsp; End Module MSort</p><p>&nbsp; &nbsp; !-------------------------------------------------------------------<br />&nbsp; &nbsp; PROGRAM Test_Sort<br />&nbsp; &nbsp; &nbsp; &nbsp; use nrtype<br />&nbsp; &nbsp; &nbsp; &nbsp; implicit none<br />&nbsp; &nbsp; &nbsp; &nbsp; character(1) :: a</p><p>&nbsp; &nbsp; &nbsp; &nbsp; call Test_MergSort()</p><p>&nbsp; &nbsp; &nbsp; &nbsp; WRITE(*,&#039;(/1x,&quot;Press return to exit&quot;,$)&#039;)<br />&nbsp; &nbsp; &nbsp; &nbsp; READ(*,&#039;(a1)&#039;) a<br />&nbsp; &nbsp; End Program Test_Sort</p><p>&nbsp; &nbsp; !-------------------------------------------------------------------<br />&nbsp; &nbsp; Subroutine Test_MergSort()<br />&nbsp; &nbsp; &nbsp; &nbsp; use nrtype<br />&nbsp; &nbsp; &nbsp; &nbsp; use MSort<br />&nbsp; &nbsp; &nbsp; &nbsp; implicit none</p><p>&nbsp; &nbsp; &nbsp; &nbsp; real(SP) :: t1, t2, tsum<br />&nbsp; &nbsp; &nbsp; &nbsp; real(DP),allocatable :: array1(:)<br />&nbsp; &nbsp; &nbsp; &nbsp; integer(I4B) :: j, k, m, n<br />&nbsp; &nbsp; &nbsp; &nbsp; integer(I4B) :: left, right, isize<br />&nbsp; &nbsp; &nbsp; &nbsp; logical(LGT) :: bflag, btot</p><p>&nbsp; &nbsp; &nbsp; &nbsp; m = 10<br />&nbsp; &nbsp; &nbsp; &nbsp; n = 14<br />&nbsp; &nbsp; &nbsp; &nbsp; btot = .TRUE.</p><p>&nbsp; &nbsp; &nbsp; &nbsp; WRITE(*,&#039;(/1x,&quot;Testing MergSort&quot;)&#039;)<br />&nbsp; &nbsp; &nbsp; &nbsp; WRITE(*,&#039;(1x,a)&#039;) REPEAT(&quot;-&quot;, 35)</p><p>&nbsp; &nbsp; &nbsp; &nbsp; do j = m, n<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- 1,034 to 16,398 random numbers<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isize = 2**j<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isize = isize + j<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; allocate( array1(isize) )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tsum = 0.0<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; do k = 1, m<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; call random_number( array1 )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; left = 1<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; right = isize</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Start timer<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; t1 = DeltaTime( .TRUE. )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Sort in Ascending Order<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; array1 = MergSort( array1 )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- End timer<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; t2 = DeltaTime( .FALSE. )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tsum = tsum + (t2 - t1)<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end do</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WRITE(*,&#039;(1x,&quot;Random numbers =&quot;,1x,I0)&#039;) isize<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WRITE(*,&#039;(1x,&quot;Average elapsed time =&quot;,1x,F6.4,1x,&quot;sec&quot;)&#039;) tsum/m</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !--- Check that the array was sorted correctly.<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; call check_sort( array1, left, right, bflag )</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; btot = (btot .eqv. bflag)</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; deallocate(array1)<br />&nbsp; &nbsp; &nbsp; &nbsp; end do</p><p>&nbsp; &nbsp; &nbsp; &nbsp; WRITE(*, &amp;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#039;(1x,&quot;All tests were sorted correctly:&quot;,1x,L1,&quot;RUE&quot;)&#039;) btot<br />&nbsp; &nbsp; &nbsp; &nbsp; WRITE(*,&#039;(1x,a)&#039;) REPEAT(&quot;-&quot;, 35)</p><p>&nbsp; &nbsp; &nbsp; &nbsp; return<br />&nbsp; &nbsp; !End Subroutine Test_MergSort</p><p>&nbsp; &nbsp; !-------------------------------------------------------------------<br />&nbsp; &nbsp; CONTAINS<br />&nbsp; &nbsp; !-------------------------------------------------------------------</p><p>&nbsp; &nbsp; !-------------------------------------------------------------------<br />&nbsp; &nbsp; Subroutine check_sort( array, left, right, bflag )<br />&nbsp; &nbsp; &nbsp; &nbsp; use nrtype<br />&nbsp; &nbsp; &nbsp; &nbsp; implicit none<br />&nbsp; &nbsp; &nbsp; &nbsp; integer(I4B), intent(in)&nbsp; :: left, right<br />&nbsp; &nbsp; &nbsp; &nbsp; real(DP), intent(inout)&nbsp; &nbsp;:: array(left:right)<br />&nbsp; &nbsp; &nbsp; &nbsp; logical(LGT), intent(out) :: bflag<br />&nbsp; &nbsp; &nbsp; &nbsp; integer(I4B) :: j</p><p>&nbsp; &nbsp; &nbsp; &nbsp; bflag = .true.<br />&nbsp; &nbsp; &nbsp; &nbsp; do j = 1, size(array)-1<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if( array(j+1) &lt; array(j) ) then<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bflag = .false.<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; EXIT<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end if<br />&nbsp; &nbsp; &nbsp; &nbsp; end do</p><p>&nbsp; &nbsp; &nbsp; &nbsp; if (bflag) then<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print *, &quot;Correctly sorted array&quot;<br />&nbsp; &nbsp; &nbsp; &nbsp; else<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print *, &quot;Incorrectly sorted array&quot;<br />&nbsp; &nbsp; &nbsp; &nbsp; end if<br />&nbsp; &nbsp; &nbsp; &nbsp; PRINT *</p><p>&nbsp; &nbsp; &nbsp; &nbsp; return<br />&nbsp; &nbsp; End Subroutine check_sort</p><p>&nbsp; &nbsp; !-------------------------------------------------------------------<br />&nbsp; &nbsp; FUNCTION DeltaTime(Start) RESULT(tm)<br />&nbsp; &nbsp; &nbsp; &nbsp; !-------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; !--- Routine to calculate run time<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; print *, &#039;Starttime:&#039;,&nbsp; t0<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; print *, &#039;Finishtime:&#039;, t1<br />&nbsp; &nbsp; &nbsp; &nbsp; !&nbsp; &nbsp; print *, &#039;Elapsed time=&#039;, t1 - t0<br />&nbsp; &nbsp; &nbsp; &nbsp; !-------------------------------------<br />&nbsp; &nbsp; &nbsp; &nbsp; IMPLICIT NONE<br />&nbsp; &nbsp; &nbsp; &nbsp; LOGICAL, INTENT(IN) :: Start<br />&nbsp; &nbsp; &nbsp; &nbsp; LOGICAL&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:: Begin<br />&nbsp; &nbsp; &nbsp; &nbsp; REAL, SAVE&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :: t0<br />&nbsp; &nbsp; &nbsp; &nbsp; REAL&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :: t1<br />&nbsp; &nbsp; &nbsp; &nbsp; REAL&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :: tm<br />&nbsp; &nbsp; &nbsp; &nbsp; REAL, SAVE&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :: tt</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Start timer<br />&nbsp; &nbsp; &nbsp; &nbsp; !--- Start = .TRUE.<br />&nbsp; &nbsp; &nbsp; &nbsp; Begin = Start<br />&nbsp; &nbsp; &nbsp; &nbsp; IF ( Begin ) THEN<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; call cpu_time ( t0 )<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; t1 = t0<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Begin = .FALSE.</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Stop timer<br />&nbsp; &nbsp; &nbsp; &nbsp; ELSE !--- Start = .FALSE.<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; call cpu_time ( t1 )<br />&nbsp; &nbsp; &nbsp; &nbsp; END IF</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Calculate time in seconds<br />&nbsp; &nbsp; &nbsp; &nbsp; tt = tt + (t1 - t0)</p><p>&nbsp; &nbsp; &nbsp; &nbsp; !--- Return total time in seconds<br />&nbsp; &nbsp; &nbsp; &nbsp; tm = tt<br />&nbsp; &nbsp; END FUNCTION DeltaTime</p><p>&nbsp; &nbsp; !-------------------------------------------------------------------<br />&nbsp; &nbsp; End Subroutine Test_MergSort<br />&nbsp; &nbsp; !-------------------------------------------------------------------<br />&nbsp; &nbsp; !---------------- End of MergSort Routine --------------------------<br />&nbsp; &nbsp; !-------------------------------------------------------------------</p>]]></content>
			<author>
				<name><![CDATA[drfrank]]></name>
				<uri>https://forums.approximatrix.com/profile.php?id=223</uri>
			</author>
			<updated>2020-11-27T14:57:22Z</updated>
			<id>https://forums.approximatrix.com/viewtopic.php?pid=3650#p3650</id>
		</entry>
</feed>
