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