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