26 #if defined(HAVE_CONFIG_H)
53 GetPerms (
const Array<T>& ar_in,
bool uniq_v,
bool do_sort =
false)
56 double nr = Factorial (
m);
60 for (
int i = 0; i <
m; i++)
69 ar = ar.sort (ar.dims () (1) > ar.dims () (0) ? 1 : 0,
ASCENDING);
70 const T *Ar = ar.data ();
79 if (Ar[i + 1] != Ar[i])
81 nr /= Factorial (N_el);
89 nr /= Factorial (N_el);
93 ar = ar.sort (ar.dims () (1) > ar.dims () (0) ? 1 : 0,
ASCENDING);
97 std::sort (myvidx, myvidx +
m, std::greater<int> ());
99 const T *Ar = ar.data ();
104 T *Res = res.fortran_vec ();
108 std::sort (myvidx, myvidx +
m, std::greater<int> ());
112 Res[i + j *
n] = Ar[myvidx[j]];
115 while (std::next_permutation (myvidx, myvidx +
m, std::greater<int> ()));
124 template <
typename T>
126 GetPermsNoSort (
const Array<T>& ar_in,
bool uniq_v =
false)
129 double nr = Factorial (
m);
133 for (
int i = 0; i <
m; i++)
136 const T *Ar = ar_in.
data ();
147 if (myvidx[j] > myvidx[i] && Ar[i].is_equal (Ar[j]))
149 myvidx[j] = myvidx[i];
154 nr /= Factorial (N_el);
159 nr /= Factorial (N_el);
163 std::sort (myvidx, myvidx +
m, std::greater<int> ());
168 T *Res = res.fortran_vec ();
175 Res[i + j *
n] = Ar[myvidx[j]];
178 while (std::next_permutation (myvidx, myvidx +
m, std::greater<int> ()));
183 DEFUN (perms, args, ,
238 int nargin = args.length ();
240 if (nargin < 1 || nargin > 2)
249 const charMatrix opt = args (1).char_matrix_value ();
250 const char *str = opt.
data ();
251 if (std::string (str, opt.
cols ()) !=
"unique")
253 error (
"perms: option must be the string \"unique\".");
258 if (! (args (0).is_matrix_type () || args (0).is_range ()
259 || args (0).iscell () || args (0).is_scalar_type ()
260 || args (0).isstruct ()))
262 error (
"perms: INPUT must be a matrix, a range, a cell array, "
263 "a struct or a scalar.");
266 std::string clname = args (0).class_name ();
269 if (clname ==
"double")
270 retval = GetPerms<double> (args (0).array_value (), uniq_v);
271 else if (clname ==
"single")
272 retval = GetPerms<float> (args (0).float_array_value (), uniq_v);
273 else if (clname ==
"logical")
274 retval = GetPerms<bool> (args (0).bool_array_value (), uniq_v);
275 else if (clname ==
"char")
276 retval = GetPerms<char> (args (0).char_array_value (), uniq_v);
277 else if (clname ==
"int8")
278 retval = GetPerms<octave_int8> (args (0).int8_array_value (), uniq_v);
279 else if (clname ==
"int16")
280 retval = GetPerms<octave_int16> (args (0).int16_array_value (), uniq_v);
281 else if (clname ==
"int32")
282 retval = GetPerms<octave_int32> (args (0).int32_array_value (), uniq_v);
283 else if (clname ==
"int64")
284 retval = GetPerms<octave_int64> (args (0).int64_array_value (), uniq_v);
285 else if (clname ==
"uint8")
286 retval = GetPerms<octave_uint8> (args (0).uint8_array_value (), uniq_v);
287 else if (clname ==
"uint16")
288 retval = GetPerms<octave_uint16> (args (0).uint16_array_value (), uniq_v);
289 else if (clname ==
"uint32")
290 retval = GetPerms<octave_uint32> (args (0).uint32_array_value (), uniq_v);
291 else if (clname ==
"uint64")
292 retval = GetPerms<octave_uint64> (args (0).uint64_array_value (), uniq_v);
293 else if (clname ==
"cell")
294 retval = GetPermsNoSort<octave_value> (args (0).cell_value (), uniq_v);
295 else if (clname ==
"struct")
297 const octave_map map_in (args (0).map_value ());
307 if (fn.
numel () == 0)
315 out.
assign (fn (i), GetPermsNoSort<octave_value>
316 (map_in.
contents (fn (i)), uniq_v));
324 warning (
"perms: unable to permute for class %s", clname.c_str ());
399 OCTAVE_END_NAMESPACE (
octave)
const T * data() const
Size of the specified dimension.
octave_idx_type cols() const
octave_idx_type numel() const
Number of elements in the array.
Vector representing the dimensions (size) of an Array.
string_vector fieldnames() const
octave_idx_type numel() const
void assign(const std::string &k, const Cell &val)
const Cell & contents(const_iterator p) const
octave_idx_type numel() const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void warning(const char *fmt,...)
void() error(const char *fmt,...)
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.