7 #ifndef WONTON_MATRIX_H_ 8 #define WONTON_MATRIX_H_ 14 #include <type_traits> 26 static std::string ignore_msg=
"ignore";
27 static std::string &ignore_msg_ref(ignore_msg);
31 Matrix() : Rows_(0), Columns_(0) {}
33 Matrix(
int const Rows,
int const Columns) :
34 Rows_(Rows), Columns_(Columns) {
35 A_.resize(Rows_*Columns_);
39 explicit Matrix(
int const Rows,
int const Columns,
41 Rows_(Rows), Columns_(Columns) {
42 A_.resize(Rows_*Columns_);
43 for (
int i = 0; i < Rows_; ++i)
44 for (
int j = 0; j < Columns_; ++j)
45 A_[i*Columns_+j] = initval;
52 explicit Matrix(
std::vector<std::vector<double>>
const& invals) {
53 Rows_ = invals.size();
54 Columns_ = invals[0].size();
55 A_.resize(Rows_*Columns_);
56 for (
int i = 0; i < Rows_; ++i)
57 for (
int j = 0; j < Columns_; ++j)
58 A_[i*Columns_+j] = invals[i][j];
61 Matrix(Matrix
const& M) : Rows_(M.rows()), Columns_(M.columns()) {
65 Matrix& operator=(Matrix
const& M) {
67 Columns_ = M.columns();
68 A_.resize(Rows_*Columns_);
69 for (
int i = 0; i < Rows_; ++i)
70 for (
int j = 0; j < Columns_; ++j)
71 A_[i*Columns_+j] = M[i][j];
79 Matrix& operator+=(
const Matrix& rhs) {
80 assert((Rows_ == rhs.rows()) && (Columns_ == rhs.columns()));
82 for (
int i = 0; i < Rows_; ++i)
83 for (
int j = 0; j < Columns_; ++j)
84 A_[i*Columns_+j] += rhs[i][j];
92 Matrix& operator-=(
const Matrix& rhs) {
93 assert((Rows_ == rhs.rows()) && (Columns_ == rhs.columns()));
95 for (
int i = 0; i < Rows_; ++i)
96 for (
int j = 0; j < Columns_; ++j)
97 A_[i*Columns_+j] -= rhs[i][j];
105 Matrix& operator*=(
const double rhs) {
119 int rows()
const {
return Rows_;}
122 int columns()
const {
return Columns_;}
131 double * operator[](
int const RowIndex) {
133 return &(A_[RowIndex*Columns_]);
141 double const * operator[](
int const RowIndex)
const {
142 return &(A_[RowIndex*Columns_]);
146 Matrix transpose()
const {
147 Matrix AT(Columns_, Rows_);
148 for (
int i = 0; i < Rows_; ++i)
149 for (
int j = 0; j < Columns_; ++j)
150 AT[j][i] = A_[i*Columns_+j];
157 if (Rows_ != Columns_) {
158 std::cerr <<
"Matrix is not rectangular" << std::endl;
159 throw std::exception();
162 Matrix Ainv(Rows_, Rows_, 0.0);
165 Matrix D(Rows_, 2*Rows_);
169 for (
int i = 0; i < Rows_; i++) {
170 for (
int j = 0; j < Rows_; j++) {
171 D[i][j] = A_[i*Columns_+j];
178 for (
int i = 0; i < Rows_; i++) {
179 double alpha = D[i][i];
185 for (
int j = 0; j < Rows2; j++)
186 D[i][j] = D[i][j]/alpha;
188 for (
int k = 0; k < Rows_; k++) {
192 double beta = D[k][i];
193 for (
int j = 0; j < Rows2; j++)
194 D[k][j] = D[k][j] - beta*D[i][j];
200 for (
int i = 0; i < Rows_; i++)
201 for (
int j = 0; j < Rows_; j++)
202 Ainv[i][j] = D[i][j + Rows_];
213 std::vector<double>
operator*(std::vector<double>
const&
X)
const {
214 assert(
unsigned(Columns_) == X.size());
216 std::vector<double> AX(Rows_);
217 for (
int i = 0; i < Rows_; ++i) {
219 for (
int j = 0; j < Columns_; ++j)
220 AX[i] += A_[i*Columns_+j]*X[j];
232 Vector<D>
operator*(Vector<D>
const& X)
const {
233 assert(Rows_ == D && Columns_ == D);
236 for (
int i = 0; i < Rows_; ++i) {
238 for (
int j = 0; j < Columns_; ++j)
239 AX[i] += A_[i*Columns_+j]*X[j];
249 Matrix
operator*(Matrix
const& B)
const {
250 assert(Columns_ == B.rows());
252 Matrix AB(Rows_, B.columns(), 0.0);
254 for (
int i = 0; i < Rows_; ++i)
255 for (
int j = 0; j < B.columns(); ++j)
256 for (
int k = 0; k < Columns_; ++k)
257 AB[i][j] += A_[i*Columns_+k]*B[k][j];
266 const std::vector<double>& data()
const {
return A_; }
288 Matrix solve(Matrix
const& B,
289 std::string method=
"inverse",
290 std::string &error=ignore_msg_ref);
305 std::vector<double> A_;
307 int is_singular_ = 0;
311 inline Matrix
operator+(
const Matrix& A,
const Matrix& B) {
312 assert((A.rows() == B.rows()) && (A.columns() == B.columns()));
315 for (
int i = 0; i < A.rows(); ++i)
316 for (
int j = 0; j < A.columns(); ++j)
317 Sum[i][j] += B[i][j];
323 inline Matrix
operator-(
const Matrix& A,
const Matrix& B) {
324 assert((A.rows() == B.rows()) && (A.columns() == B.columns()));
327 for (
int i = 0; i < A.rows(); ++i)
328 for (
int j = 0; j < A.columns(); ++j)
329 Diff[i][j] -= B[i][j];
338 inline Matrix
operator*(
const Matrix& A,
const double& s) {
341 for (
int i = 0; i < A.rows(); ++i)
342 for (
int j = 0; j < A.columns(); ++j)
352 inline Matrix
operator*(
const double& s,
const Matrix& A) {
355 for (
int i = 0; i < A.rows(); ++i)
356 for (
int j = 0; j < A.columns(); ++j)
364 inline Matrix
operator*(
const Vector<D>& a,
const Vector<D>& b) {
366 for (
int i = 0; i < D; i++)
367 for (
int j = 0; j < D; j++)
368 prod[i][j] = a[i]*b[j];
385 void solve(
const Matrix& A,
const Vector<D>& b, Vector<D>& x) {
387 assert(n == A.columns());
390 const std::vector<double>& a_ = A.data();
397 std::vector<double> y(n);
400 for (i = 0; i < n; i++)
404 for (i = 0; i < n - 1; i++) {
406 for (j = i + 1, s = 0.0; j < n; j++) {
410 norm = sqrt(s +
pow2(y[i]));
411 assert(std::fabs(norm > std::numeric_limits<double>::epsilon()));
416 norm = sqrt(s +
pow2(y[i]));
418 for (j = i; j < n; j++)
422 for (k = 0; k < n; k++)
423 for (l = 0; l < n; l++)
425 U[k][l] = (k == l) ? 1.0 : 0.0;
427 U[k][l] = (k == l) ? 1.0 - 2.0*y[k]*y[l] : -2.0*y[k]*y[l];
435 assert(std::fabs(R[n - 1][n - 1]) > std::numeric_limits<double>::epsilon());
437 Vector<D> QTb = Q.transpose()*b;
440 for (i = n - 1; i >= 0; i--) {
441 for (k = i + 1; k < n; k++)
442 QTb[i] -= R[i][k]*x[k];
444 x[i] = QTb[i]/R[i][i];
456 void solve<1>(
const Matrix& A,
const Vector<1>& b, Vector<1>& x) {
457 assert(std::fabs(A[0][0]) > std::numeric_limits<double>::epsilon());
469 void solve<2>(
const Matrix& A,
const Vector<2>& b, Vector<2>& x) {
470 double detA = A[0][0]*A[1][1] - A[0][1]*A[1][0];
471 assert(std::fabs(detA) > std::numeric_limits<double>::epsilon());
473 x[0] = (A[1][1]*b[0] - A[0][1]*b[1])/detA;
474 x[1] = (A[0][0]*b[1] - A[1][0]*b[0])/detA;
479 #endif // WONTON_MATRIX_H_ Factorize a number N into D equal (or nearly equal) factors.
Definition: adaptive_refinement_mesh.h:31
std::vector< T > vector
Definition: wonton.h:285
WONTON_INLINE Point< D > operator*(const Point< D > &p, double s)
Definition: Point.h:247
const int X
Definition: Point.h:39
double pow2(double x)
Definition: wonton.h:329
WONTON_INLINE Vector< D > operator-(const Point< D > &p1, const Point< D > &p2)
Definition: Point.h:239
WONTON_INLINE Point< D > operator+(const Point< D > &p, const Vector< D > &v)
Definition: Point.h:227