Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re^4: OT: Finding Factor Closest To Square Root

by QM (Parson)
on Feb 20, 2005 at 07:39 UTC ( [id://432848]=note: print w/replies, xml ) Need Help??


in reply to Re^3: OT: Finding Factor Closest To Square Root
in thread OT: Finding Factor Closest To Square Root

Another optimisation possible if N is odd, is to step back by 2 each time.
And if N is even, factor out all the powers of 2, and run the algorithm against the remaining factor. For example,
1000 == 2**3 * 5**3
which leaves
125 == 5**3
leading to
5 * 2**2 == 20
as "close enough".

-QM
--
Quantum Mechanics: The dreams stuff is made of

Replies are listed 'Best First'.
Re^5: OT: Finding Factor Closest To Square Root
by BrowserUk (Patriarch) on Feb 20, 2005 at 15:26 UTC

    I moved away from using M::B::F. The "best" I came up with is:

    #! perl -slw use strict; my $NUM = $ARGV[ 0 ] || die 'No arg'; $NUM = eval $NUM if $NUM =~ m[\D]; my $root = sqrt( $NUM ); my $near = int $root; my $step = $NUM % 2 ? 2 : 1; $near-= $step while $near and $NUM % $near; $near = 1 unless $near; printf "%10.f (%10f) %.f\n", $NUM, $root, $near;

    It's a simple brute force search for a factor < root.

    There may be a way to use the prime factors to speed the search, but the time they take to produce, a linear search down from the root is quicker.

    Even with a largish prime like 988041964007, which means a linear search all the way to 1, this takes less than a second, where Math::Big::Factors::Factors_wheel() churns for hours trying to factorise it.

    Maybe there's a qucker factorising module out there somewhere? Even so, from what I've tried and seen from other peoples attempts, having the prime factors doesn't give you any obvious way to avoid what amounts to a linear search.


    Examine what is said, not who speaks.
    Silence betokens consent.
    Love the truth but pardon error.

      The original question started "given N and N's prime factorization", so it seems inappropriate to take into account the time taken to factorize.

      In this case though, note that 988041964007 = 7 x 11087 x 12731023 - you are losing accuracy by throwing out the BigInts.

      In general if the factorization of N is taking longer than it takes to do sqrt(N) trial divisions then the factorization algorithm is pretty bad, since "trial division up to the square root" is the classical example of a slow algorithm.

      Many of the high precision maths libraries out there do factorization - for example the pari library (Math::Pari) has a factorint() function:

      use Math::Pari qw/ factorint /; my $n = Math::Pari->new("988041964007"); my $f = factorint($n); my $count = $#{ $f->[0] }; print join(" * ", map { my($prime, $power) = ($f->[0][$_], $f->[1][$_]); $power > 1 ? "$prime ^ $power" : $prime } 0 .. $count), "\n"; 7 * 11087 * 12731023

      Note that this algorithm does not guarantee primality: for large factors you need to verify with an isprime() check.

      Hugo

        so it seems inappropriate to take into account the time taken to factorize

        Inappropriate maybe, but it's bloody boring waiting for it :)

        The other part of the argument against doing the factorising, is I haven't thought of, nor seen, a way to use them, that arrives at the result more quickly.

        As the factor you are looking for can be any combination (small c), of the prime factors of N, I haven't seen any algorithm that doesn't require an exhaustive search of those combinations plus trial division to determine if you've found the answer. The result is that the descending, linear search is easier to code and runs more quickly.

        I have produced the results for all the integers 1-2 million, and 3-4 million, 10-11 million and 100-101 million and then atttempted to find some sort of pattern to the results. There may be one there, but my meagre memory of numerical analysis is not enough to devine it.

        28.x% of of the low ranges are primes. This falls of very slowly as the scale of the range increases, but it's only dropped to 27.76% by the time you get the the 100-101 million range. This is worst case for the linear search. If the factorisation ran more quickly, then it would allow you to skip the search in those cases.

        Whether that would result in an overall speed up, given that you would have to factor all the numbers and (so far) fall back to a linear search for those Ns that are not primes, I think is dubious.

        As the range gets higher, the frequency of the primes gets less, so the benefit of performing the factorisation reduces as the cost of the linear search increases, but also the cost of the factorisation increase and much more rapidly that the cost of the linear search.

        I will install Math::Pari. I think it would be interesting to see if there is any pattern to the prime factors of the factor.

        This has probably already been analysed to death sometime, but if it has, I'm not typing in the right keywords to locate it.


        Examine what is said, not who speaks.
        Silence betokens consent.
        Love the truth but pardon error.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://432848]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (4)
As of 2024-04-19 04:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found