rng.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import random
  2. from fate_arch.session import computing_session
  3. import numpy as np
  4. from federatedml.secureprotol.paillier_tensor import PaillierTensor
  5. BITS = 10
  6. MIXED_RATE = 0.5
  7. class RandomNumberGenerator(object):
  8. def __init__(self):
  9. self.lower_bound = -2 ** BITS
  10. self.upper_bound = 2 ** BITS
  11. @staticmethod
  12. def get_size_by_shape(shape):
  13. size = 1
  14. for dim in shape:
  15. size *= dim
  16. return size
  17. def generate_random_number_1d(
  18. self,
  19. size,
  20. mixed_rate=MIXED_RATE,
  21. keep=None):
  22. if keep is not None:
  23. ret = [0] * size
  24. for i in range(size):
  25. if keep[i]:
  26. rng = random.SystemRandom().uniform(
  27. self.lower_bound,
  28. self.upper_bound) if np.random.rand() < mixed_rate else np.random.uniform(
  29. self.lower_bound,
  30. self.upper_bound)
  31. ret[i] = rng
  32. return np.array(ret)[keep]
  33. else:
  34. return [
  35. random.SystemRandom().uniform(
  36. self.lower_bound,
  37. self.upper_bound) if np.random.rand() < mixed_rate else np.random.uniform(
  38. self.lower_bound,
  39. self.upper_bound) for _ in range(size)]
  40. def generate_random_number(
  41. self,
  42. shape=None,
  43. mixed_rate=MIXED_RATE,
  44. keep=None):
  45. if keep is not None:
  46. size = self.get_size_by_shape(keep.shape)
  47. return self.generate_random_number_1d(
  48. size, mixed_rate=mixed_rate, keep=keep)
  49. else:
  50. size = self.get_size_by_shape(shape)
  51. return np.reshape(
  52. self.generate_random_number_1d(
  53. size, mixed_rate=mixed_rate), shape)
  54. def fast_generate_random_number(
  55. self,
  56. shape,
  57. partition=10,
  58. mixed_rate=MIXED_RATE,
  59. keep_table=None):
  60. if keep_table:
  61. tb = keep_table.mapValues(
  62. lambda keep_array: self.generate_random_number(
  63. keep=keep_array, mixed_rate=mixed_rate))
  64. return PaillierTensor(tb)
  65. else:
  66. tb = computing_session.parallelize(
  67. [None for _ in range(shape[0])], include_key=False, partition=partition)
  68. tb = tb.mapValues(lambda val: self.generate_random_number(
  69. shape[1:], mixed_rate=mixed_rate))
  70. return PaillierTensor(tb)