Geophysical Inversion and Modelling Library v1.5.4
Loading...
Searching...
No Matches
blockmatrix.h
1/******************************************************************************
2 * Copyright (C) 2005-2024 by the GIMLi development team *
3 * Carsten Rücker carsten@resistivity.net *
4 * *
5 * Licensed under the Apache License, Version 2.0 (the "License"); *
6 * you may not use this file except in compliance with the License. *
7 * You may obtain a copy of the License at *
8 * *
9 * http://www.apache.org/licenses/LICENSE-2.0 *
10 * *
11 * Unless required by applicable law or agreed to in writing, software *
12 * distributed under the License is distributed on an "AS IS" BASIS, *
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
14 * See the License for the specific language governing permissions and *
15 * limitations under the License. *
16 * *
17 ******************************************************************************/
18
19#ifndef _GIMLI_BLOCKMATRIX__H
20#define _GIMLI_BLOCKMATRIX__H
21
22#include "gimli.h"
23
24#ifndef PYTEST
25 #include "sparsematrix.h"
26#endif
27
28#include "matrix.h"
29
30namespace GIMLI{
31
34public:
35 Index rowStart;
36 Index colStart;
37 Index matrixID;
38 double scale;
39 bool transpose;
40};
41
42template < class ValueType >
43class DLLEXPORT BlockMatrix : public MatrixBase{
44public:
45 BlockMatrix(bool verbose=false)
46 : MatrixBase(verbose), rows_(0), cols_(0) {
47 }
48
49 virtual ~BlockMatrix(){
50 this->clear();
51 }
52
54 virtual uint rtti() const { return GIMLI_BLOCKMATRIX_RTTI; }
55
56 virtual const Vector < ValueType > operator [] (Index r) const { return this->row(r); }
57
58 virtual Index rows() const { recalcMatrixSize(); return rows_; }
59
60 virtual Index cols() const { recalcMatrixSize(); return cols_; }
61
62 virtual const Vector < ValueType > row(Index r) const {
63 ASSERT_RANGE(r, 0, rows())
64 Vector < ValueType > b(rows(), 0.0);
65 b[r]=1.0;
66 return transMult(b);
67 }
68
69 virtual const Vector < ValueType > col(Index r) const{
70 ASSERT_RANGE(r, 0, cols())
71 Vector < ValueType > b(cols(), 0.0);
72 b[r]=1.0;
73 return mult(b);
74 }
75
76 virtual void clear(){
77 matrices_.clear();
78 entries_.clear();
79 }
80 virtual void clean(){
81 for (Index i = 0; i < matrices_.size(); i ++ ){
82 matrices_[i]->clean();
83 }
84 }
85
86 MatrixBase * mat(Index idx) {
87 ASSERT_SIZE(matrices_, idx)
88 return matrices_[idx];
89 }
90
91 MatrixBase & matRef(Index idx) const {
92 ASSERT_SIZE(matrices_, idx)
93 return *matrices_[idx];
94 }
95
96 std::vector< BlockMatrixEntry > entries() const {
97 return entries_; }
98
100 Index add(MatrixBase * matrix, Index rowStart, Index colStart){
101 return addMatrix(matrix, rowStart, colStart);
102 }
103
107 Index addMatrix(MatrixBase * matrix){
108// __MS(matrix << " " << matrix->rtti())
109 matrices_.push_back(matrix);
110 return matrices_.size() - 1;
111 }
112
114 Index addMatrix(MatrixBase * matrix, Index rowStart, Index colStart,
115 ValueType scale=1.0){
116 Index matrixID = addMatrix(matrix);
117 addMatrixEntry(matrixID, rowStart, colStart, scale);
118 return matrixID;
119 }
120
122 void addMatrixEntry(Index matrixID, Index rowStart, Index colStart){
123 // no default arg here .. pygimli@win64 linker bug
124 addMatrixEntry(matrixID, rowStart, colStart, ValueType(1.0));
125 }
126
128 void addMatrixEntry(Index matrixID, Index rowStart, Index colStart,
129 ValueType scale, bool transpose=false){
130 if (matrixID > matrices_.size()){
131 throwLengthError(WHERE_AM_I + " matrix entry to large: " +
132 str(matrixID) + " " + str(matrices_.size()));
133 }
134 BlockMatrixEntry entry;
135 entry.rowStart = rowStart;
136 entry.colStart = colStart;
137 entry.matrixID = matrixID;
138 entry.scale = scale;
139 entry.transpose = transpose;
140
141 entries_.push_back(entry);
142 recalcMatrixSize();
143 }
144
145 void recalcMatrixSize() const {
146 for (Index i = 0; i < entries_.size(); i++){
147 BlockMatrixEntry entry(entries_[i]);
148 MatrixBase *mat = matrices_[entry.matrixID];
149
150 rows_ = max(rows_, entry.rowStart + mat->rows());
151 cols_ = max(cols_, entry.colStart + mat->cols());
152 }
153 }
154
155 virtual Vector < ValueType > mult(const Vector < ValueType > & b) const;
156
157 virtual Vector < ValueType > transMult(const Vector < ValueType > & b) const;
158
159 RSparseMapMatrix sparseMapMatrix() const;
160
161 virtual void save(const std::string & filename) const {
162 std::cerr << WHERE_AM_I << "WARNING " << " don't save blockmatrix." << std::endl;
163// THROW_TO_IMPL
164 }
165
166protected:
167 std::vector< MatrixBase * > matrices_;
168 std::vector< BlockMatrixEntry > entries_;
169private:
171 mutable Index rows_;
172
174 mutable Index cols_;
175};
176
177template <> DLLEXPORT RVector BlockMatrix< double >::
178 mult(const RVector & b) const;
179
180template <> DLLEXPORT RVector BlockMatrix< double >::
181 transMult(const RVector & b) const;
182
183template <> DLLEXPORT RSparseMapMatrix BlockMatrix< double >::
184 sparseMapMatrix() const;
185
186inline RVector transMult(const BlockMatrix < double > & A, const RVector & b){
187 return A.transMult(b);
188}
189inline RVector operator * (const BlockMatrix < double > & A, const RVector & b){
190 return A.mult(b);
191}
192
193#ifndef PYTEST
196class DLLEXPORT H2SparseMapMatrix : public MatrixBase{
197public:
198
199 H2SparseMapMatrix(){}
200
201 virtual ~H2SparseMapMatrix(){}
202
203 virtual Index rows() const { return H1_.rows(); }
204
205 virtual Index cols() const { return H1_.cols() + H2_.cols(); }
206
207 virtual void clear() { H1_.clear(); H2_.clear(); }
208
210 virtual RVector mult(const RVector & a) const {
211 return H1_ * a(0, H1_.cols()) + H2_ * a(H1_.cols(), cols());
212 }
213
215 virtual RVector transMult(const RVector & a) const {
216 return cat(H1_.transMult(a), H2_.transMult(a));
217 }
218
220 inline const RSparseMapMatrix & H1() const { return H1_; }
221 inline const RSparseMapMatrix & H2() const { return H2_; }
222 inline RSparseMapMatrix & H1() { return H1_; }
223 inline RSparseMapMatrix & H2() { return H2_; }
224
225protected:
227 RSparseMapMatrix H1_, H2_;
228}; // class H2SparseMapMatrix
229
230
231inline void rank1Update(H2SparseMapMatrix & A, const RVector & u, const RVector & v) {
232 CERR_TO_IMPL
233 return;
234}
235
236inline bool save(const H2SparseMapMatrix & A, const std::string & filename, IOFormat format = Ascii){
237 CERR_TO_IMPL
238 return false;
239}
240
241// /*! Do we have to do this for every matrix type?? */
242// inline RVector operator * (const H2SparseMapMatrix & A, const RVector & x){
243// return A.H1() * x(0, A.H1().cols()) + A.H2() * x(A.H1().cols(), A.cols());
244// }
245//
246// inline RVector transMult(const H2SparseMapMatrix & A, const RVector & b){
247// return cat(transMult(A.H1(), b), transMult(A.H2(), b));
248// }
249
251template< class Matrix1, class Matrix2 > class H2Matrix{
252public:
253 H2Matrix(){}
254
255 virtual ~H2Matrix(){}
256
258 virtual Index rows() const { return H1_.rows(); }
259 virtual Index cols() const { return H1_.cols() + H2_.cols(); }
260
262 virtual RVector mult(const RVector & a) const {
263 return H1_ * a(0, H1_.cols()) + H2_ * a(H1_.cols(), cols());
264 }
265
267 virtual RVector transMult(const RVector & a) const {
268 return cat(H1_.transMult(a), H2_.transMult(a));
269 }
270protected:
271 Matrix1 H1_;
272 Matrix2 H2_;
273
274}; // H2Matrix
275
277template< class Matrix1, class Matrix2 > class V2Matrix : public MatrixBase{ };
279template< class Matrix1, class Matrix2 > class D2Matrix : public MatrixBase{ };
280
282template< class Matrix > class HNMatrix : public MatrixBase{
283public:
284 HNMatrix(){}
285
286 virtual ~HNMatrix(){}
287
288 void push_back(Matrix Mat){ //** standard procedure to build up matrix
289 if (Mats_.size() > 0 && Mats_[0].nrows() == Mat.rows()) {
290 Mats_.push_back(Mat);
291 } else {
292 throwLengthError(WHERE_AM_I + " matrix rows do not match " +
293 toStr(Mats_[0].nrows()) + " " + toStr(Mat.nrows()));
294 }
295 }
297 virtual Index rows() const {
298 if (Mats_.size() > 0) return Mats_[0].rows();
299 return 0;
300 }
301 virtual Index cols() const {
302 Index ncols = 0;
303 for (Index i=0 ; i < Mats_.cols() ; i++) ncols += Mats_[i].cols();
304 return ncols;
305 }
306
307protected:
308 std::vector < Matrix > Mats_;
309}; // HNMatrix
310
312template< class Matrix > class VNMatrix : public MatrixBase{ };
314template< class Matrix > class DNMatrix : public MatrixBase{ };
315
317template< class Matrix > class HRMatrix : public MatrixBase{
318public:
320 HRMatrix(){} //useful?
321 HRMatrix(const Matrix & Mat) : Mat_(Mat){}
322 HRMatrix(const Matrix & Mat, Index nmats) : Mat_(Mat), nmats_(nmats){}
323
324 ~HRMatrix(){}
325
326 void setNumber(Index nmats){ nmats_ = nmats; }
328 virtual Index rows() const { return Mat_.rows(); }
329 virtual Index cols() const { return Mat_.cols() * nmats_; }
330
331 inline const Matrix & Mat() const { return Mat_; }
332 inline Matrix & Mat() { return Mat_; }
333protected:
334 Matrix Mat_;
335 Index nmats_;
336}; // HRMatrix
337
339template< class Matrix > class VRMatrix : public MatrixBase{ };
341template< class Matrix > class DRMatrix : public MatrixBase{ };
342
343//** specializations better moved into gimli.h
347typedef DRMatrix< RMatrix > RDRMatrix;
349
352typedef DRMatrix< TwoModelsCMatrix > ManyModelsCMatrix; //** not really diagonal!
353typedef DRMatrix< RSparseMapMatrix > ManyCMatrix;
354typedef V2Matrix< ManyCMatrix, ManyModelsCMatrix > MMMatrix; // Multiple models (LCI,timelapse)
355#endif
356} // namespace GIMLI
357
358#endif //_GIMLI_BLOCKMATRIX__H
Block matrices for easier inversion, see appendix E in GIMLi tutorial.
Definition blockmatrix.h:33
virtual void clean()
Definition blockmatrix.h:80
Index addMatrix(MatrixBase *matrix)
Definition blockmatrix.h:107
void addMatrixEntry(Index matrixID, Index rowStart, Index colStart)
Definition blockmatrix.h:122
virtual uint rtti() const
Definition blockmatrix.h:54
virtual void clear()
Definition blockmatrix.h:76
virtual void save(const std::string &filename) const
Definition blockmatrix.h:161
virtual Index cols() const
Definition blockmatrix.h:60
Index add(MatrixBase *matrix, Index rowStart, Index colStart)
Definition blockmatrix.h:100
virtual Index rows() const
Definition blockmatrix.h:58
void addMatrixEntry(Index matrixID, Index rowStart, Index colStart, ValueType scale, bool transpose=false)
Definition blockmatrix.h:128
Index addMatrix(MatrixBase *matrix, Index rowStart, Index colStart, ValueType scale=1.0)
Definition blockmatrix.h:114
Definition blockmatrix.h:279
Definition blockmatrix.h:314
Definition blockmatrix.h:341
virtual RVector mult(const RVector &a) const
Definition blockmatrix.h:262
virtual Index rows() const
Definition blockmatrix.h:258
virtual RVector transMult(const RVector &a) const
Definition blockmatrix.h:267
Definition blockmatrix.h:196
virtual Index rows() const
Definition blockmatrix.h:203
virtual Index cols() const
Definition blockmatrix.h:205
RSparseMapMatrix H1_
create inplace (or better hold references of it?)
Definition blockmatrix.h:227
virtual RVector transMult(const RVector &a) const
Definition blockmatrix.h:215
virtual RVector mult(const RVector &a) const
Definition blockmatrix.h:210
const RSparseMapMatrix & H1() const
Definition blockmatrix.h:220
virtual void clear()
Definition blockmatrix.h:207
virtual Index rows() const
Definition blockmatrix.h:297
virtual Index cols() const
Definition blockmatrix.h:301
Definition blockmatrix.h:317
virtual Index rows() const
Definition blockmatrix.h:328
virtual Index cols() const
Definition blockmatrix.h:329
HRMatrix()
Definition blockmatrix.h:320
Interface class for matrices.
Definition matrix.h:137
MatrixBase(bool verbose=false)
Definition matrix.h:141
virtual Index cols() const
Definition matrix.h:163
virtual Index rows() const
Definition matrix.h:157
Simple row-based dense matrix based on Vector.
Definition matrix.h:324
Index rows() const
Definition matrix.h:422
Definition blockmatrix.h:277
Definition blockmatrix.h:312
Definition blockmatrix.h:339
One dimensional array aka Vector of limited size.
Definition vector.h:186
GIMLi main namespace for the Geophyiscal Inversion and Modelling Library.
Definition baseentity.h:24
H2Matrix< RMatrix, RMatrix > RH2Matrix
nomenclature: Type(R/S)+Alignment(H/V/D)+Number(2/N/R)+Matrix
Definition blockmatrix.h:345
H2Matrix< IdentityMatrix, IdentityMatrix > TwoModelsCMatrix
Some examples useful for special inversions.
Definition blockmatrix.h:351