1 #ifndef MHO_LinearAlgebraUtilities_HH__
2 #define MHO_LinearAlgebraUtilities_HH__
15 #define MHO_LINALG_PRINT_ERROR
17 #define MHO_CHECK_ARRAY_OVERRUN
56 #ifdef MHO_LINALG_PRINT_ERROR
103 unsigned int size()
const {
return fSize; };
115 void zero() { std::fill(fData.begin(), fData.end(), 0.0); }
120 #ifndef MHO_CHECK_ARRAY_OVERRUN
129 std::stringstream ss;
130 ss <<
"MHO_linalg_vector::operator() error, out of range: " << i <<
" !< " << fSize;
139 #ifndef MHO_CHECK_ARRAY_OVERRUN
148 std::stringstream ss;
149 ss <<
"MHO_linalg_vector::operator() error, out of range: " << i <<
" !< " << fSize;
161 this->fData = other.fData;
172 fData = std::move(other.fData);
179 if(this->fSize == other.
size())
181 for(
unsigned int i = 0; i < fSize; ++i)
183 this->fData[i] += other(i);
189 "MHO_linalg_vector::operator+= error, vectors have difference sizes.");
196 if(this->fSize == other.
size())
198 for(
unsigned int i = 0; i < fSize; ++i)
200 this->fData[i] -= other(i);
206 "MHO_linalg_vector::operator-= error, vectors have difference sizes.");
226 inline void scale(
const XValueType& scale_factor)
228 for(
unsigned int i = 0; i < fSize; ++i)
230 fData[i] *= scale_factor;
237 if(fSize == b.
size())
239 for(
unsigned int i = 0; i < fSize; i++)
241 val += fData[i] * b(i);
246 std::stringstream ss;
247 ss <<
"MHO_linalg_inner_product: error, vectors have different sizes: " << fSize <<
" != " << b.
size() <<
"."
256 XValueType val = 0.0;
257 for(
unsigned int i = 0; i < fSize; i++)
259 val += fData[i] * fData[i];
261 return std::sqrt(val);
269 this->
scale(1.0 / norm);
282 c(0) = fData[1] * b(2) - fData[2] * b(1);
283 c(1) = fData[2] * b(0) - fData[0] * b(2);
284 c(2) = fData[0] * b(1) - fData[1] * b(0);
289 "MHO_linalg_vector_cross_product: error, requires vectors of size 3");
296 std::vector< XValueType > fData;
310 : fNRows(nrows), fNCols(ncols), fTotalSize(nrows * ncols), fData(nrows * ncols, 0.0)
315 : fNRows(copy.fNRows), fNCols(copy.fNCols), fTotalSize(copy.fTotalSize), fData(copy.fData)
320 : fNRows(other.fNRows), fNCols(other.fNCols), fTotalSize(other.fTotalSize), fData(std::move(other.fData))
325 other.fTotalSize = 0;
331 void resize(
unsigned int nrows,
unsigned int ncols)
333 if(fTotalSize != nrows * ncols)
335 fData.resize(nrows * ncols);
339 fTotalSize = fNRows * fNCols;
342 unsigned int n_rows()
const {
return fNRows; };
344 unsigned int n_cols()
const {
return fNCols; };
348 for(
unsigned int i = 0; i < fNRows * fNCols; i++)
366 for(
unsigned int i = 0; i <
min; i++)
375 #ifndef MHO_CHECK_ARRAY_OVERRUN
376 return fData[i * fNCols + j];
378 if(i < fNRows && j < fNCols)
380 return fData[i * fNCols + j];
384 std::stringstream ss;
385 ss <<
"MHO_linalg_matrix::operator() error, out of range, row: " << i <<
" !< " << fNRows <<
" or col: " << j
393 const XValueType&
operator()(
unsigned int i,
unsigned int j)
const
395 #ifndef MHO_CHECK_ARRAY_OVERRUN
396 return fData[i * fNCols + j];
398 if(i < fNRows && j < fNCols)
400 return fData[i * fNCols + j];
404 std::stringstream ss;
405 ss <<
"MHO_linalg_matrix::operator() error, out of range, row: " << i <<
" !< " << fNRows <<
" or col: " << j
420 this->
resize(other.fNRows, other.fNCols);
421 this->fData = other.fData;
430 this->fNRows = other.fNRows;
431 this->fNCols = other.fNCols;
432 this->fTotalSize = other.fTotalSize;
433 this->fData = std::move(other.fData);
438 other.fTotalSize = 0;
445 if(this->fNRows == b.fNRows && this->fNCols == b.fNCols)
448 for(
unsigned int i = 0; i < this->fTotalSize; ++i)
450 this->fData[i] += b.fData[i];
456 "MHO_linalg_matrix::operator+: error, matrices have difference sizes.");
463 if(this->fNRows == b.fNRows && this->fNCols == b.fNCols)
466 for(
unsigned int i = 0; i < this->fTotalSize; ++i)
468 this->fData[i] -= b.fData[i];
474 "MHO_linalg_matrix::operator-: error, matrices have difference sizes.");
494 void scale(
const XValueType& scale_factor)
496 for(
unsigned int i = 0; i < this->fTotalSize; ++i)
498 this->fData[i] *= scale_factor;
506 for(
unsigned int i = 0; i < fTotalSize; ++i)
508 sum += fData[i] * fData[i];
510 return std::sqrt(sum);
516 unsigned int fTotalSize;
517 std::vector< XValueType > fData;
525 template<
typename XValueType =
double >
533 for(
unsigned int i = 0; i < m.
n_rows(); i++)
536 for(
unsigned int j = 0; j < m.
n_cols(); j++)
538 elem += m(i, j) * in(j);
545 std::stringstream ss;
546 ss <<
"MHO_linalg_matrix_vector_product: error, matrix/vector sizes are mismatched."
548 ss <<
"matrix m is " << m.
n_rows() <<
" by " << m.
n_cols() <<
"."
550 ss <<
"input vector has size " << in.
size() <<
"."
552 ss <<
"output vector has size " << out.
size() <<
"."
558 template<
typename XValueType =
double >
567 for(
unsigned int i = 0; i < m.
n_cols(); i++)
571 for(
unsigned int j = 0; j < m.
n_rows(); j++)
573 elem += m(j, i) * in(j);
580 std::stringstream ss;
581 ss <<
"MHO_linalg_matrix_transpose_vector_product: error, matrix/vector sizes are mismatched."
583 ss <<
"transpose of matrix m is " << m.
n_cols() <<
" by " << m.
n_rows() <<
"."
585 ss <<
"input vector has size " << in.
size() <<
"."
587 ss <<
"output vector has size " << out.
size() <<
"."
593 template<
typename XValueType =
double >
603 for(
unsigned int i = 0; i < p.
n_rows(); i++)
605 for(
unsigned int j = 0; j < p.
n_cols(); j++)
607 p(i, j) = a(i) * b(j);
617 template<
typename XValueType =
double >
622 unsigned int a_row = A.
n_rows();
623 unsigned int a_col = A.
n_cols();
625 unsigned int b_row = B.
n_rows();
626 unsigned int b_col = B.
n_cols();
628 unsigned int c_row = C.
n_rows();
629 unsigned int c_col = C.
n_cols();
631 if((a_col == b_row) && (c_row == a_row) && (c_col == b_col))
634 for(
unsigned int i = 0; i < c_row; i++)
636 for(
unsigned int j = 0; j < c_col; j++)
638 XValueType elem = 0.0;
640 for(
unsigned int offset = 0; offset < b_row; offset++)
642 elem += (A(i, offset)) * (B(offset, j));
650 std::stringstream ss;
651 ss <<
"MHO_linalg_matrix_multiply: error, matrices have different sizes."
653 ss <<
"matrix a is " << A.
n_rows() <<
" by " << A.
n_cols() <<
"."
655 ss <<
"matrix b is " << B.
n_rows() <<
" by " << B.
n_cols() <<
"."
657 ss <<
"matrix c is " << C.
n_rows() <<
" by " << C.
n_cols() <<
"."
664 template<
typename XValueType =
double >
674 template<
typename XValueType =
double >
679 unsigned int a_row = A.
n_rows();
680 unsigned int a_col = A.
n_cols();
684 unsigned int swap = a_col;
689 unsigned int b_row = B.
n_rows();
690 unsigned int b_col = B.
n_cols();
694 unsigned int swap = b_col;
699 unsigned int c_row = C.
n_rows();
700 unsigned int c_col = C.
n_cols();
702 unsigned int ai, aj, bi, bj;
704 if((a_col == b_row) && (c_row == a_row) && (c_col == b_col))
707 for(
unsigned int i = 0; i < c_row; i++)
709 for(
unsigned int j = 0; j < c_col; j++)
711 XValueType elem = 0.0;
713 for(
unsigned int offset = 0; offset < b_row; offset++)
737 elem += (A(ai, aj)) * (B(bi, bj));
746 std::stringstream ss;
747 ss <<
"MHO_linalg_matrix_multiply_with_transpose: error, matrices have different sizes."
749 ss <<
"matrix a is " << A.
n_rows() <<
" by " << A.
n_cols() <<
"."
751 ss <<
"matrix b is " << B.
n_rows() <<
" by " << B.
n_cols() <<
"."
753 ss <<
"matrix c is " << C.
n_rows() <<
" by " << C.
n_cols() <<
"."
760 template<
typename XValueType =
double >
766 unsigned int c_row = A.
n_rows();
767 unsigned int c_col = B.
n_cols();
781 template<
typename XValueType =
double >
795 unsigned int n = A.
n_rows();
796 unsigned int m = A.
n_cols();
800 std::stringstream ss;
801 ss <<
"MHO_linalg_matrix_svd: error, only tall (n_row >= m_cols) or square matrices supported."
803 ss <<
"matrix A is " << n <<
" by " << m <<
"."
808 if(
U.n_rows() != n ||
U.n_cols() != m)
810 std::stringstream ss;
811 ss <<
"MHO_linalg_matrix_svd: error, matrices A and U have different sizes, will resize U."
813 ss <<
"matrix A is " << n <<
" by " << m <<
"."
815 ss <<
"matrix U was " <<
U.n_rows() <<
" by " <<
U.n_cols() <<
"."
821 if(
V.n_rows() != m ||
V.n_cols() != m)
823 std::stringstream ss;
824 ss <<
"MHO_linalg_matrix_svd: error, matrix V has wrong size, will resize."
826 ss <<
"matrix V is " <<
V.n_rows() <<
" by " <<
V.n_cols() <<
"."
828 ss <<
"matrix V should be " << m <<
" by " << m <<
"."
836 std::stringstream ss;
837 ss <<
"MHO_linalg_matrix_svd: error, vector S has wrong size, will resize"
839 ss <<
"vector S is length " << S.
size() <<
"\n";
840 ss <<
"vector S should be length " << m <<
"."
852 int n_max_iter = 10 * m;
854 XValueType a, b, c, g1, g2, cs, sn,
t, psi, sign;
857 for(
unsigned int i = 0; i < n; i++)
859 for(
unsigned int j = 0; j < m; j++)
865 tol = tol * n * m * std::numeric_limits< XValueType >::epsilon() * std::numeric_limits< XValueType >::epsilon();
873 for(
unsigned int i = 0; i < m - 1; i++)
875 for(
unsigned int j = i + 1; j < m; j++)
883 for(
unsigned int k = 0; k < n; k++)
891 if((c * c) / (a * b) > tol)
894 psi = (b - a) / (2.0 * c);
900 t = (sign) / (std::fabs(psi) + std::sqrt(1.0 + psi * psi));
901 cs = 1.0 / std::sqrt(1.0 +
t *
t);
904 for(
unsigned int k = 0; k < n; k++)
909 U(k, i) = cs * g1 - sn * g2;
910 U(k, j) = sn * g1 + cs * g2;
912 for(
unsigned int k = 0; k < m; k++)
917 V(k, i) = cs * g1 - sn * g2;
918 V(k, j) = sn * g1 + cs * g2;
929 if(n_iter >= n_max_iter)
931 std::stringstream ss;
932 ss <<
"MHO_linalg_matrix_svd: error, SVD failed to converge within " << n_max_iter <<
" iterations, "
942 XValueType norm_s = 0.0;
943 for(
unsigned int i = 0; i < m; i++)
946 for(
unsigned int j = 0; j < n; j++)
955 norm_s = std::sqrt(norm_s);
956 tol = std::numeric_limits< XValueType >::epsilon() * norm_s;
958 for(
unsigned int i = 0; i < m; i++)
966 for(
unsigned int i = 0; i < n; i++)
968 for(
unsigned int j = 0; j < m; j++)
984 template<
typename XValueType =
double >
993 unsigned int nrows = in.
n_rows();
994 unsigned int ncols = in.
n_cols();
997 for(
unsigned int row = 0; row < nrows; row++)
999 for(
unsigned int col = 0; col < ncols; col++)
1001 temp = in(row, col);
1002 out(col, row) = temp;
1007 template<
typename XValueType =
double >
1026 double norm_s = S.
norm();
1027 for(
unsigned int i = 0; i < S.
size(); i++)
1030 if(s > std::numeric_limits< XValueType >::epsilon() * norm_s)
1033 elem = (1.0 / s) * x(i);
1049 for(
unsigned int i = 0; i < m.
n_rows(); i++)
1051 for(
unsigned int j = 0; j < (m.
n_cols() - 1); j++)
1053 std::cout << m(i, j) <<
", ";
1055 std::cout << m(i, m.
n_cols() - 1);
1056 std::cout << std::endl;
1062 for(
unsigned int j = 0; j < m.
size() - 1; j++)
1064 std::cout << m(j) <<
", ";
1066 std::cout << m(m.
size() - 1);
1067 std::cout << std::endl;
1073 unsigned int n = s.
size();
1076 for(
unsigned int i = 0; i < n; ++i)
1084 template<
typename XValueType >
1088 for(
unsigned int i = 0; i < A.
n_rows(); ++i)
1090 for(
unsigned int j = 0; j < A.
n_cols(); ++j)
#define msg_warn(xKEY, xCONTENT)
Definition: MHO_Message.hh:248
#define V
Definition: adump.h:36
#define U
Definition: adump.h:35
Definition: MHO_LinearAlgebraUtilities.hh:305
MHO_linalg_matrix & operator=(const MHO_linalg_matrix &other)
Definition: MHO_LinearAlgebraUtilities.hh:414
unsigned int n_cols() const
Definition: MHO_LinearAlgebraUtilities.hh:344
XValueType & operator()(unsigned int i, unsigned int j)
Definition: MHO_LinearAlgebraUtilities.hh:373
void zero()
Definition: MHO_LinearAlgebraUtilities.hh:346
MHO_linalg_matrix()
Definition: MHO_LinearAlgebraUtilities.hh:307
void resize(unsigned int nrows, unsigned int ncols)
Definition: MHO_LinearAlgebraUtilities.hh:331
const XValueType & operator()(unsigned int i, unsigned int j) const
Definition: MHO_LinearAlgebraUtilities.hh:393
MHO_linalg_matrix & operator+=(const MHO_linalg_matrix &b)
Definition: MHO_LinearAlgebraUtilities.hh:443
MHO_linalg_matrix & operator=(MHO_linalg_matrix &&other) noexcept
Definition: MHO_LinearAlgebraUtilities.hh:426
MHO_linalg_matrix operator-(const MHO_linalg_matrix &other)
Definition: MHO_LinearAlgebraUtilities.hh:486
void set_as_identity()
Definition: MHO_LinearAlgebraUtilities.hh:354
XValueType frobenius_norm()
Definition: MHO_LinearAlgebraUtilities.hh:503
unsigned int n_rows() const
Definition: MHO_LinearAlgebraUtilities.hh:342
MHO_linalg_matrix(MHO_linalg_matrix &&other)
Definition: MHO_LinearAlgebraUtilities.hh:319
MHO_linalg_matrix(unsigned int nrows, unsigned int ncols)
Definition: MHO_LinearAlgebraUtilities.hh:309
MHO_linalg_matrix(const MHO_linalg_matrix ©)
Definition: MHO_LinearAlgebraUtilities.hh:314
MHO_linalg_matrix operator+(const MHO_linalg_matrix &other)
Definition: MHO_LinearAlgebraUtilities.hh:479
void scale(const XValueType &scale_factor)
Definition: MHO_LinearAlgebraUtilities.hh:494
MHO_linalg_matrix & operator-=(const MHO_linalg_matrix &b)
Definition: MHO_LinearAlgebraUtilities.hh:461
Definition: MHO_LinearAlgebraUtilities.hh:85
MHO_linalg_vector(unsigned int sz)
Definition: MHO_LinearAlgebraUtilities.hh:89
MHO_linalg_vector(MHO_linalg_vector &&other) noexcept
Definition: MHO_LinearAlgebraUtilities.hh:96
MHO_linalg_vector()
Definition: MHO_LinearAlgebraUtilities.hh:87
MHO_linalg_vector operator-(const MHO_linalg_vector &other)
Definition: MHO_LinearAlgebraUtilities.hh:218
XValueType norm() const
Definition: MHO_LinearAlgebraUtilities.hh:254
XValueType inner_product(const MHO_linalg_vector &b) const
Definition: MHO_LinearAlgebraUtilities.hh:234
MHO_linalg_vector & operator=(const MHO_linalg_vector &other) noexcept
Definition: MHO_LinearAlgebraUtilities.hh:157
MHO_linalg_vector cross_product(const MHO_linalg_vector &b)
Definition: MHO_LinearAlgebraUtilities.hh:277
void zero()
Definition: MHO_LinearAlgebraUtilities.hh:115
unsigned int size() const
Definition: MHO_LinearAlgebraUtilities.hh:103
MHO_linalg_vector operator+(const MHO_linalg_vector &other)
Definition: MHO_LinearAlgebraUtilities.hh:211
XValueType & operator()(unsigned int i)
Definition: MHO_LinearAlgebraUtilities.hh:118
MHO_linalg_vector & operator+=(const MHO_linalg_vector &other)
Definition: MHO_LinearAlgebraUtilities.hh:177
const XValueType & operator()(unsigned int i) const
Definition: MHO_LinearAlgebraUtilities.hh:137
void normalize()
Definition: MHO_LinearAlgebraUtilities.hh:264
MHO_linalg_vector & operator=(MHO_linalg_vector &&other) noexcept
Definition: MHO_LinearAlgebraUtilities.hh:167
void resize(unsigned int sz)
Definition: MHO_LinearAlgebraUtilities.hh:105
void scale(const XValueType &scale_factor)
Definition: MHO_LinearAlgebraUtilities.hh:226
MHO_linalg_vector & operator-=(const MHO_linalg_vector &other)
Definition: MHO_LinearAlgebraUtilities.hh:194
MHO_linalg_vector(const MHO_linalg_vector ©) noexcept
Definition: MHO_LinearAlgebraUtilities.hh:98
#define min(a, b)
Definition: max555.c:9
void msg(const char *string, int level,...)
Definition: msg.c:25
t
Definition: picking_aedit.py:14
Definition: MHO_AdhocFlagging.hh:18
void report_error(MHO_linalg_error code, const std::string &msg)
Definition: MHO_LinearAlgebraUtilities.hh:48
MHO_linalg_error get_last_error() noexcept
Definition: MHO_LinearAlgebraUtilities.hh:65
void set_error_handler(MHO_linalg_error_handler handler)
Definition: MHO_LinearAlgebraUtilities.hh:75
void MHO_linalg_matrix_svd(const MHO_linalg_matrix< XValueType > &A, MHO_linalg_matrix< XValueType > &U, MHO_linalg_vector< XValueType > &S, MHO_linalg_matrix< XValueType > &V)
Definition: MHO_LinearAlgebraUtilities.hh:782
void MHO_linalg_matrix_multiply_with_transpose(bool transposeA, bool transposeB, const MHO_linalg_matrix< XValueType > &A, const MHO_linalg_matrix< XValueType > &B, MHO_linalg_matrix< XValueType > &C)
Definition: MHO_LinearAlgebraUtilities.hh:675
void MHO_linalg_matrix_transpose(const MHO_linalg_matrix< XValueType > &in, MHO_linalg_matrix< XValueType > &out)
Definition: MHO_LinearAlgebraUtilities.hh:985
void MHO_linalg_matrix_print(const MHO_linalg_matrix< XValueType > &m)
Definition: MHO_LinearAlgebraUtilities.hh:1047
thread_local MHO_linalg_error_handler error_handler
Definition: MHO_LinearAlgebraUtilities.hh:46
MHO_linalg_matrix< XValueType > MHO_linalg_diag_matrix(const MHO_linalg_vector< XValueType > &s)
Definition: MHO_LinearAlgebraUtilities.hh:1071
void MHO_linalg_vector_outer_product(const MHO_linalg_vector< XValueType > &a, const MHO_linalg_vector< XValueType > &b, MHO_linalg_matrix< XValueType > &p)
Definition: MHO_LinearAlgebraUtilities.hh:594
MHO_linalg_matrix< XValueType > MHO_linalg_transpose_matrix(const MHO_linalg_matrix< XValueType > &A)
Definition: MHO_LinearAlgebraUtilities.hh:1085
void MHO_linalg_vector_print(const MHO_linalg_vector< XValueType > &m)
Definition: MHO_LinearAlgebraUtilities.hh:1060
void MHO_linalg_matrix_vector_product(const MHO_linalg_matrix< XValueType > &m, const MHO_linalg_vector< XValueType > &in, MHO_linalg_vector< XValueType > &out)
Definition: MHO_LinearAlgebraUtilities.hh:526
std::function< void(MHO_linalg_error, const std::string &) > MHO_linalg_error_handler
Definition: MHO_LinearAlgebraUtilities.hh:45
void MHO_linalg_matrix_multiply(const MHO_linalg_matrix< XValueType > &A, const MHO_linalg_matrix< XValueType > &B, MHO_linalg_matrix< XValueType > &C)
Definition: MHO_LinearAlgebraUtilities.hh:618
thread_local MHO_linalg_error last_error
Definition: MHO_LinearAlgebraUtilities.hh:41
thread_local std::string last_error_msg
Definition: MHO_LinearAlgebraUtilities.hh:42
const std::string & get_last_error_message() noexcept
Definition: MHO_LinearAlgebraUtilities.hh:70
void MHO_linalg_matrix_svd_solve(const MHO_linalg_matrix< XValueType > &U, const MHO_linalg_vector< XValueType > &S, const MHO_linalg_matrix< XValueType > &V, const MHO_linalg_vector< XValueType > &b, MHO_linalg_vector< XValueType > &x)
Definition: MHO_LinearAlgebraUtilities.hh:1008
void MHO_linalg_matrix_transpose_vector_product(const MHO_linalg_matrix< XValueType > &m, const MHO_linalg_vector< XValueType > &in, MHO_linalg_vector< XValueType > &out)
Definition: MHO_LinearAlgebraUtilities.hh:559
MHO_linalg_error
Definition: MHO_LinearAlgebraUtilities.hh:28