ARTS  2.3.1285(git:92a29ea9-dirty)
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 */
42 template <class T>
43 void 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 
69 /* Implementation for array types to append single element */
70 template <class T>
71 void Append( // WS Generic Output:
72  Array<T>& out,
73  const String& /* out_name */,
74  // WS Generic Input:
75  const T& in,
76  const String& direction _U_,
77  const String& /* in_name */,
78  const String& /* direction_name */,
79  const Verbosity&) {
80  // Append in to end of out:
81  out.push_back(in);
82 }
83 
84 /* Implementation for array types to append single element */
85 inline void Append(Workspace& ws,
86  // WS Generic Output:
87  ArrayOfAgenda& out,
88  const String& out_name,
89  // WS Generic Input:
90  const Agenda& in,
91  const String& direction _U_,
92  const String& /* in_name */,
93  const String& /* direction_name */,
94  const Verbosity& verbosity) {
95  // Append in to end of out:
96  out.push_back(in);
97  out[out.nelem() - 1].set_name(out_name);
98  out[out.nelem() - 1].check(ws, verbosity);
99 }
100 
101 /* Implementation for array types to append single element */
102 inline void Append(Workspace& ws,
103  // WS Generic Output:
104  ArrayOfAgenda& out,
105  const String& out_name,
106  // WS Generic Input:
107  const ArrayOfAgenda& in,
108  const String& direction _U_,
109  const String& /* in_name */,
110  const String& /* direction_name */,
111  const Verbosity& verbosity) {
112  // Append in to end of out:
113  for (ArrayOfAgenda::const_iterator it = in.begin(); it != in.end(); it++) {
114  out.push_back(*it);
115  out[out.nelem() - 1].set_name(out_name);
116  out[out.nelem() - 1].check(ws, verbosity);
117  }
118 }
119 
120 /* Implementation for Vector */
121 inline void Append( // WS Generic Output:
122  Vector& out,
123  const String& /* out_name */,
124  // WS Generic Input:
125  const Vector& in,
126  const String& direction _U_,
127  const String& /* in_name */,
128  const String& /* direction_name */,
129  const Verbosity&) {
130  const Vector* in_pnt;
131  Vector in_copy;
132 
133  if (&in == &out) {
134  in_copy = in;
135  in_pnt = &in_copy;
136  } else
137  in_pnt = &in;
138 
139  const Vector& in_ref = *in_pnt;
140 
141  // Get backup of out:
142  Vector dummy = out;
143 
144  // Make out the right size:
145  out.resize(dummy.nelem() + in_ref.nelem());
146 
147  // Copy dummy to first part of out:
148  if (dummy.nelem()) out[Range(0, dummy.nelem())] = dummy;
149 
150  // Copy in to last part of out:
151  if (in_ref.nelem()) out[Range(dummy.nelem(), in_ref.nelem())] = in_ref;
152 }
153 
154 /* Implementation for Matrix */
155 inline void Append( // WS Generic Output:
156  Matrix& out,
157  const String& /* out_name */,
158  // WS Generic Input:
159  const Matrix& in,
160  const String& direction,
161  const String& /* in_name */,
162  const String& /* direction_name */,
163  const Verbosity&) {
164  const Matrix* in_pnt;
165  Matrix in_copy;
166 
167  if (&in == &out) {
168  in_copy = in;
169  in_pnt = &in_copy;
170  } else
171  in_pnt = &in;
172 
173  const Matrix& in_ref = *in_pnt;
174 
175  // Get backup of out:
176  Matrix dummy = out;
177 
178  if (!out.nrows() || !out.ncols()) {
179  out = in_ref;
180  } else if (direction == "leading") {
181  if (out.ncols() != in_ref.ncols())
182  throw runtime_error(
183  "Input and output matrix must have the same number of columns.");
184 
185  out.resize(dummy.nrows() + in_ref.nrows(), dummy.ncols());
186 
187  if (dummy.nrows() && dummy.ncols())
188  out(Range(0, dummy.nrows()), Range(0, dummy.ncols())) = dummy;
189  if (dummy.nrows() && in_ref.nrows() && in_ref.ncols())
190  out(Range(dummy.nrows(), in_ref.nrows()), Range(0, in_ref.ncols())) =
191  in_ref;
192  } else if (direction == "trailing") {
193  if (out.nrows() != in_ref.nrows())
194  throw runtime_error(
195  "Input and output matrix must have the same number of rows.");
196 
197  out.resize(dummy.nrows(), dummy.ncols() + in_ref.ncols());
198 
199  if (dummy.nrows() && dummy.ncols())
200  out(Range(0, dummy.nrows()), Range(0, dummy.ncols())) = dummy;
201  if (dummy.ncols() && in_ref.nrows() && in_ref.ncols())
202  out(Range(0, in_ref.nrows()), Range(dummy.ncols(), in_ref.ncols())) =
203  in_ref;
204  } else
205  throw runtime_error(
206  "Dimension must be either \"leading\" or \"trailing\".");
207 }
208 
209 /* Implementation for Matrix/Vector */
210 inline void Append( // WS Generic Output:
211  Matrix& out,
212  const String& /* out_name */,
213  // WS Generic Input:
214  const Vector& in,
215  const String& direction,
216  const String& /* in_name */,
217  const String& /* direction_name */,
218  const Verbosity&) {
219  // Get backup of out:
220  Matrix dummy = out;
221 
222  if (direction == "leading") {
223  if (!out.nrows() || !out.ncols()) {
224  out = in;
225  } else {
226  if (out.ncols() != in.nelem())
227  throw runtime_error(
228  "Number of elements in the input Vector has to match "
229  "the number of columns in the output Matrix.");
230 
231  out.resize(dummy.nrows() + 1, dummy.ncols());
232  out(Range(0, dummy.nrows()), Range(0, dummy.ncols())) = dummy;
233  out(Range(dummy.nrows(), 1), Range(0, in.nelem())) = transpose(in);
234  }
235  } else if (direction == "trailing") {
236  if (!out.nrows() || !out.ncols()) {
237  out = transpose(in);
238  } else if (in.nelem()) {
239  if (out.nrows() != in.nelem() && out.nrows() && out.ncols())
240  throw runtime_error(
241  "Number of elements in the input Vector has to match "
242  "the number of rows in the output Matrix.");
243 
244  out.resize(dummy.nrows(), dummy.ncols() + 1);
245  out(Range(0, dummy.nrows()), Range(0, dummy.ncols())) = dummy;
246  out(Range(0, in.nelem()), Range(dummy.ncols(), 1)) = in;
247  }
248  } else
249  throw runtime_error(
250  "Dimension must be either \"leading\" or \"trailing\".");
251 }
252 
253 /* Implementation for Vector/Numeric */
254 inline void Append( // WS Generic Output:
255  Vector& out,
256  const String& /* out_name */,
257  // WS Generic Input:
258  const Numeric& in,
259  const String& direction _U_,
260  const String& /* in_name */,
261  const String& /* direction_name */,
262  const Verbosity&) {
263  // Get backup of out:
264  Vector dummy = out;
265 
266  // Make out the right size:
267  out.resize(dummy.nelem() + 1);
268 
269  // Copy dummy to first part of out:
270  if (dummy.nelem()) out[Range(0, dummy.nelem())] = dummy;
271 
272  // Copy in to last part of out:
273  out[Range(dummy.nelem(), 1)] = in;
274 }
275 
276 /* Implementation for Tensor3/Matrix */
277 inline void Append( // WS Generic Output:
278  Tensor3& out,
279  const String& /* out_name */,
280  // WS Generic Input:
281  const Matrix& in,
282  // const String& direction,
283  const String& direction _U_,
284  const String& /* in_name */,
285  const String& /* direction_name */,
286  const Verbosity&) {
287  // Get backup of out:
288  Tensor3 dummy = out;
289 
290  if (!out.npages() || !out.nrows() || !out.ncols()) {
291  out.resize(1, in.nrows(), in.ncols());
292  out(0, joker, joker) = in;
293  } else {
294  if (out.nrows() != in.nrows() || out.ncols() != in.ncols())
295  throw runtime_error(
296  "Number of rows and columns in the input Matrix have to match\n"
297  "the number of rows and columns in the output Tensor3.");
298 
299  out.resize(dummy.npages() + 1, dummy.nrows(), dummy.ncols());
300  out(Range(0, dummy.npages()),
301  Range(0, dummy.nrows()),
302  Range(0, dummy.ncols())) = dummy;
303  out(dummy.npages(), Range(0, dummy.nrows()), Range(0, dummy.ncols())) = in;
304  }
305 }
306 
307 /* Implementation for Tensor3 */
308 inline void Append( // WS Generic Output:
309  Tensor3& out,
310  const String& /* out_name */,
311  // WS Generic Input:
312  const Tensor3& in,
313  // const String& direction,
314  const String& direction _U_,
315  const String& /* in_name */,
316  const String& /* direction_name */,
317  const Verbosity&) {
318  const Tensor3* in_pnt;
319  Tensor3 in_copy;
320 
321  if (&in == &out) {
322  in_copy = in;
323  in_pnt = &in_copy;
324  } else
325  in_pnt = &in;
326 
327  const Tensor3& in_ref = *in_pnt;
328 
329  // Get backup of out:
330  Tensor3 dummy = out;
331 
332  if (out.nrows() != in_ref.nrows() || out.ncols() != in_ref.ncols())
333  throw runtime_error(
334  "Tensor3 append is performed in pages dimension.\n"
335  "All other dimensions (rows, columns) must have identical\n"
336  "sizes in In and Out Tensor.");
337 
338  out.resize(dummy.npages() + in_ref.npages(), dummy.nrows(), dummy.ncols());
339 
340  if (dummy.npages() && dummy.nrows() && dummy.ncols())
341  out(Range(0, dummy.npages()),
342  Range(0, dummy.nrows()),
343  Range(0, dummy.ncols())) = dummy;
344  if (dummy.npages() && in_ref.npages() && in_ref.nrows() && in_ref.ncols())
345  out(Range(dummy.npages(), in_ref.npages()),
346  Range(0, in_ref.nrows()),
347  Range(0, in_ref.ncols())) = in_ref;
348 }
349 
350 /* Implementation for Tensor4/Tensor3 */
351 inline void Append( // WS Generic Output:
352  Tensor4& out,
353  const String& /* out_name */,
354  // WS Generic Input:
355  const Tensor3& in,
356  // const String& direction,
357  const String& direction _U_,
358  const String& /* in_name */,
359  const String& /* direction_name */,
360  const Verbosity&) {
361  // Get backup of out:
362  Tensor4 dummy = out;
363 
364  if (!out.nbooks() || !out.npages() || !out.nrows() || !out.ncols()) {
365  out.resize(1, in.npages(), in.nrows(), in.ncols());
366  out(0, joker, joker, joker) = in;
367  } else {
368  if (out.npages() != in.npages() || out.nrows() != in.nrows() ||
369  out.ncols() != in.ncols())
370  throw runtime_error(
371  "Dimensions of input Tensor3 have to match corresponding\n"
372  "dimensions in the output Tensor4.");
373 
374  out.resize(
375  dummy.nbooks() + 1, dummy.npages(), dummy.nrows(), dummy.ncols());
376  out(Range(0, dummy.nbooks()),
377  Range(0, dummy.npages()),
378  Range(0, dummy.nrows()),
379  Range(0, dummy.ncols())) = dummy;
380  out(dummy.nbooks(),
381  Range(0, dummy.npages()),
382  Range(0, dummy.nrows()),
383  Range(0, dummy.ncols())) = in;
384  }
385 }
386 
387 /* Implementation for Tensor4 */
388 inline void Append( // WS Generic Output:
389  Tensor4& out,
390  const String& /* out_name */,
391  // WS Generic Input:
392  const Tensor4& in,
393  // const String& direction,
394  const String& direction _U_,
395  const String& /* in_name */,
396  const String& /* direction_name */,
397  const Verbosity&) {
398  const Tensor4* in_pnt;
399  Tensor4 in_copy;
400 
401  if (&in == &out) {
402  in_copy = in;
403  in_pnt = &in_copy;
404  } else
405  in_pnt = &in;
406 
407  const Tensor4& in_ref = *in_pnt;
408 
409  // Get backup of out:
410  Tensor4 dummy = out;
411 
412  if (out.npages() != in_ref.npages() || out.nrows() != in_ref.nrows() ||
413  out.ncols() != in_ref.ncols())
414  throw runtime_error(
415  "Tensor4 append is performed in books dimension.\n"
416  "All other dimensions (pages, rows, columns) must have identical\n"
417  "sizes in In and Out Tensor.");
418 
419  out.resize(dummy.nbooks() + in_ref.nbooks(),
420  dummy.npages(),
421  dummy.nrows(),
422  dummy.ncols());
423 
424  if (dummy.nbooks() && dummy.npages() && dummy.nrows() && dummy.ncols())
425  out(Range(0, dummy.nbooks()),
426  Range(0, dummy.npages()),
427  Range(0, dummy.nrows()),
428  Range(0, dummy.ncols())) = dummy;
429  if (dummy.nbooks() && in_ref.nbooks() && in_ref.npages() && in_ref.nrows() &&
430  in_ref.ncols())
431  out(Range(dummy.nbooks(), in_ref.nbooks()),
432  Range(0, in_ref.npages()),
433  Range(0, in_ref.nrows()),
434  Range(0, in_ref.ncols())) = in_ref;
435 }
436 
437 /* Implementation for String */
438 inline void Append( // WS Generic Output:
439  String& out,
440  const String& /* out_name */,
441  // WS Generic Input:
442  const String& in,
443  const String& direction _U_,
444  const String& /* in_name */,
445  const String& /* direction_name */,
446  const Verbosity&) {
447  // String stream for easy string operations:
448  ostringstream os;
449 
450  os << out << in;
451 
452  out = os.str();
453 }
454 
455 #endif // m_append_h
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
The Agenda class.
Definition: agenda_class.h:44
Index nelem() const
Number of elements.
Definition: array.h:195
The Vector class.
Definition: matpackI.h:860
The Tensor4 class.
Definition: matpackIV.h:421
The range class.
Definition: matpackI.h:160
Index npages() const
Returns the number of pages.
Definition: matpackIV.cc:60
Index nrows() const
Returns the number of rows.
Definition: matpackIII.h:147
Index nrows() const
Returns the number of rows.
Definition: matpackIV.cc:63
Index nelem() const
Returns the number of elements.
Definition: matpackI.cc:51
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
This file contains the definition of Array.
Index ncols() const
Returns the number of columns.
Definition: matpackI.cc:432
The Tensor3 class.
Definition: matpackIII.h:339
_CS_string_type str() const
Definition: sstream.h:491
Index ncols() const
Returns the number of columns.
Definition: matpackIII.h:150
Declarations for agendas.
The declarations of all the exception classes.
const Joker joker
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
The Matrix class.
Definition: matpackI.h:1193
Implementation of Matrix, Vector, and such stuff.
void resize(Index p, Index r, Index c)
Resize function.
Definition: matpackIII.cc:664
Index npages() const
Returns the number of pages.
Definition: matpackIII.h:144
This can be used to make arrays out of anything.
Definition: array.h:40
ConstComplexMatrixView transpose(ConstComplexMatrixView m)
Const version of transpose.
Definition: complex.cc:1509
void resize(Index n)
Resize function.
Definition: matpackI.cc:404
Workspace class.
Definition: workspace_ng.h:40
Index nbooks() const
Returns the number of books.
Definition: matpackIV.cc:57
#define _U_
Definition: config.h:183
Index ncols() const
Returns the number of columns.
Definition: matpackIV.cc:66
Index nrows() const
Returns the number of rows.
Definition: matpackI.cc:429
void resize(Index b, Index p, Index r, Index c)
Resize function.
Definition: matpackIV.cc:1064
void resize(Index r, Index c)
Resize function.
Definition: matpackI.cc:1056