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>;
221 retval = handler (a, b);
254 bool is_changed =
false;
259 if (dva(j) != 1 && k % dvc (j) != k1 % dvc (j))
312 idx (j) = i % dv (j);
317 DEFUN (bsxfun, args, ,
319 @deftypefn {Built-in Function} {} bsxfun (@var{f}, @var{A}, @var{B})\n\
320 The binary singleton expansion function performs broadcasting,\n\
321 that is, it applies a binary function @var{f} element-by-element to two\n\
322 array arguments @var{A} and @var{B}, and expands as necessary\n\
323 singleton dimensions in either input argument.\n\
325 @var{f} is a function handle, inline function, or string containing the name\n\
326 of the function to evaluate. The function @var{f} must be capable of\n\
327 accepting two column-vector arguments of equal length, or one column vector\n\
328 argument and a scalar.\n\
330 The dimensions of @var{A} and @var{B} must be equal or singleton. The\n\
331 singleton dimensions of the arrays will be expanded to the same\n\
332 dimensionality as the other array.\n\
333 @seealso{arrayfun, cellfun}\n\
336 int nargin = args.length ();
350 error (
"bsxfun: invalid function name: %s", name.c_str ());
352 else if (! (args(0).is_function_handle ()
353 || args(0).is_inline_function ()))
354 error (
"bsxfun: F must be a string or function handle");
394 if (dva (i) != dvb (i) && dva (i) != 1 && dvb (i) != 1)
396 error (
"bsxfun: dimensions of A and B must match");
407 dvc (i) = (dva (i) < 1 ? dva (i)
408 : (dvb (i) < 1 ? dvb (i)
410 ? dva (i) : dvb (i))));
412 if (dva == dvb || dva.
numel () == 1 || dvb.
numel () == 1)
419 else if (dvc.
numel () < 1)
422 inputs (0) = A.
resize (dvc);
423 inputs (1) = B.
resize (dvc);
434 bool have_ ## T = false;
473 #define BSXINIT(T, CLS, EXTRACTOR) \
474 (result_type == CLS) \
478 tmp (0). EXTRACTOR ## _array_value (); \
479 result_ ## T .resize (dvc); \
484 if (! tmp(0).is_sparse_type ())
486 std::string result_type = tmp(0).class_name ();
487 if (result_type ==
"double")
489 if (tmp(0).is_real_type ())
493 result_NDArray.
resize (dvc);
497 have_ComplexNDArray =
true;
498 result_ComplexNDArray =
499 tmp(0).complex_array_value ();
500 result_ComplexNDArray.
resize (dvc);
503 else if (result_type ==
"single")
505 if (tmp(0).is_real_type ())
507 have_FloatNDArray =
true;
509 = tmp(0).float_array_value ();
510 result_FloatNDArray.
resize (dvc);
514 have_ComplexNDArray =
true;
515 result_ComplexNDArray =
516 tmp(0).complex_array_value ();
517 result_ComplexNDArray.
resize (dvc);
540 if (have_FloatNDArray
541 || have_FloatComplexNDArray)
543 if (! tmp(0).is_float_type ())
545 if (have_FloatNDArray)
547 have_FloatNDArray =
false;
548 C = result_FloatNDArray;
552 have_FloatComplexNDArray =
false;
553 C = result_FloatComplexNDArray;
557 else if (tmp(0).is_double_type ())
559 if (tmp(0).is_complex_type ()
560 && have_FloatNDArray)
562 result_ComplexNDArray =
564 result_ComplexNDArray.insert
565 (tmp(0).complex_array_value (), ra_idx);
566 have_FloatComplexNDArray =
false;
567 have_ComplexNDArray =
true;
573 result_NDArray.insert
574 (tmp(0).array_value (), ra_idx);
575 have_FloatNDArray =
false;
579 else if (tmp(0).is_real_type ())
580 result_FloatNDArray.insert
581 (tmp(0).float_array_value (), ra_idx);
584 result_FloatComplexNDArray =
586 result_FloatComplexNDArray.insert
587 (tmp(0).float_complex_array_value (),
589 have_FloatNDArray =
false;
590 have_FloatComplexNDArray =
true;
593 else if (have_NDArray)
595 if (! tmp(0).is_float_type ())
597 have_NDArray =
false;
601 else if (tmp(0).is_real_type ())
602 result_NDArray.insert (tmp(0).array_value (),
606 result_ComplexNDArray =
608 result_ComplexNDArray.insert
609 (tmp(0).complex_array_value (), ra_idx);
610 have_NDArray =
false;
611 have_ComplexNDArray =
true;
615 #define BSXLOOP(T, CLS, EXTRACTOR) \
618 if (tmp (0).class_name () != CLS) \
620 have_ ## T = false; \
622 C = do_cat_op (C, tmp (0), ra_idx); \
625 result_ ## T .insert \
626 (tmp(0). EXTRACTOR ## _array_value (), \
647 retval(0) = result_ ## T;
octave_value(* bsxfun_handler)(const octave_value &, const octave_value &)
bool is_builtin_function(void) const
bool is_object(void) const
const octave_base_value const Array< octave_idx_type > & ra_idx
octave_value do_cat_op(const octave_value &v1, const octave_value &v2, const Array< octave_idx_type > &ra_idx)
boolNDArray bsxfun_le(const charNDArray &x, const charNDArray &y)
static octave_value bsxfun_forward_op(const octave_value &x, const octave_value &y)
OCTINTERP_API void print_usage(void)
F77_RET_T const octave_idx_type Complex * A
bool is_defined(void) const
static bsxfun_builtin_op bsxfun_builtin_lookup(const std::string &name)
void resize(int n, int fill_value=0)
static octave_value do_bsxfun_real_pow(const octave_value &x, const octave_value &y)
#define DEFUN(name, args_name, nargout_name, doc)
void error(const char *fmt,...)
std::string name(void) const
octave_value resize(const dim_vector &dv, bool fill=false) const
boolNDArray bsxfun_lt(const charNDArray &x, const charNDArray &y)
static octave_value maybe_optimized_builtin(const std::string &name, const octave_value &a, const octave_value &b)
static octave_value find_function(const std::string &name, const octave_value_list &args=octave_value_list(), bool local_funcs=true)
bool is_function_handle(void) const
octave_idx_type numel(int n=0) const
Number of elements that a matrix with this dimensions would have.
boolNDArray bsxfun_eq(const charNDArray &x, const charNDArray &y)
octave_value single_subsref(const std::string &type, const octave_value_list &idx)
octave_value_list do_multi_index_op(int nargout, const octave_value_list &idx)
#define REGISTER_OP_HANDLER(OP, BTYP, NDA, FUNOP)
std::string string_value(bool force=false) const
bool is_string(void) const
static void update_index(Array< int > &idx, const dim_vector &dv, octave_idx_type i)
void resize(const dim_vector &dv, const T &rfv)
#define REGISTER_REL_HANDLER(REL, BTYP, NDA, FUNREL)
boolNDArray bsxfun_and(const boolNDArray &x, const boolNDArray &y)
dim_vector dims(void) const
ComplexNDArray bsxfun_pow(const ComplexNDArray &x, const ComplexNDArray &y)
boolNDArray bsxfun_ge(const charNDArray &x, const charNDArray &y)
octave_function * function_value(bool silent=false) const
#define BSXLOOP(T, CLS, EXTRACTOR)
static bool maybe_update_column(octave_value &Ac, const octave_value &A, const dim_vector &dva, const dim_vector &dvc, octave_idx_type i, octave_value_list &idx)
Handles the reference counting for all the derived classes.
F77_RET_T const octave_idx_type Complex const octave_idx_type Complex * B
Array< octave_value > array_value(void) const
static octave_value bsxfun_forward_rel(const octave_value &x, const octave_value &y)
static void maybe_fill_table(void)
const char * bsxfun_builtin_names[]
boolNDArray bsxfun_ne(const charNDArray &x, const charNDArray &y)
bool is_undefined(void) const
void resize(octave_idx_type n, const octave_value &rfv=octave_value())
boolNDArray bsxfun_gt(const charNDArray &x, const charNDArray &y)
bsxfun_handler bsxfun_handler_table[bsxfun_num_builtin_ops][btyp_num_types]
#define REGISTER_STD_HANDLERS(BTYP, NDA)
builtin_type_t builtin_type(void) const
boolNDArray bsxfun_or(const boolNDArray &x, const boolNDArray &y)
return octave_value(v1.char_array_value().concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string())? '\'': '"'))
F77_RET_T const double * x
#define BSXINIT(T, CLS, EXTRACTOR)