multiple_modular_multiplicative_inversions.sf 729 B

1234567891011121314151617181920212223242526272829303132333435363738
  1. #!/usr/bin/ruby
  2. # Algorithm for computing the modular inverse of a list of numbers:
  3. # 0 < x_1, ..., x_k < n
  4. #
  5. # Output:
  6. # y_1 = 1/x_1 mod n, ..., y_k = 1/x_k mod n
  7. # Algorithm 2.11 "MultipleInversion" presented in the book:
  8. #
  9. # Modern Computer Arithmetic
  10. # - by Richard P. Brent and Paul Zimmermann
  11. #
  12. func multiple_inversion (Array x, Number n) {
  13. var k = x.end
  14. var z = [x[0]]
  15. for i in (1 .. k) {
  16. z[i] = ((z[i-1] * x[i]) % n)
  17. }
  18. var y = []
  19. var q = invmod(z[k], n)
  20. for i in (k `downto` 1) {
  21. y[i] = ((q * z[i-1]) % n)
  22. q = ((q * x[i]) % n)
  23. }
  24. y[0] = q
  25. return y
  26. }
  27. say multiple_inversion([33, 42, 99, 103], 2017) #=> [489, 1969, 163, 235]