├── .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 |
--------------------------------------------------------------------------------