1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2012-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25
26 #if ! defined (octave_bsxfun_h)
27 #define octave_bsxfun_h 1
28
29 #include "octave-config.h"
30
31 #include <algorithm>
32 #include <string>
33
34 #include "dim-vector.h"
35 #include "lo-error.h"
36
37 inline
38 bool
is_valid_bsxfun(const std::string & name,const dim_vector & xdv,const dim_vector & ydv)39 is_valid_bsxfun (const std::string& name,
40 const dim_vector& xdv, const dim_vector& ydv)
41 {
42 for (int i = 0; i < std::min (xdv.ndims (), ydv.ndims ()); i++)
43 {
44 octave_idx_type xk = xdv(i);
45 octave_idx_type yk = ydv(i);
46 // Check the three conditions for valid bsxfun dims
47 if (! ((xk == yk) || (xk == 1 && yk != 1) || (xk != 1 && yk == 1)))
48 return false;
49 }
50
51 (*current_liboctave_warning_with_id_handler)
52 ("Octave:language-extension", "performing '%s' automatic broadcasting",
53 name.c_str ());
54
55 return true;
56 }
57
58 // For inplace operations the size of the resulting matrix cannot be changed.
59 // Therefore we can only apply singleton expansion on the second matrix which
60 // alters the conditions to check.
61 inline
62 bool
is_valid_inplace_bsxfun(const std::string & name,const dim_vector & rdv,const dim_vector & xdv)63 is_valid_inplace_bsxfun (const std::string& name,
64 const dim_vector& rdv, const dim_vector& xdv)
65 {
66 octave_idx_type r_nd = rdv.ndims ();
67 octave_idx_type x_nd = xdv.ndims ();
68 if (r_nd < x_nd)
69 return false;
70
71 for (int i = 0; i < r_nd; i++)
72 {
73 octave_idx_type rk = rdv(i);
74 octave_idx_type xk = xdv(i);
75
76 // Only two valid conditions to check; can't stretch rk
77 if (! ((rk == xk) || (rk != 1 && xk == 1)))
78 return false;
79 }
80
81 (*current_liboctave_warning_with_id_handler)
82 ("Octave:language-extension", "performing '%s' automatic broadcasting",
83 name.c_str ());
84
85 return true;
86 }
87
88 #include "bsxfun-defs.cc"
89
90 #endif
91