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