101 for (
Index i = 0;
i < n;
i++) x[
i] = start +
i * step;
103 out2 <<
" Creating a linearly spaced ArrayOfIndex.\n";
104 out3 <<
" length : " << x.
nelem() <<
"\n";
105 out3 <<
" first value : " << x[0] <<
"\n";
108 out3 <<
" step size : " << x[1] - x[0] <<
"\n";
109 out3 <<
" last value : " << x[x.nelem() - 1] <<
"\n";
117 sa.resize(sa2.
nelem());
172 out(
r, c) = in(
r, c);
188 if (direction ==
"page") {
189 if (index >= t3.
npages()) {
191 os <<
"The index " << index
192 <<
" is outside the page range of the Matrix.";
193 throw runtime_error(os.
str());
198 }
else if (direction ==
"row") {
199 if (index >= t3.
nrows()) {
201 os <<
"The index " << index <<
" is outside the row range of the Matrix.";
202 throw runtime_error(os.
str());
207 }
else if (direction ==
"column") {
208 if (index >= t3.
ncols()) {
210 os <<
"The index " << index
211 <<
" is outside the column range of the Matrix.";
212 throw runtime_error(os.
str());
219 os <<
"Keyword *direction* must be either *page* or *row* or *column*," 220 <<
"but you gave: " << direction <<
".";
221 throw runtime_error(os.
str());
235 os <<
"Matrix dimensions must be consistent!\n" 236 <<
"Matrix1.ncols() = " << M.
ncols() <<
"\n" 237 <<
"Matrix2.nrows() = " << X.
nrows();
238 throw runtime_error(os.
str());
248 Y.
resize(dummy.nrows(), dummy.ncols());
263 os <<
"Matrix and vector dimensions must be consistent!\n" 264 <<
"Matrix.ncols() = " << M.
ncols() <<
"\n" 265 <<
"Vector.nelem() = " << X.
nelem();
266 throw runtime_error(os.
str());
299 if (v2.
nelem() != nv)
300 throw runtime_error(
"Vectors must be of the same size.");
318 throw runtime_error(
"Vectors must be of the same size.");
347 if (v2.
nelem() != nv)
348 throw runtime_error(
"Vectors must be of the same size.");
366 throw runtime_error(
"Vectors must be of the same size.");
434 else if (op ==
"last")
435 out = in[in.
nelem() - 1];
436 else if (op ==
"max")
438 else if (op ==
"min")
440 else if (op ==
"mean")
444 os <<
"Your choice, *op* = \"" << op <<
"\", is not recognised.\n" 445 <<
"Valid options are: \"first\", \"last\", \"max\", \"min\" and \"mean\".";
446 throw runtime_error(os.
str());
482 x.resize(values.
nelem());
513 const Index& numerator,
514 const Index& denominator,
516 x =
Rational(numerator, denominator);
529 os <<
"Matrix dimensions must be consistent!\n" 530 <<
"Matrix1.ncols() = " << M.
ncols() <<
"\n" 531 <<
"Matrix2.nrows() = " << X.
nrows();
532 throw runtime_error(os.
str());
552 if (value != 1.0) X *= value;
629 x.
resize(npages, nrows, ncols);
632 out2 <<
" Tensor3 = " << value <<
"\n";
633 out3 <<
" npages : " << npages <<
"\n";
634 out3 <<
" nrows : " << nrows <<
"\n";
635 out3 <<
" ncols : " << ncols <<
"\n";
685 x.
resize(nbooks, npages, nrows, ncols);
688 out2 <<
" Tensor4 = " << value <<
"\n";
689 out3 <<
" nbooks : " << nbooks <<
"\n";
690 out3 <<
" npages : " << npages <<
"\n";
691 out3 <<
" nrows : " << nrows <<
"\n";
692 out3 <<
" ncols : " << ncols <<
"\n";
715 const Index& nshelves,
725 x.
resize(nshelves, nbooks, npages, nrows, ncols);
728 out2 <<
" Tensor5 = " << value <<
"\n";
729 out3 <<
" nshelves : " << nshelves <<
"\n";
730 out3 <<
" nbooks : " << nbooks <<
"\n";
731 out3 <<
" npages : " << npages <<
"\n";
732 out3 <<
" nrows : " << nrows <<
"\n";
733 out3 <<
" ncols : " << ncols <<
"\n";
761 const Index& nvitrines,
762 const Index& nshelves,
772 x.
resize(nvitrines, nshelves, nbooks, npages, nrows, ncols);
775 out2 <<
" Tensor6 = " << value <<
"\n";
776 out3 <<
" nvitrines : " << nvitrines <<
"\n";
777 out3 <<
" nshelves : " << nshelves <<
"\n";
778 out3 <<
" nbooks : " << nbooks <<
"\n";
779 out3 <<
" npages : " << npages <<
"\n";
780 out3 <<
" nrows : " << nrows <<
"\n";
781 out3 <<
" ncols : " << ncols <<
"\n";
810 const Index& nlibraries,
811 const Index& nvitrines,
812 const Index& nshelves,
822 x.
resize(nlibraries, nvitrines, nshelves, nbooks, npages, nrows, ncols);
825 out2 <<
" Tensor7 = " << value <<
"\n";
826 out3 <<
" nlibraries : " << nlibraries <<
"\n";
827 out3 <<
" nvitrines : " << nvitrines <<
"\n";
828 out3 <<
" nshelves : " << nshelves <<
"\n";
829 out3 <<
" nbooks : " << nbooks <<
"\n";
830 out3 <<
" npages : " << npages <<
"\n";
831 out3 <<
" nrows : " << nrows <<
"\n";
832 out3 <<
" ncols : " << ncols <<
"\n";
862 if (b.
nelem() == 1) {
889 "The vector *b* must have length 1 or match *a* in length.");
901 if (b.
nelem() == 1) {
928 "The vector *b* must have length 1 or match *a* in length.");
942 if (in[
i] >= min_value && in[
i] <= max_value) {
955 if (c[
i] >= min_value && c[
i] <= max_value) {
979 if (direction ==
"row") {
980 if (index >= m.
nrows()) {
982 os <<
"The index " << index <<
" is outside the row range of the Matrix.";
983 throw runtime_error(os.
str());
988 }
else if (direction ==
"column") {
989 if (index >= m.
ncols()) {
991 os <<
"The index " << index
992 <<
" is outside the column range of the Matrix.";
993 throw runtime_error(os.
str());
1000 os <<
"Keyword *direction* must be either *row* or *column*," 1001 <<
"but you gave: " << direction <<
".";
1002 throw runtime_error(os.
str());
1017 if (direction ==
"book") {
1018 if (index >= t4.
nbooks()) {
1020 os <<
"The index " << index
1021 <<
" is outside the book range of the Tensor4.";
1022 throw runtime_error(os.
str());
1027 }
else if (direction ==
"page") {
1028 if (index >= t4.
npages()) {
1030 os <<
"The index " << index
1031 <<
" is outside the pages range of the Tensor4.";
1032 throw runtime_error(os.
str());
1037 }
else if (direction ==
"row") {
1038 if (index >= t4.
nrows()) {
1040 os <<
"The index " << index
1041 <<
" is outside the row range of the Tensor4.";
1042 throw runtime_error(os.
str());
1047 }
else if (direction ==
"column") {
1048 if (index >= t4.
ncols()) {
1050 os <<
"The index " << index
1051 <<
" is outside the column range of the Tensor4.";
1052 throw runtime_error(os.
str());
1059 os <<
"Keyword *direction* must be either *page*, *book*, *row* or *column*," 1060 <<
"but you gave: " << direction <<
".";
1061 throw runtime_error(os.
str());
1073 for (
Index i = 0;
i < n;
i++) out[
i] = v[n - 1 -
i];
1077 for (
Index i = 0;
i < n;
i++) out[
i] = in[n - 1 -
i];
1115 os <<
"The input Vector must be either\n" 1116 <<
"strictly increasing or strictly decreasing,\n" 1117 <<
"but this is not the case.\n";
1118 os <<
"The vector contains:\n" << ig;
1119 throw runtime_error(os.
str());
1128 for (
Index j = 0; j < p.
nelem(); j++) p[j] = dummy[si[j]];
1134 Index iig = 0, ip = 0;
1137 if (p[ip] < ig[iig]) {
1140 }
else if (p[ip] > ig[iig]) {
1141 x.push_back(ig[iig]);
1144 out3 <<
" Skipping point " << p[ip] <<
", which is already " 1145 <<
"in the original grid.\n";
1151 out2 <<
" " << sk <<
" points skipped.\n";
1155 if (ip == p.
nelem()) {
1157 while (iig < ig.
nelem()) {
1158 x.push_back(ig[iig]);
1161 }
else if (iig == ig.
nelem()) {
1163 while (ip < p.
nelem()) {
1196 out2 <<
" Creating a linearly spaced vector.\n";
1197 out3 <<
" length : " << x.
nelem() <<
"\n";
1198 out3 <<
" first value : " << x[0] <<
"\n";
1200 if (x.nelem() > 1) {
1201 out3 <<
" step size : " << x[1] - x[0] <<
"\n";
1202 out3 <<
" last value : " << x[x.nelem() - 1] <<
"\n";
1215 linspace(x, log(start), log(stop), step);
1218 out2 <<
" Creating a logarithmically spaced vector.\n";
1219 out3 <<
" length : " << x.
nelem() <<
"\n";
1220 out3 <<
" first value : " << x[0] <<
"\n";
1222 if (x.nelem() > 1) {
1223 out3 <<
" step size : " << x[1] - x[0] <<
"\n";
1224 out3 <<
" last value : " << x[x.nelem() - 1] <<
"\n";
1238 os <<
"Matrix and vector dimensions must be consistent!\n" 1239 <<
"Matrix.ncols() = " << M.
ncols() <<
"\n" 1240 <<
"Vector.nelem() = " << x.
nelem();
1241 throw runtime_error(os.
str());
1263 if (n < 2)
throw runtime_error(
"The number of points must be > 1.");
1266 out2 <<
" Creating a linearly spaced vector.\n";
1267 out3 <<
" length : " << n <<
"\n";
1268 out3 <<
" first value : " << x[0] <<
"\n";
1270 if (x.nelem() > 1) {
1271 out3 <<
" step size : " << x[1] - x[0] <<
"\n";
1272 out3 <<
" last value : " << x[x.nelem() - 1] <<
"\n";
1285 if (n < 2)
throw runtime_error(
"The number of points must be > 1.");
1286 if ((start <= 0) || (stop <= 0))
1287 throw runtime_error(
"Only positive numbers are allowed.");
1291 out2 <<
" Creating a logarithmically spaced vector.\n";
1292 out3 <<
" length : " << n <<
"\n";
1293 out3 <<
" first value : " << x[0] <<
"\n";
1296 out3 <<
" last value : " << x[x.nelem() - 1] <<
"\n";
1311 if (direction ==
"column") {
1312 for (
Index col = 0; col < ncols; col++) {
1313 for (
Index row = 0; row < nrows; row++) {
1314 v[iv] = m(row, col);
1318 }
else if (direction ==
"row") {
1319 for (
Index row = 0; row < nrows; row++) {
1320 for (
Index col = 0; col < ncols; col++) {
1321 v[iv] = m(row, col);
1327 os <<
"Keyword *direction* must be either *row* or *column*," 1328 <<
"but you gave: " << direction <<
".";
1329 throw runtime_error(os.
str());
1362 out2 <<
" Creating a constant vector.\n";
1363 out3 <<
" length : " << n <<
"\n";
1364 out3 <<
" value : " << value <<
"\n";
1382 os <<
"Both vectors have to have identical dimensions!\n" 1383 <<
"Vector1.nelem() = " << x1.
nelem() <<
"\n" 1384 <<
"Vector2.nelem() = " << x2.
nelem();
1385 throw runtime_error(os.
str());
1400 const String& error_message,
1406 Numeric maxdiff = var1 - var2;
1408 if (std::isnan(var1) || std::isnan(var2)) {
1409 if (std::isnan(var1) && std::isnan(var2)) {
1411 }
else if (std::isnan(var1)) {
1413 os <<
"Nan found in " << var1name <<
", but there is no " 1414 <<
"NaN at same position in " << var2name <<
".\nThis " 1415 <<
"is not allowed.";
1416 throw runtime_error(os.
str());
1419 os <<
"Nan found in " << var2name <<
", but there is no " 1420 <<
"NaN at same position in " << var1name <<
".\nThis " 1421 <<
"is not allowed.";
1422 throw runtime_error(os.
str());
1426 if (
abs(maxdiff) > maxabsdiff) {
1428 os << var1name <<
"-" << var2name <<
" FAILED!\n";
1429 if (error_message.length()) os << error_message <<
"\n";
1430 os <<
"Max allowed deviation set to: " << maxabsdiff << endl
1431 <<
"but the value deviates with: " << maxdiff << endl;
1432 throw runtime_error(os.
str());
1436 out2 <<
" " << var1name <<
"-" << var2name
1437 <<
" OK (maximum difference = " << maxdiff <<
").\n";
1444 const String& error_message,
1452 if (var2.
nelem() != n) {
1454 os << var1name <<
" (" << n <<
") and " << var2name <<
" (" << var2.
nelem()
1455 <<
") do not have the same size.";
1456 throw runtime_error(os.
str());
1463 if (std::isnan(var1[
i]) || std::isnan(var2[i])) {
1464 if (std::isnan(var1[i]) && std::isnan(var2[i])) {
1466 }
else if (std::isnan(var1[i])) {
1468 os <<
"Nan found in " << var1name <<
", but there is no " 1469 <<
"NaN at same position in " << var2name <<
".\nThis " 1470 <<
"is not allowed.";
1471 throw runtime_error(os.
str());
1474 os <<
"Nan found in " << var2name <<
", but there is no " 1475 <<
"NaN at same position in " << var1name <<
".\nThis " 1476 <<
"is not allowed.";
1477 throw runtime_error(os.
str());
1481 if (
abs(diff) >
abs(maxdiff)) {
1486 if (std::isnan(maxdiff) ||
abs(maxdiff) > maxabsdiff) {
1488 os << var1name <<
"-" << var2name <<
" FAILED!\n";
1489 if (error_message.length()) os << error_message <<
"\n";
1490 os <<
"Max allowed deviation set to: " << maxabsdiff << endl
1491 <<
"but the vectors deviate with: " << maxdiff << endl;
1492 throw runtime_error(os.
str());
1496 out2 <<
" " << var1name <<
"-" << var2name
1497 <<
" OK (maximum difference = " << maxdiff <<
").\n";
1504 const String& error_message,
1513 if (var2.
nrows() != nrows || var2.
ncols() != ncols) {
1515 os << var1name <<
" (" << nrows <<
"," << ncols <<
") and " << var2name
1516 <<
" (" << var2.
nrows() <<
"," << var2.
ncols()
1517 <<
") do not have the same size.";
1518 throw runtime_error(os.
str());
1523 for (
Index r = 0;
r < nrows;
r++) {
1524 for (
Index c = 0; c < ncols; c++) {
1527 if (std::isnan(var1(
r, c)) || std::isnan(var2(
r, c))) {
1528 if (std::isnan(var1(
r, c)) && std::isnan(var2(
r, c))) {
1530 }
else if (std::isnan(var1(
r, c))) {
1532 os <<
"Nan found in " << var1name <<
", but there is no " 1533 <<
"NaN at same position in " << var2name <<
".\nThis " 1534 <<
"is not allowed.";
1535 throw runtime_error(os.
str());
1538 os <<
"Nan found in " << var2name <<
", but there is no " 1539 <<
"NaN at same position in " << var1name <<
".\nThis " 1540 <<
"is not allowed.";
1541 throw runtime_error(os.
str());
1545 if (
abs(diff) >
abs(maxdiff)) {
1551 if (
abs(maxdiff) > maxabsdiff) {
1553 os << var1name <<
"-" << var2name <<
" FAILED!\n";
1554 if (error_message.length()) os << error_message <<
"\n";
1555 os <<
"Max allowed deviation set to : " << maxabsdiff << endl
1556 <<
"but the matrices deviate with: " << maxdiff << endl;
1557 throw runtime_error(os.
str());
1561 out2 <<
" " << var1name <<
"-" << var2name
1562 <<
" OK (maximum difference = " << maxdiff <<
").\n";
1569 const String& error_message,
1579 if (var2.
ncols() != ncols || var2.
nrows() != nrows ||
1580 var2.
npages() != npages) {
1582 os << var1name <<
" and " << var2name <<
" do not have the same size.";
1583 throw runtime_error(os.
str());
1588 for (
Index c = 0; c < ncols; c++)
1590 for (
Index p = 0; p < npages; p++) {
1591 Numeric diff = var1(p,
r, c) - var2(p,
r, c);
1593 if (std::isnan(var1(p,
r, c)) || std::isnan(var2(p,
r, c))) {
1594 if (std::isnan(var1(p,
r, c)) && std::isnan(var2(p,
r, c))) {
1596 }
else if (std::isnan(var1(p,
r, c))) {
1598 os <<
"Nan found in " << var1name <<
", but there is no " 1599 <<
"NaN at same position in " << var2name <<
".\nThis " 1600 <<
"is not allowed.";
1601 throw runtime_error(os.
str());
1604 os <<
"Nan found in " << var2name <<
", but there is no " 1605 <<
"NaN at same position in " << var1name <<
".\nThis " 1606 <<
"is not allowed.";
1607 throw runtime_error(os.
str());
1611 if (
abs(diff) >
abs(maxdiff)) {
1616 if (
abs(maxdiff) > maxabsdiff) {
1618 os << var1name <<
"-" << var2name <<
" FAILED!\n";
1619 if (error_message.length()) os << error_message <<
"\n";
1620 os <<
"Max allowed deviation set to : " << maxabsdiff << endl
1621 <<
"but the tensors deviate with: " << maxdiff << endl;
1622 throw runtime_error(os.
str());
1626 out2 <<
" " << var1name <<
"-" << var2name
1627 <<
" OK (maximum difference = " << maxdiff <<
").\n";
1634 const String& error_message,
1645 if (var2.
ncols() != ncols || var2.
nrows() != nrows ||
1648 os << var1name <<
" and " << var2name <<
" do not have the same size.";
1649 throw runtime_error(os.
str());
1654 for (
Index c = 0; c < ncols; c++)
1656 for (
Index p = 0; p < npages; p++)
1657 for (
Index b = 0; b < nbooks; b++) {
1658 Numeric diff = var1(b, p,
r, c) - var2(b, p,
r, c);
1660 if (std::isnan(var1(b, p,
r, c)) || std::isnan(var2(b, p,
r, c))) {
1661 if (std::isnan(var1(b, p,
r, c)) && std::isnan(var2(b, p,
r, c))) {
1663 }
else if (std::isnan(var1(b, p,
r, c))) {
1665 os <<
"Nan found in " << var1name <<
", but there is no " 1666 <<
"NaN at same position in " << var2name <<
".\nThis " 1667 <<
"is not allowed.";
1668 throw runtime_error(os.
str());
1671 os <<
"Nan found in " << var2name <<
", but there is no " 1672 <<
"NaN at same position in " << var1name <<
".\nThis " 1673 <<
"is not allowed.";
1674 throw runtime_error(os.
str());
1678 if (
abs(diff) >
abs(maxdiff)) {
1683 if (
abs(maxdiff) > maxabsdiff) {
1685 os << var1name <<
"-" << var2name <<
" FAILED!\n";
1686 if (error_message.length()) os << error_message <<
"\n";
1687 os <<
"Max allowed deviation set to : " << maxabsdiff << endl
1688 <<
"but the tensors deviate with: " << maxdiff << endl;
1689 throw runtime_error(os.
str());
1693 out2 <<
" " << var1name <<
"-" << var2name
1694 <<
" OK (maximum difference = " << maxdiff <<
").\n";
1701 const String& error_message,
1713 if (var2.
ncols() != ncols || var2.
nrows() != nrows ||
1717 os << var1name <<
" and " << var2name <<
" do not have the same size.";
1718 throw runtime_error(os.
str());
1723 for (
Index c = 0; c < ncols; c++)
1725 for (
Index p = 0; p < npages; p++)
1726 for (
Index b = 0; b < nbooks; b++)
1727 for (
Index s = 0; s < nshelves; s++) {
1728 Numeric diff = var1(s, b, p,
r, c) - var2(s, b, p,
r, c);
1730 if (std::isnan(var1(s, b, p,
r, c)) ||
1731 std::isnan(var2(s, b, p,
r, c))) {
1732 if (std::isnan(var1(s, b, p,
r, c)) &&
1733 std::isnan(var2(s, b, p,
r, c))) {
1735 }
else if (std::isnan(var1(s, b, p,
r, c))) {
1737 os <<
"Nan found in " << var1name <<
", but there is no " 1738 <<
"NaN at same position in " << var2name <<
".\nThis " 1739 <<
"is not allowed.";
1740 throw runtime_error(os.
str());
1743 os <<
"Nan found in " << var2name <<
", but there is no " 1744 <<
"NaN at same position in " << var1name <<
".\nThis " 1745 <<
"is not allowed.";
1746 throw runtime_error(os.
str());
1750 if (
abs(diff) >
abs(maxdiff)) {
1755 if (
abs(maxdiff) > maxabsdiff) {
1757 os << var1name <<
"-" << var2name <<
" FAILED!\n";
1758 if (error_message.length()) os << error_message <<
"\n";
1759 os <<
"Max allowed deviation set to : " << maxabsdiff << endl
1760 <<
"but the tensors deviate with: " << maxdiff << endl;
1761 throw runtime_error(os.
str());
1765 out2 <<
" " << var1name <<
"-" << var2name
1766 <<
" OK (maximum difference = " << maxdiff <<
").\n";
1773 const String& error_message,
1787 if (var2.
ncols() != ncols || var2.
nrows() != nrows ||
1792 os << var1name <<
" and " << var2name <<
" do not have the same size.";
1793 throw runtime_error(os.
str());
1798 for (
Index c = 0; c < ncols; c++)
1800 for (
Index p = 0; p < npages; p++)
1801 for (
Index b = 0; b < nbooks; b++)
1802 for (
Index s = 0; s < nshelves; s++)
1803 for (
Index v = 0; v < nvitrines; v++)
1804 for (
Index l = 0; l < nlibraries; l++) {
1806 var1(l, v, s, b, p,
r, c) - var2(l, v, s, b, p,
r, c);
1808 if (std::isnan(var1(l, v, s, b, p,
r, c)) ||
1809 std::isnan(var2(l, v, s, b, p,
r, c))) {
1810 if (std::isnan(var1(l, v, s, b, p,
r, c)) &&
1811 std::isnan(var2(l, v, s, b, p,
r, c))) {
1813 }
else if (std::isnan(var1(l, v, s, b, p,
r, c))) {
1815 os <<
"Nan found in " << var1name <<
", but there is no " 1816 <<
"NaN at same position in " << var2name <<
".\nThis " 1817 <<
"is not allowed.";
1818 throw runtime_error(os.
str());
1821 os <<
"Nan found in " << var2name <<
", but there is no " 1822 <<
"NaN at same position in " << var1name <<
".\nThis " 1823 <<
"is not allowed.";
1824 throw runtime_error(os.
str());
1828 if (
abs(diff) >
abs(maxdiff)) {
1833 if (
abs(maxdiff) > maxabsdiff) {
1835 os << var1name <<
"-" << var2name <<
" FAILED!\n";
1836 if (error_message.length()) os << error_message <<
"\n";
1837 os <<
"Max allowed deviation set to : " << maxabsdiff << endl
1838 <<
"but the tensors deviate with: " << maxdiff << endl;
1839 throw runtime_error(os.
str());
1843 out2 <<
" " << var1name <<
"-" << var2name
1844 <<
" OK (maximum difference = " << maxdiff <<
").\n";
1851 const String& error_message,
1859 os <<
"The two arrays do not have the same size." << endl
1860 << var1name <<
" nelem: " << var1.
nelem() << endl
1861 << var2name <<
" nelem: " << var2.
nelem() << endl;
1862 throw runtime_error(os.
str());
1865 bool failed =
false;
1870 vn1 << var1name <<
"[" <<
i <<
"]";
1871 vn2 << var2name <<
"[" << i <<
"]";
1881 }
catch (
const std::runtime_error& e) {
1885 <<
"Mismatch at array index: " <<
i << endl;
1889 if (failed)
throw runtime_error(fail_msg.
str());
1896 const String& error_message,
1904 os <<
"The two arrays do not have the same size." << endl
1905 << var1name <<
" nelem: " << var1.
nelem() << endl
1906 << var2name <<
" nelem: " << var2.
nelem() << endl;
1907 throw runtime_error(os.
str());
1910 bool failed =
false;
1915 vn1 << var1name <<
"[" <<
i <<
"]";
1916 vn2 << var2name <<
"[" << i <<
"]";
1926 }
catch (
const std::runtime_error& e) {
1930 <<
"Mismatch at array index: " <<
i << endl;
1934 if (failed)
throw runtime_error(fail_msg.
str());
1941 const String& error_message,
1949 os <<
"The two arrays do not have the same size." << endl
1950 << var1name <<
" nelem: " << var1.
nelem() << endl
1951 << var2name <<
" nelem: " << var2.
nelem() << endl;
1952 throw runtime_error(os.
str());
1955 bool failed =
false;
1960 vn1 << var1name <<
"[" <<
i <<
"]";
1961 vn2 << var2name <<
"[" << i <<
"]";
1971 }
catch (
const std::runtime_error& e) {
1975 <<
"Mismatch at array index: " <<
i << endl;
1979 if (failed)
throw runtime_error(fail_msg.
str());
1986 const String& error_message,
1995 os << var1name <<
" and " << var2name <<
" grid " <<
i 1998 throw runtime_error(os.
str());
2002 os << var1name <<
" and " << var2name <<
" grid " <<
i 2005 throw runtime_error(os.
str());
2024 const String& error_message,
2033 if (var2.
nrows() != nrows || var2.
ncols() != ncols) {
2035 os << var1name <<
" (" << nrows <<
"," << ncols <<
") and " << var2name
2036 <<
" (" << var2.
nrows() <<
"," << var2.
ncols()
2037 <<
") do not have the same size.";
2038 throw runtime_error(os.
str());
2043 for (
Index r = 0;
r < nrows;
r++) {
2044 for (
Index c = 0; c < ncols; c++) {
2047 if (std::isnan(var1(
r, c)) || std::isnan(var2(
r, c))) {
2048 if (std::isnan(var1(
r, c)) && std::isnan(var2(
r, c))) {
2050 }
else if (std::isnan(var1(
r, c))) {
2052 os <<
"Nan found in " << var1name <<
", but there is no " 2053 <<
"NaN at same position in " << var2name <<
".\nThis " 2054 <<
"is not allowed.";
2055 throw runtime_error(os.
str());
2058 os <<
"Nan found in " << var2name <<
", but there is no " 2059 <<
"NaN at same position in " << var1name <<
".\nThis " 2060 <<
"is not allowed.";
2061 throw runtime_error(os.
str());
2065 if (
abs(diff) >
abs(maxdiff)) {
2071 if (
abs(maxdiff) > maxabsdiff) {
2073 os << var1name <<
"-" << var2name <<
" FAILED!\n";
2074 if (error_message.length()) os << error_message <<
"\n";
2075 os <<
"Max allowed deviation set to : " << maxabsdiff << endl
2076 <<
"but the matrices deviate with: " << maxdiff << endl;
2077 throw runtime_error(os.
str());
2081 out2 <<
" " << var1name <<
"-" << var2name
2082 <<
" OK (maximum difference = " << maxdiff <<
").\n";
2089 const String& error_message,
2097 os <<
"The particle types don't match: " << std::endl
2100 throw std::runtime_error(os.str());
2106 var1name +
".f_grid",
2107 var2name +
".f_grid",
2115 var1name +
".T_grid",
2116 var2name +
".T_grid",
2124 var1name +
".za_grid",
2125 var2name +
".za_grid",
2133 var1name +
".aa_grid",
2134 var2name +
".aa_grid",
2142 var1name +
".pha_mat_data",
2143 var2name +
".pha_mat_data",
2151 var1name +
".ext_mat_data",
2152 var2name +
".ext_mat_data",
2160 var1name +
".abs_vec_data",
2161 var2name +
".abs_vec_data",
2170 const String& error_message,
2176 if (var1 not_eq 0. and var2 not_eq 0.) {
2177 const Numeric absreldiff =
abs(var1 / var2 - 1);
2178 if (absreldiff > maxabsreldiff) {
2180 os << var1name <<
"-" << var2name <<
" FAILED!\n";
2181 if (error_message.length()) os << error_message <<
"\n";
2182 os <<
"Max allowed deviation set to: " << maxabsreldiff * 100.0 <<
"%" 2184 <<
"but the input deviate with: " << absreldiff * 100.0 <<
"%\n" 2185 <<
"If you compare non-scalar variables, the reported deviation is\n" 2186 <<
"the first one found violating the criterion. The maximum\n" 2187 <<
"difference can be higher.\n";
2188 throw runtime_error(os.
str());
2196 const String& error_message,
2203 if (var2.
nelem() not_eq n)
2204 throw std::runtime_error(
"Cannot compare variables of different size");
2220 const String& error_message,
2227 if (var2.
nrows() not_eq n)
2228 throw std::runtime_error(
"Cannot compare variables of different size");
2244 const String& error_message,
2251 if (var2.
npages() not_eq n)
2252 throw std::runtime_error(
"Cannot compare variables of different size");
2268 const String& error_message,
2275 if (var2.
nbooks() not_eq n)
2276 throw std::runtime_error(
"Cannot compare variables of different size");
2292 const String& error_message,
2300 throw std::runtime_error(
"Cannot compare variables of different size");
2316 const String& error_message,
2324 throw std::runtime_error(
"Cannot compare variables of different size");
2340 const String& error_message,
2348 throw std::runtime_error(
"Cannot compare variables of different size");
2364 const String& error_message,
2384 const String& error_message,
2405 const String& error_message,
2412 if (var2.
nelem() not_eq n)
2413 throw std::runtime_error(
"Cannot compare arrays of different length");
2430 const String& error_message,
2449 const String& error_message,
2468 const String& error_message,
2487 const String& error_message,
2506 const String& error_message,
2525 const String& error_message,
2544 const String& error_message,
2563 const String& error_message,
2582 const String& error_message,
2601 const String& error_message,
2620 const String& error_message,
2639 const String& error_message,
2658 const String& error_message,
2677 const String& error_message,
2696 const String& error_message,
2715 const String& error_message,
2734 const String& error_message,
2753 const String& error_message,
2772 const String& error_message,
2791 const String& error_message,
2810 const String& error_message,
2829 const String& error_message,
2849 const String& error_message,
2869 const String& error_message,
2889 const String& error_message,
2909 const String& error_message,
2930 const String& error_message,
2970 out0 << std::setprecision(15) << std::scientific;
2971 out0 <<
"---------------------------------------------------------\n" 2972 <<
"Numerical const in ARTS \tValue\n" 2973 <<
"Avogadro's constant: \t " << AVOGADROS_NUMB <<
'\n' 2974 <<
"Bohr's magneton: \t " << BOHR_MAGNETON <<
'\n' 2975 <<
"Boltzmann's constant: \t " << BOLTZMAN_CONST <<
'\n' 2976 <<
"Electron charge: \t" << ELECTRON_CHARGE <<
'\n' 2977 <<
"Electron mass: \t " << ELECTRON_MASS <<
'\n' 2978 <<
"Ideal gas constant: \t " << GAS_CONSTANT <<
'\n' 2979 <<
"Planck's constant: \t " << PLANCK_CONST <<
'\n' 2980 <<
"Speed of light: \t " << SPEED_OF_LIGHT <<
'\n' 2981 <<
"Vacuum permittivity: \t " << VACUUM_PERMITTIVITY <<
'\n' 2982 <<
"Doppler constant: \t " << DOPPLER_CONST <<
'\n' 2983 <<
"---------------------------------------------------------\n";
Index npages() const
Returns the number of pages.
INDEX Index
The type to use for all integer numbers and indices.
void RationalSet(Rational &x, const Index &numerator, const Index &denominator, const Verbosity &)
WORKSPACE METHOD: RationalSet.
const Numeric PLANCK_CONST
Global constant, the Planck constant [Js].
void NumericInvScale(Numeric &out, const Numeric &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: NumericInvScale.
void Tensor7Scale(Tensor7 &out, const Tensor7 &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: Tensor7Scale.
void VectorFlip(Vector &out, const Vector &in, const Verbosity &)
WORKSPACE METHOD: VectorFlip.
void SparseMatrixIdentity(Sparse &X, const Index &n, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: SparseMatrixIdentity.
const Numeric VACUUM_PERMITTIVITY
Global constant, the vacuum permittivity [F m-1].
Index nrows() const
Returns the number of rows.
void ArrayOfIndexLinSpace(ArrayOfIndex &x, const Index &start, const Index &stop, const Index &step, const Verbosity &verbosity)
WORKSPACE METHOD: ArrayOfIndexLinSpace.
void MatrixExtractFromTensor3(Matrix &m, const Tensor3 &t3, const Index &index, const String &direction, const Verbosity &)
WORKSPACE METHOD: MatrixExtractFromTensor3.
void VectorScale(Vector &out, const Vector &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: VectorScale.
void NumericSet(Numeric &x, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: NumericSet.
Index nelem() const
Number of elements.
void resize(Index s, Index b, Index p, Index r, Index c)
Resize function.
void Tensor5Scale(Tensor5 &out, const Tensor5 &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: Tensor5Scale.
void arts_exit(int status)
This is the exit function of ARTS.
void MatrixScale(Matrix &out, const Matrix &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: MatrixScale.
Declarations having to do with the four output streams.
const Numeric BOLTZMAN_CONST
Global constant, the Boltzmann constant [J/K].
A constant view of a Tensor7.
void RationalInvScale(Rational &out, const Rational &in, const Rational &value, const Verbosity &)
WORKSPACE METHOD: RationalInvScale.
void Matrix1ColFromVector(Matrix &m, const Vector &v, const Verbosity &)
WORKSPACE METHOD: Matrix1ColFromVector.
const Numeric ELECTRON_MASS
Global constant, the mass of an electron [kg].
const Numeric ELECTRON_CHARGE
Global constant, the charge of an electron [As] N.B.
void Matrix2RowFromVectors(Matrix &m, const Vector &v1, const Vector &v2, const Verbosity &)
WORKSPACE METHOD: Matrix2RowFromVectors.
const Numeric GAS_CONSTANT
Global constant, universal gas constant.
Index nvitrines() const
Returns the number of vitrines.
void VectorNLinSpace(Vector &x, const Index &n, const Numeric &start, const Numeric &stop, const Verbosity &verbosity)
WORKSPACE METHOD: VectorNLinSpace.
A constant view of a Tensor6.
void CompareRelative(const Numeric &var1, const Numeric &var2, const Numeric &maxabsreldiff, const String &error_message, const String &var1name, const String &var2name, const String &, const String &, const Verbosity &verbosity)
WORKSPACE METHOD: CompareRelative.
const Tensor4 & Data() const noexcept
Energy level type.
void VectorVectorMultiply(Vector &y, const Vector &x1, const Vector &x2, const Verbosity &)
WORKSPACE METHOD: VectorVectorMultiply.
bool is_increasing(ConstVectorView x)
Checks if a vector is sorted and strictly increasing.
void SparseSparseMultiply(Sparse &Y, const Sparse &M, const Sparse &X, const Verbosity &)
WORKSPACE METHOD: SparseSparseMultiply.
void Tensor6Scale(Tensor6 &out, const Tensor6 &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: Tensor6Scale.
void Tensor3SetConstant(Tensor3 &x, const Index &npages, const Index &nrows, const Index &ncols, const Numeric &value, const Verbosity &verbosity)
WORKSPACE METHOD: Tensor3SetConstant.
void IndexSet(Index &x, const Index &value, const Verbosity &)
WORKSPACE METHOD: IndexSet.
Index nrows() const
Returns the number of rows.
Linear algebra functions.
Index npages() const
Returns the number of pages.
void Matrix3RowFromVectors(Matrix &m, const Vector &v1, const Vector &v2, const Vector &v3, const Verbosity &)
WORKSPACE METHOD: Matrix3RowFromVectors.
void IndexAdd(Index &out, const Index &in, const Index &value, const Verbosity &)
WORKSPACE METHOD: IndexAdd.
Index ncols() const
Returns the number of columns.
const Vector & Energies() const noexcept
Energy level type.
void VectorInsertGridPoints(Vector &og, const Vector &ingrid, const Vector &points, const Verbosity &verbosity)
WORKSPACE METHOD: VectorInsertGridPoints.
Index nbooks() const
Returns the number of books.
Index nrows() const
Returns the number of rows.
void Tensor5SetConstant(Tensor5 &x, const Index &nshelves, const Index &nbooks, const Index &npages, const Index &nrows, const Index &ncols, const Numeric &value, const Verbosity &verbosity)
WORKSPACE METHOD: Tensor5SetConstant.
Stokes vector is as Propagation matrix but only has 4 possible values.
void NumericFromVector(Numeric &out, const Vector &in, const String &op, const Verbosity &)
WORKSPACE METHOD: NumericFromVector.
Index nrows() const
Returns the number of rows.
void Tensor4SetConstant(Tensor4 &x, const Index &nbooks, const Index &npages, const Index &nrows, const Index &ncols, const Numeric &value, const Verbosity &verbosity)
WORKSPACE METHOD: Tensor4SetConstant.
Index nelem() const
Returns the number of elements.
Contains sorting routines.
A constant view of a Tensor4.
void ArrayOfQuantumIdentifierSet(ArrayOfQuantumIdentifier &x, const ArrayOfString &values, const Verbosity &verbosity)
WORKSPACE METHOD: ArrayOfQuantumIdentifierSet.
This file contains the definition of Array.
void MatrixMatrixMultiply(Matrix &Y, const Matrix &M, const Matrix &X, const Verbosity &)
WORKSPACE METHOD: MatrixMatrixMultiply.
void FlagOn(Index &x, const Verbosity &)
WORKSPACE METHOD: FlagOn.
Index get_dim() const
Get the dimension of this gridded field.
void VectorLogSpace(Vector &x, const Numeric &start, const Numeric &stop, const Numeric &step, const Verbosity &verbosity)
WORKSPACE METHOD: VectorLogSpace.
Index ncols() const
Returns the number of columns.
void VectorSet(Vector &x, const Vector &values, const Verbosity &)
WORKSPACE METHOD: VectorSet.
void VectorReshapeMatrix(Vector &v, const Matrix &m, const String &direction, const Verbosity &)
WORKSPACE METHOD: VectorReshapeMatrix.
void Tensor3Scale(Tensor3 &out, const Tensor3 &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: Tensor3Scale.
void Tensor7SetConstant(Tensor7 &x, const Index &nlibraries, const Index &nvitrines, const Index &nshelves, const Index &nbooks, const Index &npages, const Index &nrows, const Index &ncols, const Numeric &value, const Verbosity &verbosity)
WORKSPACE METHOD: Tensor7SetConstant.
The global header file for ARTS.
Index nshelves() const
Returns the number of shelves.
Header file for sparse matrices.
void MatrixIdentity(Matrix &out, const Index &n, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: MatrixIdentity.
void MatrixSet(Matrix &x, const Matrix &values, const Verbosity &)
WORKSPACE METHOD: MatrixSet.
void RationalScale(Rational &out, const Rational &in, const Rational &value, const Verbosity &)
WORKSPACE METHOD: RationalScale.
_CS_string_type str() const
Index ncols() const
Returns the number of columns.
void Tensor3AddScalar(Tensor3 &out, const Tensor3 &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: Tensor3AddScalar.
void MatrixAddScalar(Matrix &out, const Matrix &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: MatrixAddScalar.
void VectorCrop(Vector &out, const Vector &in, const Numeric &min_value, const Numeric &max_value, const Verbosity &)
WORKSPACE METHOD: VectorCrop.
void Tensor4AddScalar(Tensor4 &out, const Tensor4 &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: Tensor4AddScalar.
void Tensor3ExtractFromTensor4(Tensor3 &t3, const Tensor4 &t4, const Index &index, const String &direction, const Verbosity &)
WORKSPACE METHOD: Tensor3ExtractFromTensor4.
Implements rational numbers to work with other ARTS types.
The declarations of all the exception classes.
void nlinspace(Vector &x, const Numeric start, const Numeric stop, const Index n)
nlinspace
Index get_grid_size(Index i) const
Get the size of a grid.
void ArrayOfStringSet(ArrayOfString &sa, const ArrayOfString &sa2, const Verbosity &)
WORKSPACE METHOD: ArrayOfStringSet.
void VectorExtractFromMatrix(Vector &v, const Matrix &m, const Index &index, const String &direction, const Verbosity &)
WORKSPACE METHOD: VectorExtractFromMatrix.
Index nrows() const
Returns the number of rows.
void MatrixVectorMultiply(Vector &Y, const Matrix &M, const Vector &X, const Verbosity &)
WORKSPACE METHOD: MatrixVectorMultiply.
Index nrows() const
Returns the number of rows.
Class to identify and match lines by their quantum numbers.
void VectorAddVector(Vector &c, const Vector &a, const Vector &b, const Verbosity &)
WORKSPACE METHOD: VectorAddVector.
void NumericAdd(Numeric &out, const Numeric &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: NumericAdd.
A constant view of a Tensor5.
NUMERIC Numeric
The type to use for all floating point numbers.
Index nlibraries() const
Returns the number of libraries.
Tensor4 & Data()
Get full view to data.
void VectorNLogSpace(Vector &x, const Index &n, const Numeric &start, const Numeric &stop, const Verbosity &verbosity)
WORKSPACE METHOD: VectorNLogSpace.
void Matrix1RowFromVector(Matrix &m, const Vector &v, const Verbosity &)
WORKSPACE METHOD: Matrix1RowFromVector.
void nlogspace(Vector &x, const Numeric start, const Numeric stop, const Index n)
nlogspace
Implementation of Matrix, Vector, and such stuff.
void ArrayOfIndexSetConstant(ArrayOfIndex &aoi, const Index &nelem, const Index &value, const Verbosity &)
WORKSPACE METHOD: ArrayOfIndexSetConstant.
Class to map energy levels.
void resize(Index p, Index r, Index c)
Resize function.
void _cr_internal_(const Numeric &var1, const Numeric &var2, const Numeric &maxabsreldiff, const String &error_message, const String &var1name, const String &var2name, const String &, const String &, const Verbosity &)
void get_sorted_indexes(ArrayOfIndex &sorted, const T &data)
get_sorted_indexes
void mult(ComplexVectorView y, const ConstComplexMatrixView &M, const ConstComplexVectorView &x)
Matrix-Vector Multiplication.
void RationalAdd(Rational &out, const Rational &in, const Rational &value, const Verbosity &)
WORKSPACE METHOD: RationalAdd.
const Numeric AVOGADROS_NUMB
Global constant, the Avogadro's number [molec/kg].
Header file for logic.cc.
void VectorMatrixMultiply(Vector &y, const Matrix &M, const Vector &x, const Verbosity &)
WORKSPACE METHOD: VectorMatrixMultiply.
basic_ostringstream< char, string_char_traits< char >, alloc > ostringstream
void VectorSetConstant(Vector &x, const Index &n, const Numeric &value, const Verbosity &verbosity)
WORKSPACE METHOD: VectorSetConstant.
Index npages() const
Returns the number of pages.
This can be used to make arrays out of anything.
void Matrix2ColFromVectors(Matrix &m, const Vector &v1, const Vector &v2, const Verbosity &)
WORKSPACE METHOD: Matrix2ColFromVectors.
Index nshelves() const
Returns the number of shelves.
Index ncols() const
Returns the number of columns.
void NumericScale(Numeric &out, const Numeric &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: NumericScale.
const Numeric BOHR_MAGNETON
Bohr Magneton.
void IndexStepDown(Index &xout, const Index &xin, const Verbosity &)
WORKSPACE METHOD: IndexStepDown.
const String & get_grid_name(Index i) const
Get grid name.
void resize(Index n)
Resize function.
void VectorSubtractVector(Vector &c, const Vector &a, const Vector &b, const Verbosity &)
WORKSPACE METHOD: VectorSubtractVector.
void Matrix3ColFromVectors(Matrix &m, const Vector &v1, const Vector &v2, const Vector &v3, const Verbosity &)
WORKSPACE METHOD: Matrix3ColFromVectors.
A constant view of a Tensor3.
void MatrixCopySparse(Matrix &out, const Sparse &in, const Verbosity &)
WORKSPACE METHOD: MatrixCopySparse.
void Compare(const Numeric &var1, const Numeric &var2, const Numeric &maxabsdiff, const String &error_message, const String &var1name, const String &var2name, const String &, const String &, const Verbosity &verbosity)
WORKSPACE METHOD: Compare.
A constant view of a Vector.
Index npages() const
Returns the number of pages.
void VectorAddScalar(Vector &out, const Vector &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: VectorAddScalar.
Index nshelves() const
Returns the number of shelves.
Numeric mean(const ConstVectorView &x)
Mean function, vector version.
Index nelem(const Lines &l)
Number of lines.
String PTypeToString(const PType &ptype)
Convert particle type enum value to String.
constexpr Rational start(Rational Ju, Rational Jl, Polarization type) noexcept
Gives the lowest M for a polarization type of this transition.
A constant view of a Matrix.
void Tensor4Scale(Tensor4 &out, const Tensor4 &in, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: Tensor4Scale.
Index npages() const
Returns the number of pages.
Index nbooks() const
Returns the number of books.
void resize(Index v, Index s, Index b, Index p, Index r, Index c)
Resize function.
void transform(VectorView y, double(&my_func)(double), ConstVectorView x)
A generic transform function for vectors, which can be used to implement mathematical functions opera...
void DiagonalMatrix(Matrix &X, const Vector &diag, const Verbosity &)
WORKSPACE METHOD: DiagonalMatrix.
Implementation of gridded fields.
void resize(Index r, Index c)
Resize function.
Index ncols() const
Returns the number of columns.
void MatrixSetConstant(Matrix &x, const Index &nrows, const Index &ncols, const Numeric &value, const Verbosity &)
WORKSPACE METHOD: MatrixSetConstant.
bool is_decreasing(ConstVectorView x)
Checks if a vector is sorted in reversed order and is strictly decreasing.
void QuantumIdentifierSet(QuantumIdentifier &x, const String &value, const Verbosity &)
WORKSPACE METHOD: QuantumIdentifierSet.
void id_mat(MatrixView I)
Identity Matrix.
Index nvitrines() const
Returns the number of vitrines.
void ArrayOfIndexSet(ArrayOfIndex &aoi, const ArrayOfIndex &values, const Verbosity &)
WORKSPACE METHOD: ArrayOfIndexSet.
Index ncols() const
Returns the number of columns.
Index ncols() const
Returns the number of columns.
const Numeric DOPPLER_CONST
void resize(Index l, Index v, Index s, Index b, Index p, Index r, Index c)
Resize function.
std::vector< T > linspace(T s, T e, typename std::vector< T >::size_type count) noexcept
const Numeric SPEED_OF_LIGHT
void VectorLinSpace(Vector &x, const Numeric &start, const Numeric &stop, const Numeric &step, const Verbosity &verbosity)
WORKSPACE METHOD: VectorLinSpace.
void Tensor6SetConstant(Tensor6 &x, const Index &nvitrines, const Index &nshelves, const Index &nbooks, const Index &npages, const Index &nrows, const Index &ncols, const Numeric &value, const Verbosity &verbosity)
WORKSPACE METHOD: Tensor6SetConstant.
void StringSet(String &s, const String &s2, const Verbosity &)
WORKSPACE METHOD: StringSet.
Scattering database structure and functions.
Index nrows() const
Returns the number of rows.
Index nbooks() const
Returns the number of books.
void IndexStepUp(Index &xout, const Index &xin, const Verbosity &)
WORKSPACE METHOD: IndexStepUp.
void FlagOff(Index &x, const Verbosity &)
WORKSPACE METHOD: FlagOff.
void resize(Index b, Index p, Index r, Index c)
Resize function.
void insert_elements(Index nnz, const ArrayOfIndex &rowind, const ArrayOfIndex &colind, ConstVectorView data)
Insert vector of elements with given row and column indices.
This file contains the definition of String, the ARTS string class.
void resize(Index r, Index c)
Resize function.
void PrintPhysicalConstants(const Verbosity &verbosity)
WORKSPACE METHOD: PrintPhysicalConstants.
Index nbooks() const
Returns the number of books.