ARTS 2.5.10 (git: 2f1c442c)
m_append.h
Go to the documentation of this file.
1/* Copyright (C) 2002-2012 Stefan Buehler <sbuehler@ltu.se>
2
3 This program is free software; you can redistribute it and/or modify it
4 under the terms of the GNU General Public License as published by the
5 Free Software Foundation; either version 2, or (at your option) any
6 later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 USA. */
17
29#ifndef m_append_h
30#define m_append_h
31
32#include "agenda_class.h"
33#include "array.h"
34#include "exceptions.h"
35#include "matpackI.h"
36#include "matpackIII.h"
37#include "matpackVI.h"
38
39/* Implementations for supported types follow. */
40
41/* Implementation for array types */
42template <class T>
43void Append( // WS Generic Output:
44 Array<T>& out,
45 const String& /* out_name */,
46 // WS Generic Input:
47 const Array<T>& in,
48 const String& direction _U_,
49 const String& /* in_name */,
50 const String& /* direction_name */,
51 const Verbosity&) {
52 const Array<T>* in_pnt;
53 Array<T> in_copy;
54
55 if (&in == &out) {
56 in_copy = in;
57 in_pnt = &in_copy;
58 } else
59 in_pnt = &in;
60
61 const Array<T>& in_ref = *in_pnt;
62
63 // Reserve memory in advance to avoid reallocations:
64 out.reserve(out.nelem() + in_ref.nelem());
65 // Append in to end of out:
66 for (Index i = 0; i < in_ref.nelem(); ++i) out.push_back(in_ref[i]);
67}
68
69inline void Append( // WS Generic Output:
71 const String& /* out_name */,
72 // WS Generic Input:
73 const ArrayOfSpeciesTag& in,
74 const String& direction _U_,
75 const String& /* in_name */,
76 const String& /* direction_name */,
77 const Verbosity&) {
78 const ArrayOfSpeciesTag* in_pnt;
79 ArrayOfSpeciesTag in_copy;
80
81 if (&in == &out) {
82 in_copy = in;
83 in_pnt = &in_copy;
84 } else
85 in_pnt = &in;
86
87 const ArrayOfSpeciesTag& in_ref = *in_pnt;
88
89 // Reserve memory in advance to avoid reallocations:
90 out.reserve(out.nelem() + in_ref.nelem());
91 // Append in to end of out:
92 for (Index i = 0; i < in_ref.nelem(); ++i) out.push_back(in_ref[i]);
93}
94
95/* Implementation for array types to append single element */
96template <class T>
97void Append( // WS Generic Output:
98 Array<T>& out,
99 const String& /* out_name */,
100 // WS Generic Input:
101 const T& in,
102 const String& direction _U_,
103 const String& /* in_name */,
104 const String& /* direction_name */,
105 const Verbosity&) {
106 // Append in to end of out:
107 out.push_back(in);
108}
109
110/* Implementation for array types to append single element */
111inline void Append( // WS Generic Output:
113 const String& /* out_name */,
114 // WS Generic Input:
115 const SpeciesTag& in,
116 const String& direction _U_,
117 const String& /* in_name */,
118 const String& /* direction_name */,
119 const Verbosity&) {
120 // Append in to end of out:
121 out.push_back(in);
122}
123
124/* Implementation for array types to append single element */
125inline void Append(Workspace& ws,
126 // WS Generic Output:
127 ArrayOfAgenda& out,
128 const String& out_name,
129 // WS Generic Input:
130 const Agenda& in,
131 const String& direction _U_,
132 const String& /* in_name */,
133 const String& /* direction_name */,
134 const Verbosity& verbosity) {
135 // Append in to end of out:
136 auto& newag = out.emplace_back(in);
137 newag.set_name(out_name);
138 newag.check(ws, verbosity);
139}
140
141/* Implementation for array types to append single element */
142inline void Append(Workspace& ws_in,
143 // WS Generic Output:
144 ArrayOfAgenda& out,
145 const String& out_name,
146 // WS Generic Input:
147 const ArrayOfAgenda& in,
148 const String& direction _U_,
149 const String& /* in_name */,
150 const String& /* direction_name */,
151 const Verbosity& verbosity) {
152 // Append in to end of out:
153 for (const auto & it : in) {
154 auto& newag = out.emplace_back(it);
155 newag.set_name(out_name);
156 newag.check(ws_in, verbosity);
157 }
158}
159
160/* Implementation for Vector */
161inline void Append( // WS Generic Output:
162 Vector& out,
163 const String& /* out_name */,
164 // WS Generic Input:
165 const Vector& in,
166 const String& direction _U_,
167 const String& /* in_name */,
168 const String& /* direction_name */,
169 const Verbosity&) {
170 const Vector* in_pnt;
171 Vector in_copy;
172
173 if (&in == &out) {
174 in_copy = in;
175 in_pnt = &in_copy;
176 } else
177 in_pnt = &in;
178
179 const Vector& in_ref = *in_pnt;
180
181 // Get backup of out:
182 Vector dummy = out;
183
184 // Make out the right size:
185 out.resize(dummy.nelem() + in_ref.nelem());
186
187 // Copy dummy to first part of out:
188 if (dummy.nelem()) out[Range(0, dummy.nelem())] = dummy;
189
190 // Copy in to last part of out:
191 if (in_ref.nelem()) out[Range(dummy.nelem(), in_ref.nelem())] = in_ref;
192}
193
194/* Implementation for Matrix */
195inline void Append( // WS Generic Output:
196 Matrix& out,
197 const String& /* out_name */,
198 // WS Generic Input:
199 const Matrix& in,
200 const String& direction,
201 const String& /* in_name */,
202 const String& /* direction_name */,
203 const Verbosity&) {
204 const Matrix* in_pnt;
205 Matrix in_copy;
206
207 if (&in == &out) {
208 in_copy = in;
209 in_pnt = &in_copy;
210 } else
211 in_pnt = &in;
212
213 const Matrix& in_ref = *in_pnt;
214
215 // Get backup of out:
216 Matrix dummy = out;
217
218 if (!out.nrows() || !out.ncols()) {
219 out = in_ref;
220 } else if (direction == "leading") {
221 if (out.ncols() != in_ref.ncols())
222 throw runtime_error(
223 "Input and output matrix must have the same number of columns.");
224
225 out.resize(dummy.nrows() + in_ref.nrows(), dummy.ncols());
226
227 if (dummy.nrows() && dummy.ncols())
228 out(Range(0, dummy.nrows()), Range(0, dummy.ncols())) = dummy;
229 if (dummy.nrows() && in_ref.nrows() && in_ref.ncols())
230 out(Range(dummy.nrows(), in_ref.nrows()), Range(0, in_ref.ncols())) =
231 in_ref;
232 } else if (direction == "trailing") {
233 if (out.nrows() != in_ref.nrows())
234 throw runtime_error(
235 "Input and output matrix must have the same number of rows.");
236
237 out.resize(dummy.nrows(), dummy.ncols() + in_ref.ncols());
238
239 if (dummy.nrows() && dummy.ncols())
240 out(Range(0, dummy.nrows()), Range(0, dummy.ncols())) = dummy;
241 if (dummy.ncols() && in_ref.nrows() && in_ref.ncols())
242 out(Range(0, in_ref.nrows()), Range(dummy.ncols(), in_ref.ncols())) =
243 in_ref;
244 } else
245 throw runtime_error(
246 R"(Dimension must be either "leading" or "trailing".)");
247}
248
249/* Implementation for Matrix/Vector */
250inline void Append( // WS Generic Output:
251 Matrix& out,
252 const String& /* out_name */,
253 // WS Generic Input:
254 const Vector& in,
255 const String& direction,
256 const String& /* in_name */,
257 const String& /* direction_name */,
258 const Verbosity&) {
259 // Get backup of out:
260 Matrix dummy = out;
261
262 if (direction == "leading") {
263 if (!out.nrows() || !out.ncols()) {
264 out = in;
265 } else {
266 if (out.ncols() != in.nelem())
267 throw runtime_error(
268 "Number of elements in the input Vector has to match "
269 "the number of columns in the output Matrix.");
270
271 out.resize(dummy.nrows() + 1, dummy.ncols());
272 out(Range(0, dummy.nrows()), Range(0, dummy.ncols())) = dummy;
273 out(Range(dummy.nrows(), 1), Range(0, in.nelem())) = transpose(in);
274 }
275 } else if (direction == "trailing") {
276 if (!out.nrows() || !out.ncols()) {
277 out = transpose(in);
278 } else if (in.nelem()) {
279 if (out.nrows() != in.nelem() && out.nrows() && out.ncols())
280 throw runtime_error(
281 "Number of elements in the input Vector has to match "
282 "the number of rows in the output Matrix.");
283
284 out.resize(dummy.nrows(), dummy.ncols() + 1);
285 out(Range(0, dummy.nrows()), Range(0, dummy.ncols())) = dummy;
286 out(Range(0, in.nelem()), Range(dummy.ncols(), 1)) = in;
287 }
288 } else
289 throw runtime_error(
290 R"(Dimension must be either "leading" or "trailing".)");
291}
292
293/* Implementation for Vector/Numeric */
294inline void Append( // WS Generic Output:
295 Vector& out,
296 const String& /* out_name */,
297 // WS Generic Input:
298 const Numeric& in,
299 const String& direction _U_,
300 const String& /* in_name */,
301 const String& /* direction_name */,
302 const Verbosity&) {
303 // Get backup of out:
304 Vector dummy = out;
305
306 // Make out the right size:
307 out.resize(dummy.nelem() + 1);
308
309 // Copy dummy to first part of out:
310 if (dummy.nelem()) out[Range(0, dummy.nelem())] = dummy;
311
312 // Copy in to last part of out:
313 out[Range(dummy.nelem(), 1)] = in;
314}
315
316/* Implementation for Tensor3/Matrix */
317inline void Append( // WS Generic Output:
318 Tensor3& out,
319 const String& /* out_name */,
320 // WS Generic Input:
321 const Matrix& in,
322 // const String& direction,
323 const String& direction _U_,
324 const String& /* in_name */,
325 const String& /* direction_name */,
326 const Verbosity&) {
327 // Get backup of out:
328 Tensor3 dummy = out;
329
330 if (!out.npages() || !out.nrows() || !out.ncols()) {
331 out.resize(1, in.nrows(), in.ncols());
332 out(0, joker, joker) = in;
333 } else {
334 if (out.nrows() != in.nrows() || out.ncols() != in.ncols())
335 throw runtime_error(
336 "Number of rows and columns in the input Matrix have to match\n"
337 "the number of rows and columns in the output Tensor3.");
338
339 out.resize(dummy.npages() + 1, dummy.nrows(), dummy.ncols());
340 out(Range(0, dummy.npages()),
341 Range(0, dummy.nrows()),
342 Range(0, dummy.ncols())) = dummy;
343 out(dummy.npages(), Range(0, dummy.nrows()), Range(0, dummy.ncols())) = in;
344 }
345}
346
347/* Implementation for Tensor3 */
348inline void Append( // WS Generic Output:
349 Tensor3& out,
350 const String& /* out_name */,
351 // WS Generic Input:
352 const Tensor3& in,
353 // const String& direction,
354 const String& direction _U_,
355 const String& /* in_name */,
356 const String& /* direction_name */,
357 const Verbosity&) {
358 const Tensor3* in_pnt;
359 Tensor3 in_copy;
360
361 if (&in == &out) {
362 in_copy = in;
363 in_pnt = &in_copy;
364 } else
365 in_pnt = &in;
366
367 const Tensor3& in_ref = *in_pnt;
368
369 // Get backup of out:
370 Tensor3 dummy = out;
371
372 if (out.nrows() != in_ref.nrows() || out.ncols() != in_ref.ncols())
373 throw runtime_error(
374 "Tensor3 append is performed in pages dimension.\n"
375 "All other dimensions (rows, columns) must have identical\n"
376 "sizes in In and Out Tensor.");
377
378 out.resize(dummy.npages() + in_ref.npages(), dummy.nrows(), dummy.ncols());
379
380 if (dummy.npages() && dummy.nrows() && dummy.ncols())
381 out(Range(0, dummy.npages()),
382 Range(0, dummy.nrows()),
383 Range(0, dummy.ncols())) = dummy;
384 if (dummy.npages() && in_ref.npages() && in_ref.nrows() && in_ref.ncols())
385 out(Range(dummy.npages(), in_ref.npages()),
386 Range(0, in_ref.nrows()),
387 Range(0, in_ref.ncols())) = in_ref;
388}
389
390/* Implementation for Tensor4/Tensor3 */
391inline void Append( // WS Generic Output:
392 Tensor4& out,
393 const String& /* out_name */,
394 // WS Generic Input:
395 const Tensor3& in,
396 // const String& direction,
397 const String& direction _U_,
398 const String& /* in_name */,
399 const String& /* direction_name */,
400 const Verbosity&) {
401 // Get backup of out:
402 Tensor4 dummy = out;
403
404 if (!out.nbooks() || !out.npages() || !out.nrows() || !out.ncols()) {
405 out.resize(1, in.npages(), in.nrows(), in.ncols());
406 out(0, joker, joker, joker) = in;
407 } else {
408 if (out.npages() != in.npages() || out.nrows() != in.nrows() ||
409 out.ncols() != in.ncols())
410 throw runtime_error(
411 "Dimensions of input Tensor3 have to match corresponding\n"
412 "dimensions in the output Tensor4.");
413
414 out.resize(
415 dummy.nbooks() + 1, dummy.npages(), dummy.nrows(), dummy.ncols());
416 out(Range(0, dummy.nbooks()),
417 Range(0, dummy.npages()),
418 Range(0, dummy.nrows()),
419 Range(0, dummy.ncols())) = dummy;
420 out(dummy.nbooks(),
421 Range(0, dummy.npages()),
422 Range(0, dummy.nrows()),
423 Range(0, dummy.ncols())) = in;
424 }
425}
426
427/* Implementation for Tensor4 */
428inline void Append( // WS Generic Output:
429 Tensor4& out,
430 const String& /* out_name */,
431 // WS Generic Input:
432 const Tensor4& in,
433 // const String& direction,
434 const String& direction _U_,
435 const String& /* in_name */,
436 const String& /* direction_name */,
437 const Verbosity&) {
438 const Tensor4* in_pnt;
439 Tensor4 in_copy;
440
441 if (&in == &out) {
442 in_copy = in;
443 in_pnt = &in_copy;
444 } else
445 in_pnt = &in;
446
447 const Tensor4& in_ref = *in_pnt;
448
449 // Get backup of out:
450 Tensor4 dummy = out;
451
452 if (out.npages() != in_ref.npages() || out.nrows() != in_ref.nrows() ||
453 out.ncols() != in_ref.ncols())
454 throw runtime_error(
455 "Tensor4 append is performed in books dimension.\n"
456 "All other dimensions (pages, rows, columns) must have identical\n"
457 "sizes in In and Out Tensor.");
458
459 out.resize(dummy.nbooks() + in_ref.nbooks(),
460 dummy.npages(),
461 dummy.nrows(),
462 dummy.ncols());
463
464 if (dummy.nbooks() && dummy.npages() && dummy.nrows() && dummy.ncols())
465 out(Range(0, dummy.nbooks()),
466 Range(0, dummy.npages()),
467 Range(0, dummy.nrows()),
468 Range(0, dummy.ncols())) = dummy;
469 if (dummy.nbooks() && in_ref.nbooks() && in_ref.npages() && in_ref.nrows() &&
470 in_ref.ncols())
471 out(Range(dummy.nbooks(), in_ref.nbooks()),
472 Range(0, in_ref.npages()),
473 Range(0, in_ref.nrows()),
474 Range(0, in_ref.ncols())) = in_ref;
475}
476
477/* Implementation for String */
478inline void Append( // WS Generic Output:
479 String& out,
480 const String& /* out_name */,
481 // WS Generic Input:
482 const String& in,
483 const String& direction _U_,
484 const String& /* in_name */,
485 const String& /* direction_name */,
486 const Verbosity&) {
487 // String stream for easy string operations:
488 ostringstream os;
489
490 os << out << in;
491
492 out = os.str();
493}
494
495#endif // m_append_h
Declarations for agendas.
This file contains the definition of Array.
The Agenda class.
Definition: agenda_class.h:69
This can be used to make arrays out of anything.
Definition: array.h:48
Index nelem() const ARTS_NOEXCEPT
Definition: array.h:92
Index nrows() const noexcept
Definition: matpackI.h:1079
Index ncols() const noexcept
Definition: matpackI.h:1080
Index npages() const
Returns the number of pages.
Definition: matpackIII.h:145
Index nrows() const
Returns the number of rows.
Definition: matpackIII.h:148
Index ncols() const
Returns the number of columns.
Definition: matpackIII.h:151
Index ncols() const noexcept
Definition: matpackIV.h:146
Index nrows() const noexcept
Definition: matpackIV.h:145
Index nbooks() const noexcept
Definition: matpackIV.h:143
Index npages() const noexcept
Definition: matpackIV.h:144
Index nelem() const noexcept
Returns the number of elements.
Definition: matpackI.h:547
The Matrix class.
Definition: matpackI.h:1285
void resize(Index r, Index c)
Resize function.
Definition: matpackI.cc:1011
The range class.
Definition: matpackI.h:160
The Tensor3 class.
Definition: matpackIII.h:352
void resize(Index p, Index r, Index c)
Resize function.
Definition: matpackIII.cc:661
The Tensor4 class.
Definition: matpackIV.h:435
void resize(Index b, Index p, Index r, Index c)
Resize function.
Definition: matpackIV.cc:1054
The Vector class.
Definition: matpackI.h:910
void resize(Index n)
Resize function.
Definition: matpackI.cc:390
Workspace class.
Definition: workspace_ng.h:53
#define _U_
Definition: config.h:180
The declarations of all the exception classes.
void Append(Array< T > &out, const String &, const Array< T > &in, const String &direction, const String &, const String &, const Verbosity &)
Definition: m_append.h:43
Implementation of Matrix, Vector, and such stuff.
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
ConstComplexMatrixView transpose(ConstComplexMatrixView m)
Const version of transpose.
const Joker joker
Species::Tag SpeciesTag
Definition: species_tags.h:100