ARTS  2.3.1285(git:92a29ea9-dirty)
m_basic_types.cc
Go to the documentation of this file.
1 /* Copyright (C) 2002-2012
2  Patrick Eriksson <Patrick.Eriksson@chalmers.se>
3  Stefan Buehler <sbuehler@ltu.se>
4 
5  This program is free software; you can redistribute it and/or modify it
6  under the terms of the GNU General Public License as published by the
7  Free Software Foundation; either version 2, or (at your option) any
8  later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18  USA. */
19 
20 /*===========================================================================
21  === File description
22  ===========================================================================*/
23 
41 /*===========================================================================
42  === External declarations
43  ===========================================================================*/
44 
45 #include <cmath>
46 #include "array.h"
47 #include "arts.h"
48 #include "energylevelmap.h"
49 #include "exceptions.h"
50 #include "gridded_fields.h"
51 #include "lin_alg.h"
52 #include "logic.h"
53 #include "math_funcs.h"
54 #include "matpackI.h"
55 #include "matpackII.h"
56 #include "matpackIII.h"
57 #include "matpackIV.h"
58 #include "matpackV.h"
59 #include "matpackVI.h"
60 #include "matpackVII.h"
61 #include "messages.h"
62 #include "mystring.h"
63 #include "optproperties.h"
64 #include "quantum.h"
65 #include "sorting.h"
66 
67 /*===========================================================================
68  === The functions (in alphabetical order)
69  ===========================================================================*/
70 
71 /* Workspace method: Doxygen documentation will be auto-generated */
73  const ArrayOfIndex& values,
74  const Verbosity&) {
75  aoi = values;
76 }
77 
78 /* Workspace method: Doxygen documentation will be auto-generated */
80  const Index& nelem,
81  const Index& value,
82  const Verbosity&) {
83  aoi.resize(nelem);
84  for (Index i = 0; i < nelem; i++) aoi[i] = value;
85 }
86 
87 /* Workspace method: Doxygen documentation will be auto-generated */
89  const Index& start,
90  const Index& stop,
91  const Index& step,
92  const Verbosity& verbosity) {
95 
96  Index n = (Index)floor((stop - start) / step) + 1;
97  if (n < 1) n = 1;
98 
99  x.resize(n);
100 
101  for (Index i = 0; i < n; i++) x[i] = start + i * step;
102 
103  out2 << " Creating a linearly spaced ArrayOfIndex.\n";
104  out3 << " length : " << x.nelem() << "\n";
105  out3 << " first value : " << x[0] << "\n";
106 
107  if (x.nelem() > 1) {
108  out3 << " step size : " << x[1] - x[0] << "\n";
109  out3 << " last value : " << x[x.nelem() - 1] << "\n";
110  }
111 }
112 
113 /* Workspace method: Doxygen documentation will be auto-generated */
115  const ArrayOfString& sa2,
116  const Verbosity&) {
117  sa.resize(sa2.nelem());
118  sa = sa2;
119 }
120 
121 /* Workspace method: Doxygen documentation will be auto-generated */
122 void FlagOff(Index& x, const Verbosity&) { x = 0; }
123 
124 /* Workspace method: Doxygen documentation will be auto-generated */
125 void FlagOn(Index& x, const Verbosity&) { x = 1; }
126 
127 /* Workspace method: Doxygen documentation will be auto-generated */
128 void IndexAdd(Index& out,
129  const Index& in,
130  const Index& value,
131  const Verbosity&) {
132  out = value + in;
133 }
134 
135 /* Workspace method: Doxygen documentation will be auto-generated */
136 void IndexSet(Index& x, const Index& value, const Verbosity&) { x = value; }
137 
138 /* Workspace method: Doxygen documentation will be auto-generated */
139 void IndexStepDown(Index& xout, const Index& xin, const Verbosity&) {
140  xout = xin - 1;
141 }
142 
143 /* Workspace method: Doxygen documentation will be auto-generated */
144 void IndexStepUp(Index& xout, const Index& xin, const Verbosity&) {
145  xout = xin + 1;
146 }
147 
148 /* Workspace method: Doxygen documentation will be auto-generated */
150  const Matrix& in,
151  const Numeric& value,
152  const Verbosity&) {
153  // Note that in and out can be the same vector
154  if (&out == &in) {
155  // Out and in are the same. Just add the scalar value.
156  out += value;
157  } else {
158  // Out and in are different. We first have to copy in to out,
159  // then add the scalar value.
160  out.resize(in.nrows(), in.ncols());
161  out = in;
162  out += value;
163  }
164 }
165 
166 /* Workspace method: Doxygen documentation will be auto-generated */
167 void MatrixCopySparse(Matrix& out, const Sparse& in, const Verbosity&) {
168  // There is probably a more efficient way to do this
169  out.resize(in.nrows(), in.ncols());
170  for (Index r = 0; r < in.nrows(); r++) {
171  for (Index c = 0; c < in.ncols(); c++) {
172  out(r, c) = in(r, c);
173  }
174  }
175 }
176 
177 /* Workspace method: Doxygen documentation will be auto-generated */
179  // WS Generic Output:
180  Matrix& m,
181  // WS Input:
182  // WS Generic Input:
183  const Tensor3& t3,
184  const Index& index,
185  // Control Parameters:
186  const String& direction,
187  const Verbosity&) {
188  if (direction == "page") {
189  if (index >= t3.npages()) {
190  ostringstream os;
191  os << "The index " << index
192  << " is outside the page range of the Matrix.";
193  throw runtime_error(os.str());
194  }
195 
196  m.resize(t3.nrows(), t3.ncols());
197  m = t3(index, joker, joker);
198  } else if (direction == "row") {
199  if (index >= t3.nrows()) {
200  ostringstream os;
201  os << "The index " << index << " is outside the row range of the Matrix.";
202  throw runtime_error(os.str());
203  }
204 
205  m.resize(t3.npages(), t3.ncols());
206  m = t3(joker, index, joker);
207  } else if (direction == "column") {
208  if (index >= t3.ncols()) {
209  ostringstream os;
210  os << "The index " << index
211  << " is outside the column range of the Matrix.";
212  throw runtime_error(os.str());
213  }
214 
215  m.resize(t3.npages(), t3.nrows());
216  m = t3(joker, joker, index);
217  } else {
218  ostringstream os;
219  os << "Keyword *direction* must be either *page* or *row* or *column*,"
220  << "but you gave: " << direction << ".";
221  throw runtime_error(os.str());
222  }
223 }
224 
225 /* Workspace method: Doxygen documentation will be auto-generated */
226 void MatrixMatrixMultiply( // WS Generic Output:
227  Matrix& Y,
228  // WS Generic Input:
229  const Matrix& M,
230  const Matrix& X,
231  const Verbosity&) {
232  // Check that dimensions are right, M.ncols() must match X.nrows():
233  if (M.ncols() != X.nrows()) {
234  ostringstream os;
235  os << "Matrix dimensions must be consistent!\n"
236  << "Matrix1.ncols() = " << M.ncols() << "\n"
237  << "Matrix2.nrows() = " << X.nrows();
238  throw runtime_error(os.str());
239  }
240 
241  // Temporary for the result:
242  Matrix dummy(M.nrows(), X.ncols());
243 
244  mult(dummy, M, X);
245 
246  // Copy result to Y:
247 
248  Y.resize(dummy.nrows(), dummy.ncols());
249 
250  Y = dummy;
251 }
252 
253 /* Workspace method: Doxygen documentation will be auto-generated */
254 void MatrixVectorMultiply( // WS Generic Output:
255  Vector& Y,
256  // WS Generic Input:
257  const Matrix& M,
258  const Vector& X,
259  const Verbosity&) {
260  // Check that dimensions are right, M.ncols() must match X.nrows():
261  if (M.ncols() != X.nelem()) {
262  ostringstream os;
263  os << "Matrix and vector dimensions must be consistent!\n"
264  << "Matrix.ncols() = " << M.ncols() << "\n"
265  << "Vector.nelem() = " << X.nelem();
266  throw runtime_error(os.str());
267  }
268 
269  // Temporary for the result:
270  Vector dummy(M.nrows());
271 
272  mult(dummy, M, X);
273 
274  // Copy result to Y:
275  Y = dummy;
276 }
277 
278 /* Workspace method: Doxygen documentation will be auto-generated */
279 void Matrix1ColFromVector( // WS Generic Output:
280  Matrix& m,
281  // WS Generic Input:
282  const Vector& v,
283  const Verbosity&) {
284  const Index nv = v.nelem();
285 
286  m.resize(nv, 1);
287  m(joker, 0) = v;
288 }
289 
290 /* Workspace method: Doxygen documentation will be auto-generated */
291 void Matrix2ColFromVectors( // WS Generic Output:
292  Matrix& m,
293  // WS Generic Input:
294  const Vector& v1,
295  const Vector& v2,
296  const Verbosity&) {
297  const Index nv = v1.nelem();
298 
299  if (v2.nelem() != nv)
300  throw runtime_error("Vectors must be of the same size.");
301 
302  m.resize(nv, 2);
303  m(joker, 0) = v1;
304  m(joker, 1) = v2;
305 }
306 
307 /* Workspace method: Doxygen documentation will be auto-generated */
308 void Matrix3ColFromVectors( // WS Generic Output:
309  Matrix& m,
310  // WS Generic Input:
311  const Vector& v1,
312  const Vector& v2,
313  const Vector& v3,
314  const Verbosity&) {
315  const Index nv = v1.nelem();
316 
317  if (v3.nelem() != nv || v2.nelem() != nv)
318  throw runtime_error("Vectors must be of the same size.");
319 
320  m.resize(nv, 3);
321  m(joker, 0) = v1;
322  m(joker, 1) = v2;
323  m(joker, 2) = v3;
324 }
325 
326 /* Workspace method: Doxygen documentation will be auto-generated */
327 void Matrix1RowFromVector( // WS Generic Output:
328  Matrix& m,
329  // WS Generic Input:
330  const Vector& v,
331  const Verbosity&) {
332  const Index nv = v.nelem();
333 
334  m.resize(1, nv);
335  m(0, joker) = v;
336 }
337 
338 /* Workspace method: Doxygen documentation will be auto-generated */
339 void Matrix2RowFromVectors( // WS Generic Output:
340  Matrix& m,
341  // WS Generic Input:
342  const Vector& v1,
343  const Vector& v2,
344  const Verbosity&) {
345  const Index nv = v1.nelem();
346 
347  if (v2.nelem() != nv)
348  throw runtime_error("Vectors must be of the same size.");
349 
350  m.resize(2, nv);
351  m(0, joker) = v1;
352  m(1, joker) = v2;
353 }
354 
355 /* Workspace method: Doxygen documentation will be auto-generated */
356 void Matrix3RowFromVectors( // WS Generic Output:
357  Matrix& m,
358  // WS Generic Input:
359  const Vector& v1,
360  const Vector& v2,
361  const Vector& v3,
362  const Verbosity&) {
363  const Index nv = v1.nelem();
364 
365  if (v3.nelem() != nv || v2.nelem() != nv)
366  throw runtime_error("Vectors must be of the same size.");
367 
368  m.resize(3, nv);
369  m(0, joker) = v1;
370  m(1, joker) = v2;
371  m(2, joker) = v3;
372 }
373 
374 /* Workspace method: Doxygen documentation will be auto-generated */
376  const Index& n,
377  const Numeric& value,
378  const Verbosity&) {
379  out.resize(n, n);
380  id_mat(out);
381  if (value != 1) {
382  out *= value;
383  }
384 }
385 
386 /* Workspace method: Doxygen documentation will be auto-generated */
387 void MatrixScale(Matrix& out,
388  const Matrix& in,
389  const Numeric& value,
390  const Verbosity&) {
391  // Note that in and out can be the same matrix
392  if (&out == &in) {
393  // Out and in are the same. Just multiply by the scalar value.
394  out *= value;
395  } else {
396  // Out and in are different. We first have to copy in to out,
397  // then multiply by the scalar value.
398  out.resize(in.nrows(), in.ncols());
399  out = in;
400  out *= value;
401  }
402 }
403 
404 /* Workspace method: Doxygen documentation will be auto-generated */
405 void MatrixSet(Matrix& x, const Matrix& values, const Verbosity&) {
406  x = values;
407 }
408 
409 /* Workspace method: Doxygen documentation will be auto-generated */
411  const Index& nrows,
412  const Index& ncols,
413  const Numeric& value,
414  const Verbosity&) {
415  x.resize(nrows, ncols);
416  x = value;
417 }
418 
419 /* Workspace method: Doxygen documentation will be auto-generated */
420 void NumericAdd(Numeric& out,
421  const Numeric& in,
422  const Numeric& value,
423  const Verbosity&) {
424  out = value + in;
425 }
426 
427 /* Workspace method: Doxygen documentation will be auto-generated */
429  const Vector& in,
430  const String& op,
431  const Verbosity&) {
432  if (op == "first")
433  out = in[0];
434  else if (op == "last")
435  out = in[in.nelem() - 1];
436  else if (op == "max")
437  out = max(in);
438  else if (op == "min")
439  out = min(in);
440  else if (op == "mean")
441  out = mean(in);
442  else {
443  ostringstream os;
444  os << "Your choice, *op* = \"" << op << "\", is not recognised.\n"
445  << "Valid options are: \"first\", \"last\", \"max\", \"min\" and \"mean\".";
446  throw runtime_error(os.str());
447  }
448 }
449 
450 /* Workspace method: Doxygen documentation will be auto-generated */
452  const Numeric& in,
453  const Numeric& value,
454  const Verbosity&) {
455  out = in / value;
456 }
457 
458 /* Workspace method: Doxygen documentation will be auto-generated */
460  const Numeric& in,
461  const Numeric& value,
462  const Verbosity&) {
463  out = value * in;
464 }
465 
466 /* Workspace method: Doxygen documentation will be auto-generated */
467 void NumericSet(Numeric& x, const Numeric& value, const Verbosity&) {
468  x = value;
469 }
470 
471 /* Workspace method: Doxygen documentation will be auto-generated */
473  const String& value,
474  const Verbosity&) {
475  x = QuantumIdentifier(value);
476 }
477 
478 /* Workspace method: Doxygen documentation will be auto-generated */
480  const ArrayOfString& values,
481  const Verbosity& verbosity) {
482  x.resize(values.nelem());
483  for (Index i = 0; i < x.nelem(); i++)
484  QuantumIdentifierSet(x[i], values[i], verbosity);
485 }
486 
487 /* Workspace method: Doxygen documentation will be auto-generated */
489  const Rational& in,
490  const Rational& value,
491  const Verbosity&) {
492  out = value + in;
493 }
494 
495 /* Workspace method: Doxygen documentation will be auto-generated */
497  const Rational& in,
498  const Rational& value,
499  const Verbosity&) {
500  out = in / value;
501 }
502 
503 /* Workspace method: Doxygen documentation will be auto-generated */
505  const Rational& in,
506  const Rational& value,
507  const Verbosity&) {
508  out = value * in;
509 }
510 
511 /* Workspace method: Doxygen documentation will be auto-generated */
513  const Index& numerator,
514  const Index& denominator,
515  const Verbosity&) {
516  x = Rational(numerator, denominator);
517 }
518 
519 /* Workspace method: Doxygen documentation will be auto-generated */
520 void SparseSparseMultiply( // WS Generic Output:
521  Sparse& Y,
522  // WS Generic Input:
523  const Sparse& M,
524  const Sparse& X,
525  const Verbosity&) {
526  // Check that dimensions are right, M.ncols() must match X.nrows():
527  if (M.ncols() != X.nrows()) {
528  ostringstream os;
529  os << "Matrix dimensions must be consistent!\n"
530  << "Matrix1.ncols() = " << M.ncols() << "\n"
531  << "Matrix2.nrows() = " << X.nrows();
532  throw runtime_error(os.str());
533  }
534 
535  // Temporary for the result:
536  Sparse dummy(M.nrows(), X.ncols());
537 
538  mult(dummy, M, X);
539 
540  // Copy result to Y:
541  Y = dummy;
542 }
543 
544 /* Workspace method: Doxygen documentation will be auto-generated */
546  const Index& n,
547  const Numeric& value,
548  const Verbosity&) {
549  X.resize(n, n);
550  id_mat(X);
551 
552  if (value != 1.0) X *= value;
553 }
554 
555 /* Workspace method: Doxygen documentation will be auto-generated */
556 void DiagonalMatrix(Matrix& X, const Vector& diag, const Verbosity& /*v*/) {
557  Index n = diag.nelem();
558  X.resize(n, n);
559  X = 0.0;
560 
561  for (Index i = 0; i < n; ++i) {
562  X(i, i) = diag[i];
563  }
564 }
565 
566 /* Workspace method: Doxygen documentation will be auto-generated */
567 void DiagonalMatrix(Sparse& X, const Vector& diag, const Verbosity& /*v*/) {
568  Index n = diag.nelem();
569  X.resize(n, n);
570 
571  ArrayOfIndex indices(n);
572 
573  for (Index i = 0; i < n; ++i) {
574  indices[i] = i;
575  }
576 
577  X.insert_elements(n, indices, indices, diag);
578 }
579 
580 /* Workspace method: Doxygen documentation will be auto-generated */
581 void StringSet(String& s, const String& s2, const Verbosity&) { s = s2; }
582 
583 /* Workspace method: Doxygen documentation will be auto-generated */
585  const Tensor3& in,
586  const Numeric& value,
587  const Verbosity&) {
588  // Note that in and out can be the same vector
589  if (&out == &in) {
590  // Out and in are the same. Just multiply by the scalar value.
591  out += value;
592  } else {
593  // Out and in are different. We first have to copy in to out,
594  // then multiply by the scalar value.
595  out.resize(in.npages(), in.nrows(), in.ncols());
596  out = in;
597  out += value;
598  }
599 }
600 
601 /* Workspace method: Doxygen documentation will be auto-generated */
603  const Tensor3& in,
604  const Numeric& value,
605  const Verbosity&) {
606  // Note that in and out can be the same vector
607  if (&out == &in) {
608  // Out and in are the same. Just multiply by the scalar value.
609  out *= value;
610  } else {
611  // Out and in are different. We first have to copy in to out,
612  // then multiply by the scalar value.
613  out.resize(in.npages(), in.nrows(), in.ncols());
614  out = in;
615  out *= value;
616  }
617 }
618 
619 /* Workspace method: Doxygen documentation will be auto-generated */
621  const Index& npages,
622  const Index& nrows,
623  const Index& ncols,
624  const Numeric& value,
625  const Verbosity& verbosity) {
626  CREATE_OUT2;
627  CREATE_OUT3;
628 
629  x.resize(npages, nrows, ncols);
630  x = value;
631 
632  out2 << " Tensor3 = " << value << "\n";
633  out3 << " npages : " << npages << "\n";
634  out3 << " nrows : " << nrows << "\n";
635  out3 << " ncols : " << ncols << "\n";
636 }
637 
638 /* Workspace method: Doxygen documentation will be auto-generated */
640  const Tensor4& in,
641  const Numeric& value,
642  const Verbosity&) {
643  // Note that in and out can be the same vector
644  if (&out == &in) {
645  // Out and in are the same. Just multiply by the scalar value.
646  out += value;
647  } else {
648  // Out and in are different. We first have to copy in to out,
649  // then multiply by the scalar value.
650  out.resize(in.nbooks(), in.npages(), in.nrows(), in.ncols());
651  out = in;
652  out += value;
653  }
654 }
655 
656 /* Workspace method: Doxygen documentation will be auto-generated */
658  const Tensor4& in,
659  const Numeric& value,
660  const Verbosity&) {
661  // Note that in and out can be the same vector
662  if (&out == &in) {
663  // Out and in are the same. Just multiply by the scalar value.
664  out *= value;
665  } else {
666  // Out and in are different. We first have to copy in to out,
667  // then multiply by the scalar value.
668  out.resize(in.nbooks(), in.npages(), in.nrows(), in.ncols());
669  out = in;
670  out *= value;
671  }
672 }
673 
674 /* Workspace method: Doxygen documentation will be auto-generated */
676  const Index& nbooks,
677  const Index& npages,
678  const Index& nrows,
679  const Index& ncols,
680  const Numeric& value,
681  const Verbosity& verbosity) {
682  CREATE_OUT2;
683  CREATE_OUT3;
684 
685  x.resize(nbooks, npages, nrows, ncols);
686  x = value;
687 
688  out2 << " Tensor4 = " << value << "\n";
689  out3 << " nbooks : " << nbooks << "\n";
690  out3 << " npages : " << npages << "\n";
691  out3 << " nrows : " << nrows << "\n";
692  out3 << " ncols : " << ncols << "\n";
693 }
694 
695 /* Workspace method: Doxygen documentation will be auto-generated */
697  const Tensor5& in,
698  const Numeric& value,
699  const Verbosity&) {
700  // Note that in and out can be the same vector
701  if (&out == &in) {
702  // Out and in are the same. Just multiply by the scalar value.
703  out *= value;
704  } else {
705  // Out and in are different. We first have to copy in to out,
706  // then multiply by the scalar value.
707  out.resize(in.nshelves(), in.nbooks(), in.npages(), in.nrows(), in.ncols());
708  out = in;
709  out *= value;
710  }
711 }
712 
713 /* Workspace method: Doxygen documentation will be auto-generated */
715  const Index& nshelves,
716  const Index& nbooks,
717  const Index& npages,
718  const Index& nrows,
719  const Index& ncols,
720  const Numeric& value,
721  const Verbosity& verbosity) {
722  CREATE_OUT2;
723  CREATE_OUT3;
724 
725  x.resize(nshelves, nbooks, npages, nrows, ncols);
726  x = value;
727 
728  out2 << " Tensor5 = " << value << "\n";
729  out3 << " nshelves : " << nshelves << "\n";
730  out3 << " nbooks : " << nbooks << "\n";
731  out3 << " npages : " << npages << "\n";
732  out3 << " nrows : " << nrows << "\n";
733  out3 << " ncols : " << ncols << "\n";
734 }
735 
736 /* Workspace method: Doxygen documentation will be auto-generated */
738  const Tensor6& in,
739  const Numeric& value,
740  const Verbosity&) {
741  // Note that in and out can be the same vector
742  if (&out == &in) {
743  // Out and in are the same. Just multiply by the scalar value.
744  out *= value;
745  } else {
746  // Out and in are different. We first have to copy in to out,
747  // then multiply by the scalar value.
748  out.resize(in.nvitrines(),
749  in.nshelves(),
750  in.nbooks(),
751  in.npages(),
752  in.nrows(),
753  in.ncols());
754  out = in;
755  out *= value;
756  }
757 }
758 
759 /* Workspace method: Doxygen documentation will be auto-generated */
761  const Index& nvitrines,
762  const Index& nshelves,
763  const Index& nbooks,
764  const Index& npages,
765  const Index& nrows,
766  const Index& ncols,
767  const Numeric& value,
768  const Verbosity& verbosity) {
769  CREATE_OUT2;
770  CREATE_OUT3;
771 
772  x.resize(nvitrines, nshelves, nbooks, npages, nrows, ncols);
773  x = value;
774 
775  out2 << " Tensor6 = " << value << "\n";
776  out3 << " nvitrines : " << nvitrines << "\n";
777  out3 << " nshelves : " << nshelves << "\n";
778  out3 << " nbooks : " << nbooks << "\n";
779  out3 << " npages : " << npages << "\n";
780  out3 << " nrows : " << nrows << "\n";
781  out3 << " ncols : " << ncols << "\n";
782 }
783 
784 /* Workspace method: Doxygen documentation will be auto-generated */
786  const Tensor7& in,
787  const Numeric& value,
788  const Verbosity&) {
789  // Note that in and out can be the same vector
790  if (&out == &in) {
791  // Out and in are the same. Just multiply by the scalar value.
792  out *= value;
793  } else {
794  // Out and in are different. We first have to copy in to out,
795  // then multiply by the scalar value.
796  out.resize(in.nlibraries(),
797  in.nvitrines(),
798  in.nshelves(),
799  in.nbooks(),
800  in.npages(),
801  in.nrows(),
802  in.ncols());
803  out = in;
804  out *= value;
805  }
806 }
807 
808 /* Workspace method: Doxygen documentation will be auto-generated */
810  const Index& nlibraries,
811  const Index& nvitrines,
812  const Index& nshelves,
813  const Index& nbooks,
814  const Index& npages,
815  const Index& nrows,
816  const Index& ncols,
817  const Numeric& value,
818  const Verbosity& verbosity) {
819  CREATE_OUT2;
820  CREATE_OUT3;
821 
822  x.resize(nlibraries, nvitrines, nshelves, nbooks, npages, nrows, ncols);
823  x = value;
824 
825  out2 << " Tensor7 = " << value << "\n";
826  out3 << " nlibraries : " << nlibraries << "\n";
827  out3 << " nvitrines : " << nvitrines << "\n";
828  out3 << " nshelves : " << nshelves << "\n";
829  out3 << " nbooks : " << nbooks << "\n";
830  out3 << " npages : " << npages << "\n";
831  out3 << " nrows : " << nrows << "\n";
832  out3 << " ncols : " << ncols << "\n";
833 }
834 
835 /* Workspace method: Doxygen documentation will be auto-generated */
837  const Vector& in,
838  const Numeric& value,
839  const Verbosity&) {
840  // Note that in and out can be the same vector
841  if (&out == &in) {
842  // Out and in are the same. Just add the scalar value.
843  out += value;
844  } else {
845  // Out and in are different. We first have to copy in to out,
846  // then add the scalar value.
847  out.resize(in.nelem());
848  out = in;
849  out += value;
850  }
851 }
852 
853 /* Workspace method: Doxygen documentation will be auto-generated */
855  const Vector& a,
856  const Vector& b,
857  const Verbosity&) {
858  // If anything is changed in the method, implement the same change in
859  // VectorSubtractVector
860 
861  // b has length 1. Here we easily can avoid just adding 0.
862  if (b.nelem() == 1) {
863  // a and c are the same WSV
864  if (&c == &a) {
865  if (b[0] != 0) {
866  c += b[0];
867  }
868  } else {
869  c = a;
870  if (b[0] != 0) {
871  c += b[0];
872  }
873  }
874  }
875 
876  // b is a vector
877  else if (b.nelem() == a.nelem()) {
878  // a and c are the same WSV
879  if (&c == &a) {
880  c += b;
881  } else {
882  c = a;
883  c += b;
884  }
885  }
886 
887  else
888  throw runtime_error(
889  "The vector *b* must have length 1 or match *a* in length.");
890 }
891 
892 /* Workspace method: Doxygen documentation will be auto-generated */
894  const Vector& a,
895  const Vector& b,
896  const Verbosity&) {
897  // If anything is changed in the method, implement the same change in
898  // VectorAddVector
899 
900  // b has length 1. Here we easily can avoid just adding 0.
901  if (b.nelem() == 1) {
902  // a and c are the same WSV
903  if (&c == &a) {
904  if (b[0] != 0) {
905  c -= b[0];
906  }
907  } else {
908  c = a;
909  if (b[0] != 0) {
910  c -= b[0];
911  }
912  }
913  }
914 
915  // b is a vector
916  else if (b.nelem() == a.nelem()) {
917  // a and c are the same WSV
918  if (&c == &a) {
919  c -= b;
920  } else {
921  c = a;
922  c -= b;
923  }
924  }
925 
926  else
927  throw runtime_error(
928  "The vector *b* must have length 1 or match *a* in length.");
929 }
930 
931 /* Workspace method: Doxygen documentation will be auto-generated */
932 void VectorCrop(Vector& out,
933  const Vector& in,
934  const Numeric& min_value,
935  const Numeric& max_value,
936  const Verbosity&) {
937  const Index nin = in.nelem();
938 
939  Index nout = 0;
940  //
941  for (Index i = 0; i < nin; i++) {
942  if (in[i] >= min_value && in[i] <= max_value) {
943  nout += 1;
944  }
945  }
946 
947  // Make copy if in-vector, as it also can be the out one
948  Vector c(in);
949 
950  out.resize(nout);
951 
952  nout = 0;
953  //
954  for (Index i = 0; i < nin; i++) {
955  if (c[i] >= min_value && c[i] <= max_value) {
956  out[nout] = c[i];
957  nout += 1;
958  }
959  }
960 }
961 
962 /* Workspace method: Doxygen documentation will be auto-generated
963 
964  2004-09-15 Patrick Eriksson
965 
966  Added keyword to control if row or column is extracted.
967 
968  2007-07-24 Stefan Buehler */
970  // WS Generic Output:
971  Vector& v,
972  // WS Input:
973  // WS Generic Input:
974  const Matrix& m,
975  const Index& index,
976  // Control Parameters:
977  const String& direction,
978  const Verbosity&) {
979  if (direction == "row") {
980  if (index >= m.nrows()) {
981  ostringstream os;
982  os << "The index " << index << " is outside the row range of the Matrix.";
983  throw runtime_error(os.str());
984  }
985 
986  v.resize(m.ncols());
987  v = m(index, joker);
988  } else if (direction == "column") {
989  if (index >= m.ncols()) {
990  ostringstream os;
991  os << "The index " << index
992  << " is outside the column range of the Matrix.";
993  throw runtime_error(os.str());
994  }
995 
996  v.resize(m.nrows());
997  v = m(joker, index);
998  } else {
999  ostringstream os;
1000  os << "Keyword *direction* must be either *row* or *column*,"
1001  << "but you gave: " << direction << ".";
1002  throw runtime_error(os.str());
1003  }
1004 }
1005 
1006 /* Workspace method: Doxygen documentation will be auto-generated */
1008  // WS Generic Output:
1009  Tensor3& t3,
1010  // WS Input:
1011  // WS Generic Input:
1012  const Tensor4& t4,
1013  const Index& index,
1014  // Control Parameters:
1015  const String& direction,
1016  const Verbosity&) {
1017  if (direction == "book") {
1018  if (index >= t4.nbooks()) {
1019  ostringstream os;
1020  os << "The index " << index
1021  << " is outside the book range of the Tensor4.";
1022  throw runtime_error(os.str());
1023  }
1024 
1025  t3.resize(t4.npages(), t4.nrows(), t4.ncols());
1026  t3 = t4(index, joker, joker, joker);
1027  } else if (direction == "page") {
1028  if (index >= t4.npages()) {
1029  ostringstream os;
1030  os << "The index " << index
1031  << " is outside the pages range of the Tensor4.";
1032  throw runtime_error(os.str());
1033  }
1034 
1035  t3.resize(t4.nbooks(), t4.nrows(), t4.ncols());
1036  t3 = t4(joker, index, joker, joker);
1037  } else if (direction == "row") {
1038  if (index >= t4.nrows()) {
1039  ostringstream os;
1040  os << "The index " << index
1041  << " is outside the row range of the Tensor4.";
1042  throw runtime_error(os.str());
1043  }
1044 
1045  t3.resize(t4.npages(), t4.nbooks(), t4.ncols());
1046  t3 = t4(joker, joker, index, joker);
1047  } else if (direction == "column") {
1048  if (index >= t4.ncols()) {
1049  ostringstream os;
1050  os << "The index " << index
1051  << " is outside the column range of the Tensor4.";
1052  throw runtime_error(os.str());
1053  }
1054 
1055  t3.resize(t4.npages(), t4.nbooks(), t4.nrows());
1056  t3 = t4(joker, joker, joker, index);
1057  } else {
1058  ostringstream os;
1059  os << "Keyword *direction* must be either *page*, *book*, *row* or *column*,"
1060  << "but you gave: " << direction << ".";
1061  throw runtime_error(os.str());
1062  }
1063 }
1064 
1065 /* Workspace method: Doxygen documentation will be auto-generated */
1066 void VectorFlip(Vector& out, const Vector& in, const Verbosity&) {
1067  const Index n = in.nelem();
1068 
1069  // Note that in and out can be the same vector
1070  if (&out == &in) {
1071  // Out and in are the same. A copy is needed
1072  const Vector v = in;
1073  for (Index i = 0; i < n; i++) out[i] = v[n - 1 - i];
1074  } else {
1075  // Out and in are different.
1076  out.resize(n);
1077  for (Index i = 0; i < n; i++) out[i] = in[n - 1 - i];
1078  }
1079 }
1080 
1081 /* Workspace method: Doxygen documentation will be auto-generated */
1082 void VectorInsertGridPoints( // WS Generic Output:
1083  Vector& og, // Output grid
1084  // WS Generic Input:
1085  const Vector& ingrid, // Input grid
1086  const Vector& points, // Points to insert
1087  const Verbosity& verbosity) {
1088  CREATE_OUT2;
1089  CREATE_OUT3;
1090 
1091  // First make duplicates of the input vectors, in case one of them
1092  // happens to be identical to the output vector. Also, we can fool
1093  // around with these, if we want.
1094  Vector ig(ingrid);
1095  Vector p(points);
1096 
1097  // Check how the input grid is sorted. If the grid is sorted in
1098  // descending order, we simply turn it around. (But don't
1099  // forget to turn it back at the end!)
1100  Index ascending; // 1=ascending, 0=descending
1101  if (is_increasing(ig)) {
1102  ascending = 1;
1103  } else if (is_decreasing(ig)) {
1104  ascending = 0;
1105 
1106  // Turn grid round.
1107 
1108  // Copy ig to dummy vector in reverse order:
1109  const Vector dummy = ig[Range(ig.nelem() - 1, ig.nelem(), -1)];
1110 
1111  // Copy dummy back to ig vector:
1112  ig = dummy;
1113  } else {
1114  ostringstream os;
1115  os << "The input Vector must be either\n"
1116  << "strictly increasing or strictly decreasing,\n"
1117  << "but this is not the case.\n";
1118  os << "The vector contains:\n" << ig;
1119  throw runtime_error(os.str());
1120  }
1121 
1122  // Sort also the vector of points to insert in increasing order:
1123  {
1124  ArrayOfIndex si; // Sorted indices
1125  get_sorted_indexes(si, p); // Get sorted p indices
1126  const Vector dummy = p; // Copy p to dummy
1127  // Copy back dummy to p in right order:
1128  for (Index j = 0; j < p.nelem(); j++) p[j] = dummy[si[j]];
1129  }
1130 
1131  // The idea is to step through both ig and p, and build up the
1132  // output in a temporary array.
1133  Array<Numeric> x;
1134  Index iig = 0, ip = 0; // indices to ig and p
1135  Index sk = 0; // skip count
1136  while (iig < ig.nelem() && ip < p.nelem()) {
1137  if (p[ip] < ig[iig]) {
1138  x.push_back(p[ip]);
1139  ++ip;
1140  } else if (p[ip] > ig[iig]) {
1141  x.push_back(ig[iig]);
1142  ++iig;
1143  } else {
1144  out3 << " Skipping point " << p[ip] << ", which is already "
1145  << "in the original grid.\n";
1146  ++ip;
1147  ++sk;
1148  }
1149  }
1150 
1151  out2 << " " << sk << " points skipped.\n";
1152 
1153  // Add remaining points of either p or ig, depending on which is
1154  // longer:
1155  if (ip == p.nelem()) {
1156  // p has reached its end.
1157  while (iig < ig.nelem()) {
1158  x.push_back(ig[iig]);
1159  ++iig;
1160  }
1161  } else if (iig == ig.nelem()) {
1162  // ig has reached its end
1163  while (ip < p.nelem()) {
1164  x.push_back(p[ip]);
1165  ++ip;
1166  }
1167  } else {
1168  // We should never be here.
1169  assert(false);
1170  arts_exit();
1171  }
1172 
1173  // Ok, x should now contain the new grid.
1174 
1175  og.resize(x.nelem());
1176 
1177  // Copy to result vector, turn around if necessary.
1178  if (ascending)
1179  for (Index i = 0; i < x.nelem(); ++i) og[i] = x[i]; // Just copy.
1180  else
1181  for (Index i = 0; i < x.nelem(); ++i)
1182  og[i] = x[x.nelem() - 1 - i]; // Copy in reverse order.
1183 }
1184 
1185 /* Workspace method: Doxygen documentation will be auto-generated */
1187  const Numeric& start,
1188  const Numeric& stop,
1189  const Numeric& step,
1190  const Verbosity& verbosity) {
1191  CREATE_OUT2;
1192  CREATE_OUT3;
1193 
1194  linspace(x, start, stop, step);
1195 
1196  out2 << " Creating a linearly spaced vector.\n";
1197  out3 << " length : " << x.nelem() << "\n";
1198  out3 << " first value : " << x[0] << "\n";
1199 
1200  if (x.nelem() > 1) {
1201  out3 << " step size : " << x[1] - x[0] << "\n";
1202  out3 << " last value : " << x[x.nelem() - 1] << "\n";
1203  }
1204 }
1205 
1206 /* Workspace method: Doxygen documentation will be auto-generated */
1208  const Numeric& start,
1209  const Numeric& stop,
1210  const Numeric& step,
1211  const Verbosity& verbosity) {
1212  CREATE_OUT2;
1213  CREATE_OUT3;
1214 
1215  linspace(x, log(start), log(stop), step);
1216  transform(x, exp, x);
1217 
1218  out2 << " Creating a logarithmically spaced vector.\n";
1219  out3 << " length : " << x.nelem() << "\n";
1220  out3 << " first value : " << x[0] << "\n";
1221 
1222  if (x.nelem() > 1) {
1223  out3 << " step size : " << x[1] - x[0] << "\n";
1224  out3 << " last value : " << x[x.nelem() - 1] << "\n";
1225  }
1226 }
1227 
1228 /* Workspace method: Doxygen documentation will be auto-generated */
1229 void VectorMatrixMultiply( // WS Generic Output:
1230  Vector& y,
1231  // WS Generic Input:
1232  const Matrix& M,
1233  const Vector& x,
1234  const Verbosity&) {
1235  // Check that dimensions are right, x must match columns of M:
1236  if (M.ncols() != x.nelem()) {
1237  ostringstream os;
1238  os << "Matrix and vector dimensions must be consistent!\n"
1239  << "Matrix.ncols() = " << M.ncols() << "\n"
1240  << "Vector.nelem() = " << x.nelem();
1241  throw runtime_error(os.str());
1242  }
1243 
1244  // Temporary for the result:
1245  Vector dummy(M.nrows());
1246 
1247  mult(dummy, M, x);
1248 
1249  y.resize(dummy.nelem());
1250 
1251  y = dummy;
1252 }
1253 
1254 /* Workspace method: Doxygen documentation will be auto-generated */
1256  const Index& n,
1257  const Numeric& start,
1258  const Numeric& stop,
1259  const Verbosity& verbosity) {
1260  CREATE_OUT2;
1261  CREATE_OUT3;
1262 
1263  if (n < 2) throw runtime_error("The number of points must be > 1.");
1264  nlinspace(x, start, stop, n);
1265 
1266  out2 << " Creating a linearly spaced vector.\n";
1267  out3 << " length : " << n << "\n";
1268  out3 << " first value : " << x[0] << "\n";
1269 
1270  if (x.nelem() > 1) {
1271  out3 << " step size : " << x[1] - x[0] << "\n";
1272  out3 << " last value : " << x[x.nelem() - 1] << "\n";
1273  }
1274 }
1275 
1276 /* Workspace method: Doxygen documentation will be auto-generated */
1278  const Index& n,
1279  const Numeric& start,
1280  const Numeric& stop,
1281  const Verbosity& verbosity) {
1282  CREATE_OUT2;
1283  CREATE_OUT3;
1284 
1285  if (n < 2) throw runtime_error("The number of points must be > 1.");
1286  if ((start <= 0) || (stop <= 0))
1287  throw runtime_error("Only positive numbers are allowed.");
1288 
1289  nlogspace(x, start, stop, n);
1290 
1291  out2 << " Creating a logarithmically spaced vector.\n";
1292  out3 << " length : " << n << "\n";
1293  out3 << " first value : " << x[0] << "\n";
1294 
1295  if (x.nelem() > 1)
1296  out3 << " last value : " << x[x.nelem() - 1] << "\n";
1297 }
1298 
1299 /* Workspace method: Doxygen documentation will be auto-generated */
1301  const Matrix& m,
1302  const String& direction,
1303  const Verbosity&) {
1304  const Index nrows = m.nrows();
1305  const Index ncols = m.ncols();
1306 
1307  v.resize(nrows * ncols);
1308 
1309  Index iv = 0;
1310 
1311  if (direction == "column") {
1312  for (Index col = 0; col < ncols; col++) {
1313  for (Index row = 0; row < nrows; row++) {
1314  v[iv] = m(row, col);
1315  iv++;
1316  }
1317  }
1318  } else if (direction == "row") {
1319  for (Index row = 0; row < nrows; row++) {
1320  for (Index col = 0; col < ncols; col++) {
1321  v[iv] = m(row, col);
1322  iv++;
1323  }
1324  }
1325  } else {
1326  ostringstream os;
1327  os << "Keyword *direction* must be either *row* or *column*,"
1328  << "but you gave: " << direction << ".";
1329  throw runtime_error(os.str());
1330  }
1331 }
1332 
1333 /* Workspace method: Doxygen documentation will be auto-generated */
1335  const Vector& in,
1336  const Numeric& value,
1337  const Verbosity&) {
1338  // Note that in and out can be the same vector
1339  if (&out == &in) {
1340  // Out and in are the same. Just multiply by the scalar value.
1341  out *= value;
1342  } else {
1343  // Out and in are different. We first have to copy in to out,
1344  // then multiply by the scalar value.
1345  out.resize(in.nelem());
1346  out = in;
1347  out *= value;
1348  }
1349 }
1350 
1351 /* Workspace method: Doxygen documentation will be auto-generated */
1353  const Index& n,
1354  const Numeric& value,
1355  const Verbosity& verbosity) {
1356  CREATE_OUT2;
1357  CREATE_OUT3;
1358 
1359  x.resize(n);
1360  x = value;
1361 
1362  out2 << " Creating a constant vector.\n";
1363  out3 << " length : " << n << "\n";
1364  out3 << " value : " << value << "\n";
1365 }
1366 
1367 /* Workspace method: Doxygen documentation will be auto-generated */
1368 void VectorSet(Vector& x, const Vector& values, const Verbosity&) {
1369  x = values;
1370 }
1371 
1372 /* Workspace method: Doxygen documentation will be auto-generated */
1373 void VectorVectorMultiply( // WS Generic Output:
1374  Vector& y,
1375  // WS Generic Input:
1376  const Vector& x1,
1377  const Vector& x2,
1378  const Verbosity&) {
1379  // Check that dimensions are right, x1 must match x2:
1380  if (x1.nelem() != x2.nelem()) {
1381  ostringstream os;
1382  os << "Both vectors have to have identical dimensions!\n"
1383  << "Vector1.nelem() = " << x1.nelem() << "\n"
1384  << "Vector2.nelem() = " << x2.nelem();
1385  throw runtime_error(os.str());
1386  }
1387 
1388  Vector dummy;
1389  dummy.resize(x1.nelem());
1390 
1391  for (Index i = 0; i < x1.nelem(); i++) dummy[i] = x1[i] * x2[i];
1392 
1393  y = dummy;
1394 }
1395 
1396 /* Workspace method: Doxygen documentation will be auto-generated */
1397 void Compare(const Numeric& var1,
1398  const Numeric& var2,
1399  const Numeric& maxabsdiff,
1400  const String& error_message,
1401  const String& var1name,
1402  const String& var2name,
1403  const String&,
1404  const String&,
1405  const Verbosity& verbosity) {
1406  Numeric maxdiff = var1 - var2;
1407 
1408  if (std::isnan(var1) || std::isnan(var2)) {
1409  if (std::isnan(var1) && std::isnan(var2)) {
1410  maxdiff = 0;
1411  } else if (std::isnan(var1)) {
1412  ostringstream os;
1413  os << "Nan found in " << var1name << ", but there is no "
1414  << "NaN at same position in " << var2name << ".\nThis "
1415  << "is not allowed.";
1416  throw runtime_error(os.str());
1417  } else {
1418  ostringstream os;
1419  os << "Nan found in " << var2name << ", but there is no "
1420  << "NaN at same position in " << var1name << ".\nThis "
1421  << "is not allowed.";
1422  throw runtime_error(os.str());
1423  }
1424  }
1425 
1426  if (abs(maxdiff) > maxabsdiff) {
1427  ostringstream os;
1428  os << var1name << "-" << var2name << " FAILED!\n";
1429  if (error_message.length()) os << error_message << "\n";
1430  os << "Max allowed deviation set to: " << maxabsdiff << endl
1431  << "but the value deviates with: " << maxdiff << endl;
1432  throw runtime_error(os.str());
1433  }
1434 
1435  CREATE_OUT2;
1436  out2 << " " << var1name << "-" << var2name
1437  << " OK (maximum difference = " << maxdiff << ").\n";
1438 }
1439 
1440 /* Workspace method: Doxygen documentation will be auto-generated */
1441 void Compare(const Vector& var1,
1442  const Vector& var2,
1443  const Numeric& maxabsdiff,
1444  const String& error_message,
1445  const String& var1name,
1446  const String& var2name,
1447  const String&,
1448  const String&,
1449  const Verbosity& verbosity) {
1450  const Index n = var1.nelem();
1451 
1452  if (var2.nelem() != n) {
1453  ostringstream os;
1454  os << var1name << " (" << n << ") and " << var2name << " (" << var2.nelem()
1455  << ") do not have the same size.";
1456  throw runtime_error(os.str());
1457  }
1458 
1459  Numeric maxdiff = 0.0;
1460  for (Index i = 0; i < n; i++) {
1461  Numeric diff = var1[i] - var2[i];
1462 
1463  if (std::isnan(var1[i]) || std::isnan(var2[i])) {
1464  if (std::isnan(var1[i]) && std::isnan(var2[i])) {
1465  diff = 0;
1466  } else if (std::isnan(var1[i])) {
1467  ostringstream os;
1468  os << "Nan found in " << var1name << ", but there is no "
1469  << "NaN at same position in " << var2name << ".\nThis "
1470  << "is not allowed.";
1471  throw runtime_error(os.str());
1472  } else {
1473  ostringstream os;
1474  os << "Nan found in " << var2name << ", but there is no "
1475  << "NaN at same position in " << var1name << ".\nThis "
1476  << "is not allowed.";
1477  throw runtime_error(os.str());
1478  }
1479  }
1480 
1481  if (abs(diff) > abs(maxdiff)) {
1482  maxdiff = diff;
1483  }
1484  }
1485 
1486  if (std::isnan(maxdiff) || abs(maxdiff) > maxabsdiff) {
1487  ostringstream os;
1488  os << var1name << "-" << var2name << " FAILED!\n";
1489  if (error_message.length()) os << error_message << "\n";
1490  os << "Max allowed deviation set to: " << maxabsdiff << endl
1491  << "but the vectors deviate with: " << maxdiff << endl;
1492  throw runtime_error(os.str());
1493  }
1494 
1495  CREATE_OUT2;
1496  out2 << " " << var1name << "-" << var2name
1497  << " OK (maximum difference = " << maxdiff << ").\n";
1498 }
1499 
1500 /* Workspace method: Doxygen documentation will be auto-generated */
1501 void Compare(const Matrix& var1,
1502  const Matrix& var2,
1503  const Numeric& maxabsdiff,
1504  const String& error_message,
1505  const String& var1name,
1506  const String& var2name,
1507  const String&,
1508  const String&,
1509  const Verbosity& verbosity) {
1510  const Index nrows = var1.nrows();
1511  const Index ncols = var1.ncols();
1512 
1513  if (var2.nrows() != nrows || var2.ncols() != ncols) {
1514  ostringstream os;
1515  os << var1name << " (" << nrows << "," << ncols << ") and " << var2name
1516  << " (" << var2.nrows() << "," << var2.ncols()
1517  << ") do not have the same size.";
1518  throw runtime_error(os.str());
1519  }
1520 
1521  Numeric maxdiff = 0.0;
1522 
1523  for (Index r = 0; r < nrows; r++) {
1524  for (Index c = 0; c < ncols; c++) {
1525  Numeric diff = var1(r, c) - var2(r, c);
1526 
1527  if (std::isnan(var1(r, c)) || std::isnan(var2(r, c))) {
1528  if (std::isnan(var1(r, c)) && std::isnan(var2(r, c))) {
1529  diff = 0;
1530  } else if (std::isnan(var1(r, c))) {
1531  ostringstream os;
1532  os << "Nan found in " << var1name << ", but there is no "
1533  << "NaN at same position in " << var2name << ".\nThis "
1534  << "is not allowed.";
1535  throw runtime_error(os.str());
1536  } else {
1537  ostringstream os;
1538  os << "Nan found in " << var2name << ", but there is no "
1539  << "NaN at same position in " << var1name << ".\nThis "
1540  << "is not allowed.";
1541  throw runtime_error(os.str());
1542  }
1543  }
1544 
1545  if (abs(diff) > abs(maxdiff)) {
1546  maxdiff = diff;
1547  }
1548  }
1549  }
1550 
1551  if (abs(maxdiff) > maxabsdiff) {
1552  ostringstream os;
1553  os << var1name << "-" << var2name << " FAILED!\n";
1554  if (error_message.length()) os << error_message << "\n";
1555  os << "Max allowed deviation set to : " << maxabsdiff << endl
1556  << "but the matrices deviate with: " << maxdiff << endl;
1557  throw runtime_error(os.str());
1558  }
1559 
1560  CREATE_OUT2;
1561  out2 << " " << var1name << "-" << var2name
1562  << " OK (maximum difference = " << maxdiff << ").\n";
1563 }
1564 
1565 /* Workspace method: Doxygen documentation will be auto-generated */
1566 void Compare(const Tensor3& var1,
1567  const Tensor3& var2,
1568  const Numeric& maxabsdiff,
1569  const String& error_message,
1570  const String& var1name,
1571  const String& var2name,
1572  const String&,
1573  const String&,
1574  const Verbosity& verbosity) {
1575  const Index ncols = var1.ncols();
1576  const Index nrows = var1.nrows();
1577  const Index npages = var1.npages();
1578 
1579  if (var2.ncols() != ncols || var2.nrows() != nrows ||
1580  var2.npages() != npages) {
1581  ostringstream os;
1582  os << var1name << " and " << var2name << " do not have the same size.";
1583  throw runtime_error(os.str());
1584  }
1585 
1586  Numeric maxdiff = 0.0;
1587 
1588  for (Index c = 0; c < ncols; c++)
1589  for (Index r = 0; r < nrows; r++)
1590  for (Index p = 0; p < npages; p++) {
1591  Numeric diff = var1(p, r, c) - var2(p, r, c);
1592 
1593  if (std::isnan(var1(p, r, c)) || std::isnan(var2(p, r, c))) {
1594  if (std::isnan(var1(p, r, c)) && std::isnan(var2(p, r, c))) {
1595  diff = 0;
1596  } else if (std::isnan(var1(p, r, c))) {
1597  ostringstream os;
1598  os << "Nan found in " << var1name << ", but there is no "
1599  << "NaN at same position in " << var2name << ".\nThis "
1600  << "is not allowed.";
1601  throw runtime_error(os.str());
1602  } else {
1603  ostringstream os;
1604  os << "Nan found in " << var2name << ", but there is no "
1605  << "NaN at same position in " << var1name << ".\nThis "
1606  << "is not allowed.";
1607  throw runtime_error(os.str());
1608  }
1609  }
1610 
1611  if (abs(diff) > abs(maxdiff)) {
1612  maxdiff = diff;
1613  }
1614  }
1615 
1616  if (abs(maxdiff) > maxabsdiff) {
1617  ostringstream os;
1618  os << var1name << "-" << var2name << " FAILED!\n";
1619  if (error_message.length()) os << error_message << "\n";
1620  os << "Max allowed deviation set to : " << maxabsdiff << endl
1621  << "but the tensors deviate with: " << maxdiff << endl;
1622  throw runtime_error(os.str());
1623  }
1624 
1625  CREATE_OUT2;
1626  out2 << " " << var1name << "-" << var2name
1627  << " OK (maximum difference = " << maxdiff << ").\n";
1628 }
1629 
1630 /* Workspace method: Doxygen documentation will be auto-generated */
1631 void Compare(const Tensor4& var1,
1632  const Tensor4& var2,
1633  const Numeric& maxabsdiff,
1634  const String& error_message,
1635  const String& var1name,
1636  const String& var2name,
1637  const String&,
1638  const String&,
1639  const Verbosity& verbosity) {
1640  const Index ncols = var1.ncols();
1641  const Index nrows = var1.nrows();
1642  const Index npages = var1.npages();
1643  const Index nbooks = var1.nbooks();
1644 
1645  if (var2.ncols() != ncols || var2.nrows() != nrows ||
1646  var2.npages() != npages || var2.nbooks() != nbooks) {
1647  ostringstream os;
1648  os << var1name << " and " << var2name << " do not have the same size.";
1649  throw runtime_error(os.str());
1650  }
1651 
1652  Numeric maxdiff = 0.0;
1653 
1654  for (Index c = 0; c < ncols; c++)
1655  for (Index r = 0; r < nrows; r++)
1656  for (Index p = 0; p < npages; p++)
1657  for (Index b = 0; b < nbooks; b++) {
1658  Numeric diff = var1(b, p, r, c) - var2(b, p, r, c);
1659 
1660  if (std::isnan(var1(b, p, r, c)) || std::isnan(var2(b, p, r, c))) {
1661  if (std::isnan(var1(b, p, r, c)) && std::isnan(var2(b, p, r, c))) {
1662  diff = 0;
1663  } else if (std::isnan(var1(b, p, r, c))) {
1664  ostringstream os;
1665  os << "Nan found in " << var1name << ", but there is no "
1666  << "NaN at same position in " << var2name << ".\nThis "
1667  << "is not allowed.";
1668  throw runtime_error(os.str());
1669  } else {
1670  ostringstream os;
1671  os << "Nan found in " << var2name << ", but there is no "
1672  << "NaN at same position in " << var1name << ".\nThis "
1673  << "is not allowed.";
1674  throw runtime_error(os.str());
1675  }
1676  }
1677 
1678  if (abs(diff) > abs(maxdiff)) {
1679  maxdiff = diff;
1680  }
1681  }
1682 
1683  if (abs(maxdiff) > maxabsdiff) {
1684  ostringstream os;
1685  os << var1name << "-" << var2name << " FAILED!\n";
1686  if (error_message.length()) os << error_message << "\n";
1687  os << "Max allowed deviation set to : " << maxabsdiff << endl
1688  << "but the tensors deviate with: " << maxdiff << endl;
1689  throw runtime_error(os.str());
1690  }
1691 
1692  CREATE_OUT2;
1693  out2 << " " << var1name << "-" << var2name
1694  << " OK (maximum difference = " << maxdiff << ").\n";
1695 }
1696 
1697 /* Workspace method: Doxygen documentation will be auto-generated */
1698 void Compare(const Tensor5& var1,
1699  const Tensor5& var2,
1700  const Numeric& maxabsdiff,
1701  const String& error_message,
1702  const String& var1name,
1703  const String& var2name,
1704  const String&,
1705  const String&,
1706  const Verbosity& verbosity) {
1707  const Index ncols = var1.ncols();
1708  const Index nrows = var1.nrows();
1709  const Index npages = var1.npages();
1710  const Index nbooks = var1.nbooks();
1711  const Index nshelves = var1.nshelves();
1712 
1713  if (var2.ncols() != ncols || var2.nrows() != nrows ||
1714  var2.npages() != npages || var2.nbooks() != nbooks ||
1715  var2.nshelves() != nshelves) {
1716  ostringstream os;
1717  os << var1name << " and " << var2name << " do not have the same size.";
1718  throw runtime_error(os.str());
1719  }
1720 
1721  Numeric maxdiff = 0.0;
1722 
1723  for (Index c = 0; c < ncols; c++)
1724  for (Index r = 0; r < nrows; r++)
1725  for (Index p = 0; p < npages; p++)
1726  for (Index b = 0; b < nbooks; b++)
1727  for (Index s = 0; s < nshelves; s++) {
1728  Numeric diff = var1(s, b, p, r, c) - var2(s, b, p, r, c);
1729 
1730  if (std::isnan(var1(s, b, p, r, c)) ||
1731  std::isnan(var2(s, b, p, r, c))) {
1732  if (std::isnan(var1(s, b, p, r, c)) &&
1733  std::isnan(var2(s, b, p, r, c))) {
1734  diff = 0;
1735  } else if (std::isnan(var1(s, b, p, r, c))) {
1736  ostringstream os;
1737  os << "Nan found in " << var1name << ", but there is no "
1738  << "NaN at same position in " << var2name << ".\nThis "
1739  << "is not allowed.";
1740  throw runtime_error(os.str());
1741  } else {
1742  ostringstream os;
1743  os << "Nan found in " << var2name << ", but there is no "
1744  << "NaN at same position in " << var1name << ".\nThis "
1745  << "is not allowed.";
1746  throw runtime_error(os.str());
1747  }
1748  }
1749 
1750  if (abs(diff) > abs(maxdiff)) {
1751  maxdiff = diff;
1752  }
1753  }
1754 
1755  if (abs(maxdiff) > maxabsdiff) {
1756  ostringstream os;
1757  os << var1name << "-" << var2name << " FAILED!\n";
1758  if (error_message.length()) os << error_message << "\n";
1759  os << "Max allowed deviation set to : " << maxabsdiff << endl
1760  << "but the tensors deviate with: " << maxdiff << endl;
1761  throw runtime_error(os.str());
1762  }
1763 
1764  CREATE_OUT2;
1765  out2 << " " << var1name << "-" << var2name
1766  << " OK (maximum difference = " << maxdiff << ").\n";
1767 }
1768 
1769 /* Workspace method: Doxygen documentation will be auto-generated */
1770 void Compare(const Tensor7& var1,
1771  const Tensor7& var2,
1772  const Numeric& maxabsdiff,
1773  const String& error_message,
1774  const String& var1name,
1775  const String& var2name,
1776  const String&,
1777  const String&,
1778  const Verbosity& verbosity) {
1779  const Index ncols = var1.ncols();
1780  const Index nrows = var1.nrows();
1781  const Index npages = var1.npages();
1782  const Index nbooks = var1.nbooks();
1783  const Index nshelves = var1.nshelves();
1784  const Index nvitrines = var1.nvitrines();
1785  const Index nlibraries = var1.nlibraries();
1786 
1787  if (var2.ncols() != ncols || var2.nrows() != nrows ||
1788  var2.npages() != npages || var2.nbooks() != nbooks ||
1789  var2.nshelves() != nshelves || var2.nvitrines() != nvitrines ||
1790  var2.nlibraries() != nlibraries) {
1791  ostringstream os;
1792  os << var1name << " and " << var2name << " do not have the same size.";
1793  throw runtime_error(os.str());
1794  }
1795 
1796  Numeric maxdiff = 0.0;
1797 
1798  for (Index c = 0; c < ncols; c++)
1799  for (Index r = 0; r < nrows; r++)
1800  for (Index p = 0; p < npages; p++)
1801  for (Index b = 0; b < nbooks; b++)
1802  for (Index s = 0; s < nshelves; s++)
1803  for (Index v = 0; v < nvitrines; v++)
1804  for (Index l = 0; l < nlibraries; l++) {
1805  Numeric diff =
1806  var1(l, v, s, b, p, r, c) - var2(l, v, s, b, p, r, c);
1807 
1808  if (std::isnan(var1(l, v, s, b, p, r, c)) ||
1809  std::isnan(var2(l, v, s, b, p, r, c))) {
1810  if (std::isnan(var1(l, v, s, b, p, r, c)) &&
1811  std::isnan(var2(l, v, s, b, p, r, c))) {
1812  diff = 0;
1813  } else if (std::isnan(var1(l, v, s, b, p, r, c))) {
1814  ostringstream os;
1815  os << "Nan found in " << var1name << ", but there is no "
1816  << "NaN at same position in " << var2name << ".\nThis "
1817  << "is not allowed.";
1818  throw runtime_error(os.str());
1819  } else {
1820  ostringstream os;
1821  os << "Nan found in " << var2name << ", but there is no "
1822  << "NaN at same position in " << var1name << ".\nThis "
1823  << "is not allowed.";
1824  throw runtime_error(os.str());
1825  }
1826  }
1827 
1828  if (abs(diff) > abs(maxdiff)) {
1829  maxdiff = diff;
1830  }
1831  }
1832 
1833  if (abs(maxdiff) > maxabsdiff) {
1834  ostringstream os;
1835  os << var1name << "-" << var2name << " FAILED!\n";
1836  if (error_message.length()) os << error_message << "\n";
1837  os << "Max allowed deviation set to : " << maxabsdiff << endl
1838  << "but the tensors deviate with: " << maxdiff << endl;
1839  throw runtime_error(os.str());
1840  }
1841 
1842  CREATE_OUT2;
1843  out2 << " " << var1name << "-" << var2name
1844  << " OK (maximum difference = " << maxdiff << ").\n";
1845 }
1846 
1847 /* Workspace method: Doxygen documentation will be auto-generated */
1848 void Compare(const ArrayOfVector& var1,
1849  const ArrayOfVector& var2,
1850  const Numeric& maxabsdiff,
1851  const String& error_message,
1852  const String& var1name,
1853  const String& var2name,
1854  const String&,
1855  const String&,
1856  const Verbosity& verbosity) {
1857  if (var1.nelem() != var2.nelem()) {
1858  ostringstream os;
1859  os << "The two arrays do not have the same size." << endl
1860  << var1name << " nelem: " << var1.nelem() << endl
1861  << var2name << " nelem: " << var2.nelem() << endl;
1862  throw runtime_error(os.str());
1863  }
1864 
1865  bool failed = false;
1866  ostringstream fail_msg;
1867  for (Index i = 0; i < var1.nelem(); i++) {
1868  try {
1869  ostringstream vn1, vn2;
1870  vn1 << var1name << "[" << i << "]";
1871  vn2 << var2name << "[" << i << "]";
1872  Compare(var1[i],
1873  var2[i],
1874  maxabsdiff,
1875  error_message,
1876  vn1.str(),
1877  vn2.str(),
1878  "",
1879  "",
1880  verbosity);
1881  } catch (const std::runtime_error& e) {
1882  failed = true;
1883  fail_msg << endl
1884  << e.what() << endl
1885  << "Mismatch at array index: " << i << endl;
1886  }
1887  }
1888 
1889  if (failed) throw runtime_error(fail_msg.str());
1890 }
1891 
1892 /* Workspace method: Doxygen documentation will be auto-generated */
1893 void Compare(const ArrayOfMatrix& var1,
1894  const ArrayOfMatrix& var2,
1895  const Numeric& maxabsdiff,
1896  const String& error_message,
1897  const String& var1name,
1898  const String& var2name,
1899  const String&,
1900  const String&,
1901  const Verbosity& verbosity) {
1902  if (var1.nelem() != var2.nelem()) {
1903  ostringstream os;
1904  os << "The two arrays do not have the same size." << endl
1905  << var1name << " nelem: " << var1.nelem() << endl
1906  << var2name << " nelem: " << var2.nelem() << endl;
1907  throw runtime_error(os.str());
1908  }
1909 
1910  bool failed = false;
1911  ostringstream fail_msg;
1912  for (Index i = 0; i < var1.nelem(); i++) {
1913  try {
1914  ostringstream vn1, vn2;
1915  vn1 << var1name << "[" << i << "]";
1916  vn2 << var2name << "[" << i << "]";
1917  Compare(var1[i],
1918  var2[i],
1919  maxabsdiff,
1920  error_message,
1921  vn1.str(),
1922  vn2.str(),
1923  "",
1924  "",
1925  verbosity);
1926  } catch (const std::runtime_error& e) {
1927  failed = true;
1928  fail_msg << endl
1929  << e.what() << endl
1930  << "Mismatch at array index: " << i << endl;
1931  }
1932  }
1933 
1934  if (failed) throw runtime_error(fail_msg.str());
1935 }
1936 
1937 /* Workspace method: Doxygen documentation will be auto-generated */
1938 void Compare(const ArrayOfTensor7& var1,
1939  const ArrayOfTensor7& var2,
1940  const Numeric& maxabsdiff,
1941  const String& error_message,
1942  const String& var1name,
1943  const String& var2name,
1944  const String&,
1945  const String&,
1946  const Verbosity& verbosity) {
1947  if (var1.nelem() != var2.nelem()) {
1948  ostringstream os;
1949  os << "The two arrays do not have the same size." << endl
1950  << var1name << " nelem: " << var1.nelem() << endl
1951  << var2name << " nelem: " << var2.nelem() << endl;
1952  throw runtime_error(os.str());
1953  }
1954 
1955  bool failed = false;
1956  ostringstream fail_msg;
1957  for (Index i = 0; i < var1.nelem(); i++) {
1958  try {
1959  ostringstream vn1, vn2;
1960  vn1 << var1name << "[" << i << "]";
1961  vn2 << var2name << "[" << i << "]";
1962  Compare(var1[i],
1963  var2[i],
1964  maxabsdiff,
1965  error_message,
1966  vn1.str(),
1967  vn2.str(),
1968  "",
1969  "",
1970  verbosity);
1971  } catch (const std::runtime_error& e) {
1972  failed = true;
1973  fail_msg << endl
1974  << e.what() << endl
1975  << "Mismatch at array index: " << i << endl;
1976  }
1977  }
1978 
1979  if (failed) throw runtime_error(fail_msg.str());
1980 }
1981 
1982 /* Workspace method: Doxygen documentation will be auto-generated */
1983 void Compare(const GriddedField3& var1,
1984  const GriddedField3& var2,
1985  const Numeric& maxabsdiff,
1986  const String& error_message,
1987  const String& var1name,
1988  const String& var2name,
1989  const String&,
1990  const String&,
1991  const Verbosity& verbosity) {
1992  for (Index i = 0; i < var1.get_dim(); i++) {
1993  if (var1.get_grid_size(i) != var2.get_grid_size(i)) {
1994  ostringstream os;
1995  os << var1name << " and " << var2name << " grid " << i
1996  << " do not have the same size: " << var1.get_grid_size(i)
1997  << " != " << var2.get_grid_size(i);
1998  throw runtime_error(os.str());
1999  }
2000  if (var1.get_grid_name(i) != var2.get_grid_name(i)) {
2001  ostringstream os;
2002  os << var1name << " and " << var2name << " grid " << i
2003  << " do not have the same name: " << var1.get_grid_name(i)
2004  << " != " << var2.get_grid_name(i);
2005  throw runtime_error(os.str());
2006  }
2007  }
2008 
2009  Compare(var1.data,
2010  var2.data,
2011  maxabsdiff,
2012  error_message,
2013  var1name,
2014  var2name,
2015  "",
2016  "",
2017  verbosity);
2018 }
2019 
2020 /* Workspace method: Doxygen documentation will be auto-generated */
2021 void Compare(const Sparse& var1,
2022  const Sparse& var2,
2023  const Numeric& maxabsdiff,
2024  const String& error_message,
2025  const String& var1name,
2026  const String& var2name,
2027  const String&,
2028  const String&,
2029  const Verbosity& verbosity) {
2030  const Index nrows = var1.nrows();
2031  const Index ncols = var1.ncols();
2032 
2033  if (var2.nrows() != nrows || var2.ncols() != ncols) {
2034  ostringstream os;
2035  os << var1name << " (" << nrows << "," << ncols << ") and " << var2name
2036  << " (" << var2.nrows() << "," << var2.ncols()
2037  << ") do not have the same size.";
2038  throw runtime_error(os.str());
2039  }
2040 
2041  Numeric maxdiff = 0.0;
2042 
2043  for (Index r = 0; r < nrows; r++) {
2044  for (Index c = 0; c < ncols; c++) {
2045  Numeric diff = var1(r, c) - var2(r, c);
2046 
2047  if (std::isnan(var1(r, c)) || std::isnan(var2(r, c))) {
2048  if (std::isnan(var1(r, c)) && std::isnan(var2(r, c))) {
2049  diff = 0;
2050  } else if (std::isnan(var1(r, c))) {
2051  ostringstream os;
2052  os << "Nan found in " << var1name << ", but there is no "
2053  << "NaN at same position in " << var2name << ".\nThis "
2054  << "is not allowed.";
2055  throw runtime_error(os.str());
2056  } else {
2057  ostringstream os;
2058  os << "Nan found in " << var2name << ", but there is no "
2059  << "NaN at same position in " << var1name << ".\nThis "
2060  << "is not allowed.";
2061  throw runtime_error(os.str());
2062  }
2063  }
2064 
2065  if (abs(diff) > abs(maxdiff)) {
2066  maxdiff = diff;
2067  }
2068  }
2069  }
2070 
2071  if (abs(maxdiff) > maxabsdiff) {
2072  ostringstream os;
2073  os << var1name << "-" << var2name << " FAILED!\n";
2074  if (error_message.length()) os << error_message << "\n";
2075  os << "Max allowed deviation set to : " << maxabsdiff << endl
2076  << "but the matrices deviate with: " << maxdiff << endl;
2077  throw runtime_error(os.str());
2078  }
2079 
2080  CREATE_OUT2;
2081  out2 << " " << var1name << "-" << var2name
2082  << " OK (maximum difference = " << maxdiff << ").\n";
2083 }
2084 
2085 /* Workspace method: Doxygen documentation will be auto-generated */
2087  const SingleScatteringData& var2,
2088  const Numeric& maxabsdiff,
2089  const String& error_message,
2090  const String& var1name,
2091  const String& var2name,
2092  const String&,
2093  const String&,
2094  const Verbosity& verbosity) {
2095  if (var1.ptype != var2.ptype) {
2096  std::ostringstream os;
2097  os << "The particle types don't match: " << std::endl
2098  << var1name << " = " << PTypeToString(var1.ptype) << ", " << var2name
2099  << " = " << PTypeToString(var2.ptype) << std::endl;
2100  throw std::runtime_error(os.str());
2101  }
2102  Compare(var1.f_grid,
2103  var2.f_grid,
2104  maxabsdiff,
2105  error_message,
2106  var1name + ".f_grid",
2107  var2name + ".f_grid",
2108  "",
2109  "",
2110  verbosity);
2111  Compare(var1.T_grid,
2112  var2.T_grid,
2113  maxabsdiff,
2114  error_message,
2115  var1name + ".T_grid",
2116  var2name + ".T_grid",
2117  "",
2118  "",
2119  verbosity);
2120  Compare(var1.za_grid,
2121  var2.za_grid,
2122  maxabsdiff,
2123  error_message,
2124  var1name + ".za_grid",
2125  var2name + ".za_grid",
2126  "",
2127  "",
2128  verbosity);
2129  Compare(var1.aa_grid,
2130  var2.aa_grid,
2131  maxabsdiff,
2132  error_message,
2133  var1name + ".aa_grid",
2134  var2name + ".aa_grid",
2135  "",
2136  "",
2137  verbosity);
2138  Compare(var1.pha_mat_data,
2139  var2.pha_mat_data,
2140  maxabsdiff,
2141  error_message,
2142  var1name + ".pha_mat_data",
2143  var2name + ".pha_mat_data",
2144  "",
2145  "",
2146  verbosity);
2147  Compare(var1.ext_mat_data,
2148  var2.ext_mat_data,
2149  maxabsdiff,
2150  error_message,
2151  var1name + ".ext_mat_data",
2152  var2name + ".ext_mat_data",
2153  "",
2154  "",
2155  verbosity);
2156  Compare(var1.abs_vec_data,
2157  var2.abs_vec_data,
2158  maxabsdiff,
2159  error_message,
2160  var1name + ".abs_vec_data",
2161  var2name + ".abs_vec_data",
2162  "",
2163  "",
2164  verbosity);
2165 }
2166 
2167 inline void _cr_internal_(const Numeric& var1,
2168  const Numeric& var2,
2169  const Numeric& maxabsreldiff,
2170  const String& error_message,
2171  const String& var1name,
2172  const String& var2name,
2173  const String&,
2174  const String&,
2175  const Verbosity&) {
2176  if (var1 not_eq 0. and var2 not_eq 0.) {
2177  const Numeric absreldiff = abs(var1 / var2 - 1);
2178  if (absreldiff > maxabsreldiff) {
2179  ostringstream os;
2180  os << var1name << "-" << var2name << " FAILED!\n";
2181  if (error_message.length()) os << error_message << "\n";
2182  os << "Max allowed deviation set to: " << maxabsreldiff * 100.0 << "%"
2183  << endl
2184  << "but the input deviate with: " << absreldiff * 100.0 << "%\n"
2185  << "If you compare non-scalar variables, the reported deviation is\n"
2186  << "the first one found violating the criterion. The maximum\n"
2187  << "difference can be higher.\n";
2188  throw runtime_error(os.str());
2189  }
2190  }
2191 }
2192 
2193 inline void _cr_internal_(const ConstVectorView var1,
2194  const ConstVectorView var2,
2195  const Numeric& maxabsreldiff,
2196  const String& error_message,
2197  const String& var1name,
2198  const String& var2name,
2199  const String&,
2200  const String&,
2201  const Verbosity& verbosity) {
2202  const Index n = var1.nelem();
2203  if (var2.nelem() not_eq n)
2204  throw std::runtime_error("Cannot compare variables of different size");
2205  for (Index i = 0; i < n; i++)
2206  _cr_internal_(var1[i],
2207  var2[i],
2208  maxabsreldiff,
2209  error_message,
2210  var1name,
2211  var2name,
2212  "",
2213  "",
2214  verbosity);
2215 }
2216 
2217 inline void _cr_internal_(const ConstMatrixView var1,
2218  const ConstMatrixView var2,
2219  const Numeric& maxabsreldiff,
2220  const String& error_message,
2221  const String& var1name,
2222  const String& var2name,
2223  const String&,
2224  const String&,
2225  const Verbosity& verbosity) {
2226  const Index n = var1.nrows();
2227  if (var2.nrows() not_eq n)
2228  throw std::runtime_error("Cannot compare variables of different size");
2229  for (Index i = 0; i < n; i++)
2230  _cr_internal_(var1(i, joker),
2231  var2(i, joker),
2232  maxabsreldiff,
2233  error_message,
2234  var1name,
2235  var2name,
2236  "",
2237  "",
2238  verbosity);
2239 }
2240 
2241 inline void _cr_internal_(const ConstTensor3View var1,
2242  const ConstTensor3View var2,
2243  const Numeric& maxabsreldiff,
2244  const String& error_message,
2245  const String& var1name,
2246  const String& var2name,
2247  const String&,
2248  const String&,
2249  const Verbosity& verbosity) {
2250  const Index n = var1.npages();
2251  if (var2.npages() not_eq n)
2252  throw std::runtime_error("Cannot compare variables of different size");
2253  for (Index i = 0; i < n; i++)
2254  _cr_internal_(var1(i, joker, joker),
2255  var2(i, joker, joker),
2256  maxabsreldiff,
2257  error_message,
2258  var1name,
2259  var2name,
2260  "",
2261  "",
2262  verbosity);
2263 }
2264 
2265 inline void _cr_internal_(const ConstTensor4View var1,
2266  const ConstTensor4View var2,
2267  const Numeric& maxabsreldiff,
2268  const String& error_message,
2269  const String& var1name,
2270  const String& var2name,
2271  const String&,
2272  const String&,
2273  const Verbosity& verbosity) {
2274  const Index n = var1.nbooks();
2275  if (var2.nbooks() not_eq n)
2276  throw std::runtime_error("Cannot compare variables of different size");
2277  for (Index i = 0; i < n; i++)
2278  _cr_internal_(var1(i, joker, joker, joker),
2279  var2(i, joker, joker, joker),
2280  maxabsreldiff,
2281  error_message,
2282  var1name,
2283  var2name,
2284  "",
2285  "",
2286  verbosity);
2287 }
2288 
2289 inline void _cr_internal_(const ConstTensor5View var1,
2290  const ConstTensor5View var2,
2291  const Numeric& maxabsreldiff,
2292  const String& error_message,
2293  const String& var1name,
2294  const String& var2name,
2295  const String&,
2296  const String&,
2297  const Verbosity& verbosity) {
2298  const Index n = var1.nshelves();
2299  if (var2.nshelves() not_eq n)
2300  throw std::runtime_error("Cannot compare variables of different size");
2301  for (Index i = 0; i < n; i++)
2302  _cr_internal_(var1(i, joker, joker, joker, joker),
2303  var2(i, joker, joker, joker, joker),
2304  maxabsreldiff,
2305  error_message,
2306  var1name,
2307  var2name,
2308  "",
2309  "",
2310  verbosity);
2311 }
2312 
2313 inline void _cr_internal_(const ConstTensor6View var1,
2314  const ConstTensor6View var2,
2315  const Numeric& maxabsreldiff,
2316  const String& error_message,
2317  const String& var1name,
2318  const String& var2name,
2319  const String&,
2320  const String&,
2321  const Verbosity& verbosity) {
2322  const Index n = var1.nvitrines();
2323  if (var2.nvitrines() not_eq n)
2324  throw std::runtime_error("Cannot compare variables of different size");
2325  for (Index i = 0; i < n; i++)
2326  _cr_internal_(var1(i, joker, joker, joker, joker, joker),
2327  var2(i, joker, joker, joker, joker, joker),
2328  maxabsreldiff,
2329  error_message,
2330  var1name,
2331  var2name,
2332  "",
2333  "",
2334  verbosity);
2335 }
2336 
2337 inline void _cr_internal_(const ConstTensor7View var1,
2338  const ConstTensor7View var2,
2339  const Numeric& maxabsreldiff,
2340  const String& error_message,
2341  const String& var1name,
2342  const String& var2name,
2343  const String&,
2344  const String&,
2345  const Verbosity& verbosity) {
2346  const Index n = var1.nlibraries();
2347  if (var2.nlibraries() not_eq n)
2348  throw std::runtime_error("Cannot compare variables of different size");
2349  for (Index i = 0; i < n; i++)
2351  var2(i, joker, joker, joker, joker, joker, joker),
2352  maxabsreldiff,
2353  error_message,
2354  var1name,
2355  var2name,
2356  "",
2357  "",
2358  verbosity);
2359 }
2360 
2361 inline void _cr_internal_(const PropagationMatrix& var1,
2362  const PropagationMatrix& var2,
2363  const Numeric& maxabsreldiff,
2364  const String& error_message,
2365  const String& var1name,
2366  const String& var2name,
2367  const String&,
2368  const String&,
2369  const Verbosity& verbosity) {
2370  _cr_internal_(var1.Data(),
2371  var2.Data(),
2372  maxabsreldiff,
2373  error_message,
2374  var1name,
2375  var2name,
2376  "",
2377  "",
2378  verbosity);
2379 }
2380 
2381 inline void _cr_internal_(const StokesVector& var1,
2382  const StokesVector& var2,
2383  const Numeric& maxabsreldiff,
2384  const String& error_message,
2385  const String& var1name,
2386  const String& var2name,
2387  const String&,
2388  const String&,
2389  const Verbosity& verbosity) {
2390  _cr_internal_(var1.Data(),
2391  var2.Data(),
2392  maxabsreldiff,
2393  error_message,
2394  var1name,
2395  var2name,
2396  "",
2397  "",
2398  verbosity);
2399 }
2400 
2401 template <class T>
2402 inline void _cr_internal_(const Array<T>& var1,
2403  const Array<T>& var2,
2404  const Numeric& maxabsreldiff,
2405  const String& error_message,
2406  const String& var1name,
2407  const String& var2name,
2408  const String&,
2409  const String&,
2410  const Verbosity& verbosity) {
2411  const Index n = var1.nelem();
2412  if (var2.nelem() not_eq n)
2413  throw std::runtime_error("Cannot compare arrays of different length");
2414  for (Index i = 0; i < n; i++)
2415  _cr_internal_(var1[i],
2416  var2[i],
2417  maxabsreldiff,
2418  error_message,
2419  var1name,
2420  var2name,
2421  "",
2422  "",
2423  verbosity);
2424 }
2425 
2426 /* Workspace method: Doxygen documentation will be auto-generated */
2427 void CompareRelative(const Numeric& var1,
2428  const Numeric& var2,
2429  const Numeric& maxabsreldiff,
2430  const String& error_message,
2431  const String& var1name,
2432  const String& var2name,
2433  const String&,
2434  const String&,
2435  const Verbosity& verbosity) {
2436  _cr_internal_(var1,
2437  var2,
2438  maxabsreldiff,
2439  error_message,
2440  var1name,
2441  var2name,
2442  "",
2443  "",
2444  verbosity);
2445 }
2446 void CompareRelative(const Vector& var1,
2447  const Vector& var2,
2448  const Numeric& maxabsreldiff,
2449  const String& error_message,
2450  const String& var1name,
2451  const String& var2name,
2452  const String&,
2453  const String&,
2454  const Verbosity& verbosity) {
2455  _cr_internal_(var1,
2456  var2,
2457  maxabsreldiff,
2458  error_message,
2459  var1name,
2460  var2name,
2461  "",
2462  "",
2463  verbosity);
2464 }
2465 void CompareRelative(const Matrix& var1,
2466  const Matrix& var2,
2467  const Numeric& maxabsreldiff,
2468  const String& error_message,
2469  const String& var1name,
2470  const String& var2name,
2471  const String&,
2472  const String&,
2473  const Verbosity& verbosity) {
2474  _cr_internal_(var1,
2475  var2,
2476  maxabsreldiff,
2477  error_message,
2478  var1name,
2479  var2name,
2480  "",
2481  "",
2482  verbosity);
2483 }
2484 void CompareRelative(const Tensor3& var1,
2485  const Tensor3& var2,
2486  const Numeric& maxabsreldiff,
2487  const String& error_message,
2488  const String& var1name,
2489  const String& var2name,
2490  const String&,
2491  const String&,
2492  const Verbosity& verbosity) {
2493  _cr_internal_(var1,
2494  var2,
2495  maxabsreldiff,
2496  error_message,
2497  var1name,
2498  var2name,
2499  "",
2500  "",
2501  verbosity);
2502 }
2503 void CompareRelative(const Tensor4& var1,
2504  const Tensor4& var2,
2505  const Numeric& maxabsreldiff,
2506  const String& error_message,
2507  const String& var1name,
2508  const String& var2name,
2509  const String&,
2510  const String&,
2511  const Verbosity& verbosity) {
2512  _cr_internal_(var1,
2513  var2,
2514  maxabsreldiff,
2515  error_message,
2516  var1name,
2517  var2name,
2518  "",
2519  "",
2520  verbosity);
2521 }
2522 void CompareRelative(const Tensor5& var1,
2523  const Tensor5& var2,
2524  const Numeric& maxabsreldiff,
2525  const String& error_message,
2526  const String& var1name,
2527  const String& var2name,
2528  const String&,
2529  const String&,
2530  const Verbosity& verbosity) {
2531  _cr_internal_(var1,
2532  var2,
2533  maxabsreldiff,
2534  error_message,
2535  var1name,
2536  var2name,
2537  "",
2538  "",
2539  verbosity);
2540 }
2541 void CompareRelative(const Tensor6& var1,
2542  const Tensor6& var2,
2543  const Numeric& maxabsreldiff,
2544  const String& error_message,
2545  const String& var1name,
2546  const String& var2name,
2547  const String&,
2548  const String&,
2549  const Verbosity& verbosity) {
2550  _cr_internal_(var1,
2551  var2,
2552  maxabsreldiff,
2553  error_message,
2554  var1name,
2555  var2name,
2556  "",
2557  "",
2558  verbosity);
2559 }
2560 void CompareRelative(const Tensor7& var1,
2561  const Tensor7& var2,
2562  const Numeric& maxabsreldiff,
2563  const String& error_message,
2564  const String& var1name,
2565  const String& var2name,
2566  const String&,
2567  const String&,
2568  const Verbosity& verbosity) {
2569  _cr_internal_(var1,
2570  var2,
2571  maxabsreldiff,
2572  error_message,
2573  var1name,
2574  var2name,
2575  "",
2576  "",
2577  verbosity);
2578 }
2580  const ArrayOfVector& var2,
2581  const Numeric& maxabsreldiff,
2582  const String& error_message,
2583  const String& var1name,
2584  const String& var2name,
2585  const String&,
2586  const String&,
2587  const Verbosity& verbosity) {
2588  _cr_internal_(var1,
2589  var2,
2590  maxabsreldiff,
2591  error_message,
2592  var1name,
2593  var2name,
2594  "",
2595  "",
2596  verbosity);
2597 }
2599  const ArrayOfMatrix& var2,
2600  const Numeric& maxabsreldiff,
2601  const String& error_message,
2602  const String& var1name,
2603  const String& var2name,
2604  const String&,
2605  const String&,
2606  const Verbosity& verbosity) {
2607  _cr_internal_(var1,
2608  var2,
2609  maxabsreldiff,
2610  error_message,
2611  var1name,
2612  var2name,
2613  "",
2614  "",
2615  verbosity);
2616 }
2618  const ArrayOfTensor3& var2,
2619  const Numeric& maxabsreldiff,
2620  const String& error_message,
2621  const String& var1name,
2622  const String& var2name,
2623  const String&,
2624  const String&,
2625  const Verbosity& verbosity) {
2626  _cr_internal_(var1,
2627  var2,
2628  maxabsreldiff,
2629  error_message,
2630  var1name,
2631  var2name,
2632  "",
2633  "",
2634  verbosity);
2635 }
2637  const ArrayOfTensor4& var2,
2638  const Numeric& maxabsreldiff,
2639  const String& error_message,
2640  const String& var1name,
2641  const String& var2name,
2642  const String&,
2643  const String&,
2644  const Verbosity& verbosity) {
2645  _cr_internal_(var1,
2646  var2,
2647  maxabsreldiff,
2648  error_message,
2649  var1name,
2650  var2name,
2651  "",
2652  "",
2653  verbosity);
2654 }
2656  const ArrayOfTensor5& var2,
2657  const Numeric& maxabsreldiff,
2658  const String& error_message,
2659  const String& var1name,
2660  const String& var2name,
2661  const String&,
2662  const String&,
2663  const Verbosity& verbosity) {
2664  _cr_internal_(var1,
2665  var2,
2666  maxabsreldiff,
2667  error_message,
2668  var1name,
2669  var2name,
2670  "",
2671  "",
2672  verbosity);
2673 }
2675  const ArrayOfTensor6& var2,
2676  const Numeric& maxabsreldiff,
2677  const String& error_message,
2678  const String& var1name,
2679  const String& var2name,
2680  const String&,
2681  const String&,
2682  const Verbosity& verbosity) {
2683  _cr_internal_(var1,
2684  var2,
2685  maxabsreldiff,
2686  error_message,
2687  var1name,
2688  var2name,
2689  "",
2690  "",
2691  verbosity);
2692 }
2694  const ArrayOfTensor7& var2,
2695  const Numeric& maxabsreldiff,
2696  const String& error_message,
2697  const String& var1name,
2698  const String& var2name,
2699  const String&,
2700  const String&,
2701  const Verbosity& verbosity) {
2702  _cr_internal_(var1,
2703  var2,
2704  maxabsreldiff,
2705  error_message,
2706  var1name,
2707  var2name,
2708  "",
2709  "",
2710  verbosity);
2711 }
2713  const ArrayOfArrayOfVector& var2,
2714  const Numeric& maxabsreldiff,
2715  const String& error_message,
2716  const String& var1name,
2717  const String& var2name,
2718  const String&,
2719  const String&,
2720  const Verbosity& verbosity) {
2721  _cr_internal_(var1,
2722  var2,
2723  maxabsreldiff,
2724  error_message,
2725  var1name,
2726  var2name,
2727  "",
2728  "",
2729  verbosity);
2730 }
2732  const ArrayOfArrayOfMatrix& var2,
2733  const Numeric& maxabsreldiff,
2734  const String& error_message,
2735  const String& var1name,
2736  const String& var2name,
2737  const String&,
2738  const String&,
2739  const Verbosity& verbosity) {
2740  _cr_internal_(var1,
2741  var2,
2742  maxabsreldiff,
2743  error_message,
2744  var1name,
2745  var2name,
2746  "",
2747  "",
2748  verbosity);
2749 }
2751  const ArrayOfArrayOfTensor3& var2,
2752  const Numeric& maxabsreldiff,
2753  const String& error_message,
2754  const String& var1name,
2755  const String& var2name,
2756  const String&,
2757  const String&,
2758  const Verbosity& verbosity) {
2759  _cr_internal_(var1,
2760  var2,
2761  maxabsreldiff,
2762  error_message,
2763  var1name,
2764  var2name,
2765  "",
2766  "",
2767  verbosity);
2768 }
2770  const ArrayOfArrayOfTensor4& var2,
2771  const Numeric& maxabsreldiff,
2772  const String& error_message,
2773  const String& var1name,
2774  const String& var2name,
2775  const String&,
2776  const String&,
2777  const Verbosity& verbosity) {
2778  _cr_internal_(var1,
2779  var2,
2780  maxabsreldiff,
2781  error_message,
2782  var1name,
2783  var2name,
2784  "",
2785  "",
2786  verbosity);
2787 }
2789  const ArrayOfArrayOfTensor5& var2,
2790  const Numeric& maxabsreldiff,
2791  const String& error_message,
2792  const String& var1name,
2793  const String& var2name,
2794  const String&,
2795  const String&,
2796  const Verbosity& verbosity) {
2797  _cr_internal_(var1,
2798  var2,
2799  maxabsreldiff,
2800  error_message,
2801  var1name,
2802  var2name,
2803  "",
2804  "",
2805  verbosity);
2806 }
2808  const ArrayOfArrayOfTensor6& var2,
2809  const Numeric& maxabsreldiff,
2810  const String& error_message,
2811  const String& var1name,
2812  const String& var2name,
2813  const String&,
2814  const String&,
2815  const Verbosity& verbosity) {
2816  _cr_internal_(var1,
2817  var2,
2818  maxabsreldiff,
2819  error_message,
2820  var1name,
2821  var2name,
2822  "",
2823  "",
2824  verbosity);
2825 }
2827  const ArrayOfArrayOfTensor7& var2,
2828  const Numeric& maxabsreldiff,
2829  const String& error_message,
2830  const String& var1name,
2831  const String& var2name,
2832  const String&,
2833  const String&,
2834  const Verbosity& verbosity) {
2835  _cr_internal_(var1,
2836  var2,
2837  maxabsreldiff,
2838  error_message,
2839  var1name,
2840  var2name,
2841  "",
2842  "",
2843  verbosity);
2844 }
2845 
2847  const ArrayOfPropagationMatrix& var2,
2848  const Numeric& maxabsreldiff,
2849  const String& error_message,
2850  const String& var1name,
2851  const String& var2name,
2852  const String&,
2853  const String&,
2854  const Verbosity& verbosity) {
2855  _cr_internal_(var1,
2856  var2,
2857  maxabsreldiff,
2858  error_message,
2859  var1name,
2860  var2name,
2861  "",
2862  "",
2863  verbosity);
2864 }
2865 
2867  const ArrayOfArrayOfPropagationMatrix& var2,
2868  const Numeric& maxabsreldiff,
2869  const String& error_message,
2870  const String& var1name,
2871  const String& var2name,
2872  const String&,
2873  const String&,
2874  const Verbosity& verbosity) {
2875  _cr_internal_(var1,
2876  var2,
2877  maxabsreldiff,
2878  error_message,
2879  var1name,
2880  var2name,
2881  "",
2882  "",
2883  verbosity);
2884 }
2885 
2887  const ArrayOfStokesVector& var2,
2888  const Numeric& maxabsreldiff,
2889  const String& error_message,
2890  const String& var1name,
2891  const String& var2name,
2892  const String&,
2893  const String&,
2894  const Verbosity& verbosity) {
2895  _cr_internal_(var1,
2896  var2,
2897  maxabsreldiff,
2898  error_message,
2899  var1name,
2900  var2name,
2901  "",
2902  "",
2903  verbosity);
2904 }
2905 
2907  const ArrayOfArrayOfStokesVector& var2,
2908  const Numeric& maxabsreldiff,
2909  const String& error_message,
2910  const String& var1name,
2911  const String& var2name,
2912  const String&,
2913  const String&,
2914  const Verbosity& verbosity) {
2915  _cr_internal_(var1,
2916  var2,
2917  maxabsreldiff,
2918  error_message,
2919  var1name,
2920  var2name,
2921  "",
2922  "",
2923  verbosity);
2924 }
2925 
2926 /* Workspace method: Doxygen documentation will be auto-generated */
2928  const EnergyLevelMap& var2,
2929  const Numeric& maxabsreldiff,
2930  const String& error_message,
2931  const String& var1name,
2932  const String& var2name,
2933  const String&,
2934  const String&,
2935  const Verbosity& verbosity) {
2936  _cr_internal_(var1.Data(),
2937  var2.Data(),
2938  maxabsreldiff,
2939  error_message,
2940  var1name,
2941  var2name,
2942  "",
2943  "",
2944  verbosity);
2945  _cr_internal_(var1.Energies(),
2946  var2.Energies(),
2947  maxabsreldiff,
2948  error_message,
2949  var1name,
2950  var2name,
2951  "",
2952  "",
2953  verbosity);
2954 }
2955 
2956 void PrintPhysicalConstants(const Verbosity& verbosity) {
2957  CREATE_OUT0;
2958 
2959  extern const Numeric AVOGADROS_NUMB;
2960  extern const Numeric BOHR_MAGNETON;
2961  extern const Numeric BOLTZMAN_CONST;
2962  extern const Numeric ELECTRON_CHARGE;
2963  extern const Numeric ELECTRON_MASS;
2964  extern const Numeric GAS_CONSTANT;
2965  extern const Numeric PLANCK_CONST;
2966  extern const Numeric SPEED_OF_LIGHT;
2967  extern const Numeric VACUUM_PERMITTIVITY;
2968  extern const Numeric DOPPLER_CONST;
2969 
2970  out0 << std::setprecision(15) << std::scientific;
2971  out0 << "---------------------------------------------------------\n"
2972  << "Numerical const in ARTS \tValue\n"
2973  << "Avogadro's constant: \t " << AVOGADROS_NUMB << '\n'
2974  << "Bohr's magneton: \t " << BOHR_MAGNETON << '\n'
2975  << "Boltzmann's constant: \t " << BOLTZMAN_CONST << '\n'
2976  << "Electron charge: \t" << ELECTRON_CHARGE << '\n'
2977  << "Electron mass: \t " << ELECTRON_MASS << '\n'
2978  << "Ideal gas constant: \t " << GAS_CONSTANT << '\n'
2979  << "Planck's constant: \t " << PLANCK_CONST << '\n'
2980  << "Speed of light: \t " << SPEED_OF_LIGHT << '\n'
2981  << "Vacuum permittivity: \t " << VACUUM_PERMITTIVITY << '\n'
2982  << "Doppler constant: \t " << DOPPLER_CONST << '\n'
2983  << "---------------------------------------------------------\n";
2984 }
Index npages() const
Returns the number of pages.
Definition: matpackV.cc:50
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
void RationalSet(Rational &x, const Index &numerator, const Index &denominator, const Verbosity &)
WORKSPACE METHOD: RationalSet.
const Numeric PLANCK_CONST
Global constant, the Planck constant [Js].
void NumericInvScale(Numeric &out, const Numeric &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: NumericInvScale.
void Tensor7Scale(Tensor7 &out, const Tensor7 &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: Tensor7Scale.
void VectorFlip(Vector &out, const Vector &in, const Verbosity &)
WORKSPACE METHOD: VectorFlip.
void SparseMatrixIdentity(Sparse &X, const Index &n, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: SparseMatrixIdentity.
const Numeric VACUUM_PERMITTIVITY
Global constant, the vacuum permittivity [F m-1].
Index nrows() const
Returns the number of rows.
Definition: matpackV.cc:53
void ArrayOfIndexLinSpace(ArrayOfIndex &x, const Index &start, const Index &stop, const Index &step, const Verbosity &verbosity)
WORKSPACE METHOD: ArrayOfIndexLinSpace.
void MatrixExtractFromTensor3(Matrix &m, const Tensor3 &t3, const Index &index, const String &direction, const Verbosity &)
WORKSPACE METHOD: MatrixExtractFromTensor3.
void VectorScale(Vector &out, const Vector &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: VectorScale.
#define x2
void NumericSet(Numeric &x, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: NumericSet.
Index nelem() const
Number of elements.
Definition: array.h:195
void resize(Index s, Index b, Index p, Index r, Index c)
Resize function.
Definition: matpackV.cc:1743
void Tensor5Scale(Tensor5 &out, const Tensor5 &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: Tensor5Scale.
void arts_exit(int status)
This is the exit function of ARTS.
Definition: arts.cc:42
void MatrixScale(Matrix &out, const Matrix &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: MatrixScale.
Declarations having to do with the four output streams.
const Numeric BOLTZMAN_CONST
Global constant, the Boltzmann constant [J/K].
A constant view of a Tensor7.
Definition: matpackVII.h:147
void RationalInvScale(Rational &out, const Rational &in, const Rational &value, const Verbosity &)
WORKSPACE METHOD: RationalInvScale.
void Matrix1ColFromVector(Matrix &m, const Vector &v, const Verbosity &)
WORKSPACE METHOD: Matrix1ColFromVector.
const Numeric ELECTRON_MASS
Global constant, the mass of an electron [kg].
const Numeric ELECTRON_CHARGE
Global constant, the charge of an electron [As] N.B.
void Matrix2RowFromVectors(Matrix &m, const Vector &v1, const Vector &v2, const Verbosity &)
WORKSPACE METHOD: Matrix2RowFromVectors.
The Vector class.
Definition: matpackI.h:860
#define abs(x)
const Numeric GAS_CONSTANT
Global constant, universal gas constant.
Index nvitrines() const
Returns the number of vitrines.
Definition: matpackVI.cc:42
void VectorNLinSpace(Vector &x, const Index &n, const Numeric &start, const Numeric &stop, const Verbosity &verbosity)
WORKSPACE METHOD: VectorNLinSpace.
A constant view of a Tensor6.
Definition: matpackVI.h:149
void CompareRelative(const Numeric &var1, const Numeric &var2, const Numeric &maxabsreldiff, const String &error_message, const String &var1name, const String &var2name, const String &, const String &, const Verbosity &verbosity)
WORKSPACE METHOD: CompareRelative.
const Tensor4 & Data() const noexcept
Energy level type.
void VectorVectorMultiply(Vector &y, const Vector &x1, const Vector &x2, const Verbosity &)
WORKSPACE METHOD: VectorVectorMultiply.
bool is_increasing(ConstVectorView x)
Checks if a vector is sorted and strictly increasing.
Definition: logic.cc:215
The Sparse class.
Definition: matpackII.h:60
void SparseSparseMultiply(Sparse &Y, const Sparse &M, const Sparse &X, const Verbosity &)
WORKSPACE METHOD: SparseSparseMultiply.
The Tensor4 class.
Definition: matpackIV.h:421
void Tensor6Scale(Tensor6 &out, const Tensor6 &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: Tensor6Scale.
The range class.
Definition: matpackI.h:160
void Tensor3SetConstant(Tensor3 &x, const Index &npages, const Index &nrows, const Index &ncols, const Numeric &value, const Verbosity &verbosity)
WORKSPACE METHOD: Tensor3SetConstant.
void IndexSet(Index &x, const Index &value, const Verbosity &)
WORKSPACE METHOD: IndexSet.
Index nrows() const
Returns the number of rows.
Definition: matpackVII.cc:57
Linear algebra functions.
Index npages() const
Returns the number of pages.
Definition: matpackIV.cc:60
void Matrix3RowFromVectors(Matrix &m, const Vector &v1, const Vector &v2, const Vector &v3, const Verbosity &)
WORKSPACE METHOD: Matrix3RowFromVectors.
void IndexAdd(Index &out, const Index &in, const Index &value, const Verbosity &)
WORKSPACE METHOD: IndexAdd.
Index ncols() const
Returns the number of columns.
Definition: matpackII.cc:69
const Vector & Energies() const noexcept
Energy level type.
The Tensor7 class.
Definition: matpackVII.h:2382
void VectorInsertGridPoints(Vector &og, const Vector &ingrid, const Vector &points, const Verbosity &verbosity)
WORKSPACE METHOD: VectorInsertGridPoints.
Index nbooks() const
Returns the number of books.
Definition: matpackV.cc:47
#define min(a, b)
Index nrows() const
Returns the number of rows.
Definition: matpackIII.h:147
void Tensor5SetConstant(Tensor5 &x, const Index &nshelves, const Index &nbooks, const Index &npages, const Index &nrows, const Index &ncols, const Numeric &value, const Verbosity &verbosity)
WORKSPACE METHOD: Tensor5SetConstant.
Stokes vector is as Propagation matrix but only has 4 possible values.
void NumericFromVector(Numeric &out, const Vector &in, const String &op, const Verbosity &)
WORKSPACE METHOD: NumericFromVector.
Index nrows() const
Returns the number of rows.
Definition: matpackIV.cc:63
void Tensor4SetConstant(Tensor4 &x, const Index &nbooks, const Index &npages, const Index &nrows, const Index &ncols, const Numeric &value, const Verbosity &verbosity)
WORKSPACE METHOD: Tensor4SetConstant.
Index nelem() const
Returns the number of elements.
Definition: matpackI.cc:51
#define x1
Contains sorting routines.
A constant view of a Tensor4.
Definition: matpackIV.h:133
void ArrayOfQuantumIdentifierSet(ArrayOfQuantumIdentifier &x, const ArrayOfString &values, const Verbosity &verbosity)
WORKSPACE METHOD: ArrayOfQuantumIdentifierSet.
This file contains the definition of Array.
void MatrixMatrixMultiply(Matrix &Y, const Matrix &M, const Matrix &X, const Verbosity &)
WORKSPACE METHOD: MatrixMatrixMultiply.
void FlagOn(Index &x, const Verbosity &)
WORKSPACE METHOD: FlagOn.
Index get_dim() const
Get the dimension of this gridded field.
void VectorLogSpace(Vector &x, const Numeric &start, const Numeric &stop, const Numeric &step, const Verbosity &verbosity)
WORKSPACE METHOD: VectorLogSpace.
Index ncols() const
Returns the number of columns.
Definition: matpackI.cc:432
void VectorSet(Vector &x, const Vector &values, const Verbosity &)
WORKSPACE METHOD: VectorSet.
void VectorReshapeMatrix(Vector &v, const Matrix &m, const String &direction, const Verbosity &)
WORKSPACE METHOD: VectorReshapeMatrix.
void Tensor3Scale(Tensor3 &out, const Tensor3 &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: Tensor3Scale.
void Tensor7SetConstant(Tensor7 &x, const Index &nlibraries, const Index &nvitrines, const Index &nshelves, const Index &nbooks, const Index &npages, const Index &nrows, const Index &ncols, const Numeric &value, const Verbosity &verbosity)
WORKSPACE METHOD: Tensor7SetConstant.
The Tensor3 class.
Definition: matpackIII.h:339
The global header file for ARTS.
Index nshelves() const
Returns the number of shelves.
Definition: matpackV.cc:44
Header file for sparse matrices.
void MatrixIdentity(Matrix &out, const Index &n, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: MatrixIdentity.
void MatrixSet(Matrix &x, const Matrix &values, const Verbosity &)
WORKSPACE METHOD: MatrixSet.
void RationalScale(Rational &out, const Rational &in, const Rational &value, const Verbosity &)
WORKSPACE METHOD: RationalScale.
_CS_string_type str() const
Definition: sstream.h:491
Index ncols() const
Returns the number of columns.
Definition: matpackIII.h:150
void Tensor3AddScalar(Tensor3 &out, const Tensor3 &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: Tensor3AddScalar.
void MatrixAddScalar(Matrix &out, const Matrix &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: MatrixAddScalar.
void VectorCrop(Vector &out, const Vector &in, const Numeric &min_value, const Numeric &max_value, const Verbosity &)
WORKSPACE METHOD: VectorCrop.
void Tensor4AddScalar(Tensor4 &out, const Tensor4 &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: Tensor4AddScalar.
void Tensor3ExtractFromTensor4(Tensor3 &t3, const Tensor4 &t4, const Index &index, const String &direction, const Verbosity &)
WORKSPACE METHOD: Tensor3ExtractFromTensor4.
Implements rational numbers to work with other ARTS types.
Definition: rational.h:54
The declarations of all the exception classes.
void nlinspace(Vector &x, const Numeric start, const Numeric stop, const Index n)
nlinspace
Definition: math_funcs.cc:231
Index get_grid_size(Index i) const
Get the size of a grid.
void ArrayOfStringSet(ArrayOfString &sa, const ArrayOfString &sa2, const Verbosity &)
WORKSPACE METHOD: ArrayOfStringSet.
void VectorExtractFromMatrix(Vector &v, const Matrix &m, const Index &index, const String &direction, const Verbosity &)
WORKSPACE METHOD: VectorExtractFromMatrix.
Index nrows() const
Returns the number of rows.
Definition: matpackII.cc:66
void MatrixVectorMultiply(Vector &Y, const Matrix &M, const Vector &X, const Verbosity &)
WORKSPACE METHOD: MatrixVectorMultiply.
Index nrows() const
Returns the number of rows.
Definition: matpackVI.cc:54
Class to identify and match lines by their quantum numbers.
Definition: quantum.h:390
void VectorAddVector(Vector &c, const Vector &a, const Vector &b, const Verbosity &)
WORKSPACE METHOD: VectorAddVector.
void NumericAdd(Numeric &out, const Numeric &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: NumericAdd.
A constant view of a Tensor5.
Definition: matpackV.h:143
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
Index nlibraries() const
Returns the number of libraries.
Definition: matpackVII.cc:42
Tensor4 & Data()
Get full view to data.
void VectorNLogSpace(Vector &x, const Index &n, const Numeric &start, const Numeric &stop, const Verbosity &verbosity)
WORKSPACE METHOD: VectorNLogSpace.
void Matrix1RowFromVector(Matrix &m, const Vector &v, const Verbosity &)
WORKSPACE METHOD: Matrix1RowFromVector.
void nlogspace(Vector &x, const Numeric start, const Numeric stop, const Index n)
nlogspace
Definition: math_funcs.cc:267
Implementation of Matrix, Vector, and such stuff.
void ArrayOfIndexSetConstant(ArrayOfIndex &aoi, const Index &nelem, const Index &value, const Verbosity &)
WORKSPACE METHOD: ArrayOfIndexSetConstant.
Class to map energy levels.
void resize(Index p, Index r, Index c)
Resize function.
Definition: matpackIII.cc:664
void _cr_internal_(const Numeric &var1, const Numeric &var2, const Numeric &maxabsreldiff, const String &error_message, const String &var1name, const String &var2name, const String &, const String &, const Verbosity &)
void get_sorted_indexes(ArrayOfIndex &sorted, const T &data)
get_sorted_indexes
Definition: sorting.h:73
void mult(ComplexVectorView y, const ConstComplexMatrixView &M, const ConstComplexVectorView &x)
Matrix-Vector Multiplication.
Definition: complex.cc:1579
void RationalAdd(Rational &out, const Rational &in, const Rational &value, const Verbosity &)
WORKSPACE METHOD: RationalAdd.
const Numeric AVOGADROS_NUMB
Global constant, the Avogadro&#39;s number [molec/kg].
Header file for logic.cc.
void VectorMatrixMultiply(Vector &y, const Matrix &M, const Vector &x, const Verbosity &)
WORKSPACE METHOD: VectorMatrixMultiply.
basic_ostringstream< char, string_char_traits< char >, alloc > ostringstream
Definition: sstream.h:204
void VectorSetConstant(Vector &x, const Index &n, const Numeric &value, const Verbosity &verbosity)
WORKSPACE METHOD: VectorSetConstant.
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
void Matrix2ColFromVectors(Matrix &m, const Vector &v1, const Vector &v2, const Verbosity &)
WORKSPACE METHOD: Matrix2ColFromVectors.
Index nshelves() const
Returns the number of shelves.
Definition: matpackVI.cc:45
Index ncols() const
Returns the number of columns.
Definition: matpackVI.cc:57
void NumericScale(Numeric &out, const Numeric &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: NumericScale.
const Numeric BOHR_MAGNETON
Bohr Magneton.
void IndexStepDown(Index &xout, const Index &xin, const Verbosity &)
WORKSPACE METHOD: IndexStepDown.
const String & get_grid_name(Index i) const
Get grid name.
void resize(Index n)
Resize function.
Definition: matpackI.cc:404
void VectorSubtractVector(Vector &c, const Vector &a, const Vector &b, const Verbosity &)
WORKSPACE METHOD: VectorSubtractVector.
void Matrix3ColFromVectors(Matrix &m, const Vector &v1, const Vector &v2, const Vector &v3, const Verbosity &)
WORKSPACE METHOD: Matrix3ColFromVectors.
#define max(a, b)
A constant view of a Tensor3.
Definition: matpackIII.h:132
void MatrixCopySparse(Matrix &out, const Sparse &in, const Verbosity &)
WORKSPACE METHOD: MatrixCopySparse.
The Tensor6 class.
Definition: matpackVI.h:1088
void Compare(const Numeric &var1, const Numeric &var2, const Numeric &maxabsdiff, const String &error_message, const String &var1name, const String &var2name, const String &, const String &, const Verbosity &verbosity)
WORKSPACE METHOD: Compare.
A constant view of a Vector.
Definition: matpackI.h:476
Index npages() const
Returns the number of pages.
Definition: matpackVI.cc:51
void VectorAddScalar(Vector &out, const Vector &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: VectorAddScalar.
Index nshelves() const
Returns the number of shelves.
Definition: matpackVII.cc:48
Numeric mean(const ConstVectorView &x)
Mean function, vector version.
Definition: matpackI.cc:1589
Index nelem(const Lines &l)
Number of lines.
String PTypeToString(const PType &ptype)
Convert particle type enum value to String.
constexpr Rational start(Rational Ju, Rational Jl, Polarization type) noexcept
Gives the lowest M for a polarization type of this transition.
Definition: zeemandata.h:77
A constant view of a Matrix.
Definition: matpackI.h:982
void Tensor4Scale(Tensor4 &out, const Tensor4 &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: Tensor4Scale.
Index npages() const
Returns the number of pages.
Definition: matpackVII.cc:54
Index nbooks() const
Returns the number of books.
Definition: matpackIV.cc:57
void resize(Index v, Index s, Index b, Index p, Index r, Index c)
Resize function.
Definition: matpackVI.cc:2175
void transform(VectorView y, double(&my_func)(double), ConstVectorView x)
A generic transform function for vectors, which can be used to implement mathematical functions opera...
Definition: matpackI.cc:1476
void DiagonalMatrix(Matrix &X, const Vector &diag, const Verbosity &)
WORKSPACE METHOD: DiagonalMatrix.
Implementation of gridded fields.
void resize(Index r, Index c)
Resize function.
Definition: matpackII.cc:361
Index ncols() const
Returns the number of columns.
Definition: matpackV.cc:56
void MatrixSetConstant(Matrix &x, const Index &nrows, const Index &ncols, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: MatrixSetConstant.
bool is_decreasing(ConstVectorView x)
Checks if a vector is sorted in reversed order and is strictly decreasing.
Definition: logic.cc:252
#define CREATE_OUT0
Definition: messages.h:204
#define CREATE_OUT3
Definition: messages.h:207
void QuantumIdentifierSet(QuantumIdentifier &x, const String &value, const Verbosity &)
WORKSPACE METHOD: QuantumIdentifierSet.
void id_mat(MatrixView I)
Identity Matrix.
Definition: lin_alg.cc:2240
Index nvitrines() const
Returns the number of vitrines.
Definition: matpackVII.cc:45
void ArrayOfIndexSet(ArrayOfIndex &aoi, const ArrayOfIndex &values, const Verbosity &)
WORKSPACE METHOD: ArrayOfIndexSet.
Index ncols() const
Returns the number of columns.
Definition: matpackVII.cc:60
Index ncols() const
Returns the number of columns.
Definition: matpackIV.cc:66
const Numeric DOPPLER_CONST
void resize(Index l, Index v, Index s, Index b, Index p, Index r, Index c)
Resize function.
Definition: matpackVII.cc:5484
std::vector< T > linspace(T s, T e, typename std::vector< T >::size_type count) noexcept
#define CREATE_OUT2
Definition: messages.h:206
const Numeric SPEED_OF_LIGHT
void VectorLinSpace(Vector &x, const Numeric &start, const Numeric &stop, const Numeric &step, const Verbosity &verbosity)
WORKSPACE METHOD: VectorLinSpace.
void Tensor6SetConstant(Tensor6 &x, const Index &nvitrines, const Index &nshelves, const Index &nbooks, const Index &npages, const Index &nrows, const Index &ncols, const Numeric &value, const Verbosity &verbosity)
WORKSPACE METHOD: Tensor6SetConstant.
void StringSet(String &s, const String &s2, const Verbosity &)
WORKSPACE METHOD: StringSet.
Scattering database structure and functions.
Index nrows() const
Returns the number of rows.
Definition: matpackI.cc:429
Index nbooks() const
Returns the number of books.
Definition: matpackVII.cc:51
void IndexStepUp(Index &xout, const Index &xin, const Verbosity &)
WORKSPACE METHOD: IndexStepUp.
void FlagOff(Index &x, const Verbosity &)
WORKSPACE METHOD: FlagOff.
void resize(Index b, Index p, Index r, Index c)
Resize function.
Definition: matpackIV.cc:1064
void insert_elements(Index nnz, const ArrayOfIndex &rowind, const ArrayOfIndex &colind, ConstVectorView data)
Insert vector of elements with given row and column indices.
Definition: matpackII.cc:337
The Tensor5 class.
Definition: matpackV.h:506
This file contains the definition of String, the ARTS string class.
void resize(Index r, Index c)
Resize function.
Definition: matpackI.cc:1056
void PrintPhysicalConstants(const Verbosity &verbosity)
WORKSPACE METHOD: PrintPhysicalConstants.
Index nbooks() const
Returns the number of books.
Definition: matpackVI.cc:48