22#define fabs(x) std::fabs((x)*1.0)
35template <
typename T>
struct PIndex {
40 PIndex() :
count(0) {}
42 std::pair<T, int> operator()(
const T &A) {
return std::pair<T, int>(A, count++); }
52template <
typename T>
struct PSep {
54 int operator()(
const std::pair<T, int> &A) {
return A.second; }
63template <
typename T>
void indexSort(
const std::vector<T> &pVec, std::vector<int> &Index) {
64 Index.resize(pVec.size());
65 std::vector<typename std::pair<T, int>> PartList;
66 PartList.resize(pVec.size());
68 transform(pVec.begin(), pVec.end(), PartList.begin(), PIndex<T>());
69 sort(PartList.begin(), PartList.end());
70 transform(PartList.begin(), PartList.end(), Index.begin(), PSep<T>());
72template void indexSort(
const std::vector<double> &, std::vector<int> &);
73template void indexSort(
const std::vector<float> &, std::vector<int> &);
74template void indexSort(
const std::vector<int> &, std::vector<int> &);
78 std::vector<T> rez(m_numRows * m_numColumns);
80 for (
size_t i = 0; i < m_numRows; i++) {
81 for (
size_t j = 0; j < m_numColumns; j++) {
82 rez[ic] = m_rawData[i][j];
91 : m_numRows(0), m_numColumns(0)
108 : m_numRows(0), m_numColumns(0)
118 setMem(A.size(), B.size());
119 for (
size_t i = 0; i < m_numRows; i++) {
120 for (
size_t j = 0; j < m_numColumns; j++) {
121 m_rawData[i][j] = A[i] * B[j];
126template <
typename T>
Matrix<T>::Matrix(
const std::vector<T> &data) : m_numRows(0), m_numColumns(0) {
127 size_t numElements = data.size();
128 auto numRows =
static_cast<size_t>(sqrt(
double(numElements)));
130 if (numElements != numRowsSquare) {
131 throw(std::invalid_argument(
"number of elements in input vector have to be square of some value"));
146Matrix<T>::Matrix(
const std::vector<T> &data,
const size_t nrow,
const size_t ncol) : m_numRows(0), m_numColumns(0) {
147 size_t numel = data.size();
148 size_t test = nrow * ncol;
150 throw(std::invalid_argument(
"number of elements in input vector have is "
151 "incompatible with the number of rows and "
168 : m_numRows(A.m_numRows - 1), m_numColumns(A.m_numColumns - 1)
176 if (nrow > m_numRows)
178 if (ncol > m_numColumns)
180 setMem(m_numRows, m_numColumns);
182 for (
size_t i = 0; i <= m_numRows; i++) {
185 for (
size_t j = 0; j <= m_numColumns; j++) {
198 : m_numRows(0), m_numColumns(0)
225 if ((m_numRows * m_numColumns) > 0) {
226 for (
size_t i = 0; i < m_numRows; i++) {
227 for (
size_t j = 0; j < m_numColumns; j++) {
238 : m_numRows(other.m_numRows), m_numColumns(other.m_numColumns), m_rawDataAlloc(std::move(other.m_rawDataAlloc)),
239 m_rawData(std::move(other.m_rawData)) {
241 other.m_numColumns = 0;
245 m_numRows = other.m_numRows;
246 m_numColumns = other.m_numColumns;
247 m_rawData = std::move(other.m_rawData);
248 m_rawDataAlloc = std::move(other.m_rawDataAlloc);
251 other.m_numColumns = 0;
268 for (
size_t i = 0; i < Xpt; i++) {
269 for (
size_t j = 0; j < Ypt; j++) {
289 for (
size_t i = 0; i < Xpt; i++) {
290 for (
size_t j = 0; j < Ypt; j++) {
335 if (m_numColumns != A.m_numRows)
338 for (
size_t i = 0; i < m_numRows; i++) {
339 for (
size_t j = 0; j < A.m_numColumns; j++) {
340 for (
size_t kk = 0; kk < m_numColumns; kk++) {
341 X.m_rawData[i][j] += m_rawData[i][kk] * A.m_rawData[kk][j];
357 if (m_numColumns > Vec.size())
360 std::vector<T> Out(m_numRows);
361 for (
size_t i = 0; i < m_numRows; i++) {
362 for (
size_t j = 0; j < m_numColumns; j++) {
363 Out[i] += m_rawData[i][j] * Vec[j];
376 out.resize(m_numRows);
377 std::fill(std::begin(out), std::end(out),
static_cast<T
>(0.0));
378 if (m_numColumns > in.size())
380 for (
size_t i = 0; i < m_numRows; i++) {
381 for (
size_t j = 0; j < m_numColumns; j++) {
382 out[i] += m_rawData[i][j] * in[j];
396 if (m_numColumns != 3 || m_numRows > 3)
400 for (
size_t i = 0; i < m_numRows; ++i) {
401 v[i] = m_rawData[i][0] * Vx.
X() + m_rawData[i][1] * Vx.Y() + m_rawData[i][2] * Vx.Z();
416 for (
size_t i = 0; i < m_numRows; i++) {
417 for (
size_t j = 0; j < m_numColumns; j++) {
418 X.m_rawData[i][j] *= Value;
447 for (
size_t i = 0; i < m_numRows; i++) {
448 for (
size_t j = 0; j < m_numColumns; j++) {
449 m_rawData[i][j] *= Value;
463 for (
size_t i = 0; i < m_numRows; i++) {
464 for (
size_t j = 0; j < m_numColumns; j++) {
465 m_rawData[i][j] /= Value;
494 return this->
equals(A, 1e-8);
512 if (A.m_numRows != m_numRows || A.m_numColumns != m_numColumns)
517 for (
size_t i = 0; i < m_numRows; i++)
518 for (
size_t j = 0; j < m_numColumns; j++) {
519 const T diff = (m_rawData[i][j] - A.m_rawData[i][j]);
520 if (std::isnan(
static_cast<double>(diff))) {
521 maxDiff = std::numeric_limits<T>::max();
523 if (
fabs(diff) > maxDiff)
524 maxDiff =
fabs(diff);
526 if (
fabs(m_rawData[i][j]) > maxS)
527 maxS =
fabs(m_rawData[i][j]);
531 if (maxS > 1.0 && (maxDiff / maxS) <
Tolerance)
552 for (
size_t i = 0; i < m_numRows; i++)
553 for (
size_t j = 0; j < m_numColumns; j++) {
554 if (m_rawData[i][j] >= A.
m_rawData[i][j])
573 for (
size_t i = 0; i < m_numRows; i++)
574 for (
size_t j = 0; j < m_numColumns; j++) {
587 if (a == m_numRows && b == m_numColumns && m_rawData !=
nullptr)
590 if (a == 0 || b == 0)
600 auto allocatedMemory = std::make_unique<T[]>((m_numRows * m_numColumns));
604 auto rowPtrs = std::make_unique<T *[]>(m_numRows);
606 for (
size_t i = 0; i < m_numRows; i++) {
608 rowPtrs[i] = &allocatedMemory[i * m_numColumns];
611 m_rawDataAlloc = std::move(allocatedMemory);
612 m_rawData = std::move(rowPtrs);
621 if ((m_numRows * m_numColumns > 0) && RowI < m_numRows && RowJ < m_numRows && RowI != RowJ) {
622 for (
size_t k = 0; k < m_numColumns; k++) {
623 T
tmp = m_rawData[RowI][k];
624 m_rawData[RowI][k] = m_rawData[RowJ][k];
625 m_rawData[RowJ][k] =
tmp;
636 if ((m_numRows * m_numColumns) > 0 && colI < m_numColumns && colJ < m_numColumns && colI != colJ) {
637 for (
size_t k = 0; k < m_numRows; k++) {
638 T
tmp = m_rawData[k][colI];
639 m_rawData[k][colI] = m_rawData[k][colJ];
640 m_rawData[k][colJ] =
tmp;
651 if ((m_numRows * m_numColumns) > 0) {
652 for (
size_t i = 0; i < m_numRows; i++) {
653 for (
size_t j = 0; j < m_numColumns; j++) {
654 m_rawData[i][j] =
static_cast<T
>(0);
667 if ((m_numRows * m_numColumns) > 0) {
668 for (
size_t i = 0; i < m_numRows; i++) {
669 for (
size_t j = 0; j < m_numColumns; j++) {
670 m_rawData[i][j] =
static_cast<T
>(j == i);
676 if (nCol >= this->m_numColumns) {
677 throw(std::invalid_argument(
"nCol requested> nCol availible"));
679 size_t m_numRowsM = newCol.size();
680 if (m_numRows < m_numRowsM)
681 m_numRowsM = m_numRows;
682 for (
size_t i = 0; i < m_numRowsM; i++) {
683 m_rawData[i][nCol] = newCol[i];
687 if (nRow >= this->m_numRows) {
688 throw(std::invalid_argument(
"nRow requested> nRow availible"));
690 size_t m_numColumnsM = newRow.size();
691 if (m_numColumns < m_numColumnsM)
692 m_numColumnsM = m_numColumns;
693 for (
size_t j = 0; j < m_numColumnsM; j++) {
694 m_rawData[nRow][j] = newRow[j];
699void Matrix<T>::rotate(
const double tau,
const double s,
const int i,
const int j,
const int k,
const int m)
712 const T gg = m_rawData[i][j];
713 const T hh = m_rawData[k][
m];
714 m_rawData[i][j] =
static_cast<T
>(gg - s * (hh + gg * tau));
715 m_rawData[k][
m] =
static_cast<T
>(hh + s * (gg - hh * tau));
727 if (Dvec.size() != m_numRows) {
728 std::ostringstream cx;
729 cx <<
"Matrix::preMultiplyByDiagonal Size: " << Dvec.size() <<
" " << m_numRows <<
" " << m_numColumns;
730 throw std::runtime_error(cx.str());
733 for (
size_t i = 0; i < Dvec.size(); i++) {
734 for (
size_t j = 0; j < m_numColumns; j++) {
735 X.m_rawData[i][j] = Dvec[i] * m_rawData[i][j];
750 if (Dvec.size() != m_numColumns) {
751 std::ostringstream cx;
752 cx <<
"Error Matrix::bDiaognal size:: " << Dvec.size() <<
" " << m_numRows <<
" " << m_numColumns;
753 throw std::runtime_error(cx.str());
757 for (
size_t i = 0; i < m_numRows; i++) {
758 for (
size_t j = 0; j < Dvec.size(); j++) {
759 X.m_rawData[i][j] = Dvec[j] * m_rawData[i][j];
773 if ((m_numRows * m_numColumns) == 0)
776 if (m_numRows == m_numColumns)
785 for (
size_t i = 0; i < m_numRows; i++)
786 for (
size_t j = 0; j < m_numColumns; j++)
800 if ((m_numRows * m_numColumns) == 0)
803 if (m_numRows == m_numColumns)
805 for (
size_t i = 0; i < m_numRows; i++) {
806 for (
size_t j = i + 1; j < m_numColumns; j++) {
807 std::swap(m_rawData[i][j], m_rawData[j][i]);
816 auto allocatedMemory = std::make_unique<T[]>((m_numRows * m_numColumns));
817 auto transposePtrs = std::make_unique<T *[]>(m_numRows);
819 for (
size_t i = 0; i < m_numColumns; i++) {
821 transposePtrs[i] = &allocatedMemory[i * m_numRows];
824 for (
size_t i = 0; i < m_numRows; i++) {
825 for (
size_t j = 0; j < m_numColumns; j++) {
826 transposePtrs[j][i] = m_rawData[i][j];
830 std::swap(m_numRows, m_numColumns);
832 m_rawDataAlloc = std::move(allocatedMemory);
833 m_rawData = std::move(transposePtrs);
849 if (m_numRows != m_numColumns || B.
m_numRows != m_numRows) {
850 throw std::invalid_argument(
"Matrix not square, or sizes do not match");
854 std::vector<int> pivoted(m_numRows);
855 fill(pivoted.begin(), pivoted.end(), 0);
857 std::vector<int> indxcol(m_numRows);
858 std::vector<int> indxrow(m_numRows);
860 size_t irow(0), icol(0);
861 for (
size_t i = 0; i < m_numRows; i++) {
863 double bigItem = 0.0;
864 for (
size_t j = 0; j < m_numRows; j++) {
867 for (
size_t k = 0; k < m_numRows; k++) {
869 if (
fabs(m_rawData[j][k]) >= bigItem) {
870 bigItem =
fabs(m_rawData[j][k]);
881 swapRows(irow, icol);
884 indxrow[i] =
static_cast<int>(irow);
885 indxcol[i] =
static_cast<int>(icol);
887 if (m_rawData[icol][icol] == 0.0) {
888 throw std::runtime_error(
"Error doing G-J elem on a singular matrix");
890 const T pivDiv = T(1.0) / m_rawData[icol][icol];
891 m_rawData[icol][icol] = 1;
892 for (
size_t l = 0; l < m_numRows; l++) {
893 m_rawData[icol][l] *= pivDiv;
899 for (
size_t ll = 0; ll < m_numRows; ll++) {
901 const T div_num = m_rawData[ll][icol];
902 m_rawData[ll][icol] = 0.0;
903 for (
size_t l = 0; l < m_numRows; l++) {
904 m_rawData[ll][l] -= m_rawData[icol][l] * div_num;
915 for (
int l =
static_cast<int>(m_numRows) - 1; l >= 0; l--) {
916 if (indxrow[l] != indxcol[l]) {
917 swapCols(indxrow[l], indxcol[l]);
931 if (m_numRows != m_numColumns && m_numRows < 1)
934 if (m_numRows == 1) {
935 T det = m_rawData[0][0];
936 if (m_rawData[0][0] !=
static_cast<T
>(0.))
937 m_rawData[0][0] =
static_cast<T
>(1.) / m_rawData[0][0];
940 std::vector<int> indx(m_numRows);
941 std::vector<double> col(m_numRows);
945 Lcomp.
lubcmp(indx.data(), determinant);
947 auto det =
static_cast<double>(determinant);
948 for (
size_t j = 0; j < m_numRows; j++)
951 for (
size_t j = 0; j < m_numRows; j++) {
952 for (
size_t i = 0; i < m_numRows; i++)
955 Lcomp.
lubksb(indx.data(), col.data());
956 for (
size_t i = 0; i < m_numRows; i++)
957 m_rawData[i][j] =
static_cast<T
>(col[i]);
959 return static_cast<T
>(det);
970 if ((numRows() > 1) && (numCols() > 1)) {
971 if (numRows() == numCols()) {
972 std::vector<T> diagonal = {m_rawData[0][0], m_rawData[1][0]};
973 for (
size_t i = 1; i < numRows() && regular; i++) {
974 for (
size_t j = 1; i < numCols() && regular; i++) {
975 size_t diff = std::abs(
static_cast<int>(i - j));
977 if (std::abs(diagonal[diff] - m_rawData[i][j]) > std::numeric_limits<double>::epsilon()) {
980 }
else if (m_rawData[i][j] != 0) {
981 throw std::runtime_error(
"Matrix is not tridiagonal");
991 T scalefactor = numRows() > 1 ? m_rawData[1][0] : 1;
992 *
this /= scalefactor;
993 long double D = m_rawData[0][0];
994 long double k =
static_cast<long double>(numRows());
996 for (
size_t i = 0; i < numRows(); i++) {
997 for (
size_t j = 0; j < numCols(); j++) {
999 auto iMinusj = std::abs(
static_cast<long double>(i) -
static_cast<long double>(j));
1000 auto iPlusj =
static_cast<long double>(i + j);
1002 m_rawData[i][j] =
static_cast<T
>(std::pow(-1.0, iPlusj));
1003 lambda = std::acosh(D / 2.0);
1004 }
else if (D > -2.0) {
1005 m_rawData[i][j] = 1;
1006 lambda = std::acos(-D / 2.0);
1008 m_rawData[i][j] = -1;
1009 lambda = std::acosh(-D / 2.0);
1011 if (std::abs(D) > 2.0) {
1012 long double a, b, c;
1013 if (((k + 1) * std::asinh(D / 2.0)) <= std::asinh(std::numeric_limits<long double>::max())) {
1014 a = std::cosh((k + 1 - iMinusj) *
lambda);
1015 b = std::cosh((k + 1 - iPlusj - 2) *
lambda);
1016 c = 2 * std::sinh(
lambda) * std::sinh((k + 1) *
lambda);
1019 a = std::exp(-iMinusj *
lambda);
1020 b = std::exp(-(iPlusj + 2) *
lambda) + std::exp(-(2 * k - iPlusj) *
lambda);
1021 c = 2 * std::sinh(
lambda);
1024 long double value = m_rawData[i][j];
1025 value *= (a - b) / c;
1026 m_rawData[i][j] =
static_cast<T
>(
value);
1027 }
else if (std::abs(D) == 2.0) {
1028 long double value = m_rawData[i][j];
1029 value *= (2 * k + 2 - iMinusj - iPlusj - 2) * (iPlusj + 2 - iMinusj);
1030 value /= (4 * (k + 1));
1031 m_rawData[i][j] =
static_cast<T
>(
value);
1033 long double value = m_rawData[i][j];
1035 std::cos((k + 1 - iPlusj - 2) *
lambda);
1037 m_rawData[i][j] =
static_cast<T
>(
value);
1041 *
this /= scalefactor;
1047template <
typename T>
1054 if (m_numRows != m_numColumns)
1062template <
typename T>
1071 if (m_numRows != m_numColumns || m_numRows < 1)
1072 throw std::runtime_error(
"Matrix::factor Matrix is not square");
1075 for (
int i = 0; i < static_cast<int>(m_numRows) - 1; i++)
1078 double Pmax =
fabs(m_rawData[i][i]);
1079 for (
int j = i + 1; j < static_cast<int>(m_numRows); j++)
1081 if (
fabs(m_rawData[i][j]) > Pmax) {
1082 Pmax =
fabs(m_rawData[i][j]);
1097 Pmax = m_rawData[i][i];
1099 for (
int k = i + 1; k < static_cast<int>(m_numRows); k++)
1101 const double scale = m_rawData[k][i] / Pmax;
1102 m_rawData[k][i] =
static_cast<T
>(0);
1103 for (
int q = i + 1; q < static_cast<int>(m_numRows); q++)
1104 m_rawData[k][q] -=
static_cast<T
>(scale * m_rawData[i][q]);
1107 deter *= m_rawData[m_numRows - 1][m_numRows - 1];
1108 return static_cast<T
>(deter);
1111template <
typename T>
1118 for (
size_t i = 0; i < m_numRows; i++) {
1120 for (
size_t j = 0; j < m_numColumns; j++) {
1121 sum += m_rawData[i][j] * m_rawData[i][j];
1123 sum =
static_cast<T
>(std::sqrt(
static_cast<double>(sum)));
1124 for (
size_t j = 0; j < m_numColumns; j++) {
1125 m_rawData[i][j] /= sum;
1130template <
typename T>
1138 for (
size_t i = 0; i < m_numRows; i++) {
1139 for (
size_t j = 0; j < m_numColumns; j++) {
1140 sum += m_rawData[i][j] * m_rawData[i][j];
1146template <
typename T>
1155 double sum, dum, big, temp;
1157 if (m_numRows != m_numColumns || m_numRows < 2) {
1158 std::cerr <<
"Error with lubcmp\n";
1161 std::vector<double> result(m_numRows);
1163 for (
int i = 0; i < static_cast<int>(m_numRows); i++) {
1165 for (
int j = 0; j < static_cast<int>(m_numRows); j++)
1166 if ((temp =
fabs(m_rawData[i][j])) > big)
1170 for (
int j = 0; j < static_cast<int>(m_numRows); j++) {
1175 result[i] = 1.0 / big;
1178 for (
int j = 0; j < static_cast<int>(m_numRows); j++) {
1179 for (
int i = 0; i < j; i++) {
1180 sum = m_rawData[i][j];
1181 for (
int k = 0; k < i; k++)
1182 sum -= m_rawData[i][k] * m_rawData[k][j];
1183 m_rawData[i][j] =
static_cast<T
>(sum);
1187 for (
int i = j; i < static_cast<int>(m_numRows); i++) {
1188 sum = m_rawData[i][j];
1189 for (
int k = 0; k < j; k++)
1190 sum -= m_rawData[i][k] * m_rawData[k][j];
1191 m_rawData[i][j] =
static_cast<T
>(sum);
1192 if ((dum = result[i] *
fabs(sum)) >= big) {
1199 for (
int k = 0; k < static_cast<int>(m_numRows); k++) {
1200 dum = m_rawData[imax][k];
1201 m_rawData[imax][k] = m_rawData[j][k];
1202 m_rawData[j][k] =
static_cast<T
>(dum);
1205 result[imax] =
static_cast<T
>(result[j]);
1209 if (m_rawData[j][j] == 0.0)
1210 m_rawData[j][j] =
static_cast<T
>(1e-14);
1211 if (j !=
static_cast<int>(m_numRows) - 1) {
1212 dum = 1.0 / (m_rawData[j][j]);
1213 for (
int i = j + 1; i < static_cast<int>(m_numRows); i++)
1214 m_rawData[i][j] *=
static_cast<T
>(dum);
1219template <
typename T>
1228 for (
int i = 0; i < static_cast<int>(m_numRows); i++) {
1229 int ip = rowperm[i];
1233 for (
int j = ii; j < i; j++)
1234 sum -= m_rawData[i][j] * b[j];
1240 for (
int i =
static_cast<int>(m_numRows) - 1; i >= 0; i--) {
1242 for (
int j = i + 1; j < static_cast<int>(m_numRows); j++)
1243 sum -= m_rawData[i][j] * b[j];
1244 b[i] = sum / m_rawData[i][i];
1248template <
typename T>
1255 const size_t minSize = (m_numRows > m_numColumns) ? m_numColumns : m_numRows;
1256 for (
size_t i = 0; i < minSize; i++) {
1257 for (
size_t j = i + 1; j < minSize; j++) {
1258 m_rawData[i][j] = (m_rawData[i][j] + m_rawData[j][i]) / 2;
1259 m_rawData[j][i] = m_rawData[i][j];
1264template <
typename T>
1271 const size_t Msize = (m_numColumns > m_numRows) ? m_numRows : m_numColumns;
1272 std::vector<T> Diag(Msize);
1273 for (
size_t i = 0; i < Msize; i++) {
1274 Diag[i] = m_rawData[i][i];
1279template <
typename T>
1286 const size_t Msize = (m_numColumns > m_numRows) ? m_numRows : m_numColumns;
1288 for (
size_t i = 0; i < Msize; i++) {
1289 Trx += m_rawData[i][i];
1294template <
typename T>
1302 if (m_numColumns != m_numRows || m_numRows != DiagMatrix.
m_numRows || m_numRows != DiagMatrix.
m_numColumns) {
1303 std::cerr <<
"Matrix not Eigen Form\n";
1304 throw(std::invalid_argument(
" Matrix is not in an eigenvalue format"));
1306 std::vector<int>
index;
1307 std::vector<T>
X = DiagMatrix.
Diagonal();
1310 for (
size_t Icol = 0; Icol < m_numRows; Icol++) {
1311 for (
size_t j = 0; j < m_numRows; j++) {
1312 m_rawData[j][Icol] = EigenVec[j][
index[Icol]];
1314 DiagMatrix[Icol][Icol] =
X[
index[Icol]];
1318template <
typename T>
1327 if (m_numRows != m_numColumns || m_numRows < 1) {
1328 std::cerr <<
"Matrix not square\n";
1331 for (
size_t i = 0; i < m_numRows; i++)
1332 for (
size_t j = i + 1; j < m_numRows; j++)
1333 if (
fabs(m_rawData[i][j] - m_rawData[j][i]) > 1e-6) {
1334 std::cerr <<
"Matrix not symmetric\n";
1335 std::cerr << (*this);
1341 EigenVec.setMem(m_numRows, m_numRows);
1342 EigenVec.identityMatrix();
1343 DiagMatrix.setMem(m_numRows, m_numRows);
1344 DiagMatrix.zeroMatrix();
1346 std::vector<double> Diag(m_numRows);
1347 std::vector<double> B(m_numRows);
1348 std::vector<double> ZeroComp(m_numRows);
1350 for (
size_t i = 0; i < m_numRows; i++) {
1356 for (
int i = 0; i < 100; i++)
1359 for (
size_t ip = 0; ip < m_numRows - 1; ip++)
1360 for (
size_t iq = ip + 1; iq < m_numRows; iq++)
1367 for (
size_t ix = 0; ix < m_numRows; ix++)
1368 DiagMatrix.m_rawData[ix][ix] =
static_cast<T
>(Diag[ix]);
1373 double tresh = (i < 6) ? 0.2 * sm /
static_cast<int>(m_numRows * m_numRows) : 0.0;
1375 for (
int ip = 0; ip < static_cast<int>(m_numRows) - 1; ip++) {
1376 for (
int iq = ip + 1; iq < static_cast<int>(m_numRows); iq++) {
1379 if (i > 6 &&
static_cast<float>(
fabs(Diag[ip] + g)) ==
static_cast<float>(
fabs(Diag[ip])) &&
1380 static_cast<float>(
fabs(Diag[iq] + g)) ==
static_cast<float>(
fabs(Diag[iq])))
1384 double tanAngle, cosAngle, sinAngle;
1385 double h = Diag[iq] - Diag[ip];
1386 double cot2Theta = 0.5 * h / A.
m_rawData[ip][iq];
1388 tanAngle = 1.0 / (
fabs(cot2Theta) + sqrt(1.0 + pow(cot2Theta, 2)));
1389 if (cot2Theta < 0.0)
1390 tanAngle = -tanAngle;
1391 cosAngle = 1.0 / sqrt(1 + tanAngle * tanAngle);
1392 sinAngle = tanAngle * cosAngle;
1393 double tau = sinAngle / (1.0 + cosAngle);
1401 for (
int j = 0; j < ip; j++)
1402 A.
rotate(tau, sinAngle, j, ip, j, iq);
1403 for (
int j = ip + 1; j < iq; j++)
1404 A.
rotate(tau, sinAngle, ip, j, j, iq);
1405 for (
int j = iq + 1; j < static_cast<int>(m_numRows); j++)
1406 A.
rotate(tau, sinAngle, ip, j, iq, j);
1407 for (
int j = 0; j < static_cast<int>(m_numRows); j++)
1408 EigenVec.rotate(tau, sinAngle, j, ip, j, iq);
1413 for (
size_t j = 0; j < m_numRows; j++) {
1414 B[j] += ZeroComp[j];
1419 std::cerr <<
"Error :: Iterations are a problem\n";
1423template <
typename T>
1429 if (this->m_numRows != this->m_numColumns)
1430 throw(std::invalid_argument(
"matrix is not square"));
1433 if (
fabs(this->determinant() - 1) > 1e-5) {
1436 Matrix<T> prod(m_numRows, m_numColumns), ident(m_numRows, m_numColumns,
true);
1439 return prod.equals(ident, 1e-5);
1443template <
typename T>
1450 if (this->m_numRows != this->m_numColumns)
1451 throw(std::invalid_argument(
"matrix is not square"));
1452 if (
fabs(
fabs(this->determinant()) - 1.) > 1e-5) {
1455 Matrix<T> prod(m_numRows, m_numColumns), ident(m_numRows, m_numColumns,
true);
1457 return prod.equals(ident, 1e-7);
1461template <
typename T>
1470 if (this->m_numRows != this->m_numColumns)
1471 throw(std::invalid_argument(
"matrix is not square"));
1472 if (
fabs(this->determinant()) < 1e-10)
1473 throw(std::invalid_argument(
"Determinant is too small"));
1475 for (
size_t i = 0; i < this->m_numColumns; ++i) {
1477 for (
size_t j = 0; j < this->m_numRows; ++j)
1478 spself += (m_rawData[j][i] * m_rawData[j][i]);
1479 for (
size_t k = i + 1; k < this->m_numColumns; ++k) {
1481 for (
size_t j = 0; j < this->m_numRows; ++j)
1482 spother += (m_rawData[j][i] * m_rawData[j][k]);
1483 for (
size_t j = 0; j < this->m_numRows; ++j)
1484 m_rawData[j][k] -=
static_cast<T
>(m_rawData[j][i] * spother / spself);
1488 std::vector<T> scale(this->m_numRows);
1489 for (
size_t i = 0; i < this->m_numColumns; ++i) {
1491 for (
size_t j = 0; j < this->m_numRows; ++j)
1492 currentScale += (m_rawData[j][i] * m_rawData[j][i]);
1493 currentScale =
static_cast<T
>(sqrt(
static_cast<double>(currentScale)));
1494 if (currentScale < 1e-10)
1495 throw(std::invalid_argument(
"Scale is too small"));
1496 scale[i] = currentScale;
1498 Matrix<T> scalingMatrix(m_numRows, m_numColumns), change(m_numRows, m_numColumns,
true);
1499 for (
size_t i = 0; i < this->m_numColumns; ++i)
1500 scalingMatrix[i][i] =
static_cast<T
>(1.0 / scale[i]);
1502 if (this->determinant() < 0.) {
1503 scale[0] = -scale[0];
1504 change[0][0] =
static_cast<T
>(-1);
1510template <
typename T>
1516 write(std::cout, 10);
1523 for (
size_t i = 0; i < m_numRows; i++) {
1524 for (
size_t j = 0; j < m_numColumns; j++) {
1525 m_rawData[i][j] =
static_cast<T
>(rng.
nextValue());
1530template <
typename T>
1538 std::ios::fmtflags oldFlags = Fh.flags();
1539 Fh.setf(std::ios::floatfield, std::ios::scientific);
1540 const size_t blockNumber((blockCnt > 0) ? blockCnt : m_numColumns);
1543 const size_t ACnt = BCnt;
1544 BCnt += blockNumber;
1545 if (BCnt > m_numColumns) {
1546 BCnt = m_numColumns;
1550 Fh <<
" ----- " << ACnt <<
" " << BCnt <<
" ------ \n";
1552 for (
size_t i = 0; i < m_numRows; i++) {
1553 for (
size_t j = ACnt; j < BCnt; j++) {
1554 Fh << std::setw(10) << m_rawData[i][j] <<
" ";
1558 }
while (BCnt < m_numColumns);
1563template <
typename T>
1570 std::ostringstream cx;
1571 for (
size_t i = 0; i < m_numRows; i++) {
1572 for (
size_t j = 0; j < m_numColumns; j++) {
1573 cx << std::setprecision(6) << m_rawData[i][j] <<
" ";
1600 os <<
"Matrix(" <<
nrows << delimiter <<
ncols <<
")";
1601 for (
size_t i = 0; i <
nrows; ++i) {
1602 for (
size_t j = 0; j <
ncols; ++j) {
1633 std::string start(7,
' ');
1634 for (
int i = 0; i < 7; ++i) {
1638 throw std::invalid_argument(
"Unexpected character when reading Matrix from stream.");
1640 if (start !=
"Matrix(")
1641 throw std::invalid_argument(
"Incorrect input format for Matrix stream.");
1646 throw std::invalid_argument(
"Expected number of rows when reading Matrix "
1647 "from stream, found something else.");
1651 throw std::invalid_argument(
"Expected number of columns when reading "
1652 "Matrix from stream, found something else.");
1655 throw std::invalid_argument(
"Expected closing parenthesis after ncols when "
1656 "reading Matrix from stream, found something "
1663 std::string value_str;
1664 size_t row(0), col(0);
1665 while (!is.eof() && std::getline(is, value_str, delimiter)) {
1667 auto value = boost::lexical_cast<T>(value_str);
1669 }
catch (boost::bad_lexical_cast &) {
1670 throw std::invalid_argument(
"Unexpected type found while reading Matrix from stream: \"" + value_str +
"\"");
1687#if defined(_MSC_VER)
1688#define KERNEL_MATRIX_SYMBOL_DLL MANTID_KERNEL_DLL
1690#define KERNEL_MATRIX_SYMBOL_DLL
1693template class KERNEL_MATRIX_SYMBOL_DLL
Matrix<int>;
const std::vector< double > * lambda
double value
The value of the point.
std::map< DeltaEMode::Type, std::string > index
Exception for index errors.
Error when two numbers should be identical (or close)
T determinant() const
Calculate the determinant.
T Invert()
LU inversion routine.
std::vector< T > toRotation()
Transform the matrix to a rotation matrix, by normalizing each column to 1.
Matrix(const size_t nrow=0, const size_t ncol=0, bool const makeIdentity=false)
Constructor with pre-set sizes.
bool operator<(const Matrix< T > &) const
Element by element comparison of < Always returns false if the Matrix have different sizes.
Matrix< T > operator-(const Matrix< T > &) const
Basic subtraction operator.
void zeroMatrix()
Set the matrix to zero.
void sortEigen(Matrix< T > &)
Sort eigenvectors.
Matrix< T > & operator+=(const Matrix< T > &)
Basic addition operator.
void multiplyPoint(const std::vector< T > &in, std::vector< T > &out) const
Multiply M*Vec.
void invertTridiagonal()
Check it's a square tridiagonal matrix with all diagonal elements equal and if yes invert the matrix ...
void lubksb(int const *, double *)
Implements a separation of the Matrix into a triangular matrix.
T Trace() const
Trace of the matrix.
Matrix< T > & operator/=(const T &)
Divide by constant.
void GaussJordan(Matrix< T > &)
Create a Gauss-Jordan Inversion.
void identityMatrix()
Makes the matrix an idenity matrix.
bool equals(const Matrix< T > &A, const double Tolerance=FLT_EPSILON) const
Element by element comparison within tolerance.
Matrix< T > Tprime() const
Transpose the matrix.
bool operator==(const Matrix< T > &) const
Element by element comparison within tolerance.
bool isRotation() const
Check if a matrix represents a proper rotation @ return :: true/false.
int Diagonalise(Matrix< T > &, Matrix< T > &) const
(only Symmetric matrix)
void setRow(const size_t nRow, const std::vector< T > &newRow)
T factor()
Calculate the factor.
Matrix< T > operator+(const Matrix< T > &) const
Basic addition operator.
T compSum() const
Add up each component sums for the matrix.
Matrix< T > preMultiplyByDiagonal(const std::vector< T > &) const
pre-multiply D*this
std::vector< T > Diagonal() const
Returns a vector of the diagonal.
void setRandom(size_t seed=0, double rMin=-1, double rMax=1)
initialize random matrix;
Matrix< T > operator*(const Matrix< T > &) const
Basic matrix multiply.
std::vector< T > getVector() const
void averSymmetric()
make Matrix symmetric
void swapCols(const size_t, const size_t)
Swap cols (second V index)
size_t numRows() const
Return the number of rows in the matrix.
void normVert()
Vertical normalisation.
void rotate(double const, double const, int const, int const, int const, int const)
Applies a rotation to a particular point of tan(theta)=tau.
size_t m_numRows
Number of rows (x coordinate)
void setColumn(const size_t nCol, const std::vector< T > &newCol)
void swapRows(const size_t, const size_t)
Swap rows (first V index)
size_t m_numColumns
Number of columns (y coordinate)
Matrix< T > & operator*=(const Matrix< T > &)
Basic matrix multipy.
size_t numCols() const
Return the number of columns in the matrix.
Matrix< T > & Transpose()
Transpose the matrix.
void write(std::ostream &, int const =0) const
Write out function for blocks of 10 Columns.
Matrix< T > & operator-=(const Matrix< T > &)
Basic subtraction operator.
std::string str() const
Convert the matrix into a simple linear string expression.
bool operator!=(const Matrix< T > &) const
Element by Element comparison.
bool isOrthogonal() const
Check if a matrix is orthogonal.
void print() const
Simple print out routine.
bool operator>=(const Matrix< T > &) const
Element by element comparison of >= Always returns false if the Matrix have different sizes.
Matrix< T > & operator=(const Matrix< T > &)
Simple assignment operator.
void lubcmp(int *, int &)
starts inversion process
void setMem(const size_t, const size_t)
Sets the memory held in matrix.
MatrixMemoryPtrs< T > m_rawData
Representation of 2D data.
Matrix< T > postMultiplyByDiagonal(const std::vector< T > &) const
post-multiply this*D
This implements the the Mersenne Twister 19937 pseudo-random number generator algorithm as a specialz...
double nextValue() override
Generate the next random number in the sequence within the given range default range.
constexpr double X() const noexcept
Get x.
MatrixWorkspace_sptr MANTID_API_DLL operator*(const MatrixWorkspace_sptr &lhs, const MatrixWorkspace_sptr &rhs)
Multiply two workspaces.
MANTID_KERNEL_DLL std::ostream & operator<<(std::ostream &, CPUTimer &)
Convenience function to provide for easier debug printing.
MANTID_KERNEL_DLL std::istream & operator>>(std::istream &, Interpolation &)
Reads in parameter value.
MANTID_KERNEL_DLL bool equals(const T x, const T y)
Test for equality of doubles using compiler-defined precision.
MANTID_KERNEL_DLL bool operator==(const Mantid::Kernel::Property &lhs, const Mantid::Kernel::Property &rhs)
Compares this to another property for equality.
void dumpToStream(std::ostream &, const Kernel::Matrix< T > &, const char)
Write a Matrix to a stream.
constexpr double Tolerance
Standard tolerance value.
void fillFromStream(std::istream &, Kernel::Matrix< T > &, const char)
Fill a Matrix from a stream using the given separator.