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