Блог пользователя duckladydinh

Автор duckladydinh, история, 22 месяца назад, По-английски

Hi

Euclidean algorithm is popular for finding the modular inverse but I find it a bit hard to implement. Instead, the following algorithm is much simpler. Let's call $$$f(i)$$$ the modular inverse of $$$i$$$ with respect to $$$m$$$

$$$ \begin{align*} m = ki + r & \implies 0 && \equiv && ki + r & \mod m \\ & \iff r && \equiv && -ki & \mod m \\ & \iff \frac{1}{i} && \equiv && -k(\frac{1}{r}) & \mod m \\ & \implies f(i) && = && (m-m/i)f(m \mod i) \mod m \end{align*} $$$

This method is often used in computing modular inverse for a range of numbers and much easier to implement to my taste BUT... what's the time complexity of this algorithm for computing a single modular inverse? I guess it's $$$O(logn)$$$ but my skill is too low to prove it :(.

Any math expert can help :)?

  • Проголосовать: нравится
  • +6
  • Проголосовать: не нравится

»
22 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Auto comment: topic has been updated by duckladydinh (previous revision, new revision, compare).

»
22 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Auto comment: topic has been updated by duckladydinh (previous revision, new revision, compare).

»
22 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Auto comment: topic has been updated by duckladydinh (previous revision, new revision, compare).

»
22 месяца назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Auto comment: topic has been updated by duckladydinh (previous revision, new revision, compare).

»
22 месяца назад, # |
  Проголосовать: нравится -14 Проголосовать: не нравится

I'm not an expert on the subject, but this is my template to calculate the modular inverse of a number using binary exponentiaton.

    int binpow(int b){ // binary exponentiation
        long long n = MOD-2; // fermat's little theorem
        long long ans = 1;
        long long place = b; 
        while(n){ // decompose n into binary representation
            if(n&1) ans = (ans * place)%MOD;
            place = (place*place)%MOD;
            n >>= 1;
        }
        return ans;
    }

I claim the time complexity is O(log n) because we bitshift n by >>= 1 for every iteration. For a 32 bit number, we shift n a maximum of 32 times and for a 64 bit number, we shift it by a maximum of 64 times.

»
22 месяца назад, # |
  Проголосовать: нравится +12 Проголосовать: не нравится

Euclidean algorithm is popular for finding the modular inverse but I find it a bit hard to implement.

well, you can shrink it to following

int inv_mod(int a, int m) { assert(0<a); assert(a<m);
	return a==1 ? 1 : m - (int64_t)m * inv_mod(m%a, a) / a;
}

it looks similar to method you described; work for every valid pair (your bad at mod=8 i=3); and run obviously in $$$O(logm)$$$.

»
22 месяца назад, # |
  Проголосовать: нравится +10 Проголосовать: не нравится