Mercurial > octave
annotate scripts/specfun/factor.m @ 30379:363fb10055df stable
maint: Style check m-files ahead of 7.1 release.
* Map.m, integral3.m, logspace.m, quad2d.m, quadgk.m, quadl.m, tsearchn.m,
get_first_help_sentence.m, print_usage.m, getframe.m, imformats.m,
javaclasspath.m, condest.m, null.m, ordeig.m, inputParser.m, license.m,
memory.m, methods.m, __publish_html_output__.m, __publish_latex_output__.m,
publish.m, ode15s.m, fminbnd.m, fzero.m, configure_make.m, get_description.m,
get_forge_pkg.m, annotation.m, camlookat.m, legend.m, __gnuplot_legend__.m,
bar.m, colorbar.m, fill3.m, isosurface.m, plotyy.m, polar.m, __bar__.m,
__ezplot__.m, __patch__.m, __pie__.m, __plt__.m, __scatter__.m, smooth3.m,
stemleaf.m, __gnuplot_drawnow__.m, print.m, printd.m, __add_default_menu__.m,
__gnuplot_draw_axes__.m, __gnuplot_print__.m, __print_parse_opts__.m,
struct2hdl.m, profexport.m, profile.m, movfun.m, sprandsym.m, betaincinv.m,
factor.m, nchoosek.m, gallery.m, hadamard.m, iqr.m, ranks.m,
__run_test_suite__.m, test.m, datevec.m, weboptions.m:
Style check m-files ahead of 7.1 release.
author | Rik <rik@octave.org> |
---|---|
date | Fri, 26 Nov 2021 20:53:22 -0800 |
parents | 01de0045b2e3 |
children | 796f54d4ddbf |
rev | line source |
---|---|
27923
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
1 ######################################################################## |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
2 ## |
29358
0a5b15007766
update Octave Project Developers copyright for the new year
John W. Eaton <jwe@octave.org>
parents:
27978
diff
changeset
|
3 ## Copyright (C) 2000-2021 The Octave Project Developers |
27918
b442ec6dda5c
use centralized file for copyright info for individual contributors
John W. Eaton <jwe@octave.org>
parents:
26376
diff
changeset
|
4 ## |
27923
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
5 ## See the file COPYRIGHT.md in the top-level directory of this |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
6 ## distribution or <https://octave.org/copyright/>. |
5827 | 7 ## |
8 ## This file is part of Octave. | |
9 ## | |
24534
194eb4bd202b
maint: Update punctuation for GPL v3 license text.
Rik <rik@octave.org>
parents:
23220
diff
changeset
|
10 ## Octave is free software: you can redistribute it and/or modify it |
5827 | 11 ## under the terms of the GNU General Public License as published by |
24534
194eb4bd202b
maint: Update punctuation for GPL v3 license text.
Rik <rik@octave.org>
parents:
23220
diff
changeset
|
12 ## the Free Software Foundation, either version 3 of the License, or |
22755
3a2b891d0b33
maint: Standardize Copyright formatting.
Rik <rik@octave.org>
parents:
22323
diff
changeset
|
13 ## (at your option) any later version. |
5827 | 14 ## |
15 ## Octave is distributed in the hope that it will be useful, but | |
16 ## WITHOUT ANY WARRANTY; without even the implied warranty of | |
22755
3a2b891d0b33
maint: Standardize Copyright formatting.
Rik <rik@octave.org>
parents:
22323
diff
changeset
|
17 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3a2b891d0b33
maint: Standardize Copyright formatting.
Rik <rik@octave.org>
parents:
22323
diff
changeset
|
18 ## GNU General Public License for more details. |
5827 | 19 ## |
20 ## You should have received a copy of the GNU General Public License | |
7016 | 21 ## along with Octave; see the file COPYING. If not, see |
24534
194eb4bd202b
maint: Update punctuation for GPL v3 license text.
Rik <rik@octave.org>
parents:
23220
diff
changeset
|
22 ## <https://www.gnu.org/licenses/>. |
27923
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
23 ## |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
24 ######################################################################## |
5827 | 25 |
26 ## -*- texinfo -*- | |
20852
516bb87ea72e
2015 Code Sprint: remove class of function from docstring for all m-files.
Rik <rik@octave.org>
parents:
20486
diff
changeset
|
27 ## @deftypefn {} {@var{pf} =} factor (@var{q}) |
516bb87ea72e
2015 Code Sprint: remove class of function from docstring for all m-files.
Rik <rik@octave.org>
parents:
20486
diff
changeset
|
28 ## @deftypefnx {} {[@var{pf}, @var{n}] =} factor (@var{q}) |
19097 | 29 ## Return the prime factorization of @var{q}. |
5827 | 30 ## |
19097 | 31 ## The prime factorization is defined as @code{prod (@var{pf}) == @var{q}} |
32 ## where every element of @var{pf} is a prime number. If @code{@var{q} == 1}, | |
25270
617fe022e965
factor.m: Return output factors of same class as input for Matlab compatibility.
Rik <rik@octave.org>
parents:
25269
diff
changeset
|
33 ## return 1. The output @var{pf} is of the same numeric class as the input. |
19593
446c46af4b42
strip trailing whitespace from most source files
John W. Eaton <jwe@octave.org>
parents:
17744
diff
changeset
|
34 ## |
19097 | 35 ## With two output arguments, return the unique prime factors @var{pf} and |
21546
f7f97d7e9294
doc: Wrap m-file docstrings to 79 characters + newline (80 total).
Rik <rik@octave.org>
parents:
20852
diff
changeset
|
36 ## their multiplicities. That is, |
f7f97d7e9294
doc: Wrap m-file docstrings to 79 characters + newline (80 total).
Rik <rik@octave.org>
parents:
20852
diff
changeset
|
37 ## @code{prod (@var{pf} .^ @var{n}) == @var{q}}. |
19596
0e1f5a750d00
maint: Periodic merge of gui-release to default.
John W. Eaton <jwe@octave.org>
diff
changeset
|
38 ## |
25270
617fe022e965
factor.m: Return output factors of same class as input for Matlab compatibility.
Rik <rik@octave.org>
parents:
25269
diff
changeset
|
39 ## Implementation Note: The input @var{q} must be less than @code{flintmax} |
30228
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
40 ## when the input is a floating-point class (double or single). |
19097 | 41 ## @seealso{gcd, lcm, isprime, primes} |
5827 | 42 ## @end deftypefn |
43 | |
19097 | 44 function [pf, n] = factor (q) |
5827 | 45 |
28891
de5f2f9a64ff
maint: Use same coding style when checking for a minimum of 1 input.
Rik <rik@octave.org>
parents:
27978
diff
changeset
|
46 if (nargin < 1) |
5827 | 47 print_usage (); |
48 endif | |
49 | |
25269
cac96fd5310d
factor.m: Emit an error if input is negative (bug #53425).
Dildar Sk <dildarsk101010@gmail.com>
parents:
25054
diff
changeset
|
50 if (! isscalar (q) || ! isreal (q) || q < 0 || q != fix (q)) |
cac96fd5310d
factor.m: Emit an error if input is negative (bug #53425).
Dildar Sk <dildarsk101010@gmail.com>
parents:
25054
diff
changeset
|
51 error ("factor: Q must be a real non-negative integer"); |
5827 | 52 endif |
53 | |
30330
01de0045b2e3
maint: Shorten some long lines to <= 80 characters (bug #57599)
Rik <rik@octave.org>
parents:
30261
diff
changeset
|
54 ## Special case if q is prime, because isprime() is now much faster than |
01de0045b2e3
maint: Shorten some long lines to <= 80 characters (bug #57599)
Rik <rik@octave.org>
parents:
30261
diff
changeset
|
55 ## factor(). This also absorbs the case of q < 4, where there are no primes |
01de0045b2e3
maint: Shorten some long lines to <= 80 characters (bug #57599)
Rik <rik@octave.org>
parents:
30261
diff
changeset
|
56 ## less than sqrt(q). |
30261
a49c635b179d
isprime.m: Speed up for large integers using Miller-Rabin test (bug #61312).
Arun Giridhar <arungiridhar@gmail.com>
parents:
30228
diff
changeset
|
57 if (q < 4 || isprime (q)) |
19097 | 58 pf = q; |
11469
c776f063fefe
Overhaul m-script files to use common variable name between code and documentation.
Rik <octave@nomad.inbox5.com>
parents:
10476
diff
changeset
|
59 n = 1; |
5827 | 60 return; |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
61 endif |
5827 | 62 |
30261
a49c635b179d
isprime.m: Speed up for large integers using Miller-Rabin test (bug #61312).
Arun Giridhar <arungiridhar@gmail.com>
parents:
30228
diff
changeset
|
63 ## If we are here, then q is composite. |
a49c635b179d
isprime.m: Speed up for large integers using Miller-Rabin test (bug #61312).
Arun Giridhar <arungiridhar@gmail.com>
parents:
30228
diff
changeset
|
64 |
29983
ecbcc4647dbe
factor.m: Overhaul function to support inputs > flintmax.
Rik <rik@octave.org>
parents:
29359
diff
changeset
|
65 cls = class (q); # store class |
ecbcc4647dbe
factor.m: Overhaul function to support inputs > flintmax.
Rik <rik@octave.org>
parents:
29359
diff
changeset
|
66 if (isfloat (q) && q > flintmax (q)) |
29984
c633d34960b4
factor.m: Fix typo in error() message.
Rik <rik@octave.org>
parents:
29983
diff
changeset
|
67 error ("factor: Q too large to factor (> flintmax)"); |
29983
ecbcc4647dbe
factor.m: Overhaul function to support inputs > flintmax.
Rik <rik@octave.org>
parents:
29359
diff
changeset
|
68 endif |
ecbcc4647dbe
factor.m: Overhaul function to support inputs > flintmax.
Rik <rik@octave.org>
parents:
29359
diff
changeset
|
69 |
30228
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
70 ## The basic idea is to divide by the prime numbers from 1 to sqrt(q). |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
71 ## But primes(sqrt(q)) can be very time-consuming to compute for q > 1e16, |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
72 ## so we divide by smaller primes first. |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
73 ## |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
74 ## This won't make a difference for prime q, but it makes a big (100x) |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
75 ## difference for large composite q. Since there are many more composites |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
76 ## than primes, this leads overall to a speedup. |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
77 ## |
11469
c776f063fefe
Overhaul m-script files to use common variable name between code and documentation.
Rik <octave@nomad.inbox5.com>
parents:
10476
diff
changeset
|
78 ## There is at most one prime greater than sqrt(q), and if it exists, |
5827 | 79 ## it has multiplicity 1, so no need to consider any factors greater |
30228
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
80 ## than sqrt(q) directly. If there were two factors p1, p2 > sqrt(q), then |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
81 ## |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
82 ## q >= p1*p2 > sqrt(q)*sqrt(q) == q, |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
83 ## |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
84 ## which is a contradiction. |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
85 ## |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
86 ## The following calculation of transition and number of divisors to use |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
87 ## was determined empirically. As of now (October 2021) it gives the best |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
88 ## overall performance over the range of 1 <= q <= intmax ("uint64"). |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
89 ## |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
90 ## For future programmers: check periodically for performance improvements |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
91 ## and tune this transition as required. Trials that didn't yield success |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
92 ## in (October 2021): |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
93 ## |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
94 ## 1.) persistent smallprimes = primes (FOO) |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
95 ## |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
96 ## For various fixed FOO in the range 10 <= FOO <= 10e6. |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
97 ## (FOO is independent of q.) The thought had been that making it |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
98 ## persistent would cache it so it didn't need to be recomputed for |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
99 ## subsequent calls, but it slowed it down overall. It seems calling |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
100 ## primes twice with smaller q is still faster than one persistent |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
101 ## call for a large q. |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
102 ## |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
103 ## 2.) smallprimes = primes (q ^ FOO) |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
104 ## |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
105 ## For various values of FOO. For FOO >= 0.25 or FOO <= 0.16, the |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
106 ## performance is very poor. FOO needs to be in the 0.17 to 0.24 range, |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
107 ## somewhat. Benchmark experiments indicate it should increase gently |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
108 ## from 0.18 to 0.21 as q goes from 10^11 to 10^18. |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
109 ## |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
110 ## But putting in such an expression would require calculating the log |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
111 ## of q, which defeats any performance improvement. Or a step-wise |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
112 ## approximation like: |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
113 ## |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
114 ## foo = 0.18 + 0.01 * (q > 1e12) + 0.01 * (q > 1e14) ... |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
115 ## + 0.01 * (q > 1e16); |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
116 ## smallprimes = primes (feval (cls, q^foo)); |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
117 ## |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
118 ## where the RHS of foo would go from 0.18 to 0.21 over several orders |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
119 ## of magnitude without calling the log. Obviously that is overly |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
120 ## empirical, so putting in q^0.2 seems to be the most robust overall |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
121 ## for 64-bit q. |
29983
ecbcc4647dbe
factor.m: Overhaul function to support inputs > flintmax.
Rik <rik@octave.org>
parents:
29359
diff
changeset
|
122 |
30228
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
123 ## Lookup table for sufficiently small values for q. |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
124 if (q < 10e9) |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
125 ## Lookup, rather calling up to primes(100) is about 3% faster, than the |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
126 ## previous value of primes(30). Same for very small q < 1e6. |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
127 ## |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
128 ## For 1e9 < q < 10e9 the lookup approach is about 7% faster. |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
129 |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
130 smallprimes = feval (cls, ... |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
131 [2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97]); |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
132 |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
133 ## Only for really small values of q, statements like |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
134 ## |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
135 ## smallprimes(smallprimes > q) = []; |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
136 ## |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
137 ## are relevant and slow down significantly for large values of q. |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
138 else |
30379
363fb10055df
maint: Style check m-files ahead of 7.1 release.
Rik <rik@octave.org>
parents:
30330
diff
changeset
|
139 ## For sufficiently large q, go up to the 5th root of q for now. |
30228
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
140 smallprimes = primes (feval (cls, q^0.2)); |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
141 endif |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
142 |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
143 ## pf is the list of prime factors returned with type of input class. |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
144 pf = feval (cls, []); |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
145 [pf, q] = reducefactors (q, pf, smallprimes); |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
146 |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
147 ## pf now contains all prime factors of q within smallprimes, including |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
148 ## repetitions, in ascending order. |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
149 ## |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
150 ## q itself will be divided by those prime factors to become smaller, |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
151 ## unless q was prime to begin with. |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
152 |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
153 ## Now go all the way to sqrt(q), where q is smaller than the original q in |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
154 ## most cases. |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
155 ## |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
156 ## Note: Do not try to weed out the smallprimes inside largeprimes, whether |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
157 ## using length(smallprimes) or max(smallprimes) -- it slows it down! |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
158 largeprimes = primes (sqrt (q)); |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
159 [pf, q] = reducefactors (q, pf, largeprimes); |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
160 |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
161 ## At this point, all prime factors <= the sqrt of the original q have been |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
162 ## pulled out in ascending order. |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
163 ## |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
164 ## If q = 1, then no further primes are left. |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
165 ## If q > 1, then q itself must be prime, and it must be the single prime |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
166 ## factor that was larger than the sqrt of the original q. |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
167 if (q > 1) |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
168 pf(end+1) = q; |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
169 endif |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
170 |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
171 ## At this point, all prime factors have been pulled out of q in ascending |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
172 ## order. There is no need to sort(pf). |
5827 | 173 |
25269
cac96fd5310d
factor.m: Emit an error if input is negative (bug #53425).
Dildar Sk <dildarsk101010@gmail.com>
parents:
25054
diff
changeset
|
174 ## Determine multiplicity. |
5827 | 175 if (nargout > 1) |
19097 | 176 idx = find ([0, pf] != [pf, 0]); |
177 pf = pf(idx(1:length (idx)-1)); | |
11469
c776f063fefe
Overhaul m-script files to use common variable name between code and documentation.
Rik <octave@nomad.inbox5.com>
parents:
10476
diff
changeset
|
178 n = diff (idx); |
5827 | 179 endif |
180 | |
181 endfunction | |
182 | |
30228
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
183 function [pf, q] = reducefactors (qin, pfin, divisors) |
30379
363fb10055df
maint: Style check m-files ahead of 7.1 release.
Rik <rik@octave.org>
parents:
30330
diff
changeset
|
184 |
30228
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
185 pf = pfin; |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
186 q = qin; |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
187 ## The following line is a few milliseconds faster than |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
188 ## divisors (mod (q, divisors) ~= 0) = []; |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
189 divisors = divisors (mod (q, divisors) == 0); |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
190 |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
191 for pp = divisors # for each factor in turn |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
192 ## Keep extracting all occurrences of that factor before going to larger |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
193 ## factors. |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
194 ## |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
195 ## Note: mod() was marginally faster than rem(), when assessed over 10e6 |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
196 ## trials of the whole factor() function. |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
197 while (mod (q, pp) == 0) |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
198 pf(end+1) = pp; |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
199 q /= pp; |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
200 endwhile |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
201 endfor |
30379
363fb10055df
maint: Style check m-files ahead of 7.1 release.
Rik <rik@octave.org>
parents:
30330
diff
changeset
|
202 |
30228
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
203 endfunction |
39a4ab124fd0
factor.m: significant speedup for large input quantities (> 1e14) (bug #61129).
Arun Giridhar <arungiridhar@gmail.com>
parents:
29984
diff
changeset
|
204 |
14363
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
205 |
29983
ecbcc4647dbe
factor.m: Overhaul function to support inputs > flintmax.
Rik <rik@octave.org>
parents:
29359
diff
changeset
|
206 ## Test special case input |
14363
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
207 %!assert (factor (1), 1) |
29983
ecbcc4647dbe
factor.m: Overhaul function to support inputs > flintmax.
Rik <rik@octave.org>
parents:
29359
diff
changeset
|
208 %!assert (factor (2), 2) |
ecbcc4647dbe
factor.m: Overhaul function to support inputs > flintmax.
Rik <rik@octave.org>
parents:
29359
diff
changeset
|
209 %!assert (factor (3), 3) |
ecbcc4647dbe
factor.m: Overhaul function to support inputs > flintmax.
Rik <rik@octave.org>
parents:
29359
diff
changeset
|
210 |
11469
c776f063fefe
Overhaul m-script files to use common variable name between code and documentation.
Rik <octave@nomad.inbox5.com>
parents:
10476
diff
changeset
|
211 %!test |
14363
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
212 %! for i = 2:20 |
19097 | 213 %! pf = factor (i); |
214 %! assert (prod (pf), i); | |
215 %! assert (all (isprime (pf))); | |
216 %! [pf, n] = factor (i); | |
217 %! assert (prod (pf.^n), i); | |
218 %! assert (all ([0,pf] != [pf,0])); | |
14363
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
219 %! endfor |
11469
c776f063fefe
Overhaul m-script files to use common variable name between code and documentation.
Rik <octave@nomad.inbox5.com>
parents:
10476
diff
changeset
|
220 |
25270
617fe022e965
factor.m: Return output factors of same class as input for Matlab compatibility.
Rik <rik@octave.org>
parents:
25269
diff
changeset
|
221 %!assert (factor (uint8 (8)), uint8 ([2 2 2])) |
617fe022e965
factor.m: Return output factors of same class as input for Matlab compatibility.
Rik <rik@octave.org>
parents:
25269
diff
changeset
|
222 %!assert (factor (single (8)), single ([2 2 2])) |
617fe022e965
factor.m: Return output factors of same class as input for Matlab compatibility.
Rik <rik@octave.org>
parents:
25269
diff
changeset
|
223 %!test |
617fe022e965
factor.m: Return output factors of same class as input for Matlab compatibility.
Rik <rik@octave.org>
parents:
25269
diff
changeset
|
224 %! [pf, n] = factor (int16 (8)); |
617fe022e965
factor.m: Return output factors of same class as input for Matlab compatibility.
Rik <rik@octave.org>
parents:
25269
diff
changeset
|
225 %! assert (pf, int16 (2)); |
617fe022e965
factor.m: Return output factors of same class as input for Matlab compatibility.
Rik <rik@octave.org>
parents:
25269
diff
changeset
|
226 %! assert (n, double (3)); |
617fe022e965
factor.m: Return output factors of same class as input for Matlab compatibility.
Rik <rik@octave.org>
parents:
25269
diff
changeset
|
227 |
19833
9fc020886ae9
maint: Clean up m-files to follow Octave coding conventions.
Rik <rik@octave.org>
parents:
19697
diff
changeset
|
228 ## Test input validation |
28896
90fea9cc9caa
test: Add expected error message <Invalid call> to BIST tests for nargin.
Rik <rik@octave.org>
parents:
28891
diff
changeset
|
229 %!error <Invalid call> factor () |
29983
ecbcc4647dbe
factor.m: Overhaul function to support inputs > flintmax.
Rik <rik@octave.org>
parents:
29359
diff
changeset
|
230 %!error <Q must be a real non-negative integer> factor ([1,2]) |
25269
cac96fd5310d
factor.m: Emit an error if input is negative (bug #53425).
Dildar Sk <dildarsk101010@gmail.com>
parents:
25054
diff
changeset
|
231 %!error <Q must be a real non-negative integer> factor (6i) |
29983
ecbcc4647dbe
factor.m: Overhaul function to support inputs > flintmax.
Rik <rik@octave.org>
parents:
29359
diff
changeset
|
232 %!error <Q must be a real non-negative integer> factor (-20) |
25269
cac96fd5310d
factor.m: Emit an error if input is negative (bug #53425).
Dildar Sk <dildarsk101010@gmail.com>
parents:
25054
diff
changeset
|
233 %!error <Q must be a real non-negative integer> factor (1.5) |
29983
ecbcc4647dbe
factor.m: Overhaul function to support inputs > flintmax.
Rik <rik@octave.org>
parents:
29359
diff
changeset
|
234 %!error <Q too large to factor> factor (flintmax ("single") + 2) |
ecbcc4647dbe
factor.m: Overhaul function to support inputs > flintmax.
Rik <rik@octave.org>
parents:
29359
diff
changeset
|
235 %!error <Q too large to factor> factor (flintmax ("double") + 2) |