1 // SPDX-License-Identifier: Apache-2.0
2 //
3 // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
4 // Copyright 2008-2016 National ICT Australia (NICTA)
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 // ------------------------------------------------------------------------
17
18
19 //! \addtogroup fn_join
20 //! @{
21
22
23
24 template<typename T1, typename T2>
25 arma_warn_unused
26 inline
27 typename
28 enable_if2
29 <
30 (is_arma_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
31 const Glue<T1, T2, glue_join_cols>
32 >::result
join_cols(const T1 & A,const T2 & B)33 join_cols(const T1& A, const T2& B)
34 {
35 arma_extra_debug_sigprint();
36
37 return Glue<T1, T2, glue_join_cols>(A, B);
38 }
39
40
41
42 template<typename eT, typename T1, typename T2, typename T3>
43 arma_warn_unused
44 inline
45 Mat<eT>
join_cols(const Base<eT,T1> & A,const Base<eT,T2> & B,const Base<eT,T3> & C)46 join_cols(const Base<eT,T1>& A, const Base<eT,T2>& B, const Base<eT,T3>& C)
47 {
48 arma_extra_debug_sigprint();
49
50 Mat<eT> out;
51
52 glue_join_cols::apply(out, A.get_ref(), B.get_ref(), C.get_ref());
53
54 return out;
55 }
56
57
58
59 template<typename eT, typename T1, typename T2, typename T3, typename T4>
60 arma_warn_unused
61 inline
62 Mat<eT>
join_cols(const Base<eT,T1> & A,const Base<eT,T2> & B,const Base<eT,T3> & C,const Base<eT,T4> & D)63 join_cols(const Base<eT,T1>& A, const Base<eT,T2>& B, const Base<eT,T3>& C, const Base<eT,T4>& D)
64 {
65 arma_extra_debug_sigprint();
66
67 Mat<eT> out;
68
69 glue_join_cols::apply(out, A.get_ref(), B.get_ref(), C.get_ref(), D.get_ref());
70
71 return out;
72 }
73
74
75
76 template<typename T1, typename T2>
77 arma_warn_unused
78 inline
79 typename
80 enable_if2
81 <
82 (is_arma_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
83 const Glue<T1, T2, glue_join_cols>
84 >::result
join_vert(const T1 & A,const T2 & B)85 join_vert(const T1& A, const T2& B)
86 {
87 arma_extra_debug_sigprint();
88
89 return Glue<T1, T2, glue_join_cols>(A, B);
90 }
91
92
93
94 template<typename eT, typename T1, typename T2, typename T3>
95 arma_warn_unused
96 inline
97 Mat<eT>
join_vert(const Base<eT,T1> & A,const Base<eT,T2> & B,const Base<eT,T3> & C)98 join_vert(const Base<eT,T1>& A, const Base<eT,T2>& B, const Base<eT,T3>& C)
99 {
100 arma_extra_debug_sigprint();
101
102 Mat<eT> out;
103
104 glue_join_cols::apply(out, A.get_ref(), B.get_ref(), C.get_ref());
105
106 return out;
107 }
108
109
110
111 template<typename eT, typename T1, typename T2, typename T3, typename T4>
112 arma_warn_unused
113 inline
114 Mat<eT>
join_vert(const Base<eT,T1> & A,const Base<eT,T2> & B,const Base<eT,T3> & C,const Base<eT,T4> & D)115 join_vert(const Base<eT,T1>& A, const Base<eT,T2>& B, const Base<eT,T3>& C, const Base<eT,T4>& D)
116 {
117 arma_extra_debug_sigprint();
118
119 Mat<eT> out;
120
121 glue_join_cols::apply(out, A.get_ref(), B.get_ref(), C.get_ref(), D.get_ref());
122
123 return out;
124 }
125
126
127
128 template<typename T1, typename T2>
129 arma_warn_unused
130 inline
131 typename
132 enable_if2
133 <
134 (is_arma_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
135 const Glue<T1, T2, glue_join_rows>
136 >::result
join_rows(const T1 & A,const T2 & B)137 join_rows(const T1& A, const T2& B)
138 {
139 arma_extra_debug_sigprint();
140
141 return Glue<T1, T2, glue_join_rows>(A, B);
142 }
143
144
145
146 template<typename eT, typename T1, typename T2, typename T3>
147 arma_warn_unused
148 inline
149 Mat<eT>
join_rows(const Base<eT,T1> & A,const Base<eT,T2> & B,const Base<eT,T3> & C)150 join_rows(const Base<eT,T1>& A, const Base<eT,T2>& B, const Base<eT,T3>& C)
151 {
152 arma_extra_debug_sigprint();
153
154 Mat<eT> out;
155
156 glue_join_rows::apply(out, A.get_ref(), B.get_ref(), C.get_ref());
157
158 return out;
159 }
160
161
162
163 template<typename eT, typename T1, typename T2, typename T3, typename T4>
164 arma_warn_unused
165 inline
166 Mat<eT>
join_rows(const Base<eT,T1> & A,const Base<eT,T2> & B,const Base<eT,T3> & C,const Base<eT,T4> & D)167 join_rows(const Base<eT,T1>& A, const Base<eT,T2>& B, const Base<eT,T3>& C, const Base<eT,T4>& D)
168 {
169 arma_extra_debug_sigprint();
170
171 Mat<eT> out;
172
173 glue_join_rows::apply(out, A.get_ref(), B.get_ref(), C.get_ref(), D.get_ref());
174
175 return out;
176 }
177
178
179
180 template<typename T1, typename T2>
181 arma_warn_unused
182 inline
183 typename
184 enable_if2
185 <
186 (is_arma_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
187 const Glue<T1, T2, glue_join_rows>
188 >::result
join_horiz(const T1 & A,const T2 & B)189 join_horiz(const T1& A, const T2& B)
190 {
191 arma_extra_debug_sigprint();
192
193 return Glue<T1, T2, glue_join_rows>(A, B);
194 }
195
196
197
198 template<typename eT, typename T1, typename T2, typename T3>
199 arma_warn_unused
200 inline
201 Mat<eT>
join_horiz(const Base<eT,T1> & A,const Base<eT,T2> & B,const Base<eT,T3> & C)202 join_horiz(const Base<eT,T1>& A, const Base<eT,T2>& B, const Base<eT,T3>& C)
203 {
204 arma_extra_debug_sigprint();
205
206 Mat<eT> out;
207
208 glue_join_rows::apply(out, A.get_ref(), B.get_ref(), C.get_ref());
209
210 return out;
211 }
212
213
214
215 template<typename eT, typename T1, typename T2, typename T3, typename T4>
216 arma_warn_unused
217 inline
218 Mat<eT>
join_horiz(const Base<eT,T1> & A,const Base<eT,T2> & B,const Base<eT,T3> & C,const Base<eT,T4> & D)219 join_horiz(const Base<eT,T1>& A, const Base<eT,T2>& B, const Base<eT,T3>& C, const Base<eT,T4>& D)
220 {
221 arma_extra_debug_sigprint();
222
223 Mat<eT> out;
224
225 glue_join_rows::apply(out, A.get_ref(), B.get_ref(), C.get_ref(), D.get_ref());
226
227 return out;
228 }
229
230
231
232 //
233 // for cubes
234
235 template<typename T1, typename T2>
236 arma_warn_unused
237 inline
238 const GlueCube<T1, T2, glue_join_slices>
join_slices(const BaseCube<typename T1::elem_type,T1> & A,const BaseCube<typename T1::elem_type,T2> & B)239 join_slices(const BaseCube<typename T1::elem_type,T1>& A, const BaseCube<typename T1::elem_type,T2>& B)
240 {
241 arma_extra_debug_sigprint();
242
243 return GlueCube<T1, T2, glue_join_slices>(A.get_ref(), B.get_ref());
244 }
245
246
247
248 template<typename T1, typename T2>
249 arma_warn_unused
250 inline
251 Cube<typename T1::elem_type>
join_slices(const Base<typename T1::elem_type,T1> & A,const Base<typename T1::elem_type,T2> & B)252 join_slices(const Base<typename T1::elem_type,T1>& A, const Base<typename T1::elem_type,T2>& B)
253 {
254 arma_extra_debug_sigprint();
255
256 typedef typename T1::elem_type eT;
257
258 const quasi_unwrap<T1> UA(A.get_ref());
259 const quasi_unwrap<T2> UB(B.get_ref());
260
261 arma_debug_assert_same_size(UA.M.n_rows, UA.M.n_cols, UB.M.n_rows, UB.M.n_cols, "join_slices(): incompatible dimensions");
262
263 Cube<eT> out(UA.M.n_rows, UA.M.n_cols, 2, arma_nozeros_indicator());
264
265 arrayops::copy(out.slice_memptr(0), UA.M.memptr(), UA.M.n_elem);
266 arrayops::copy(out.slice_memptr(1), UB.M.memptr(), UB.M.n_elem);
267
268 return out;
269 }
270
271
272
273 template<typename T1, typename T2>
274 arma_warn_unused
275 inline
276 Cube<typename T1::elem_type>
join_slices(const Base<typename T1::elem_type,T1> & A,const BaseCube<typename T1::elem_type,T2> & B)277 join_slices(const Base<typename T1::elem_type,T1>& A, const BaseCube<typename T1::elem_type,T2>& B)
278 {
279 arma_extra_debug_sigprint();
280
281 typedef typename T1::elem_type eT;
282
283 const quasi_unwrap<T1> U(A.get_ref());
284
285 const Cube<eT> M(const_cast<eT*>(U.M.memptr()), U.M.n_rows, U.M.n_cols, 1, false);
286
287 return join_slices(M,B);
288 }
289
290
291
292 template<typename T1, typename T2>
293 arma_warn_unused
294 inline
295 Cube<typename T1::elem_type>
join_slices(const BaseCube<typename T1::elem_type,T1> & A,const Base<typename T1::elem_type,T2> & B)296 join_slices(const BaseCube<typename T1::elem_type,T1>& A, const Base<typename T1::elem_type,T2>& B)
297 {
298 arma_extra_debug_sigprint();
299
300 typedef typename T1::elem_type eT;
301
302 const quasi_unwrap<T2> U(B.get_ref());
303
304 const Cube<eT> M(const_cast<eT*>(U.M.memptr()), U.M.n_rows, U.M.n_cols, 1, false);
305
306 return join_slices(A,M);
307 }
308
309
310
311 //
312 // for sparse matrices
313
314 template<typename T1, typename T2>
315 arma_warn_unused
316 inline
317 const SpGlue<T1, T2, spglue_join_cols>
join_cols(const SpBase<typename T1::elem_type,T1> & A,const SpBase<typename T1::elem_type,T2> & B)318 join_cols(const SpBase<typename T1::elem_type,T1>& A, const SpBase<typename T1::elem_type,T2>& B)
319 {
320 arma_extra_debug_sigprint();
321
322 return SpGlue<T1, T2, spglue_join_cols>(A.get_ref(), B.get_ref());
323 }
324
325
326
327 template<typename eT, typename T1, typename T2, typename T3>
328 arma_warn_unused
329 inline
330 SpMat<eT>
join_cols(const SpBase<eT,T1> & A,const SpBase<eT,T2> & B,const SpBase<eT,T3> & C)331 join_cols(const SpBase<eT,T1>& A, const SpBase<eT,T2>& B, const SpBase<eT,T3>& C)
332 {
333 arma_extra_debug_sigprint();
334
335 SpMat<eT> out;
336
337 spglue_join_cols::apply(out, A.get_ref(), B.get_ref(), C.get_ref());
338
339 return out;
340 }
341
342
343
344 template<typename eT, typename T1, typename T2, typename T3, typename T4>
345 arma_warn_unused
346 inline
347 SpMat<eT>
join_cols(const SpBase<eT,T1> & A,const SpBase<eT,T2> & B,const SpBase<eT,T3> & C,const SpBase<eT,T4> & D)348 join_cols(const SpBase<eT,T1>& A, const SpBase<eT,T2>& B, const SpBase<eT,T3>& C, const SpBase<eT,T4>& D)
349 {
350 arma_extra_debug_sigprint();
351
352 SpMat<eT> out;
353
354 spglue_join_cols::apply(out, A.get_ref(), B.get_ref(), C.get_ref(), D.get_ref());
355
356 return out;
357 }
358
359
360
361 template<typename T1, typename T2>
362 arma_warn_unused
363 inline
364 const SpGlue<T1, T2, spglue_join_cols>
join_vert(const SpBase<typename T1::elem_type,T1> & A,const SpBase<typename T1::elem_type,T2> & B)365 join_vert(const SpBase<typename T1::elem_type,T1>& A, const SpBase<typename T1::elem_type,T2>& B)
366 {
367 arma_extra_debug_sigprint();
368
369 return SpGlue<T1, T2, spglue_join_cols>(A.get_ref(), B.get_ref());
370 }
371
372
373
374 template<typename eT, typename T1, typename T2, typename T3>
375 arma_warn_unused
376 inline
377 SpMat<eT>
join_vert(const SpBase<eT,T1> & A,const SpBase<eT,T2> & B,const SpBase<eT,T3> & C)378 join_vert(const SpBase<eT,T1>& A, const SpBase<eT,T2>& B, const SpBase<eT,T3>& C)
379 {
380 arma_extra_debug_sigprint();
381
382 SpMat<eT> out;
383
384 spglue_join_cols::apply(out, A.get_ref(), B.get_ref(), C.get_ref());
385
386 return out;
387 }
388
389
390
391 template<typename eT, typename T1, typename T2, typename T3, typename T4>
392 arma_warn_unused
393 inline
394 SpMat<eT>
join_vert(const SpBase<eT,T1> & A,const SpBase<eT,T2> & B,const SpBase<eT,T3> & C,const SpBase<eT,T4> & D)395 join_vert(const SpBase<eT,T1>& A, const SpBase<eT,T2>& B, const SpBase<eT,T3>& C, const SpBase<eT,T4>& D)
396 {
397 arma_extra_debug_sigprint();
398
399 SpMat<eT> out;
400
401 spglue_join_cols::apply(out, A.get_ref(), B.get_ref(), C.get_ref(), D.get_ref());
402
403 return out;
404 }
405
406
407
408 template<typename T1, typename T2>
409 arma_warn_unused
410 inline
411 const SpGlue<T1, T2, spglue_join_rows>
join_rows(const SpBase<typename T1::elem_type,T1> & A,const SpBase<typename T1::elem_type,T2> & B)412 join_rows(const SpBase<typename T1::elem_type,T1>& A, const SpBase<typename T1::elem_type,T2>& B)
413 {
414 arma_extra_debug_sigprint();
415
416 return SpGlue<T1, T2, spglue_join_rows>(A.get_ref(), B.get_ref());
417 }
418
419
420
421 template<typename eT, typename T1, typename T2, typename T3>
422 arma_warn_unused
423 inline
424 SpMat<eT>
join_rows(const SpBase<eT,T1> & A,const SpBase<eT,T2> & B,const SpBase<eT,T3> & C)425 join_rows(const SpBase<eT,T1>& A, const SpBase<eT,T2>& B, const SpBase<eT,T3>& C)
426 {
427 arma_extra_debug_sigprint();
428
429 SpMat<eT> out;
430
431 spglue_join_rows::apply(out, A.get_ref(), B.get_ref(), C.get_ref());
432
433 return out;
434 }
435
436
437
438 template<typename eT, typename T1, typename T2, typename T3, typename T4>
439 arma_warn_unused
440 inline
441 SpMat<eT>
join_rows(const SpBase<eT,T1> & A,const SpBase<eT,T2> & B,const SpBase<eT,T3> & C,const SpBase<eT,T4> & D)442 join_rows(const SpBase<eT,T1>& A, const SpBase<eT,T2>& B, const SpBase<eT,T3>& C, const SpBase<eT,T4>& D)
443 {
444 arma_extra_debug_sigprint();
445
446 SpMat<eT> out;
447
448 spglue_join_rows::apply(out, A.get_ref(), B.get_ref(), C.get_ref(), D.get_ref());
449
450 return out;
451 }
452
453
454
455 template<typename T1, typename T2>
456 arma_warn_unused
457 inline
458 const SpGlue<T1, T2, spglue_join_rows>
join_horiz(const SpBase<typename T1::elem_type,T1> & A,const SpBase<typename T1::elem_type,T2> & B)459 join_horiz(const SpBase<typename T1::elem_type,T1>& A, const SpBase<typename T1::elem_type,T2>& B)
460 {
461 arma_extra_debug_sigprint();
462
463 return SpGlue<T1, T2, spglue_join_rows>(A.get_ref(), B.get_ref());
464 }
465
466
467
468 template<typename eT, typename T1, typename T2, typename T3>
469 arma_warn_unused
470 inline
471 SpMat<eT>
join_horiz(const SpBase<eT,T1> & A,const SpBase<eT,T2> & B,const SpBase<eT,T3> & C)472 join_horiz(const SpBase<eT,T1>& A, const SpBase<eT,T2>& B, const SpBase<eT,T3>& C)
473 {
474 arma_extra_debug_sigprint();
475
476 SpMat<typename T1::elem_type> out;
477
478 spglue_join_rows::apply(out, A.get_ref(), B.get_ref(), C.get_ref());
479
480 return out;
481 }
482
483
484
485 template<typename eT, typename T1, typename T2, typename T3, typename T4>
486 arma_warn_unused
487 inline
488 SpMat<eT>
join_horiz(const SpBase<eT,T1> & A,const SpBase<eT,T2> & B,const SpBase<eT,T3> & C,const SpBase<eT,T4> & D)489 join_horiz(const SpBase<eT,T1>& A, const SpBase<eT,T2>& B, const SpBase<eT,T3>& C, const SpBase<eT,T4>& D)
490 {
491 arma_extra_debug_sigprint();
492
493 SpMat<eT> out;
494
495 spglue_join_rows::apply(out, A.get_ref(), B.get_ref(), C.get_ref(), D.get_ref());
496
497 return out;
498 }
499
500
501
502 //! @}
503