Watchduck
Watchduck

Reputation: 1156

Factor large numbers in Matlab and then get the numbers in the result

I want to factor (these) large numbers, and Matlab does that perfectly well. (These are the results.)

The result of factor(NumberOfTypeSym) is another symbolic object:

>> factor( sym('79228162514264337589248983040') )

ans =

2^32*3*5*17*257*641*65537*6700417

But I can't do anything with that, except look at it.

Is there any way to access the single primes and exponents?

(It is beyond my comprehension, why they won't just give me an nx2 matrix, with the primes on the left, and the exponents on the right side.)

What I especially need at the moment is the number of primes in the result, i.e. the sum of all exponents.

Upvotes: 4

Views: 1367

Answers (4)

Christopher Creutzig
Christopher Creutzig

Reputation: 8774

Just to add another option:

N = sym('79228162514264337589248983040');
F = children(factor(N));
primefactors = F(2:2:end)

  primefactors =

  [ 2, 3, 5, 17, 257, 641, 65537, 6700417]

multiplicities = F(3:2:end)

  multiplicities =

  [ 32, 1, 1, 1, 1, 1, 1, 1]

sum(multiplicities)

  ans =

  39

Or, making use of a function found in the MuPAD documentation,

feval(symengine, 'numlib::Omega', N)

  ans =

  39

Upvotes: 0

Watchduck
Watchduck

Reputation: 1156

Just an extension of the answer provided by P0W:

function [ y ] = symfactor2mat( x )

    Str = char(x) ;

    Parts = regexp(Str,'*','split') ;

    Long = length(Parts) ;

    Mat = sym(ones(Long,2)) ;

    for m=1:Long
        Part = Parts{m} ;
        if isempty(strfind( Part, '^' ))
            Mat(m,1) = sym(Part) ;
        else
            PE = regexp(Part,'\^','split') ;  % prime and exponent
            Mat(m,1) = sym(PE{1}) ;
            Mat(m,2) = sym(PE{2}) ;
        end
    end

    y = Mat ;

end

Upvotes: 1

user85109
user85109

Reputation:

Easy is to use my vpi tool, found on the file exchange. This returns a direct list of integers.

x=factor(vpi('79228162514264337589248983040'))
x =
Columns 1 through 7
          2     2     2     2     2     2     2
Columns 8 through 14
          2     2     2     2     2     2     2
Columns 15 through 21
          2     2     2     2     2     2     2
Columns 22 through 28
          2     2     2     2     2     2     2
Columns 29 through 35
          2     2     2     2     3     5    17
Columns 36 through 39
        257   641   65537   6700417

The replacement (essentially ready for release) for vpi is vpij, which took half the time to factor that number, but vpij can handle considerably larger numbers than can vpi. In fact, the last thing to write is a yet more improved version of factor, but I'll probably release vpij before that is done.

Of course, the factors must be also variable precision integers, since some of those factors will be quite large. Here a number with 50+ digits that someone commented about on the math site recently.

N = vpij(84)^27 + 1
N =
    9026943488964407632833018690186861978797224381906945

x = factor(N)
x =
   5   17   19  109  367  757  2017  230077  397741265470599434164843152148837

Upvotes: 3

P0W
P0W

Reputation: 47824

How about this :

>> x=factor( sym('79228162514264337589248983040') )

x =

2^32*3*5*17*257*641*65537*6700417

>> p=char(x)

p =

2^32*3*5*17*257*641*65537*6700417

>> s=regexp(p,'*','split')

s = 

    '2^32'    '3'    '5'    '17'    '257'    '641'    '65537'    '6700417'

>> exp=regexp(s{1},'\^','split')

exp = 

    '2'    '32'
>> [exp s(2:end)]

ans = 

    '2'    '32'    '3'    '5'    '17'    '257'    '641'    '65537'    '6700417'

Now play with the characters, convert them to numbers, as required.

Upvotes: 3

Related Questions