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