add: matrix3d read from/dump to stream plus test
This commit is contained in:
parent
bd14b9c0ee
commit
08f4f1353f
@ -14,8 +14,8 @@
|
|||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
#include <iomanip>
|
||||||
#include <numeric>
|
#include <fstream>
|
||||||
|
|
||||||
|
|
||||||
TEST(TestMatrix, AddBlock)
|
TEST(TestMatrix, AddBlock)
|
||||||
@ -61,3 +61,21 @@ TEST(TestMatrix, AddRows)
|
|||||||
for (size_t i = 1; i <= 2; i++, fasit++)
|
for (size_t i = 1; i <= 2; i++, fasit++)
|
||||||
ASSERT_EQ(a(i,j), fasit);
|
ASSERT_EQ(a(i,j), fasit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST(TestMatrix3D, DumpRead)
|
||||||
|
{
|
||||||
|
size_t n0(2), n1(3), n2(4);
|
||||||
|
utl::matrix3d<double> A(n0, n1, n2);
|
||||||
|
Real* p = A.ptr();
|
||||||
|
for (size_t i = 0; i<A.size(); ++i, ++p)
|
||||||
|
*p = 3.14159*i*i;
|
||||||
|
|
||||||
|
std::string fname = std::tmpnam(nullptr);
|
||||||
|
std::ofstream os(fname);
|
||||||
|
os << std::setprecision(16) << A;
|
||||||
|
std::ifstream is(fname, std::ios::in);
|
||||||
|
utl::matrix3d<double> B(is);
|
||||||
|
B -= A;
|
||||||
|
ASSERT_NEAR(B.norm2(), 0.0, 1.0e-13);
|
||||||
|
}
|
||||||
|
@ -753,6 +753,32 @@ namespace utl //! General utility classes and functions.
|
|||||||
n[2] = n_3;
|
n[2] = n_3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! \brief Constructor to read a matrix from a stream.
|
||||||
|
matrix3d(std::istream& is, std::streamsize max = 10)
|
||||||
|
{
|
||||||
|
// Read size
|
||||||
|
is.ignore(10, ':');
|
||||||
|
is.ignore(1);
|
||||||
|
for (size_t i=0; i<3; ++i)
|
||||||
|
is >> n[i];
|
||||||
|
is.ignore(1, '\n');
|
||||||
|
|
||||||
|
// Read contents
|
||||||
|
double num;
|
||||||
|
elem.resize(n[0]*n[1]*n[2]);
|
||||||
|
for (size_t k=0; k<n[2]; ++k) {
|
||||||
|
is.ignore(max, '\n');
|
||||||
|
for (size_t i=0; i<n[0]; ++i) {
|
||||||
|
is.ignore(max, ':');
|
||||||
|
for (size_t j=0; j<n[1]; ++j) {
|
||||||
|
is >> num;
|
||||||
|
elem[n[0]*n[1]*k + n[0]*j + i] = num;
|
||||||
|
}
|
||||||
|
is.ignore(1, '\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//! \brief Resize the matrix to dimension \f$n_1 \times n_2 \times n_3\f$.
|
//! \brief Resize the matrix to dimension \f$n_1 \times n_2 \times n_3\f$.
|
||||||
//! \details Will erase the previous content, but only if both
|
//! \details Will erase the previous content, but only if both
|
||||||
//! the total matrix size, and n_1 or n_2 in the matrix are changed.
|
//! the total matrix size, and n_1 or n_2 in the matrix are changed.
|
||||||
@ -821,6 +847,13 @@ namespace utl //! General utility classes and functions.
|
|||||||
return elem[i1-1 + n[0]*((i2-1) + n[1]*(i3-1))];
|
return elem[i1-1 + n[0]*((i2-1) + n[1]*(i3-1))];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! \brief Add the given matrix \b X to \a *this.
|
||||||
|
matrix3d<T>& operator+=(const matrix3d<T>& X) { return this->add(X); }
|
||||||
|
//! \brief Subtract the given matrix \b X from \a *this.
|
||||||
|
matrix3d<T>& operator-=(const matrix3d<T>& X) { return this->add(X,T(-1)); }
|
||||||
|
//! \brief Add the given matrix \b X scaled by \a alfa to \a *this.
|
||||||
|
matrix3d<T>& add(const matrix3d<T>& X, T alfa = T(1));
|
||||||
|
|
||||||
//! \brief Access through pointer.
|
//! \brief Access through pointer.
|
||||||
T* ptr() { return &elem.front(); }
|
T* ptr() { return &elem.front(); }
|
||||||
//! \brief Reference through pointer.
|
//! \brief Reference through pointer.
|
||||||
@ -842,6 +875,9 @@ namespace utl //! General utility classes and functions.
|
|||||||
bool multiply(const matrix<T>& A, const matrix3d<T>& B,
|
bool multiply(const matrix<T>& A, const matrix3d<T>& B,
|
||||||
bool transA = false, bool addTo = false);
|
bool transA = false, bool addTo = false);
|
||||||
|
|
||||||
|
//! \brief Return the Euclidean norm of the matrix.
|
||||||
|
T norm2() const { return elem.norm2(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! \brief Check dimension compatibility for matrix-matrix multiplication.
|
//! \brief Check dimension compatibility for matrix-matrix multiplication.
|
||||||
bool compatible(const matrix<T>& A, const matrix3d<T>& B,
|
bool compatible(const matrix<T>& A, const matrix3d<T>& B,
|
||||||
@ -988,6 +1024,22 @@ namespace utl //! General utility classes and functions.
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<> inline
|
||||||
|
matrix3d<float>& matrix3d<float>::add(const matrix3d<float>& X, float alfa)
|
||||||
|
{
|
||||||
|
size_t n = this->size() < X.size() ? this->size() : X.size();
|
||||||
|
cblas_saxpy(n,alfa,X.ptr(),1,this->ptr(),1);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> inline
|
||||||
|
matrix3d<double>& matrix3d<double>::add(const matrix3d<double>& X, double alfa)
|
||||||
|
{
|
||||||
|
size_t n = this->size() < X.size() ? this->size() : X.size();
|
||||||
|
cblas_daxpy(n,alfa,X.ptr(),1,this->ptr(),1);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
template<> inline
|
template<> inline
|
||||||
matrix<float>& matrix<float>::multiply(float c)
|
matrix<float>& matrix<float>::multiply(float c)
|
||||||
{
|
{
|
||||||
@ -1407,6 +1459,16 @@ namespace utl //! General utility classes and functions.
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T> inline
|
||||||
|
matrix3d<T>& matrix3d<T>::add(const matrix3d<T>& X, T alfa)
|
||||||
|
{
|
||||||
|
T* p = this->ptr();
|
||||||
|
const T* q = X.ptr();
|
||||||
|
for (size_t i = 0; i < this->size() && i < X.size(); i++, p++, q++)
|
||||||
|
*p += alfa*(*q);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
template<class T> inline
|
template<class T> inline
|
||||||
matrix<T>& matrix<T>::multiply(T c)
|
matrix<T>& matrix<T>::multiply(T c)
|
||||||
{
|
{
|
||||||
@ -1626,7 +1688,7 @@ namespace utl //! General utility classes and functions.
|
|||||||
//! \brief Truncate a value to zero when it is less than a given threshold.
|
//! \brief Truncate a value to zero when it is less than a given threshold.
|
||||||
//! \details Used when printing matrices for easy comparison with other
|
//! \details Used when printing matrices for easy comparison with other
|
||||||
//! matrices when they contain terms that are numerically zero, except for
|
//! matrices when they contain terms that are numerically zero, except for
|
||||||
//! some round-off noice. The value of the global variable \a zero_print_tol
|
//! some round-off noise. The value of the global variable \a zero_print_tol
|
||||||
//! is used as a tolerance in this method.
|
//! is used as a tolerance in this method.
|
||||||
template<class T> inline T trunc(const T& v)
|
template<class T> inline T trunc(const T& v)
|
||||||
{
|
{
|
||||||
@ -1678,6 +1740,7 @@ namespace utl //! General utility classes and functions.
|
|||||||
if (A.empty())
|
if (A.empty())
|
||||||
return s <<" (empty)"<< std::endl;
|
return s <<" (empty)"<< std::endl;
|
||||||
|
|
||||||
|
s <<"Dimension: "<< A.dim(1) <<" "<< A.dim(2) <<" "<< A.dim(3);
|
||||||
matrix<T> B(A.dim(1),A.dim(2));
|
matrix<T> B(A.dim(1),A.dim(2));
|
||||||
const T* Aptr = A.ptr();
|
const T* Aptr = A.ptr();
|
||||||
for (size_t k = 0; k < A.dim(3); k++, Aptr += B.size())
|
for (size_t k = 0; k < A.dim(3); k++, Aptr += B.size())
|
||||||
|
Loading…
Reference in New Issue
Block a user