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.

lineardiophantine(A,B,C)
function [x0,y0,xt,yt] = lineardiophantine(A,B,C)
% lineardiophantine: solve the linear Diophantine equation, A*x + B*y = C
% usage: [x0,x0,yt,yt] = lineardiophantine(A,B,C)
%
% http://en.wikipedia.org/wiki/Diophantine_equation
%
% The solution will be written parametrically as
%   x = x0 + xt*t
%   y = y0 + yt*t
% where t is any integer value
%
% Arguments: (input)
%  A,B,C - scalar, integer coefficients of the
%       linear Diophantine equation, A*x + B*y = C

if nargin~=3
  error('Must supply all three of A, B, C as arguments')
end

% special cases?
if C == 0
  % the solution is simple.
  % x = B*t, y = A*t
  x0 = 0;
  xt = B;
  y0 = 0;
  yt = -A;
  return
elseif (A == 0) && (B == 0)
  % No solution exists when both A and B
  % are zero, but C is non-zero
  x0 = [];
  xt = [];
  y0 = [];
  yt = [];
  
  warning('LINEARDIOPHANTINE:nosolution', ...
    'No solution exists, A==B==0, but C~=0')
  
  return
elseif A == 0
  % this reduces to the solutions of
  % B*y = C. B is not zero here.
  if gcd(B,C) == B
    y0 = C/B;
    yt = 0;
    x0 = 0;
    xt = 0;
    return
  else
    % no solution can exist otherwise
    x0 = [];
    xt = [];
    y0 = [];
    yt = [];
    
    warning('LINEARDIOPHANTINE:nosolution',...
      'No solutions exist, A == 0, but C is not divisible by B')
    
    return
  end
elseif B == 0
  % this reduces to the solutions of
  % A*x = C. A is not zero here.
  if gcd(A,C) == A
    y0 = 0;
    yt = 0;
    x0 = C/A;
    xt = 0;
    return
  else
    % no solution can exist otherwise
    x0 = [];
    xt = [];
    y0 = [];
    yt = [];
    
    warning('LINEARDIOPHANTINE:nosolution', ...
      'No solutions exist, B == 0, but C is not divisible by A')
    
    return
  end
end

% The final test is against the gcd(A,B).
% gcd(A,B) must also divide C.
G = gcd(A,B);
R = mod(C,G);
if R ~= 0
  x0 = [];
  xt = [];
  y0 = [];
  yt = [];
  
  warning('LINEARDIOPHANTINE:nosolution', ...
    'No solution can exist. C must be divisible by gcd(A,B).')
  
  return
end

% reduce the problem by dividing out any
% common factors of all three numbers.
A = A/G;
B = B/G;
C = C/G;

% negative C
if C < 0
  C = abs(C);
  A = -A;
  B = -B;
end
% or negative A or B
Asign = sign(A);
Bsign = sign(B);
A = abs(A);
B = abs(B);

% If we make it to here, then the solution
% is given by the extended Euclidean algorithm,
% which solves the problem for C == 1.
xt = B;
yt = -A;

% all we need now is one particular solution.
R1 = vpi(A); % make sure that quotient will run
R2 = B; % we already know that B ~= 0
[x1,x2] = deal(1,0);
[y1,y2] = deal(0,1);

% get the particular solution by iteratively calling quotient.
R = 1;
while (R~=0)
  [Q,R] = quotient(R1,R2);
  if R == 0
    % we are done
    x0 = x2;
    y0 = y2;
  else
    % more to do
    [R1,R2] = deal(R2,R);
    [x1,x2] = deal(x2,x1 - x2*Q);
    [y1,y2] = deal(y2,y1 - y2*Q);
  end
end

% now correct for C~=1
if C ~= 1
  x0 = x0*C;
  y0 = y0*C;
end

if Asign < 0
  x0 = -x0;
  xt = -xt;
end
if Bsign < 0
  y0 = -y0;
  yt = -yt;
end

Contact us