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