comparison scripts/specfun/factor.m @ 31112:bbb59cc6698c stable

factor.m: Performance tweak to avoid division in certain cases factor.m: For large numbers where only one factor lies outside the fast first round of divisions, check if it is prime before calling primes () trying to factorize it. This is up to 8000X faster for such numbers, and for an "average" input it gives a 22% to 40% speedup over a large number of trials.
author Arun Giridhar <arungiridhar@gmail.com>
date Sat, 25 Jun 2022 16:40:36 -0400
parents 796f54d4ddbf
children
comparison
equal deleted inserted replaced
31108:7797481038fc 31112:bbb59cc6698c
148 ## repetitions, in ascending order. 148 ## repetitions, in ascending order.
149 ## 149 ##
150 ## q itself will be divided by those prime factors to become smaller, 150 ## q itself will be divided by those prime factors to become smaller,
151 ## unless q was prime to begin with. 151 ## unless q was prime to begin with.
152 152
153 ## Now go all the way to sqrt(q), where q is smaller than the original q in 153 if (isprime (q))
154 ## most cases. 154 ## This is an optimization for numbers like 18446744073709551566
155 ## 155 ## == 2 * 9223372036854775783, where the small factors can be pulled
156 ## Note: Do not try to weed out the smallprimes inside largeprimes, whether 156 ## out easily and the remaining is prime. This optimization reduces
157 ## using length(smallprimes) or max(smallprimes) -- it slows it down! 157 ## 14.3 s to 1.8 ms (8000X faster) for such cases.
158 largeprimes = primes (sqrt (q));
159 [pf, q] = reducefactors (q, pf, largeprimes);
160
161 ## At this point, all prime factors <= the sqrt of the original q have been
162 ## pulled out in ascending order.
163 ##
164 ## If q = 1, then no further primes are left.
165 ## If q > 1, then q itself must be prime, and it must be the single prime
166 ## factor that was larger than the sqrt of the original q.
167 if (q > 1)
168 pf(end+1) = q; 158 pf(end+1) = q;
169 endif 159 else
160 ## Now go all the way to sqrt(q), where q is smaller than the original q in
161 ## most cases.
162 ##
163 ## Note: Do not try to weed out the smallprimes inside largeprimes, whether
164 ## using length(smallprimes) or max(smallprimes) -- it slows it down!
165 largeprimes = primes (sqrt (q));
166 [pf, q] = reducefactors (q, pf, largeprimes);
167
168 ## At this point, all prime factors <= the sqrt of the original q have been
169 ## pulled out in ascending order.
170 ##
171 ## If q = 1, then no further primes are left.
172 ## If q > 1, then q itself must be prime, and it must be the single prime
173 ## factor that was larger than the sqrt of the original q.
174 if (q > 1)
175 pf(end+1) = q;
176 endif
177 end
170 178
171 ## At this point, all prime factors have been pulled out of q in ascending 179 ## At this point, all prime factors have been pulled out of q in ascending
172 ## order. There is no need to sort(pf). 180 ## order. There is no need to sort(pf).
173 181
174 ## Determine multiplicity. 182 ## Determine multiplicity.