Code covered by the BSD License  

Highlights from
Variable Precision Integer Arithmetic

  • demo_vpi
  • base2vpi(B,base) bin2vpi: converts an integer in an arbitrary base into vpi (decimal) form
  • bin2vpi(B) bin2vpi: converts a binary representation of an integer into vpi (decimal) form
  • binomfactors(n,k) binomfactors: list all factors of the binomial coefficient nchoosek(n,k)
  • catdigits(N,M) catdigits: concatenates the digits of N and M into an aggregate number
  • createPrimesList createPrimesList - For users of older matlab releases, this function will generate a compatible _primeslist_ file
  • factorialfactors(n) factorialfactors: efficient computation of the prime factors of factorial(n)
  • fibonacci(n) fibonacci: vpi tool to efficiently compute the n'th Fibonacci number and the n'th Lucas number
  • getprimeslist loads the primeslist file, and decompresses it, returning the list of primes up to 2^26
  • ispalindrome(N) ispalindrome: test if the number N (vpi or numeric, or a digit string as a vector) is a palindrome
  • iszero(INT) vpi/iszero: test to see if a numeric object is zero
  • legendresymbol(a,p) legendresymbol: computes the legendre symbol (a/p) for prime p
  • lineardiophantine(A,B,C) lineardiophantine: solve the linear Diophantine equation, A*x + B*y = C
  • mersenne(p) mersenne: identify whether 2^p-1 is a Mersenne prime, using the Lucas-Lehmer test
  • minv(a,p)
  • modfibonacci(n,modulus) fibonacci: compute the n'th Fibonacci number and the n'th Lucas number, all modulo a given value
  • modrank(A,p) modrank: compute the rank of an integer array, modulo p
  • modroot(a,p)
  • modsolve(A,rhs,p)
  • nextprime(N,direction,kprimes) nextprime: finds the next larger prime number directly above (or below) N
  • numberOfPartitions(N) numberOfPartitions: compute the number of partitions of the positive integer n
  • powermod(a,d,n) vpi/powermod: Compute mod(a^d,n)
  • quadraticresidues(N) quadraticresidues: returns a list of the possible quadratic residues of the integer N
  • quotient(numerator,denominato... quotient: divides two integers, computing a quotient and remainder
  • subfactorial(N) subfactorial: The subfactorial of an integer (or integers) N, known as !N
  • totient(N) vpi/totient: the number of positive integers less than N that are coprime to N
  • vpi(N) vpi: Creator function for a variable precision integer
  • View all files
from Variable Precision Integer Arithmetic by John D'Errico
Arithmetic with integers of fully arbitrary size. Arrays and vectors of vpi numbers are supported.

minv(a,p)
function x = minv(a,p)
% vpi/minv: the inverse of a modulo p, such that mod(a*x,p) == 1
% usage: x = minv(a,p)
%
% if a and p are relatively prime (co-prime)
% uses the extended Euclidean algorithm to find
% a solution to the problem a*x - q*p = 1
% 
% minv returns an empty result if a and p are
% relatively prime, (also known as coprime.) A
% warning will be generated in this event.
%
% Example:
%  a = 35;
%  p = vpi(2^31 - 1);
%  ainv = minv(a,p)
%
% ainv =
%     1656630242
%
%  mod(a*ainv,p)
% ans =
%     1
%
% Example:
%  a and p must be coprime, or a warning will
%  be generated. Since no inverse exists, an
%  empty will be returned.
%
%  minv(3,15)
% Warning: a and p must be relatively prime, gcd(a,p) == 1
% ans =
%     []
%
%  See also: mod, rem
%  
%  Author: John D'Errico
%  e-mail: woodchips@rochester.rr.com
%  Release: 1.0
%  Release date: 3/6/09


if nargin~=2
  error('minv requires two arguments, a and p')
end

if isempty(a) || isempty(p)
  % propagate empty
  x = [];
  return
end

if (numel(p) > 1) || (p < 2)
  error('p must be scalar, no less than 2')
end

% make sure that a has been reduced mod p
a = mod(a,p);

% just in case p is too large. arithmetic might
% overflow the double integer limit otherwise.
if p > floor(sqrt(2^53-1))
  a = vpi(a);
end

% Is a a scalar or an array?
if numel(a) == 1
  % a is scalar
  
  % special cases
  if (a == 1) || (a == (p-1))
    % 1 and -1 are self inverses
    x = a;
    return
  elseif a == 0
    % no inverse exists for 0
    warning('MINV:zero','zero has no inverse mod p')
    x = [];
    return
  end
  
  % test that gcd(a,p) == 1
  if gcd(a,p) ~= 1
    warning('MINV:coprime','a and p must be relatively prime, gcd(a,p) == 1')
    x = [];
    return
  end
  
  % so the code will work properly for both
  % numeric and vpi numbers.
  numflag = (isnumeric(a) && isnumeric(p));
  
  % initialize the "table" for the extended
  % Euclidean algorithm
  [Riminus1,Ri] = deal(p,a);
  [Uiminus1,Ui] = deal(0,1);
  [Viminus1,Vi] = deal(1,0);
  i = 2;
  while i > 0
    if numflag
      Qiplus1 = fix(Riminus1/Ri);
      Riplus1 = mod(Riminus1,Ri);
    else
      % I could have used the same code for
      % vpi numbers as for the numeric case, but
      % this is more efficient, since quotient
      % gives both terms at once.
      [Qiplus1,Riplus1] = quotient(Riminus1,Ri);
    end
    Uiplus1 = Uiminus1 - Qiplus1*Ui;
    if Riplus1 == 1
      x = Uiplus1;
      break
    end
    Viplus1 = Viminus1 - Qiplus1*Vi;
    i = i + 1;
    
    % shift the table
    [Riminus1,Ri] = deal(Ri,Riplus1);
    [Uiminus1,Ui] = deal(Ui,Uiplus1);
    [Viminus1,Vi] = deal(Vi,Viplus1);
  end
  
  % make sure that x was reduced mod p
  x = mod(x,p);
  
else
  % a was an array
  error('minv is not supported for general arrays')
  
end

Contact us at files@mathworks.com