1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1996-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 (HAVE_CONFIG_H)
27 #  include "config.h"
28 #endif
29 
30 #include "errwarn.h"
31 #include "ovl.h"
32 #include "ov.h"
33 #include "ov-cx-mat.h"
34 #include "ov-flt-cx-mat.h"
35 #include "ov-typeinfo.h"
36 #include "ov-null-mat.h"
37 #include "ops.h"
38 #include "xdiv.h"
39 #include "xpow.h"
40 
41 // unary complex matrix ops.
42 
43 DEFNDUNOP_OP (not, float_complex_matrix, float_complex_array, !)
44 DEFNDUNOP_OP (uplus, float_complex_matrix, float_complex_array, /* no-op */)
45 DEFNDUNOP_OP (uminus, float_complex_matrix, float_complex_array, -)
46 
DEFUNOP(transpose,float_complex_matrix)47 DEFUNOP (transpose, float_complex_matrix)
48 {
49   const octave_float_complex_matrix& v
50     = dynamic_cast<const octave_float_complex_matrix&> (a);
51 
52   if (v.ndims () > 2)
53     error ("transpose not defined for N-D objects");
54 
55   return octave_value (v.float_complex_matrix_value ().transpose ());
56 }
57 
DEFUNOP(hermitian,float_complex_matrix)58 DEFUNOP (hermitian, float_complex_matrix)
59 {
60   const octave_float_complex_matrix& v
61     = dynamic_cast<const octave_float_complex_matrix&> (a);
62 
63   if (v.ndims () > 2)
64     error ("complex-conjugate transpose not defined for N-D objects");
65 
66   return octave_value (v.float_complex_matrix_value ().hermitian ());
67 }
68 
DEFNCUNOP_METHOD(incr,float_complex_matrix,increment)69 DEFNCUNOP_METHOD (incr, float_complex_matrix, increment)
70 DEFNCUNOP_METHOD (decr, float_complex_matrix, decrement)
71 DEFNCUNOP_METHOD (changesign, float_complex_matrix, changesign)
72 
73 // complex matrix by complex matrix ops.
74 
75 DEFNDBINOP_OP (add, float_complex_matrix, float_complex_matrix,
76                float_complex_array, float_complex_array, +)
77 DEFNDBINOP_OP (sub, float_complex_matrix, float_complex_matrix,
78                float_complex_array, float_complex_array, -)
79 
80 DEFBINOP_OP (mul, float_complex_matrix, float_complex_matrix, *)
81 
82 DEFBINOP (div, float_complex_matrix, float_complex_matrix)
83 {
84   const octave_float_complex_matrix& v1
85     = dynamic_cast<const octave_float_complex_matrix&> (a1);
86   const octave_float_complex_matrix& v2
87     = dynamic_cast<const octave_float_complex_matrix&> (a2);
88   MatrixType typ = v2.matrix_type ();
89 
90   FloatComplexMatrix ret = xdiv (v1.float_complex_matrix_value (),
91                                  v2.float_complex_matrix_value (), typ);
92 
93   v2.matrix_type (typ);
94   return ret;
95 }
96 
DEFBINOPX(pow,float_complex_matrix,float_complex_matrix)97 DEFBINOPX (pow, float_complex_matrix, float_complex_matrix)
98 {
99   error ("can't do A ^ B for A and B both matrices");
100 }
101 
DEFBINOP(ldiv,float_complex_matrix,float_complex_matrix)102 DEFBINOP (ldiv, float_complex_matrix, float_complex_matrix)
103 {
104   const octave_float_complex_matrix& v1
105     = dynamic_cast<const octave_float_complex_matrix&> (a1);
106   const octave_float_complex_matrix& v2
107     = dynamic_cast<const octave_float_complex_matrix&> (a2);
108   MatrixType typ = v1.matrix_type ();
109 
110   FloatComplexMatrix ret = xleftdiv (v1.float_complex_matrix_value (),
111                                      v2.float_complex_matrix_value (), typ);
112 
113   v1.matrix_type (typ);
114   return ret;
115 }
116 
DEFBINOP(trans_mul,float_complex_matrix,float_complex_matrix)117 DEFBINOP (trans_mul, float_complex_matrix, float_complex_matrix)
118 {
119   const octave_float_complex_matrix& v1
120     = dynamic_cast<const octave_float_complex_matrix&> (a1);
121   const octave_float_complex_matrix& v2
122     = dynamic_cast<const octave_float_complex_matrix&> (a2);
123   return octave_value(xgemm (v1.float_complex_matrix_value (),
124                              v2.float_complex_matrix_value (),
125                              blas_trans, blas_no_trans));
126 }
127 
DEFBINOP(mul_trans,float_complex_matrix,float_complex_matrix)128 DEFBINOP (mul_trans, float_complex_matrix, float_complex_matrix)
129 {
130   const octave_float_complex_matrix& v1
131     = dynamic_cast<const octave_float_complex_matrix&> (a1);
132   const octave_float_complex_matrix& v2
133     = dynamic_cast<const octave_float_complex_matrix&> (a2);
134   return octave_value(xgemm (v1.float_complex_matrix_value (),
135                              v2.float_complex_matrix_value (),
136                              blas_no_trans, blas_trans));
137 }
138 
DEFBINOP(herm_mul,float_complex_matrix,float_complex_matrix)139 DEFBINOP (herm_mul, float_complex_matrix, float_complex_matrix)
140 {
141   const octave_float_complex_matrix& v1
142     = dynamic_cast<const octave_float_complex_matrix&> (a1);
143   const octave_float_complex_matrix& v2
144     = dynamic_cast<const octave_float_complex_matrix&> (a2);
145   return octave_value(xgemm (v1.float_complex_matrix_value (),
146                              v2.float_complex_matrix_value (),
147                              blas_conj_trans, blas_no_trans));
148 }
149 
DEFBINOP(mul_herm,float_complex_matrix,float_complex_matrix)150 DEFBINOP (mul_herm, float_complex_matrix, float_complex_matrix)
151 {
152   const octave_float_complex_matrix& v1
153     = dynamic_cast<const octave_float_complex_matrix&> (a1);
154   const octave_float_complex_matrix& v2
155     = dynamic_cast<const octave_float_complex_matrix&> (a2);
156   return octave_value(xgemm (v1.float_complex_matrix_value (),
157                              v2.float_complex_matrix_value (),
158                              blas_no_trans, blas_conj_trans));
159 }
160 
DEFBINOP(trans_ldiv,float_complex_matrix,float_complex_matrix)161 DEFBINOP (trans_ldiv, float_complex_matrix, float_complex_matrix)
162 {
163   const octave_float_complex_matrix& v1
164     = dynamic_cast<const octave_float_complex_matrix&> (a1);
165   const octave_float_complex_matrix& v2
166     = dynamic_cast<const octave_float_complex_matrix&> (a2);
167   MatrixType typ = v1.matrix_type ();
168 
169   FloatComplexMatrix ret = xleftdiv (v1.float_complex_matrix_value (),
170                                      v2.float_complex_matrix_value (),
171                                      typ, blas_trans);
172 
173   v1.matrix_type (typ);
174   return ret;
175 }
176 
DEFBINOP(herm_ldiv,float_complex_matrix,float_complex_matrix)177 DEFBINOP (herm_ldiv, float_complex_matrix, float_complex_matrix)
178 {
179   const octave_float_complex_matrix& v1
180     = dynamic_cast<const octave_float_complex_matrix&> (a1);
181   const octave_float_complex_matrix& v2
182     = dynamic_cast<const octave_float_complex_matrix&> (a2);
183   MatrixType typ = v1.matrix_type ();
184 
185   FloatComplexMatrix ret = xleftdiv (v1.float_complex_matrix_value (),
186                                      v2.float_complex_matrix_value (),
187                                      typ, blas_conj_trans);
188 
189   v1.matrix_type (typ);
190   return ret;
191 }
192 
DEFNDCMPLXCMPOP_FN(lt,float_complex_matrix,float_complex_matrix,float_complex_array,float_complex_array,mx_el_lt)193 DEFNDCMPLXCMPOP_FN (lt, float_complex_matrix, float_complex_matrix,
194                     float_complex_array, float_complex_array, mx_el_lt)
195 DEFNDCMPLXCMPOP_FN (le, float_complex_matrix, float_complex_matrix,
196                     float_complex_array, float_complex_array, mx_el_le)
197 DEFNDCMPLXCMPOP_FN (eq, float_complex_matrix, float_complex_matrix,
198                     float_complex_array, float_complex_array, mx_el_eq)
199 DEFNDCMPLXCMPOP_FN (ge, float_complex_matrix, float_complex_matrix,
200                     float_complex_array, float_complex_array, mx_el_ge)
201 DEFNDCMPLXCMPOP_FN (gt, float_complex_matrix, float_complex_matrix,
202                     float_complex_array, float_complex_array, mx_el_gt)
203 DEFNDCMPLXCMPOP_FN (ne, float_complex_matrix, float_complex_matrix,
204                     float_complex_array, float_complex_array, mx_el_ne)
205 
206 DEFNDBINOP_FN (el_mul, float_complex_matrix, float_complex_matrix,
207                float_complex_array, float_complex_array, product)
208 DEFNDBINOP_FN (el_div, float_complex_matrix, float_complex_matrix,
209                float_complex_array, float_complex_array, quotient)
210 DEFNDBINOP_FN (el_pow, float_complex_matrix, float_complex_matrix,
211                float_complex_array, float_complex_array, elem_xpow)
212 
213 DEFBINOP (el_ldiv, float_complex_matrix, float_complex_matrix)
214 {
215   const octave_float_complex_matrix& v1
216     = dynamic_cast<const octave_float_complex_matrix&> (a1);
217   const octave_float_complex_matrix& v2
218     = dynamic_cast<const octave_float_complex_matrix&> (a2);
219 
220   return octave_value (quotient (v2.float_complex_array_value (),
221                                  v1.float_complex_array_value ()));
222 }
223 
DEFNDBINOP_FN(el_and,float_complex_matrix,float_complex_matrix,float_complex_array,float_complex_array,mx_el_and)224 DEFNDBINOP_FN (el_and, float_complex_matrix, float_complex_matrix,
225                float_complex_array, float_complex_array, mx_el_and)
226 DEFNDBINOP_FN (el_or,  float_complex_matrix, float_complex_matrix,
227                float_complex_array, float_complex_array, mx_el_or)
228 
229 DEFNDCATOP_FN (fcm_fcm, float_complex_matrix, float_complex_matrix,
230                float_complex_array, float_complex_array, concat)
231 
232 DEFNDCATOP_FN (cm_fcm, complex_matrix, float_complex_matrix,
233                float_complex_array, float_complex_array, concat)
234 
235 DEFNDCATOP_FN (fcm_cm, float_complex_matrix, complex_matrix,
236                float_complex_array, float_complex_array, concat)
237 
238 DEFNDASSIGNOP_FN (assign, float_complex_matrix, float_complex_matrix,
239                   float_complex_array, assign)
240 DEFNDASSIGNOP_FN (sgl_clx_assign, float_complex_matrix, complex_matrix,
241                   float_complex_array, assign)
242 DEFNDASSIGNOP_FN (sgl_assign, float_complex_matrix, matrix,
243                   float_complex_array, assign)
244 DEFNDASSIGNOP_FN (dbl_assign, complex_matrix, float_complex_matrix,
245                   complex_array, assign)
246 
247 DEFNULLASSIGNOP_FN (null_assign, float_complex_matrix, delete_elements)
248 
249 DEFNDASSIGNOP_OP (assign_add, float_complex_matrix,
250                   float_complex_matrix, float_complex_array, +=)
251 DEFNDASSIGNOP_OP (assign_sub, float_complex_matrix,
252                   float_complex_matrix, float_complex_array, -=)
253 DEFNDASSIGNOP_FNOP (assign_el_mul, float_complex_matrix, float_complex_matrix,
254                     float_complex_array, product_eq)
255 DEFNDASSIGNOP_FNOP (assign_el_div, float_complex_matrix, float_complex_matrix,
256                     float_complex_array, quotient_eq)
257 
258 void
259 install_fcm_fcm_ops (octave::type_info& ti)
260 {
261   INSTALL_UNOP_TI (ti, op_not, octave_float_complex_matrix, not);
262   INSTALL_UNOP_TI (ti, op_uplus, octave_float_complex_matrix, uplus);
263   INSTALL_UNOP_TI (ti, op_uminus, octave_float_complex_matrix, uminus);
264   INSTALL_UNOP_TI (ti, op_transpose, octave_float_complex_matrix, transpose);
265   INSTALL_UNOP_TI (ti, op_hermitian, octave_float_complex_matrix, hermitian);
266 
267   INSTALL_NCUNOP_TI (ti, op_incr, octave_float_complex_matrix, incr);
268   INSTALL_NCUNOP_TI (ti, op_decr, octave_float_complex_matrix, decr);
269   INSTALL_NCUNOP_TI (ti, op_uminus, octave_float_complex_matrix, changesign);
270 
271   INSTALL_BINOP_TI (ti, op_add, octave_float_complex_matrix,
272                     octave_float_complex_matrix, add);
273   INSTALL_BINOP_TI (ti, op_sub, octave_float_complex_matrix,
274                     octave_float_complex_matrix, sub);
275   INSTALL_BINOP_TI (ti, op_mul, octave_float_complex_matrix,
276                     octave_float_complex_matrix, mul);
277   INSTALL_BINOP_TI (ti, op_div, octave_float_complex_matrix,
278                     octave_float_complex_matrix, div);
279   INSTALL_BINOP_TI (ti, op_pow, octave_float_complex_matrix,
280                     octave_float_complex_matrix, pow);
281   INSTALL_BINOP_TI (ti, op_ldiv, octave_float_complex_matrix,
282                     octave_float_complex_matrix, ldiv);
283   INSTALL_BINOP_TI (ti, op_trans_mul, octave_float_complex_matrix,
284                     octave_float_complex_matrix, trans_mul);
285   INSTALL_BINOP_TI (ti, op_mul_trans, octave_float_complex_matrix,
286                     octave_float_complex_matrix, mul_trans);
287   INSTALL_BINOP_TI (ti, op_herm_mul, octave_float_complex_matrix,
288                     octave_float_complex_matrix, herm_mul);
289   INSTALL_BINOP_TI (ti, op_mul_herm, octave_float_complex_matrix,
290                     octave_float_complex_matrix, mul_herm);
291   INSTALL_BINOP_TI (ti, op_trans_ldiv, octave_float_complex_matrix,
292                     octave_float_complex_matrix, trans_ldiv);
293   INSTALL_BINOP_TI (ti, op_herm_ldiv, octave_float_complex_matrix,
294                     octave_float_complex_matrix, herm_ldiv);
295 
296   INSTALL_BINOP_TI (ti, op_lt, octave_float_complex_matrix,
297                     octave_float_complex_matrix, lt);
298   INSTALL_BINOP_TI (ti, op_le, octave_float_complex_matrix,
299                     octave_float_complex_matrix, le);
300   INSTALL_BINOP_TI (ti, op_eq, octave_float_complex_matrix,
301                     octave_float_complex_matrix, eq);
302   INSTALL_BINOP_TI (ti, op_ge, octave_float_complex_matrix,
303                     octave_float_complex_matrix, ge);
304   INSTALL_BINOP_TI (ti, op_gt, octave_float_complex_matrix,
305                     octave_float_complex_matrix, gt);
306   INSTALL_BINOP_TI (ti, op_ne, octave_float_complex_matrix,
307                     octave_float_complex_matrix, ne);
308   INSTALL_BINOP_TI (ti, op_el_mul, octave_float_complex_matrix,
309                     octave_float_complex_matrix, el_mul);
310   INSTALL_BINOP_TI (ti, op_el_div, octave_float_complex_matrix,
311                     octave_float_complex_matrix, el_div);
312   INSTALL_BINOP_TI (ti, op_el_pow, octave_float_complex_matrix,
313                     octave_float_complex_matrix, el_pow);
314   INSTALL_BINOP_TI (ti, op_el_ldiv, octave_float_complex_matrix,
315                     octave_float_complex_matrix, el_ldiv);
316   INSTALL_BINOP_TI (ti, op_el_and, octave_float_complex_matrix,
317                     octave_float_complex_matrix, el_and);
318   INSTALL_BINOP_TI (ti, op_el_or, octave_float_complex_matrix,
319                     octave_float_complex_matrix, el_or);
320 
321   INSTALL_CATOP_TI (ti, octave_float_complex_matrix,
322                     octave_float_complex_matrix, fcm_fcm);
323   INSTALL_CATOP_TI (ti, octave_complex_matrix,
324                     octave_float_complex_matrix, cm_fcm);
325   INSTALL_CATOP_TI (ti, octave_float_complex_matrix,
326                     octave_complex_matrix, fcm_cm);
327 
328   INSTALL_ASSIGNOP_TI (ti, op_asn_eq, octave_float_complex_matrix,
329                        octave_float_complex_matrix, assign);
330   INSTALL_ASSIGNOP_TI (ti, op_asn_eq, octave_float_complex_matrix,
331                        octave_complex_matrix, sgl_clx_assign);
332   INSTALL_ASSIGNOP_TI (ti, op_asn_eq, octave_float_complex_matrix,
333                        octave_matrix, sgl_assign);
334   INSTALL_ASSIGNOP_TI (ti, op_asn_eq, octave_complex_matrix,
335                        octave_float_complex_matrix, dbl_assign);
336 
337   INSTALL_ASSIGNOP_TI (ti, op_asn_eq, octave_float_complex_matrix,
338                        octave_null_matrix, null_assign);
339   INSTALL_ASSIGNOP_TI (ti, op_asn_eq, octave_float_complex_matrix,
340                        octave_null_str, null_assign);
341   INSTALL_ASSIGNOP_TI (ti, op_asn_eq, octave_float_complex_matrix,
342                        octave_null_sq_str, null_assign);
343 
344   INSTALL_ASSIGNOP_TI (ti, op_add_eq, octave_float_complex_matrix,
345                        octave_float_complex_matrix, assign_add);
346   INSTALL_ASSIGNOP_TI (ti, op_sub_eq, octave_float_complex_matrix,
347                        octave_float_complex_matrix, assign_sub);
348   INSTALL_ASSIGNOP_TI (ti, op_el_mul_eq, octave_float_complex_matrix,
349                        octave_float_complex_matrix, assign_el_mul);
350   INSTALL_ASSIGNOP_TI (ti, op_el_div_eq, octave_float_complex_matrix,
351                        octave_float_complex_matrix, assign_el_div);
352 }
353