1
// Copyright (C) 2011 Piotr Krzyzanowski <piotr.krzyzanowski@mimuw.edu.pl>
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 "randmtzig.h"
21
IntSetBins2 class and its usage from 'Programming Pearls'
22
by Jon Bentley, 2nd edition, available at
23
http://netlib.bell-labs.com/cm/cs/pearls/sets.cpp.
25
The notice on http://netlib.bell-labs.com/cm/cs/pearls/code.html says
26
"You may use this code for any purpose,
27
as long as you leave the copyright notice and book citation attached."
31
/* IntSetBins2 class Copyright (C) 1999 Lucent Technologies */
32
/* From 'Programming Pearls', 2nd edition, by Jon Bentley */
33
/* sets.cpp -- exercise set implementations on random numbers */
45
node **bin, *sentinel, *freenode;
46
node *rinsert(node *p, double t)
48
p->next = rinsert(p->next, t);
49
} else if (p->val > t) {
58
IntSetBins2(unsigned int maxelements, double pmaxval)
61
freenode = new node[maxelements];
62
bin = new node*[bins];
64
sentinel->val = maxval;
65
for (unsigned int i = 0; i < bins; i++)
69
unsigned int size() { return n; }
70
void insert1(double t)
71
{ unsigned int i = t / (1.0 + maxval/bins);
72
bin[i] = rinsert(bin[i], t);
76
unsigned int i = t / (1.0 + maxval/bins);
77
for (p = &bin[i]; (*p)->val < t; p = &((*p)->next))
86
void report(double *v)
88
for (unsigned int i = 0; i < bins; i++)
89
for (node *p = bin[i]; p != sentinel; p = p->next)
95
DEFUN_DLD (sample, args, , "-*- texinfo -*-\n\
96
@deftypefn {Loadable Function} {@var{s}} = sample (@var{m}, @var{n})\n\
97
Return @var{m} unique random integer values from 0..@var{n}-1,\n\
98
sorted in ascending order.\n\
100
Based on a code from Jon Bentley's \"Programming Pearls\", \n\
101
see @url{http://netlib.bell-labs.com/cm/cs/pearls/}.\n\
104
int nargin = args.length();
108
return octave_value ();
112
double M = args(0).scalar_value(); // temporarily allow for
113
// negative values of "m"
114
double n = args(1).scalar_value(); // allow huge values of "n"
120
m = M; // set actual "m" only after making sure it is not negative
123
/* as in the code from "Programming Pearls" */
126
S.insert(floor(oct_randu()*n)); // use Octave's uniform RNG
127
S.report(s.fortran_vec());
128
return octave_value (s);
131
%!assert (isempty(sample(0,10)));
132
%!assert (isempty(sample(-2,10)));
133
%!assert (sample(10,10),[0:9]);
134
%!assert (sample(12,10),[0:9]);
135
%!assert (length(sample(9,10)),9);
141
%!assert (all(a>=0));
142
%!assert (length(a),m);
146
%!assert (all(a>=0));
147
%!assert (length(a),m);
150
%! % s should contain an increasing sequence of 4 integers from the range 0..7