Shiokaze Framework
A research-oriented fluid solver for computer graphics
RCMatrix_utility.h
Go to the documentation of this file.
1 /*
2 ** RCMatrix_utility.h
3 **
4 ** This is part of Shiokaze, a research-oriented fluid solver for computer graphics.
5 ** Inspired by Robert Bridson's matrix code, re-written by Ryoichi Ando on Feb 7, 2017.
6 **
7 ** Permission is hereby granted, free of charge, to any person obtaining a copy of
8 ** this software and associated documentation files (the "Software"), to deal in
9 ** the Software without restriction, including without limitation the rights to use,
10 ** copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
11 ** Software, and to permit persons to whom the Software is furnished to do so,
12 ** subject to the following conditions:
13 **
14 ** The above copyright notice and this permission notice shall be included in all copies
15 ** or substantial portions of the Software.
16 **
17 ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
18 ** INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
19 ** PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 ** HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
21 ** CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22 ** OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24 //
25 #ifndef SHKZ_RCMATRIX_UTILITY_H
26 #define SHKZ_RCMATRIX_UTILITY_H
27 //
29 #include <shiokaze/core/console.h>
30 #include <cmath>
31 //
33 //
35 template <class N, class T> class RCMatrix_utility {
38 public:
47  static void diag( const RCMatrix_interface<N,T> *matrix, const std::vector<T> &diag ) {
48  matrix->initialize(diag.size(),diag.size());
49  for( N row=0; row<diag.size(); ++row ) matrix->add_to_element(row,row,diag[row]);
50  }
59  static T symmetricity_error ( const RCMatrix_interface<N,T> *matrix ) {
60  T max_error (0.0);
61  for( N row=0; row<matrix->rows(); ++row ) {
62  matrix->const_for_each(row,[&]( N column, T value ) {
63  if( column < matrix->rows()) {
64  max_error = std::max(max_error,std::abs(value-matrix->get(column,row)));
65  } else {
66  max_error = std::max(max_error,std::abs(value));
67  }
68  });
69  }
70  return max_error;
71  }
82  static bool report( const RCMatrix_interface<N,T> *matrix, std::string name ) {
83  //
84  N active(0), max_row(0), min_row(std::numeric_limits<N>::max()), active_rows(0);
85  T avg_row(0.0), max_diag(0.0), min_diag(std::numeric_limits<T>::max());
86  T diag_ratio(0.0);
87  bool symm_postive_diag (true);
88  bool has_nan (false);
89  for( N i=0; i<matrix->rows(); i++ ) {
90  if( ! matrix->empty(i) ) {
91  N row_nonzero = matrix->non_zeros(i);
92  active += row_nonzero;
93  max_row = std::max(max_row,row_nonzero);
94  min_row = std::min(min_row,row_nonzero);
95  avg_row += row_nonzero;
96  T diag (0.0);
97  T max_nondiag (0.0);
98  matrix->const_for_each(i,[&]( N column, T value ) {
99  if( column == i ) diag = value;
100  else max_nondiag = std::max(max_nondiag,std::abs(value));
101  if( value!=value ) has_nan = true;
102  });
103  max_diag = std::max(max_diag,diag);
104  min_diag = std::min(min_diag,diag);
105  if( diag ) diag_ratio = std::max( diag_ratio, max_nondiag / diag );
106  active_rows ++;
107  }
108  }
109  if( active_rows ) avg_row /= (T)active_rows;
110  double symmetric_error = symmetricity_error(matrix);
111  console::dump( ">>> ==== Matrix [%s] analysis ====\n", name.c_str());
112  console::dump( "Matrix dimension = %dx%d\n", matrix->rows(), matrix->columns() );
113  console::dump( "Matrix active row size = %d\n", active_rows );
114  console::dump( "Matrix nonzero entries = %d\n", active );
115  console::dump( "Matrix maximal row = %d\n", max_row );
116  console::dump( "Matrix minimal row = %d\n", min_row );
117  console::dump( "Matrix row average = %.2f\n", avg_row );
118  console::dump( "Matrix max diag = %.2e\n", max_diag );
119  console::dump( "Matrix min diag = %.2e\n", min_diag );
120  console::dump( "Matrix worst max(non_diag) / diag = %.2e\n", diag_ratio );
121  console::dump( "Matrix max(symmetricity error) = %.2e\n", symmetric_error );
122  console::dump( "Matrix has_NaN = %s\n", has_nan ? "Yes" : "No");
123  console::dump( "<<< =========================\n" );
124  if( min_diag < 0.0 ) {
125  console::dump( "WARNING: min_diag < 0.0\n");
126  symm_postive_diag = false;
127  }
128  if( symmetric_error ) symm_postive_diag = false;
129  return symm_postive_diag;
130  }
131  //
132 };
133 //
135 //
136 #endif
137 //
RCMatrix_interface::empty
bool empty() const
Get if the matrix is empty.
Definition: RCMatrix_interface.h:456
console::dump
void dump(std::string format,...)
Print a log message in a single line.
RCMatrix_interface.h
RCMatrix_interface::columns
virtual N columns() const =0
Get the size of columns.
RCMatrix_utility::symmetricity_error
static T symmetricity_error(const RCMatrix_interface< N, T > *matrix)
Measure the uniform norm of the symmetericity error.
Definition: RCMatrix_utility.h:59
RCMatrix_interface::const_for_each
void const_for_each(N row, std::function< void(N column, T value)> func) const
Read elements in serial order.
Definition: RCMatrix_interface.h:492
RCMatrix_interface::add_to_element
virtual void add_to_element(N row, N column, T increment_value)=0
Add a value to an element.
console.h
RCMatrix_interface::rows
virtual N rows() const =0
Get the size of rows.
RCMatrix_interface::get
virtual T get(N row, N column) const =0
Get the element value at the row and the column.
SHKZ_BEGIN_NAMESPACE
#define SHKZ_BEGIN_NAMESPACE
Name space beggining definition for shiokaze.
Definition: common.h:39
RCMatrix_utility::diag
static void diag(const RCMatrix_interface< N, T > *matrix, const std::vector< T > &diag)
Generate a diagonal matrix.
Definition: RCMatrix_utility.h:47
RCMatrix_utility::report
static bool report(const RCMatrix_interface< N, T > *matrix, std::string name)
Report matrix properties.
Definition: RCMatrix_utility.h:82
RCMatrix_interface::non_zeros
virtual N non_zeros(N row) const =0
Get the size of non zero entries in a row.
RCMatrix_interface
Interface for Row Compressed Matrix.
Definition: RCMatrix_interface.h:38
SHKZ_END_NAMESPACE
#define SHKZ_END_NAMESPACE
Name space end definition for shiokaze.
Definition: common.h:44
RCMatrix_interface::initialize
virtual void initialize(N rows, N columns)=0
Initialize matrix with rows and columns.
RCMatrix_utility
Class that provides utility functions for RCMatrix_interface.
Definition: RCMatrix_utility.h:37