KASKADE 7 development version
umfpack_solve.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2002-2022 Zuse Institute Berlin */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13#ifndef UMFPACK_SOLVE_HH
14#define UMFPACK_SOLVE_HH
15
16#include <vector>
17#include <memory>
18
20
21namespace Kaskade
22{
23
28// A class for creating and storing symbolic factorizations.
29template<class Scalar,class UMFPackIndex=int>
30class UMFSymbolic
31{
32public:
33 //
34 UMFSymbolic(std::vector<UMFPackIndex> const & Ap,
35 std::vector<UMFPackIndex> const & Ai,
36 std::vector<Scalar> const & Az,
37 int verbose_ = 0);
38
39 ~UMFSymbolic();
40
41 // the opaque symbolic factorization data computed by UMFPack
42 void* getMem() { return mem; }
43
44 // compressed column storage index arrays
45 UMFPackIndex* getAp() { return &lAp[0]; }
46 UMFPackIndex* getAi() { return &lAi[0]; }
47
48private:
49 void* mem;
50 std::vector<UMFPackIndex> lAp;
51 std::vector<UMFPackIndex> lAi;
52};
53
54// A class for creating and storing numeric factorizations.
55template<class Scalar, class UMFPackIndex=int>
56class UMFFactorizationSpace
57{
58public:
59 UMFFactorizationSpace(std::vector<UMFPackIndex> const& Ap,
60 std::vector<UMFPackIndex> const& Ai,
61 std::vector<Scalar> const& Az);
62 ~UMFFactorizationSpace();
63
64 // the opaque numeric factorization data computed by UMFPack
65 void* getMem() { return mem; }
66
67 // compressed column storage index arrays
68 UMFPackIndex* getAp() { return symbolic.getAp(); }
69 UMFPackIndex* getAi() { return symbolic.getAi(); }
70
71private:
72 UMFSymbolic<Scalar,UMFPackIndex> symbolic;
73 void* mem;
74};
79// ------------------------------------------------------------------------------------------------
80
87template <class Scalar, class UMFPackIndex = int>
88class UMFFactorization: public Factorization<Scalar>
89{
90public:
91
101 UMFFactorization(UMFPackIndex n_,
102 std::vector<UMFPackIndex> const& ridx,
103 std::vector<UMFPackIndex> const& cidx,
104 std::vector<Scalar> const& values,
106 : N(ridx.size())
107 , n(n_), Az(N)
108 , options(opt)
109 {
110 assert(cidx.size()==N && values.size()==N);
111
112 // Transform triplet form into compressed column
113 std::vector<UMFPackIndex> Ap(n+1), Ai(N);
114 Kaskade::tripletToCompressedColumn(UMFPackIndex(n), UMFPackIndex(n), N,
115 ridx, cidx, values, Ap, Ai, Az);
116 factorization.reset(new UMFFactorizationSpace<Scalar,UMFPackIndex>(Ap,Ai,Az));
117 }
118
129 UMFFactorization(UMFPackIndex n_,
130 std::unique_ptr<std::vector<UMFPackIndex>> const ridx,
131 std::unique_ptr<std::vector<UMFPackIndex>> const cidx,
132 std::unique_ptr<std::vector<Scalar>> const values,
134 : N(ridx->size())
135 , n(n_), Az(N)
136 , options(opt)
137 {
138 assert(cidx->size()==N && values->size()==N);
139
140 // Transform triplet form into compressed column
141 std::vector<UMFPackIndex> Ap(n+1), Ai(N);
142 Kaskade::tripletToCompressedColumn(UMFPackIndex(n), UMFPackIndex(n), N,
143 ridx, cidx, values, Ap, Ai, Az);
144
145 // Clear memory of data that is not needed anymore.
146 ridx.reset();
147 cidx.reset();
148 values.reset();
149
150 factorization.reset(new UMFFactorizationSpace<Scalar,UMFPackIndex>(Ap,Ai,Az));
151 }
152
153
158 void solve(std::vector<Scalar> const& b, std::vector<Scalar>& x, bool transposed = false) const
159 {
160 assert(b.size() >= n);
161 x.resize(n);
162 solve_internal(&b[0],&x[0],transposed);
163 }
164
165 void solve(Scalar const* b, Scalar* x, bool transposed = false) const
166 {
167 solve_internal(b,x,transposed);
168 }
169
170 void solve(std::vector<Scalar> const& b, std::vector<Scalar>& x, int nr, bool transposed = false) const
171 {
172 assert(b.size()>=n*nr);
173 x.resize(nr*n);
174 for(int i=0; i<nr; ++i)
175 solve_internal(&b[i*n],&x[i*n],transposed);
176 }
177
184 void solve(std::vector<Scalar>& b) const
185 {
186 assert(b.size() >= n);
187 std::vector<Scalar> x(n);
188 solve(b,x);
189 std::swap(b,x);
190 }
191
198 void solve(Scalar* b) const
199 {
200 std::vector<Scalar> x(n);
201 solve(b,&x[0]);
202 std::copy(x.begin(),x.end(),b);
203 }
204
208 virtual size_t size() const
209 {
210 return n;
211 }
212
213
214private:
215
216 virtual void solve_internal(Scalar const* bp, Scalar* xp, bool transposed) const;
217
218 size_t const N; // number of nonzeroes in A
219 size_t const n; // dimension of A
220 std::vector<Scalar> Az;
221 std::unique_ptr<UMFFactorizationSpace<Scalar,UMFPackIndex>> factorization;
222 FactorizationOptions options;
223};
224
225void umfpack_solve(std::vector<int> const& ridx,
226 std::vector<int> const& cidx,
227 std::vector<double> const& values,
228 std::vector<double> const& b,
229 std::vector<double>& x);
230
231} // namespace Kaskade
232#endif
Abstract base class for matrix factorizations.
Factorization of sparse linear systems with UMFPack.
void solve(Scalar *b) const
Solves the system for the given right hand side.
void solve(std::vector< Scalar > const &b, std::vector< Scalar > &x, bool transposed=false) const
void solve(std::vector< Scalar > &b) const
Solves the system for the given right hand side.
UMFFactorization(UMFPackIndex n_, std::unique_ptr< std::vector< UMFPackIndex > > const ridx, std::unique_ptr< std::vector< UMFPackIndex > > const cidx, std::unique_ptr< std::vector< Scalar > > const values, FactorizationOptions opt)
Constructor destroying input data before factorization: more memory efficient.
virtual size_t size() const
reports the dimension of the system
void solve(std::vector< Scalar > const &b, std::vector< Scalar > &x, int nr, bool transposed=false) const
void solve(Scalar const *b, Scalar *x, bool transposed=false) const
Solves the system for the given right hand side .
UMFFactorization(UMFPackIndex n_, std::vector< UMFPackIndex > const &ridx, std::vector< UMFPackIndex > const &cidx, std::vector< Scalar > const &values, FactorizationOptions opt)
Constructor keeping input data in triplet format (aka coordinate format) constant....
void tripletToCompressedColumn(Index nRows, Index nCols, size_t nNonZeros, std::vector< Index > const &ridx, std::vector< Index > const &cidx, std::vector< Scalar > const &values, std::vector< Index > &Ap, std::vector< Index > &Ai, std::vector< Scalar > &Az)
Converts a matrix in triplet format to a compressed column format.
void umfpack_solve(std::vector< int > const &ridx, std::vector< int > const &cidx, std::vector< double > const &values, std::vector< double > const &b, std::vector< double > &x)
The Options struct allows to specify several options of factorization.