Heidelberg Educational Numerics Library Version 0.27 (from 15 March 2021)
densematrix.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2/*
3 * File: densematrix.hh
4 * Author: ngo
5 *
6 * Created on April 15, 2011
7 */
8
9#ifndef DENSEMATRIX_HH
10#define DENSEMATRIX_HH
11
12#include <cstdlib>
13#include <fstream>
14#include <iomanip>
15#include <iostream>
16#include <sstream>
17#include <string>
18
19#include "exceptions.hh"
20#include "sparsematrix.hh"
21#include "vector.hh"
22
23namespace hdnum {
24
25// forward-declare the sparse matrix template to make the transforming
26// constructor from hdnum::SparseMatrix -> hdnum::DenseMatrix working
27template <typename REAL>
28class SparseMatrix;
29
32template <typename REAL>
34public:
36 typedef std::size_t size_type;
37 typedef typename std::vector<REAL> VType;
38 typedef typename VType::const_iterator ConstVectorIterator;
39 typedef typename VType::iterator VectorIterator;
40
41private:
42 VType m_data; // Matrix data is stored in an STL vector!
43 std::size_t m_rows; // Number of Matrix rows
44 std::size_t m_cols; // Number of Matrix columns
45
46 static bool bScientific;
47 static std::size_t nIndexWidth;
48 static std::size_t nValueWidth;
49 static std::size_t nValuePrecision;
50
52 REAL myabs(REAL x) const {
53 if (x >= REAL(0))
54 return x;
55 else
56 return -x;
57 }
58
60 inline REAL& at(const std::size_t row, const std::size_t col) {
61 return m_data[row * m_cols + col];
62 }
63
65 inline const REAL& at(const std::size_t row, const std::size_t col) const {
66 return m_data[row * m_cols + col];
67 }
68
69public:
71 DenseMatrix() : m_data(0, 0), m_rows(0), m_cols(0) {}
72
74 DenseMatrix(const std::size_t _rows, const std::size_t _cols,
75 const REAL def_val = 0)
76 : m_data(_rows * _cols, def_val), m_rows(_rows), m_cols(_cols) {}
77
79 DenseMatrix(const std::initializer_list<std::initializer_list<REAL>>& v) {
80 m_rows = v.size();
81 m_cols = v.begin()->size();
82 for (auto row : v) {
83 if (row.size() != m_cols) {
84 std::cout << "Zeilen der Matrix nicht gleich lang" << std::endl;
85 exit(1);
86 }
87 for (auto elem : row) m_data.push_back(elem);
88 }
89 }
90
93 : m_data(other.rowsize() * other.colsize()), m_rows(other.rowsize()),
94 m_cols(other.colsize()) {
95 using counter_type = typename hdnum::SparseMatrix<REAL>::size_type;
96 counter_type row_index {};
97 for (auto& row : other) {
98 for (auto it = row.ibegin(); it != row.iend(); it++) {
99 this->operator[](row_index)[it.index()] = it.value();
100 }
101 row_index++;
102 }
103 }
104
105 void addNewRow(const hdnum::Vector<REAL>& rowvector) {
106 m_rows++;
107 m_cols = rowvector.size();
108 for (std::size_t i = 0; i < m_cols; i++) m_data.push_back(rowvector[i]);
109 }
110
111 /*
112 // copy constructor (not needed, since it inherits from the STL vector)
113 DenseMatrix( const DenseMatrix& A )
114 {
115 this->m_data = A.m_data;
116 m_rows = A.m_rows;
117 m_cols = A.m_cols;
118 }
119 */
120
136 size_t rowsize() const { return m_rows; }
137
153 size_t colsize() const { return m_cols; }
154
155 // pretty-print output properties
156 bool scientific() const { return bScientific; }
157
179 void scientific(bool b) const { bScientific = b; }
180
182 std::size_t iwidth() const { return nIndexWidth; }
183
185 std::size_t width() const { return nValueWidth; }
186
188 std::size_t precision() const { return nValuePrecision; }
189
191 void iwidth(std::size_t i) const { nIndexWidth = i; }
192
194 void width(std::size_t i) const { nValueWidth = i; }
195
197 void precision(std::size_t i) const { nValuePrecision = i; }
198
242 // overloaded element access operators
243 // write access on matrix element A_ij using A(i,j)
244 inline REAL& operator()(const std::size_t row, const std::size_t col) {
245 assert(row < m_rows || col < m_cols);
246 return at(row, col);
247 }
248
250 inline const REAL& operator()(const std::size_t row,
251 const std::size_t col) const {
252 assert(row < m_rows || col < m_cols);
253 return at(row, col);
254 }
255
257 const ConstVectorIterator operator[](const std::size_t row) const {
258 assert(row < m_rows);
259 return m_data.begin() + row * m_cols;
260 }
261
263 VectorIterator operator[](const std::size_t row) {
264 assert(row < m_rows);
265 return m_data.begin() + row * m_cols;
266 }
267
291 m_data = A.m_data;
292 m_rows = A.m_rows;
293 m_cols = A.m_cols;
294 return *this;
295 }
296
316 DenseMatrix& operator=(const REAL value) {
317 for (std::size_t i = 0; i < rowsize(); i++)
318 for (std::size_t j = 0; j < colsize(); j++) (*this)(i, j) = value;
319 return *this;
320 }
321
335 DenseMatrix A(rows, cols);
336 DenseMatrix& self = *this;
337 for (size_type k1 = 0; k1 < rows; k1++) {
338 for (size_type k2 = 0; k2 < cols; k2++) {
339 A[k1][k2] = self[k1 + i][k2 + j];
340 }
341 }
342 return A;
343 }
344
351 DenseMatrix A(m_cols, m_rows);
352 for (size_type i = 0; i < m_rows; i++) {
353 for (size_type j = 0; j < m_cols; j++) {
354 A[j][i] = this->operator[](i)[j];
355 }
356 }
357 return A;
358 }
359
360 // Basic Matrix Operations
361
370 for (size_type i = 0; i < rowsize(); ++i) {
371 for (size_type j = 0; j < colsize(); ++j) {
372 (*this)(i, j) += B(i, j);
373 }
374 }
375 return *this;
376 }
377
386 for (std::size_t i = 0; i < rowsize(); ++i)
387 for (std::size_t j = 0; j < colsize(); ++j)
388 (*this)(i, j) -= B(i, j);
389 return *this;
390 }
391
421 DenseMatrix& operator*=(const REAL s) {
422 for (std::size_t i = 0; i < rowsize(); ++i)
423 for (std::size_t j = 0; j < colsize(); ++j) (*this)(i, j) *= s;
424 return *this;
425 }
426
457 DenseMatrix& operator/=(const REAL s) {
458 for (std::size_t i = 0; i < rowsize(); ++i)
459 for (std::size_t j = 0; j < colsize(); ++j) (*this)(i, j) /= s;
460 return *this;
461 }
462
489 void update(const REAL s, const DenseMatrix& B) {
490 for (std::size_t i = 0; i < rowsize(); ++i)
491 for (std::size_t j = 0; j < colsize(); ++j)
492 (*this)(i, j) += s * B(i, j);
493 }
494
537 template <class V>
538 void mv(Vector<V>& y, const Vector<V>& x) const {
539 if (this->rowsize() != y.size())
540 HDNUM_ERROR("mv: size of A and y do not match");
541 if (this->colsize() != x.size())
542 HDNUM_ERROR("mv: size of A and x do not match");
543 for (std::size_t i = 0; i < rowsize(); ++i) {
544 y[i] = 0;
545 for (std::size_t j = 0; j < colsize(); ++j)
546 y[i] += (*this)(i, j) * x[j];
547 }
548 }
549
597 template <class V>
598 void umv(Vector<V>& y, const Vector<V>& x) const {
599 if (this->rowsize() != y.size())
600 HDNUM_ERROR("mv: size of A and y do not match");
601 if (this->colsize() != x.size())
602 HDNUM_ERROR("mv: size of A and x do not match");
603 for (std::size_t i = 0; i < rowsize(); ++i) {
604 for (std::size_t j = 0; j < colsize(); ++j)
605 y[i] += (*this)(i, j) * x[j];
606 }
607 }
608
659 template <class V>
660 void umv(Vector<V>& y, const V& s, const Vector<V>& x) const {
661 if (this->rowsize() != y.size())
662 HDNUM_ERROR("mv: size of A and y do not match");
663 if (this->colsize() != x.size())
664 HDNUM_ERROR("mv: size of A and x do not match");
665 for (std::size_t i = 0; i < rowsize(); ++i) {
666 for (std::size_t j = 0; j < colsize(); ++j)
667 y[i] += s * (*this)(i, j) * x[j];
668 }
669 }
670
719 void mm(const DenseMatrix<REAL>& A, const DenseMatrix<REAL>& B) {
720 if (this->rowsize() != A.rowsize())
721 HDNUM_ERROR("mm: size incompatible");
722 if (this->colsize() != B.colsize())
723 HDNUM_ERROR("mm: size incompatible");
724 if (A.colsize() != B.rowsize()) HDNUM_ERROR("mm: size incompatible");
725
726 for (std::size_t i = 0; i < rowsize(); i++)
727 for (std::size_t j = 0; j < colsize(); j++) {
728 (*this)(i, j) = 0;
729 for (std::size_t k = 0; k < A.colsize(); k++)
730 (*this)(i, j) += A(i, k) * B(k, j);
731 }
732 }
733
787 void umm(const DenseMatrix<REAL>& A, const DenseMatrix<REAL>& B) {
788 if (this->rowsize() != A.rowsize())
789 HDNUM_ERROR("mm: size incompatible");
790 if (this->colsize() != B.colsize())
791 HDNUM_ERROR("mm: size incompatible");
792 if (A.colsize() != B.rowsize()) HDNUM_ERROR("mm: size incompatible");
793
794 for (std::size_t i = 0; i < rowsize(); i++)
795 for (std::size_t j = 0; j < colsize(); j++)
796 for (std::size_t k = 0; k < A.colsize(); k++)
797 (*this)(i, j) += A(i, k) * B(k, j);
798 }
799
833 void sc(const Vector<REAL>& x, std::size_t k) {
834 if (this->rowsize() != x.size()) HDNUM_ERROR("cc: size incompatible");
835
836 for (std::size_t i = 0; i < rowsize(); i++) (*this)(i, k) = x[i];
837 }
838
874 void sr(const Vector<REAL>& x, std::size_t k) {
875 if (this->colsize() != x.size()) HDNUM_ERROR("cc: size incompatible");
876
877 for (std::size_t i = 0; i < colsize(); i++) (*this)(k, i) = x[i];
878 }
879
881 REAL norm_infty() const {
882 REAL norm(0.0);
883 for (std::size_t i = 0; i < rowsize(); i++) {
884 REAL sum(0.0);
885 for (std::size_t j = 0; j < colsize(); j++)
886 sum += myabs((*this)(i, j));
887 if (sum > norm) norm = sum;
888 }
889 return norm;
890 }
891
893 REAL norm_1() const {
894 REAL norm(0.0);
895 for (std::size_t j = 0; j < colsize(); j++) {
896 REAL sum(0.0);
897 for (std::size_t i = 0; i < rowsize(); i++)
898 sum += myabs((*this)(i, j));
899 if (sum > norm) norm = sum;
900 }
901 return norm;
902 }
903
950 assert(x.size() == colsize());
951
953 for (std::size_t r = 0; r < rowsize(); ++r) {
954 for (std::size_t c = 0; c < colsize(); ++c) {
955 y[r] += at(r, c) * x[c];
956 }
957 }
958 return y;
959 }
960
1004 assert(colsize() == x.rowsize());
1005
1006 const std::size_t out_rows = rowsize();
1007 const std::size_t out_cols = x.colsize();
1008 DenseMatrix y(out_rows, out_cols, 0.0);
1009 for (std::size_t r = 0; r < out_rows; ++r)
1010 for (std::size_t c = 0; c < out_cols; ++c)
1011 for (std::size_t i = 0; i < colsize(); ++i)
1012 y(r, c) += at(r, i) * x(i, c);
1013
1014 return y;
1015 }
1016
1060 assert(colsize() == x.colsize());
1061 assert(rowsize() == x.rowsize());
1062
1063 const std::size_t out_rows = rowsize();
1064 const std::size_t out_cols = x.colsize();
1065 DenseMatrix y(out_rows, out_cols, 0.0);
1066 y = *this;
1067 y += x;
1068 return y;
1069 }
1070
1114 assert(colsize() == x.colsize());
1115 assert(rowsize() == x.rowsize());
1116
1117 const std::size_t out_rows = rowsize();
1118 const std::size_t out_cols = x.colsize();
1119 DenseMatrix y(out_rows, out_cols, 0.0);
1120 y = *this;
1121 y -= x;
1122 return y;
1123 }
1124};
1125
1126template <typename REAL>
1127bool DenseMatrix<REAL>::bScientific = true;
1128template <typename REAL>
1129std::size_t DenseMatrix<REAL>::nIndexWidth = 10;
1130template <typename REAL>
1131std::size_t DenseMatrix<REAL>::nValueWidth = 10;
1132template <typename REAL>
1133std::size_t DenseMatrix<REAL>::nValuePrecision = 3;
1134
1158template <typename REAL>
1159inline std::ostream& operator<<(std::ostream& s, const DenseMatrix<REAL>& A) {
1160 s << std::endl;
1161 s << " " << std::setw(A.iwidth()) << " "
1162 << " ";
1163 for (typename DenseMatrix<REAL>::size_type j = 0; j < A.colsize(); ++j)
1164 s << std::setw(A.width()) << j << " ";
1165 s << std::endl;
1166
1167 for (typename DenseMatrix<REAL>::size_type i = 0; i < A.rowsize(); ++i) {
1168 s << " " << std::setw(A.iwidth()) << i << " ";
1169 for (typename DenseMatrix<REAL>::size_type j = 0; j < A.colsize();
1170 ++j) {
1171 if (A.scientific()) {
1172 s << std::setw(A.width()) << std::scientific << std::showpoint
1173 << std::setprecision(A.precision()) << A[i][j] << " ";
1174 } else {
1175 s << std::setw(A.width()) << std::fixed << std::showpoint
1176 << std::setprecision(A.precision()) << A[i][j] << " ";
1177 }
1178 }
1179 s << std::endl;
1180 }
1181 return s;
1182}
1183
1190template <typename REAL>
1191inline void fill(DenseMatrix<REAL>& A, const REAL& t) {
1192 for (typename DenseMatrix<REAL>::size_type i = 0; i < A.rowsize(); ++i)
1193 for (typename DenseMatrix<REAL>::size_type j = 0; j < A.colsize(); ++j)
1194 A[i][j] = t;
1195}
1196
1198template <typename REAL>
1199inline void zero(DenseMatrix<REAL>& A) {
1200 for (std::size_t i = 0; i < A.rowsize(); ++i)
1201 for (std::size_t j = 0; j < A.colsize(); ++j) A(i, j) = REAL(0);
1202}
1203
1237template <class T>
1238inline void identity(DenseMatrix<T>& A) {
1239 for (typename DenseMatrix<T>::size_type i = 0; i < A.rowsize(); ++i)
1240 for (typename DenseMatrix<T>::size_type j = 0; j < A.colsize(); ++j)
1241 if (i == j)
1242 A[i][i] = T(1);
1243 else
1244 A[i][j] = T(0);
1245}
1246
1282template <typename REAL>
1283inline void spd(DenseMatrix<REAL>& A) {
1284 if (A.rowsize() != A.colsize() || A.rowsize() == 0)
1285 HDNUM_ERROR("need square and nonempty matrix");
1286 for (std::size_t i = 0; i < A.rowsize(); ++i)
1287 for (std::size_t j = 0; j < A.colsize(); ++j)
1288 if (i == j)
1289 A(i, i) = REAL(4.0);
1290 else
1291 A(i, j) = -REAL(1.0) / ((i - j) * (i - j));
1292}
1293
1343template <typename REAL>
1345 if (A.rowsize() != A.colsize() || A.rowsize() == 0)
1346 HDNUM_ERROR("need square and nonempty matrix");
1347 if (A.rowsize() != x.size()) HDNUM_ERROR("need A and x of same size");
1348 for (typename DenseMatrix<REAL>::size_type i = 0; i < A.rowsize(); ++i) {
1349 REAL p(1.0);
1350 for (typename DenseMatrix<REAL>::size_type j = 0; j < A.colsize();
1351 ++j) {
1352 A[i][j] = p;
1353 p *= x[i];
1354 }
1355 }
1356}
1357
1359template <typename REAL>
1360inline void gnuplot(const std::string& fname, const DenseMatrix<REAL>& A) {
1361 std::fstream f(fname.c_str(), std::ios::out);
1362 for (typename DenseMatrix<REAL>::size_type i = 0; i < A.rowsize(); ++i) {
1363 for (typename DenseMatrix<REAL>::size_type j = 0; j < A.colsize();
1364 ++j) {
1365 if (A.scientific()) {
1366 f << std::setw(A.width()) << std::scientific << std::showpoint
1367 << std::setprecision(A.precision()) << A[i][j];
1368 } else {
1369 f << std::setw(A.width()) << std::fixed << std::showpoint
1370 << std::setprecision(A.precision()) << A[i][j];
1371 }
1372 }
1373 f << std::endl;
1374 }
1375 f.close();
1376}
1377
1407template <typename REAL>
1408inline void readMatrixFromFileDat(const std::string& filename,
1409 DenseMatrix<REAL>& A) {
1410 std::string buffer;
1411 std::ifstream fin(filename.c_str());
1412 std::size_t i = 0;
1413 std::size_t j = 0;
1414 if (fin.is_open()) {
1415 while (std::getline(fin, buffer)) {
1416 std::istringstream iss(buffer);
1418 while (iss) {
1419 std::string sub;
1420 iss >> sub;
1421 // std::cout << " sub = " << sub.c_str() << ": ";
1422 if (sub.length() > 0) {
1423 REAL a = atof(sub.c_str());
1424 // std::cout << std::fixed << std::setw(10) <<
1425 // std::setprecision(5) << a;
1426 rowvector.push_back(a);
1427 }
1428 j++;
1429 }
1430 if (rowvector.size() > 0) {
1431 A.addNewRow(rowvector);
1432 i++;
1433 // std::cout << std::endl;
1434 }
1435 }
1436 fin.close();
1437 } else {
1438 HDNUM_ERROR("Could not open file!");
1439 }
1440}
1441
1475template <typename REAL>
1476inline void readMatrixFromFileMatrixMarket(const std::string& filename,
1477 DenseMatrix<REAL>& A) {
1478 std::string buffer;
1479 std::ifstream fin(filename.c_str());
1480 std::size_t i = 0;
1481 std::size_t j = 0;
1482 if (fin.is_open()) {
1483 // ignore all comments from the file (starting with %)
1484 while (fin.peek() == '%') fin.ignore(2048, '\n');
1485
1486 std::getline(fin, buffer);
1487 std::istringstream first_line(buffer);
1488 first_line >> i >> j;
1490
1491 while (std::getline(fin, buffer)) {
1492 std::istringstream iss(buffer);
1493
1494 REAL value {};
1495 iss >> i >> j >> value;
1496 // i-1, j-1, because matrix market does not use zero based indexing
1497 A_temp(i - 1, j - 1) = value;
1498 }
1499 A = A_temp;
1500 fin.close();
1501 } else {
1502 HDNUM_ERROR("Could not open file! \"" + filename + "\"");
1503 }
1504}
1505
1506} // namespace hdnum
1507
1508#endif // DENSEMATRIX_HH
Class with mathematical matrix operations.
Definition densematrix.hh:33
VectorIterator operator[](const std::size_t row)
write-access on matrix element A_ij using A[i][j]
Definition densematrix.hh:263
const ConstVectorIterator operator[](const std::size_t row) const
read-access on matrix element A_ij using A[i][j]
Definition densematrix.hh:257
const REAL & operator()(const std::size_t row, const std::size_t col) const
read-access on matrix element A_ij using A(i,j)
Definition densematrix.hh:250
std::size_t iwidth() const
get index field width for pretty-printing
Definition densematrix.hh:182
REAL & operator()(const std::size_t row, const std::size_t col)
(i,j)-operator for accessing entries of a (m x n)-matrix directly
Definition densematrix.hh:244
REAL norm_infty() const
compute row sum norm
Definition densematrix.hh:881
void readMatrixFromFileMatrixMarket(const std::string &filename, DenseMatrix< REAL > &A)
Read matrix from a matrix market file.
Definition densematrix.hh:1476
void mv(Vector< V > &y, const Vector< V > &x) const
matrix vector product y = A*x
Definition densematrix.hh:538
void umm(const DenseMatrix< REAL > &A, const DenseMatrix< REAL > &B)
add matrix product A*B to matrix C
Definition densematrix.hh:787
DenseMatrix & operator/=(const REAL s)
Scalar division assignment.
Definition densematrix.hh:457
DenseMatrix & operator*=(const REAL s)
Scalar multiplication assignment.
Definition densematrix.hh:421
void umv(Vector< V > &y, const V &s, const Vector< V > &x) const
update matrix vector product y += sA*x
Definition densematrix.hh:660
DenseMatrix & operator=(const DenseMatrix &A)
assignment operator
Definition densematrix.hh:290
void width(std::size_t i) const
set data field width for pretty-printing
Definition densematrix.hh:194
void update(const REAL s, const DenseMatrix &B)
Scaled update of a Matrix.
Definition densematrix.hh:489
DenseMatrix operator-(const DenseMatrix &x) const
matrix = matrix - matrix
Definition densematrix.hh:1113
REAL norm_1() const
compute column sum norm
Definition densematrix.hh:893
DenseMatrix()
default constructor (empty Matrix)
Definition densematrix.hh:71
DenseMatrix sub(size_type i, size_type j, size_type rows, size_type cols)
Submatrix extraction.
Definition densematrix.hh:334
DenseMatrix & operator=(const REAL value)
assignment from a scalar value
Definition densematrix.hh:316
void sc(const Vector< REAL > &x, std::size_t k)
set column: make x the k'th column of A
Definition densematrix.hh:833
void sr(const Vector< REAL > &x, std::size_t k)
set row: make x the k'th row of A
Definition densematrix.hh:874
DenseMatrix(const std::initializer_list< std::initializer_list< REAL > > &v)
constructor from initializer list
Definition densematrix.hh:79
void identity(DenseMatrix< T > &A)
Definition densematrix.hh:1238
void scientific(bool b) const
Switch between floating point (default=true) and fixed point (false) display.
Definition densematrix.hh:179
DenseMatrix & operator-=(const DenseMatrix &B)
Subtraction assignment.
Definition densematrix.hh:385
void iwidth(std::size_t i) const
set index field width for pretty-printing
Definition densematrix.hh:191
std::size_t precision() const
get data precision for pretty-printing
Definition densematrix.hh:188
size_t rowsize() const
get number of rows of the matrix
Definition densematrix.hh:136
DenseMatrix(const std::size_t _rows, const std::size_t _cols, const REAL def_val=0)
constructor
Definition densematrix.hh:74
void readMatrixFromFileDat(const std::string &filename, DenseMatrix< REAL > &A)
Read matrix from a text file.
Definition densematrix.hh:1408
void spd(DenseMatrix< REAL > &A)
Definition densematrix.hh:1283
size_t colsize() const
get number of columns of the matrix
Definition densematrix.hh:153
DenseMatrix operator*(const DenseMatrix &x) const
matrix = matrix * matrix
Definition densematrix.hh:1003
std::size_t size_type
Type used for array indices.
Definition densematrix.hh:36
DenseMatrix operator+(const DenseMatrix &x) const
matrix = matrix + matrix
Definition densematrix.hh:1059
void precision(std::size_t i) const
set data precision for pretty-printing
Definition densematrix.hh:197
void umv(Vector< V > &y, const Vector< V > &x) const
update matrix vector product y += A*x
Definition densematrix.hh:598
DenseMatrix & operator+=(const DenseMatrix &B)
Addition assignment.
Definition densematrix.hh:369
void mm(const DenseMatrix< REAL > &A, const DenseMatrix< REAL > &B)
assign to matrix product C = A*B to matrix C
Definition densematrix.hh:719
std::size_t width() const
get data field width for pretty-printing
Definition densematrix.hh:185
DenseMatrix transpose() const
Transposition.
Definition densematrix.hh:350
Vector< REAL > operator*(const Vector< REAL > &x) const
vector = matrix * vector
Definition densematrix.hh:949
void vandermonde(DenseMatrix< REAL > &A, const Vector< REAL > x)
Definition densematrix.hh:1344
DenseMatrix(const hdnum::SparseMatrix< REAL > &other)
constructor from hdnum::SparseMatrix
Definition densematrix.hh:92
Sparse matrix Class with mathematical matrix operations.
Definition sparsematrix.hh:31
std::size_t size_type
Types used for array indices.
Definition sparsematrix.hh:34
Class with mathematical vector operations.
Definition vector.hh:31
A few common exception classes.