csun22's picture
Upload 59 files
ca1888b verified
#!/usr/bin/env python
"""
random.py
Tools related to randomness
"""
from __future__ import absolute_import
import os
import sys
import numpy as np
import random
import core_scripts.other_tools.display as nii_display
__author__ = "Xin Wang"
__email__ = "wangxin@nii.ac.jp"
__copyright__ = "Copyright 2021, Xin Wang"
##############
# Shuffling tools
##############
def f_shuffle_slice_inplace(input_list, slice_start=None, slice_stop=None):
""" shuffle_slice(input_list, slice_start, slice_stop)
Shuffling input list (in place) in the range specified by slice_start
and slice_stop.
Based on Knuth shuffling
https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
input
-----
input_list: list
slice_start: int, start idx of the range to be shuffled
slice_end: int, end idx of the range to be shuffled
Both slice_start and slice_end should be in the style of python index
e.g., shuffle_slice(input_list, 0, N) will shuffle the slice input[0:N]
When slice_start / slice_stop is None,
slice_start = 0 / slice_stop = len(input_list)
output
------
none: shuffling is done in place
"""
if slice_start is None or slice_start < 0:
slice_start = 0
if slice_stop is None or slice_stop > len(input_list):
slice_stop = len(input_list)
idx = slice_start
while (idx < slice_stop - 1):
idx_swap = random.randrange(idx, slice_stop)
# naive swap
tmp = input_list[idx_swap]
input_list[idx_swap] = input_list[idx]
input_list[idx] = tmp
idx += 1
return
def f_shuffle_in_block_inplace(input_list, block_size):
"""
f_shuffle_in_block_inplace(input_list, block_size)
Shuffle the input list (in place) by dividing the list input blocks and
shuffling within each block
Example:
>>> data = [1,2,3,4,5,6]
>>> random_tools.f_shuffle_in_block_inplace(data, 3)
>>> data
[3, 1, 2, 5, 4, 6]
input
-----
input_list: input list
block_size: int
output
------
None: shuffling is done in place
"""
if block_size <= 1:
# no need to shuffle if block size if 1
return
else:
list_length = len(input_list)
# range( -(- x // y) ) -> int(ceil(x / y))
for iter_idx in range( -(-list_length // block_size) ):
# shuffle within each block
f_shuffle_slice_inplace(
input_list, iter_idx * block_size, (iter_idx+1) * block_size)
return
def f_shuffle_blocks_inplace(input_list, block_size):
"""
f_shuffle_blocks_inplace(input_list, block_size)
Shuffle the input list (in place) by dividing the list input blocks and
shuffling blocks
Example:
>> data = np.arange(1, 7)
>> f_shuffle_blocks_inplace(data, 3)
>> print(data)
[4 5 6 1 2 3]
input
-----
input_list: input list
block_size: int
output
------
None: shuffling is done in place
"""
# new list
tmp_list = input_list.copy()
block_number = len(input_list) // block_size
shuffle_block_idx = [x for x in range(block_number)]
random.shuffle(shuffle_block_idx)
new_idx = None
for iter_idx in range(block_size * block_number):
block_idx = iter_idx // block_size
in_block_idx = iter_idx % block_size
new_idx = shuffle_block_idx[block_idx] * block_size + in_block_idx
input_list[iter_idx] = tmp_list[new_idx]
return
if __name__ == "__main__":
print("Definition of randomness tools")