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