33 #define ABORT_ON_INDEX_CHECK abort()
35 #define ABORT_ON_INDEX_CHECK
37 #define CHECK_INDEX(label,i,n) if (i < 1 || i > n) { \
38 std::cerr << label << i <<" is out of range [1,"<< n <<"]"<< std::endl; \
39 ABORT_ON_INDEX_CHECK; }
41 #define CHECK_INDEX(label,i,n)
42 #define ABORT_ON_INDEX_CHECK
46 #define ABORT_ON_SINGULARITY abort()
48 #define ABORT_ON_SINGULARITY
71 vector(
const T* values,
size_t n) { this->
fill(values,n); }
92 bool zero(T tol = T(0))
const
95 [tol](T v) { return std::fabs(v) <= tol; });
101 using VecIter =
typename std::vector<T>::iterator;
113 operator const std::vector<T>&()
const {
return myVec; }
115 operator std::vector<T>&() {
return myVec; }
125 CHECK_INDEX(
"vector::operator(): Index ",i,
myVec.size());
132 CHECK_INDEX(
"vector::operator(): Index ",i,
myVec.size());
139 void fill(
const T* values,
size_t n = 0)
141 if (n >
myVec.size())
143 memcpy(
myVec.data(),values,
myVec.size()*
sizeof(T));
169 for (
size_t i = 0; i <
myVec.size() && i < X.size(); i++)
176 for (
size_t i = 0; i <
myVec.size() && i < X.size(); i++)
177 myVec[i] *= (X[i] == T(0) ? T(0) : T(1)/X[i]);
186 vector<T>&
add(
const std::vector<T>& X,
const T& alfa = T(1),
187 unsigned int ofsx = 0,
int stridex = 1,
188 unsigned int ofsy = 0,
int stridey = 1);
197 this->
add(X,T(1)-alfa);
215 T
dot(
const T* v,
size_t nv,
216 size_t off1 = 0,
int inc1 = 1,
217 size_t off2 = 0,
int inc2 = 1)
const;
225 T
dot(
const std::vector<T>& v,
226 size_t off1 = 0,
int inc1 = 1,
227 size_t off2 = 0,
int inc2 = 1)
const
229 return this->
dot(v.data(),v.size(),off1,inc1,off2,inc2);
235 T
norm2(
size_t off = 0,
int inc = 1)
const;
241 T
normInf(
size_t& off,
int inc = 1,
bool sign =
false)
const;
254 T
asum(
size_t off = 0,
int inc = 1)
const;
260 T
sum(
size_t off = 0,
int inc = 1,
size_t max = 0)
const
263 if (inc < 1 ||
myVec.empty())
268 for (
size_t i = off; i <
max; i += inc)
277 bool resize(
size_t n,
char forceClear = 0)
279 if (n ==
myVec.size())
288 myVec.resize(n,T(0));
316 matrixBase(
size_t n_1,
size_t n_2,
size_t n_3 = 1,
size_t n_4 = 1)
325 memcpy(
n,mat.
n,
sizeof(
n));
338 void redim(
size_t n_1,
size_t n_2,
size_t n_3,
size_t n_4,
bool forceClear)
343 if (this->
size() == n_1*n_2*n_3*n_4)
349 if (
n[0] == n_1 &&
n[1] == n_2 &&
n[2] == n_3 &&
n[3] == n_4)
355 size_t oldSize = this->
size();
360 if (this->
size() == oldSize)
376 size_t dim(
short int d = 1)
const {
return d > 0 && d <= 4 ?
n[d-1] : 0; }
378 size_t size()
const {
return n[0]*
n[1]*
n[2]*
n[3]; }
382 bool zero(T tol = T(0))
const {
return elem.zero(tol); }
387 operator const std::vector<T>&()
const {
return elem; }
389 operator std::vector<T>&() {
return elem; }
394 return n[0]*c <
elem.size() ?
elem.ptr() +
n[0]*c :
nullptr;
397 const T*
ptr(
size_t c = 0)
const
399 return n[0]*c <
elem.size() ?
elem.ptr() +
n[0]*c :
nullptr;
403 typename std::vector<T>::iterator
begin() {
return elem.begin(); }
405 typename std::vector<T>::iterator
end() {
return elem.end(); }
413 void fill(
const T* values,
size_t n = 0) {
elem.fill(values,
n); }
422 T
norm2(
int inc = 1)
const {
return elem.norm2(0,inc); }
425 T
asum(
int inc = 1)
const {
return elem.asum(0,inc); }
432 return elem.sum(0,inc);
433 else if (inc == 0 || (inc *= -1) >
static_cast<int>(
n[1]))
436 return elem.sum((inc-1)*
n[0],1,inc*
n[0]);
473 for (
size_t r = 0; r <
ncol; r++)
474 for (
size_t c = 0; c <
nrow; c++)
476 else if (!mat.
elem.empty())
488 void resize(
size_t r,
size_t c,
bool forceClear =
false)
490 this->
redim(r,c,1,1,forceClear);
496 int newRows =
nrow + incRows;
497 if (newRows < 1 ||
ncol < 1)
500 else if (incRows < 0)
503 T* newMat = this->
ptr() + newRows;
504 for (
size_t c = 1; c <
ncol; c++, newMat += newRows)
505 memmove(newMat,this->
ptr(c),newRows*
sizeof(T));
509 else if (incRows > 0)
512 size_t oldRows =
nrow;
515 T* oldMat = this->
ptr() + oldRows*(
ncol-1);
516 for (
size_t c =
ncol-1; c > 0; c--, oldMat -= oldRows)
518 memmove(this->
ptr(c),oldMat,oldRows*
sizeof(T));
519 for (
size_t r =
nrow-1; r >= oldRows; r--)
532 size_t oldRows =
nrow;
535 T* oldMat = this->
ptr() + oldRows*(
ncol-1);
536 for (
size_t c =
ncol; c > 0; c--, oldMat -= oldRows)
539 memmove(this->
ptr(c-1),oldMat,oldRows*
sizeof(T));
540 for (
size_t r =
nrow; r > oldRows; r--)
541 this->
elem[r-1+
nrow*(c-1)] = B(r-oldRows,c);
568 memcpy(this->
n,A.
n,
sizeof(A.
n));
577 size_t nval = X.size() < this->
elem.size() ? X.size() : this->
elem.size();
578 std::copy(X.begin(),X.begin()+nval,this->elem.begin());
579 std::fill(this->
elem.begin()+nval,this->elem.end(),T(0));
587 CHECK_INDEX(
"matrix::operator(): Row-index ",r,
nrow);
588 CHECK_INDEX(
"matrix::operator(): Column-index ",c,
ncol);
596 CHECK_INDEX(
"matrix::operator(): Row-index ",r,
nrow);
597 CHECK_INDEX(
"matrix::operator(): Column-index ",c,
ncol);
604 CHECK_INDEX(
"matrix::getRow: Row-index ",r,
nrow);
609 for (
size_t i = 0; i <
ncol; i++)
617 CHECK_INDEX(
"matrix::getColumn: Column-index ",c,
ncol);
621 std::vector<T> col(
nrow);
622 memcpy(col.data(),this->ptr(c-1),
nrow*
sizeof(T));
628 void fill(
const std::vector<T>& v,
size_t n,
size_t m = 0)
630 if (
n == 0 || v.size() <
n)
632 if (m == 0) m = v.size()/
n;
635 this->
elem.fill(v.data());
636 else if ((
n = v.size()/m) >
nrow)
637 for (
size_t c = 0; c <
ncol; c++)
640 for (
size_t c = 0; c <
ncol; c++)
641 for (
size_t r = 0; r <
n; r++)
648 CHECK_INDEX(
"matrix::fillColumn: Column-index ",c,
ncol);
649 size_t ndata =
nrow > data.size() ? data.size() :
nrow;
650 memcpy(this->
ptr(c-1),data.data(),ndata*
sizeof(T));
656 CHECK_INDEX(
"matrix::fillColumn: Column-index ",c,
ncol);
657 memcpy(this->
ptr(c-1),data,
nrow*
sizeof(T));
663 CHECK_INDEX(
"matrix::fillRow: Row-index ",r,
nrow);
665 this->
elem.fill(data);
666 else for (
size_t i = 0; i <
ncol; i++)
672 bool transposed =
false)
674 size_t nr = transposed ? block.
cols() : block.
rows();
675 size_t nc = transposed ? block.
rows() : block.
cols();
676 for (
size_t i = 1; i <= nr && i+r-1 <=
nrow; i++)
678 size_t ip = i+r-2 +
nrow*(c-1);
679 for (
size_t j = 1; j <= nc && j+c-1 <=
ncol; j++, ip +=
nrow)
680 this->
elem[ip] = transposed ? block(j,i) : block(i,j);
686 bool transposed =
false)
688 size_t nr = transposed ? block.
cols() : block.
rows();
689 size_t nc = transposed ? block.
rows() : block.
cols();
690 for (
size_t i = 1; i <= nr && i+r-1 <=
nrow; i++)
692 size_t ip = i+r-2 +
nrow*(c-1);
693 for (
size_t j = 1; j <= nc && j+c-1 <=
ncol; j++, ip +=
nrow)
694 this->
elem[ip] += s*(transposed ? block(j,i) : block(i,j));
700 bool addTo =
false,
bool transposed =
false)
const
702 size_t nr = transposed ? block.
cols() : block.
rows();
703 size_t nc = transposed ? block.
rows() : block.
cols();
704 for (
size_t i = 1; i <= nr && i+r-1 <=
nrow; i++)
706 size_t ip = i+r-2 +
nrow*(c-1);
707 for (
size_t j = 1; j <= nc && j+c-1 <=
ncol; j++, ip +=
nrow)
709 (transposed ? block(j,i) : block(i,j)) += this->
elem[ip];
711 (transposed ? block(j,i) : block(i,j)) = this->
elem[ip];
722 for (
size_t r = 0; r <
nrow && r <
ncol; r++)
731 for (
size_t r = 0; r <
nrow; r++)
732 for (
size_t c = 0; c <
ncol; c++)
747 #define THIS(i,j) this->operator()(i,j)
755 return THIS(1,1)*THIS(2,2) - THIS(2,1)*THIS(1,2);
757 return THIS(1,1)*(THIS(2,2)*THIS(3,3) - THIS(3,2)*THIS(2,3))
758 - THIS(1,2)*(THIS(2,1)*THIS(3,3) - THIS(3,1)*THIS(2,3))
759 + THIS(1,3)*(THIS(2,1)*THIS(3,2) - THIS(3,1)*THIS(2,2));
761 std::cerr <<
"matrix::det: Not available for "
762 <<
nrow <<
"x"<<
ncol <<
" matrices"<< std::endl;
763 ABORT_ON_SINGULARITY;
778 else if (Det <= tol && Det >= -tol) {
779 std::cerr <<
"matrix::inverse: Singular matrix |A|="<< Det << std::endl;
780 ABORT_ON_SINGULARITY;
785 THIS(1,1) = T(1) / Det;
786 else if (
ncol == 2) {
788 B(1,1) = THIS(2,2) / Det;
789 B(2,1) = -THIS(2,1) / Det;
790 B(1,2) = -THIS(1,2) / Det;
791 B(2,2) = THIS(1,1) / Det;
794 else if (
ncol == 3) {
796 B(1,1) = (THIS(2,2)*THIS(3,3) - THIS(3,2)*THIS(2,3)) / Det;
797 B(2,1) = -(THIS(2,1)*THIS(3,3) - THIS(3,1)*THIS(2,3)) / Det;
798 B(3,1) = (THIS(2,1)*THIS(3,2) - THIS(3,1)*THIS(2,2)) / Det;
799 B(1,2) = -(THIS(1,2)*THIS(3,3) - THIS(3,2)*THIS(1,3)) / Det;
800 B(2,2) = (THIS(1,1)*THIS(3,3) - THIS(3,1)*THIS(1,3)) / Det;
801 B(3,2) = -(THIS(1,1)*THIS(3,2) - THIS(3,1)*THIS(1,2)) / Det;
802 B(1,3) = (THIS(1,2)*THIS(2,3) - THIS(2,2)*THIS(1,3)) / Det;
803 B(2,3) = -(THIS(1,1)*THIS(2,3) - THIS(2,1)*THIS(1,3)) / Det;
804 B(3,3) = (THIS(1,1)*THIS(2,2) - THIS(2,1)*THIS(1,2)) / Det;
818 for (
size_t r = 0; r <
nrow; r++)
819 for (
size_t c = 0; c < r; c++)
822 if (diff < -tol || diff > tol)
861 bool transA =
false,
bool transB =
false,
862 bool addTo =
false,
const T& alpha = T(1));
877 bool transA =
false,
bool addTo =
false);
892 bool transB =
false,
bool addTo =
false);
903 bool multiply(
const std::vector<T>& X, std::vector<T>& Y,
904 bool transA =
false,
char addTo = 0)
const;
911 bool multiply(
const std::vector<T>& X, std::vector<T>& Y,
912 const T& alpha,
const T& beta = T(0),
913 bool transA =
false,
int stridex = 1,
int stridey = 1,
914 unsigned int ofsx = 0,
unsigned int ofsy = 0)
const;
918 bool addTo =
false, T alpha = T(1));
928 for (
size_t i = 0; i <
nrow; i++)
930 return *std::max_element(sums.
begin(),sums.
end());
938 if ((transA ?
nrow :
ncol) == X.size())
941 std::cerr <<
"matrix::multiply: Incompatible matrices: A("
942 <<
nrow <<
','<<
ncol <<
"), X("<< X.size() <<
")\n"
943 <<
" when computing Y = "
944 << (transA ?
"A^t":
"A") <<
" * X"<< std::endl;
945 ABORT_ON_INDEX_CHECK;
951 bool transA,
bool transB,
size_t&
M,
size_t& N,
size_t&
K)
959 std::cerr <<
"matrix::multiply: Incompatible matrices: A("
962 <<
" when computing C = "
963 << (transA ?
"A^t":
"A") <<
" * "
964 << (transB ?
"B^t":
"B") << std::endl;
965 ABORT_ON_INDEX_CHECK;
972 bool transA,
size_t&
M,
size_t& N,
size_t&
K)
976 N =
K > 0 ? B.size()/
K : 0;
977 if (N*
K == B.size() && !B.
empty())
980 std::cerr <<
"matrix::multiply: Incompatible matrices: A("
981 << A.
nrow <<
','<< A.
ncol <<
"), B(r*c="<< B.size() <<
")\n"
982 <<
" when computing C = "
983 << (transA ?
"A^t":
"A") <<
" * B"<< std::endl;
984 ABORT_ON_INDEX_CHECK;
991 bool transB,
size_t&
M,
size_t& N,
size_t&
K)
995 M =
K > 0 ? A.size() /
K : 0;
996 if (
M*
K == A.size() && !A.
empty())
999 std::cerr <<
"matrix::multiply: Incompatible matrices: A(r*c="<< A.size()
1000 <<
"), B("<< B.
nrow <<
","<< B.
ncol <<
")\n"
1001 <<
" when computing C = A * "
1002 << (transB ?
"B^t":
"B") << std::endl;
1003 ABORT_ON_INDEX_CHECK;
1008 bool compatible(
const std::vector<T>& X,
const std::vector<T>& Y)
1010 if (X.size() ==
nrow && Y.size() ==
ncol)
1013 std::cerr <<
"matrix::outer_product: Incompatible matrix and vectors: A("
1015 << X.size() <<
"), Y("<< Y.size() <<
")\n"
1016 <<
" when computing A += X*Y^t"
1018 ABORT_ON_INDEX_CHECK;
1026 if (n1 !=
nrow) this->
elem.clear();
1043 cblas_sscal(myVec.size(),c,myVec.data(),1);
1050 cblas_dscal(myVec.size(),c,myVec.data(),1);
1056 size_t o1,
int i1,
size_t o2,
int i2)
const
1058 int n1 = i1 > 1 || i1 < -1 ? myVec.size()/abs(i1) : myVec.size()-o1;
1059 int n2 = i2 > 1 || i2 < -1 ? nv/abs(i2) : nv-o2;
1060 int n = n1 < n2 ? n1 : n2;
1061 return cblas_sdot(n,myVec.data()+o1,i1,v+o2,i2);
1066 size_t o1,
int i1,
size_t o2,
int i2)
const
1068 int n1 = i1 > 1 || i1 < -1 ? myVec.size()/abs(i1) : myVec.size()-o1;
1069 int n2 = i2 > 1 || i2 < -1 ? nv/abs(i2) : nv-o2;
1070 int n = n1 < n2 ? n1 : n2;
1071 return cblas_ddot(n,myVec.data()+o1,i1,v+o2,i2);
1077 int n = inc > 1 || inc < -1 ? myVec.size()/abs(inc) : myVec.size()-off;
1078 return cblas_snrm2(n,myVec.data()+off,inc);
1084 int n = inc > 1 || inc < -1 ? myVec.size()/abs(inc) : myVec.size()-off;
1085 return cblas_dnrm2(n,myVec.data()+off,inc);
1091 if (inc < 1 || myVec.empty())
1094 const float* v = myVec.data() + off;
1095 off = 1 + cblas_isamax(myVec.size()/inc,v,inc);
1096 return sign ? v[(off-1)*inc] : fabsf(v[(off-1)*inc]);
1102 if (inc < 1 || myVec.empty())
1105 const double* v = myVec.data() + off;
1106 off = 1 + cblas_idamax(myVec.size()/inc,v,inc);
1107 return sign ? v[(off-1)*inc] : fabs(v[(off-1)*inc]);
1113 int n = inc > 1 || inc < -1 ? myVec.size()/abs(inc) : myVec.size()-off;
1114 return cblas_sasum(n,myVec.data()+off,inc);
1120 int n = inc > 1 || inc < -1 ? myVec.size()/abs(inc) : myVec.size()-off;
1121 return cblas_dasum(n,myVec.data()+off,inc);
1127 unsigned int ofsx,
int stridex,
1128 unsigned int ofsy,
int stridey)
1130 if (myVec.empty() && stridex > 0 && stridey > 0)
1131 myVec.resize(ofsy+stridey*(X.size()-ofsx)/stridex);
1133 int nx = stridex == 0 ? 1 : 1 + (X.size()-ofsx-1)/abs(stridex);
1134 int ny = stridey == 0 ? 1 : 1 + (myVec.size()-ofsy-1)/abs(stridey);
1135 int n = nx < ny ? (stridex == 0 ? ny : nx) : (stridey == 0 ? nx : ny);
1137 cblas_saxpy(n,alfa,X.data()+ofsx,stridex,myVec.data()+ofsy,stridey);
1144 unsigned int ofsx,
int stridex,
1145 unsigned int ofsy,
int stridey)
1147 if (myVec.empty() && stridex > 0 && stridey > 0)
1148 myVec.resize(ofsy+stridey*(X.size()-ofsx)/stridex);
1150 int nx = stridex == 0 ? 1 : 1 + (X.size()-ofsx-1)/abs(stridex);
1151 int ny = stridey == 0 ? 1 : 1 + (myVec.size()-ofsy-1)/abs(stridey);
1152 int n = nx < ny ? (stridex == 0 ? ny : nx) : (stridey == 0 ? nx : ny);
1154 cblas_daxpy(n,alfa,X.data()+ofsx,stridex,myVec.data()+ofsy,stridey);
1162 int n = this->size() < A.size() ? this->size() : A.size();
1164 cblas_saxpy(n,alfa,A.ptr(),1,this->ptr(),1);
1172 int n = this->size() < A.size() ? this->size() : A.size();
1174 cblas_daxpy(n,alfa,A.ptr(),1,this->ptr(),1);
1181 cblas_sscal(this->size(),c,this->ptr(),1);
1188 cblas_dscal(this->size(),c,this->ptr(),1);
1194 std::vector<float>& Y,
1195 bool transA,
char addTo)
const
1197 if (!this->compatible(X,transA))
1199 else if (!addTo || Y.empty())
1201 Y.resize(transA ? ncol : nrow);
1202 if (addTo) std::fill(Y.begin(),Y.end(),0.0f);
1205 cblas_sgemv(CblasColMajor,
1206 transA ? CblasTrans : CblasNoTrans,
1207 nrow, ncol, addTo < 0 ? -1.0f : 1.0f,
1209 X.data(), 1, addTo ? 1.0f : 0.0f,
1217 std::vector<double>& Y,
1218 bool transA,
char addTo)
const
1220 if (!this->compatible(X,transA))
1222 else if (!addTo || Y.empty())
1224 Y.resize(transA ? ncol : nrow);
1225 if (addTo) std::fill(Y.begin(),Y.end(),0.0);
1228 cblas_dgemv(CblasColMajor,
1229 transA ? CblasTrans : CblasNoTrans,
1230 nrow, ncol, addTo < 0 ? -1.0 : 1.0,
1232 X.data(), 1, addTo ? 1.0 : 0.0,
1240 std::vector<float>& Y,
1241 const float& alpha,
const float& beta,
1242 bool transA,
int stridex,
int stridey,
1243 unsigned int ofsx,
unsigned int ofsy)
const
1245 if (stridex == 0 || stridey == 0)
1247 std::cerr <<
"matrix::multiply: Stride must be non-zero ("
1248 << stridex <<
", "<< stridey <<
")"<< std::endl;
1249 ABORT_ON_INDEX_CHECK;
1253 if (ofsx == 0 && stridex == 1 && !this->compatible(X,transA))
1255 else if (beta == 0.0f || Y.empty())
1257 Y.resize(ofsy + 1 + ((transA ? ncol : nrow)-1)*abs(stridey));
1258 if (beta != 0.0f) std::fill(Y.begin(),Y.end(),0.0f);
1261 cblas_sgemv(CblasColMajor,
1262 transA ? CblasTrans : CblasNoTrans,
1265 X.data()+ofsx, stridex, beta,
1266 Y.data()+ofsy, stridey);
1273 std::vector<double>& Y,
1274 const double& alpha,
const double& beta,
1275 bool transA,
int stridex,
int stridey,
1276 unsigned int ofsx,
unsigned int ofsy)
const
1278 if (stridex == 0 || stridey == 0)
1280 std::cerr <<
"matrix::multiply: Stride must be non-zero ("
1281 << stridex <<
", "<< stridey <<
")"<< std::endl;
1282 ABORT_ON_INDEX_CHECK;
1286 if (ofsx == 0 && stridex == 1 && !this->compatible(X,transA))
1288 else if (beta == 0.0 || Y.empty())
1290 Y.resize(ofsy + 1 + ((transA ? ncol : nrow)-1)*abs(stridey));
1291 if (beta != 0.0) std::fill(Y.begin(),Y.end(),0.0);
1294 cblas_dgemv(CblasColMajor,
1295 transA ? CblasTrans : CblasNoTrans,
1298 X.data()+ofsx, stridex, beta,
1299 Y.data()+ofsy, stridey);
1306 const matrix<float>& B,
1307 bool transA,
bool transB,
1308 bool addTo,
const float& alpha)
1311 if (!this->compatible(A,B,transA,transB,
M,N,
K))
1316 else if (!addTo || this->empty())
1319 cblas_sgemm(CblasColMajor,
1320 transA ? CblasTrans : CblasNoTrans,
1321 transB ? CblasTrans : CblasNoTrans,
1325 addTo ? 1.0f : 0.0f,
1333 const matrix<double>& B,
1334 bool transA,
bool transB,
1335 bool addTo,
const double& alpha)
1338 if (!this->compatible(A,B,transA,transB,
M,N,
K))
1343 else if (!addTo || this->empty())
1346 cblas_dgemm(CblasColMajor,
1347 transA ? CblasTrans : CblasNoTrans,
1348 transB ? CblasTrans : CblasNoTrans,
1360 const std::vector<float>& B,
1361 bool transA,
bool addTo)
1364 if (!this->compatible(A,B,transA,
M,N,
K))
1366 else if (!addTo || this->empty())
1369 cblas_sgemm(CblasColMajor,
1370 transA ? CblasTrans : CblasNoTrans, CblasNoTrans,
1374 addTo ? 1.0f : 0.0f,
1382 const std::vector<double>& B,
1383 bool transA,
bool addTo)
1386 if (!this->compatible(A,B,transA,
M,N,
K))
1388 else if (!addTo || this->empty())
1391 cblas_dgemm(CblasColMajor,
1392 transA ? CblasTrans : CblasNoTrans, CblasNoTrans,
1404 const matrix<float>& B,
1405 bool transB,
bool addTo)
1408 if (!this->compatible(A,B,transB,
M,N,
K))
1410 else if (!addTo || this->empty())
1413 cblas_sgemm(CblasColMajor,
1414 CblasNoTrans, transB ? CblasTrans : CblasNoTrans,
1418 addTo ? 1.0f : 0.0f,
1426 const matrix<double>& B,
1427 bool transB,
bool addTo)
1430 if (!this->compatible(A,B,transB,
M,N,
K))
1432 else if (!addTo || this->empty())
1435 cblas_dgemm(CblasColMajor,
1436 CblasNoTrans, transB ? CblasTrans : CblasNoTrans,
1448 const std::vector<float>& Y,
1449 bool addTo,
float alpha)
1452 this->resize(X.size(),Y.size());
1453 else if (!this->compatible(X,Y))
1456 cblas_sgemm(CblasColMajor,
1457 CblasNoTrans, CblasTrans,
1458 nrow, ncol, 1, alpha,
1461 addTo ? 1.0f : 0.0f,
1469 const std::vector<double>& Y,
1470 bool addTo,
double alpha)
1473 this->resize(X.size(),Y.size());
1474 else if (!this->compatible(X,Y))
1477 cblas_dgemm(CblasColMajor,
1478 CblasNoTrans, CblasTrans,
1479 nrow, ncol, 1, alpha,
1493 template<
class T>
inline
1501 template<
class T>
inline
1503 size_t o1,
int i1,
size_t o2,
int i2)
const
1507 for (i = o1, j = o2; i < myVec.size() && j < nv; i += i1, j += i2)
1508 dotprod += myVec[i] * v[j];
1512 template<
class T>
inline
1516 if (inc < 1 || myVec.size() <= off)
1520 for (
size_t i = off; i < myVec.size(); i += inc)
1521 xsum += myVec[i]*myVec[i];
1525 template<
class T>
inline
1529 if (inc < 1 || myVec.size() <= off)
1533 for (
size_t i = off; i < myVec.size(); i += inc)
1534 if (myVec[i] > amax)
1537 xmax = amax = myVec[i];
1539 else if (myVec[i] < -amax)
1546 return sign ? xmax : amax;
1549 template<
class T>
inline
1553 if (inc < 1 || myVec.size() <= off)
1556 for (
size_t i = off; i < myVec.size(); i += inc)
1557 xsum += myVec[i] < T(0) ? -myVec[i] : myVec[i];
1561 template<
class T>
inline
1563 unsigned int ofsx,
int stridex,
1564 unsigned int ofsy,
int stridey)
1566 if (stridex < 0 || stridey < 0 || stridex+stridey == 0)
1568 std::cerr <<
"vector::add: Negative stride not supported ("
1569 << stridex <<
", "<< stridey <<
")"<< std::endl;
1570 ABORT_ON_INDEX_CHECK;
1574 std::vector<T>& Y = myVec;
1575 if (Y.empty() && stridex > 0)
1576 Y.resize(ofsy+stridey*(X.size()-ofsx)/stridex);
1578 for (; ofsx < X.size() && ofsy < Y.size(); ofsx += stridex, ofsy += stridey)
1579 Y[ofsy] += alfa*X[ofsx];
1583 template<
class T>
inline
1589 for (
size_t i = 0; i < X.
size() && i < Y.
size(); i++)
1594 template<
class T>
inline
1597 for (T& x : this->elem)
1602 template<
class T>
inline
1604 bool transA,
char addTo)
const
1606 if (!this->compatible(X,transA))
1608 else if (!addTo || Y.empty())
1610 Y.resize(transA ? ncol : nrow);
1611 std::fill(Y.begin(),Y.end(),T(0));
1614 for (
size_t i = 0; i < Y.size(); i++)
1615 for (
size_t j = 0; j < X.size(); j++)
1617 Y[i] += THIS(j+1,i+1) * (addTo < 0 ? -X[j] : X[j]);
1619 Y[i] += THIS(i+1,j+1) * (addTo < 0 ? -X[j] : X[j]);
1624 template<
class T>
inline
1626 const T& alpha,
const T& beta,
1627 bool transA,
int stridex,
int stridey,
1628 unsigned int ofsx,
unsigned int ofsy)
const
1630 if (stridex <= 0 || stridey <= 0)
1632 std::cerr <<
"matrix::multiply: Non-positive stride not supported ("
1633 << stridex <<
", "<< stridey <<
")"<< std::endl;
1634 ABORT_ON_INDEX_CHECK;
1638 if (ofsx == 0 && stridex == 1 && !this->compatible(X,transA))
1640 else if (beta == T(0) || Y.empty())
1642 Y.resize(ofsy + 1 + ((transA ? ncol : nrow)-1)*stridey);
1643 std::fill(Y.begin(),Y.end(),T(0));
1645 else if (beta != T(1))
1646 for (
size_t i = ofsy; i < Y.size(); i += stridey)
1650 for (a = 1, i = ofsy; i < Y.size(); a++, i += stridey)
1651 for (b = 1, j = ofsx; j < X.size(); b++, j += stridex)
1653 Y[i] += alpha * THIS(b,a) * X[j];
1655 Y[i] += alpha * THIS(a,b) * X[j];
1660 template<
class T>
inline
1663 bool transA,
bool transB,
bool addTo,
1667 if (!this->compatible(A,B,transA,transB,
M,N,
K))
1672 else if (!addTo || this->empty())
1673 this->resize(
M,N,
true);
1675 for (
size_t i = 1; i <=
M; i++)
1676 for (
size_t j = 1; j <= N; j++)
1677 for (
size_t k = 1; k <=
K; k++)
1678 if (transA && transB)
1679 THIS(i,j) += alpha*A(k,i)*B(j,k);
1681 THIS(i,j) += alpha*A(k,i)*B(k,j);
1683 THIS(i,j) += alpha*A(i,k)*B(j,k);
1685 THIS(i,j) += alpha*A(i,k)*B(k,j);
1690 template<
class T>
inline
1692 bool transA,
bool addTo)
1695 if (!this->compatible(A,B,transA,
M,N,
K))
1697 else if (!addTo || this->empty())
1698 this->resize(
M,N,
true);
1700 for (
size_t i = 1; i <=
M; i++)
1701 for (
size_t j = 1; j <= N; j++)
1702 for (
size_t k = 1; k <=
K; k++)
1704 THIS(i,j) += A(k,i)*B[k-1+
K*(j-1)];
1706 THIS(i,j) += A(i,k)*B[k-1+
K*(j-1)];
1711 template<
class T>
inline
1713 bool transB,
bool addTo)
1716 if (!this->compatible(A,B,transB,
M,N,
K))
1718 else if (!addTo || this->empty())
1719 this->resize(
M,N,
true);
1721 for (
size_t i = 1; i <=
M; i++)
1722 for (
size_t j = 1; j <= N; j++)
1723 for (
size_t k = 1; k <=
K; k++)
1725 THIS(i,j) += A[i-1+
M*(k-1)]*B(j,k);
1727 THIS(i,j) += A[i-1+
M*(k-1)]*B(k,j);
1732 template<
class T>
inline
1734 const std::vector<T>& Y,
1735 bool addTo, T alpha)
1738 this->resize(X.size(),Y.size());
1739 else if (!this->compatible(X,Y))
1743 for (
size_t j = 0; j < ncol; j++)
1744 for (
size_t i = 0; i < nrow; i++)
1745 this->elem[i+nrow*j] += alpha*X[i]*Y[j];
1747 for (
size_t j = 0; j < ncol; j++)
1748 for (
size_t i = 0; i < nrow; i++)
1749 this->elem[i+nrow*j] = alpha*X[i]*Y[j];
1788 else for (
size_t i = 0; i < X.
size(); i++)
1791 return s << std::endl;
1797 size_t m = 0, n = 0;
1799 while (s.get(c) && isspace(c));
1800 bool symmetric = (c ==
'S' || c ==
's');
1801 bool columnori = (c ==
'C' || c ==
'c');
1808 else if (isalpha(c))
1819 for (
size_t i = 1; i <= m; i++)
1821 while (s.get(c) && isspace(c));
1826 for (
size_t j = (symmetric ? i : 1); j <= n; j++)
1828 s >> (columnori ? A(j,i) : A(i,j));
1829 if (symmetric && j > i)
1845 return s <<
" (empty)"<< std::endl;
1848 for (
size_t i = 1; i <= A.
rows(); i++)
1850 size_t c1 = symm ? i : 1;
1851 s <<
"\nRow "<< i <<
": "<<
trunc(A(i,c1));
1852 for (
size_t j = c1+1; j <= A.
cols(); j++)
1853 s <<
' '<<
trunc(A(i,j));
1856 return s << std::endl;
1861 std::ostream& s = std::cout)
1864 s << label <<
" = [";
1868 for (
size_t i = 1; i <= X.
size(); i++)
1869 s <<
' '<<
trunc(X(i));
1870 s <<
" ];"<< std::endl;
1875 std::ostream& s = std::cout)
1878 s << label <<
" = [";
1882 size_t nsp = label ? 4 + strlen(label) : 1;
1883 for (
size_t i = 1; i <= A.
rows(); i++)
1888 for (
size_t k = 0; k < nsp; k++) s <<
' ';
1890 for (
size_t j = 1; j <= A.
cols(); j++)
1891 s <<
' '<<
trunc(A(i,j));
1893 s <<
" ];"<< std::endl;
BLAS support for various platforms.
static SystemMatrix * K
Pointer to coefficient matrix A.
Definition: EigSolver.C:91
static SystemMatrix * M
Pointer to coefficient matrix B.
Definition: EigSolver.C:92
virtual bool empty() const
Checks if the matrix is empty.
Definition: SystemMatrix.h:249
Common base class for multi-dimensional (2D and 3D) matrices.
Definition: matrix.h:308
size_t n[4]
Dimension of the matrix.
Definition: matrix.h:440
size_t dim(short int d=1) const
Query dimensions.
Definition: matrix.h:376
const T * ptr(size_t c=0) const
Reference through pointer.
Definition: matrix.h:397
matrixBase< T > & add(const matrixBase< T > &A, const T &alfa)
Add the given matrix A scaled by alfa to *this.
Definition: matrix.h:1584
matrixBase(vector< T > &vec)
Constructor using an external vector for matrix element storage.
Definition: matrix.h:313
void fill(const T *values, size_t n=0)
Fill the matrix with data from an array.
Definition: matrix.h:413
matrixBase()
The constructor is protected to allow sub-class instances only.
Definition: matrix.h:311
const vector< T > & toVec() const
Type casting to a one-dimensional utl::vector, for access.
Definition: matrix.h:385
vector< T > & elem
Actual matrix elements, stored column by column.
Definition: matrix.h:441
void fill(T s)
Fill the matrix with a scalar value.
Definition: matrix.h:411
matrixBase(const matrixBase< T > &mat, bool copyContent=true)
Copy constructor.
Definition: matrix.h:322
size_t size() const
Query total matrix size.
Definition: matrix.h:378
T norm2(int inc=1) const
Return the Euclidean norm of the matrix.
Definition: matrix.h:422
void clear()
Clears the matrix and sets its dimension to zero.
Definition: matrix.h:408
T * ptr(size_t c=0)
Access through pointer.
Definition: matrix.h:392
T asum(int inc=1) const
Return the sum of the absolute value of the matrix elements.
Definition: matrix.h:425
T sum(int inc=1) const
Return the sum of the matrix elements.
Definition: matrix.h:429
bool empty() const
Check if the matrix is empty.
Definition: matrix.h:380
bool zero(T tol=T(0)) const
Check if the matrix elements are all zero.
Definition: matrix.h:382
virtual void clearIfNrowChanged(size_t n1, size_t n2, size_t n3)=0
Clears the matrix content if the first dimension(s) changed.
void redim(size_t n_1, size_t n_2, size_t n_3, size_t n_4, bool forceClear)
Resize the matrix to dimension .
Definition: matrix.h:338
matrixBase(size_t n_1, size_t n_2, size_t n_3=1, size_t n_4=1)
Constructor creating a matrix of dimension .
Definition: matrix.h:316
vector< T > myElem
Internal matrix storage.
Definition: matrix.h:444
matrixBase< T > & multiply(const T &c)
Multiplication of this matrix by a scalar c.
Definition: matrix.h:1595
std::vector< T >::iterator begin()
Iterator to the start of the matrix elements.
Definition: matrix.h:403
std::vector< T >::iterator end()
Iterator to the end of the matrix elements.
Definition: matrix.h:405
Two-dimensional rectangular matrix with some algebraic operations.
Definition: matrix.h:456
matrix< T > & operator/=(T d)
Division by a scalar.
Definition: matrix.h:842
size_t cols() const
Query number of matrix columns.
Definition: matrix.h:560
bool multiply(const std::vector< T > &X, std::vector< T > &Y, const T &alpha, const T &beta=T(0), bool transA=false, int stridex=1, int stridey=1, unsigned int ofsx=0, unsigned int ofsy=0) const
Matrix-vector multiplication.
Definition: matrix.h:1625
bool multiply(const std::vector< T > &X, std::vector< T > &Y, bool transA=false, char addTo=0) const
Matrix-vector multiplication.
Definition: matrix.h:1603
matrix< T > & add(const matrix< T > &A, T alfa=T(1))
Add the given matrix A scaled by alfa to *this.
Definition: matrix.h:834
T trace() const
Return the trace of the matrix (sum of its diagonal elements).
Definition: matrix.h:741
matrix< T > & operator*=(T c)
Multiplication with a scalar.
Definition: matrix.h:840
std::vector< T > getColumn(size_t c) const
Extract a column from the matrix.
Definition: matrix.h:615
matrix(size_t r, size_t c)
Constructor creating a matrix of dimension .
Definition: matrix.h:464
void extractBlock(matrix< T > &block, size_t r, size_t c, bool addTo=false, bool transposed=false) const
Extract a block of the matrix to another matrix.
Definition: matrix.h:699
void fillRow(size_t r, const T *data)
Fill a row of the matrix.
Definition: matrix.h:661
void clearIfNrowChanged(size_t n1, size_t, size_t) override
Clears the content if the number of rows changed.
Definition: matrix.h:1024
T normInf() const
Return the infinite norm of the matrix.
Definition: matrix.h:921
size_t & ncol
Number of matrix columns.
Definition: matrix.h:1031
bool augmentRows(const matrix< T > &B)
Increase the number of rows by augmenting the given matrix.
Definition: matrix.h:527
bool augmentCols(const matrix< T > &B)
Increase the number of columns by augmenting the given matrix.
Definition: matrix.h:547
bool compatible(const std::vector< T > &X, const std::vector< T > &Y)
Check dimension compatibility for outer product multiplication.
Definition: matrix.h:1008
matrix< T > & multiply(const matrix< T > &A, const matrix< T > &B, bool transA=false, bool transB=false, bool addTo=false, const T &alpha=T(1))
Matrix-matrix multiplication.
Definition: matrix.h:1661
matrix< T > & multiply(T c)
Multiplication of this matrix by a scalar c.
Definition: matrix.h:844
T & operator()(size_t r, size_t c)
Index-1 based element access.
Definition: matrix.h:585
bool isSymmetric(T tol=T(0)) const
Check for symmetry.
Definition: matrix.h:813
vector< T > getRow(size_t r) const
Extract a row from the matrix.
Definition: matrix.h:602
matrix< T > & transpose()
Replace the current matrix by its transpose.
Definition: matrix.h:728
T det() const
Compute the determinant of a square matrix.
Definition: matrix.h:750
matrix< T > & operator=(const matrix< T > &A)
Assignment operator.
Definition: matrix.h:563
matrix< T > & operator+=(const matrix< T > &A)
Add the given matrix A to *this.
Definition: matrix.h:830
T inverse(T tol=T(0))
Compute the inverse of a square matrix.
Definition: matrix.h:773
void fillColumn(size_t c, const T *data)
Fill a column of the matrix.
Definition: matrix.h:654
matrix(const matrix< T > &mat, bool transposed=false)
Copy constructor, optionally creates the transpose of mat.
Definition: matrix.h:467
void fillBlock(const matrix< T > &block, size_t r, size_t c, bool transposed=false)
Fill a block of the matrix with another matrix.
Definition: matrix.h:671
bool compatible(const matrix< T > &A, const matrix< T > &B, bool transA, bool transB, size_t &M, size_t &N, size_t &K)
Check dimension compatibility for matrix-matrix multiplication.
Definition: matrix.h:950
size_t & nrow
Number of matrix rows.
Definition: matrix.h:1030
T colsum(size_t c) const
Return the sum of a matrix column.
Definition: matrix.h:745
const T & operator()(size_t r, size_t c) const
Index-1 based element reference.
Definition: matrix.h:594
void resize(size_t r, size_t c, bool forceClear=false)
Resize the matrix to dimension .
Definition: matrix.h:488
T rowsum(size_t r) const
Return the sum of a matrix row.
Definition: matrix.h:743
size_t rows() const
Query number of matrix rows.
Definition: matrix.h:558
matrix< T > & operator-=(const matrix< T > &A)
Subtract the given matrix A from *this.
Definition: matrix.h:832
virtual ~matrix()
Empty destructor.
Definition: matrix.h:480
matrix()
Constructor creating an empty matrix.
Definition: matrix.h:459
void addBlock(const matrix< T > &block, T s, size_t r, size_t c, bool transposed=false)
Add a scalar multiple of another matrix to a block of the matrix.
Definition: matrix.h:685
matrix< T > & diag(T d, size_t dim=0)
Create a diagonal matrix.
Definition: matrix.h:716
bool multiplyMat(const std::vector< T > &A, const matrix< T > &B, bool transB=false, bool addTo=false)
Matrix-matrix multiplication.
Definition: matrix.h:1712
bool outer_product(const std::vector< T > &X, const std::vector< T > &Y, bool addTo=false, T alpha=T(1))
Outer product between two vectors.
Definition: matrix.h:1733
void fillColumn(size_t c, const std::vector< T > &data)
Fill a column of the matrix.
Definition: matrix.h:646
matrix< T > & operator=(const std::vector< T > &X)
Overloaded assignment operator.
Definition: matrix.h:574
bool multiplyMat(const matrix< T > &A, const std::vector< T > &B, bool transA=false, bool addTo=false)
Matrix-matrix multiplication.
Definition: matrix.h:1691
matrix(vector< T > &vec)
Constructor using an external vector for matrix element storage.
Definition: matrix.h:461
bool compatible(const std::vector< T > &X, bool transA) const
Check dimension compatibility for matrix-vector multiplication.
Definition: matrix.h:935
matrix< T > & expandRows(int incRows)
Increase or decrease the number of rows in the matrix.
Definition: matrix.h:494
bool compatible(const matrix< T > &A, const std::vector< T > &B, bool transA, size_t &M, size_t &N, size_t &K)
Check dimension compatibility for matrix-matrix multiplication, when the matrix B is represented by a...
Definition: matrix.h:971
void fill(const std::vector< T > &v, size_t n, size_t m=0)
Fill the matrix with vector data.
Definition: matrix.h:628
bool compatible(const std::vector< T > &A, const matrix< T > &B, bool transB, size_t &M, size_t &N, size_t &K)
Check dimension compatibility for matrix-matrix multiplication, when the matrix A is represented by a...
Definition: matrix.h:990
A vector class with some added algebraic operations.
Definition: matrix.h:64
VecIter begin()
Start of the vector container, for update.
Definition: matrix.h:108
VecIter end()
End of the vector container, for update.
Definition: matrix.h:110
vector()
Constructor creating an empty vector.
Definition: matrix.h:67
vector(const T *values, size_t n)
Constructor creating a vector from a C-array.
Definition: matrix.h:71
const T & operator()(size_t i) const
Index-1 based element reference.
Definition: matrix.h:130
vector< T > & operator+=(const vector< T > &X)
Add the given vector X to *this.
Definition: matrix.h:182
void fill(T s)
Fill the vector with a scalar value.
Definition: matrix.h:137
void fill(const T *values, size_t n=0)
Fill the vector with data from an array.
Definition: matrix.h:139
T asum(size_t off=0, int inc=1) const
Return the sum of the absolute value of the vector elements.
Definition: matrix.h:1550
vector< T > & operator*=(const std::vector< T > &X)
Component-wise multiplication with a vector.
Definition: matrix.h:167
T max() const
Return the largest element of the vector.
Definition: matrix.h:247
typename std::vector< T >::iterator VecIter
Convenience alias for non-const iterators.
Definition: matrix.h:101
void push_back(T c)
Append a scalar value to the vector, increasing its size by one.
Definition: matrix.h:147
bool empty() const
Is the vector empty (zero size)?
Definition: matrix.h:90
T normInf(int inc=1) const
Return the infinite norm of the vector (no index offset).
Definition: matrix.h:244
void reserve(size_t n)
Pre-allocation of vector length to n.
Definition: matrix.h:293
void push_back(const T *p, const T *q)
Append a range of values increasing the size by q-p.
Definition: matrix.h:156
bool zero(T tol=T(0)) const
Is the vector elements all zero?
Definition: matrix.h:92
T & operator()(size_t i)
Index-1 based element access.
Definition: matrix.h:123
vector< T > & add(const std::vector< T > &X, const T &alfa=T(1), unsigned int ofsx=0, int stridex=1, unsigned int ofsy=0, int stridey=1)
Add the given vector X scaled by alfa to *this.
Definition: matrix.h:1562
vector< T > & operator/=(const std::vector< T > &X)
Component-wise division with a vector.
Definition: matrix.h:174
T norm2(size_t off=0, int inc=1) const
Return the Euclidean norm of the vector.
Definition: matrix.h:1513
ConstVecIter begin() const
Start of the vector container, for access.
Definition: matrix.h:104
void swap(vector< T > &vec)
Swap the content with another vector.
Definition: matrix.h:159
std::vector< T > myVec
Internal vector storage.
Definition: matrix.h:298
typename std::vector< T >::const_iterator ConstVecIter
Convenience alias for const iterators.
Definition: matrix.h:99
vector< T > & relax(T alfa, const std::vector< T > &X, const std::vector< T > &Y)
Perform where Z = *this.
Definition: matrix.h:203
vector< T > & operator-=(const vector< T > &X)
Subtract the given vector X from *this.
Definition: matrix.h:184
T & operator[](size_t i)
Index-0 based element access.
Definition: matrix.h:118
ConstVecIter end() const
End of the vector container, for access.
Definition: matrix.h:106
vector< T > & operator=(const std::vector< T > &X)
Overloaded assignment operator.
Definition: matrix.h:76
T min() const
Return the smallest element of the vector.
Definition: matrix.h:249
void push_back(ConstVecIter i1, ConstVecIter i2)
Append a range of values increasing the size by i2-i1.
Definition: matrix.h:150
vector(const std::vector< T > &X)
Overloaded copy constructor.
Definition: matrix.h:73
bool resize(size_t n, char forceClear=0)
Resize the vector to length n.
Definition: matrix.h:277
T sum(size_t off=0, int inc=1, size_t max=0) const
Return the sum of the vector elements.
Definition: matrix.h:260
void clear()
Clear the vector, setting its size to zero.
Definition: matrix.h:295
T dot(const T *v, size_t nv, size_t off1=0, int inc1=1, size_t off2=0, int inc2=1) const
Dot product between *this and another vector.
Definition: matrix.h:1502
vector< T > & operator*=(T c)
Multiplication with a scalar.
Definition: matrix.h:1494
vector< T > & relax(T alfa, const std::vector< T > &X)
Perform where Y = *this.
Definition: matrix.h:192
size_t size() const
Size of the vector.
Definition: matrix.h:88
vector< T > & operator/=(T d)
Division by a scalar.
Definition: matrix.h:164
const T & operator[](size_t i) const
Index-0 based element reference.
Definition: matrix.h:120
T normInf(size_t &off, int inc=1, bool sign=false) const
Return the infinite norm of the vector, or signed max value.
Definition: matrix.h:1526
vector(size_t n)
Constructor creating a vector of length n.
Definition: matrix.h:69
const T * ptr() const
Reference through pointer.
Definition: matrix.h:85
T * ptr()
Access through pointer.
Definition: matrix.h:83
T dot(const std::vector< T > &v, size_t off1=0, int inc1=1, size_t off2=0, int inc2=1) const
Dot product between *this and another vector.
Definition: matrix.h:225
General utility classes and functions.
Definition: SIMoptions.h:22
T trunc(T v)
Truncate a value to zero when it is less than a given threshold.
Definition: matrix.h:1765
double zero_print_tol
Zero tolerance for printing numbers.
Definition: MatVec.C:24
std::ostream & operator<<(std::ostream &s, const vector< T > &X)
Print the vector X to the stream s.
Definition: matrix.h:1783
int nval_per_line
Number of values to print per line.
Definition: MatVec.C:23
const char RETAIN
Flag for vector::resize() method telling it to retain its content.
Definition: matrix.h:55
std::istream & operator>>(std::istream &s, vector< T > &X)
Read the vector X from the stream s.
Definition: matrix.h:1772
void writeMatlab(const char *label, const vector< T > &X, std::ostream &s=std::cout)
Print the vector X to the stream s in matlab format.
Definition: matrix.h:1860
Global parameters for controlling the print of vectors and matrices.