Hi, I am very new to 'R' and am trying to write an R function which returns the prime factors of a given number(n) Unfortunately, the function only works for very small numbers, if for example I pass 18 to the function a mysteriously long vector is returned. I have not been able to find where or why this is happening. I know I've done something wrong. I've tried using debugging statements. Sometimes the currentPrime variable seems to become some sort of array?! can you help? library(gmp) #passing 18 returns: 2 1 0 0 0 1 0 0 0 1 0 0 0 3 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 3 0 0 0 # expected: 2 3 3 getPrimeFactors = function(n){ primeList <- c() if( isprime(n) ){ primeList <- append(primeList,n) return (primeList) } currentPrime <- 2 while(TRUE){ # Check if input is divisible by the current prime if(n %% currentPrime == 0){ cat(sprintf("the number %f is divisible by %f\n", n, currentPrime)) n = n%/%currentPrime cat(sprintf("value of n is %f\n", n)) cat(sprintf("current prime :%f\n", currentPrime)) primeList = append(primeList,currentPrime) # print(c("list contents:", primeList)) currentPrime = 2 if( isprime(n)){ primeList = append(primeList, n) return (primeList) } } else{ cat(sprintf("the number %f is NOT divisible by %f\n", n, currentPrime)) #cat(sprintf("current prime before is: %f\n", currentPrime)) #print(c("current prime before:", currentPrime)) currentPrime = nextprime(currentPrime) #cat(sprintf("current prime after is: %f\n", currentPrime)) #print(c("current prime after:", currentPrime)) } } } } [[alternative HTML version deleted]]
Franklin Bretschneider
2015-Dec-03 13:29 UTC
[R] Problems trying to generate a prime factor vector
Hi Kevin Wright, Re:> > I am very new to 'R' and am trying to write an R function which returns the > prime factors of a given number(n) > > Unfortunately, the function only works for very small numbers, if for > example I pass 18 to the function > a mysteriously long vector is returned. I have not been able to find where > or why this is happening. > I know I've done something wrong. I've tried using debugging statements. > Sometimes the > currentPrime variable seems to become some sort of array?! > > > can you help? > > > library(gmp) >But why writing one? Such a function is already in gmp: factorize(n), and it works with fairly large numbers:>library(gmp) >factorize(12345678987654321)Big Integer ('bigz') object of length 13: [1] 2 2 2 2 5 7 11 73 101 109 109 137 167 Success, Frank ------ Franklin Bretschneider Dept of Biology Utrecht University bretschr at xs4all.nl
It's very commendable that you try writing your own functions to learn R. Of course the function factorize() is in gmp, but that's beside the point. Your code looks messy - before asking your question you could have removed all these print statements. It gets further messed up because you posted in HTML. The logic is awkward. Instead of returning from the inside of an infinite loop in spaghetti code fashion, write your loop to test for your termination condition. Use "<-" and "=" consistently! Don't write return (), but keep parentheses attached to their functions. "if( isprime(n) ){ return(n)}" is enough for your first test. DRY (Do not repeat yourself). Whenever you find yourself writing essentially the same code in different places of your function, your logic is almost always wrong (you have three different places where you append to your prime list). But, funny enough, that's not actually the source of your problem. The problem is: you are using the gmp function nextprime(), which - although it doesn't say so in it's help page - returns a big integer of class bigz. str(nextprime(2)) The problem is you can't mix integers and big integers in the same list. c(nextprime(2), nextprime(3)) c(27, nextprime(2), nextprime(3)) So keep it all as plain integers: currentPrime = as.integer(nextprime(currentPrime)) ... and it will work as expected. But do clean it up. B. PS: factorize(18) Big Integer ('bigz') object of length 3: [1] 2 3 3 ... On Dec 3, 2015, at 6:42 AM, Kevin Wright <wrightkevin3000 at gmail.com> wrote:> Hi, > > I am very new to 'R' and am trying to write an R function which returns the > prime factors of a given number(n) > > Unfortunately, the function only works for very small numbers, if for > example I pass 18 to the function > a mysteriously long vector is returned. I have not been able to find where > or why this is happening. > I know I've done something wrong. I've tried using debugging statements. > Sometimes the > currentPrime variable seems to become some sort of array?! > > > can you help? > > > library(gmp) > > > #passing 18 returns: 2 1 0 0 0 1 0 0 0 1 0 0 0 3 0 0 0 1 0 0 0 1 0 0 0 1 0 > 0 0 3 0 0 0 > # expected: 2 3 3 > getPrimeFactors = function(n){ > primeList <- c() > > if( isprime(n) ){ > primeList <- append(primeList,n) > return (primeList) > } > > currentPrime <- 2 > > while(TRUE){ > # Check if input is divisible by the current prime > if(n %% currentPrime == 0){ > cat(sprintf("the number %f is divisible by %f\n", n, > currentPrime)) > n = n%/%currentPrime > > cat(sprintf("value of n is %f\n", n)) > > cat(sprintf("current prime :%f\n", currentPrime)) > primeList = append(primeList,currentPrime) > # print(c("list contents:", primeList)) > > > currentPrime = 2 > > if( isprime(n)){ > > primeList = append(primeList, n) > return (primeList) > > } > > } > else{ > cat(sprintf("the number %f is NOT divisible by %f\n", n, > currentPrime)) > #cat(sprintf("current prime before is: %f\n", currentPrime)) > #print(c("current prime before:", currentPrime)) > currentPrime = nextprime(currentPrime) > #cat(sprintf("current prime after is: %f\n", currentPrime)) > #print(c("current prime after:", currentPrime)) > > } > > > > } > > > > > } > > > > > > > } > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
* ... in the same vector. On Dec 3, 2015, at 10:48 AM, Boris Steipe <boris.steipe at utoronto.ca> wrote:> It's very commendable that you try writing your own functions to learn R. Of course the function factorize() is in gmp, but that's beside the point. > > Your code looks messy - before asking your question you could have removed all these print statements. It gets further messed up because you posted in HTML. The logic is awkward. Instead of returning from the inside of an infinite loop in spaghetti code fashion, write your loop to test for your termination condition. Use "<-" and "=" consistently! Don't write return (), but keep parentheses attached to their functions. "if( isprime(n) ){ return(n)}" is enough for your first test. DRY (Do not repeat yourself). Whenever you find yourself writing essentially the same code in different places of your function, your logic is almost always wrong (you have three different places where you append to your prime list). > > But, funny enough, that's not actually the source of your problem. The problem is: you are using the gmp function nextprime(), which - although it doesn't say so in it's help page - returns a big integer of class bigz. > > str(nextprime(2)) > > The problem is you can't mix integers and big integers in the same list. > > c(nextprime(2), nextprime(3)) > c(27, nextprime(2), nextprime(3)) > > So keep it all as plain integers: > currentPrime = as.integer(nextprime(currentPrime)) > > ... and it will work as expected. > But do clean it up. > > > B. > > PS: > factorize(18) > Big Integer ('bigz') object of length 3: > [1] 2 3 3 > > ... > > > On Dec 3, 2015, at 6:42 AM, Kevin Wright <wrightkevin3000 at gmail.com> wrote: > >> Hi, >> >> I am very new to 'R' and am trying to write an R function which returns the >> prime factors of a given number(n) >> >> Unfortunately, the function only works for very small numbers, if for >> example I pass 18 to the function >> a mysteriously long vector is returned. I have not been able to find where >> or why this is happening. >> I know I've done something wrong. I've tried using debugging statements. >> Sometimes the >> currentPrime variable seems to become some sort of array?! >> >> >> can you help? >> >> >> library(gmp) >> >> >> #passing 18 returns: 2 1 0 0 0 1 0 0 0 1 0 0 0 3 0 0 0 1 0 0 0 1 0 0 0 1 0 >> 0 0 3 0 0 0 >> # expected: 2 3 3 >> getPrimeFactors = function(n){ >> primeList <- c() >> >> if( isprime(n) ){ >> primeList <- append(primeList,n) >> return (primeList) >> } >> >> currentPrime <- 2 >> >> while(TRUE){ >> # Check if input is divisible by the current prime >> if(n %% currentPrime == 0){ >> cat(sprintf("the number %f is divisible by %f\n", n, >> currentPrime)) >> n = n%/%currentPrime >> >> cat(sprintf("value of n is %f\n", n)) >> >> cat(sprintf("current prime :%f\n", currentPrime)) >> primeList = append(primeList,currentPrime) >> # print(c("list contents:", primeList)) >> >> >> currentPrime = 2 >> >> if( isprime(n)){ >> >> primeList = append(primeList, n) >> return (primeList) >> >> } >> >> } >> else{ >> cat(sprintf("the number %f is NOT divisible by %f\n", n, >> currentPrime)) >> #cat(sprintf("current prime before is: %f\n", currentPrime)) >> #print(c("current prime before:", currentPrime)) >> currentPrime = nextprime(currentPrime) >> #cat(sprintf("current prime after is: %f\n", currentPrime)) >> #print(c("current prime after:", currentPrime)) >> >> } >> >> >> >> } >> >> >> >> >> } >> >> >> >> >> >> >> } >> >> [[alternative HTML version deleted]] >> >> ______________________________________________ >> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >> https://stat.ethz.ch/mailman/listinfo/r-help >> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html >> and provide commented, minimal, self-contained, reproducible code. > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.