These are the results I have currently for the inputs [989 9400 43300 2400]:
tmoertel's haskell implementation of the cancelling code ( in 2.6 seconds):
[11:20:43.54] C:\ghc\ghc-6.4\code>FET < ex1.dat
+8.070604647867604097576877675243109941729476950993498765160880e-7030
[11:20:46.34] C:\ghc\ghc-6.4\code>
Using Math::Pari (in 26 ms):
P:\test>MP-FET.pl
8.070604647867604097576877668E-7030
1 trial of _default ( 24.817ms total), 24.817ms/trial
Using Math::BigInt (Yes. That 4 hrs 38 minutes!)
P:\test>MBF-FET.pl
8.070604647867604097576877675243109941729e-7030
1 trial of _default ( 16,699s total), 16,699s/trial
The whole point of the cancelling code is that you do not have to calculate the huge factorials in infinite precison (slow) math, because you reduce the factorials to products of sets of much smaller, prime factors and then cancel most of those.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
| [reply] [Watch: Dir/Any] [d/l] [select] |
Thanks for the update
I cannot read Haskell so I was not sure how the factoring was done. Going through the example it seems like tmoertel was just factoring like terms. If the code does further factoring (school days division) then I am surprised that it can loop through that fast!
If you take a look at my scratchpad I tried ikegami's logic on gcd. I added a condition to check for values == 1 to save an extra GCD. I also did not have the Math module he was using so picked up another one. This one takes about 9 minutes. It would be interesting to see what will happen if we apply BigInt from here onwards!
I am also curious to see the runtime of the prime factor approach. I shall try hv's code to see how fast it runs. If I remember correctly Euclidean algo for GCD is O(n+log n) and prime factorization is NP-complete. For small values, prime fact is a breeze but the complexity does not change so i shall let you know when i get around testing the runtime for it!
cheers
SK
| [reply] [Watch: Dir/Any] |
7!
-----
3! 4!
{ expand fac into series of multiplications }
P(2,3,4,5,6,7)
-----------------
P(2,3) * P(2,3,4)
{ merge multiplied products }
P(2,3,4,5,6,7)
-----------------
P(2,2,3,3,4)
{ cancel like terms across division boundary }
P(/,/,/,5,6,7)
-----------------
P(/,2,/,3,/)
{ multiply and divide remaining terms }
5 * 6 * 7
---------
2 * 3
{ result }
35
In reality, the code does all of these steps in a parallel pipeline, which means I don't have to pay the price for large intermediate terms: bits of big terms are plucked off and used as they are produced lazily. This is an essentially free benefit of using Haskell.
Cheers, Tom
| [reply] [Watch: Dir/Any] [d/l] |
The last two digits of the Math::Pari implementation's result seem to be off:
+8.070604647867604097576877675243109941729476950993498765160880e-7030
8.070604647867604097576877675243109941729e-7030
8.070604647867604097576877668E-7030 <-- Math::Pari
^^
Can you increase the implementation's precision? Or is that the limit?
Cheers, Tom
| [reply] [Watch: Dir/Any] [d/l] |
The precision is setable, but I had left at the default.
Increasing the precision to the point where it match or suppassed the accuracy of your Haskell code (a setting of 58), doubled the time it took to a gnat's under 50 ms:
[ 6:46:43.79] P:\test>MP-FET.pl
8.070604647867604097576877675243109941729476950993498765160880911582E-
+7030
1 trial of _default ( 49.865ms total), 49.865ms/trial
BTW: Could you explain something for me? In this:
cancel (x:xs) (y:ys)
| x == y = cancel xs ys
| x < y = let (xs', ys') = cancel xs (y:ys) in (x:xs', ys')
| otherwise = let (xs', ys') = cancel (x:xs) ys in (xs', y:ys')
cancel xs ys = (xs, ys)
I understand how it cancels between the lists, but I am confused about when it would pattern match against the second definition?
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
| [reply] [Watch: Dir/Any] [d/l] [select] |
| [reply] [Watch: Dir/Any] |
| [reply] [Watch: Dir/Any] |
| [reply] [Watch: Dir/Any] [d/l] [select] |