1
// Copyright (C) 2006 Torsten Finke <fi@igh-essen.com>
3
// This program is free software; you can redistribute it and/or modify it under
4
// the terms of the GNU General Public License as published by the Free Software
5
// Foundation; either version 3 of the License, or (at your option) any later
8
// This program is distributed in the hope that it will be useful, but WITHOUT
9
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13
// You should have received a copy of the GNU General Public License along with
14
// this program; if not, see <http://www.gnu.org/licenses/>.
16
#include <octave/oct.h>
17
#include <octave/lo-ieee.h>
21
unsigned long * pcnt(unsigned long n)
23
unsigned long *s = new unsigned long[n];
24
unsigned long *x = new unsigned long[n*n];
25
unsigned long **p = new unsigned long*[n];
26
for (unsigned long k=0; k<n; ++k) {
30
for (unsigned long k=0; k<n*n; ++k) x[k] = 0;
32
for (unsigned long k=1; k<n; ++k)
34
// p[N][j] == numpart of N with max summand j
35
for (unsigned long j=1; j<=k; ++j) {
36
p[k][j] = p[k-1][j-1] + p[k-j][j];
38
for (unsigned long j=1; j<=k; ++j) {
39
s[k] += p[k][j]; // S(k) = numpart(n)
45
DEFUN_DLD (partcnt, args, ,
47
@deftypefn{Loadable Function} {@var{p} =} partcnt(@var{n})\n\
49
@cindex partition count\n\
51
Calculate integer partition count. Argument @var{n} be scalar, vector\n\
52
or matrix of non-negative numbers. A partition is the sum decomposition \n\
57
partcnt([1, 5; 17 -3])\n\
68
Joerg Arndt: Algorithms for programmers (http://www.jjj.de), 2006.\n\n\
75
int nargin = args.length ();
77
error("partcnt accepts exactly one argument");
80
if ( ! args(0).is_numeric_type()) {
81
error("partcnt only accepts a numeric argument");
85
NDArray f(args(0).matrix_value());
87
double mmax = m.max();
89
error("partcnt is only defined for non-negative arguments");
93
unsigned long n = (unsigned long) mmax + 1;
94
unsigned long *s = pcnt(n);
95
unsigned long fr = (unsigned long) f.rows();
96
unsigned long fc = (unsigned long) f.columns();
97
for (unsigned long i=0; i<fr; i++) {
98
for (unsigned long k=0; k<fc; k++) {
99
unsigned long idx = (unsigned long) f(i, k);
100
if (0 < idx && idx < n) {
103
f(i, k) = lo_ieee_nan_value();
113
%!assert(partcnt(1), 1);
114
%!assert(partcnt(17), 297);
115
%!fail("partcnt()", "partcnt");
116
%!fail("partcnt(1,2)", "partcnt");
117
%!fail("partcnt('xyz')", "partcnt");
119
%! p = partcnt([1, 5; 17 -5])
123
DEFUN_DLD (partint, args, ,
125
@deftypefn{Loadable Function} {@var{p} =} partint(@var{n})\n\
129
Calculate all integer partitions. Argument @var{n} be \n\
130
a positive number. A partition is the sum decomposition \n\
151
$$\eqalign{4 & = 4 \\cdot 1 \\cr\n\
152
& = 2 \\cdot 1 + 1 \\cdot 2 \\cr\n\
153
& = 2 \\cdot 2 \\cr\n\
154
& = 1 \\cdot 1 + 1 \\cdot 3 \\cr\n\
155
& = 1 \\cdot 1 \\cr\n\
171
partint(n) * [1:n]' == n\n\
174
Joerg Arndt: Algorithms for programmers (http://www.jjj.de), 2006.\n\n\
181
int nargin = args.length ();
183
! args(0).is_scalar_type() ||
184
! args(0).is_numeric_type()
186
error("partint only accepts one scalar positive integer argument");
189
double arg0 = args(0).double_value();
191
error("partint is only defined for positive integer arguments");
195
unsigned long n = (unsigned long) arg0;
196
unsigned long *s = pcnt(n+1);
197
unsigned long k = s[n];
202
const unsigned long *d = p.data();
203
for (unsigned long j=0; j<n; j++) {
204
pa(i, j) = (unsigned long)d[j+1];
214
%!assert(partint(1), 1);
215
%!assert(all(partint(n=17) * [1:n]' == n) - 1, 0);
217
%! expected = [4,0,0,0; 2,1,0,0; 0,2,0,0; 1,0,1,0; 0,0,0,1];
218
%! assert(partint(4), expected);
219
%!fail("partint()", "partint");
220
%!fail("partint(1,2)", "partint");
221
%!fail("partint('xyz')", "partint");