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.

nextprime(N,direction,kprimes)
function P = nextprime(N,direction,kprimes)
% nextprime: finds the next larger prime number directly above (or below) N
% usage: P = nextprime(N)
% usage: P = nextprime(N,direction)
% usage: P = nextprime(N,direction,kprimes)
%
% arguments: (input)
%  N - a positive scalar numeric variable or vpi number)
%      or an array of numbers.
%
%  direction - (OPTIONAL) character string (or empty)
%      Either 'above' or 'below', or any simple shortening
%      that matches the first few characters in those words.
%
%      'above' --> Finds the first prime P > N
%      'below' --> Finds the first prime P < N
%
%      An attempt to find the next prime BELOW 2 will
%      result in a NaN, and a warning message.
%
%      DEFAULT: 'above'
%
%
% Example:
%  nextprime(100:10:200)
% ans =
%   101   113   127   131   149   151   163   173   181   191   211
% 
%  nextprime(100:10:200,'below')
% ans =
%    97   109   113   127   139   149   157   167   179   181   199
% 
%  nextprime(vpi('10000000000000'))
% ans =
%   10000000000037
%
%
%  See also: isprime, factor
%
%
%  Author: John D'Errico
%  e-mail: woodchips@rochester.rr.com
%  Release: 2.0
%  Release date: 4/9/09

if nargin<2 || isempty(direction)
  incsign = 1;
elseif ~ischar(direction)
  error('NEXTPRIME:direction',...
    'direction must be either ''above'' or ''below''')
else
  valid = {'above','below'};
  ind = strmatch(direction,valid);
  if ~isempty(ind)
    if ind == 1
      incsign = 1;
    else
      incsign = -1;
    end
  else
    error('NEXTPRIME:direction',...
      'direction must be either ''above'' or ''below''')
  end
end

if any(N(:) <= 0)
  error('NEXTPRIME:PositiveN',...
    'N must be a positive number, or an array of positive numbers')
end

% If the inputs are a numeric variable, support only inputs
% as large as 2^46 in terms of doubles.
if isnumeric(N) && (any(N(:) > 2^46))
  % I could convert (on the fly) any numeric variable to
  % vpi above some limit. I'd be limited to 2^53 there
  % anyway, since doubles are not represented exactly as
  % integers beyond 2^53.
  %
  % For 2^46 <= N <= 2^53, I could switch to a vpi form
  % on the fly. This seems rude to me, since the user might
  % not have vpi installed, but changing class here to a
  % vpi seems a rude surprise. If N is already a vpi number
  % and of any size, then nextprime will work with ease.
  %
  % So I've chosen to replace the call to isprime with a
  % hacked version of isprime, called isbigprime. This will
  % allow nextprime to work up to 2^46. isprime actually
  % works slightly beyond 2^46, but I need to leave some
  % headroom there to find larger primes.
  error('NEXTPRIME:InputOutOfRange',...
    'The maximum value of N (for numeric input) allowed is 2^46.');
end

% set a flag to indicate the vpi version of isprime
% this gets around a bug in MATLAB, because if I named
% isbigprime as isprime, then the wrong version gets
% called when N is a vpi number.
Nisvpi = isa(N,'vpi');

% just in case N was not an integer
switch incsign
  case 1
    % take the floor of N. If it was
    % an integer already, then no harm
    N = floor(N);
  case -1
    N = ceil(N);
end

% pre-allocate the result
P = N;

% possession of a few small primes will help us
% to avoid actually testing every number for
% explicit primality.
smallprimes = primes(5*max(1,max(ceil(log2(N)))));
oddprimes = smallprimes(2:end);

for i = 1:numel(N)
  Ni = N(i);
  if (Ni + incsign) <= smallprimes(end)
    % N is really small
    switch incsign
      case 1
        k = find(Ni < smallprimes,1,'first');
        P(i) = smallprimes(k);
      case -1
        if Ni > 2
          k = find(Ni > smallprimes,1,'last');
          P(i) = smallprimes(k);
        else
          if Nisvpi
            error('NEXTPRIME:SmallPrimes', ...
              'There is no prime below 2. An error since vpi numbers cannot be NaN')
          else
            warning('NEXTPRIME:SmallPrimes', ...
              'There is no prime below 2. NaN returned')
            P(i) = NaN;
          end
        end
    end
  else
    % N is large enough
    flag = true;
    if rem(Ni,2) == 0
      % Ni is even, so shift it to an odd number
      % since we know the next prime must be odd.
      % we don't need to worry about 2, since the
      % small primes were already weeded out.
      Ni = Ni - incsign;
    end
    moduli = double(mod(Ni,oddprimes));
    offset = 0;
    while flag
      offset = offset + 2*incsign;
      
      if any((Ni + offset) == smallprimes) || ...
          (all(0 ~= mod(offset + moduli,oddprimes)) && ...
          (Nisvpi && isprime(Ni+offset)) || (~Nisvpi && isbigprime(Ni + offset)))
        P(i) = Ni + offset;
        flag = false;
      end
    end
  end
end

% ================================
% end mainline, begin subfunctions
% =================================

function isp = isbigprime(X)
%isbigprime True for prime numbers. This version works up to 1.5*2^46.
%   isbigprime(X) is 1 for the elements of X that are prime, 0 otherwise.
%
%   Class support for input X:
%      float: double, single
%
%   See also FACTOR, PRIMES.

% Modified from the built-in R2007b version to work for larger inputs.
%  Copyright 1984-2006 The MathWorks, Inc. 

if isempty(X), isp = false(size(X)); return, end
if ~isreal(X) || any(X(:) < 0) || any(floor(X(:)) ~= X(:))
  error('MATLAB:isbigprime:InputNotPosInt',...
        'All entries of X must be positive integers.'); 
end

isp = false(size(X));
n = max(X(:));
if n > (1.5*2^46)
    error('NEXTPRIME:isbigprime:InputOutOfRange',...
          'The maximum value of X allowed is 2^46.');
end

p = primes(ceil(sqrt(n)));
for k = 1:numel(isp)
   isp(k) = all(rem(X(k), p(p<X(k))));
end

% p(p<1) would give an empty matrix and all([]) returns true.
% we need to correct isp for this case.
isp(X==1 | X==0)=0;



Contact us at files@mathworks.com