├── .gitignore ├── GoFactorial ├── binomial │ ├── binomial.go │ └── binomial_test.go ├── doublefactorial │ ├── doublefactorial.go │ └── doublefactorial_test.go ├── go.mod ├── primefactorial │ ├── primefactorial.go │ └── primefactorial_test.go ├── primes │ ├── primes.go │ └── primes_test.go ├── simplefactorial │ ├── simplefactorial.go │ └── simplefactorial_test.go ├── swingfactorial │ ├── swingfactorial.go │ └── swingfactorial_test.go └── xmath │ ├── xmath.go │ └── xmath_test.go ├── JavaFactorial ├── dist │ ├── FactorialBench2015.jar │ ├── README.TXT │ └── lib │ │ ├── apfloat.jar │ │ ├── applet.jar │ │ ├── jgoodies-common-1.8.1.jar │ │ ├── jgoodies-forms-1.9.0.jar │ │ └── jgoodies-looks-2.7.0.jar ├── readme.html └── src │ └── de │ └── luschny │ ├── apps │ ├── LoggedTextBox.java │ ├── StopWatch.java │ └── factorial │ │ ├── AboutDialog.java │ │ ├── BenchmarkApplication.java │ │ ├── BenchmarkForm.java │ │ ├── BenchmarkWorker.java │ │ ├── Candidate.java │ │ ├── FactorialTest.java │ │ └── Results.java │ └── math │ ├── Xmath.java │ ├── arithmetic │ └── Xint.java │ ├── factorial │ ├── FactorialAdditiveMoessner.java │ ├── FactorialAdditiveSwing.java │ ├── FactorialBoitenSplit.java │ ├── FactorialDifference.java │ ├── FactorialFactors.java │ ├── FactorialHyper.java │ ├── FactorialParallelPrimeSplit.java │ ├── FactorialParallelPrimeSwing.java │ ├── FactorialParallelSplit.java │ ├── FactorialParallelSwing.java │ ├── FactorialPoorMans.java │ ├── FactorialPrimeBorwein.java │ ├── FactorialPrimeLeenstra.java │ ├── FactorialPrimeSchoenhage.java │ ├── FactorialPrimeSwing.java │ ├── FactorialPrimeSwingCache.java │ ├── FactorialPrimeSwingList.java │ ├── FactorialPrimeVardi.java │ ├── FactorialProductNaive.java │ ├── FactorialProductRecursive.java │ ├── FactorialSplit.java │ ├── FactorialSquaredDiff.java │ ├── FactorialSquaredDiffProd.java │ ├── FactorialSwing.java │ ├── FactorialSwingDouble.java │ ├── FactorialSwingRational.java │ ├── FactorialSwingRationalDouble.java │ ├── FactorialSwingSimple.java │ └── IFactorialFunction.java │ ├── primes │ ├── IPrimeIteration.java │ ├── IPrimeSieve.java │ └── PrimeSieve.java │ └── util │ ├── ILoggable.java │ └── PositiveRange.java ├── JuliaFactorial ├── BasicSwingFactorial.jl └── PrimeSwingFactorialJulia.jl ├── LICENSE ├── MpirBasedFunctions ├── ClassDiagram.png ├── binomial.cpp ├── binomial.h ├── double_fac_ui.cpp ├── doublefactorial.cpp ├── lmp.h ├── main.cpp ├── makefile ├── parallelbinomial.cpp ├── paralleldoublefactorial.cpp ├── parallelschoenhage.cpp ├── parallelswing.cpp ├── primeswing.cpp ├── primeswing.h ├── readme.txt ├── schoenhage.cpp ├── schoenhage.h ├── stopwatch.h ├── test.h └── xmath.h ├── PerlFactorial └── BasicSwingFactorial.pl ├── PythonFactorial ├── PrimeSwingFactorialGmpy.py └── PrimeSwingFactorialPy.py ├── README.md ├── SageMathFactorial └── SageMathPrimeSwingFactorial.ipynb └── SilverFactorial64 ├── Sharith ├── Arithmetic │ └── XInt.cs ├── Factorial │ ├── Binomial.cs │ ├── FactorialAdditiveMoessner.cs │ ├── FactorialAdditiveSwing.cs │ ├── FactorialBalkan.cs │ ├── FactorialBalkanBig.cs │ ├── FactorialBoitenSplit.cs │ ├── FactorialCrandallPomerance.cs │ ├── FactorialFactors.cs │ ├── FactorialHyper.cs │ ├── FactorialLinearDifference.cs │ ├── FactorialMyFactorial.cs │ ├── FactorialParallelForPrimeSplit.cs │ ├── FactorialParallelPrimeSplit.cs │ ├── FactorialParallelPrimeSwing.cs │ ├── FactorialParallelPrimeSwingList.cs │ ├── FactorialParallelSplit.cs │ ├── FactorialParallelSplitPrimeSwing.cs │ ├── FactorialParallelSwing.cs │ ├── FactorialPoorMans.cs │ ├── FactorialPrimeBorwein.cs │ ├── FactorialPrimeLeenstra.cs │ ├── FactorialPrimeSchoenhage.cs │ ├── FactorialPrimeSwing.cs │ ├── FactorialPrimeSwingAllInOne.cs │ ├── FactorialPrimeSwingCache.cs │ ├── FactorialPrimeSwingList.cs │ ├── FactorialPrimeVardi.cs │ ├── FactorialProductNaive.cs │ ├── FactorialProductRecursive.cs │ ├── FactorialSplit.cs │ ├── FactorialSquaredDiffProd.cs │ ├── FactorialSquaredDifference.cs │ ├── FactorialSwing.cs │ ├── FactorialSwingDouble.cs │ ├── FactorialSwingRational.cs │ ├── FactorialSwingRationalDouble.cs │ ├── FactorialSwingSimple.cs │ └── IFactorialFunction.cs ├── MathUtils │ ├── PositiveRange.cs │ └── XMath.cs ├── Primes │ ├── IPrimeCollection.cs │ ├── IPrimeSieve.cs │ └── PrimeSieve.cs ├── Properties │ └── AssemblyInfo.cs └── Sharith.csproj ├── SilverFactorial ├── Application.xaml ├── Application.xaml.cs ├── Benchmark │ ├── Candidates.cs │ ├── Results.cs │ ├── TestParameters.cs │ └── Worker.cs ├── BrowserForm.cs ├── BrowserForm.resx ├── LoggedTextBox.cs ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ ├── Settings.settings │ └── app.manifest ├── SilverFactorial.csproj ├── app.config ├── bin │ └── x64 │ │ └── Release │ │ ├── Sharith.dll │ │ ├── SilverFactorial.application │ │ ├── SilverFactorial.exe │ │ ├── SilverFactorial.exe.config │ │ ├── SilverFactorial.exe.manifest │ │ └── mpir.dll ├── mpir.dll └── silverfactorial.ico └── SilverFactorial64.sln /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | *.vs 44 | 45 | # Build results 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | *_i.c 49 | *_p.c 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.vspscc 64 | .builds 65 | *.dotCover 66 | 67 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 68 | #packages/ 69 | 70 | # Visual C++ cache files 71 | ipch/ 72 | *.aps 73 | *.ncb 74 | *.opensdf 75 | *.sdf 76 | 77 | # Visual Studio profiler 78 | *.psess 79 | *.vsp 80 | 81 | # ReSharper is a .NET coding add-in 82 | _ReSharper* 83 | 84 | # Installshield output folder 85 | [Ee]xpress 86 | 87 | # DocProject is a documentation generator add-in 88 | DocProject/buildhelp/ 89 | DocProject/Help/*.HxT 90 | DocProject/Help/*.HxC 91 | DocProject/Help/*.hhc 92 | DocProject/Help/*.hhk 93 | DocProject/Help/*.hhp 94 | DocProject/Help/Html2 95 | DocProject/Help/html 96 | 97 | # Click-Once directory 98 | publish 99 | 100 | # Others 101 | [Bb]in 102 | [Oo]bj 103 | sql 104 | TestResults 105 | *.Cache 106 | ClientBin 107 | stylecop.* 108 | ~$* 109 | *.dbmdl 110 | Generated_Code #added for RIA/Silverlight projects 111 | 112 | # Backup & report files from converting an old project file to a newer 113 | # Visual Studio version. Backup files are not needed, because we have git ;-) 114 | _UpgradeReport_Files/ 115 | Backup*/ 116 | UpgradeLog*.XML 117 | 118 | 119 | 120 | ############ 121 | ## Windows 122 | ############ 123 | 124 | # Windows image file caches 125 | Thumbs.db 126 | 127 | # Folder config file 128 | Desktop.ini 129 | 130 | 131 | ############# 132 | ## Python 133 | ############# 134 | 135 | *.py[co] 136 | 137 | # Packages 138 | *.egg 139 | *.egg-info 140 | 141 | build 142 | eggs 143 | parts 144 | bin 145 | var 146 | sdist 147 | develop-eggs 148 | .installed.cfg 149 | 150 | # Installer logs 151 | pip-log.txt 152 | 153 | # Unit test / coverage reports 154 | .coverage 155 | .tox 156 | 157 | #Translations 158 | *.mo 159 | 160 | #Mr Developer 161 | .mr.developer.cfg 162 | 163 | # Mac crap 164 | .DS_Store 165 | -------------------------------------------------------------------------------- /GoFactorial/binomial/binomial.go: -------------------------------------------------------------------------------- 1 | // binomial package binomial.go 2 | // 2010/6/29 Sonia Keys 3 | // 2011/6/29 edited Peter Luschny 4 | // MIT license 5 | 6 | package binomial 7 | 8 | import ( 9 | "math/big" 10 | 11 | "github.com/PeterLuschny/Fast-Factorial-Functions/GoFactorial/primes" 12 | "github.com/PeterLuschny/Fast-Factorial-Functions/GoFactorial/xmath" 13 | ) 14 | 15 | func binomial(p *primes.Sieve, n, k uint64) *big.Int { 16 | var r big.Int 17 | if k > n { 18 | return &r 19 | } 20 | 21 | if k > n/2 { 22 | k = n - k 23 | } 24 | 25 | if k < 3 { 26 | switch k { 27 | case 0: 28 | return r.SetInt64(1) 29 | case 1: 30 | return r.SetInt64(int64(n)) 31 | case 2: 32 | var n1 big.Int 33 | return r.Rsh(r.Mul(r.SetInt64(int64(n)), n1.SetInt64(int64(n-1))), 1) 34 | } 35 | } 36 | 37 | var i int 38 | rootN := xmath.FloorSqrt(n) 39 | factors := make([]uint64, n) 40 | 41 | p.IteratePrimes(2, rootN, func(p uint64) { 42 | var r, nn, kk uint64 = 0, n, k 43 | for nn > 0 { 44 | if nn%p < kk%p+r { 45 | r = 1 46 | factors[i] = p 47 | i++ 48 | } else { 49 | r = 0 50 | } 51 | nn /= p 52 | kk /= p 53 | } 54 | }) 55 | 56 | p.IteratePrimes(rootN+1, n/2, func(p uint64) { 57 | if n%p < k%p { 58 | factors[i] = p 59 | i++ 60 | } 61 | }) 62 | 63 | p.IteratePrimes(n-k+1, n, func(p uint64) { 64 | factors[i] = p 65 | i++ 66 | }) 67 | 68 | return xmath.Product(factors[0:i]) 69 | } 70 | 71 | func Binomial(n, k uint64) *big.Int { 72 | p := primes.Primes(n) 73 | return binomial(p, n, k) 74 | } 75 | -------------------------------------------------------------------------------- /GoFactorial/binomial/binomial_test.go: -------------------------------------------------------------------------------- 1 | // binomial_test project binomial_test.go 2 | 3 | package binomial 4 | 5 | import ( 6 | "fmt" 7 | "math/big" 8 | "strconv" 9 | "testing" 10 | ) 11 | 12 | var four00, _ = new(big.Int).SetString("102440298642203415893508338627265658464886492916495172372984138881515753604628814525708055242762679553795073231350024000", 10) 13 | var five00, _ = new(big.Int).SetString("2314422827984300469017756871661048812545657819062792522329327913362690", 10) 14 | var binomialBenchmarks = []uint64{ 15 | 100, 16 | 1000, 17 | 10000, 18 | 100000, 19 | 1000000, 20 | 2000000, 21 | } 22 | 23 | func BenchmarkBinomial(b *testing.B) { 24 | for _, benchmark := range binomialBenchmarks { 25 | b.Run(fmt.Sprintf("%d", benchmark), func(b *testing.B) { 26 | for j := 0; j < b.N; j++ { 27 | Binomial(benchmark, benchmark/3) 28 | } 29 | }) 30 | } 31 | } 32 | 33 | func BenchmarkGoBinomial(b *testing.B) { 34 | for _, benchmark := range binomialBenchmarks { 35 | var bi big.Int 36 | b.Run(fmt.Sprintf("%d", benchmark), func(b *testing.B) { 37 | for j := 0; j < b.N; j++ { 38 | bi.Binomial(int64(benchmark), int64(benchmark/3)) 39 | 40 | } 41 | }) 42 | } 43 | } 44 | 45 | func TestBinomial(t *testing.T) { 46 | tests := []struct { 47 | inputN, inputK uint64 48 | expected *big.Int 49 | }{ 50 | {0, 0, big.NewInt(1)}, 51 | {1, 0, big.NewInt(1)}, 52 | {1, 1, big.NewInt(1)}, 53 | {2, 0, big.NewInt(1)}, 54 | {2, 1, big.NewInt(2)}, 55 | {2, 2, big.NewInt(1)}, 56 | {3, 0, big.NewInt(1)}, 57 | {3, 1, big.NewInt(3)}, 58 | {3, 2, big.NewInt(3)}, 59 | {3, 3, big.NewInt(1)}, 60 | {123, 108, big.NewInt(int64(7012067478708989884))}, 61 | {400, 199, four00}, 62 | {500, 50, five00}, 63 | {1000, 998, big.NewInt(499500)}, 64 | } 65 | for ii, tt := range tests { 66 | t.Run(strconv.Itoa(ii), func(t *testing.T) { 67 | if gotR := Binomial(tt.inputN, tt.inputK); gotR.Cmp(tt.expected) != 0 { 68 | t.Errorf("Binomial() = %v, want %v", gotR, tt.expected) 69 | } 70 | }) 71 | } 72 | } 73 | 74 | func TestBinomial2(t *testing.T) { 75 | for n := 10; n < 1<<10; n++ { 76 | for k := 0; k < n; k++ { 77 | expected := new(big.Int).Binomial(int64(n), int64(k)) 78 | actual := Binomial(uint64(n), uint64(k)) 79 | if expected.Cmp(actual) != 0 { 80 | t.Fatalf("expected (%v,%v) to match", n, k) 81 | } 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /GoFactorial/doublefactorial/doublefactorial.go: -------------------------------------------------------------------------------- 1 | // doublefactorial package doublefactorial.go 2 | // 2010/6/29 Sonia Keys 3 | // 2011/6/29 edited Peter Luschny 4 | // MIT license 5 | 6 | package doublefactorial 7 | 8 | import ( 9 | "math/big" 10 | 11 | "github.com/PeterLuschny/Fast-Factorial-Functions/GoFactorial/swingfactorial" 12 | "github.com/PeterLuschny/Fast-Factorial-Functions/GoFactorial/xmath" 13 | ) 14 | 15 | // returns nil if sieve not big enough 16 | func doubleFactorial(s *swingfactorial.Swing, n uint64) (r *big.Int) { 17 | 18 | nEven := n&1 == 0 19 | 20 | if n < uint64(len(smallOddDoubleFactorial)) { 21 | r = big.NewInt(smallOddDoubleFactorial[n]) 22 | } else { 23 | var nn uint64 24 | if nEven { 25 | nn = n / 2 26 | } else { 27 | nn = n + 1 28 | } 29 | r = oddDoubleFactorial(s, nn, n) 30 | } 31 | 32 | if nEven { 33 | exp := uint(n - uint64(xmath.BitCount64(n))) 34 | r.Lsh(r, exp) 35 | } 36 | 37 | return 38 | } 39 | 40 | func oddDoubleFactorial(s *swingfactorial.Swing, n, m uint64) *big.Int { 41 | 42 | if n < uint64(len(smallOddFactorial)) { 43 | return big.NewInt(smallOddFactorial[n]) 44 | } 45 | 46 | of := oddDoubleFactorial(s, n/2, m) 47 | if n < m { 48 | of.Mul(of, of) 49 | } 50 | 51 | return of.Mul(of, s.OddSwing(n)) 52 | } 53 | 54 | func DoubleFactorial(n uint64) *big.Int { 55 | s := swingfactorial.NewSwing(n + 1) 56 | return doubleFactorial(s, n) 57 | } 58 | 59 | var smallOddFactorial []int64 = []int64{1, 1, 1, 3, 3, 60 | 15, 45, 315, 315, 2835, 14175, 155925, 467775, 61 | 6081075, 42567525, 638512875, 638512875, 10854718875, 62 | 97692469875, 1856156927625, 9280784638125, 194896477400625, 63 | 2143861251406875, 49308808782358125, 147926426347074375, 64 | 3698160658676859375} 65 | 66 | var smallOddDoubleFactorial []int64 = []int64{1, 1, 1, 3, 1, 67 | 15, 3, 105, 3, 945, 15, 10395, 45, 135135, 315, 2027025, 315, 68 | 34459425, 2835, 654729075, 14175, 13749310575, 155925, 69 | 316234143225, 467775, 7905853580625, 6081075, 213458046676875, 70 | 42567525, 6190283353629375, 638512875, 191898783962510625, 71 | 638512875, 6332659870762850625, 10854718875} 72 | -------------------------------------------------------------------------------- /GoFactorial/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/PeterLuschny/Fast-Factorial-Functions/GoFactorial 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /GoFactorial/primefactorial/primefactorial.go: -------------------------------------------------------------------------------- 1 | // primefactorial package primefactorial.go 2 | // 2010/6/29 Sonia Keys 3 | // 2011/6/29 edited Peter Luschny 4 | // MIT license 5 | 6 | package primefactorial 7 | 8 | import ( 9 | "math/big" 10 | 11 | "github.com/PeterLuschny/Fast-Factorial-Functions/GoFactorial/swingfactorial" 12 | "github.com/PeterLuschny/Fast-Factorial-Functions/GoFactorial/xmath" 13 | ) 14 | 15 | func Factorial(n uint64) *big.Int { 16 | 17 | if n < 20 { 18 | var r big.Int 19 | return r.MulRange(1, int64(n)) 20 | } 21 | 22 | s := swingfactorial.NewSwing(n) 23 | r := OddFactorial(s, n) 24 | exp := uint(n - uint64(xmath.BitCount64(n))) 25 | return r.Lsh(r, exp) 26 | } 27 | 28 | func OddFactorial(s *swingfactorial.Swing, n uint64) *big.Int { 29 | 30 | if n < uint64(len(smallOddFactorial)) { 31 | return big.NewInt(smallOddFactorial[n]) 32 | } 33 | 34 | of := OddFactorial(s, n/2) // recurse 35 | of.Mul(of, of) // square 36 | 37 | return of.Mul(of, s.OddSwing(n)) 38 | } 39 | 40 | var smallOddFactorial []int64 = []int64{1, 1, 1, 3, 3, 41 | 15, 45, 315, 315, 2835, 14175, 155925, 467775, 42 | 6081075, 42567525, 638512875, 638512875, 10854718875, 43 | 97692469875, 1856156927625, 9280784638125, 194896477400625, 44 | 2143861251406875, 49308808782358125, 147926426347074375, 45 | 3698160658676859375} 46 | -------------------------------------------------------------------------------- /GoFactorial/primefactorial/primefactorial_test.go: -------------------------------------------------------------------------------- 1 | // primeswing_test project 2 | 3 | package primefactorial 4 | 5 | import ( 6 | "fmt" 7 | "math/big" 8 | "strconv" 9 | "testing" 10 | ) 11 | 12 | var six5, _ = new(big.Int).SetString("8247650592082470666723170306785496252186258551345437492922123134388955774976000000000000000", 10) 13 | var one00, _ = new(big.Int).SetString("93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000", 10) 14 | var four02, _ = new(big.Int).SetString("10322493151921465164081017511444523549144957788957729070658850054871632028467255601190963314928373192348001901396930189622367360453148777593779130493841936873495349332423413459470518031076600468677681086479354644916620480632630350145970538235260826120203515476630017152557002993632050731959317164706296917171625287200618560036028326143938282329483693985566225033103398611546364400484246579470387915281737632989645795534475998050620039413447425490893877731061666015468384131920640823824733578473025588407103553854530737735183050931478983505845362197959913863770041359352031682005647007823330600995250982455385703739491695583970372977196372367980241040180516191489137558020294105537577853569647066137370488100581103217089054291400441697731894590238418118698720784367447615471616000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 10) 15 | var benchmarks = []uint64{ 16 | 100, 17 | 1000, 18 | 10000, 19 | 100000, 20 | // 1000000, 21 | } 22 | 23 | func BenchmarkFactorial(b *testing.B) { 24 | for _, benchmark := range benchmarks { 25 | b.Run(fmt.Sprintf("%d", benchmark), func(b *testing.B) { 26 | for j := 0; j < b.N; j++ { 27 | Factorial(benchmark) 28 | } 29 | }) 30 | } 31 | } 32 | 33 | func BenchmarkGoFactorial(b *testing.B) { 34 | for _, benchmark := range benchmarks { 35 | b.Run(fmt.Sprintf("%d", benchmark), func(b *testing.B) { 36 | for j := 0; j < b.N; j++ { 37 | Factorial(benchmark) 38 | } 39 | }) 40 | } 41 | } 42 | 43 | func TestFactorial(t *testing.T) { 44 | tests := []struct { 45 | input uint64 46 | expected *big.Int 47 | }{ 48 | {0, big.NewInt(1)}, 49 | {1, big.NewInt(1)}, 50 | {2, big.NewInt(2)}, 51 | {3, big.NewInt(6)}, 52 | {4, big.NewInt(24)}, 53 | {20, big.NewInt(int64(2432902008176640000))}, 54 | {65, six5}, 55 | {100, one00}, 56 | {402, four02}, 57 | } 58 | for ii, tt := range tests { 59 | t.Run(strconv.Itoa(ii), func(t *testing.T) { 60 | if got := Factorial(tt.input); got.Cmp(tt.expected) != 0 { 61 | t.Errorf("Factorial() = %v, want %v", got, tt.expected) 62 | } 63 | }) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /GoFactorial/primes/primes_test.go: -------------------------------------------------------------------------------- 1 | // primes_test project primes_test.go 2 | // 2010/6/29 Sonia Keys 3 | // 2011/6/29 edited Peter Luschny 4 | // MIT license 5 | 6 | package primes 7 | 8 | import ( 9 | "fmt" 10 | "strconv" 11 | "testing" 12 | ) 13 | 14 | var benchmarks = []uint64{ 15 | 10000, 16 | 100000, 17 | 1000000, 18 | 10000000, 19 | 100000000, 20 | 200000000, 21 | // 4294967295, 22 | } 23 | 24 | func TestNumberOfPrimesNotExceeding(t *testing.T) { 25 | tests := []struct { 26 | input uint64 27 | expected int 28 | }{ 29 | {0, 0}, 30 | {1, 0}, 31 | {2, 2}, 32 | {3, 2}, 33 | {4, 2}, 34 | {5, 3}, 35 | {6, 3}, 36 | {7, 4}, 37 | {8, 4}, 38 | {100000000, 5761455}, 39 | //{4294967295, 203280221}, 40 | } 41 | for ii, tt := range tests { 42 | t.Run(strconv.Itoa(ii), func(t *testing.T) { 43 | if gotR := NumberOfPrimesNotExceeding(tt.input); gotR != tt.expected { 44 | t.Errorf("NumberOfPrimesNotExceeding() = %v, want %v", gotR, tt.expected) 45 | } 46 | }) 47 | } 48 | } 49 | 50 | func BenchmarkNumberOfPrimesNotExceeding(b *testing.B) { 51 | for _, benchmark := range benchmarks { 52 | b.Run(fmt.Sprintf("%d", benchmark), func(b *testing.B) { 53 | for j := 0; j < b.N; j++ { 54 | NumberOfPrimesNotExceeding(benchmark) 55 | } 56 | }) 57 | } 58 | } 59 | 60 | func TestIterator(t *testing.T) { 61 | 62 | t.Log("Iterator test running!") 63 | 64 | p := Primes(100000000) 65 | 66 | // ----------------- 67 | 68 | count := p.NumberOfPrimes(1, 1000) 69 | t.Logf("[1,1000] includes %d primes.\n", count) 70 | 71 | count = p.NumberOfPrimes(99999000, 100000000) 72 | t.Logf("[99999000,100000000] includes %d primes.\n", count) 73 | 74 | // ----------------- 75 | 76 | var sum uint64 77 | primesum := func(prime uint64) { 78 | sum += prime 79 | } 80 | 81 | p.IteratePrimes(1, 10, primesum) 82 | t.Logf("The sum of primes <= %d is %d.\n", 10, sum) 83 | if sum != 2+3+5+7 { 84 | t.Errorf("expected %v but found %v", 2+3+5+7, sum) 85 | } 86 | 87 | // ----------------- 88 | 89 | bp := p.Primorial(1, 10) 90 | t.Logf("The promorial(%d) = %d.\n", 10, bp) 91 | 92 | bp = p.Primorial(100, 110) 93 | t.Logf("The product of primes p, %d <= p <= %d is %d.\n", 100, 110, bp) 94 | 95 | // ----------------- 96 | 97 | if p.IsPrime(4567) { 98 | t.Logf("4567 is prime.\n") 99 | } else { 100 | t.Errorf("expected true but found false") 101 | } 102 | 103 | if !p.IsPrime(1234567) { 104 | t.Logf("1234567 is not prime.\n") 105 | } else { 106 | t.Errorf("expected false but found true") 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /GoFactorial/simplefactorial/simplefactorial.go: -------------------------------------------------------------------------------- 1 | // simplefactorial package simplefactorial.go 2 | // 2010/6/29 Sonia Keys 3 | // 2011/6/29 edited Peter Luschny 4 | // MIT license 5 | 6 | package simplefactorial 7 | 8 | import ( 9 | "math/big" 10 | 11 | "github.com/PeterLuschny/Fast-Factorial-Functions/GoFactorial/xmath" 12 | ) 13 | 14 | func Factorial(n uint64) (r *big.Int) { 15 | var oddFactNDiv2, oddFactNDiv4 big.Int 16 | 17 | // closes on oddFactNDiv2, oddFactNDiv4 18 | oddSwing := func(n uint64) (r *big.Int) { 19 | 20 | if n < uint64(len(smallOddSwing)) { 21 | return big.NewInt(smallOddSwing[n]) 22 | } 23 | 24 | length := (n - 1) / 4 25 | if n%4 != 2 { 26 | length++ 27 | } 28 | high := n - (n+1)&1 29 | ndiv4 := n / 4 30 | 31 | var oddFact big.Int 32 | if ndiv4 < uint64(len(smallOddFactorial)) { 33 | oddFact.SetInt64(smallOddFactorial[ndiv4]) 34 | r = &oddFact 35 | } else { 36 | r = &oddFactNDiv4 37 | } 38 | 39 | return oddFact.Quo(oddProduct(high, length), r) 40 | } 41 | 42 | // closes on oddFactNDiv2, oddFactNDiv4, oddSwing, and itself 43 | var oddFactorial func(uint64) *big.Int 44 | oddFactorial = func(n uint64) (oddFact *big.Int) { 45 | if n < uint64(len(smallOddFactorial)) { 46 | oddFact = big.NewInt(smallOddFactorial[n]) 47 | } else { 48 | oddFact = oddFactorial(n / 2) 49 | oddFact.Mul(oddFact.Mul(oddFact, oddFact), oddSwing(n)) 50 | } 51 | 52 | oddFactNDiv4.Set(&oddFactNDiv2) 53 | oddFactNDiv2.Set(oddFact) 54 | return oddFact 55 | } 56 | 57 | oddFactNDiv2.SetInt64(1) 58 | oddFactNDiv4.SetInt64(1) 59 | r = oddFactorial(n) 60 | exp := uint(n - uint64(xmath.BitCount64(n))) 61 | return r.Lsh(r, exp) 62 | } 63 | 64 | func oddProduct(m, length uint64) *big.Int { 65 | switch length { 66 | case 1: 67 | return big.NewInt(int64(m)) 68 | case 2: 69 | var mb big.Int 70 | mb.SetInt64(int64(m)) 71 | mb2 := big.NewInt(int64(m - 2)) 72 | return mb2.Mul(&mb, mb2) 73 | } 74 | hlen := length / 2 75 | h := oddProduct(m-hlen*2, length-hlen) 76 | return h.Mul(h, oddProduct(m, hlen)) 77 | } 78 | 79 | var smallOddSwing []int64 = []int64{1, 1, 1, 3, 3, 15, 5, 80 | 35, 35, 315, 63, 693, 231, 3003, 429, 6435, 6435, 81 | 109395, 12155, 230945, 46189, 969969, 88179, 2028117, 676039, 82 | 16900975, 1300075, 35102025, 5014575, 145422675, 9694845, 83 | 300540195, 300540195, 9917826435, 583401555, 20419054425, 84 | 2268783825, 83945001525, 4418157975, 172308161025, 85 | 34461632205, 1412926920405, 67282234305, 2893136075115, 86 | 263012370465, 11835556670925, 514589420475, 24185702762325, 87 | 8061900920775, 395033145117975, 15801325804719, 88 | 805867616040669, 61989816618513, 3285460280781189, 89 | 121683714103007, 6692604275665385, 956086325095055, 90 | 54496920530418135, 1879204156221315, 110873045217057585, 91 | 7391536347803839, 450883717216034179, 14544636039226909, 92 | 916312070471295267, 916312070471295267} 93 | 94 | var smallOddFactorial []int64 = []int64{1, 1, 1, 3, 3, 95 | 15, 45, 315, 315, 2835, 14175, 155925, 467775, 96 | 6081075, 42567525, 638512875, 638512875, 10854718875, 97 | 97692469875, 1856156927625, 9280784638125, 194896477400625, 98 | 2143861251406875, 49308808782358125, 147926426347074375, 99 | 3698160658676859375} 100 | -------------------------------------------------------------------------------- /GoFactorial/simplefactorial/simplefactorial_test.go: -------------------------------------------------------------------------------- 1 | package simplefactorial 2 | 3 | import ( 4 | "fmt" 5 | "math/big" 6 | "strconv" 7 | "testing" 8 | ) 9 | 10 | var one00, _ = new(big.Int).SetString("93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000", 10) 11 | var benchmarks = []uint64{ 12 | 100, 13 | 1000, 14 | 10000, 15 | 100000, 16 | } 17 | 18 | func BenchmarkFactorial(b *testing.B) { 19 | for _, benchmark := range benchmarks { 20 | b.Run(fmt.Sprintf("%d", benchmark), func(b *testing.B) { 21 | for j := 0; j < b.N; j++ { 22 | Factorial(benchmark) 23 | } 24 | }) 25 | } 26 | } 27 | 28 | // func info(a *big.Int, n uint) { 29 | // dtrunc := int64(float64(a.BitLen())*.30103) - 10 30 | // var first, rest big.Int 31 | // rest.Exp(first.SetInt64(10), rest.SetInt64(dtrunc), nil) 32 | // first.Quo(a, &rest) 33 | // fstr := first.String() 34 | // fmt.Printf("%d! begins %s... and has %d digits.\n", 35 | // n, fstr, int64(len(fstr))+dtrunc) 36 | // } 37 | 38 | func TestFactorial(t *testing.T) { 39 | tests := []struct { 40 | input uint64 41 | expected *big.Int 42 | }{ 43 | {0, big.NewInt(1)}, 44 | {1, big.NewInt(1)}, 45 | {2, big.NewInt(2)}, 46 | {3, big.NewInt(6)}, 47 | {4, big.NewInt(24)}, 48 | {5, big.NewInt(120)}, 49 | {100, one00}, 50 | } 51 | for ii, tt := range tests { 52 | t.Run(strconv.Itoa(ii), func(t *testing.T) { 53 | if gotR := Factorial(tt.input); gotR.Cmp(tt.expected) != 0 { 54 | t.Errorf("Factorial() = %v, want %v", gotR, tt.expected) 55 | } 56 | }) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /GoFactorial/swingfactorial/swingfactorial.go: -------------------------------------------------------------------------------- 1 | // swingfactorial package swingfactorial.go 2 | // 2010/6/29 Sonia Keys 3 | // 2011/6/29 edited by Peter Luschny 4 | // MIT license 5 | 6 | package swingfactorial 7 | 8 | import ( 9 | "math/big" 10 | 11 | "github.com/PeterLuschny/Fast-Factorial-Functions/GoFactorial/primes" 12 | "github.com/PeterLuschny/Fast-Factorial-Functions/GoFactorial/xmath" 13 | ) 14 | 15 | type Swing struct { 16 | primes *primes.Sieve 17 | factors []uint64 18 | } 19 | 20 | // constructor, completes Swing 21 | func NewSwing(n uint64) (s *Swing) { 22 | s = new(Swing) 23 | s.primes = primes.Primes(n) 24 | 25 | if n >= uint64(len(smallOddSwing)) { 26 | s.factors = make([]uint64, n) 27 | } 28 | 29 | return s 30 | } 31 | 32 | // Computes A056040 on OEIS 33 | func SwingingFactorial(n uint64) *big.Int { 34 | s := new(Swing) 35 | s.primes = primes.Primes(n) 36 | 37 | if n >= uint64(len(smallOddSwing)) { 38 | s.factors = make([]uint64, n) 39 | } 40 | 41 | r := s.OddSwing(n) 42 | return r.Lsh(r, xmath.BitCount64(n>>1)) 43 | } 44 | 45 | func (s *Swing) OddSwing(k uint64) *big.Int { 46 | 47 | if k < uint64(len(smallOddSwing)) { 48 | return big.NewInt(smallOddSwing[k]) 49 | } 50 | 51 | rootK := xmath.FloorSqrt(k) 52 | var i int 53 | 54 | s.primes.IteratePrimes(3, rootK, func(p uint64) { 55 | q := k / p 56 | for q > 0 { 57 | if q&1 == 1 { 58 | s.factors[i] = p 59 | i++ 60 | } 61 | q /= p 62 | } 63 | }) 64 | 65 | s.primes.IteratePrimes(rootK+1, k/3, func(p uint64) { 66 | if (k / p & 1) == 1 { 67 | s.factors[i] = p 68 | i++ 69 | } 70 | }) 71 | 72 | s.primes.IteratePrimes(k/2+1, k, func(p uint64) { 73 | s.factors[i] = p 74 | i++ 75 | }) 76 | 77 | return xmath.Product(s.factors[0:i]) 78 | } 79 | 80 | var smallOddSwing []int64 = []int64{1, 1, 1, 3, 3, 15, 5, 81 | 35, 35, 315, 63, 693, 231, 3003, 429, 6435, 6435, 82 | 109395, 12155, 230945, 46189, 969969, 88179, 2028117, 676039, 83 | 16900975, 1300075, 35102025, 5014575, 145422675, 9694845, 84 | 300540195, 300540195, 9917826435, 583401555, 20419054425, 85 | 2268783825, 83945001525, 4418157975, 172308161025, 86 | 34461632205, 1412926920405, 67282234305, 2893136075115, 87 | 263012370465, 11835556670925, 514589420475, 24185702762325, 88 | 8061900920775, 395033145117975, 15801325804719, 89 | 805867616040669, 61989816618513, 3285460280781189, 90 | 121683714103007, 6692604275665385, 956086325095055, 91 | 54496920530418135, 1879204156221315, 110873045217057585, 92 | 7391536347803839, 450883717216034179, 14544636039226909, 93 | 916312070471295267, 916312070471295267} 94 | -------------------------------------------------------------------------------- /GoFactorial/swingfactorial/swingfactorial_test.go: -------------------------------------------------------------------------------- 1 | // swingfactorial_test project swingfactorial_test.go 2 | 3 | package swingfactorial 4 | 5 | import ( 6 | "fmt" 7 | "math/big" 8 | "strconv" 9 | "testing" 10 | ) 11 | 12 | var one03, _ = new(big.Int).SetString("41159712051274678559296251331536", 10) 13 | var five00, _ = new(big.Int).SetString("116744315788277682920934734762176619659230081180311446124100284957811112673608473715666417775521605376810865902709989580160037468226393900042796872256", 10) 14 | var one000, _ = new(big.Int).SetString("270288240945436569515614693625975275496152008446548287007392875106625428705522193898612483924502370165362606085021546104802209750050679917549894219699518475423665484263751733356162464079737887344364574161119497604571044985756287880514600994219426752366915856603136862602484428109296905863799821216320", 10) 15 | var benchmarks = []uint64{ 16 | 100, 17 | 1000, 18 | 10000, 19 | 100000, 20 | 1000000, 21 | } 22 | 23 | func TestSwingingFactorial(t *testing.T) { 24 | tests := []struct { 25 | input uint64 26 | expected *big.Int 27 | }{ 28 | {0, big.NewInt(1)}, 29 | {1, big.NewInt(1)}, 30 | {2, big.NewInt(2)}, 31 | {3, big.NewInt(6)}, 32 | {4, big.NewInt(6)}, 33 | {5, big.NewInt(30)}, 34 | {6, big.NewInt(20)}, 35 | {7, big.NewInt(140)}, 36 | {8, big.NewInt(70)}, 37 | {103, one03}, 38 | {500, five00}, 39 | {1000, one000}, 40 | } 41 | for ii, tt := range tests { 42 | t.Run(strconv.Itoa(ii), func(t *testing.T) { 43 | if gotR := SwingingFactorial(tt.input); gotR.Cmp(tt.expected) != 0 { 44 | t.Errorf("SwingingFactorial() = %v, want %v", gotR, tt.expected) 45 | } 46 | }) 47 | } 48 | } 49 | 50 | func BenchmarkSwingingFactorial(b *testing.B) { 51 | for _, benchmark := range benchmarks { 52 | b.Run(fmt.Sprintf("%d", benchmark), func(b *testing.B) { 53 | for j := 0; j < b.N; j++ { 54 | SwingingFactorial(benchmark) 55 | } 56 | }) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /GoFactorial/xmath/xmath.go: -------------------------------------------------------------------------------- 1 | // xmath package xmath.go 2 | // 2010/6/29 Sonia Keys 3 | // 2011/6/29 Peter Luschny edited 4 | // MIT license 5 | 6 | package xmath 7 | 8 | import ( 9 | "math/big" 10 | ) 11 | 12 | const productSerialThreshold = 20 13 | 14 | func Product(seq []uint64) *big.Int { 15 | 16 | if len(seq) <= productSerialThreshold { 17 | var b big.Int 18 | sprod := big.NewInt(int64(seq[0])) 19 | for _, s := range seq[1:] { 20 | b.SetInt64(int64(s)) 21 | sprod.Mul(sprod, &b) 22 | } 23 | return sprod 24 | } 25 | 26 | halfLen := len(seq) / 2 27 | lprod := Product(seq[0:halfLen]) 28 | return lprod.Mul(lprod, Product(seq[halfLen:])) 29 | } 30 | 31 | func FloorSqrt(n uint64) uint64 { 32 | for b := n; ; { 33 | a := b 34 | b = (n/a + a) / 2 35 | if b >= a { 36 | return a 37 | } 38 | } 39 | return 0 // unreachable. required by current compiler. 40 | } 41 | 42 | func BitCount32(w uint32) uint { 43 | const ( 44 | ff = 1<<32 - 1 45 | mask1 = ff / 3 46 | mask3 = ff / 5 47 | maskf = ff / 17 48 | maskp = ff / 255 49 | ) 50 | w -= w >> 1 & mask1 51 | w = w&mask3 + w>>2&mask3 52 | w = (w + w>>4) & maskf 53 | return uint(w * maskp >> 24) 54 | } 55 | 56 | func BitCount64(w uint64) uint { // loopfree! 57 | const ( 58 | ff = 1<<64 - 1 59 | mask1 = ff / 3 60 | mask3 = ff / 5 61 | maskf = ff / 17 62 | maskp = maskf >> 3 & maskf 63 | ) 64 | w -= w >> 1 & mask1 65 | w = w&mask3 + w>>2&mask3 66 | w = (w + w>>4) & maskf 67 | return uint(w * maskp >> 56) 68 | } 69 | 70 | func BitCount(x uint) uint { 71 | x = x - ((x >> 1) & 0x55555555) 72 | x = (x & 0x33333333) + ((x >> 2) & 0x33333333) 73 | x = (x + (x >> 4)) & 0x0F0F0F0F 74 | x = x + (x >> 8) 75 | x = x + (x >> 16) 76 | return x & 0x0000003F 77 | } 78 | -------------------------------------------------------------------------------- /GoFactorial/xmath/xmath_test.go: -------------------------------------------------------------------------------- 1 | // xmath_test project xmath_test.go 2 | package xmath 3 | 4 | import ( 5 | "strconv" 6 | "testing" 7 | ) 8 | 9 | // TODO: Calibrate the serial threshold for product. 10 | 11 | func TestBinomial(t *testing.T) { 12 | tests := []struct { 13 | input uint64 14 | expected uint64 15 | }{ 16 | {4, 2}, 17 | } 18 | for ii, tt := range tests { 19 | t.Run(strconv.Itoa(ii), func(t *testing.T) { 20 | if gotR := FloorSqrt(tt.input); gotR != tt.expected { 21 | t.Errorf("FloorSqrt() = %v, want %v", gotR, tt.expected) 22 | } 23 | }) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /JavaFactorial/dist/FactorialBench2015.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterLuschny/Fast-Factorial-Functions/9ab709a1ade401cdacce909cc976cebf9a8830ed/JavaFactorial/dist/FactorialBench2015.jar -------------------------------------------------------------------------------- /JavaFactorial/dist/README.TXT: -------------------------------------------------------------------------------- 1 | ======================== 2 | BUILD OUTPUT DESCRIPTION 3 | ======================== 4 | 5 | When you build an Java application project that has a main class, the IDE 6 | automatically copies all of the JAR 7 | files on the projects classpath to your projects dist/lib folder. The IDE 8 | also adds each of the JAR files to the Class-Path element in the application 9 | JAR files manifest file (MANIFEST.MF). 10 | 11 | To run the project from the command line, go to the dist folder and 12 | type the following: 13 | 14 | java -jar "FactorialBench2015.jar" 15 | 16 | To distribute this project, zip up the dist folder (including the lib folder) 17 | and distribute the ZIP file. 18 | 19 | Notes: 20 | 21 | * If two JAR files on the project classpath have the same name, only the first 22 | JAR file is copied to the lib folder. 23 | * Only JAR files are copied to the lib folder. 24 | If the classpath contains other types of files or folders, these files (folders) 25 | are not copied. 26 | * If a library on the projects classpath also has a Class-Path element 27 | specified in the manifest,the content of the Class-Path element has to be on 28 | the projects runtime path. 29 | * To set a main class in a standard Java project, right-click the project node 30 | in the Projects window and choose Properties. Then click Run and enter the 31 | class name in the Main Class field. Alternatively, you can manually type the 32 | class name in the manifest Main-Class element. 33 | -------------------------------------------------------------------------------- /JavaFactorial/dist/lib/apfloat.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterLuschny/Fast-Factorial-Functions/9ab709a1ade401cdacce909cc976cebf9a8830ed/JavaFactorial/dist/lib/apfloat.jar -------------------------------------------------------------------------------- /JavaFactorial/dist/lib/applet.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterLuschny/Fast-Factorial-Functions/9ab709a1ade401cdacce909cc976cebf9a8830ed/JavaFactorial/dist/lib/applet.jar -------------------------------------------------------------------------------- /JavaFactorial/dist/lib/jgoodies-common-1.8.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterLuschny/Fast-Factorial-Functions/9ab709a1ade401cdacce909cc976cebf9a8830ed/JavaFactorial/dist/lib/jgoodies-common-1.8.1.jar -------------------------------------------------------------------------------- /JavaFactorial/dist/lib/jgoodies-forms-1.9.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterLuschny/Fast-Factorial-Functions/9ab709a1ade401cdacce909cc976cebf9a8830ed/JavaFactorial/dist/lib/jgoodies-forms-1.9.0.jar -------------------------------------------------------------------------------- /JavaFactorial/dist/lib/jgoodies-looks-2.7.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterLuschny/Fast-Factorial-Functions/9ab709a1ade401cdacce909cc976cebf9a8830ed/JavaFactorial/dist/lib/jgoodies-looks-2.7.0.jar -------------------------------------------------------------------------------- /JavaFactorial/readme.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | readme 7 | 20 | 21 | 22 | 23 | 24 |

Readme

25 |

This software links to Mikko Tommila's Apfloat library and to Karsten Lentzsch's 26 | JGoodies.

27 |

Apfloat

28 |

Copyright © 2009 Mikko Tommila

29 |

This library is free software; you can redistribute it and/or modify it under 30 | the terms of the GNU Lesser General Public License as published by the Free Software 31 | Foundation; either version 2.1 of the License, or (at your option) any later version.

32 |

This library is distributed in the hope that it will be useful, but WITHOUT ANY 33 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 34 | PARTICULAR PURPOSE. See the 35 | GNU Lesser General Public License for more details.

36 |

If you have any questions or need a different type of license, please contact 37 | Mikko at ApfloatOrg.

38 |

Jgoodies

39 |

Copyright © Karsten Lentzsch

40 |

The libraries are provided under the terms of the 41 | BSD open source 42 | license.

43 |

Here are the 44 | libraries 45 | from. If you want to contact the 46 | author Karsten Lentzsch.

47 |

Fast Factorial Functions

48 |

Copyright © Peter Luschny

49 |

The MIT license 50 | applies. Visit the 51 | homepage 52 | of fast factorial functions. Comments mail to peter AT luschny POINT de.

53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/apps/StopWatch.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.apps; 6 | 7 | /** 8 | * StopWatch 9 | * 10 | * @author Peter Luschny 11 | * @version 2001-05-12 12 | */ 13 | public class StopWatch { 14 | 15 | private long elapsedCount; 16 | private long startCount; 17 | 18 | /** 19 | * Start the time-counter. 20 | */ 21 | public void start() { 22 | startCount = System.currentTimeMillis(); 23 | } 24 | 25 | /** 26 | * Stop the time-counter 27 | */ 28 | public void stop() { 29 | final long stopCount = System.currentTimeMillis(); 30 | elapsedCount += (stopCount - startCount); 31 | } 32 | 33 | /** 34 | * Clear the elapsed time-counter. 35 | */ 36 | public void clear() { 37 | elapsedCount = 0; 38 | } 39 | 40 | /** 41 | * Get the elapsed time converted to seconds. 42 | * 43 | * @return elapsed time converted to seconds 44 | */ 45 | public double getSeconds() { 46 | return elapsedCount / 1000.0; 47 | } 48 | 49 | /** 50 | * Get the elapsed time converted to milli seconds. 51 | * 52 | * @return elapsed time converted to milli seconds 53 | */ 54 | private long getMilliSeconds() { 55 | return elapsedCount; 56 | } 57 | 58 | /** 59 | * Get the elapsed time as a formatted string. 60 | * @return milli seconds as string 61 | */ 62 | @Override 63 | public String toString() { 64 | return getMilliSeconds() + " ms"; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/apps/factorial/FactorialTest.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.apps.factorial; 6 | 7 | import java.util.Iterator; 8 | 9 | public class FactorialTest { 10 | 11 | public static final int benchMax = 100000000; 12 | public boolean[] selectedAlgo; 13 | public int benchLength; 14 | public int benchStart; 15 | public double stepFactor; 16 | public boolean showFullValue; 17 | public boolean verbose; 18 | public double workLoad; 19 | public int[] benchValues; 20 | public int cardSelected; 21 | public boolean sanityTest; 22 | 23 | public void init() { 24 | Candidate.setSelected(selectedAlgo); 25 | 26 | benchValues = new int[benchLength]; 27 | double sum = 0; 28 | long value = benchStart; 29 | 30 | for (int m = 0; m < benchLength; m++) { 31 | if (value < benchMax) { 32 | benchValues[m] = (int) value; 33 | sum += value; 34 | } else { 35 | benchValues[m] = 1; 36 | } 37 | value = (long) (value * stepFactor); 38 | } 39 | 40 | cardSelected = 0; 41 | workLoad = 0; 42 | 43 | Iterator selectedCandidates = Candidate.getSelected(); 44 | while (selectedCandidates.hasNext()) { 45 | Candidate cand = selectedCandidates.next(); 46 | cardSelected++; 47 | workLoad += cand.workLoad * sum; 48 | } 49 | } 50 | 51 | // Do not expose the class Candidate to the BenchmarkForm 52 | public static boolean[] getPrimeAlgos() { 53 | return Candidate.getPrimeAlgos(); 54 | } 55 | 56 | public static boolean[] getSimpleAlgos() { 57 | return Candidate.getSimpleAlgos(); 58 | } 59 | 60 | public static boolean[] getRecommendedAlgos() { 61 | return Candidate.getRecommendedAlgos(); 62 | } 63 | 64 | public static boolean[] getLameAlgos() { 65 | return Candidate.getLameAlgos(); 66 | } 67 | 68 | public static boolean[] getParallelAlgos() { 69 | return Candidate.getParallelAlgos(); 70 | } 71 | 72 | public static String[] getNames() { 73 | return Candidate.getNames(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/FactorialAdditiveMoessner.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.arithmetic.Xint; 8 | 9 | public class FactorialAdditiveMoessner implements IFactorialFunction { 10 | 11 | public FactorialAdditiveMoessner() { 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return "AdditiveMoessner "; 17 | } 18 | 19 | @Override 20 | public Xint factorial(int n) { 21 | if (n < 0) { 22 | throw new ArithmeticException("Factorial: n has to be >= 0, but was " + n); 23 | } 24 | 25 | Xint[] s = new Xint[n + 1]; 26 | s[0] = Xint.ONE; 27 | 28 | for (int m = 1; m <= n; m++) { 29 | s[m] = Xint.ZERO; 30 | for (int k = m; k >= 1; k--) { 31 | for (int i = 1; i <= k; i++) { 32 | s[i] = s[i].add(s[i - 1]); 33 | } 34 | } 35 | } 36 | return s[n]; 37 | } 38 | } // endOfFactorialMoessner 39 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/FactorialAdditiveSwing.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.arithmetic.Xint; 8 | 9 | public class FactorialAdditiveSwing implements IFactorialFunction { 10 | 11 | public FactorialAdditiveSwing() { 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return "AdditiveSwing "; 17 | } 18 | 19 | @Override 20 | public Xint factorial(int n) { 21 | if (n < 0) { 22 | throw new ArithmeticException("Factorial: n has to be >= 0, but was " + n); 23 | } 24 | 25 | return recFactorial(n); 26 | } 27 | 28 | private Xint recFactorial(int n) { 29 | if (n < 2) { 30 | return Xint.ONE; 31 | } 32 | 33 | return recFactorial(n / 2).square().multiply(swing(n)); 34 | } 35 | 36 | private Xint swing(int n) { 37 | Xint w = Xint.ONE; 38 | 39 | if (n > 1) { 40 | n = n + 2; 41 | Xint[] s = new Xint[n + 1]; 42 | 43 | s[0] = s[1] = Xint.ZERO; 44 | s[2] = w; 45 | 46 | for (int m = 3; m <= n; m++) { 47 | s[m] = s[m - 2]; 48 | for (int k = m; k >= 2; k--) { 49 | s[k] = s[k].add(s[k - 2]); 50 | if ((k & 1) == 1) // if k is odd 51 | { 52 | s[k] = s[k].add(s[k - 1]); 53 | } 54 | } 55 | } 56 | w = s[n]; 57 | } 58 | return w; 59 | } 60 | } // endOfFactorialAdditiveSwing 61 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/FactorialBoitenSplit.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.arithmetic.Xint; 8 | 9 | public class FactorialBoitenSplit implements IFactorialFunction { 10 | 11 | public FactorialBoitenSplit() { 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return "BoitenSplit "; 17 | } 18 | 19 | @Override 20 | public Xint factorial(int n) { 21 | if (n < 0) { 22 | throw new ArithmeticException("Factorial: n has to be >= 0, but was " + n); 23 | } 24 | 25 | if (n < 2) { 26 | return Xint.ONE; 27 | } 28 | 29 | Xint p = Xint.ONE; 30 | Xint r = Xint.ONE; 31 | 32 | // log2n = floor(log2(n)); 33 | int log2n = 31 - Integer.numberOfLeadingZeros(n); 34 | int h = 0, shift = 0, k = 1; 35 | 36 | while (h != n) { 37 | shift += h; 38 | h = n >>> log2n--; 39 | int high = (h & 1) == 1 ? h : h - 1; 40 | 41 | while (k != high) { 42 | k += 2; 43 | p = p.multiply(k); 44 | } 45 | r = r.multiply(p); 46 | } 47 | return r.shiftLeft(shift); 48 | } 49 | } // endOfFactorialSplitBoiten 50 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/FactorialDifference.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.arithmetic.Xint; 8 | 9 | public class FactorialDifference implements IFactorialFunction { 10 | 11 | public FactorialDifference() { 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return "Difference "; 17 | } 18 | 19 | @Override 20 | public Xint factorial(int n) { 21 | if (n < 0) { 22 | throw new ArithmeticException("Factorial: n has to be >= 0, but was " + n); 23 | } 24 | 25 | if (n < 2) { 26 | return Xint.ONE; 27 | } 28 | 29 | Xint f; 30 | 31 | switch (n % 4) { 32 | case 1: 33 | f = Xint.valueOf(n); 34 | break; 35 | case 2: 36 | f = Xint.valueOf((long) n * (n - 1)); 37 | break; 38 | case 3: 39 | f = Xint.valueOf((long) n * (n - 1) * (n - 2)); 40 | break; 41 | default: 42 | f = Xint.ONE; 43 | } 44 | 45 | long prod = 24; 46 | long diff1 = 1656; 47 | long diff2 = 8544; 48 | long diff3 = 13056; 49 | 50 | int i = n / 4; 51 | while (i-- > 0) { 52 | f = f.multiply(Xint.valueOf(prod)); 53 | prod += diff1; 54 | diff1 += diff2; 55 | diff2 += diff3; 56 | diff3 += 6144; 57 | } 58 | 59 | return f; 60 | } 61 | } // endOfFactorialDifference 62 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/FactorialFactors.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.primes.IPrimeIteration; 8 | import de.luschny.math.primes.IPrimeSieve; 9 | import de.luschny.math.primes.PrimeSieve; 10 | 11 | import java.io.BufferedWriter; 12 | import java.io.FileWriter; 13 | import java.io.IOException; 14 | import java.io.PrintWriter; 15 | 16 | public class FactorialFactors { 17 | 18 | public FactorialFactors() { 19 | } 20 | private int[] primeList; 21 | private int[] multiList; 22 | private int n, card; 23 | 24 | public FactorialFactors(int n) { 25 | this.n = n; 26 | card = primeFactors(n); 27 | } 28 | 29 | public void saveToFile(String fileName) { 30 | try { 31 | PrintWriter primeReport = new PrintWriter(new BufferedWriter(new FileWriter(fileName))); 32 | 33 | writeFactors(primeReport); 34 | primeReport.close(); 35 | } catch (IOException e) { 36 | System.err.println(e.toString()); 37 | } 38 | } 39 | 40 | public void writeFactors(PrintWriter file) { 41 | file.println("The prime factors of " + this.n + "! "); 42 | 43 | int sum = n - Integer.bitCount(n); 44 | file.print("2^" + sum); 45 | 46 | for (int p = 0; p < this.card; p++) { 47 | int f = primeList[p], m = multiList[p]; 48 | sum += m; 49 | 50 | if (m > 1) { 51 | file.print("*" + f + "^" + m); 52 | } else { 53 | file.print("*" + f); 54 | } 55 | } 56 | 57 | file.println(); 58 | file.println("Number of different factors: " + this.card); 59 | file.println("Number of all factors: " + sum); 60 | } 61 | 62 | private int primeFactors(int k) { 63 | IPrimeSieve sieve = new PrimeSieve(k); 64 | IPrimeIteration pIter = sieve.getIteration(2, k); 65 | 66 | int piN = pIter.getNumberOfPrimes(); 67 | 68 | primeList = new int[piN]; 69 | multiList = new int[piN]; 70 | 71 | int maxBound = k / 2, count = 0; 72 | 73 | for (int prime : pIter) { 74 | int m = prime > maxBound ? 1 : 0; 75 | 76 | if (prime <= maxBound) { 77 | int q = k; 78 | while (q >= prime) { 79 | m += q /= prime; 80 | } 81 | } 82 | 83 | primeList[count] = prime; 84 | multiList[count++] = m; 85 | } 86 | return count; 87 | } 88 | } -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/FactorialHyper.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.arithmetic.Xint; 8 | 9 | public class FactorialHyper implements IFactorialFunction { 10 | 11 | public FactorialHyper() { 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return "Hyper "; 17 | } 18 | private boolean nostart; 19 | private long S, K, A; 20 | 21 | @Override 22 | public Xint factorial(int n) { 23 | if (n < 0) { 24 | throw new ArithmeticException("Factorial: n has to be >= 0, but was " + n); 25 | } 26 | 27 | nostart = false; 28 | int h = n / 2; 29 | S = h + 1; 30 | K = S + h; 31 | A = (n & 1) == 1 ? K : 1; 32 | if ((h & 1) == 1) { 33 | A = -A; 34 | } 35 | K += 4; 36 | 37 | return hyperFact(h + 1).shiftLeft(h); 38 | } 39 | 40 | private Xint hyperFact(int l) { 41 | if (l > 1) { 42 | int m = l / 2; 43 | return hyperFact(m).multiply(hyperFact(l - m)); 44 | } 45 | 46 | if (nostart) { 47 | S -= K -= 4; 48 | return Xint.valueOf(S); 49 | } 50 | 51 | nostart = true; 52 | return Xint.valueOf(A); 53 | } 54 | } // endOfFactorialHyper 55 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/FactorialPrimeBorwein.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.Xmath; 8 | import de.luschny.math.arithmetic.Xint; 9 | import de.luschny.math.primes.IPrimeIteration; 10 | import de.luschny.math.primes.IPrimeSieve; 11 | import de.luschny.math.primes.PrimeSieve; 12 | 13 | public class FactorialPrimeBorwein implements IFactorialFunction { 14 | 15 | private int[] primeList; 16 | private int[] multiList; 17 | 18 | public FactorialPrimeBorwein() { 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return "PrimeBorwein "; 24 | } 25 | 26 | @Override 27 | public Xint factorial(int n) { 28 | // For very small n the 'NaiveFactorial' is ok. 29 | if (n < 20) { 30 | return Xmath.smallFactorial(n); 31 | } 32 | 33 | int lgN = 31 - Integer.numberOfLeadingZeros(n); 34 | int piN = 2 + (15 * n) / (8 * (lgN - 1)); 35 | 36 | primeList = new int[piN]; 37 | multiList = new int[piN]; 38 | 39 | int len = primeFactors(n); 40 | return repeatedSquare(len, 1).shiftLeft(n - Integer.bitCount(n)); 41 | } 42 | 43 | private Xint repeatedSquare(int len, int k) { 44 | if (len == 0) { 45 | return Xint.ONE; 46 | } 47 | 48 | // multiList and primeList initialized in function 'factorial'! 49 | int i = 0, mult = multiList[0]; 50 | 51 | while (mult > 1) { 52 | if ((mult & 1) == 1) // is mult odd ? 53 | { 54 | primeList[len++] = primeList[i]; 55 | } 56 | 57 | multiList[i++] = mult / 2; 58 | mult = multiList[i]; 59 | } 60 | return Xint.product(primeList, i, len - i).toPowerOf(k).multiply(repeatedSquare(i, 2 * k)); 61 | } 62 | 63 | private int primeFactors(int n) { 64 | IPrimeSieve sieve = new PrimeSieve(n); 65 | IPrimeIteration pIter = sieve.getIteration(3, n); 66 | 67 | int maxBound = n / 2, count = 0; 68 | 69 | for (int prime : pIter) { 70 | int m = prime > maxBound ? 1 : 0; 71 | 72 | if (prime <= maxBound) { 73 | int q = n; 74 | while (q >= prime) { 75 | m += q /= prime; 76 | } 77 | } 78 | 79 | // multiList and primeList initialized in function 'factorial'! 80 | primeList[count] = prime; 81 | multiList[count++] = m; 82 | } 83 | return count; 84 | } 85 | } // endOfFactorialPrimeBorwein 86 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/FactorialPrimeLeenstra.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.Xmath; 8 | import de.luschny.math.arithmetic.Xint; 9 | import de.luschny.math.primes.IPrimeIteration; 10 | import de.luschny.math.primes.PrimeSieve; 11 | 12 | public class FactorialPrimeLeenstra implements IFactorialFunction { 13 | 14 | public FactorialPrimeLeenstra() { 15 | } 16 | 17 | @Override 18 | public String getName() { 19 | return "PrimeLeenstra "; 20 | } 21 | 22 | @Override 23 | public Xint factorial(int n) { 24 | // For very small n the 'NaiveFactorial' is OK. 25 | if (n < 20) { 26 | return Xmath.smallFactorial(n); 27 | } 28 | 29 | int rootN = (int) Math.floor(Math.sqrt(n)); 30 | int log2N = 31 - Integer.numberOfLeadingZeros(n); 31 | Xint[] expBit = new Xint[log2N + 1]; 32 | 33 | for (int j = 0; j < expBit.length; j++) { 34 | expBit[j] = Xint.ONE; 35 | } 36 | 37 | PrimeSieve sieve = new PrimeSieve(n); 38 | IPrimeIteration pIter = sieve.getIteration(3, rootN); 39 | 40 | for (int prime : pIter) { 41 | int k = 0, m = 0, q = n; 42 | 43 | do { 44 | m += q /= prime; 45 | 46 | } while (q >= 1); 47 | 48 | while (m > 0) { 49 | if ((m & 1) == 1) { 50 | expBit[k] = expBit[k].multiply(prime); 51 | } 52 | m = m / 2; 53 | k++; 54 | } 55 | } 56 | 57 | int j = 2, low = n, high; 58 | 59 | while (low != rootN) { 60 | high = low; 61 | low = n / j++; 62 | 63 | if (low < rootN) { 64 | low = rootN; 65 | } 66 | 67 | Xint primorial = sieve.getPrimorial(low + 1, high); 68 | 69 | if (!primorial.isONE()) { 70 | int k = 0, m = j - 2; 71 | 72 | while (m > 0) { 73 | if ((m & 1) == 1) { 74 | expBit[k] = expBit[k].multiply(primorial); 75 | } 76 | m = m / 2; 77 | k++; 78 | } 79 | } 80 | } 81 | 82 | Xint fact = expBit[log2N]; 83 | for (int i = log2N - 1; i >= 0; --i) { 84 | fact = fact.square().multiply(expBit[i]); 85 | } 86 | 87 | return fact.shiftLeft(n - Integer.bitCount(n)); 88 | } 89 | } // endOfFactorialPrimeLeenstra 90 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/FactorialPrimeSchoenhage.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.Xmath; 8 | import de.luschny.math.arithmetic.Xint; 9 | import de.luschny.math.primes.IPrimeIteration; 10 | import de.luschny.math.primes.IPrimeSieve; 11 | import de.luschny.math.primes.PrimeSieve; 12 | 13 | public class FactorialPrimeSchoenhage implements IFactorialFunction { 14 | 15 | private int[] primeList; 16 | private int[] multiList; 17 | 18 | public FactorialPrimeSchoenhage() { 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return "PrimeSchoenhage "; 24 | } 25 | 26 | @Override 27 | public Xint factorial(int n) { 28 | // For very small n the 'NaiveFactorial' is ok. 29 | if (n < 20) { 30 | return Xmath.smallFactorial(n); 31 | } 32 | 33 | int log2n = 31 - Integer.numberOfLeadingZeros(n); 34 | int piN = 2 + (15 * n) / (8 * (log2n - 1)); 35 | 36 | primeList = new int[piN]; 37 | multiList = new int[piN]; 38 | 39 | int len = primeFactors(n); 40 | return nestedSquare(len).shiftLeft(n - Integer.bitCount(n)); 41 | } 42 | 43 | private Xint nestedSquare(int len) { 44 | if (len == 0) { 45 | return Xint.ONE; 46 | } 47 | 48 | // // multiList and primeList initialized in function 'factorial'! 49 | int i = 0, mult = multiList[0]; 50 | 51 | while (mult > 1) { 52 | if ((mult & 1) == 1) // is mult odd ? 53 | { 54 | primeList[len++] = primeList[i]; 55 | } 56 | 57 | multiList[i++] = mult / 2; 58 | mult = multiList[i]; 59 | } 60 | if (len <= i) { 61 | return nestedSquare(i).square(); 62 | } 63 | 64 | return Xint.product(primeList, i, len - i).multiply(nestedSquare(i).square()); 65 | } 66 | 67 | private int primeFactors(int n) { 68 | IPrimeSieve sieve = new PrimeSieve(n); 69 | IPrimeIteration pIter = sieve.getIteration(3, n); 70 | 71 | int maxBound = n / 2, count = 0; 72 | 73 | for (int prime : pIter) { 74 | int m = prime > maxBound ? 1 : 0; 75 | 76 | if (prime <= maxBound) { 77 | int q = n; 78 | while (q >= prime) { 79 | m += q /= prime; 80 | } 81 | } 82 | 83 | // multiList and primeList initialized in function 'factorial'! 84 | primeList[count] = prime; 85 | multiList[count++] = m; 86 | } 87 | return count; 88 | } 89 | } // endOfFactorialPrimeSchoenhage 90 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/FactorialPrimeSwing.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.Xmath; 8 | import de.luschny.math.arithmetic.Xint; 9 | import de.luschny.math.primes.IPrimeIteration; 10 | import de.luschny.math.primes.PrimeSieve; 11 | 12 | public class FactorialPrimeSwing implements IFactorialFunction { 13 | 14 | private PrimeSieve sieve; 15 | private int[] primeList; 16 | 17 | public FactorialPrimeSwing() { 18 | } 19 | 20 | @Override 21 | public String getName() { 22 | return "PrimeSwing "; 23 | } 24 | 25 | @Override 26 | public Xint factorial(int n) { 27 | // For very small n the 'NaiveFactorial' is OK. 28 | if (n < 20) { 29 | return Xmath.smallFactorial(n); 30 | } 31 | 32 | int pLen = (int) (2.0 * Math.floor(Math.sqrt(n) + n / (Xmath.log2(n) - 1))); 33 | primeList = new int[pLen]; 34 | sieve = new PrimeSieve(n); 35 | 36 | return recFactorial(n).shiftLeft(n - Integer.bitCount(n)); 37 | } 38 | 39 | private Xint recFactorial(int n) { 40 | if (n < 2) { 41 | return Xint.ONE; 42 | } 43 | return recFactorial(n / 2).square().multiply(swing(n)); 44 | } 45 | 46 | private Xint swing(int n) { 47 | if (n < 33) { 48 | return Xint.valueOf(smallOddSwing[n]); 49 | } 50 | 51 | // sieve and primeList initialized in function 'factorial'! 52 | int sqrtN = (int) Math.floor(Math.sqrt(n)); 53 | IPrimeIteration pIter0 = sieve.getIteration(3, sqrtN); 54 | IPrimeIteration pIter1 = sieve.getIteration(sqrtN + 1, n / 3); 55 | 56 | int count = 0; 57 | 58 | for (int prime : pIter0) { 59 | int q = n, p = 1; 60 | 61 | while ((q /= prime) > 0) { 62 | if ((q & 1) == 1) { 63 | p *= prime; 64 | } 65 | } 66 | 67 | if (p > 1) { 68 | primeList[count++] = p; 69 | } 70 | } 71 | 72 | for (int prime : pIter1) { 73 | if (((n / prime) & 1) == 1) { 74 | primeList[count++] = prime; 75 | } 76 | } 77 | 78 | Xint prod = sieve.getPrimorial(n / 2 + 1, n); 79 | return prod.multiply(primeList, count); 80 | } 81 | private static final int[] smallOddSwing = {1, 1, 1, 3, 3, 15, 5, 35, 35, 315, 63, 693, 231, 3003, 429, 82 | 6435, 6435, 109395, 12155, 230945, 46189, 969969, 88179, 83 | 2028117, 676039, 16900975, 1300075, 35102025, 5014575, 84 | 145422675, 9694845, 300540195, 300540195}; 85 | } // endOfFactorialPrimeSwingLuschny -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/FactorialPrimeSwingList.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.Xmath; 8 | import de.luschny.math.arithmetic.Xint; 9 | import de.luschny.math.primes.IPrimeIteration; 10 | import de.luschny.math.primes.PrimeSieve; 11 | 12 | public class FactorialPrimeSwingList implements IFactorialFunction { 13 | 14 | private int[][] listPrime; 15 | private int[] listLength; 16 | private int[] tower; 17 | private int[] bound; 18 | 19 | public FactorialPrimeSwingList() { 20 | } 21 | 22 | @Override 23 | public final String getName() { 24 | return "PrimeSwingList "; 25 | } 26 | 27 | @Override 28 | public Xint factorial(int n) { 29 | // For very small n the 'NaiveFactorial' is OK. 30 | if (n < 20) { 31 | return Xmath.smallFactorial(n); 32 | } 33 | 34 | // log2n = floor(log2(n)); 35 | int log2n = 31 - Integer.numberOfLeadingZeros(n); 36 | int j = log2n, hN = n; 37 | 38 | this.listPrime = new int[log2n][]; 39 | listLength = new int[log2n]; 40 | bound = new int[log2n]; 41 | tower = new int[log2n + 1]; 42 | 43 | while (true) { 44 | tower[j] = hN; 45 | if (hN == 1) { 46 | break; 47 | } 48 | bound[--j] = hN / 3; 49 | listPrime[j] = new int[omegaSwingHighBound(hN)]; 50 | hN /= 2; 51 | } 52 | tower[0] = 2; 53 | 54 | primeFactors(n); 55 | return iterQuad().shiftLeft(n - Integer.bitCount(n)); 56 | } 57 | 58 | private Xint iterQuad() { 59 | 60 | // Initializations in in function 'factorial'! 61 | int init = listLength[0] == 0 ? 1 : 3; 62 | Xint fact = Xint.valueOf(init); 63 | 64 | int listLen = listPrime.length; 65 | 66 | for (int i = 1; i < listLen; i++) { 67 | fact = (fact.square()).multiply(listPrime[i], listLength[i]); 68 | } 69 | return fact; 70 | } 71 | 72 | private void primeFactors(int n) { 73 | int maxBound = n / 3; 74 | int lastList = listPrime.length - 1; 75 | int start = tower[1] == 2 ? 1 : 0; 76 | 77 | PrimeSieve sieve = new PrimeSieve(n); 78 | 79 | for (int list = start; list < listPrime.length; list++) { 80 | IPrimeIteration pIter = sieve.getIteration(tower[list] + 1, tower[list + 1]); 81 | 82 | for (int prime : pIter) { 83 | listPrime[list][listLength[list]++] = prime; 84 | if (prime > maxBound) { 85 | continue; 86 | } 87 | 88 | int np = n; 89 | do { 90 | int k = lastList; 91 | int q = np /= prime; 92 | 93 | do { 94 | if ((q & 1) == 1) { 95 | listPrime[k][listLength[k]++] = prime; 96 | } 97 | } while (((q /= 2) > 0) && (prime <= bound[--k])); 98 | 99 | } while (prime <= np); 100 | } 101 | } 102 | } 103 | 104 | private int omegaSwingHighBound(int n) { 105 | return n < 4 ? 6 : (int) (2.0 * (Math.floor(Math.sqrt(n) + n / (Math.log(n) * 1.4426950408889634 - 1.0)))); 106 | } 107 | } // endOfFactorialPrimeSwingList 108 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/FactorialPrimeVardi.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.Xmath; 8 | import de.luschny.math.arithmetic.Xint; 9 | import de.luschny.math.primes.IPrimeIteration; 10 | import de.luschny.math.primes.PrimeSieve; 11 | 12 | public class FactorialPrimeVardi implements IFactorialFunction { 13 | 14 | private PrimeSieve sieve; 15 | 16 | public FactorialPrimeVardi() { 17 | } 18 | 19 | @Override 20 | public final String getName() { 21 | return "PrimeVardi "; 22 | } 23 | 24 | @Override 25 | public Xint factorial(int n) { 26 | // For very small n the 'NaiveFactorial' is ok. 27 | if (n < 20) { 28 | return Xmath.smallFactorial(n); 29 | } 30 | 31 | sieve = new PrimeSieve(n); 32 | 33 | return recFactorial(n); 34 | } 35 | 36 | private Xint recFactorial(int n) { 37 | if (n < 2) { 38 | return Xint.ONE; 39 | } 40 | 41 | if ((n & 1) == 1) { 42 | return recFactorial(n - 1).multiply(n); 43 | } 44 | 45 | return middleBinomial(n).multiply(recFactorial(n / 2).square()); 46 | } 47 | 48 | private Xint middleBinomial(int n) // assuming n = 2k 49 | { 50 | if (n < 50) { 51 | return Xint.valueOf(binom[n / 2]); 52 | } 53 | 54 | int k = n / 2, pc = 0, pp = 0, e; 55 | int rootN = (int) Math.floor(Math.sqrt(n)); 56 | 57 | // sieve initialized in function 'factorial! 58 | Xint bigPrimes = sieve.getPrimorial(k + 1, n); 59 | Xint smallPrimes = sieve.getPrimorial(k / 2 + 1, n / 3); 60 | 61 | IPrimeIteration pIter = sieve.getIteration(rootN + 1, n / 5); 62 | int[] primeList = new int[pIter.getNumberOfPrimes()]; 63 | 64 | for (int prime : pIter) { 65 | if ((n / prime & 1) == 1) // if n/prime is odd... 66 | { 67 | primeList[pc++] = prime; 68 | } 69 | } 70 | Xint prodPrimes = Xint.product(primeList, 0, pc); 71 | 72 | pIter = sieve.getIteration(1, rootN); 73 | Xint[] primePowerList = new Xint[pIter.getNumberOfPrimes()]; 74 | 75 | for (int prime : pIter) { 76 | if ((e = expSum(prime, n)) > 0) { 77 | primePowerList[pp++] = Xint.valueOf(prime).toPowerOf(e); 78 | } 79 | } 80 | Xint powerPrimes = Xint.product(primePowerList, 0, pp); 81 | 82 | return bigPrimes.multiply(smallPrimes).multiply(prodPrimes).multiply(powerPrimes); 83 | } 84 | 85 | private int expSum(int p, int n) { 86 | int exp = 0, q = n / p; 87 | 88 | while (0 < q) { 89 | exp += q & 1; 90 | q /= p; 91 | } 92 | 93 | return exp; 94 | } 95 | private static final long[] binom = {1, 2, 6, 20, 70, 252, 924, 3432, 12870, 48620, 184756, 705432, 2704156, 96 | 10400600, 40116600, 155117520, 601080390, 2333606220L, 9075135300L, 97 | 35345263800L, 137846528820L, 538257874440L, 2104098963720L, 8233430727600L, 98 | 32247603683100L}; 99 | } // endOfFactorialPrimeVardi 100 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/FactorialProductNaive.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.arithmetic.Xint; 8 | 9 | public class FactorialProductNaive implements IFactorialFunction { 10 | 11 | public FactorialProductNaive() { 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return "ProductNaive "; 17 | } 18 | 19 | @Override 20 | public Xint factorial(int n) { 21 | if (n < 0) { 22 | throw new ArithmeticException("Factorial: n has to be >= 0, but was " + n); 23 | } 24 | 25 | Xint nFact = Xint.ONE; 26 | 27 | for (int i = 2; i <= n; i++) { 28 | nFact = nFact.multiply(i); 29 | } 30 | 31 | return nFact; 32 | } 33 | } // endOfFactorialProductNaive 34 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/FactorialProductRecursive.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.arithmetic.Xint; 8 | 9 | public class FactorialProductRecursive implements IFactorialFunction { 10 | 11 | public FactorialProductRecursive() { 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return "ProductRecursive "; 17 | } 18 | 19 | @Override 20 | public Xint factorial(int n) { 21 | if (n < 0) { 22 | throw new ArithmeticException("Factorial: n has to be >= 0, but was " + n); 23 | } 24 | 25 | if (1 < n) { 26 | return recProduct(1, n); 27 | } 28 | 29 | return Xint.ONE; 30 | } 31 | 32 | private Xint recProduct(int n, int len) { 33 | if (1 < len) { 34 | int l = len / 2; 35 | return recProduct(n, l).multiply(recProduct(n + l, len - l)); 36 | } 37 | 38 | return Xint.valueOf(n); 39 | } 40 | } // endOfFactorialProductRecursive 41 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/FactorialSplit.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.arithmetic.Xint; 8 | 9 | public class FactorialSplit implements IFactorialFunction { 10 | 11 | public FactorialSplit() { 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return "Split "; 17 | } 18 | private long N; 19 | 20 | @Override 21 | public Xint factorial(int n) { 22 | if (n < 0) { 23 | throw new ArithmeticException("Factorial: n has to be >= 0, but was " + n); 24 | } 25 | 26 | if (n < 2) { 27 | return Xint.ONE; 28 | } 29 | 30 | Xint p = Xint.ONE; 31 | Xint r = Xint.ONE; 32 | N = 1; 33 | 34 | // log2n = floor(log2(n)); 35 | int log2n = 31 - Integer.numberOfLeadingZeros(n); 36 | int h = 0, shift = 0, high = 1; 37 | 38 | while (h != n) { 39 | shift += h; 40 | h = n >>> log2n--; 41 | int len = high; 42 | high = (h & 1) == 1 ? h : h - 1; 43 | len = (high - len) / 2; 44 | 45 | if (len > 0) { 46 | p = p.multiply(product(len)); 47 | r = r.multiply(p); 48 | } 49 | } 50 | return r.shiftLeft(shift); 51 | } 52 | 53 | private Xint product(int n) { 54 | int m = n / 2; 55 | if (m == 0) { 56 | return Xint.valueOf(N += 2); 57 | } 58 | if (n == 2) { 59 | return Xint.valueOf((N += 2) * (N += 2)); 60 | } 61 | return product(n - m).multiply(product(m)); 62 | } 63 | } // endOfFactorialSplitRecursive 64 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/FactorialSquaredDiff.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.arithmetic.Xint; 8 | 9 | public class FactorialSquaredDiff implements IFactorialFunction { 10 | 11 | public FactorialSquaredDiff() { 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return "SquaredDiff "; 17 | } 18 | 19 | @Override 20 | public Xint factorial(int n) { 21 | if (n < 0) { 22 | throw new ArithmeticException("Factorial: n has to be >= 0, but was " + n); 23 | } 24 | 25 | if (n < 2) { 26 | return Xint.ONE; 27 | } 28 | 29 | long h = n / 2, q = h * h; 30 | long r = (n & 1) == 1 ? 2 * q * n : 2 * q; 31 | Xint f = Xint.valueOf(r); 32 | 33 | for (int d = 1; d < n - 2; d += 2) { 34 | f = f.multiply(q -= d); 35 | } 36 | 37 | return f; 38 | } 39 | } // endOfFactorialSqrDiff 40 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/FactorialSquaredDiffProd.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.arithmetic.Xint; 8 | 9 | public class FactorialSquaredDiffProd implements IFactorialFunction { 10 | 11 | public FactorialSquaredDiffProd() { 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return "SquaredDiffProduct"; 17 | } 18 | 19 | @Override 20 | public Xint factorial(int n) { 21 | if (n < 0) { 22 | throw new ArithmeticException("Factorial: n has to be >= 0, but was " + n); 23 | } 24 | 25 | if (n < 4) { 26 | return Xint.valueOf(n < 2 ? 1 : n == 2 ? 2 : 6); 27 | } 28 | 29 | long h = n / 2, q = h * h; 30 | long[] f = new long[(int) h]; 31 | f[0] = (n & 1) == 1 ? 2 * q * n : 2 * q; 32 | int i = 1; 33 | 34 | for (int d = 1; d < n - 2; d += 2) { 35 | f[i++] = q -= d; 36 | } 37 | 38 | return Xint.product(f); 39 | } 40 | } // endOfFactorialSquaredrDiffProd 41 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/FactorialSwing.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.arithmetic.Xint; 8 | 9 | public class FactorialSwing implements IFactorialFunction { 10 | 11 | public FactorialSwing() { 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return "Swing "; 17 | } 18 | private Xint ndiv4OddFact, ndiv2OddFact; 19 | 20 | @Override 21 | public Xint factorial(int n) { 22 | if (n < 0) { 23 | throw new ArithmeticException("Factorial: n has to be >= 0, but was " + n); 24 | } 25 | 26 | ndiv4OddFact = ndiv2OddFact = Xint.ONE; 27 | 28 | return oddFactorial(n).shiftLeft(n - Integer.bitCount(n)); 29 | } 30 | 31 | private Xint oddFactorial(int n) { 32 | Xint oddFact; 33 | if (n < 17) { 34 | oddFact = Xint.valueOf(smallOddFactorial[n]); 35 | } else { 36 | oddFact = oddFactorial(n / 2).square().multiply(oddSwing(n)); 37 | } 38 | 39 | ndiv4OddFact = ndiv2OddFact; 40 | ndiv2OddFact = oddFact; 41 | return oddFact; 42 | } 43 | 44 | private Xint oddSwing(int n) { 45 | if (n < 33) { 46 | return Xint.valueOf(smallOddSwing[n]); 47 | } 48 | 49 | int len = (n - 1) / 4; 50 | if ((n % 4) != 2) { 51 | len++; 52 | } 53 | int high = n - ((n + 1) & 1); 54 | 55 | int ndiv4 = n / 4; 56 | Xint oddFact = ndiv4 < 17 ? Xint.valueOf(smallOddFactorial[ndiv4]) : ndiv4OddFact; 57 | 58 | return product(high, len).divide(oddFact); 59 | } 60 | 61 | private static Xint product(int m, int len) { 62 | if (len == 1) { 63 | return Xint.valueOf(m); 64 | } 65 | if (len == 2) { 66 | return Xint.valueOf((long) m * (m - 2)); 67 | } 68 | 69 | int hlen = len >>> 1; 70 | return product(m - hlen * 2, len - hlen).multiply(product(m, hlen)); 71 | } 72 | private static final int[] smallOddSwing = {1, 1, 1, 3, 3, 15, 5, 35, 35, 315, 63, 693, 231, 3003, 429, 6435, 6435, 109395, 12155, 230945, 46189, 969969, 73 | 88179, 2028117, 676039, 16900975, 1300075, 35102025, 5014575, 145422675, 9694845, 300540195, 300540195}; 74 | private static final int[] smallOddFactorial = {1, 1, 1, 3, 3, 15, 45, 315, 315, 2835, 14175, 155925, 467775, 6081075, 42567525, 638512875, 638512875}; 75 | } // endOfFactorialSwing 76 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/FactorialSwingDouble.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.arithmetic.Xint; 8 | 9 | public class FactorialSwingDouble implements IFactorialFunction { 10 | 11 | public FactorialSwingDouble() { 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return "SwingDouble "; 17 | } 18 | 19 | @Override 20 | public Xint factorial(int n) { 21 | if (n < 0) { 22 | throw new ArithmeticException("Factorial: n has to be >= 0, but was " + n); 23 | } 24 | 25 | return recFactorial(n); 26 | } 27 | 28 | private Xint recFactorial(int n) { 29 | if (n < 2) { 30 | return Xint.ONE; 31 | } 32 | return recFactorial(n / 2).square().multiply(swing(n)); 33 | } 34 | 35 | private Xint swing(int n) { 36 | boolean oddN = (n & 1) == 1; 37 | boolean div = false; 38 | long h = n / 2; 39 | 40 | switch ((n / 2) % 4) { 41 | case 0: 42 | h = oddN ? h + 1 : 1; 43 | break; 44 | case 1: 45 | h = oddN ? 2 * (h + 2) : 2; 46 | break; 47 | case 2: 48 | h = oddN ? 2 * (h + 1) * (h + 3) : 2 * (h + 1); 49 | div = n > 7; 50 | break; 51 | case 3: 52 | h = oddN ? 4 * (h + 2) * (h + 4) : 4 * (h + 2); 53 | div = n > 7; 54 | break; 55 | // We do not need a default case here. 56 | } 57 | 58 | Xint b = Xint.valueOf(h); 59 | 60 | long D = 1, N = oddN ? 2 * (long)n : 2 * (long)(n - 1); 61 | 62 | for (int i = n / 8; i > 0; --i) { 63 | long num = N * (N - 4), g = num; 64 | long den = D * (D + 1), f = den; 65 | 66 | N -= 8; 67 | D += 2; 68 | 69 | while (f != 0) { 70 | long t = g % f; 71 | g = f; 72 | f = t; 73 | } 74 | 75 | b = b.multiply(num / g).divide(den / g); 76 | } 77 | 78 | if (div) { 79 | b = b.divide(n / 4); 80 | } 81 | 82 | return b; 83 | } 84 | } // endOfSwingDouble 85 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/FactorialSwingSimple.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.arithmetic.Xint; 8 | 9 | public class FactorialSwingSimple implements IFactorialFunction { 10 | 11 | public FactorialSwingSimple() { 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return "SwingSimple "; 17 | } 18 | 19 | @Override 20 | public Xint factorial(int n) { 21 | if (n < 0) { 22 | throw new ArithmeticException("Factorial: n has to be >= 0, but was " + n); 23 | } 24 | 25 | return recFactorial(n); 26 | } 27 | 28 | private Xint recFactorial(int n) { 29 | if (n < 2) { 30 | return Xint.ONE; 31 | } 32 | 33 | return recFactorial(n / 2).square().multiply(swing(n)); 34 | } 35 | 36 | private Xint swing(int n) { 37 | int z; 38 | 39 | switch (n % 4) { 40 | case 1: 41 | z = n / 2 + 1; 42 | break; 43 | case 2: 44 | z = 2; 45 | break; 46 | case 3: 47 | z = 2 * (n / 2 + 2); 48 | break; 49 | default: 50 | z = 1; 51 | break; 52 | } 53 | 54 | Xint b = Xint.valueOf(z); 55 | z = 2 * (n - ((n + 1) & 1)); 56 | 57 | for (int i = 1; i <= n / 4; i++, z -= 4) { 58 | b = b.multiply(z).divide(i); 59 | } 60 | 61 | return b; 62 | } 63 | } // endOfFactorialSwing 64 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/factorial/IFactorialFunction.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.factorial; 6 | 7 | import de.luschny.math.arithmetic.Xint; 8 | 9 | // An interface for the factorial function 10 | // n! = 1*2*3*...*n 11 | // for nonnegative integer values n. 12 | public interface IFactorialFunction { 13 | 14 | Xint factorial(int n); 15 | 16 | String getName(); 17 | } 18 | 19 | // endOfIFactorialFunction 20 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/primes/IPrimeSieve.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.primes; 6 | 7 | import de.luschny.math.util.ILoggable; 8 | import de.luschny.math.util.PositiveRange; 9 | 10 | /** 11 | * An interface for a prime number sieve. 12 | * 13 | * @author Peter Luschny 14 | * @version 2004-09-12 15 | */ 16 | public interface IPrimeSieve extends ILoggable { 17 | 18 | /** 19 | * Checks if a given number is prime. 20 | * 21 | * @param i 22 | * The number the primality of which is to be checked. 23 | * @return True if the given number is prime, false otherwise. 24 | */ 25 | boolean isPrime(int i); 26 | 27 | /** 28 | * Get the n-th prime number. (The first prime number is 2, the second 3, 29 | * the third 5, ...) 30 | * 31 | * @param n 32 | * The index of the prime number searched. 33 | * @return The n-th prime number. 34 | */ 35 | int getNthPrime(int n); 36 | 37 | /** 38 | * The default iteration of the full sieve. Thus it gives the iteration of 39 | * the prime numbers in the range [1, n], where n is the upper bound of the 40 | * sieve, which is an argument to the constructor of the sieve. 41 | * 42 | * @return An iteration of the prime numbers in the range of the sieve. 43 | */ 44 | IPrimeIteration getIteration(); 45 | 46 | /** 47 | * Gives the iteration of the prime numbers in the range [low, high]. 48 | *

49 | * Note: If the range is not in the range of the sieve, the function throws 50 | * an IllegalArgumentException. 51 | * 52 | * @param low 53 | * The lower bound of the range to be sieved. 54 | * @param high 55 | * The upper bound of the range to be sieved. 56 | * @return An iteration of the prime numbers in the range [low, high]. 57 | */ 58 | IPrimeIteration getIteration(int low, int high); 59 | 60 | /** 61 | * Gives the iteration of the prime numbers in the given range. 62 | *

63 | * Note: If the range is not in the range of the sieve, the function throws 64 | * an IllegalArgumentException. 65 | * 66 | * @param range 67 | * The range of integers to be sieved. 68 | * @return An iteration of the prime numbers over the given range. 69 | */ 70 | IPrimeIteration getIteration(PositiveRange range); 71 | } 72 | -------------------------------------------------------------------------------- /JavaFactorial/src/de/luschny/math/util/ILoggable.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2004-2009 Peter Luschny, MIT License applies. 2 | // See http://en.wikipedia.org/wiki/MIT_License 3 | // Visit http://www.luschny.de/math/factorial/FastFactorialFunctions.htm 4 | // Comments mail to: peter(at)luschny.de 5 | package de.luschny.math.util; 6 | 7 | import java.util.logging.Logger; 8 | 9 | /** 10 | * Components that need to log can implement this 11 | * interface to be provided Loggers. 12 | * Note that we use 'enableLogging()' instead of 'setLogger()'. 13 | * The reason is, that this enables a quick refactoring 14 | * if org.apache.avalon.framework.logger is to be used. 15 | */ 16 | public interface ILoggable { 17 | 18 | /** 19 | * Provide a component with a logger. 20 | * 21 | * @param logger The Logger to be used to log the messages. 22 | */ 23 | void enableLogging(Logger logger); 24 | } 25 | -------------------------------------------------------------------------------- /JuliaFactorial/BasicSwingFactorial.jl: -------------------------------------------------------------------------------- 1 | # Copyright Peter Luschny. License is MIT. 2 | 3 | module BasicSwingFactorial 4 | export SwingFactorial 5 | 6 | """ 7 | Return the factorial of ``n``. Implementation of the swing algorithm using no 8 | primes. An advanced version based on prime-factorization which is much faster 9 | is available as the prime-swing factorial. However the claim is that this is 10 | the fastest algorithm not using prime-factorization. It has the same recursive 11 | structure as his big brother. 12 | """ 13 | function SwingFactorial(n::Int)::BigInt 14 | 15 | smallOddFactorial = BigInt[ 0x0000000000000000000000000000001, 16 | 0x0000000000000000000000000000001, 0x0000000000000000000000000000001, 17 | 0x0000000000000000000000000000003, 0x0000000000000000000000000000003, 18 | 0x000000000000000000000000000000f, 0x000000000000000000000000000002d, 19 | 0x000000000000000000000000000013b, 0x000000000000000000000000000013b, 20 | 0x0000000000000000000000000000b13, 0x000000000000000000000000000375f, 21 | 0x0000000000000000000000000026115, 0x000000000000000000000000007233f, 22 | 0x00000000000000000000000005cca33, 0x0000000000000000000000002898765, 23 | 0x00000000000000000000000260eeeeb, 0x00000000000000000000000260eeeeb, 24 | 0x0000000000000000000000286fddd9b, 0x00000000000000000000016beecca73, 25 | 0x000000000000000000001b02b930689, 0x00000000000000000000870d9df20ad, 26 | 0x0000000000000000000b141df4dae31, 0x00000000000000000079dd498567c1b, 27 | 0x00000000000000000af2e19afc5266d, 0x000000000000000020d8a4d0f4f7347, 28 | 0x000000000000000335281867ec241ef, 0x0000000000000029b3093d46fdd5923, 29 | 0x0000000000000465e1f9767cc5866b1, 0x0000000000001ec92dd23d6966aced7, 30 | 0x0000000000037cca30d0f4f0a196e5b, 0x0000000000344fd8dc3e5a1977d7755, 31 | 0x000000000655ab42ab8ce915831734b, 0x000000000655ab42ab8ce915831734b, 32 | 0x00000000d10b13981d2a0bc5e5fdcab, 0x0000000de1bc4d19efcac82445da75b, 33 | 0x000001e5dcbe8a8bc8b95cf58cde171, 0x00001114c2b2deea0e8444a1f3cecf9, 34 | 0x0002780023da37d4191deb683ce3ffd, 0x002ee802a93224bddd3878bc84ebfc7, 35 | 0x07255867c6a398ecb39a64b83ff3751, 0x23baba06e131fc9f8203f7993fc1495] 36 | 37 | function oddProduct(m, len) 38 | if len < 24 39 | p = BigInt(m) 40 | for k in 2:2:2(len-1) 41 | p *= (m - k) 42 | end 43 | return p 44 | end 45 | hlen = len >> 1 46 | oddProduct(m - 2 * hlen, len - hlen) * oddProduct(m, hlen) 47 | end 48 | 49 | function oddFactorial(n) 50 | if n < 41 51 | oddFact = smallOddFactorial[1+n] 52 | sqrOddFact = smallOddFactorial[1+div(n, 2)] 53 | else 54 | sqrOddFact, oldOddFact = oddFactorial(div(n, 2)) 55 | len = div(n - 1, 4) 56 | (n % 4) != 2 && (len += 1) 57 | high = n - ((n + 1) & 1) 58 | oddSwing = div(oddProduct(high, len), oldOddFact) 59 | oddFact = sqrOddFact^2 * oddSwing 60 | end 61 | (oddFact, sqrOddFact) 62 | end 63 | 64 | n < 0 && ArgumentError("n must be ≥ 0") 65 | if n == 0 return 1 end 66 | sh = n - count_ones(n) 67 | oddFactorial(n)[1] << sh 68 | end 69 | 70 | #START-TEST-################################################ 71 | using Test 72 | 73 | function main() 74 | @testset "SwingFactorial" begin 75 | for n in 0:999 76 | S = SwingFactorial(n) 77 | B = Base.factorial(BigInt(n)) 78 | @test S == B 79 | end 80 | end 81 | 82 | GC.gc() 83 | n = 1000000 84 | @time SwingFactorial(n) 85 | end 86 | 87 | main() 88 | 89 | end # module 90 | -------------------------------------------------------------------------------- /JuliaFactorial/PrimeSwingFactorialJulia.jl: -------------------------------------------------------------------------------- 1 | # Copyright Peter Luschny. License is MIT. 2 | 3 | module PrimeSwingFactorial 4 | using PrimesIterator 5 | export PSfactorial, Swing 6 | 7 | """ 8 | Return the accumulated product of an array. 9 | """ 10 | function ∏(A) 11 | function prod(a, b) 12 | n = b - a 13 | if n < 24 14 | p = BigInt(1) 15 | for k in a:b 16 | p *= A[k] 17 | end 18 | return BigInt(p) 19 | end 20 | m = div(a + b, 2) 21 | prod(a, m) * prod(m + 1, b) 22 | end 23 | A == [] && return 1 24 | prod(1, length(A)) 25 | end 26 | 27 | const SwingOddpart = [1,1,1,3,3,15,5,35,35, 315, 63, 693, 231, 3003, 429, 6435, 28 | 6435,109395,12155,230945,46189,969969,88179,2028117,676039,16900975,1300075, 29 | 35102025,5014575,145422675,9694845,300540195,300540195] 30 | 31 | """ 32 | Computes the odd part of the swinging factorial ``n≀``. Cf. A163590. 33 | """ 34 | function swing_oddpart(n::Int) 35 | n < 33 && return ZZ(SwingOddpart[n+1]) 36 | 37 | sqrtn = isqrt(n) 38 | factors = Primes(div(n,2) + 1, n) 39 | r = Primes(sqrtn + 1, div(n, 3)) 40 | s = filter(x -> isodd(div(n, x)), r) 41 | 42 | for prime in Primes(3, sqrtn) 43 | p, q = 1, n 44 | while true 45 | q = div(q, prime) 46 | q == 0 && break 47 | isodd(q) && (p *= prime) 48 | end 49 | p > 1 && push!(s, p) 50 | end 51 | 52 | return ∏(factors)*∏(s) 53 | end 54 | 55 | """ 56 | Computes the swinging factorial (a.k.a. Swing numbers n≀). Cf. A056040. 57 | """ 58 | function Swing(n::Int) 59 | sh = count_ones(div(n, 2)) 60 | swing_oddpart(n) << sh 61 | end 62 | 63 | const FactorialOddPart = [1, 1, 1, 3, 3, 15, 45, 315, 315, 2835, 14175, 155925, 64 | 467775, 6081075, 42567525, 638512875, 638512875, 10854718875, 97692469875, 65 | 1856156927625, 9280784638125, 194896477400625, 2143861251406875, 66 | 49308808782358125, 147926426347074375, 3698160658676859375] 67 | 68 | """ 69 | Return the largest odd divisor of ``n!``. Cf. A049606. 70 | """ 71 | function factorial_oddpart(n::Int) 72 | n < length(FactorialOddPart) && return BigInt(FactorialOddPart[n+1]) 73 | swing_oddpart(n)*(factorial_oddpart(div(n,2))^2) 74 | end 75 | 76 | """ 77 | Return the factorial ``n! = 1*2*...*n``, which is the order of the 78 | symmetric group S_n or the number of permutations of n letters. Cf. A000142. 79 | """ 80 | function PSfactorial(n::Int) 81 | n < 0 && ArgumentError("Argument must be >= 0") 82 | sh = n - count_ones(n) 83 | factorial_oddpart(n) << sh 84 | end 85 | 86 | #START-TEST-######################################################## 87 | using Test 88 | 89 | function main() 90 | @testset "PrimeSwing" begin 91 | for n in 0:999 92 | S = PSfactorial(n) 93 | B = Base.factorial(BigInt(n)) 94 | @test S == B 95 | end 96 | end 97 | @time PSfactorial(1000000) 98 | end 99 | 100 | main() 101 | 102 | end # module 103 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Peter Luschny 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MpirBasedFunctions/ClassDiagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterLuschny/Fast-Factorial-Functions/9ab709a1ade401cdacce909cc976cebf9a8830ed/MpirBasedFunctions/ClassDiagram.png -------------------------------------------------------------------------------- /MpirBasedFunctions/binomial.cpp: -------------------------------------------------------------------------------- 1 | // Author & Copyright : Peter Luschny 2 | // Created: 2010-02-01 3 | // License: LGPL version 2.1 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | 6 | // Based on: 7 | // P. Goetgheluck, Computing Binomial Coefficients, 8 | // American Math. Monthly 94 (1987), 360-365. 9 | // with some additional features. 10 | 11 | #include 12 | #include "binomial.h" 13 | #include "xmath.h" 14 | 15 | void Binomial::PrimeBinomial(Xint binom, ulong n, ulong k) 16 | { 17 | assert(k <= n); // TODO: Error handling 18 | 19 | lmp::SetUi(binom, 1); 20 | if ((k == 0) || (k == n)) return; 21 | 22 | if (k > n / 2) { k = n - k; } 23 | ulong fi = 0, nk = n - k; 24 | 25 | ulong rootN = Xmath::Sqrt(n); 26 | ulong* primes; 27 | ulong piN = Xmath::PrimeSieve(&primes, n); 28 | 29 | for(ulong i = 0; i < piN; i++) 30 | { 31 | ulong prime = primes[i]; 32 | 33 | if (prime > nk) 34 | { 35 | primes[fi++] = prime; 36 | continue; 37 | } 38 | 39 | if (prime > n / 2) 40 | { 41 | continue; 42 | } 43 | 44 | if (prime > rootN) 45 | { 46 | if (n % prime < k % prime) 47 | { 48 | primes[fi++] = prime; 49 | } 50 | continue; 51 | } 52 | 53 | ulong N = n, K = k, p = 1, r = 0; 54 | 55 | while (N > 0) 56 | { 57 | r = (N % prime) < (K % prime + r) ? 1 : 0; 58 | if (r == 1) 59 | { 60 | p *= prime; 61 | } 62 | N /= prime; 63 | K /= prime; 64 | } 65 | primes[fi++] = p; 66 | } 67 | 68 | Xmath::Product(binom, primes, 0, fi); 69 | lmp::FreeUi(primes, piN); 70 | } 71 | 72 | -------------------------------------------------------------------------------- /MpirBasedFunctions/binomial.h: -------------------------------------------------------------------------------- 1 | // Author & Copyright : Peter Luschny 2 | // Created: 2010-01-15 3 | // License: LGPL version 2.1 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | 6 | #ifndef BINOMIAL_H_ 7 | #define BINOMIAL_H_ 8 | 9 | #include "lmp.h" 10 | 11 | class Binomial { 12 | public: 13 | // Computes the factorial of an integer. 14 | static void PrimeBinomial(Xint fact, ulong n, ulong k); 15 | 16 | // Computes the double factorial (Swing algo). 17 | static void ParallelBinomial(Xint fact, ulong n, ulong k); 18 | }; 19 | 20 | #endif // BINOMIAL_H_ 21 | -------------------------------------------------------------------------------- /MpirBasedFunctions/doublefactorial.cpp: -------------------------------------------------------------------------------- 1 | // Author & Copyright : Peter Luschny 2 | // Created: 2010-01-15 3 | // License: LGPL version 2.1 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | 6 | // Computes double factorial. 7 | 8 | #include 9 | #include "primeswing.h" 10 | #include "xmath.h" 11 | 12 | void PrimeSwing::DoubleFactorial(Xint fact, ulong d) 13 | { 14 | if (d < THRESHOLD) { Xmath::NaiveDoubleFactorial(fact, d); return; } 15 | lmp::SetUi(fact, 1); 16 | 17 | int n = ((d & 1) == 0) ? d / 2 : d + 1; 18 | ulong* primes; 19 | ulong piN = Xmath::PrimeSieve(&primes, n); 20 | ulong* factors = lmp::MallocUi(piN); 21 | ulong iterLen = 0; ulong i = n; 22 | slong m = n; while (m > 0) { m >>= 1; iterLen++; } 23 | ulong* iter = lmp::MallocUi(iterLen); 24 | ulong* lim = lmp::MallocUi(iterLen); 25 | m = n; i = iterLen; 26 | while (m > 0) { iter[--i] = m; m >>= 1; } 27 | 28 | Xint primorial; lmp::Init(primorial); 29 | Xint swing; lmp::Init(swing); 30 | 31 | lim[0] = 0; 32 | for (i = 1; i < iterLen; i++) 33 | lim[i] = iter[i] < SOSLEN / 2 ? 0 : 34 | GetIndexOf(primes, iter[i], lim[i-1], piN); 35 | 36 | for (i = 1; i < iterLen; i++) 37 | { 38 | ulong N = iter[i]; 39 | bool norm = (((d & 1) == 0) || (i < iterLen - 1)); 40 | 41 | if (N < SOSLEN) 42 | { 43 | if(norm) lmp::Pow2(fact, fact); 44 | lmp::SetUi(swing, smallOddSwing[N]); 45 | } 46 | else 47 | { 48 | if(norm) 49 | { 50 | lmp::Pow2(fact, fact); 51 | } 52 | 53 | ulong prime = 3; 54 | slong pi = 2, fi = 0; 55 | ulong max = Xmath::Sqrt(N); 56 | 57 | while (prime <= max) 58 | { 59 | ulong q = N, p = 1; 60 | while ((q /= prime) > 0) 61 | { 62 | if ((q & 1) == 1) { p *= prime; } 63 | } 64 | 65 | if (p > 1) { factors[fi++] = p; } 66 | prime = primes[pi++]; 67 | } 68 | 69 | max = N / 3; 70 | while (prime <= max) 71 | { 72 | if (((N / prime) & 1) == 1) 73 | { 74 | factors[fi++] = prime; 75 | } 76 | prime = primes[pi++]; 77 | } 78 | 79 | pi = lim[i] - lim[i-1]; 80 | memcpy(factors + fi, primes + lim[i-1], pi * sizeof(ulong)); 81 | 82 | Xmath::Product(swing, factors, 0, fi + pi); 83 | } 84 | 85 | lmp::Mul(fact, fact, swing); 86 | } 87 | 88 | if((d & 1) == 0) 89 | { 90 | lmp::Mul2Exp(fact, fact, d - Xmath::BitCount(n)); 91 | } 92 | 93 | lmp::Clear(swing); 94 | lmp::Clear(primorial); 95 | lmp::FreeUi(primes, piN); 96 | lmp::FreeUi(factors, piN); 97 | lmp::FreeUi(iter, iterLen); 98 | lmp::FreeUi(lim, iterLen); 99 | } 100 | -------------------------------------------------------------------------------- /MpirBasedFunctions/lmp.h: -------------------------------------------------------------------------------- 1 | // Author & Copyright : Peter Luschny 2 | // Created: 2010-01-15 3 | // License: LGPL version 2.1 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | 6 | // Adapter for library functions. 7 | 8 | #ifndef LMP_H_ 9 | #define LMP_H_ 10 | 11 | #include 12 | 13 | #ifndef __GMP_H__ 14 | #include "mpir.h" 15 | #endif 16 | 17 | typedef mpz_t Xint; 18 | typedef long int slong; 19 | typedef unsigned long int ulong; 20 | 21 | // Paul Zimmermann's implementation of the double factorial 22 | void mpz_fac_ui2 (mpz_ptr result, ulong n); 23 | 24 | class lmp { 25 | public: 26 | 27 | static void Init(Xint res) { 28 | mpz_init(res); 29 | } 30 | static void SetUi(Xint res, ulong n) { 31 | mpz_set_ui(res, n); 32 | } 33 | static void InitSetUi(Xint res, ulong n) { 34 | mpz_init_set_ui(res, n); 35 | } 36 | static void MulUi(Xint res, Xint op1, ulong op2) { 37 | mpz_mul_ui(res, op1, op2); 38 | } 39 | static void Mul(Xint res, Xint op1, Xint op2) { 40 | mpz_mul(res, op1, op2); 41 | } 42 | static void Div(Xint res, Xint op1, Xint op2) { 43 | mpz_cdiv_q(res, op1, op2); 44 | } 45 | // Assuming that mul detects the special case of squaring. 46 | // Otherwise the use of pow(bas, 2) might be better. 47 | static void Pow2(Xint res, Xint bas) { 48 | mpz_mul(res, bas, bas); 49 | } 50 | static void Mul2Exp(Xint res, Xint op1, slong op2) { 51 | mpz_mul_2exp(res, op1, op2); 52 | } 53 | static void FacUi(Xint res, ulong n) { 54 | mpz_fac_ui(res, n); 55 | } 56 | static void BinomialUiUi(Xint res, ulong n, ulong k) { 57 | mpz_bin_uiui(res, n, k); 58 | } 59 | static void ZimmermannFacUi2(mpz_ptr res, ulong n) { 60 | mpz_fac_ui2 (res, n); 61 | } 62 | static slong Cmp(Xint op1, Xint op2) { 63 | return mpz_cmp(op1, op2); 64 | } 65 | static void Clear(Xint b) { 66 | mpz_clear(b); 67 | } 68 | static slong* Malloc(ulong card) { 69 | return (slong*) (malloc)(card * sizeof(slong)); 70 | } 71 | static ulong* MallocUi(ulong card) { 72 | return (ulong*) (malloc)(card * sizeof(ulong)); 73 | } 74 | static void Free(slong* list, ulong card) { 75 | free(list); 76 | } 77 | static void FreeUi(ulong* list, ulong card) { 78 | free(list); 79 | } 80 | }; 81 | 82 | #endif // LMP_H_ 83 | -------------------------------------------------------------------------------- /MpirBasedFunctions/main.cpp: -------------------------------------------------------------------------------- 1 | // Author & Copyright : Peter Luschny 2 | // Created: 2010-01-15 3 | // License: LGPL version 2.1 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | 6 | #include 7 | #include "test.h" 8 | 9 | // static void msg() { std::cout << std::endl << 10 | // "The fastes function is ParallelPrimeSwing. The computing " << std::endl << 11 | // "times of Schoenhage and PrimeSwing are approximately equal. " << std::endl << 12 | // "Note that PrimeSwing uses 1/3 less space than Schoenhage's " << std::endl << 13 | // "algorithm. The space requirements in our implementation are " << std::endl << 14 | // "2.PrimePi(n) for PrimeSwing and 3.PrimePi(n) for Schoenhage." << std::endl << 15 | // "Writing an implementation for large n! without also paying " << std::endl << 16 | // "attention to the required space is pointless." << std::endl; 17 | // std::cin.get(); } 18 | 19 | static void FactTest() 20 | { 21 | Test::FactorialSanityCheck(1000); 22 | 23 | //for(ulong n = 1000000; n < 64000001; n = n*2) 24 | for(ulong n = 1000000; n < 1000000000; n = n*2) 25 | { 26 | Test::FactorialBenchmark(n); 27 | } 28 | 29 | //Test::FactorialBenchmark(100000000); 30 | Test::FactorialBenchmark(1000000000); 31 | } 32 | 33 | static void DoubleFactTest() 34 | { 35 | Test::DoubleFactorialSanityCheck(1000); 36 | 37 | for(ulong n = 1000000; n < 64000002; n = n*2) 38 | { 39 | Test::DoubleFactorialBenchmark(n); 40 | Test::DoubleFactorialBenchmark(n+1); 41 | } 42 | } 43 | 44 | static void BinomialTest() 45 | { 46 | Test::BinomialSanityCheck(333); 47 | 48 | for(ulong n = 100000; n < 6400002; n = n*2) 49 | { 50 | Test::BinomialBenchmark(n, n / 3); 51 | } 52 | } 53 | 54 | int main() 55 | { 56 | char yes; 57 | 58 | std::cout << std::endl << "Factorial Test? (y/n)" << std::endl; 59 | std::cin >> yes; if(yes == 'y' || yes == 'Y') FactTest(); 60 | 61 | std::cout << std::endl << "Binomial Test? (y/n)" << std::endl; 62 | std::cin >> yes; if(yes == 'y' || yes == 'Y') BinomialTest(); 63 | 64 | std::cout << std::endl << "Double Factorial Test? (y/n)" << std::endl; 65 | std::cin >> yes; if(yes == 'y' || yes == 'Y') DoubleFactTest(); 66 | 67 | std::cout << std::endl << "Done." << std::endl; std::cin.get(); 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /MpirBasedFunctions/makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CXX=g++ 3 | RM=rm -f 4 | CPPFLAGS=-g -std=c++11 -pthread -I/usr/local/include 5 | 6 | LDFLAGS=-g -std=c++11 -pthread 7 | LDLIBS=-L/usr/local/lib -lgmp 8 | 9 | SRCS=binomial.cpp double_fac_ui.cpp parallelbinomial.cpp parallelschoenhage.cpp primeswing.cpp doublefactorial.cpp main.cpp paralleldoublefactorial.cpp parallelswing.cpp schoenhage.cpp 10 | 11 | OBJS=$(subst .cpp,.o,$(SRCS)) 12 | 13 | all: main 14 | 15 | main: $(OBJS) 16 | $(CXX) $(LDFLAGS) -o main $(OBJS) $(LDLIBS) 17 | 18 | depend: .depend 19 | 20 | .depend: $(SRCS) 21 | $(RM) ./.depend 22 | $(CXX) $(CPPFLAGS) -MM $^>>./.depend; 23 | 24 | clean: 25 | $(RM) $(OBJS) 26 | 27 | distclean: clean 28 | $(RM) *~ .depend 29 | 30 | include .depend 31 | -------------------------------------------------------------------------------- /MpirBasedFunctions/parallelbinomial.cpp: -------------------------------------------------------------------------------- 1 | // Author & Copyright : Peter Luschny 2 | // Created: 2010-02-01 3 | // License: LGPL version 2.1 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | 6 | // Based on: 7 | // P. Goetgheluck, Computing Binomial Coefficients, 8 | // American Math. Monthly 94 (1987), 360-365. 9 | // with some additional features. 10 | 11 | #include 12 | #include "binomial.h" 13 | #include "xmath.h" 14 | 15 | void Binomial::ParallelBinomial(Xint binom, ulong n, ulong k) 16 | { 17 | assert(k <= n); // TODO: Error handling 18 | 19 | lmp::SetUi(binom, 1); 20 | if ((k == 0) || (k == n)) return; 21 | 22 | if (k > n / 2) { k = n - k; } 23 | ulong fi = 0, nk = n - k; 24 | 25 | ulong rootN = Xmath::Sqrt(n); 26 | ulong* primes; 27 | ulong piN = Xmath::PrimeSieve(&primes, n); 28 | 29 | for(ulong i = 0; i < piN; i++) 30 | { 31 | ulong prime = primes[i]; 32 | 33 | if (prime > nk) 34 | { 35 | primes[fi++] = prime; 36 | continue; 37 | } 38 | 39 | if (prime > n / 2) 40 | { 41 | continue; 42 | } 43 | 44 | if (prime > rootN) 45 | { 46 | if (n % prime < k % prime) 47 | { 48 | primes[fi++] = prime; 49 | } 50 | continue; 51 | } 52 | 53 | ulong N = n, K = k, p = 1, r = 0; 54 | 55 | while (N > 0) 56 | { 57 | r = (N % prime) < (K % prime + r) ? 1 : 0; 58 | if (r == 1) 59 | { 60 | p *= prime; 61 | } 62 | N /= prime; 63 | K /= prime; 64 | } 65 | primes[fi++] = p; 66 | } 67 | 68 | Xmath::ParallelProduct(binom, primes, 0, fi); 69 | lmp::FreeUi(primes, piN); 70 | } 71 | -------------------------------------------------------------------------------- /MpirBasedFunctions/paralleldoublefactorial.cpp: -------------------------------------------------------------------------------- 1 | // Author & Copyright : Peter Luschny 2 | // Created: 2010-01-15 3 | // License: LGPL version 2.1 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | 6 | // Computes double factorial. 7 | 8 | #include 9 | #include "primeswing.h" 10 | #include "xmath.h" 11 | 12 | void PrimeSwing::ParallelDoubleFactorial(Xint fact, ulong d) 13 | { 14 | if (d < THRESHOLD) { Xmath::NaiveDoubleFactorial(fact, d); return; } 15 | lmp::SetUi(fact, 1); 16 | 17 | int n = ((d & 1) == 0) ? d / 2 : d; 18 | ulong* primes; 19 | ulong piN = Xmath::PrimeSieve(&primes, n); 20 | ulong* factors = lmp::MallocUi(piN); 21 | ulong iterLen = 0; ulong i = n; 22 | slong m = n; while (m > 0) { m >>= 1; iterLen++; } 23 | ulong* iter = lmp::MallocUi(iterLen); 24 | ulong* lim = lmp::MallocUi(iterLen); 25 | m = n; i = iterLen; 26 | while (m > 0) { iter[--i] = m; m >>= 1; } 27 | 28 | Xint primorial; lmp::Init(primorial); 29 | Xint swing; lmp::Init(swing); 30 | 31 | lim[0] = 0; 32 | for (i = 1; i < iterLen; i++) 33 | lim[i] = iter[i] < SOSLEN / 2 ? 0 : 34 | GetIndexOf(primes, iter[i], lim[i-1], piN); 35 | 36 | std::thread pow2fact; 37 | 38 | for (i = 1; i < iterLen; i++) 39 | { 40 | ulong N = iter[i]; 41 | bool norm = (((d & 1) == 0) || (i < iterLen - 1)); 42 | 43 | if (N < SOSLEN) 44 | { 45 | if(norm) lmp::Pow2(fact, fact); 46 | lmp::SetUi(swing, smallOddSwing[N]); 47 | } 48 | else 49 | { 50 | if(norm) pow2fact = std::thread(lmp::Pow2, fact, fact); 51 | 52 | ulong prime = 3; 53 | slong pi = 2, fi = 0; 54 | ulong max = Xmath::Sqrt(N); 55 | 56 | while (prime <= max) 57 | { 58 | ulong q = N, p = 1; 59 | while ((q /= prime) > 0) 60 | { 61 | if ((q & 1) == 1) { p *= prime; } 62 | } 63 | 64 | if (p > 1) { factors[fi++] = p; } 65 | prime = primes[pi++]; 66 | } 67 | 68 | max = N / 3; 69 | while (prime <= max) 70 | { 71 | if (((N / prime) & 1) == 1) 72 | { 73 | factors[fi++] = prime; 74 | } 75 | prime = primes[pi++]; 76 | } 77 | 78 | pi = lim[i] - lim[i-1]; 79 | memcpy(factors + fi, primes + lim[i-1], pi * sizeof(ulong)); 80 | 81 | Xmath::Product(swing, factors, 0, fi + pi); 82 | if(norm) pow2fact.join(); 83 | } 84 | 85 | lmp::Mul(fact, fact, swing); 86 | } 87 | 88 | if((d & 1) == 0) 89 | { 90 | lmp::Mul2Exp(fact, fact, d - Xmath::BitCount(n)); 91 | } 92 | 93 | lmp::Clear(swing); 94 | lmp::Clear(primorial); 95 | lmp::FreeUi(primes, piN); 96 | lmp::FreeUi(factors, piN); 97 | lmp::FreeUi(iter, iterLen); 98 | lmp::FreeUi(lim, iterLen); 99 | } 100 | 101 | -------------------------------------------------------------------------------- /MpirBasedFunctions/parallelschoenhage.cpp: -------------------------------------------------------------------------------- 1 | // Author & Copyright : Peter Luschny 2 | // Created: 2010-01-15 3 | // License: LGPL version 2.1 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | 6 | // Differs only in a single function call from Schoenhage::Factorial. 7 | 8 | #include "schoenhage.h" 9 | #include "xmath.h" 10 | 11 | void Schoenhage::ParallelFactorial(Xint result, ulong n) 12 | { 13 | lmp::SetUi(result, 1); 14 | 15 | if (n < 2) { return; } 16 | 17 | slong iterLen = 0, m = n; 18 | ulong lim = n / 2, i; 19 | while (m > 0) { m >>= 1; iterLen++; } 20 | 21 | ulong* primes = 0; 22 | ulong piN = Xmath::PrimeSieve(&primes, n); 23 | ulong* exponents = lmp::MallocUi(piN); 24 | ulong* factors = lmp::MallocUi(piN); 25 | 26 | exponents[0] = n - Xmath::BitCount(n); 27 | 28 | for (i = 1; i < piN; i++) 29 | { 30 | ulong p = primes[i]; 31 | ulong exp = 1; 32 | if (p <= lim) 33 | { 34 | slong N = n / p; 35 | exp = N; 36 | while (N > 0) 37 | { 38 | N /= p; 39 | exp += N; 40 | } 41 | } 42 | exponents[i] = exp; 43 | } 44 | 45 | Xint prod; lmp::Init(prod); 46 | 47 | for (; iterLen >= 0; iterLen--) 48 | { 49 | ulong count = 0; 50 | for (ulong k = 1; k < piN ; k++) 51 | { 52 | if (((exponents[k] >> iterLen) & 1) == 1) 53 | { 54 | factors[count++] = primes[k]; 55 | } 56 | } 57 | 58 | lmp::Pow2(result, result); 59 | if (count > 0) 60 | { 61 | Xmath::ParallelProduct(prod, factors, 0, count); 62 | lmp::Mul(result, result, prod); 63 | } 64 | } 65 | 66 | lmp::Mul2Exp(result, result, exponents[0]); 67 | 68 | lmp::FreeUi(factors, piN); 69 | lmp::FreeUi(primes, piN); 70 | lmp::FreeUi(exponents, piN); 71 | lmp::Clear(prod); 72 | } 73 | 74 | -------------------------------------------------------------------------------- /MpirBasedFunctions/parallelswing.cpp: -------------------------------------------------------------------------------- 1 | // Author & Copyright : Peter Luschny 2 | // Created: 2010-01-15 3 | // License: LGPL version 2.1 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | 6 | #include 7 | #include "primeswing.h" 8 | #include "xmath.h" 9 | 10 | void PrimeSwing::ParallelFactorial(Xint fact, ulong n) 11 | { 12 | if (n < THRESHOLD) { Xmath::NaiveFactorial(fact, n); return; } 13 | lmp::SetUi(fact, 1); 14 | 15 | ulong* primes; 16 | ulong piN = Xmath::PrimeSieve(&primes, n); 17 | ulong* factors = lmp::MallocUi(piN); 18 | ulong iterLen = 0; ulong i = n; 19 | slong m = n; while (m > 0) { m >>= 1; iterLen++; } 20 | ulong* iter = lmp::MallocUi(iterLen); 21 | ulong* lim = lmp::MallocUi(iterLen); 22 | m = n; i = iterLen; 23 | while (m > 0) { iter[--i] = m; m >>= 1; } 24 | 25 | Xint primorial; lmp::Init(primorial); 26 | Xint swing; lmp::Init(swing); 27 | 28 | lim[0] = 0; 29 | for (i = 1; i < iterLen; i++) 30 | lim[i] = iter[i] < SOSLEN / 2 ? 0 : 31 | GetIndexOf(primes, iter[i], lim[i-1], piN); 32 | 33 | for (i = 1; i < iterLen; i++) 34 | { 35 | ulong N = iter[i]; 36 | 37 | if (N < SOSLEN) 38 | { 39 | lmp::Pow2(fact, fact); 40 | lmp::SetUi(swing, smallOddSwing[N]); 41 | } 42 | else 43 | { 44 | std::thread pow(lmp::Pow2, fact, fact); 45 | 46 | ulong prime = 3; 47 | slong pi = 2, fi = 0; 48 | ulong max = Xmath::Sqrt(N); 49 | 50 | while (prime <= max) 51 | { 52 | ulong q = N, p = 1; 53 | while ((q /= prime) > 0) 54 | { 55 | if ((q & 1) == 1) { p *= prime; } 56 | } 57 | 58 | if (p > 1) { factors[fi++] = p; } 59 | prime = primes[pi++]; 60 | } 61 | 62 | max = N / 3; 63 | while (prime <= max) 64 | { 65 | if (((N / prime) & 1) == 1) 66 | { 67 | factors[fi++] = prime; 68 | } 69 | prime = primes[pi++]; 70 | } 71 | 72 | pi = lim[i] - lim[i-1]; 73 | memcpy(factors + fi, primes + lim[i-1], pi * sizeof(ulong)); 74 | 75 | Xmath::Product(swing, factors, 0, fi + pi); 76 | pow.join(); 77 | } 78 | 79 | lmp::Mul(fact, fact, swing); 80 | } 81 | 82 | lmp::Mul2Exp(fact, fact, n - Xmath::BitCount(n)); 83 | 84 | lmp::Clear(swing); 85 | lmp::Clear(primorial); 86 | lmp::FreeUi(primes, piN); 87 | lmp::FreeUi(factors, piN); 88 | lmp::FreeUi(iter, iterLen); 89 | lmp::FreeUi(lim, iterLen); 90 | } 91 | 92 | -------------------------------------------------------------------------------- /MpirBasedFunctions/primeswing.cpp: -------------------------------------------------------------------------------- 1 | // Author & Copyright : Peter Luschny 2 | // Created: 2010-01-15 3 | // License: LGPL version 2.1 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | 6 | #include 7 | #include "primeswing.h" 8 | #include "xmath.h" 9 | 10 | void PrimeSwing::Factorial(Xint fact, ulong n) 11 | { 12 | if (n < THRESHOLD) { Xmath::NaiveFactorial(fact, n); return; } 13 | lmp::SetUi(fact, 1); 14 | 15 | ulong* primes; 16 | ulong piN = Xmath::PrimeSieve(&primes, n); 17 | ulong* factors = lmp::MallocUi(piN); 18 | ulong iterLen = 0; ulong i = n; 19 | slong m = n; while (m > 0) { m >>= 1; iterLen++; } 20 | ulong* iter = lmp::MallocUi(iterLen); 21 | ulong* lim = lmp::MallocUi(iterLen); 22 | m = n; i = iterLen; 23 | while (m > 0) { iter[--i] = m; m >>= 1; } 24 | 25 | Xint primorial; lmp::Init(primorial); 26 | Xint swing; lmp::Init(swing); 27 | 28 | lim[0] = 0; 29 | for (i = 1; i < iterLen; i++) 30 | lim[i] = iter[i] < SOSLEN / 2 ? 0 : 31 | GetIndexOf(primes, iter[i], lim[i-1], piN); 32 | 33 | for (i = 1; i < iterLen; i++) 34 | { 35 | ulong N = iter[i]; 36 | 37 | if (N < SOSLEN) 38 | { 39 | lmp::SetUi(swing, smallOddSwing[N]); 40 | } 41 | else 42 | { 43 | ulong prime = 3; 44 | slong pi = 2, fi = 0; 45 | ulong max = Xmath::Sqrt(N); 46 | 47 | while (prime <= max) 48 | { 49 | ulong q = N, p = 1; 50 | while ((q /= prime) > 0) 51 | { 52 | if ((q & 1) == 1) { p *= prime; } 53 | } 54 | 55 | if (p > 1) 56 | { 57 | factors[fi++] = p; 58 | } 59 | prime = primes[pi++]; 60 | } 61 | 62 | max = N / 3; 63 | while (prime <= max) 64 | { 65 | if (((N / prime) & 1) == 1) 66 | { 67 | factors[fi++] = prime; 68 | } 69 | prime = primes[pi++]; 70 | } 71 | 72 | // for(int k=lim[i-1]; k= lim) { return low; } 47 | if (p[low] == val) { low++; } 48 | 49 | return low; 50 | } 51 | }; 52 | 53 | #endif // PRIMESWING_H_ 54 | 55 | -------------------------------------------------------------------------------- /MpirBasedFunctions/readme.txt: -------------------------------------------------------------------------------- 1 | This project has to be linked against the MPIR library. 2 | http://mpir.org/ 3 | 4 | Look at mpir-devel for the latest informations. 5 | https://groups.google.com/forum/#!forum/mpir-devel 6 | 7 | I used Brian Gladman's fork for testing with Windows. 8 | https://github.com/BrianGladman/mpir 9 | 10 | The provided makefile assumes you install mpir library into 11 | /usr/local/lib and header files into /usr/local/include 12 | If you choose a different location, then edit the CPPFLAGS and 13 | LDFLAGS in makefile accordingly. 14 | 15 | Compiling with makefile has been tested on SLES 12SP3 and 16 | gcc 4.8.5 17 | -------------------------------------------------------------------------------- /MpirBasedFunctions/schoenhage.cpp: -------------------------------------------------------------------------------- 1 | // Author & Copyright : Peter Luschny 2 | // Created: 2010-01-15 3 | // License: LGPL version 2.1 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | 6 | #include "schoenhage.h" 7 | #include "xmath.h" 8 | 9 | void Schoenhage::Factorial(Xint result, ulong n) 10 | { 11 | lmp::SetUi(result, 1); 12 | 13 | if (n < 2) { return; } 14 | 15 | slong iterLen = 0, m = n; 16 | ulong lim = n / 2, i; 17 | while (m > 0) { m >>= 1; iterLen++; } 18 | 19 | ulong* primes = 0; 20 | ulong piN = Xmath::PrimeSieve(&primes, n); 21 | ulong* exponents = lmp::MallocUi(piN); 22 | ulong* factors = lmp::MallocUi(piN); 23 | 24 | exponents[0] = n - Xmath::BitCount(n); 25 | 26 | for(i = 1; i < piN; i++) 27 | { 28 | ulong p = primes[i]; 29 | ulong exp = 1; 30 | if (p <= lim) 31 | { 32 | slong N = n / p; 33 | exp = N; 34 | while (N > 0) 35 | { 36 | N /= p; 37 | exp += N; 38 | } 39 | } 40 | exponents[i] = exp; 41 | } 42 | 43 | Xint prod; lmp::Init(prod); 44 | 45 | for (; iterLen >= 0; iterLen--) 46 | { 47 | ulong count = 0; 48 | for (ulong k = 1; k < piN ; k++) 49 | { 50 | if (((exponents[k] >> iterLen) & 1) == 1) 51 | { 52 | factors[count++] = primes[k]; 53 | } 54 | } 55 | 56 | lmp::Pow2(result, result); 57 | if (count > 0) 58 | { 59 | Xmath::Product(prod, factors, 0, count); 60 | lmp::Mul(result, result, prod); 61 | } 62 | } 63 | 64 | lmp::Mul2Exp(result, result, exponents[0]); 65 | 66 | lmp::FreeUi(factors, piN); 67 | lmp::FreeUi(primes, piN); 68 | lmp::FreeUi(exponents, piN); 69 | lmp::Clear(prod); 70 | } 71 | 72 | 73 | -------------------------------------------------------------------------------- /MpirBasedFunctions/schoenhage.h: -------------------------------------------------------------------------------- 1 | // Author & Copyright : Peter Luschny 2 | // Created: 2010-01-15 3 | // License: LGPL version 2.1 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | 6 | #ifndef SCHOENHAGE_H_ 7 | #define SCHOENHAGE_H_ 8 | 9 | #include "lmp.h" 10 | 11 | class Schoenhage { 12 | public: 13 | 14 | // Computes the factorial of an integer. 15 | static void Factorial(Xint fact, ulong n); 16 | 17 | // Computes the factorial of an integer using threads. 18 | static void ParallelFactorial(Xint fact, ulong n); 19 | }; 20 | 21 | #endif // SCHOENHAGE_H_ 22 | 23 | -------------------------------------------------------------------------------- /MpirBasedFunctions/stopwatch.h: -------------------------------------------------------------------------------- 1 | // Author & Copyright : Peter Luschny 2 | // Created: 2010-01-15 3 | // License: LGPL version 2.1 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | 6 | #ifndef __STOPWATCH_H 7 | #define __STOPWATCH_H 8 | 9 | #include 10 | #include 11 | 12 | typedef std::chrono::high_resolution_clock Time; 13 | typedef std::chrono::milliseconds ms; 14 | typedef std::chrono::duration fsec; 15 | 16 | auto was = Time::now(); 17 | 18 | class StopWatch { 19 | public: 20 | 21 | static void Start() 22 | { 23 | was = Time::now(); 24 | } 25 | 26 | static void ElapsedTime() 27 | { 28 | auto now = Time::now(); 29 | 30 | fsec fs = now - was; 31 | ms d = std::chrono::duration_cast(fs); 32 | std::cout << fs.count() << " s "; 33 | } 34 | }; 35 | 36 | #endif // __STOPWATCH_H 37 | 38 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/Binomial.cs: -------------------------------------------------------------------------------- 1 | /// -------- ToujoursEnBeta 2 | /// Author & Copyright : Peter Luschny 3 | /// License: LGPL version 3.0 or (at your option) 4 | /// Creative Commons Attribution-ShareAlike 3.0 5 | /// Comments mail to: peter(at)luschny.de 6 | /// Created: 2010-03-01 7 | 8 | namespace Sharith.Math.Factorial 9 | { 10 | using Xint = MpirWrapper.Xint; 11 | using Sharith.Math.Primes; 12 | 13 | public sealed class FastBinomial 14 | { 15 | private FastBinomial() { } 16 | 17 | public static Xint Binomial(int n, int k) 18 | { 19 | if (0 > k || k > n) 20 | { 21 | throw new System.ArgumentOutOfRangeException("n", 22 | "Binomial: 0 <= k and k <= n required, but n was " 23 | + n + " and k was " + k); 24 | } 25 | 26 | if (k > n / 2) { k = n - k; } 27 | 28 | int rootN = (int)System.Math.Floor(System.Math.Sqrt(n)); 29 | Xint binom = Xint.One; 30 | 31 | var primeCollection = new PrimeSieve(n).GetPrimeCollection(); 32 | 33 | foreach (int prime in primeCollection) // Equivalent to a nextPrime() function. 34 | { 35 | if (prime > n - k) 36 | { 37 | binom *= prime; 38 | continue; 39 | } 40 | 41 | if (prime > n / 2) 42 | { 43 | continue; 44 | } 45 | 46 | if (prime > rootN) 47 | { 48 | if (n % prime < k % prime) 49 | { 50 | binom *= prime; 51 | } 52 | continue; 53 | } 54 | 55 | int exp = 0, r = 0, N = n, K = k; 56 | 57 | while (N > 0) 58 | { 59 | r = (N % prime) < (K % prime + r) ? 1 : 0; 60 | exp += r; 61 | N /= prime; 62 | K /= prime; 63 | } 64 | 65 | if (exp > 0) 66 | { 67 | binom *= Xint.Pow((Xint) prime, exp); 68 | } 69 | } 70 | return binom; 71 | } 72 | 73 | //static void Main() 74 | //{ 75 | // int n = 5673, k = 1239; 76 | // // int n = 567, k = 123; 77 | 78 | // Xint b = Binomial(n, k); 79 | // Console.WriteLine("(" + n + "," + k + ") -> " + b); 80 | // Console.ReadLine(); 81 | //} 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialAdditiveMoessner.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using XInt = Arithmetic.XInt; 11 | 12 | public class AdditiveMoessner : IFactorialFunction 13 | { 14 | public string Name => "AdditiveMoessner "; 15 | 16 | public XInt Factorial(int n) 17 | { 18 | if (n < 0) 19 | { 20 | throw new System.ArgumentOutOfRangeException( 21 | this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); 22 | } 23 | 24 | var s = new XInt[n + 1]; 25 | s[0] = XInt.One; 26 | 27 | for (var m = 1; m <= n; m++) 28 | { 29 | s[m] = XInt.Zero; 30 | for (var k = m; k >= 1; k--) 31 | { 32 | for (var i = 1; i <= k; i++) 33 | { 34 | s[i] += s[i - 1]; 35 | } 36 | } 37 | } 38 | return s[n]; 39 | } 40 | } 41 | } // endOfFactorialAdditiveMoessner 42 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialAdditiveSwing.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using XInt = Arithmetic.XInt; 11 | 12 | public class AdditiveSwing : IFactorialFunction 13 | { 14 | public string Name => "AdditiveSwing "; 15 | 16 | public XInt Factorial(int n) 17 | { 18 | if (n < 0) 19 | { 20 | throw new System.ArgumentOutOfRangeException( 21 | this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); 22 | } 23 | 24 | return this.RecFactorial(n); 25 | } 26 | 27 | private XInt RecFactorial(int n) 28 | { 29 | if (n < 2) return XInt.One; 30 | 31 | return XInt.Pow(this.RecFactorial(n / 2), 2) * Swing(n); 32 | } 33 | 34 | static XInt Swing(int n) 35 | { 36 | var w = XInt.One; 37 | 38 | if (n > 1) 39 | { 40 | n = n + 2; 41 | var s = new XInt[n + 1]; 42 | 43 | s[0] = s[1] = XInt.Zero; 44 | s[2] = w; 45 | 46 | for (var m = 3; m <= n; m++) 47 | { 48 | s[m] = s[m - 2]; 49 | for (var k = m; k >= 2; k--) 50 | { 51 | s[k] += s[k - 2]; 52 | if ((k & 1) == 1) // if k is odd 53 | { 54 | s[k] += s[k - 1]; 55 | } 56 | } 57 | } 58 | w = s[n]; 59 | } 60 | return w; 61 | } 62 | } 63 | } // endOfFactorialAdditiveSwing 64 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialBalkan.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2013-02-18 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using XInt = Arithmetic.XInt; 11 | using XMath = MathUtils.XMath; 12 | 13 | public class Balkan : IFactorialFunction 14 | { 15 | public string Name => "Balkan "; 16 | 17 | public XInt Factorial(int n) 18 | { 19 | if (n < 0) 20 | { 21 | throw new System.ArgumentOutOfRangeException( 22 | this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); 23 | } 24 | 25 | if (n < 7) 26 | { 27 | return (XInt)(new int[] { 1, 1, 2, 6, 24, 120, 720 })[n]; 28 | } 29 | 30 | int i = 1, loop = n / 2; 31 | var f = new long[loop + (n & 1)]; 32 | 33 | f[0] = loop; 34 | if ((n & 1) == 1) { f[loop] = n; } 35 | 36 | long s = loop; 37 | 38 | for (var inc = loop - 1; inc > 0; inc--) 39 | { 40 | s += inc; 41 | var t = s; 42 | 43 | while ((t & 1) == 0) 44 | { 45 | t /= 2; 46 | loop++; 47 | } 48 | f[i++] = t; 49 | } 50 | return XMath.Product(f) << loop; 51 | 52 | } 53 | } // endOfFactorialBalkan 54 | } 55 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialBalkanBig.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2013-02-18 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using System.Collections.Generic; 11 | using System.Threading.Tasks; 12 | 13 | using XInt = Arithmetic.XInt; 14 | 15 | public class BalkanBig : IFactorialFunction 16 | { 17 | public string Name => "BalkanBig "; 18 | 19 | public XInt Factorial(int n) 20 | { 21 | if (n < 0) 22 | { 23 | throw new System.ArgumentOutOfRangeException( 24 | this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); 25 | } 26 | 27 | if (n < 7) 28 | { 29 | return (XInt)(new int[] { 1, 1, 2, 6, 24, 120, 720 })[n]; 30 | } 31 | 32 | int i = 1, loop = n / 2; 33 | var f = new XInt[loop + (n & 1)]; 34 | 35 | f[0] = loop; 36 | if ((n & 1) == 1) 37 | { 38 | f[loop] = n; 39 | } 40 | 41 | XInt s = loop, t; 42 | 43 | for (var inc = loop - 1; inc > 0; inc--) 44 | { 45 | s += inc; 46 | t = s; 47 | 48 | while (t.IsEven()) 49 | { 50 | loop++; 51 | t /= 2; 52 | } 53 | 54 | f[i++] = t; 55 | } 56 | 57 | return SplitProduct(f) << loop; 58 | } 59 | 60 | static XInt SplitProduct(IReadOnlyList f) 61 | { 62 | var last = f.Count - 1; 63 | 64 | var leftTask = Task.Factory.StartNew(() => RecMul(f, 0, last / 2)); 65 | var right = RecMul(f, last / 2 + 1, last); 66 | 67 | return leftTask.Result * right; 68 | } 69 | 70 | static XInt RecMul(IReadOnlyList f, int n, int m) 71 | { 72 | if (m == n + 1) 73 | { 74 | return f[n] * f[m]; 75 | } 76 | 77 | if (m == n + 2) 78 | { 79 | return f[n] * f[n + 1] * f[m]; 80 | } 81 | 82 | int k = (n + m) / 2; 83 | 84 | return RecMul(f, n, k) * RecMul(f, k + 1, m); 85 | } 86 | 87 | } // endOfFactorialBalkanBig 88 | } 89 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialBoitenSplit.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using XInt = Arithmetic.XInt; 11 | using XMath = MathUtils.XMath; 12 | 13 | public class BoitenSplit : IFactorialFunction 14 | { 15 | public string Name => "BoitenSplit "; 16 | 17 | public XInt Factorial(int n) 18 | { 19 | if (n < 0) 20 | { 21 | throw new System.ArgumentOutOfRangeException( 22 | this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); 23 | } 24 | 25 | if (n < 2) return XInt.One; 26 | 27 | var p = XInt.One; 28 | var r = XInt.One; 29 | 30 | int h = 0, shift = 0, k = 1; 31 | var log2N = XMath.FloorLog2(n); 32 | 33 | while (h != n) 34 | { 35 | shift += h; 36 | h = n >> log2N--; 37 | var high = (h & 1) == 1 ? h : h - 1; 38 | 39 | while (k != high) 40 | { 41 | k += 2; 42 | p *= k; 43 | } 44 | r *= p; 45 | } 46 | 47 | return r << shift; 48 | } 49 | } 50 | } // endOfFactorialBoitenSplit 51 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialCrandallPomerance.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using System.Threading.Tasks; 11 | 12 | using XInt = Arithmetic.XInt; 13 | using XMath = MathUtils.XMath; 14 | 15 | public class CrandallPomerance : IFactorialFunction 16 | { 17 | public string Name => "CrandallPomerance "; 18 | 19 | private static XInt CPpoly(XInt x) 20 | { 21 | // Implemented after Fredrik Johansson's arb-function 22 | // rising_fmprb_ui_bsplit_eight (please speak aloud). 23 | // x(x+1)...(x+7) = (28+98x+63x^2+14x^3+x^4)^2-16(7+2x)^2 24 | 25 | // t = x^2, v = x^3, u = x^4 26 | var t = x * x; 27 | var v = x * t; 28 | var u = t * t; 29 | 30 | // u = (28 + 98x + 63x^2 + 14x^3 + x^4)^2 31 | u += v * 14u; 32 | u += t * 63u; 33 | u += x * 98u; 34 | u += 28; 35 | u *= u; 36 | 37 | // 16 (7+2x)^2 = 784 + 448x + 64x^2 38 | u -= 784u; 39 | u -= x * 448u; 40 | u -= t << 6; 41 | return u ; 42 | } 43 | 44 | public XInt Factorial(int n) 45 | { 46 | if (n < 0) 47 | { 48 | throw new System.ArgumentOutOfRangeException( 49 | this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); 50 | } 51 | 52 | int r = n % 8, s = n / 8 + 1; 53 | var rf = (long)(new int[] { 1, 1, 2, 6, 24, 120, 720, 5040 })[r]; 54 | 55 | if (n < 8) 56 | { 57 | return rf; 58 | } 59 | 60 | var factors = new XInt[s]; 61 | factors[s - 1] = rf; 62 | 63 | Parallel.For(0, s - 1, i => 64 | { 65 | factors[i] = CPpoly(i * 8 + r + 1); 66 | }); 67 | 68 | return XMath.Product(factors, 0, s); 69 | } 70 | } 71 | } // endOfCrandallPomerance 72 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialFactors.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using System.IO; 11 | using Sharith.Primes; 12 | using XMath = MathUtils.XMath; 13 | 14 | public class FactorialFactors 15 | { 16 | public FactorialFactors() 17 | { 18 | } 19 | 20 | public FactorialFactors(int n) 21 | { 22 | this.Factor(n); 23 | } 24 | 25 | int[] primeList; 26 | int[] multiList; 27 | int n, card; 28 | 29 | public int Factor(int n) 30 | { 31 | this.n = n; 32 | 33 | var lgN = XMath.FloorLog2(n); 34 | var piN = 2 + (15 * n) / (8 * (lgN - 1)); 35 | 36 | this.primeList = new int[piN]; 37 | this.multiList = new int[piN]; 38 | 39 | return this.card = this.PrimeFactors(n); 40 | } 41 | 42 | public void SaveToFile(string fileName) 43 | { 44 | var file = new FileInfo(@fileName); 45 | var stream = file.AppendText(); 46 | this.WriteFactors(stream); 47 | stream.Close(); 48 | } 49 | 50 | public void WriteFactors(TextWriter file) 51 | { 52 | if (file == null) 53 | { 54 | return; 55 | } 56 | file.WriteLine("The prime factors of {0}! ", this.n); 57 | 58 | var sum = this.n - XMath.BitCount(this.n); 59 | file.Write("2^{0}", sum); 60 | 61 | for (var p = 0; p < this.card; p++) 62 | { 63 | int f = this.primeList[p], m = this.multiList[p]; 64 | sum += m; 65 | if (m > 1) 66 | { 67 | file.Write("*{0}^{1}", f, m); 68 | } 69 | else 70 | { 71 | file.Write("*{0}", f); 72 | } 73 | } 74 | 75 | file.WriteLine(); 76 | file.WriteLine("Number of different factors: {0} ", this.card); 77 | file.WriteLine("Number of all factors: {0} ", sum); 78 | } 79 | 80 | private int PrimeFactors(int n) 81 | { 82 | var sieve = new PrimeSieve(n); 83 | var primeCollection = sieve.GetPrimeCollection(2, n); 84 | 85 | int maxBound = n / 2, count = 0; 86 | 87 | foreach (var prime in primeCollection) 88 | { 89 | var m = prime > maxBound ? 1 : 0; 90 | 91 | if (prime <= maxBound) 92 | { 93 | var q = n; 94 | while (q >= prime) 95 | { 96 | m += q /= prime; 97 | } 98 | } 99 | 100 | this.primeList[count] = prime; 101 | this.multiList[count++] = m; 102 | } 103 | 104 | return count; 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialHyper.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2004-03-01 7 | 8 | ///////////////////////////////// 9 | //// buggy for large values of n 10 | ///////////////////////////////// 11 | namespace Sharith.Factorial 12 | { 13 | using XInt = Arithmetic.XInt; 14 | 15 | public class Hyper : IFactorialFunction 16 | { 17 | public string Name => "Hyper "; 18 | 19 | bool nostart; 20 | long s, k, a; 21 | 22 | public XInt Factorial(int n) 23 | { 24 | if (n < 0) 25 | { 26 | throw new System.ArgumentOutOfRangeException( 27 | this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); 28 | } 29 | 30 | this.nostart = false; 31 | var h = n / 2; 32 | this.s = h + 1; 33 | this.k = this.s + h; 34 | this.a = (n & 1) == 1 ? this.k : 1; 35 | if ((h & 1) == 1) this.a = -this.a; 36 | this.k += 4; 37 | 38 | return this.HyperFact(h + 1) << h; 39 | } 40 | 41 | private XInt HyperFact(int l) 42 | { 43 | if (l > 1) 44 | { 45 | var m = l >> 1; 46 | return this.HyperFact(m) * this.HyperFact(l - m); 47 | } 48 | 49 | if (this.nostart) 50 | { 51 | this.s -= this.k -= 4; 52 | return (XInt)this.s; 53 | } 54 | this.nostart = true; 55 | return (XInt)this.a; 56 | } 57 | } 58 | } // endOfFactorialHyper 59 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialLinearDifference.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using XInt = Arithmetic.XInt; 11 | 12 | public class LinearDifference : IFactorialFunction 13 | { 14 | public string Name => "LinearDifference "; 15 | 16 | public XInt Factorial(int n) 17 | { 18 | if (n < 0) 19 | { 20 | throw new System.ArgumentOutOfRangeException( 21 | this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); 22 | } 23 | 24 | if (n < 2) return XInt.One; 25 | 26 | XInt f; 27 | 28 | switch (n % 4) 29 | { 30 | case 1: f = (XInt) n; break; 31 | case 2: f = (XInt)((long)n * (n - 1)); break; 32 | case 3: f = (XInt)((long)n * (n - 1) * (n - 2)); break; 33 | default: f = XInt.One; break; 34 | } 35 | 36 | long prod = 24; 37 | long diff1 = 1656; 38 | long diff2 = 8544; 39 | long diff3 = 13056; 40 | 41 | var i = n / 4; 42 | while (i-- > 0) 43 | { 44 | f = f * prod; 45 | prod += diff1; 46 | diff1 += diff2; 47 | diff2 += diff3; 48 | diff3 += 6144; 49 | } 50 | return f; 51 | } 52 | } 53 | } // endOfFactorialLinearDifference 54 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialMyFactorial.cs: -------------------------------------------------------------------------------- 1 | // This is a template. 2 | // Just replace the body of "public XInt Factorial(int n)" with your function, 3 | // compile and start benchmarking your solution. If you found a nice solution 4 | // please share it and send it to me for inclusion. 5 | 6 | namespace Sharith.Factorial 7 | { 8 | using XInt = Sharith.Arithmetic.XInt; 9 | 10 | public class MyFactorial : IFactorialFunction 11 | { 12 | public string Name => "MyFactorial "; 13 | 14 | // --- Implement this function! --- 15 | public XInt Factorial(int n) 16 | { 17 | return new ParallelPrimeSwing().Factorial(n); 18 | } 19 | } 20 | } // endOfMyFactorial 21 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialParallelForPrimeSplit.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using System.Linq; 11 | using System.Threading.Tasks; 12 | 13 | using Sharith.Primes; 14 | 15 | using XInt = Sharith.Arithmetic.XInt; 16 | using XMath = Sharith.MathUtils.XMath; 17 | 18 | public class ParallelForPrimeSplit : IFactorialFunction 19 | { 20 | PrimeSieve sieve; 21 | 22 | public string Name => "ParallelFrPrimeSplit"; 23 | 24 | public XInt Factorial(int n) 25 | { 26 | if (n < 20) { return XMath.Factorial(n); } 27 | 28 | this.sieve = new PrimeSieve(n); 29 | var log2N = XMath.FloorLog2(n); 30 | var source = new int[log2N]; 31 | int h = 0, shift = 0, length = 0; 32 | 33 | // -- It is more efficient to add the big intervals 34 | // -- first and the small ones later! Is it? 35 | while (h != n) 36 | { 37 | shift += h; 38 | h = n >> log2N--; 39 | if (h > 2) { source[length++] = h; } 40 | } 41 | 42 | var results = new XInt[length]; 43 | 44 | Parallel.For(0, length, currentIndex => 45 | results[currentIndex] = this.Swing(source[currentIndex]) 46 | ); 47 | 48 | XInt p = XInt.One, r = XInt.One, rl = XInt.One; 49 | 50 | for (var i = 0; i < length; i++) 51 | { 52 | var t = rl * results[i]; 53 | p = p * t; 54 | rl = r; 55 | r = r * p; 56 | } 57 | 58 | return r << shift; 59 | } 60 | 61 | XInt Swing(int n) 62 | { 63 | if (n < 33) return SmallOddSwing[n]; 64 | 65 | var primorial = Task.Factory.StartNew(() => 66 | this.sieve.GetPrimorial(n / 2 + 1, n)); 67 | var count = 0; 68 | var rootN = XMath.FloorSqrt(n); 69 | var aPrimes = this.sieve.GetPrimeCollection(3, rootN); 70 | var bPrimes = this.sieve.GetPrimeCollection(rootN + 1, n / 3); 71 | var piN = aPrimes.NumberOfPrimes + bPrimes.NumberOfPrimes; 72 | var primeList = new int[piN]; 73 | 74 | foreach (var prime in aPrimes) 75 | { 76 | int q = n, p = 1; 77 | 78 | while ((q /= prime) > 0) 79 | { 80 | if ((q & 1) == 1) 81 | { 82 | p *= prime; 83 | } 84 | } 85 | 86 | if (p > 1) 87 | { 88 | primeList[count++] = p; 89 | } 90 | } 91 | 92 | foreach (var prime in bPrimes.Where(prime => ((n / prime) & 1) == 1)) 93 | { 94 | primeList[count++] = prime; 95 | } 96 | 97 | var primeProduct = XMath.Product(primeList, 0, count); 98 | return primeProduct * primorial.Result; 99 | } 100 | 101 | static readonly XInt[] SmallOddSwing = { 102 | 1,1,1,3,3,15,5,35,35,315,63,693,231,3003,429,6435,6435,109395, 103 | 12155,230945,46189,969969,88179,2028117,676039,16900975,1300075, 104 | 35102025,5014575,145422675,9694845,300540195,300540195 }; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialParallelPrimeSplit.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using System; 11 | using System.Linq; 12 | using System.Threading.Tasks; 13 | using Sharith.Primes; 14 | 15 | using XInt = Arithmetic.XInt; 16 | using XMath = MathUtils.XMath; 17 | 18 | public class ParallelPrimeSplit : IFactorialFunction 19 | { 20 | PrimeSieve sieve; 21 | 22 | public string Name => "ParallelPrimeSplit "; 23 | 24 | delegate XInt SwingDelegate(int n); 25 | 26 | public XInt Factorial(int n) 27 | { 28 | if (n < 20) { return XMath.Factorial(n); } 29 | 30 | this.sieve = new PrimeSieve(n); 31 | var log2N = XMath.FloorLog2(n); 32 | 33 | SwingDelegate swingDelegate = this.Swing; 34 | var results = new IAsyncResult[log2N]; 35 | 36 | int h = 0, shift = 0, taskCounter = 0; 37 | 38 | // -- It is more efficient to add the big intervals 39 | // -- first and the small ones later! 40 | while (h != n) 41 | { 42 | shift += h; 43 | h = n >> log2N--; 44 | if (h > 2) 45 | { 46 | results[taskCounter++] = swingDelegate.BeginInvoke(h, null, null); 47 | } 48 | } 49 | 50 | XInt p = XInt.One, r = XInt.One, rl = XInt.One; 51 | 52 | for (var i = 0; i < taskCounter; i++) 53 | { 54 | var t = rl * swingDelegate.EndInvoke(results[i]); 55 | p = p * t; 56 | rl = r; 57 | r = r * p; 58 | } 59 | 60 | return r << shift; 61 | } 62 | 63 | private XInt Swing(int n) 64 | { 65 | if (n < 33) return SmallOddSwing[n]; 66 | 67 | var primorial = Task.Factory.StartNew(() => this.sieve.GetPrimorial(n / 2 + 1, n)); 68 | var count = 0; 69 | var rootN = XMath.FloorSqrt(n); 70 | var aPrimes = this.sieve.GetPrimeCollection(3, rootN); 71 | var bPrimes = this.sieve.GetPrimeCollection(rootN + 1, n / 3); 72 | var piN = aPrimes.NumberOfPrimes + bPrimes.NumberOfPrimes; 73 | var primeList = new int[piN]; 74 | 75 | foreach (var prime in aPrimes) 76 | { 77 | int q = n, p = 1; 78 | 79 | while ((q /= prime) > 0) 80 | { 81 | if ((q & 1) == 1) 82 | { 83 | p *= prime; 84 | } 85 | } 86 | 87 | if (p > 1) 88 | { 89 | primeList[count++] = p; 90 | } 91 | } 92 | 93 | foreach (var prime in bPrimes.Where(prime => ((n / prime) & 1) == 1)) 94 | { 95 | primeList[count++] = prime; 96 | } 97 | 98 | var primeProduct = XMath.Product(primeList, 0, count); 99 | return primeProduct * primorial.Result; 100 | } 101 | 102 | static readonly XInt[] SmallOddSwing = { 103 | 1,1,1,3,3,15,5,35,35,315,63,693,231,3003,429,6435,6435,109395, 104 | 12155,230945,46189,969969,88179,2028117,676039,16900975,1300075, 105 | 35102025,5014575,145422675,9694845,300540195,300540195 }; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialParallelPrimeSwingList.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using System.Threading.Tasks; 11 | using Sharith.Primes; 12 | 13 | using XInt = Arithmetic.XInt; 14 | using XMath = MathUtils.XMath; 15 | 16 | public class ParallelPrimeSwingList : IFactorialFunction 17 | { 18 | private int[][] primeList; 19 | private int[] listLength; 20 | private int[] tower; 21 | private int[] bound; 22 | 23 | public string Name => "ParallelPrimeSwingList"; 24 | 25 | public XInt Factorial(int n) 26 | { 27 | if (n < 20) { return XMath.Factorial(n); } 28 | 29 | var log2N = XMath.FloorLog2(n); 30 | var j = log2N; 31 | var hN = n; 32 | 33 | this.primeList = new int[log2N][]; 34 | this.listLength = new int[log2N]; 35 | this.bound = new int[log2N]; 36 | this.tower = new int[log2N + 1]; 37 | 38 | while (true) 39 | { 40 | this.tower[j] = hN; 41 | if (hN == 1) break; 42 | this.bound[--j] = hN / 3; 43 | var pLen = hN < 4 ? 6 : (int)(2.0 * (XMath.FloorSqrt(hN) 44 | + (double) hN / (XMath.Log2(hN) - 1))); 45 | this.primeList[j] = new int[pLen]; 46 | hN >>= 1; 47 | } 48 | 49 | this.tower[0] = 2; 50 | this.PrimeFactors(n); 51 | 52 | var init = this.listLength[0] == 0 ? 1 : 3; 53 | var oddFactorial = new XInt(init); 54 | 55 | var results = new XInt[log2N]; 56 | Parallel.For(1, log2N, i => 57 | results[i] = XMath.Product(this.primeList[i], 0, this.listLength[i]) 58 | ); 59 | 60 | for (var i = 1; i < log2N; i++) 61 | { 62 | oddFactorial = XInt.Pow(oddFactorial, 2); 63 | oddFactorial = oddFactorial * results[i]; 64 | } 65 | 66 | return oddFactorial << (n - XMath.BitCount(n)); 67 | } 68 | 69 | private void PrimeFactors(int n) 70 | { 71 | var maxBound = n / 3; 72 | var lastList = this.primeList.Length - 1; 73 | var start = this.tower[1] == 2 ? 1 : 0; 74 | var sieve = new PrimeSieve(n); 75 | 76 | for (var section = start; section < this.primeList.Length; section++) 77 | { 78 | var primes = sieve.GetPrimeCollection(this.tower[section] + 1, this.tower[section + 1]); 79 | 80 | foreach (var prime in primes) 81 | { 82 | this.primeList[section][this.listLength[section]++] = prime; 83 | if (prime > maxBound) continue; 84 | 85 | var np = n; 86 | do 87 | { 88 | var k = lastList; 89 | var q = np /= prime; 90 | 91 | do if ((q & 1) == 1) //if q is odd 92 | { 93 | this.primeList[k][this.listLength[k]++] = prime; 94 | } 95 | while (((q >>= 1) > 0) && (prime <= this.bound[--k])); 96 | 97 | } while (prime <= np); 98 | } 99 | } 100 | } 101 | } 102 | } // endOfFactorialParallelPrimeSwingList 103 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialParallelSplit.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | // Same algorithm as Split 9 | // but computing products using tasks. 10 | 11 | namespace Sharith.Factorial 12 | { 13 | using System; 14 | using System.Threading.Tasks; 15 | 16 | using XInt = Arithmetic.XInt; 17 | using XMath = MathUtils.XMath; 18 | 19 | public class ParallelSplit : IFactorialFunction 20 | { 21 | public string Name => "ParallelSplit "; 22 | 23 | private delegate XInt ProductDelegate(int from, int to); 24 | 25 | XInt IFactorialFunction.Factorial(int n) 26 | { 27 | if (n < 0) 28 | { 29 | throw new System.ArgumentOutOfRangeException( 30 | this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); 31 | } 32 | 33 | if (n < 2) return XInt.One; 34 | 35 | var log2N = XMath.FloorLog2(n); 36 | ProductDelegate prodDelegate = Product; 37 | var results = new IAsyncResult[log2N]; 38 | 39 | int high = n, low = n >> 1, shift = low, taskCounter = 0; 40 | 41 | // -- It is more efficient to add the big intervals 42 | // -- first and the small ones later! 43 | while ((low + 1) < high) 44 | { 45 | results[taskCounter++] = prodDelegate.BeginInvoke(low + 1, high, null, null); 46 | high = low; 47 | low >>= 1; 48 | shift += low; 49 | } 50 | 51 | XInt p = XInt.One, r = XInt.One; 52 | while (--taskCounter >= 0) 53 | { 54 | var I = Task.Factory.StartNew(() => r * p); 55 | var t = p * prodDelegate.EndInvoke(results[taskCounter]); 56 | r = I.Result; 57 | p = t; 58 | } 59 | 60 | return (r * p) << shift; 61 | } 62 | 63 | private static XInt Product(int n, int m) 64 | { 65 | n = n | 1; // Round n up to the next odd number 66 | m = (m - 1) | 1; // Round m down to the next odd number 67 | 68 | if (m == n) 69 | { 70 | return new XInt(m); 71 | } 72 | 73 | if (m == (n + 2)) 74 | { 75 | return new XInt((long)n * m); 76 | } 77 | 78 | var k = (n + m) >> 1; 79 | return Product(n, k) * Product(k + 1, m); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialParallelSwing.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using System; 11 | using System.Threading.Tasks; 12 | 13 | using XInt = Arithmetic.XInt; 14 | using XMath = MathUtils.XMath; 15 | 16 | public class ParallelSwing : IFactorialFunction 17 | { 18 | public string Name => "ParallelSwing "; 19 | 20 | private XInt oddFactNdiv4, oddFactNdiv2; 21 | private const int Smallswing = 33; 22 | private const int Smallfact = 17; 23 | private Task oddSwingTask; 24 | 25 | public XInt Factorial(int n) 26 | { 27 | if (n < 0) 28 | { 29 | throw new ArithmeticException( 30 | this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); 31 | } 32 | 33 | this.oddFactNdiv4 = this.oddFactNdiv2 = XInt.One; 34 | return this.OddFactorial(n) << (n - XMath.BitCount(n)); 35 | } 36 | 37 | private XInt OddFactorial(int n) 38 | { 39 | if (n < Smallfact) 40 | { 41 | return SmallOddFactorial[n]; 42 | } 43 | 44 | var sqrOddFact = this.OddFactorial(n / 2); 45 | XInt oddFact; 46 | 47 | if (n < Smallswing) 48 | { 49 | oddFact = XInt.Pow(sqrOddFact, 2) * SmallOddSwing[n]; 50 | } 51 | else 52 | { 53 | var ndiv4 = n / 4; 54 | var oddFactNd4 = ndiv4 < Smallfact ? SmallOddFactorial[ndiv4] : this.oddFactNdiv4; 55 | this.oddSwingTask = Task.Factory.StartNew( () => OddSwing(n, oddFactNd4)); 56 | 57 | sqrOddFact = XInt.Pow(sqrOddFact, 2); 58 | oddFact = sqrOddFact * this.oddSwingTask.Result; 59 | } 60 | 61 | this.oddFactNdiv4 = this.oddFactNdiv2; 62 | this.oddFactNdiv2 = oddFact; 63 | return oddFact; 64 | } 65 | 66 | static XInt OddSwing(int n, XInt oddFactNdiv4) 67 | { 68 | var len = (n - 1) / 4; 69 | if ((n % 4) != 2) len++; 70 | 71 | //-- if type(n, odd) then high = n else high = n-1. 72 | var high = n - ((n + 1) & 1); 73 | 74 | return Product(high, len) / oddFactNdiv4; 75 | } 76 | 77 | static XInt Product(int m, int len) 78 | { 79 | if (len == 1) return new XInt(m); 80 | if (len == 2) return new XInt((long)m * (m - 2)); 81 | 82 | var hlen = len >> 1; 83 | return Product(m - hlen * 2, len - hlen) * Product(m, hlen); 84 | } 85 | 86 | static readonly XInt[] SmallOddSwing = { 87 | 1,1,1,3,3,15,5,35,35,315,63,693,231,3003,429,6435,6435,109395, 88 | 12155,230945,46189,969969,88179,2028117,676039,16900975,1300075, 89 | 35102025,5014575,145422675,9694845,300540195,300540195 }; 90 | 91 | static readonly XInt[] SmallOddFactorial = { 92 | 1,1,1,3,3,15,45,315,315,2835,14175,155925,467775,6081075, 93 | 42567525,638512875,638512875 }; 94 | 95 | } // endOfFactorialParallelSwing 96 | } 97 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialPrimeBorwein.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using Sharith.Primes; 11 | 12 | using XInt = Arithmetic.XInt; 13 | using XMath = MathUtils.XMath; 14 | 15 | public class PrimeBorwein : IFactorialFunction 16 | { 17 | public string Name => "PrimeBorwein "; 18 | 19 | int[] primeList; 20 | int[] multiList; 21 | 22 | public XInt Factorial(int n) 23 | { 24 | if (n < 0) 25 | { 26 | throw new System.ArgumentOutOfRangeException( 27 | this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); 28 | } 29 | 30 | if (n < 20) { return XMath.Factorial(n); } 31 | 32 | var lgN = XMath.FloorLog2(n); 33 | var piN = 2 + (15 * n) / (8 * (lgN - 1)); 34 | 35 | this.primeList = new int[piN]; 36 | this.multiList = new int[piN]; 37 | 38 | var len = this.PrimeFactors(n); 39 | var exp2 = n - XMath.BitCount(n); 40 | 41 | return this.RepeatedSquare(len, 1) << exp2; 42 | } 43 | 44 | private XInt RepeatedSquare(int len, int k) 45 | { 46 | if (len == 0) return XInt.One; 47 | 48 | int i = 0, mult = this.multiList[0]; 49 | 50 | while (mult > 1) 51 | { 52 | if ((mult & 1) == 1) // is mult odd ? 53 | { 54 | this.primeList[len++] = this.primeList[i]; 55 | } 56 | 57 | this.multiList[i++] = mult >> 1; 58 | mult = this.multiList[i]; 59 | } 60 | 61 | var p = XMath.Product(this.primeList, i, len - i); 62 | return XInt.Pow(p, k) * this.RepeatedSquare(i, 2 * k); 63 | } 64 | 65 | private int PrimeFactors(int n) 66 | { 67 | var sieve = new PrimeSieve(n); 68 | var primeCollection = sieve.GetPrimeCollection(3, n); 69 | 70 | int maxBound = n / 2, count = 0; 71 | 72 | foreach (var prime in primeCollection) 73 | { 74 | var m = prime > maxBound ? 1 : 0; 75 | 76 | if (prime <= maxBound) 77 | { 78 | var q = n; 79 | while (q >= prime) 80 | { 81 | m += q /= prime; 82 | } 83 | } 84 | this.primeList[count] = prime; 85 | this.multiList[count++] = m; 86 | } 87 | return count; 88 | } 89 | } 90 | } // endOfFactorialPrimeBorwein 91 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialPrimeLeenstra.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using Sharith.Primes; 11 | 12 | using XInt = Sharith.Arithmetic.XInt; 13 | using XMath = Sharith.MathUtils.XMath; 14 | 15 | public class PrimeLeenstra : IFactorialFunction 16 | { 17 | public string Name => "PrimeLeenstra "; 18 | 19 | public XInt Factorial(int n) 20 | { 21 | if (n < 20) { return XMath.Factorial(n); } 22 | 23 | var rootN = XMath.FloorSqrt(n); 24 | var log2N = XMath.FloorLog2(n); 25 | var section = new XInt[log2N + 1]; 26 | 27 | for (var i = 0; i < section.Length; i++) 28 | { 29 | section[i] = XInt.One; 30 | } 31 | 32 | var sieve = new PrimeSieve(n); 33 | var primes = sieve.GetPrimeCollection(3, rootN); 34 | 35 | foreach (var prime in primes) 36 | { 37 | int k = 0, m = 0, q = n; 38 | 39 | do 40 | { 41 | m += q /= prime; 42 | 43 | } while (q >= 1); 44 | 45 | while (m > 0) 46 | { 47 | if ((m & 1) == 1) 48 | { 49 | section[k] *= prime; 50 | } 51 | m = m / 2; 52 | k++; 53 | } 54 | } 55 | 56 | var j = 2; 57 | var low = n; 58 | 59 | while (low != rootN) 60 | { 61 | var high = low; 62 | low = n / j++; 63 | 64 | if (low < rootN) { low = rootN; } 65 | 66 | var primorial = sieve.GetPrimorial(low + 1, high); 67 | 68 | if (primorial != XInt.One) 69 | { 70 | int k = 0, m = j - 2; 71 | 72 | while (m > 0) 73 | { 74 | if ((m & 1) == 1) 75 | { 76 | section[k] *= primorial; 77 | } 78 | m = m / 2; 79 | k++; 80 | } 81 | } 82 | } 83 | 84 | var factorial = section[log2N]; 85 | for (var i = log2N - 1; i >= 0; --i) 86 | { 87 | factorial = XInt.Pow(factorial,2) * section[i]; 88 | } 89 | 90 | var exp2N = n - XMath.BitCount(n); 91 | return factorial << exp2N; 92 | } 93 | } 94 | } // endOfFactorialPrimeLeenstra 95 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialPrimeSchoenhage.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using Sharith.Primes; 11 | 12 | using XInt = Sharith.Arithmetic.XInt; 13 | using XMath = Sharith.MathUtils.XMath; 14 | 15 | public class PrimeSchoenhage : IFactorialFunction 16 | { 17 | public string Name => "PrimeSchoenhage "; 18 | private int[] primeList; 19 | private int[] multiList; 20 | 21 | public XInt Factorial(int n) 22 | { 23 | if (n < 20) { return XMath.Factorial(n); } 24 | 25 | var lgN = XMath.FloorLog2(n); 26 | var piN = 2 + (15 * n) / (8 * (lgN - 1)); 27 | 28 | this.primeList = new int[piN]; 29 | this.multiList = new int[piN]; 30 | 31 | var len = this.PrimeFactors(n); 32 | var exp2 = n - XMath.BitCount(n); 33 | 34 | return this.NestedSquare(len) << exp2; 35 | } 36 | 37 | private XInt NestedSquare(int len) 38 | { 39 | if (len == 0) return XInt.One; 40 | 41 | var i = 0; 42 | var mult = this.multiList[0]; 43 | 44 | while (mult > 1) 45 | { 46 | if ((mult & 1) == 1) // is mult odd ? 47 | { 48 | this.primeList[len++] = this.primeList[i]; 49 | } 50 | 51 | this.multiList[i++] = mult >> 1; 52 | mult = this.multiList[i]; 53 | } 54 | 55 | return XMath.Product(this.primeList, i, len - i) 56 | * XInt.Pow(this.NestedSquare(i), 2); 57 | } 58 | 59 | private int PrimeFactors(int n) 60 | { 61 | var sieve = new PrimeSieve(n); 62 | var primes = sieve.GetPrimeCollection(3, n); 63 | 64 | int maxBound = n / 2, count = 0; 65 | 66 | foreach (var prime in primes) 67 | { 68 | var m = prime > maxBound ? 1 : 0; 69 | 70 | if (prime <= maxBound) 71 | { 72 | var q = n; 73 | while (q >= prime) 74 | { 75 | m += q /= prime; 76 | } 77 | } 78 | 79 | this.primeList[count] = prime; 80 | this.multiList[count++] = m; 81 | } 82 | return count; 83 | } 84 | } 85 | } // endOfFactorialPrimeSchoenhage 86 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialPrimeSwing.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using System.Linq; 11 | 12 | using Sharith.Primes; 13 | 14 | using XInt = Sharith.Arithmetic.XInt; 15 | using XMath = Sharith.MathUtils.XMath; 16 | 17 | public class PrimeSwing : IFactorialFunction 18 | { 19 | public string Name => "PrimeSwing "; 20 | 21 | private PrimeSieve sieve; 22 | private int[] primeList; 23 | 24 | public XInt Factorial(int n) 25 | { 26 | if (n < 20) { return XMath.Factorial(n); } 27 | 28 | this.sieve = new PrimeSieve(n); 29 | var pLen = (int)(2.0 * (XMath.FloorSqrt(n) 30 | + (double)n / (XMath.Log2(n) - 1))); 31 | this.primeList = new int[pLen]; 32 | 33 | var exp2 = n - XMath.BitCount(n); 34 | return this.RecFactorial(n) << exp2; 35 | } 36 | 37 | private XInt RecFactorial(int n) 38 | { 39 | if (n < 2) return XInt.One; 40 | 41 | return XInt.Pow(this.RecFactorial(n / 2), 2) * this.Swing(n); 42 | } 43 | 44 | private XInt Swing(int n) 45 | { 46 | if (n < 33) return SmallOddSwing[n]; 47 | 48 | int count = 0, rootN = XMath.FloorSqrt(n); 49 | 50 | var aPrimes = this.sieve.GetPrimeCollection(3, rootN); 51 | var bPrimes = this.sieve.GetPrimeCollection(rootN + 1, n / 3); 52 | 53 | foreach (var prime in aPrimes) 54 | { 55 | int q = n, p = 1; 56 | 57 | while ((q /= prime) > 0) 58 | { 59 | if ((q & 1) == 1) 60 | { 61 | p *= prime; 62 | } 63 | } 64 | 65 | if (p > 1) 66 | { 67 | this.primeList[count++] = p; 68 | } 69 | } 70 | 71 | foreach (var prime in bPrimes.Where(prime => ((n / prime) & 1) == 1)) 72 | { 73 | this.primeList[count++] = prime; 74 | } 75 | 76 | var primorial = this.sieve.GetPrimorial(n / 2 + 1, n); 77 | return primorial * XMath.Product(this.primeList, 0, count); 78 | } 79 | 80 | static readonly XInt[] SmallOddSwing = { 81 | 1,1,1,3,3,15,5,35,35,315,63,693,231,3003,429,6435,6435,109395, 82 | 12155,230945,46189,969969,88179,2028117,676039,16900975,1300075, 83 | 35102025,5014575,145422675,9694845,300540195,300540195 }; 84 | } 85 | } // endOfFactorialPrimeSwingLuschny 86 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialPrimeSwingList.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using Sharith.Primes; 11 | 12 | using XInt = Arithmetic.XInt; 13 | using XMath = MathUtils.XMath; 14 | 15 | public class PrimeSwingList : IFactorialFunction 16 | { 17 | public string Name => "PrimeSwingList "; 18 | 19 | private int[][] primeList; 20 | private int[] listLength; 21 | private int[] tower; 22 | private int[] bound; 23 | 24 | public XInt Factorial(int n) 25 | { 26 | if (n < 20) { return XMath.Factorial(n); } 27 | 28 | var log2N = XMath.FloorLog2(n); 29 | var j = log2N; 30 | var hN = n; 31 | 32 | this.primeList = new int[log2N][]; 33 | this.listLength = new int[log2N]; 34 | this.bound = new int[log2N]; 35 | this.tower = new int[log2N + 1]; 36 | 37 | while (true) 38 | { 39 | this.tower[j] = hN; 40 | if (hN == 1) break; 41 | this.bound[--j] = hN / 3; 42 | var pLen = hN < 4 ? 6 : (int)(2.0 * (XMath.FloorSqrt(hN) 43 | + (double) hN / (XMath.Log2(hN) - 1))); 44 | this.primeList[j] = new int[pLen]; 45 | hN >>= 1; 46 | } 47 | 48 | this.tower[0] = 2; 49 | this.PrimeFactors(n); 50 | 51 | var init = this.listLength[0] == 0 ? 1 : 3; 52 | var oddFactorial = new XInt(init); 53 | 54 | for (var i = 1; i < log2N; i++) 55 | { 56 | oddFactorial = XInt.Pow(oddFactorial, 2) 57 | * XMath.Product(this.primeList[i], 0, this.listLength[i]); 58 | } 59 | return oddFactorial << (n - XMath.BitCount(n)); 60 | } 61 | 62 | private void PrimeFactors(int n) 63 | { 64 | var maxBound = n / 3; 65 | var lastList = this.primeList.Length - 1; 66 | var start = this.tower[1] == 2 ? 1 : 0; 67 | var sieve = new PrimeSieve(n); 68 | 69 | for (var section = start; section < this.primeList.Length; section++) 70 | { 71 | var primes = sieve.GetPrimeCollection(this.tower[section] + 1, this.tower[section + 1]); 72 | 73 | foreach (var prime in primes) 74 | { 75 | this.primeList[section][this.listLength[section]++] = prime; 76 | if (prime > maxBound) continue; 77 | 78 | var np = n; 79 | do 80 | { 81 | var k = lastList; 82 | var q = np /= prime; 83 | 84 | do if ((q & 1) == 1) //if q is odd 85 | { 86 | this.primeList[k][this.listLength[k]++] = prime; 87 | } 88 | while (((q >>= 1) > 0) && (prime <= this.bound[--k])); 89 | 90 | } while (prime <= np); 91 | } 92 | } 93 | } 94 | } 95 | } // endOfFactorialPrimeSwingList 96 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialPrimeVardi.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using System.Linq; 11 | using Sharith.Primes; 12 | 13 | using XInt = Arithmetic.XInt; 14 | using XMath = MathUtils.XMath; 15 | 16 | public class PrimeVardi : IFactorialFunction 17 | { 18 | public string Name => "PrimeVardi "; 19 | 20 | private PrimeSieve sieve; 21 | 22 | public XInt Factorial(int n) 23 | { 24 | if (n < 20) { return XMath.Factorial(n); } 25 | 26 | this.sieve = new PrimeSieve(n); 27 | 28 | return this.RecFactorial(n); 29 | } 30 | 31 | private XInt RecFactorial(int n) 32 | { 33 | if (n < 2) return XInt.One; 34 | 35 | if ((n & 1) == 1) 36 | { 37 | return this.RecFactorial(n - 1) * n; 38 | } 39 | 40 | return this.MiddleBinomial(n) * XInt.Pow(this.RecFactorial(n / 2), 2); 41 | } 42 | 43 | private XInt MiddleBinomial(int n) // assuming n = 2k 44 | { 45 | if (n < 50) return new XInt(Binomial[n / 2]); 46 | 47 | int k = n / 2, pc = 0, pp = 0; 48 | var rootN = XMath.FloorSqrt(n); 49 | 50 | var bigPrimes = this.sieve.GetPrimorial(k + 1, n); 51 | var smallPrimes = this.sieve.GetPrimorial(k / 2 + 1, n / 3); 52 | 53 | var primes = this.sieve.GetPrimeCollection(rootN + 1, n / 5); 54 | var primeList = new int[primes.NumberOfPrimes]; 55 | 56 | foreach (var prime in primes.Where(prime => (n / prime & 1) == 1)) 57 | { 58 | primeList[pc++] = prime; 59 | } 60 | var prodPrimes = XMath.Product(primeList, 0, pc); 61 | 62 | primes = this.sieve.GetPrimeCollection(1, rootN); 63 | var primePowers = new XInt[primes.NumberOfPrimes]; 64 | 65 | var exp = 0; 66 | foreach (var prime in primes.Where(prime => (exp = ExpSum(prime, n)) > 0)) 67 | { 68 | primePowers[pp++] = XInt.Pow(prime, exp); 69 | } 70 | 71 | var powerPrimes = XMath.Product(primePowers, 0, pp); 72 | 73 | return bigPrimes * smallPrimes * prodPrimes * powerPrimes; 74 | } 75 | 76 | private static int ExpSum(int p, int n) 77 | { 78 | int exp = 0, q = n / p; 79 | 80 | while (0 < q) 81 | { 82 | exp += q & 1; 83 | q /= p; 84 | } 85 | 86 | return exp; 87 | } 88 | 89 | static readonly long[] Binomial = { 90 | 1,2,6,20,70,252,924,3432,12870,48620,184756,705432,2704156, 91 | 10400600,40116600,155117520,601080390,2333606220L,9075135300L, 92 | 35345263800L,137846528820L,538257874440L,2104098963720L, 93 | 8233430727600L,32247603683100L }; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialProductNaive.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using XInt = Arithmetic.XInt; 11 | 12 | public class ProductNaive : IFactorialFunction 13 | { 14 | public string Name => "ProductNaive "; 15 | 16 | public XInt Factorial(int n) 17 | { 18 | if (n < 0) 19 | { 20 | throw new System.ArgumentOutOfRangeException( 21 | this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); 22 | } 23 | 24 | var nFact = XInt.One; 25 | 26 | for (var i = 2; i <= n; i++) 27 | { 28 | nFact *= i; 29 | } 30 | return nFact; 31 | } 32 | } 33 | } // endOfProductNaive 34 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialProductRecursive.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using XInt = Arithmetic.XInt; 11 | 12 | public class ProductRecursive : IFactorialFunction 13 | { 14 | public string Name => "ProductRecursive "; 15 | 16 | public XInt Factorial(int n) 17 | { 18 | if (n < 0) 19 | { 20 | throw new System.ArgumentOutOfRangeException( 21 | this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); 22 | } 23 | 24 | if (1 < n) 25 | { 26 | return this.RecProduct(1, n); 27 | } 28 | 29 | return XInt.One; 30 | } 31 | 32 | private XInt RecProduct(int n, int len) 33 | { 34 | if (1 < len) 35 | { 36 | var l = len >> 1; 37 | return this.RecProduct(n, l) * this.RecProduct(n + l, len - l); 38 | } 39 | 40 | return new XInt(n); 41 | } 42 | } 43 | } // endOfFactorialProductRecursive 44 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialSplit.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using XInt = Arithmetic.XInt; 11 | using XMath = MathUtils.XMath; 12 | 13 | public class Split : IFactorialFunction 14 | { 15 | public string Name => "Split "; 16 | 17 | XInt currentN; 18 | 19 | public XInt Factorial(int n) 20 | { 21 | if (n < 0) 22 | { 23 | throw new System.ArgumentOutOfRangeException( 24 | this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); 25 | } 26 | 27 | if (n < 2) return XInt.One; 28 | 29 | var p = XInt.One; 30 | var r = XInt.One; 31 | this.currentN = XInt.One; 32 | 33 | int h = 0, shift = 0, high = 1; 34 | var log2N = XMath.FloorLog2(n); 35 | 36 | while (h != n) 37 | { 38 | shift += h; 39 | h = n >> log2N--; 40 | var len = high; 41 | high = (h - 1) | 1; 42 | len = (high - len) / 2; 43 | 44 | if (len > 0) 45 | { 46 | p *= this.Product(len); 47 | r *= p; 48 | } 49 | } 50 | 51 | return r << shift; 52 | } 53 | 54 | private XInt Product(int n) 55 | { 56 | var m = n / 2; 57 | if (m == 0) return this.currentN += 2; 58 | if (n == 2) return (this.currentN += 2) * (this.currentN += 2); 59 | return this.Product(n - m) * this.Product(m); 60 | } 61 | } 62 | } // endOfFactorialBinSplit 63 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialSquaredDiffProd.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using XInt = Arithmetic.XInt; 11 | using XMath = MathUtils.XMath; 12 | 13 | public class SquaredDiffProd : IFactorialFunction 14 | { 15 | public string Name => "SquaredDiffProduct "; 16 | 17 | public XInt Factorial(int n) 18 | { 19 | if (n < 0) 20 | { 21 | throw new System.ArgumentOutOfRangeException( 22 | this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); 23 | } 24 | 25 | if (n < 7) 26 | { 27 | return (XInt)(new[] { 1, 1, 2, 6, 24, 120, 720 })[n]; 28 | } 29 | 30 | long h = n / 2; 31 | var q = h * h; 32 | var f = new long[(int)h]; 33 | f[0] = (n & 1) == 1 ? 2 * q * n : 2 * q; 34 | var i = 1; 35 | 36 | for (var d = 1; d < n - 2; d += 2) 37 | { 38 | f[i++] = q -= d; 39 | } 40 | 41 | return XMath.Product(f, f.Length); 42 | } 43 | } 44 | } // endOfFactorialSquaredDiffProd 45 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialSquaredDifference.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using XInt = Arithmetic.XInt; 11 | 12 | public class SquaredDifference : IFactorialFunction 13 | { 14 | public string Name => "SquaredDifference "; 15 | 16 | public XInt Factorial(int n) 17 | { 18 | if (n < 0) 19 | { 20 | throw new System.ArgumentOutOfRangeException( 21 | this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); 22 | } 23 | 24 | if (n < 2) 25 | { 26 | return XInt.One; 27 | } 28 | 29 | long h = n / 2; 30 | var q = h * h; 31 | var r = (n & 1) == 1 ? 2 * q * n : 2 * q; 32 | var f = new XInt(r); 33 | 34 | for (var d = 1; d < n - 2; d += 2) 35 | { 36 | f *= q -= d; 37 | } 38 | 39 | return f; 40 | } 41 | } 42 | } // endOfFactorialSquaredDifference 43 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialSwing.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using System; 11 | 12 | using XInt = Sharith.Arithmetic.XInt; 13 | using XMath = Sharith.MathUtils.XMath; 14 | 15 | public class Swing : IFactorialFunction 16 | { 17 | public string Name => "Swing "; 18 | 19 | private XInt oddFactNdiv4, oddFactNdiv2; 20 | private const int Smallswing = 33; 21 | private const int Smallfact = 17; 22 | 23 | public XInt Factorial(int n) 24 | { 25 | if (n < 0) 26 | { 27 | throw new ArithmeticException( 28 | this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); 29 | } 30 | 31 | this.oddFactNdiv4 = this.oddFactNdiv2 = XInt.One; 32 | 33 | return this.OddFactorial(n) << (n - XMath.BitCount(n)); 34 | } 35 | 36 | private XInt OddFactorial(int n) 37 | { 38 | XInt oddFact; 39 | 40 | if (n < Smallfact) 41 | { 42 | oddFact = SmallOddFactorial[n]; 43 | } 44 | else 45 | { 46 | var sqrOddFact = this.OddFactorial(n / 2); 47 | var ndiv4 = n / 4; 48 | var oddFactNd4 = ndiv4 < Smallfact 49 | ? SmallOddFactorial[ndiv4] 50 | : this.oddFactNdiv4; 51 | 52 | oddFact = XInt.Pow(sqrOddFact, 2) * OddSwing(n, oddFactNd4); 53 | } 54 | 55 | this.oddFactNdiv4 = this.oddFactNdiv2; 56 | this.oddFactNdiv2 = oddFact; 57 | return oddFact; 58 | } 59 | 60 | static XInt OddSwing(int n, XInt oddFactNdiv4) 61 | { 62 | if (n < Smallswing) return SmallOddSwing[n]; 63 | 64 | var len = (n - 1) / 4; 65 | if ((n % 4) != 2) len++; 66 | var high = n - ((n + 1) & 1); 67 | 68 | return Product(high, len) / oddFactNdiv4; 69 | } 70 | 71 | static XInt Product(int m, int len) 72 | { 73 | if (len == 1) return new XInt(m); 74 | if (len == 2) return new XInt((long)m * (m - 2)); 75 | 76 | var hlen = len >> 1; 77 | return Product(m - hlen * 2, len - hlen) * Product(m, hlen); 78 | } 79 | 80 | static readonly XInt[] SmallOddSwing = { 81 | 1,1,1,3,3,15,5,35,35,315,63,693,231,3003,429,6435,6435,109395, 82 | 12155,230945,46189,969969,88179,2028117,676039,16900975,1300075, 83 | 35102025,5014575,145422675,9694845,300540195,300540195 }; 84 | 85 | static readonly XInt[] SmallOddFactorial = { 86 | 1,1,1,3,3,15,45,315,315,2835,14175,155925,467775,6081075, 87 | 42567525,638512875,638512875 }; 88 | 89 | } // endOfFactorialSwing 90 | } 91 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialSwingDouble.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using XInt = Arithmetic.XInt; 11 | 12 | public class SwingDouble : IFactorialFunction 13 | { 14 | public string Name => "SwingDouble "; 15 | 16 | XInt f; 17 | long gN; 18 | 19 | public XInt Factorial(int n) 20 | { 21 | if (n < 0) 22 | { 23 | throw new System.ArgumentOutOfRangeException( 24 | this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); 25 | } 26 | 27 | this.gN = 1; 28 | this.f = XInt.One; 29 | return this.RecFactorial(n); 30 | } 31 | 32 | private XInt RecFactorial(int n) 33 | { 34 | if (n < 2) return XInt.One; 35 | 36 | return XInt.Pow(this.RecFactorial(n / 2),2) * this.Swing(n); 37 | } 38 | 39 | private XInt Swing(long n) 40 | { 41 | var s = this.gN - 1 + ((n - this.gN + 1) % 4); 42 | bool oddN = (this.gN & 1) != 1; 43 | 44 | for (; this.gN <= s; this.gN++) 45 | { 46 | if (oddN = !oddN) this.f *= this.gN; 47 | else this.f = (this.f * 4) / this.gN; 48 | } 49 | 50 | if (oddN) for (; this.gN <= n; this.gN += 4) 51 | { 52 | var m = ((this.gN + 1) * (this.gN + 3)) << 1; 53 | var d = (this.gN * (this.gN + 2)) >> 3; 54 | 55 | this.f = (this.f * m) / d; 56 | } 57 | else for (; this.gN <= n; this.gN += 4) 58 | { 59 | var m = (this.gN * (this.gN + 2)) << 1; 60 | var d = ((this.gN + 1) * (this.gN + 3)) >> 3; 61 | 62 | this.f = (this.f * m) / d; 63 | } 64 | 65 | return this.f; 66 | } 67 | } 68 | } // endOfSwingDouble 69 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/FactorialSwingSimple.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using XInt = Arithmetic.XInt; 11 | 12 | public class SwingSimple : IFactorialFunction 13 | { 14 | 15 | public string Name => "SwingSimple "; 16 | 17 | public XInt Factorial(int n) 18 | { 19 | if (n < 0) 20 | { 21 | throw new System.ArgumentOutOfRangeException( 22 | this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); 23 | } 24 | 25 | return this.RecFactorial(n); 26 | } 27 | 28 | private XInt RecFactorial(int n) 29 | { 30 | if (n < 2) return XInt.One; 31 | 32 | return XInt.Pow(this.RecFactorial(n / 2), 2) * Swing(n); 33 | } 34 | 35 | private static XInt Swing(int n) 36 | { 37 | int z; 38 | 39 | switch (n % 4) 40 | { 41 | case 1: z = n / 2 + 1; break; 42 | case 2: z = 2; break; 43 | case 3: z = 2 * (n / 2 + 2); break; 44 | default: z = 1; break; 45 | } 46 | 47 | var b = new XInt(z); 48 | z = 2 * (n - ((n + 1) & 1)); 49 | 50 | for (var i = 1; i <= n / 4; i++, z -= 4) 51 | { 52 | b = (b * z) / i; 53 | } 54 | 55 | return b; 56 | } 57 | } 58 | } // endOfFactorialSwingSimple 59 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Factorial/IFactorialFunction.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Factorial 9 | { 10 | using System.Diagnostics.CodeAnalysis; 11 | 12 | using XInt = Arithmetic.XInt; 13 | 14 | ///

An interface for the factorial function 15 | /// n! = 1*2*3*...*n 16 | /// for nonnegative integer values n. 17 | /// 18 | public interface IFactorialFunction 19 | { 20 | string Name { get; } 21 | 22 | XInt Factorial(int n); 23 | } 24 | } // endOfIFactorialFunction 25 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Primes/IPrimeCollection.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Primes 9 | { 10 | using System.Collections.Generic; 11 | 12 | using Sharith.MathUtils; 13 | 14 | /// 15 | /// An interface for enumerating a prime number sieve. 16 | /// 17 | /// An IPrimeCollection is both IEnumerable<int> 18 | /// and IDisposable as well as an IEnumerator<int>. 19 | ///
20 |      ///
21 |      /// To understand the difference between "SieveRange" and "PrimeRange"
22 |      /// better, let us consider the following example:
23 |      ///
24 |      /// If the SieveRange is 10..20, then the PrimeRange is 5..8,
25 |      /// because of the following table
26 |      ///
27 |      ///                    <-     SieveRange           ->
28 |      /// 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
29 |      /// x,1,2,x,3,x,4,x,x, x, 5, x, 6, x, x, x, 7, x, 8, x, x, x, 9
30 |      ///                    <-     PrimeRange           ->
31 |      ///
32 |      /// Thus the smallest prime in the SieveRange is the 5-th prime and
33 |      /// the largest prime in this SieveRange is the 8-th prime.
34 |      ///
35 |      /// 
36 | /// 37 | /// version cs-2004-09-03 38 | /// author Peter Luschny 39 | /// 40 | ///
41 | public interface IPrimeCollection : IEnumerator, IEnumerable 42 | { 43 | /// 44 | /// Gets the number of primes in the enumeration. 45 | /// 46 | int NumberOfPrimes { get; } 47 | 48 | /// 49 | /// Gets the intervall proceeded by the sieve. 50 | /// 51 | PositiveRange SieveRange { get; } 52 | 53 | /// 54 | /// Gets the SieveRange of the indices of the prime numbers in the enumeration. 55 | /// 56 | PositiveRange PrimeRange { get; } 57 | 58 | /// 59 | /// Returns the primes in the SieveRange under consideration 60 | /// as an array. 61 | /// 62 | /// An array of the primes in the SieveRange. 63 | int[] ToArray(); 64 | 65 | /// 66 | /// Writes the prime number enumeration (somewhat formatted) 67 | /// to a file. 68 | /// 69 | /// The name of the file where the 70 | /// enumeration is to be stored. 71 | /// Full path of the file written to. 72 | string ToFile(string fileName); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Primes/IPrimeSieve.cs: -------------------------------------------------------------------------------- 1 | // -------- ToujoursEnBeta 2 | // Author & Copyright : Peter Luschny 3 | // License: LGPL version 3.0 or (at your option) 4 | // Creative Commons Attribution-ShareAlike 3.0 5 | // Comments mail to: peter(at)luschny.de 6 | // Created: 2010-03-01 7 | 8 | namespace Sharith.Primes 9 | { 10 | using Sharith.MathUtils; 11 | 12 | /// 13 | /// The interface for a prime number sieve. 14 | /// Much of its functionality is given through PrimeCollections. 15 | /// 16 | /// @version cs-2004-09-02 17 | /// @author Peter Luschny 18 | /// 19 | public interface IPrimeSieve 20 | { 21 | /// 22 | /// Checks if a given number is prime. 23 | /// 24 | /// The number the primality of which is 25 | /// to be checked. 26 | /// True iff the given number is prime. 27 | bool IsPrime(int cand); 28 | 29 | /// 30 | /// Gets the n-th prime number. 31 | /// 32 | /// The index of the prime number. 33 | /// The n-th prime number. 34 | int GetNthPrime(int n); 35 | 36 | /// 37 | /// Returns the default PrimeCollection of the full sieve. 38 | /// In other words: This PrimeCollection includes all 39 | /// prime numbers p, such that 1 <= p <= high, where 40 | /// high is the upper bound of the under laying sieve. 41 | /// 42 | /// The enumeration of the sieve. 43 | IPrimeCollection GetPrimeCollection(); 44 | 45 | /// 46 | /// Gives the PrimeCollection of a subrange of the sieve. 47 | /// It is the collection of all prime numbers p, 48 | /// such that low <= p <= high. 49 | /// Note: If the range [low, high] is not included in the range 50 | /// of the sieve, this function might throw an ArgumentOutOfRangeException. 51 | /// 52 | /// The low limit of the enumeration interval. 53 | /// The high limit of the enumeration interval. 54 | /// The enumeration of the prime numbers between 55 | /// low and high. 56 | IPrimeCollection GetPrimeCollection(int low, int high); 57 | 58 | /// 59 | /// Gives the PrimeCollection of a subrange of the sieve. 60 | /// It is the collection of all prime numbers p, 61 | /// such that 0 < range.low <= p <= range.high. 62 | /// Note: If the range is not included in the range of the sieve, 63 | /// this function might throw an ArgumentOutOfRangeException. 64 | /// 65 | /// The range of the enumeration. 66 | /// The enumeration of the prime numbers in 67 | /// the given range. 68 | IPrimeCollection GetPrimeCollection(PositiveRange range); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /SilverFactorial64/Sharith/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Sharith")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("Sharith")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("9971a683-3a1b-43c8-a205-895b9a0d9ec0")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SilverFactorial64/SilverFactorial/Application.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SilverFactorial64/SilverFactorial/Benchmark/TestParameters.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace SilverFactorial.Benchmark 3 | { 4 | internal class TestParameters 5 | { 6 | public const int TestMax = int.MaxValue; 7 | 8 | public int TestLength; 9 | public int TestStart; 10 | public int StepFactor; 11 | public static int[] TestValues; 12 | public static int CardSelected; 13 | public bool[] AlgoSelected; 14 | public bool ShowFullValue; 15 | public bool Verbose; 16 | public bool SanityTest; 17 | public double WorkLoad; 18 | 19 | public TestParameters(int noOfCandidates) 20 | { 21 | this.AlgoSelected = new bool[noOfCandidates]; 22 | } 23 | 24 | public void Init() 25 | { 26 | TestValues = new int[this.TestLength]; 27 | double sum = 0; 28 | long value = this.TestStart; 29 | 30 | for (int m = 0; m < this.TestLength; m++) 31 | { 32 | if (value < TestMax) 33 | { 34 | TestValues[m] = (int)value; 35 | sum += value; 36 | } 37 | else 38 | { 39 | TestValues[m] = 1; 40 | } 41 | value = (long)((this.StepFactor * value) / 10.0); 42 | } 43 | 44 | CardSelected = 0; this.WorkLoad = 0; 45 | 46 | foreach (Candidate cand in Candidate.Selected) 47 | { 48 | CardSelected++; 49 | this.WorkLoad += cand.WorkLoad * sum; 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /SilverFactorial64/SilverFactorial/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("SilverFactorial")] 11 | [assembly: AssemblyDescription("Benchmark Factorial Functions")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("Peter Luschny")] 14 | [assembly: AssemblyProduct("SilverFactorial")] 15 | [assembly: AssemblyCopyright("Copyright © 2011")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(false)] 23 | 24 | //In order to begin building localizable applications, set 25 | //CultureYouAreCodingWith in your .csproj file 26 | //inside a . For example, if you are using US english 27 | //in your source files, set the to en-US. Then uncomment 28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 29 | //the line below to match the UICulture setting in the project file. 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 36 | //(used if a resource is not found in the page, 37 | // or application resource dictionaries) 38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 39 | //(used if a resource is not found in the page, 40 | // app, or any theme specific resource dictionaries) 41 | )] 42 | 43 | 44 | // Version information for an assembly consists of the following four values: 45 | // 46 | // Major Version 47 | // Minor Version 48 | // Build Number 49 | // Revision 50 | // 51 | // You can specify all the values or you can default the Build and Revision Numbers 52 | // by using the '*' as shown below: 53 | // [assembly: AssemblyVersion("1.0.*")] 54 | [assembly: AssemblyVersion("2.0.0.0")] 55 | [assembly: AssemblyFileVersion("1.1.0.0")] 56 | [assembly: NeutralResourcesLanguageAttribute("en-US")] 57 | -------------------------------------------------------------------------------- /SilverFactorial64/SilverFactorial/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18034 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace SilverFactorial.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SilverFactorial.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /SilverFactorial64/SilverFactorial/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18034 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace SilverFactorial.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SilverFactorial64/SilverFactorial/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /SilverFactorial64/SilverFactorial/Properties/app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /SilverFactorial64/SilverFactorial/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /SilverFactorial64/SilverFactorial/bin/x64/Release/Sharith.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterLuschny/Fast-Factorial-Functions/9ab709a1ade401cdacce909cc976cebf9a8830ed/SilverFactorial64/SilverFactorial/bin/x64/Release/Sharith.dll -------------------------------------------------------------------------------- /SilverFactorial64/SilverFactorial/bin/x64/Release/SilverFactorial.application: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | JpAQmphhdv6beBAqp5mORR4pJh08ND/IE3HR0VxWBb4= 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /SilverFactorial64/SilverFactorial/bin/x64/Release/SilverFactorial.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterLuschny/Fast-Factorial-Functions/9ab709a1ade401cdacce909cc976cebf9a8830ed/SilverFactorial64/SilverFactorial/bin/x64/Release/SilverFactorial.exe -------------------------------------------------------------------------------- /SilverFactorial64/SilverFactorial/bin/x64/Release/SilverFactorial.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /SilverFactorial64/SilverFactorial/bin/x64/Release/mpir.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterLuschny/Fast-Factorial-Functions/9ab709a1ade401cdacce909cc976cebf9a8830ed/SilverFactorial64/SilverFactorial/bin/x64/Release/mpir.dll -------------------------------------------------------------------------------- /SilverFactorial64/SilverFactorial/mpir.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterLuschny/Fast-Factorial-Functions/9ab709a1ade401cdacce909cc976cebf9a8830ed/SilverFactorial64/SilverFactorial/mpir.dll -------------------------------------------------------------------------------- /SilverFactorial64/SilverFactorial/silverfactorial.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PeterLuschny/Fast-Factorial-Functions/9ab709a1ade401cdacce909cc976cebf9a8830ed/SilverFactorial64/SilverFactorial/silverfactorial.ico -------------------------------------------------------------------------------- /SilverFactorial64/SilverFactorial64.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Express 2012 for Windows Desktop 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SilverFactorial", "SilverFactorial\SilverFactorial.csproj", "{D2D1FC52-A876-4076-AD23-1569A5705038}" 5 | ProjectSection(ProjectDependencies) = postProject 6 | {1BEB9265-1E27-4279-9062-DD518F1BC9AB} = {1BEB9265-1E27-4279-9062-DD518F1BC9AB} 7 | EndProjectSection 8 | EndProject 9 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sharith", "Sharith\Sharith.csproj", "{1BEB9265-1E27-4279-9062-DD518F1BC9AB}" 10 | EndProject 11 | Global 12 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 13 | Debug|Any CPU = Debug|Any CPU 14 | Debug|Mixed Platforms = Debug|Mixed Platforms 15 | Debug|x64 = Debug|x64 16 | Debug|x86 = Debug|x86 17 | Release|Any CPU = Release|Any CPU 18 | Release|Mixed Platforms = Release|Mixed Platforms 19 | Release|x64 = Release|x64 20 | Release|x86 = Release|x86 21 | EndGlobalSection 22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 23 | {D2D1FC52-A876-4076-AD23-1569A5705038}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 24 | {D2D1FC52-A876-4076-AD23-1569A5705038}.Debug|Any CPU.Build.0 = Debug|Any CPU 25 | {D2D1FC52-A876-4076-AD23-1569A5705038}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 26 | {D2D1FC52-A876-4076-AD23-1569A5705038}.Debug|Mixed Platforms.Build.0 = Debug|x86 27 | {D2D1FC52-A876-4076-AD23-1569A5705038}.Debug|x64.ActiveCfg = Debug|x64 28 | {D2D1FC52-A876-4076-AD23-1569A5705038}.Debug|x64.Build.0 = Debug|x64 29 | {D2D1FC52-A876-4076-AD23-1569A5705038}.Debug|x86.ActiveCfg = Debug|x64 30 | {D2D1FC52-A876-4076-AD23-1569A5705038}.Debug|x86.Build.0 = Debug|x64 31 | {D2D1FC52-A876-4076-AD23-1569A5705038}.Release|Any CPU.ActiveCfg = Release|x64 32 | {D2D1FC52-A876-4076-AD23-1569A5705038}.Release|Any CPU.Build.0 = Release|x64 33 | {D2D1FC52-A876-4076-AD23-1569A5705038}.Release|Mixed Platforms.ActiveCfg = Release|x86 34 | {D2D1FC52-A876-4076-AD23-1569A5705038}.Release|Mixed Platforms.Build.0 = Release|x86 35 | {D2D1FC52-A876-4076-AD23-1569A5705038}.Release|x64.ActiveCfg = Release|x64 36 | {D2D1FC52-A876-4076-AD23-1569A5705038}.Release|x64.Build.0 = Release|x64 37 | {D2D1FC52-A876-4076-AD23-1569A5705038}.Release|x86.ActiveCfg = Release|x64 38 | {D2D1FC52-A876-4076-AD23-1569A5705038}.Release|x86.Build.0 = Release|x64 39 | {1BEB9265-1E27-4279-9062-DD518F1BC9AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 40 | {1BEB9265-1E27-4279-9062-DD518F1BC9AB}.Debug|Any CPU.Build.0 = Debug|Any CPU 41 | {1BEB9265-1E27-4279-9062-DD518F1BC9AB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 42 | {1BEB9265-1E27-4279-9062-DD518F1BC9AB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 43 | {1BEB9265-1E27-4279-9062-DD518F1BC9AB}.Debug|x64.ActiveCfg = Debug|x64 44 | {1BEB9265-1E27-4279-9062-DD518F1BC9AB}.Debug|x64.Build.0 = Debug|x64 45 | {1BEB9265-1E27-4279-9062-DD518F1BC9AB}.Debug|x86.ActiveCfg = Debug|x64 46 | {1BEB9265-1E27-4279-9062-DD518F1BC9AB}.Release|Any CPU.ActiveCfg = Release|x64 47 | {1BEB9265-1E27-4279-9062-DD518F1BC9AB}.Release|Any CPU.Build.0 = Release|x64 48 | {1BEB9265-1E27-4279-9062-DD518F1BC9AB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 49 | {1BEB9265-1E27-4279-9062-DD518F1BC9AB}.Release|Mixed Platforms.Build.0 = Release|Any CPU 50 | {1BEB9265-1E27-4279-9062-DD518F1BC9AB}.Release|x64.ActiveCfg = Release|x64 51 | {1BEB9265-1E27-4279-9062-DD518F1BC9AB}.Release|x64.Build.0 = Release|x64 52 | {1BEB9265-1E27-4279-9062-DD518F1BC9AB}.Release|x86.ActiveCfg = Release|x64 53 | {1BEB9265-1E27-4279-9062-DD518F1BC9AB}.Release|x86.Build.0 = Release|x64 54 | EndGlobalSection 55 | GlobalSection(SolutionProperties) = preSolution 56 | HideSolutionNode = FALSE 57 | EndGlobalSection 58 | EndGlobal 59 | --------------------------------------------------------------------------------