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.

modrank(A,p)
function R = modrank(A,p)
% modrank: compute the rank of an integer array, modulo p
% usage: R = modrank(A,p)
%
% Returns the rank of the matrix A under
% modulo arithmetic, mod p.
% 
% Because all operations are performed using
% integer arithmetic, the computed rank will
% be exact.
%
% Arguments: (input)
%  A - A must be a 2-d array of integer
%      elements, or any vpi array.
%
%  p - any scalar integer or vpi number
%      Required: p > 1
%
%      If p > sqrt(2^53-1), then computations
%      will be done in a vpi form, which will
%      be somewhat slower than otherwise.
% 
% Arguments: (output)
%  R - an integer that denotes the rank of A
%
%        0 <= R <= min(size(A))
%
% Example: 
%  A = magic(5)
% A =
%    17    24     1     8    15
%    23     5     7    14    16
%     4     6    13    20    22
%    10    12    19    21     3
%    11    18    25     2     9
%
% modrank(A,2)
% ans =
%      4
%
% modrank(A,5)
% ans =
%      2
%
% modrank(A,29)
% ans =
%      5
%
%  See also: rank, mod, rem
%  
% 
%  Author: John D'Errico
%  e-mail: woodchips@rochester.rr.com
%  Release: 1.0
%  Release date: 3/3/09

if (nargin~=2)
  error('Exactly two arguments required for modrank')
end

if (numel(p) ~= 1) || (p <= 1)
  error('p must be scalar numeric or scalar vpi, p > 1')
end

% an empty matrix must have rank 0
if isempty(A) || isempty(p) || (p == 1)
  R = 0;
  return
end

% get the shape of A
sa = size(A);
if length(sa) > 2
  error('A may not be more than a 2 dimensional array')
end
nr = sa(1);
nc = sa(2);

if (~isnumeric(A) && ~isa(A,'vpi')) || (isnumeric(A) && all((A(:)~=round(A(:)))))
  error('A must be an integer numeric array or a vpi array')
end

% if A has more rows than columns, best to transpose.
% this will not change the rank.
if (nr > nc)
  A = A.';
  [nr,nc] = deal(nc,nr);
end

% p mst be limited to sqrt(2^53 - 1), or else we must
% convert to vpi arithmetic
if p > sqrt(2^53-1)
  A = vpi(A);
end

% take the mod first, just in case
A = mod(A,p);

% do the work here. this will just be gaussian
% elimination, with column and row pivoting in
% case of zero pivots
i = 1;
R = nr; % in case we drop through the while loop
flag = true;
while flag && (i<=nr)
  % choose a pivot element
  [ipiv,jpiv] = find(A(i:nr,i:nc),1,'first');
  if isempty(ipiv)
    % the rank has been revealed if no
    % non-zeros remain for pivoting
    R = i-1;
    break
  end
  if i > 1
    ipiv = ipiv + i-1;
    jpiv = jpiv + i-1;
  end

  % swap rows
  if ipiv ~= i
    A([ipiv,i],:) = A([i,ipiv],:);
  end
  % and columns
  if jpiv ~= i
    A(:,[jpiv,i],:) = A(:,[i,jpiv]);
  end
  
  % kill off the remaining elements in the i'th column
  % if i == nr, then we are done, since A(i,i) must be
  % non-zero since we just did a pivot op.
  if i < nr
    % the pivot element
    piv = A(i,i);
    
    % which elements of A below the pivot are non-zero?
    k = i + find(A((i+1):nr,i));
    if ~isempty(k)
      for m = 1:length(k)
        A(k(m),(i+1):nc) = mod(piv*A(k(m),(i+1):nc) - A(k(m),i)*A(i,(i+1):nc),p);
        A(k(m),i) = 0;
      end
    end
  end
  
  % increment i to keep working
  i = i + 1;
end


Contact us