Makes new distribution with decimation and multiplicity
Definition of multiplicity and nimages Multiplicity and decimation (number of images) are used to match process grid coordinates on nonsquare process grids. Given source_nbins and target_nbins, their relation is source_nbins * target_multiplicity = target_nbins * target_nimages. It is best when both multiplicity and nimages are small. To get these two factors, then, one can use the following formulas: nimages = lcm(source_nbins, target_nbins) / target_nbins multiplicity = target_nbins / gcd(source_nbins, target_nbins) from the target's point of view (nimages = target_nimages).
Mapping The new distribution comprises of real bins and images within bins. These can be view as target_nbinsnimages virtual columns. These same virtual columns are also source_nbinsmultiplicity in number. Therefore these virtual columns are mapped from source_nbinsmultiplicity onto target_binsnimages (each target bin has nimages images): Source 4: 1 2 34 5 67 8 9A B C (43) Target 6: 1 23 45 67 89 AB C (62) multiplicity=3, nimages=2, 12 virtual columns (1C). Source bin elements are evenly mapped into one of multiplicity virtual columns. Other (noneven, blocksize aware) mappings could be better.
Type  Intent  Optional  Attributes  Name  

integer,  intent(out),  DIMENSION(:)  ::  new_bins  new real distribution new image distribution 

integer,  intent(out),  DIMENSION(:)  ::  images  new real distribution new image distribution 

integer,  intent(in),  DIMENSION(:), CONTIGUOUS  ::  source_bins  Basis for the new distribution and images 

integer,  intent(in)  ::  nbins  number of bins in the new real distribution multiplicity number of images in the new distribution 

integer,  intent(in)  ::  multiplicity  number of bins in the new real distribution multiplicity number of images in the new distribution 

integer,  intent(in)  ::  nimages  number of bins in the new real distribution multiplicity number of images in the new distribution 
SUBROUTINE rebin_distribution(new_bins, images, source_bins, &
nbins, multiplicity, nimages)
!! Makes new distribution with decimation and multiplicity
!!
!! Definition of multiplicity and nimages
!! Multiplicity and decimation (number of images) are used to
!! match process grid coordinates on nonsquare process
!! grids. Given source_nbins and target_nbins, their relation is
!! source_nbins * target_multiplicity
!! = target_nbins * target_nimages.
!! It is best when both multiplicity and nimages are small. To
!! get these two factors, then, one can use the following formulas:
!! nimages = lcm(source_nbins, target_nbins) / target_nbins
!! multiplicity = target_nbins / gcd(source_nbins, target_nbins)
!! from the target's point of view (nimages = target_nimages).
!!
!! Mapping
!! The new distribution comprises of real bins and images within
!! bins. These can be view as target_nbins*nimages virtual
!! columns. These same virtual columns are also
!! source_nbins*multiplicity in number. Therefore these virtual
!! columns are mapped from source_nbins*multiplicity onto
!! target_bins*nimages (each target bin has nimages images):
!! Source 4: 1 2 34 5 67 8 9A B C (4*3)
!! Target 6: 1 23 45 67 89 AB C (6*2)
!! multiplicity=3, nimages=2, 12 virtual columns (1C).
!! Source bin elements are evenly mapped into one of multiplicity
!! virtual columns. Other (noneven, blocksize aware) mappings
!! could be better.
INTEGER, DIMENSION(:), INTENT(OUT) :: new_bins, images
!! new real distribution
!! new image distribution
INTEGER, DIMENSION(:), CONTIGUOUS, INTENT(IN) :: source_bins
!! Basis for the new distribution and images
INTEGER, INTENT(IN) :: nbins, multiplicity, nimages
!! number of bins in the new real distribution
!! multiplicity
!! number of images in the new distribution
INTEGER :: bin, i, old_nbins, virtual_bin
INTEGER, ALLOCATABLE, DIMENSION(:) :: bin_multiplier
! 
IF (MOD(nbins*nimages, multiplicity) .NE. 0) &
DBCSR_WARN("mulitplicity is not divisor of new process grid coordinate")
old_nbins = (nbins*nimages)/multiplicity
ALLOCATE (bin_multiplier(0:old_nbins  1))
bin_multiplier(:) = 0
DO i = 1, SIZE(new_bins)
IF (i .LE. SIZE(source_bins)) THEN
bin = source_bins(i)
ELSE
! Fill remainder with a cyclic distribution
bin = MOD(i, old_nbins)
END IF
virtual_bin = bin*multiplicity + bin_multiplier(bin)
new_bins(i) = virtual_bin/nimages
images(i) = 1 + MOD(virtual_bin, nimages)
bin_multiplier(bin) = bin_multiplier(bin) + 1
IF (bin_multiplier(bin) .GE. multiplicity) THEN
bin_multiplier(bin) = 0
END IF
END DO
END SUBROUTINE rebin_distribution