02 July 2013

factorization

Here's a recursive function that returns the factors of an integer:

factors=function(n){
n=abs(n)
out=NULL
new=0
if (floor(n) != ceiling(n))
return (factors(floor(n)))
for (i in 2:n){
if (n/i == floor(n/i)){
new=n/i
break
}
}
if (new==1){
return (i)
} else {
return (c(i, factors(new)))

}

The n=abs(n) and return (factors(floor(n))) statements protect against negative and non-integer inputs. The idea is take a number n and divide it by the numbers 2 up to n until that division results in another whole number. If it does and that number is n itself then the function returns i=n, else there is another factorization to be made and so returns i with the next factor by the statement return (c(i, factors(new))).

> factors(223092870)
[1]  2  3  5  7 11 13 17 19 23
>
> factors(1073741824)
[1] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
>
> factors(1765469)
[1] 1765469
>
> system.time(factors(223092870))
   user  system elapsed 
   0.09    0.39    0.48 
>
> system.time(factors(1073741824))
   user  system elapsed 
   1.13    1.53    2.66 
>
> system.time(factors(1765469))
   user  system elapsed 
   2.51    0.00    2.51 


Improvements can be made in at least one place. After n/2 we know there aren't going to be any new factors, but the code currently iterates through all the values from n/2 to n. Making some slight changes can decrease the computation time significantly, especially for prime numbers.

No comments:

Post a Comment