GNU Octave
4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
Main Page
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Pages
liboctave
operators
mx-op-defs.h
Go to the documentation of this file.
1
/*
2
3
Copyright (C) 1996-2017 John W. Eaton
4
Copyright (C) 2008-2009 Jaroslav Hajek
5
Copyright (C) 2009-2010 VZLU Prague, a.s.
6
7
This file is part of Octave.
8
9
Octave is free software; you can redistribute it and/or modify it
10
under the terms of the GNU General Public License as published by the
11
Free Software Foundation; either version 3 of the License, or (at your
12
option) any later version.
13
14
Octave is distributed in the hope that it will be useful, but WITHOUT
15
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17
for more details.
18
19
You should have received a copy of the GNU General Public License
20
along with Octave; see the file COPYING. If not, see
21
<http://www.gnu.org/licenses/>.
22
23
*/
24
25
#if ! defined (octave_mx_op_defs_h)
26
#define octave_mx_op_defs_h 1
27
28
#include "octave-config.h"
29
30
#include "
lo-array-errwarn.h
"
31
#include "
mx-op-decl.h
"
32
#include "
mx-inlines.cc
"
33
34
#define SNANCHK(s) \
35
if (octave::math::isnan (s)) \
36
octave::err_nan_to_logical_conversion ()
37
38
#define MNANCHK(m, MT) \
39
if (do_mx_check (m, mx_inline_any_nan<MT>)) \
40
octave::err_nan_to_logical_conversion ()
41
42
// vector by scalar operations.
43
44
#define VS_BIN_OP(R, F, OP, V, S) \
45
R \
46
F (const V& v, const S& s) \
47
{ \
48
return do_ms_binary_op<R::element_type, V::element_type, S> (v, s, OP); \
49
}
50
51
#define VS_BIN_OPS(R, V, S) \
52
VS_BIN_OP (R, operator +, mx_inline_add, V, S) \
53
VS_BIN_OP (R, operator -, mx_inline_sub, V, S) \
54
VS_BIN_OP (R, operator *, mx_inline_mul, V, S) \
55
VS_BIN_OP (R, operator /, mx_inline_div, V, S)
56
57
// scalar by vector by operations.
58
59
#define SV_BIN_OP(R, F, OP, S, V) \
60
R \
61
F (const S& s, const V& v) \
62
{ \
63
return do_sm_binary_op<R::element_type, S, V::element_type> (s, v, OP); \
64
}
65
66
#define SV_BIN_OPS(R, S, V) \
67
SV_BIN_OP (R, operator +, mx_inline_add, S, V) \
68
SV_BIN_OP (R, operator -, mx_inline_sub, S, V) \
69
SV_BIN_OP (R, operator *, mx_inline_mul, S, V) \
70
SV_BIN_OP (R, operator /, mx_inline_div, S, V)
71
72
// vector by vector operations.
73
74
#define VV_BIN_OP(R, F, OP, V1, V2) \
75
R \
76
F (const V1& v1, const V2& v2) \
77
{ \
78
return do_mm_binary_op<R::element_type, V1::element_type, V2::element_type> (v1, v2, OP, OP, OP, #F); \
79
}
80
81
#define VV_BIN_OPS(R, V1, V2) \
82
VV_BIN_OP (R, operator +, mx_inline_add, V1, V2) \
83
VV_BIN_OP (R, operator -, mx_inline_sub, V1, V2) \
84
VV_BIN_OP (R, product, mx_inline_mul, V1, V2) \
85
VV_BIN_OP (R, quotient, mx_inline_div, V1, V2)
86
87
// matrix by scalar operations.
88
89
#define MS_BIN_OP(R, OP, M, S, F) \
90
R \
91
OP (const M& m, const S& s) \
92
{ \
93
return do_ms_binary_op<R::element_type, M::element_type, S> (m, s, F); \
94
}
95
96
#define MS_BIN_OPS(R, M, S) \
97
MS_BIN_OP (R, operator +, M, S, mx_inline_add) \
98
MS_BIN_OP (R, operator -, M, S, mx_inline_sub) \
99
MS_BIN_OP (R, operator *, M, S, mx_inline_mul) \
100
MS_BIN_OP (R, operator /, M, S, mx_inline_div)
101
102
#define MS_CMP_OP(F, OP, M, S) \
103
boolMatrix \
104
F (const M& m, const S& s) \
105
{ \
106
return do_ms_binary_op<bool, M::element_type, S> (m, s, OP); \
107
}
108
109
#define MS_CMP_OPS(M, S) \
110
MS_CMP_OP (mx_el_lt, mx_inline_lt, M, S) \
111
MS_CMP_OP (mx_el_le, mx_inline_le, M, S) \
112
MS_CMP_OP (mx_el_ge, mx_inline_ge, M, S) \
113
MS_CMP_OP (mx_el_gt, mx_inline_gt, M, S) \
114
MS_CMP_OP (mx_el_eq, mx_inline_eq, M, S) \
115
MS_CMP_OP (mx_el_ne, mx_inline_ne, M, S)
116
117
#define MS_BOOL_OP(F, OP, M, S) \
118
boolMatrix \
119
F (const M& m, const S& s) \
120
{ \
121
MNANCHK (m, M::element_type); \
122
SNANCHK (s); \
123
return do_ms_binary_op<bool, M::element_type, S> (m, s, OP); \
124
}
125
126
#define MS_BOOL_OPS(M, S) \
127
MS_BOOL_OP (mx_el_and, mx_inline_and, M, S) \
128
MS_BOOL_OP (mx_el_or, mx_inline_or, M, S)
129
130
// scalar by matrix operations.
131
132
#define SM_BIN_OP(R, OP, S, M, F) \
133
R \
134
OP (const S& s, const M& m) \
135
{ \
136
return do_sm_binary_op<R::element_type, S, M::element_type> (s, m, F); \
137
}
138
139
#define SM_BIN_OPS(R, S, M) \
140
SM_BIN_OP (R, operator +, S, M, mx_inline_add) \
141
SM_BIN_OP (R, operator -, S, M, mx_inline_sub) \
142
SM_BIN_OP (R, operator *, S, M, mx_inline_mul) \
143
SM_BIN_OP (R, operator /, S, M, mx_inline_div)
144
145
#define SM_CMP_OP(F, OP, S, M) \
146
boolMatrix \
147
F (const S& s, const M& m) \
148
{ \
149
return do_sm_binary_op<bool, S, M::element_type> (s, m, OP); \
150
}
151
152
#define SM_CMP_OPS(S, M) \
153
SM_CMP_OP (mx_el_lt, mx_inline_lt, S, M) \
154
SM_CMP_OP (mx_el_le, mx_inline_le, S, M) \
155
SM_CMP_OP (mx_el_ge, mx_inline_ge, S, M) \
156
SM_CMP_OP (mx_el_gt, mx_inline_gt, S, M) \
157
SM_CMP_OP (mx_el_eq, mx_inline_eq, S, M) \
158
SM_CMP_OP (mx_el_ne, mx_inline_ne, S, M)
159
160
#define SM_BOOL_OP(F, OP, S, M) \
161
boolMatrix \
162
F (const S& s, const M& m) \
163
{ \
164
SNANCHK (s); \
165
MNANCHK (m, M::element_type); \
166
return do_sm_binary_op<bool, S, M::element_type> (s, m, OP); \
167
}
168
169
#define SM_BOOL_OPS(S, M) \
170
SM_BOOL_OP (mx_el_and, mx_inline_and, S, M) \
171
SM_BOOL_OP (mx_el_or, mx_inline_or, S, M)
172
173
// matrix by matrix operations.
174
175
#define MM_BIN_OP(R, OP, M1, M2, F) \
176
R \
177
OP (const M1& m1, const M2& m2) \
178
{ \
179
return do_mm_binary_op<R::element_type, M1::element_type, M2::element_type> (m1, m2, F, F, F, #OP); \
180
}
181
182
#define MM_BIN_OPS(R, M1, M2) \
183
MM_BIN_OP (R, operator +, M1, M2, mx_inline_add) \
184
MM_BIN_OP (R, operator -, M1, M2, mx_inline_sub) \
185
MM_BIN_OP (R, product, M1, M2, mx_inline_mul) \
186
MM_BIN_OP (R, quotient, M1, M2, mx_inline_div)
187
188
#define MM_CMP_OP(F, OP, M1, M2) \
189
boolMatrix \
190
F (const M1& m1, const M2& m2) \
191
{ \
192
return do_mm_binary_op<bool, M1::element_type, M2::element_type> (m1, m2, OP, OP, OP, #F); \
193
}
194
195
#define MM_CMP_OPS(M1, M2) \
196
MM_CMP_OP (mx_el_lt, mx_inline_lt, M1, M2) \
197
MM_CMP_OP (mx_el_le, mx_inline_le, M1, M2) \
198
MM_CMP_OP (mx_el_ge, mx_inline_ge, M1, M2) \
199
MM_CMP_OP (mx_el_gt, mx_inline_gt, M1, M2) \
200
MM_CMP_OP (mx_el_eq, mx_inline_eq, M1, M2) \
201
MM_CMP_OP (mx_el_ne, mx_inline_ne, M1, M2)
202
203
#define MM_BOOL_OP(F, OP, M1, M2) \
204
boolMatrix \
205
F (const M1& m1, const M2& m2) \
206
{ \
207
MNANCHK (m1, M1::element_type); \
208
MNANCHK (m2, M2::element_type); \
209
return do_mm_binary_op<bool, M1::element_type, M2::element_type> (m1, m2, OP, OP, OP, #F); \
210
}
211
212
#define MM_BOOL_OPS(M1, M2) \
213
MM_BOOL_OP (mx_el_and, mx_inline_and, M1, M2) \
214
MM_BOOL_OP (mx_el_or, mx_inline_or, M1, M2)
215
216
// N-D matrix by scalar operations.
217
218
#define NDS_BIN_OP(R, OP, ND, S, F) \
219
R \
220
OP (const ND& m, const S& s) \
221
{ \
222
return do_ms_binary_op<R::element_type, ND::element_type, S> (m, s, F); \
223
}
224
225
#define NDS_BIN_OPS(R, ND, S) \
226
NDS_BIN_OP (R, operator +, ND, S, mx_inline_add) \
227
NDS_BIN_OP (R, operator -, ND, S, mx_inline_sub) \
228
NDS_BIN_OP (R, operator *, ND, S, mx_inline_mul) \
229
NDS_BIN_OP (R, operator /, ND, S, mx_inline_div)
230
231
#define NDS_CMP_OP(F, OP, ND, S) \
232
boolNDArray \
233
F (const ND& m, const S& s) \
234
{ \
235
return do_ms_binary_op<bool, ND::element_type, S> (m, s, OP); \
236
}
237
238
#define NDS_CMP_OPS(ND, S) \
239
NDS_CMP_OP (mx_el_lt, mx_inline_lt, ND, S) \
240
NDS_CMP_OP (mx_el_le, mx_inline_le, ND, S) \
241
NDS_CMP_OP (mx_el_ge, mx_inline_ge, ND, S) \
242
NDS_CMP_OP (mx_el_gt, mx_inline_gt, ND, S) \
243
NDS_CMP_OP (mx_el_eq, mx_inline_eq, ND, S) \
244
NDS_CMP_OP (mx_el_ne, mx_inline_ne, ND, S)
245
246
#define NDS_BOOL_OP(F, OP, ND, S) \
247
boolNDArray \
248
F (const ND& m, const S& s) \
249
{ \
250
MNANCHK (m, ND::element_type); \
251
SNANCHK (s); \
252
return do_ms_binary_op<bool, ND::element_type, S> (m, s, OP); \
253
}
254
255
#define NDS_BOOL_OPS(ND, S) \
256
NDS_BOOL_OP (mx_el_and, mx_inline_and, ND, S) \
257
NDS_BOOL_OP (mx_el_or, mx_inline_or, ND, S) \
258
NDS_BOOL_OP (mx_el_not_and, mx_inline_not_and, ND, S) \
259
NDS_BOOL_OP (mx_el_not_or, mx_inline_not_or, ND, S) \
260
NDS_BOOL_OP (mx_el_and_not, mx_inline_and_not, ND, S) \
261
NDS_BOOL_OP (mx_el_or_not, mx_inline_or_not, ND, S)
262
263
// scalar by N-D matrix operations.
264
265
#define SND_BIN_OP(R, OP, S, ND, F) \
266
R \
267
OP (const S& s, const ND& m) \
268
{ \
269
return do_sm_binary_op<R::element_type, S, ND::element_type> (s, m, F); \
270
}
271
272
#define SND_BIN_OPS(R, S, ND) \
273
SND_BIN_OP (R, operator +, S, ND, mx_inline_add) \
274
SND_BIN_OP (R, operator -, S, ND, mx_inline_sub) \
275
SND_BIN_OP (R, operator *, S, ND, mx_inline_mul) \
276
SND_BIN_OP (R, operator /, S, ND, mx_inline_div)
277
278
#define SND_CMP_OP(F, OP, S, ND) \
279
boolNDArray \
280
F (const S& s, const ND& m) \
281
{ \
282
return do_sm_binary_op<bool, S, ND::element_type> (s, m, OP); \
283
}
284
285
#define SND_CMP_OPS(S, ND) \
286
SND_CMP_OP (mx_el_lt, mx_inline_lt, S, ND) \
287
SND_CMP_OP (mx_el_le, mx_inline_le, S, ND) \
288
SND_CMP_OP (mx_el_ge, mx_inline_ge, S, ND) \
289
SND_CMP_OP (mx_el_gt, mx_inline_gt, S, ND) \
290
SND_CMP_OP (mx_el_eq, mx_inline_eq, S, ND) \
291
SND_CMP_OP (mx_el_ne, mx_inline_ne, S, ND)
292
293
#define SND_BOOL_OP(F, OP, S, ND) \
294
boolNDArray \
295
F (const S& s, const ND& m) \
296
{ \
297
SNANCHK (s); \
298
MNANCHK (m, ND::element_type); \
299
return do_sm_binary_op<bool, S, ND::element_type> (s, m, OP); \
300
}
301
302
#define SND_BOOL_OPS(S, ND) \
303
SND_BOOL_OP (mx_el_and, mx_inline_and, S, ND) \
304
SND_BOOL_OP (mx_el_or, mx_inline_or, S, ND) \
305
SND_BOOL_OP (mx_el_not_and, mx_inline_not_and, S, ND) \
306
SND_BOOL_OP (mx_el_not_or, mx_inline_not_or, S, ND) \
307
SND_BOOL_OP (mx_el_and_not, mx_inline_and_not, S, ND) \
308
SND_BOOL_OP (mx_el_or_not, mx_inline_or_not, S, ND)
309
310
// N-D matrix by N-D matrix operations.
311
312
#define NDND_BIN_OP(R, OP, ND1, ND2, F) \
313
R \
314
OP (const ND1& m1, const ND2& m2) \
315
{ \
316
return do_mm_binary_op<R::element_type, ND1::element_type, ND2::element_type> (m1, m2, F, F, F, #OP); \
317
}
318
319
#define NDND_BIN_OPS(R, ND1, ND2) \
320
NDND_BIN_OP (R, operator +, ND1, ND2, mx_inline_add) \
321
NDND_BIN_OP (R, operator -, ND1, ND2, mx_inline_sub) \
322
NDND_BIN_OP (R, product, ND1, ND2, mx_inline_mul) \
323
NDND_BIN_OP (R, quotient, ND1, ND2, mx_inline_div)
324
325
#define NDND_CMP_OP(F, OP, ND1, ND2) \
326
boolNDArray \
327
F (const ND1& m1, const ND2& m2) \
328
{ \
329
return do_mm_binary_op<bool, ND1::element_type, ND2::element_type> (m1, m2, OP, OP, OP, #F); \
330
}
331
332
#define NDND_CMP_OPS(ND1, ND2) \
333
NDND_CMP_OP (mx_el_lt, mx_inline_lt, ND1, ND2) \
334
NDND_CMP_OP (mx_el_le, mx_inline_le, ND1, ND2) \
335
NDND_CMP_OP (mx_el_ge, mx_inline_ge, ND1, ND2) \
336
NDND_CMP_OP (mx_el_gt, mx_inline_gt, ND1, ND2) \
337
NDND_CMP_OP (mx_el_eq, mx_inline_eq, ND1, ND2) \
338
NDND_CMP_OP (mx_el_ne, mx_inline_ne, ND1, ND2)
339
340
#define NDND_BOOL_OP(F, OP, ND1, ND2) \
341
boolNDArray \
342
F (const ND1& m1, const ND2& m2) \
343
{ \
344
MNANCHK (m1, ND1::element_type); \
345
MNANCHK (m2, ND2::element_type); \
346
return do_mm_binary_op<bool, ND1::element_type, ND2::element_type> (m1, m2, OP, OP, OP, #F); \
347
}
348
349
#define NDND_BOOL_OPS(ND1, ND2) \
350
NDND_BOOL_OP (mx_el_and, mx_inline_and, ND1, ND2) \
351
NDND_BOOL_OP (mx_el_or, mx_inline_or, ND1, ND2) \
352
NDND_BOOL_OP (mx_el_not_and, mx_inline_not_and, ND1, ND2) \
353
NDND_BOOL_OP (mx_el_not_or, mx_inline_not_or, ND1, ND2) \
354
NDND_BOOL_OP (mx_el_and_not, mx_inline_and_not, ND1, ND2) \
355
NDND_BOOL_OP (mx_el_or_not, mx_inline_or_not, ND1, ND2)
356
357
// scalar by diagonal matrix operations.
358
359
#define SDM_BIN_OP(R, OP, S, DM) \
360
R \
361
operator OP (const S& s, const DM& dm) \
362
{ \
363
R r (dm.rows (), dm.cols ()); \
364
\
365
for (octave_idx_type i = 0; i < dm.length (); i++) \
366
r.dgxelem (i) = s OP dm.dgelem (i); \
367
\
368
return r; \
369
}
370
371
#define SDM_BIN_OPS(R, S, DM) \
372
SDM_BIN_OP (R, *, S, DM)
373
374
// diagonal matrix by scalar operations.
375
376
#define DMS_BIN_OP(R, OP, DM, S) \
377
R \
378
operator OP (const DM& dm, const S& s) \
379
{ \
380
R r (dm.rows (), dm.cols ()); \
381
\
382
for (octave_idx_type i = 0; i < dm.length (); i++) \
383
r.dgxelem (i) = dm.dgelem (i) OP s; \
384
\
385
return r; \
386
}
387
388
#define DMS_BIN_OPS(R, DM, S) \
389
DMS_BIN_OP (R, *, DM, S) \
390
DMS_BIN_OP (R, /, DM, S)
391
392
// matrix by diagonal matrix operations.
393
394
#define MDM_BIN_OP(R, OP, M, DM, OPEQ) \
395
R \
396
OP (const M& m, const DM& dm) \
397
{ \
398
R r; \
399
\
400
octave_idx_type m_nr = m.rows (); \
401
octave_idx_type m_nc = m.cols (); \
402
\
403
octave_idx_type dm_nr = dm.rows (); \
404
octave_idx_type dm_nc = dm.cols (); \
405
\
406
if (m_nr != dm_nr || m_nc != dm_nc) \
407
octave::err_nonconformant (#OP, m_nr, m_nc, dm_nr, dm_nc); \
408
\
409
r.resize (m_nr, m_nc); \
410
\
411
if (m_nr > 0 && m_nc > 0) \
412
{ \
413
r = R (m); \
414
\
415
octave_idx_type len = dm.length (); \
416
\
417
for (octave_idx_type i = 0; i < len; i++) \
418
r.elem (i, i) OPEQ dm.elem (i, i); \
419
} \
420
\
421
return r; \
422
}
423
424
#define MDM_MULTIPLY_OP(R, M, DM, R_ZERO) \
425
R \
426
operator * (const M& m, const DM& dm) \
427
{ \
428
R r; \
429
\
430
octave_idx_type m_nr = m.rows (); \
431
octave_idx_type m_nc = m.cols (); \
432
\
433
octave_idx_type dm_nr = dm.rows (); \
434
octave_idx_type dm_nc = dm.cols (); \
435
\
436
if (m_nc != dm_nr) \
437
octave::err_nonconformant ("operator *", m_nr, m_nc, dm_nr, dm_nc); \
438
\
439
r = R (m_nr, dm_nc); \
440
R::element_type *rd = r.fortran_vec (); \
441
const M::element_type *md = m.data (); \
442
const DM::element_type *dd = dm.data (); \
443
\
444
octave_idx_type len = dm.length (); \
445
for (octave_idx_type i = 0; i < len; i++) \
446
{ \
447
mx_inline_mul (m_nr, rd, md, dd[i]); \
448
rd += m_nr; md += m_nr; \
449
} \
450
mx_inline_fill (m_nr * (dm_nc - len), rd, R_ZERO); \
451
\
452
return r; \
453
}
454
455
#define MDM_BIN_OPS(R, M, DM, R_ZERO) \
456
MDM_BIN_OP (R, operator +, M, DM, +=) \
457
MDM_BIN_OP (R, operator -, M, DM, -=) \
458
MDM_MULTIPLY_OP (R, M, DM, R_ZERO)
459
460
// diagonal matrix by matrix operations.
461
462
#define DMM_BIN_OP(R, OP, DM, M, OPEQ, PREOP) \
463
R \
464
OP (const DM& dm, const M& m) \
465
{ \
466
R r; \
467
\
468
octave_idx_type dm_nr = dm.rows (); \
469
octave_idx_type dm_nc = dm.cols (); \
470
\
471
octave_idx_type m_nr = m.rows (); \
472
octave_idx_type m_nc = m.cols (); \
473
\
474
if (dm_nr != m_nr || dm_nc != m_nc) \
475
octave::err_nonconformant (#OP, dm_nr, dm_nc, m_nr, m_nc); \
476
else \
477
{ \
478
if (m_nr > 0 && m_nc > 0) \
479
{ \
480
r = R (PREOP m); \
481
\
482
octave_idx_type len = dm.length (); \
483
\
484
for (octave_idx_type i = 0; i < len; i++) \
485
r.elem (i, i) OPEQ dm.elem (i, i); \
486
} \
487
else \
488
r.resize (m_nr, m_nc); \
489
} \
490
\
491
return r; \
492
}
493
494
#define DMM_MULTIPLY_OP(R, DM, M, R_ZERO) \
495
R \
496
operator * (const DM& dm, const M& m) \
497
{ \
498
R r; \
499
\
500
octave_idx_type dm_nr = dm.rows (); \
501
octave_idx_type dm_nc = dm.cols (); \
502
\
503
octave_idx_type m_nr = m.rows (); \
504
octave_idx_type m_nc = m.cols (); \
505
\
506
if (dm_nc != m_nr) \
507
octave::err_nonconformant ("operator *", dm_nr, dm_nc, m_nr, m_nc); \
508
\
509
r = R (dm_nr, m_nc); \
510
R::element_type *rd = r.fortran_vec (); \
511
const M::element_type *md = m.data (); \
512
const DM::element_type *dd = dm.data (); \
513
\
514
octave_idx_type len = dm.length (); \
515
for (octave_idx_type i = 0; i < m_nc; i++) \
516
{ \
517
mx_inline_mul (len, rd, md, dd); \
518
rd += len; md += m_nr; \
519
mx_inline_fill (dm_nr - len, rd, R_ZERO); \
520
rd += dm_nr - len; \
521
} \
522
\
523
return r; \
524
}
525
526
#define DMM_BIN_OPS(R, DM, M, R_ZERO) \
527
DMM_BIN_OP (R, operator +, DM, M, +=, ) \
528
DMM_BIN_OP (R, operator -, DM, M, +=, -) \
529
DMM_MULTIPLY_OP (R, DM, M, R_ZERO)
530
531
// diagonal matrix by diagonal matrix operations.
532
533
#define DMDM_BIN_OP(R, OP, DM1, DM2, F) \
534
R \
535
OP (const DM1& dm1, const DM2& dm2) \
536
{ \
537
R r; \
538
\
539
octave_idx_type dm1_nr = dm1.rows (); \
540
octave_idx_type dm1_nc = dm1.cols (); \
541
\
542
octave_idx_type dm2_nr = dm2.rows (); \
543
octave_idx_type dm2_nc = dm2.cols (); \
544
\
545
if (dm1_nr != dm2_nr || dm1_nc != dm2_nc) \
546
octave::err_nonconformant (#OP, dm1_nr, dm1_nc, dm2_nr, dm2_nc); \
547
\
548
r.resize (dm1_nr, dm1_nc); \
549
\
550
if (dm1_nr > 0 && dm1_nc > 0) \
551
F (dm1.length (), r.fortran_vec (), dm1.data (), dm2.data ()); \
552
\
553
return r; \
554
}
555
556
#define DMDM_BIN_OPS(R, DM1, DM2) \
557
DMDM_BIN_OP (R, operator +, DM1, DM2, mx_inline_add) \
558
DMDM_BIN_OP (R, operator -, DM1, DM2, mx_inline_sub) \
559
DMDM_BIN_OP (R, product, DM1, DM2, mx_inline_mul)
560
561
// scalar by N-D array min/max ops
562
563
#define SND_MINMAX_FCN(FCN, OP, T, S) \
564
T \
565
FCN (S d, const T& m) \
566
{ \
567
return do_sm_binary_op<T::element_type, S, T::element_type> (d, m, mx_inline_x##FCN); \
568
}
569
570
#define NDS_MINMAX_FCN(FCN, OP, T, S) \
571
T \
572
FCN (const T& m, S d) \
573
{ \
574
return do_ms_binary_op<T::element_type, T::element_type, S> (m, d, mx_inline_x##FCN); \
575
}
576
577
#define NDND_MINMAX_FCN(FCN, OP, T, S) \
578
T \
579
FCN (const T& a, const T& b) \
580
{ \
581
return do_mm_binary_op<T::element_type, T::element_type, T::element_type> (a, b, mx_inline_x##FCN, mx_inline_x##FCN, mx_inline_x##FCN, #FCN); \
582
}
583
584
#define MINMAX_FCNS(T, S) \
585
SND_MINMAX_FCN (min, <, T, S) \
586
NDS_MINMAX_FCN (min, <, T, S) \
587
NDND_MINMAX_FCN (min, <, T, S) \
588
SND_MINMAX_FCN (max, >, T, S) \
589
NDS_MINMAX_FCN (max, >, T, S) \
590
NDND_MINMAX_FCN (max, >, T, S)
591
592
// permutation matrix by matrix ops and vice versa
593
594
#define PMM_MULTIPLY_OP(PM, M) \
595
M operator * (const PM& p, const M& x) \
596
{ \
597
octave_idx_type nr = x.rows (); \
598
octave_idx_type nc = x.columns (); \
599
M result; \
600
if (p.columns () != nr) \
601
octave::err_nonconformant ("operator *", p.rows (), p.columns (), nr, nc); \
602
else \
603
{ \
604
result = M (nr, nc); \
605
result.assign (p.col_perm_vec (), idx_vector::colon, x); \
606
} \
607
\
608
return result; \
609
}
610
611
#define MPM_MULTIPLY_OP(M, PM) \
612
M operator * (const M& x, const PM& p) \
613
{ \
614
octave_idx_type nr = x.rows (); \
615
octave_idx_type nc = x.columns (); \
616
M result; \
617
if (p.rows () != nc) \
618
octave::err_nonconformant ("operator *", nr, nc, p.rows (), p.columns ()); \
619
\
620
result = x.index (idx_vector::colon, p.col_perm_vec ()); \
621
\
622
return result; \
623
}
624
625
#define PMM_BIN_OPS(R, PM, M) \
626
PMM_MULTIPLY_OP(PM, M);
627
628
#define MPM_BIN_OPS(R, M, PM) \
629
MPM_MULTIPLY_OP(M, PM);
630
631
#define NDND_MAPPER_BODY(R, NAME) \
632
R retval (dims ()); \
633
octave_idx_type n = numel (); \
634
for (octave_idx_type i = 0; i < n; i++) \
635
retval.xelem (i) = NAME (elem (i)); \
636
return retval;
637
638
#endif
lo-array-errwarn.h
mx-op-decl.h
mx-inlines.cc
Generated on Wed May 10 2017 15:42:59 for GNU Octave by
1.8.8