1#ifndef VIENNASHE_SHE_ELIMINATE_HPP
2#define VIENNASHE_SHE_ELIMINATE_HPP
39 template <
typename FullMatrixType,
typename VectorType>
41 std::size_t line1, std::size_t line_to_add, std::size_t column_to_zero)
44 typedef typename FullMatrixType::row_type RowType;
45 typedef typename FullMatrixType::iterator2 AlongRowIterator;
47 const double s = system_matrix(line1, column_to_zero) / system_matrix(line_to_add, line_to_add);
51 RowType & values_to_add = system_matrix.row(line_to_add);
54 rhs[line1] = rhs[line1] - rhs[line_to_add] * s;
56 for (AlongRowIterator iter = values_to_add.begin(); iter != values_to_add.end(); ++iter)
58 const double value = iter->second;
59 const std::size_t current_col = iter->first;
63 system_matrix(line1, current_col) -= value * s ;
66 system_matrix.row(line1).erase(column_to_zero);
79 template <
typename FullMatrixType,
typename VectorType>
82 typedef typename FullMatrixType::row_type RowType;
83 typedef typename RowType::iterator AlongRowIterator;
85 const std::size_t N = rhs.size();
91 for ( std::size_t i = num_even + 1; i < N; ++i)
94 RowType & line = system_matrix.row(i);
96 for (AlongRowIterator cit = line.begin(); cit != line.end(); ++cit)
98 const std::size_t column_id = cit->first;
103 if ( column_id < num_even)
109 const std::size_t line_to_add = i - (i - column_id);
113 if (line_to_add < num_even)
115 std::cerr <<
"Oh no! line_to_add < num_even " << std::endl;
116 std::cerr <<
"Oh no! " << i <<
" - " << column_id <<
" < " << num_even << std::endl;
117 throw "Oh no! line_to_add < num_even ";
128 for (std::size_t i = num_even - 1; i < N; ++i)
130 RowType & col = system_matrix.row(i);
131 for (AlongRowIterator cit = col.begin(); cit != col.end(); )
135 AlongRowIterator cit_delete = cit;
137 col.erase(cit_delete);
147 for ( std::size_t i = N - 1 ;
151 RowType & line = system_matrix.row(i);
153 for (AlongRowIterator cit = line.begin(); cit != line.end(); ++cit)
155 const std::size_t column_id = cit->first;
157 if (column_id < i && column_id >= num_even)
159 std::cerr <<
"Oh no! There are still values left to the diagonal!" << std::endl;
160 std::cerr <<
" column_id = " << column_id <<
" # i = " << i <<
" # num_even = " << num_even << std::endl;
161 std::cerr << cit->second << std::endl;
162 throw "Oh no! There are still values left to the diagonal!";
166 if (column_id < num_even)
170 else if (column_id == i)
178 const std::size_t line_to_add = i + (column_id - i);
180 if (line_to_add >= N)
182 std::cerr <<
"Oh no! line_to_add >= N # " << line_to_add <<
" >= " << N << std::endl;
183 throw "Oh no! line_to_add >= N ";
196 for (std::size_t i = num_even - 1; i < N; ++i)
198 RowType & col = system_matrix.row(i);
199 for (AlongRowIterator cit = col.begin(); cit != col.end(); )
203 AlongRowIterator cit_delete = cit;
205 col.erase(cit_delete);
225 template <
typename FullMatrixType,
typename CompressedMatrixType,
typename VectorType>
227 CompressedMatrixType & compressed_matrix, VectorType & compressed_rhs)
229 typedef typename FullMatrixType::row_type RowType;
230 typedef typename FullMatrixType::iterator2 AlongRowIterator;
232 std::size_t num_even = compressed_matrix.size1();
234 for (std::size_t i=0; i<num_even; ++i)
237 compressed_rhs[i] = rhs[i];
239 RowType & row = system_matrix.row(i);
240 for ( AlongRowIterator iter = row.begin();
244 if ( iter->first < num_even )
246 compressed_matrix(i, iter->first) += iter->second;
251 double odd_diagonal_entry = -1.0;
253 RowType & odd_row = system_matrix.row(iter->first);
254 for ( AlongRowIterator odd_iter = odd_row.begin();
255 odd_iter != odd_row.end();
258 if (iter->first == odd_iter->first)
260 odd_diagonal_entry = odd_iter->second;
265 if ( odd_diagonal_entry <= 0.0 )
267 log::error() <<
"ERROR in eliminate_odd_unknowns(): Diagonal entry " << iter->first
268 <<
" not positive or not existing: " << odd_diagonal_entry << std::endl;
272 for ( AlongRowIterator odd_iter = odd_row.begin();
273 odd_iter != odd_row.end();
276 if (odd_iter->first < num_even)
278 compressed_matrix(i, odd_iter->first) -= iter->second * odd_iter->second / odd_diagonal_entry;
280 else if (iter->first != odd_iter->first)
282 log::error() <<
"WARNING in eliminate_odd_unknowns(): Odd2Odd block matrix has offdiagonal entry at ("
283 << iter->first <<
"," << odd_iter->first <<
")" << std::endl;
288 compressed_rhs[i] -= iter->second * rhs[iter->first] / odd_diagonal_entry;
304 template <
typename MatrixT,
typename VectorT>
306 VectorT
const & full_rhs,
307 VectorT
const & compressed_result)
309 typedef typename MatrixT::row_type RowType;
310 typedef typename MatrixT::const_iterator2 AlongRowIterator;
312 VectorT full_result(full_rhs.size());
313 size_t num_even = compressed_result.size();
315 for (std::size_t i=0; i<full_matrix.size1(); ++i)
317 RowType
const & row_i = full_matrix.row(i);
321 full_result[i] = compressed_result[i];
325 double diagonal_entry = 0.0;
326 full_result[i] = full_rhs[i];
327 for ( AlongRowIterator iter = row_i.begin();
331 if ( iter->first < num_even )
333 full_result[i] -= iter->second * full_result[iter->first];
335 else if ( i == iter->first )
337 diagonal_entry = iter->second;
339 else if( iter->second != 0.0)
341 log::warn() <<
"Non-diagonal entry found in odd-to-odd block!" << std::endl;
342 log::info<log_recover_odd_unknowns > () <<
"col_iter.index1() = " << i << std::endl;
343 log::info<log_recover_odd_unknowns > () <<
"col_iter.index2() = " << iter->first << std::endl;
344 log::info<log_recover_odd_unknowns > () <<
"*col_iter = " << iter->second << std::endl;
345 assert(
bool(
"Non-diagonal entry found in odd-to-odd block!"));
348 assert(diagonal_entry > 0.0 &&
bool(
"FATAL ERROR: Diagonal entry missing when recovering odd coefficients!"));
349 full_result[i] /= diagonal_entry;
Exception for the case that invalid expansion order is accessed.
A logging facility providing fine-grained control over logging in ViennaSHE.
logger< true > error()
Used to log errors. The logging level is logERROR.
logger< true > warn()
Used to log warnings. The logging level is logWARNING.
void combine_lines(FullMatrixType &system_matrix, VectorType &rhs, std::size_t line1, std::size_t line_to_add, std::size_t column_to_zero)
VectorT recover_odd_unknowns(MatrixT const &full_matrix, VectorT const &full_rhs, VectorT const &compressed_result)
Recovers the odd-order unknowns from the even-order unknowns.
void eliminate_odd_unknowns(FullMatrixType &system_matrix, VectorType const &rhs, CompressedMatrixType &compressed_matrix, VectorType &compressed_rhs)
Eliminates all odd spherical harmonics expansion coefficients from the system matrix.
void diagonalise_odd2odd_coupling_matrix(FullMatrixType &system_matrix, VectorType &rhs, std::size_t num_even)
Eliminates all odd spherical harmonics expansion coefficients in the off diagonals of S^oo from the s...
The main ViennaSHE namespace. All functionality resides inside this namespace.
Provides the exceptions used inside the viennashe::she namespace.
Defines the log keys used within the viennashe::she namespace.