87 if (name == bsxfun_builtin_names[i])
98 template <
class NDA, NDA (bsxfun_op) (const NDA&, const NDA&)>
102 NDA xa = octave_value_extract<NDA> (
x);
103 NDA ya = octave_value_extract<NDA> (y);
107 template <
class NDA,
boolNDArray (bsxfun_rel) (const NDA&, const NDA&)>
111 NDA xa = octave_value_extract<NDA> (
x);
112 NDA ya = octave_value_extract<NDA> (y);
118 template <
class NDA,
class CNDA>
122 NDA xa = octave_value_extract<NDA> (
x);
123 NDA ya = octave_value_extract<NDA> (y);
124 if (! ya.all_integers () && xa.any_element_is_negative ())
132 static bool filled =
false;
136 #define REGISTER_OP_HANDLER(OP, BTYP, NDA, FUNOP) \
137 bsxfun_handler_table[OP][BTYP] = bsxfun_forward_op<NDA, FUNOP>
138 #define REGISTER_REL_HANDLER(REL, BTYP, NDA, FUNREL) \
139 bsxfun_handler_table[REL][BTYP] = bsxfun_forward_rel<NDA, FUNREL>
140 #define REGISTER_STD_HANDLERS(BTYP, NDA) \
141 REGISTER_OP_HANDLER (bsxfun_builtin_plus, BTYP, NDA, bsxfun_add); \
142 REGISTER_OP_HANDLER (bsxfun_builtin_minus, BTYP, NDA, bsxfun_sub); \
143 REGISTER_OP_HANDLER (bsxfun_builtin_times, BTYP, NDA, bsxfun_mul); \
144 REGISTER_OP_HANDLER (bsxfun_builtin_divide, BTYP, NDA, bsxfun_div); \
145 REGISTER_OP_HANDLER (bsxfun_builtin_max, BTYP, NDA, bsxfun_max); \
146 REGISTER_OP_HANDLER (bsxfun_builtin_min, BTYP, NDA, bsxfun_min); \
147 REGISTER_REL_HANDLER (bsxfun_builtin_eq, BTYP, NDA, bsxfun_eq); \
148 REGISTER_REL_HANDLER (bsxfun_builtin_ne, BTYP, NDA, bsxfun_ne); \
149 REGISTER_REL_HANDLER (bsxfun_builtin_lt, BTYP, NDA, bsxfun_lt); \
150 REGISTER_REL_HANDLER (bsxfun_builtin_le, BTYP, NDA, bsxfun_le); \
151 REGISTER_REL_HANDLER (bsxfun_builtin_gt, BTYP, NDA, bsxfun_gt); \
152 REGISTER_REL_HANDLER (bsxfun_builtin_ge, BTYP, NDA, bsxfun_ge)
173 do_bsxfun_real_pow<NDArray, ComplexNDArray>;
175 do_bsxfun_real_pow<FloatNDArray, FloatComplexNDArray>;
220 retval = handler (a, b);
253 bool is_changed =
false;
258 if (dva(j) != 1 && k % dvc (j) != k1 % dvc (j))
311 idx (j) = i % dv (j);
316 DEFUN (bsxfun, args, ,
318 @deftypefn {Built-in Function} {} bsxfun (@var{f}, @var{A}, @var{B})\n\
319 The binary singleton expansion function applier performs broadcasting,\n\
320 that is, applies a binary function @var{f} element-by-element to two\n\
321 array arguments @var{A} and @var{B}, and expands as necessary\n\
322 singleton dimensions in either input argument. @var{f} is a function\n\
323 handle, inline function, or string containing the name of the function\n\
324 to evaluate. The function @var{f} must be capable of accepting two\n\
325 column-vector arguments of equal length, or one column vector argument\n\
328 The dimensions of @var{A} and @var{B} must be equal or singleton. The\n\
329 singleton dimensions of the arrays will be expanded to the same\n\
330 dimensionality as the other array.\n\
331 @seealso{arrayfun, cellfun}\n\
334 int nargin = args.length ();
348 error (
"bsxfun: invalid function name: %s", name.c_str ());
350 else if (! (args(0).is_function_handle ()
351 || args(0).is_inline_function ()))
352 error (
"bsxfun: F must be a string or function handle");
392 if (dva (i) != dvb (i) && dva (i) != 1 && dvb (i) != 1)
394 error (
"bsxfun: dimensions of A and B must match");
405 dvc (i) = (dva (i) < 1 ? dva (i)
406 : (dvb (i) < 1 ? dvb (i)
408 ? dva (i) : dvb (i))));
410 if (dva == dvb || dva.
numel () == 1 || dvb.
numel () == 1)
417 else if (dvc.
numel () < 1)
420 inputs (0) = A.
resize (dvc);
421 inputs (1) = B.
resize (dvc);
432 bool have_ ## T = false;
471 #define BSXINIT(T, CLS, EXTRACTOR) \
472 (result_type == CLS) \
476 tmp (0). EXTRACTOR ## _array_value (); \
477 result_ ## T .resize (dvc); \
482 if (! tmp(0).is_sparse_type ())
484 std::string result_type = tmp(0).class_name ();
485 if (result_type ==
"double")
487 if (tmp(0).is_real_type ())
491 result_NDArray.
resize (dvc);
495 have_ComplexNDArray =
true;
496 result_ComplexNDArray =
497 tmp(0).complex_array_value ();
498 result_ComplexNDArray.
resize (dvc);
501 else if (result_type ==
"single")
503 if (tmp(0).is_real_type ())
505 have_FloatNDArray =
true;
507 = tmp(0).float_array_value ();
508 result_FloatNDArray.
resize (dvc);
512 have_ComplexNDArray =
true;
513 result_ComplexNDArray =
514 tmp(0).complex_array_value ();
515 result_ComplexNDArray.
resize (dvc);
538 if (have_FloatNDArray ||
539 have_FloatComplexNDArray)
541 if (! tmp(0).is_float_type ())
543 if (have_FloatNDArray)
545 have_FloatNDArray =
false;
546 C = result_FloatNDArray;
550 have_FloatComplexNDArray =
false;
551 C = result_FloatComplexNDArray;
555 else if (tmp(0).is_double_type ())
557 if (tmp(0).is_complex_type () &&
560 result_ComplexNDArray =
562 result_ComplexNDArray.insert
563 (tmp(0).complex_array_value (), ra_idx);
564 have_FloatComplexNDArray =
false;
565 have_ComplexNDArray =
true;
571 result_NDArray.insert
572 (tmp(0).array_value (), ra_idx);
573 have_FloatNDArray =
false;
577 else if (tmp(0).is_real_type ())
578 result_FloatNDArray.insert
579 (tmp(0).float_array_value (), ra_idx);
582 result_FloatComplexNDArray =
584 result_FloatComplexNDArray.insert
585 (tmp(0).float_complex_array_value (),
587 have_FloatNDArray =
false;
588 have_FloatComplexNDArray =
true;
591 else if (have_NDArray)
593 if (! tmp(0).is_float_type ())
595 have_NDArray =
false;
599 else if (tmp(0).is_real_type ())
600 result_NDArray.insert (tmp(0).array_value (),
604 result_ComplexNDArray =
606 result_ComplexNDArray.insert
607 (tmp(0).complex_array_value (), ra_idx);
608 have_NDArray =
false;
609 have_ComplexNDArray =
true;
613 #define BSXLOOP(T, CLS, EXTRACTOR) \
616 if (tmp (0).class_name () != CLS) \
618 have_ ## T = false; \
620 C = do_cat_op (C, tmp (0), ra_idx); \
623 result_ ## T .insert \
624 (tmp(0). EXTRACTOR ## _array_value (), \
645 retval(0) = result_ ## T;