@ -13,6 +13,7 @@ 
			
		
	
		
			
				
					# include  "src/exceptions/out_of_range.h"  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					# include  "Eigen/Sparse"  
			
		
	
		
			
				
					# include  "src/sparse/eigen_sparse_additions.h"  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					namespace  mrmc  {  
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -46,13 +47,13 @@ class StaticSparseMatrix { 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/ / !  Constructor  
			
		
	
		
			
				
						 /*!  
			
		
	
		
			
				
							\ param  rows  Row - Count  and  therefore  column - count  of  the  symmetric  matrix  
			
		
	
		
			
				
							\ param  non_zero_entries  The  exact  count  of  entries  that  will  be  submitted  through  addNextValue  * excluding *  those  on  the  diagonal  ( A_ { i , j }  with  i  =  j )  
			
		
	
		
			
				
							\ param  rows  Row - Count  and  therefore  column - count  of  the  square  matrix  
			
		
	
		
			
				
						 */  
			
		
	
		
			
				
						StaticSparseMatrix ( uint_fast32_t  rows ,  uint_fast32_t  non_zero_entries )  {  
			
		
	
		
			
				
							setState ( MatrixStatus : : UnInitialized ) ;  
			
		
	
		
			
				
						StaticSparseMatrix ( uint_fast32_t  rows )  {  
			
		
	
		
			
				
							/ /  Using  direct  access  instead  of  setState ( )  because  of  undefined  initialization  value  
			
		
	
		
			
				
							/ /  setState ( )  stays  in  Error  should  Error  be  the  current  value  
			
		
	
		
			
				
							internal_status  =  MatrixStatus : : UnInitialized ;  
			
		
	
		
			
				
							current_size  =  0 ;  
			
		
	
		
			
				
							storage_size  =  0 ;  
			
		
	
		
			
				
							 
			
		
	
		
			
				
							value_storage  =  NULL ;  
			
		
	
		
			
				
							diagonal_storage  =  NULL ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -60,7 +61,7 @@ class StaticSparseMatrix { 
			
		
	
		
			
				
							row_indications  =  NULL ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							row_count  =  rows ;  
			
		
	
		
			
				
							non_zero_entry_count  =  non_zero_entries ;  
			
		
	
		
			
				
							non_zero_entry_count  =  0 ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							/ / initialize ( rows ,  non_zero_entries ) ;  
			
		
	
		
			
				
						}  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -85,98 +86,123 @@ class StaticSparseMatrix { 
			
		
	
		
			
				
							}  
			
		
	
		
			
				
						}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/ / !  Getter  for  saving  matrix  entry  A_ { row , col }  to  target  
			
		
	
		
			
				
						/*!  
			
		
	
		
			
				
							Getter  function  for  the  matrix .  This  function  does  not  check  the  internal  status  for  errors  for  performance  reasons .  
			
		
	
		
			
				
							\ param  row  1 - based  index  of  the  requested  row  
			
		
	
		
			
				
							\ param  col  1 - based  index  of  the  requested  column  
			
		
	
		
			
				
							\ param  target  pointer  to  where  the  result  will  be  stored  
			
		
	
		
			
				
							\ return  True  iff  the  value  was  set ,  false  otherwise .  On  false ,  0  will  be  written  to  * target .  
			
		
	
		
			
				
						*/  
			
		
	
		
			
				
						inline  bool  getValue ( uint_fast32_t  row ,  uint_fast32_t  col ,  T *  const  target )  {  
			
		
	
		
			
				
							 
			
		
	
		
			
				
							if  ( row  = =  col )  {  
			
		
	
		
			
				
								/ /  storage  is  row_count  +  1  large  for  direct  access  without  the  - 1  
			
		
	
		
			
				
								* target  =  diagonal_storage [ row ] ;  
			
		
	
		
			
				
								return  true ;  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( ( row  >  row_count )  | |  ( col  >  row_count )  | |  ( row  = =  0 )  | |  ( col  = =  0 ) )  {  
			
		
	
		
			
				
								throw  mrmc : : exceptions : : out_of_range ( " mrmc::StaticSparseMatrix::getValue: row or col not in 1 .. rows " ) ;  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							uint_fast32_t  row_start  =  row_indications [ row  -  1 ] ;  
			
		
	
		
			
				
							uint_fast32_t  row_end  =  row_indications [ row ] ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							while  ( row_start  <  row_end )  {  
			
		
	
		
			
				
								if  ( column_indications [ row_start ]  = =  col )  {  
			
		
	
		
			
				
									* target  =  value_storage [ row_start ] ;  
			
		
	
		
			
				
									return  true ;  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
								if  ( column_indications [ row_start ]  >  col )  {  
			
		
	
		
			
				
									break ;  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
								row_start + + ;  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							* target  =  0 ;  
			
		
	
		
			
				
							return  false ;  
			
		
	
		
			
				
						}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/ / !  Mandatory  initialization  of  the  matrix  
			
		
	
		
			
				
						/ / !  Mandatory  initialization  of  the  matrix ,  variant  for  initialize ( ) ,  addNextValue ( )  and  finalize ( )  
			
		
	
		
			
				
						/*!  
			
		
	
		
			
				
							Mandatory  initialization  of  the  matrix ,  must  be  called  before  using  any  other  member  function .  
			
		
	
		
			
				
							This  version  is  to  be  used  together  with  addNextValue ( ) .  
			
		
	
		
			
				
							For  initialization  from  a  Eigen  SparseMatrix ,  use  initialize ( Eigen : : SparseMatrix < T >  & ) .  
			
		
	
		
			
				
							\ param  non_zero_entries  The  exact  count  of  entries  that  will  be  submitted  through  addNextValue  * excluding *  those  on  the  diagonal  ( A_ { i , j }  with  i  =  j )  
			
		
	
		
			
				
						 */  
			
		
	
		
			
				
						void  initialize ( )  {  
			
		
	
		
			
				
						void  initialize ( uint_fast32_t  non_zero_entries )  {  
			
		
	
		
			
				
							if  ( internal_status  ! =  MatrixStatus : : UnInitialized )  {  
			
		
	
		
			
				
								triggerErrorState ( ) ;  
			
		
	
		
			
				
								pantheios : : log_ERROR ( " StaticSparseMatrix::initialize: Throwing invalid state for status flag != 0 (is  " ,  pantheios : : integer ( internal_status ) , "  - Already initialized? " ) ;  
			
		
	
		
			
				
								throw  mrmc : : exceptions : : invalid_state ( " StaticSparseMatrix::initialize: Invalid state for status flag != 0 - Already initialized? " ) ;  
			
		
	
		
			
				
								triggerErrorState ( ) ;  
			
		
	
		
			
				
							}  else  if  ( row_count  = =  0 )  {  
			
		
	
		
			
				
								triggerErrorState ( ) ;  
			
		
	
		
			
				
								pantheios : : log_ERROR ( " StaticSparseMatrix::initialize: Throwing invalid_argument for row_count = 0 " ) ;  
			
		
	
		
			
				
								throw  mrmc : : exceptions : : invalid_argument ( " mrmc::StaticSparseMatrix::initialize: Matrix with 0 rows is not reasonable " ) ;  
			
		
	
		
			
				
							}  else  if  ( ( ( row_count  *  row_count )  -  row_count )  <  non_zero_entries )  {  
			
		
	
		
			
				
								triggerErrorState ( ) ;  
			
		
	
		
			
				
							}  else  if  ( ( ( row_count  *  row_count )  -  row_count )  <  non_zero_entry_count )  {  
			
		
	
		
			
				
								pantheios : : log_ERROR ( " StaticSparseMatrix::initialize: Throwing invalid_argument: More non-zero entries than entries in target matrix " ) ;  
			
		
	
		
			
				
								throw  mrmc : : exceptions : : invalid_argument ( " mrmc::StaticSparseMatrix::initialize: More non-zero entries than entries in target matrix " ) ;  
			
		
	
		
			
				
								triggerErrorState ( ) ;  
			
		
	
		
			
				
							}  else  {  
			
		
	
		
			
				
								storage_size  =  non_zero_entry_count ;  
			
		
	
		
			
				
								non_zero_entry_count  =  non_zero_entries ;  
			
		
	
		
			
				
								last_row  =  0 ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								/ / value_storage  =  static_cast < T * > ( calloc ( storage_size ,  sizeof ( * value_storage ) ) ) ;  
			
		
	
		
			
				
								value_storage  =  new  ( std : : nothrow )  T [ storage_size ] ( ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								/ / column_indications  =  static_cast < uint_fast32_t * > ( calloc ( storage_size ,  sizeof ( * column_indications ) ) ) ;  
			
		
	
		
			
				
								column_indications  =  new  ( std : : nothrow )  uint_fast32_t [ storage_size ] ( ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								/ / row_indications  =  static_cast < uint_fast32_t * > ( calloc ( row_count  +  1 ,  sizeof ( * row_indications ) ) ) ;  
			
		
	
		
			
				
								row_indications  =  new  ( std : : nothrow )  uint_fast32_t [ row_count  +  1 ] ( ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								/ /  row_count  +  1  so  that  access  with  1 - based  indices  can  be  direct  without  the  overhead  of  a  - 1  each  time  
			
		
	
		
			
				
								/ / diagonal_storage  =  static_cast < T * > ( calloc ( row_count  +  1 ,  sizeof ( * diagonal_storage ) ) ) ;  
			
		
	
		
			
				
								diagonal_storage  =  new  ( std : : nothrow )  T [ row_count  +  1 ] ( ) ;  
			
		
	
		
			
				
							 
			
		
	
		
			
				
								if  ( ( value_storage  = =  NULL )  | |  ( column_indications  = =  NULL )  | |  ( row_indications  = =  NULL )  | |  ( diagonal_storage  = =  NULL ) )  {  
			
		
	
		
			
				
								if  ( ! prepareInternalStorage ( ) )  {  
			
		
	
		
			
				
									triggerErrorState ( ) ;  
			
		
	
		
			
				
									pantheios : : log_ERROR ( " StaticSparseMatrix::initialize: Throwing bad_alloc: memory allocation failed " ) ;  
			
		
	
		
			
				
									throw  std : : bad_alloc ( ) ;  
			
		
	
		
			
				
									triggerErrorState ( ) ;  
			
		
	
		
			
				
								}  else  {  
			
		
	
		
			
				
									setState ( MatrixStatus : : Initialized ) ;  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
						}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/ / !  Mandatory  initialization  of  the  matrix ,  variant  for  initialize ( ) ,  addNextValue ( )  and  finalize ( )  
			
		
	
		
			
				
						/*!  
			
		
	
		
			
				
							Mandatory  initialization  of  the  matrix ,  must  be  called  before  using  any  other  member  function .  
			
		
	
		
			
				
							This  version  is  to  be  used  for  initialization  from  a  Eigen  SparseMatrix ,  use  initialize ( uint_fast32_t )  for  addNextValue .  
			
		
	
		
			
				
							\ param  eigen_sparse_matrix  The  Eigen  Sparse  Matrix  to  be  copied /  initialized  from .  MUST  BE  in  compressed  form !  
			
		
	
		
			
				
						 */  
			
		
	
		
			
				
						template < typename  _Scalar ,  int  _Options ,  typename  _Index >  
			
		
	
		
			
				
						void  initialize ( const  Eigen : : SparseMatrix < _Scalar ,  _Options ,  _Index >  & eigen_sparse_matrix )  {  
			
		
	
		
			
				
							if  ( ! eigen_sparse_matrix . isCompressed ( ) )  {  
			
		
	
		
			
				
								triggerErrorState ( ) ;  
			
		
	
		
			
				
								pantheios : : log_ERROR ( " StaticSparseMatrix::initialize: Throwing invalid_argument: eigen_sparse_matrix is not in Compressed form. " ) ;  
			
		
	
		
			
				
								throw  mrmc : : exceptions : : invalid_argument ( " StaticSparseMatrix::initialize: Throwing invalid_argument: eigen_sparse_matrix is not in Compressed form. " ) ;  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							non_zero_entry_count  =  getEigenSparseMatrixCorrectNonZeroEntryCount ( eigen_sparse_matrix ) ;  
			
		
	
		
			
				
							last_row  =  0 ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( ! prepareInternalStorage ( ) )  {  
			
		
	
		
			
				
								triggerErrorState ( ) ;  
			
		
	
		
			
				
								pantheios : : log_ERROR ( " StaticSparseMatrix::initialize: Throwing bad_alloc: memory allocation failed " ) ;  
			
		
	
		
			
				
								throw  std : : bad_alloc ( ) ;  
			
		
	
		
			
				
							}  else  {  
			
		
	
		
			
				
								/ /  easy  case ,  we  can  simply  copy  the  data  
			
		
	
		
			
				
								/ /  RowMajor :  Easy ,  ColMajor :  Hmm .  But  how  to  detect ?  
			
		
	
		
			
				
								const  T *  valuePtr  =  eigen_sparse_matrix . valuePtr ( ) ;  
			
		
	
		
			
				
								const  int_fast32_t *  indexPtr  =  eigen_sparse_matrix . innerIndexPtr ( ) ;  
			
		
	
		
			
				
								const  int_fast32_t *  outerPtr  =  eigen_sparse_matrix . outerIndexPtr ( ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								const  int_fast32_t  entryCount  =  eigen_sparse_matrix . nonZeros ( ) ;  
			
		
	
		
			
				
								const  int_fast32_t  outerCount  =  eigen_sparse_matrix . outerSize ( ) ;  
			
		
	
		
			
				
								if  ( isEigenRowMajor ( eigen_sparse_matrix ) )  {  
			
		
	
		
			
				
									/ /  Easy  case ,  all  data  can  be  copied  with  some  minor  changes .  
			
		
	
		
			
				
									/ /  We  have  to  separate  diagonal  entries  from  others  
			
		
	
		
			
				
									for  ( int  row  =  1 ;  row  < =  outerCount ;  + + row )  {  
			
		
	
		
			
				
										for  ( int  col  =  outerPtr [ row  -  1 ] ;  col  <  outerPtr [ row ] ;  + + col )  {  
			
		
	
		
			
				
											addNextValue ( row ,  indexPtr [ col ]  +  1 ,  valuePtr [ col ] ) ;  
			
		
	
		
			
				
										}  
			
		
	
		
			
				
									}  
			
		
	
		
			
				
								}  else  {  
			
		
	
		
			
				
									/ /  temp  copies ,  anyone ?  
			
		
	
		
			
				
									const  int  eigen_col_count  =  eigen_sparse_matrix . cols ( ) ;  
			
		
	
		
			
				
									const  int  eigen_row_count  =  eigen_sparse_matrix . rows ( ) ;  
			
		
	
		
			
				
									 
			
		
	
		
			
				
									/ /  initialise  all  column - start  positions  to  known  lower  boundarys  
			
		
	
		
			
				
									int_fast32_t *  positions  =  new  int_fast32_t [ eigen_col_count ] ( ) ;  
			
		
	
		
			
				
									for  ( int  i  =  0 ;  i  <  eigen_col_count ;  + + i )  {  
			
		
	
		
			
				
										positions [ i ]  =  outerPtr [ i ] ;  
			
		
	
		
			
				
									}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
									int  i  =  0 ;  
			
		
	
		
			
				
									int  currentRow  =  0 ;  
			
		
	
		
			
				
									int  currentColumn  =  0 ;  
			
		
	
		
			
				
									while  ( i  <  entryCount )  {  
			
		
	
		
			
				
										if  ( ( positions [ currentColumn ]  <  outerPtr [ currentColumn  +  1 ] )  & &  ( indexPtr [ positions [ currentColumn ] ]  = =  currentRow ) )  {  
			
		
	
		
			
				
											addNextValue ( currentRow  +  1 ,  currentColumn  +  1 ,  valuePtr [ positions [ currentColumn ] ] ) ;  
			
		
	
		
			
				
											/ /  one  more  found  
			
		
	
		
			
				
											+ + i ;  
			
		
	
		
			
				
											/ /  mark  this  position  as  " used "  
			
		
	
		
			
				
											+ + positions [ currentColumn ] ;  
			
		
	
		
			
				
										}  
			
		
	
		
			
				
										/ /  advance  to  next  column  
			
		
	
		
			
				
										+ + currentColumn ;  
			
		
	
		
			
				
										if  ( currentColumn  = =  eigen_col_count )  {  
			
		
	
		
			
				
											currentColumn  =  0 ;  
			
		
	
		
			
				
											+ + currentRow ;  
			
		
	
		
			
				
										}  
			
		
	
		
			
				
									}  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
								setState ( MatrixStatus : : Initialized ) ;  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
						}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/ / !  Linear  Setter  for  matrix  entry  A_ { row ,  col }  to  value  
			
		
	
		
			
				
						/*!  
			
		
	
		
			
				
							Linear  Setter  function  for  matrix  entry  A_ { row ,  col }  to  value .  Must  be  called  consecutively  for  each  element  in  a  row  in  ascending  order  of  columns  AND  in  ascending  order  of  rows .  
			
		
	
		
			
				
							Diagonal  entries  may  be  set  at  any  time .  
			
		
	
		
			
				
						 */  
			
		
	
		
			
				
						void  addNextValue ( const  uint_fast32_t  row ,  const  uint_fast32_t  col ,  const  T  value )  {  
			
		
	
		
			
				
						void  addNextValue ( const  uint_fast32_t  row ,  const  uint_fast32_t  col ,  const  T  & value )  {  
			
		
	
		
			
				
							if  ( ( row  >  row_count )  | |  ( col  >  row_count )  | |  ( row  = =  0 )  | |  ( col  = =  0 ) )  {  
			
		
	
		
			
				
								pantheios : : log_ERROR ( " StaticSparseMatrix::addNextValue: Throwing out_of_range: row or col not in 1 .. rows " ) ;  
			
		
	
		
			
				
								throw  mrmc : : exceptions : : out_of_range ( " mrmc::StaticSparseMatrix::addNextValue: row or col not in 1 .. rows " ) ;  
			
		
	
		
			
				
								triggerErrorState ( ) ;  
			
		
	
		
			
				
								pantheios : : log_ERROR ( " StaticSparseMatrix::addNextValue: Throwing out_of_range: row or col not in 1 .. rows (is  " ,  pantheios : : integer ( row ) ,  "  x  " ,  pantheios : : integer ( col ) ,  " , max is  " ,  pantheios : : integer ( row_count ) ,  "  x  " ,  pantheios : : integer ( row_count ) ,  " ). " ) ;  
			
		
	
		
			
				
								throw  mrmc : : exceptions : : out_of_range ( " StaticSparseMatrix::addNextValue: row or col not in 1 .. rows " ) ;  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
							 
			
		
	
		
			
				
							if  ( row  = =  col )  {  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -199,13 +225,13 @@ class StaticSparseMatrix { 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						void  finalize ( )  {  
			
		
	
		
			
				
							if  ( ! isInitialized ( ) )  {  
			
		
	
		
			
				
								triggerErrorState ( ) ;  
			
		
	
		
			
				
								pantheios : : log_ERROR ( " StaticSparseMatrix::finalize: Throwing invalid state for internal state not Initialized (is  " ,  pantheios : : integer ( internal_status ) , "  - Already finalized? " ) ;  
			
		
	
		
			
				
								throw  mrmc : : exceptions : : invalid_state ( " StaticSparseMatrix::finalize: Invalid state for internal state not Initialized - Already finalized? " ) ;  
			
		
	
		
			
				
							}  else  if  ( current_size  ! =  non_zero_entry_count )  {  
			
		
	
		
			
				
								triggerErrorState ( ) ;  
			
		
	
		
			
				
							}  else  if  ( storage_size  ! =  current_size )  {  
			
		
	
		
			
				
								pantheios : : log_ERROR ( " StaticSparseMatrix::finalize: Throwing invalid_state: Wrong call count for addNextValue " ) ;  
			
		
	
		
			
				
								throw  mrmc : : exceptions : : invalid_state ( " mrmc::StaticSparseMatrix::finalize: Wrong call count for addNextValue " ) ;  
			
		
	
		
			
				
								triggerErrorState ( ) ;  
			
		
	
		
			
				
								throw  mrmc : : exceptions : : invalid_state ( " StaticSparseMatrix::finalize: Wrong call count for addNextValue " ) ;  
			
		
	
		
			
				
							}  else  {  
			
		
	
		
			
				
								if  ( last_row  ! =  row_count )  {  
			
		
	
		
			
				
									for  ( uint_fast32_t  i  =  last_row ;  i  <  row_count ;  + + i )  {  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -213,12 +239,52 @@ class StaticSparseMatrix { 
			
		
	
		
			
				
									}  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								row_indications [ row_count ]  =  storage_size ;  
			
		
	
		
			
				
								row_indications [ row_count ]  =  non_zero_entry_count ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								setState ( MatrixStatus : : ReadReady ) ;  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
						}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/ / !  Getter  for  saving  matrix  entry  A_ { row , col }  to  target  
			
		
	
		
			
				
						/*!  
			
		
	
		
			
				
							Getter  function  for  the  matrix .  This  function  does  not  check  the  internal  status  for  errors  for  performance  reasons .  
			
		
	
		
			
				
							\ param  row  1 - based  index  of  the  requested  row  
			
		
	
		
			
				
							\ param  col  1 - based  index  of  the  requested  column  
			
		
	
		
			
				
							\ param  target  pointer  to  where  the  result  will  be  stored  
			
		
	
		
			
				
							\ return  True  iff  the  value  was  set ,  false  otherwise .  On  false ,  0  will  be  written  to  * target .  
			
		
	
		
			
				
						*/  
			
		
	
		
			
				
						inline  bool  getValue ( uint_fast32_t  row ,  uint_fast32_t  col ,  T *  const  target )  {  
			
		
	
		
			
				
							 
			
		
	
		
			
				
							if  ( row  = =  col )  {  
			
		
	
		
			
				
								/ /  storage  is  row_count  +  1  large  for  direct  access  without  the  - 1  
			
		
	
		
			
				
								* target  =  diagonal_storage [ row ] ;  
			
		
	
		
			
				
								return  true ;  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( ( row  >  row_count )  | |  ( col  >  row_count )  | |  ( row  = =  0 )  | |  ( col  = =  0 ) )  {  
			
		
	
		
			
				
								pantheios : : log_ERROR ( " StaticSparseMatrix::getValue: row or col not in 1 .. rows (is  " ,  pantheios : : integer ( row ) ,  "  x  " ,  pantheios : : integer ( col ) ,  " , max is  " ,  pantheios : : integer ( row_count ) ,  "  x  " ,  pantheios : : integer ( row_count ) ,  " ). " ) ;  
			
		
	
		
			
				
								throw  mrmc : : exceptions : : out_of_range ( " StaticSparseMatrix::getValue: row or col not in 1 .. rows " ) ;  
			
		
	
		
			
				
								return  false ;  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							uint_fast32_t  row_start  =  row_indications [ row  -  1 ] ;  
			
		
	
		
			
				
							uint_fast32_t  row_end  =  row_indications [ row ] ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							while  ( row_start  <  row_end )  {  
			
		
	
		
			
				
								if  ( column_indications [ row_start ]  = =  col )  {  
			
		
	
		
			
				
									* target  =  value_storage [ row_start ] ;  
			
		
	
		
			
				
									return  true ;  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
								if  ( column_indications [ row_start ]  >  col )  {  
			
		
	
		
			
				
									break ;  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
								row_start + + ;  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							* target  =  0 ;  
			
		
	
		
			
				
							return  false ;  
			
		
	
		
			
				
						}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						uint_fast32_t  getRowCount ( )  const  {  
			
		
	
		
			
				
							return  row_count ;  
			
		
	
		
			
				
						}  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -243,16 +309,24 @@ class StaticSparseMatrix { 
			
		
	
		
			
				
							return  ( internal_status  = =  MatrixStatus : : Error ) ;  
			
		
	
		
			
				
						}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/ / !  Converts  this  matrix  to  an  equivalent  sparse  matrix  in  Eigens  format .  
			
		
	
		
			
				
						/*!  
			
		
	
		
			
				
							Exports  this  sparse  matrix  to  Eigens  SparseMatrix  format .  
			
		
	
		
			
				
							Required  this  matrix  to  be  in  the  ReadReady  state .  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							@ return  The  Eigen  SparseMatrix  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						 */  
			
		
	
		
			
				
						Eigen : : SparseMatrix < T >  toEigenSparseMatrix ( )  {  
			
		
	
		
			
				
							Eigen : : SparseMatrix < T >  mat ( row_count ,  row_count ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( ! isReadReady ( ) )  {  
			
		
	
		
			
				
								triggerErrorState ( ) ;  
			
		
	
		
			
				
								pantheios : : log_ERROR ( " StaticSparseMatrix::toEigenSparseMatrix: Throwing invalid state for internal state not ReadReady (is  " ,  pantheios : : integer ( internal_status ) , " ). " ) ;  
			
		
	
		
			
				
								throw  mrmc : : exceptions : : invalid_state ( " StaticSparseMatrix::toEigenSparseMatrix: Invalid state for internal state not ReadReady. " ) ;  
			
		
	
		
			
				
								triggerErrorState ( ) ;  
			
		
	
		
			
				
							}  else  {  
			
		
	
		
			
				
								typedef  Eigen : : Triplet < double >  ETd ;  
			
		
	
		
			
				
								std : : vector < ETd >  tripletList ;  
			
		
	
		
			
				
								typedef  Eigen : : Triplet < int >  IntTriplet ;  
			
		
	
		
			
				
								std : : vector < IntTriplet >  tripletList ;  
			
		
	
		
			
				
								tripletList . reserve ( non_zero_entry_count  +  row_count ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								uint_fast32_t  row_start ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -261,12 +335,12 @@ class StaticSparseMatrix { 
			
		
	
		
			
				
									row_start 	=  row_indications [ row  -  1 ] ;  
			
		
	
		
			
				
									row_end 		=  row_indications [ row ] ;  
			
		
	
		
			
				
									while  ( row_start  <  row_end )  {  
			
		
	
		
			
				
										tripletList . push_back ( ETd ( row  -  1 ,  column_indications [ row_start ]  -  1 ,  value_storage [ row_start ] ) ) ;  
			
		
	
		
			
				
										tripletList . push_back ( IntTriplet ( row  -  1 ,  column_indications [ row_start ]  -  1 ,  value_storage [ row_start ] ) ) ;  
			
		
	
		
			
				
										+ + row_start ;  
			
		
	
		
			
				
									}  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
								for  ( uint_fast32_t  i  =  1 ;  i  < =  row_count ;  + + i )  {  
			
		
	
		
			
				
									tripletList . push_back ( ETd ( i ,  i ,  diagonal_storage [ i ] ) ) ;  
			
		
	
		
			
				
									tripletList . push_back ( IntTriplet ( i ,  i ,  diagonal_storage [ i ] ) ) ;  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								mat . setFromTriplets ( tripletList . begin ( ) ,  tripletList . end ( ) ) ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -276,8 +350,72 @@ class StaticSparseMatrix { 
			
		
	
		
			
				
							return  mat ;  
			
		
	
		
			
				
						}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/ / !  Alternative  way  to  initialize  this  matrix  instead  of  using  initialize ( ) ,  addNextValue ( )  and  finalize ( ) .  
			
		
	
		
			
				
						/*!  
			
		
	
		
			
				
							Initializes  the  matrix  from  the  given  eigen_sparse_matrix .  Replaces  the  calls  to  initialize ( ) ,  addNextValue ( )  and  finalize ( ) .  
			
		
	
		
			
				
							Requires  eigen_sparse_matrix  to  have  at  most  a  size  of  rows  x  rows  and  not  more  than  non_zero_entries  on  non - diagonal  fields .  
			
		
	
		
			
				
							To  calculate  the  non - zero - entry  count  on  only  non - diagonal  fields ,  you  may  use  getEigenSparseMatrixCorrectNonZeroEntryCount ( ) .  
			
		
	
		
			
				
							In  most  cases ,  it  may  be  easier  to  use  the  alternative  constructor  StaticSparseMatrix ( const  Eigen : : SparseMatrix < T >  eigen_sparse_matrix ) .  
			
		
	
		
			
				
							@ param  eigen_sparse_matrix  the  Eigen  Sparse  Matrix  from  which  this  matrix  should  be  initalized .  
			
		
	
		
			
				
							@ see  getEigenSparseMatrixCorrectNonZeroEntryCount ( )  
			
		
	
		
			
				
							@ see  StaticSparseMatrix ( const  Eigen : : SparseMatrix < T > )  
			
		
	
		
			
				
						 */  
			
		
	
		
			
				
						bool  fromEigenSparseMatrix ( const  Eigen : : SparseMatrix < T >  eigen_sparse_matrix )  {  
			
		
	
		
			
				
							if  ( getState ( )  ! =  MatrixStatus : : UnInitialized )  {  
			
		
	
		
			
				
								triggerErrorState ( ) ;  
			
		
	
		
			
				
								pantheios : : log_ERROR ( " StaticSparseMatrix::fromEigenSparseMatrix: Throwing invalid state for internal state not UnInitialized (is  " ,  pantheios : : integer ( internal_status ) , " ). " ) ;  
			
		
	
		
			
				
								throw  mrmc : : exceptions : : invalid_state ( " StaticSparseMatrix::fromEigenSparseMatrix: Invalid state for internal state not UnInitialized. " ) ;  
			
		
	
		
			
				
								return  false ;  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							int_fast32_t  eigen_row_count  =  eigen_sparse_matrix . rows ( ) ;  
			
		
	
		
			
				
							int_fast32_t  eigen_col_count  =  eigen_sparse_matrix . cols ( ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( ( eigen_row_count  >  row_count )  | |  ( eigen_col_count  >  row_count ) )  {  
			
		
	
		
			
				
								triggerErrorState ( ) ;  
			
		
	
		
			
				
								pantheios : : log_ERROR ( " StaticSparseMatrix::fromEigenSparseMatrix: Throwing invalid argument for eigenSparseMatrix is too big to fit (is  " ,  pantheios : : integer ( eigen_row_count ) , "  x  " ,  pantheios : : integer ( eigen_col_count ) ,  " , max is  " ,  pantheios : : integer ( row_count ) , "  x  " ,  pantheios : : integer ( row_count ) ,  " ). " ) ;  
			
		
	
		
			
				
								throw  mrmc : : exceptions : : invalid_argument ( " StaticSparseMatrix::fromEigenSparseMatrix: Invalid argument for eigenSparseMatrix is too big to fit. " ) ;  
			
		
	
		
			
				
								return  false ;  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							uint_fast32_t  eigen_non_zero_entries  =  mrmc : : sparse : : getEigenSparseMatrixCorrectNonZeroEntryCount ( eigen_sparse_matrix ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( eigen_non_zero_entries  >  non_zero_entry_count )  {  
			
		
	
		
			
				
								triggerErrorState ( ) ;  
			
		
	
		
			
				
								pantheios : : log_ERROR ( " StaticSparseMatrix::fromEigenSparseMatrix: Throwing invalid argument for eigenSparseMatrix has too many non-zero entries to fit (is  " ,  pantheios : : integer ( eigen_non_zero_entries ) , " , max is  " ,  pantheios : : integer ( non_zero_entry_count ) , " ). " ) ;  
			
		
	
		
			
				
								throw  mrmc : : exceptions : : invalid_argument ( " StaticSparseMatrix::fromEigenSparseMatrix: Invalid argument for eigenSparseMatrix has too many non-zero entries to fit. " ) ;  
			
		
	
		
			
				
								return  false ;  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							/ /  make  compressed  
			
		
	
		
			
				
							eigen_sparse_matrix . makeCompressed ( ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( eigen_sparse_matrix . IsRowMajor ( ) )  {  
			
		
	
		
			
				
								/ /  inner  Index  
			
		
	
		
			
				
								int_fast32_t *  eigenInnerIndex  =  eigen_sparse_matrix . innerIndexPtr ( ) ;  
			
		
	
		
			
				
								T *  eigenValuePtr  =  eigen_sparse_matrix . valuePtr ( ) ;  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
							 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							for  ( int  k  =  0 ;  k  <  tempESM . outerSize ( ) ;  + + k )  {  
			
		
	
		
			
				
								for  ( SparseMatrix < T > : : InnerIterator  it ( tempESM ,  k ) ;  it ;  + + it )  {  
			
		
	
		
			
				
									if  ( eigen_non_zero_entries  > =  non_zero_entry_count )  {  
			
		
	
		
			
				
										/ /  too  many  non  zero  entries  for  us .  
			
		
	
		
			
				
									}  
			
		
	
		
			
				
									addNextValue ( it . row ( )  -  1 ,  it . col ( )  -  1 ,  it . value ( ) ) ;  
			
		
	
		
			
				
									if  ( it . row ( )  ! =  it . col ( ) )  {  
			
		
	
		
			
				
										+ + eigen_non_zero_entries ;  
			
		
	
		
			
				
									}  
			
		
	
		
			
				
									/*it.value();  
			
		
	
		
			
				
									it . row ( ) ;    / /  row  index  
			
		
	
		
			
				
									it . col ( ) ;    / /  col  index  ( here  it  is  equal  to  k )  
			
		
	
		
			
				
									it . index ( ) ;  / /  inner  index ,  here  it  is  equal  to  it . row ( ) */  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
						}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					 private :  
			
		
	
		
			
				
						uint_fast32_t  storage_size ;  
			
		
	
		
			
				
						uint_fast32_t  current_size ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						uint_fast32_t  row_count ;  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -309,6 +447,74 @@ class StaticSparseMatrix { 
			
		
	
		
			
				
						void  setState ( const  MatrixStatus  new_state )  {  
			
		
	
		
			
				
							internal_status  =  ( internal_status  = =  MatrixStatus : : Error )  ?  internal_status  :  new_state ;  
			
		
	
		
			
				
						}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						/*!  
			
		
	
		
			
				
							Prepares  the  internal  CSR  storage .  
			
		
	
		
			
				
							Requires  non_zero_entry_count  and  row_count  to  be  set .  
			
		
	
		
			
				
							@ return  true  on  success ,  false  otherwise  ( allocation  failed ) .  
			
		
	
		
			
				
						 */  
			
		
	
		
			
				
						bool  prepareInternalStorage ( )  {  
			
		
	
		
			
				
							value_storage  =  new  ( std : : nothrow )  T [ non_zero_entry_count ] ( ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							column_indications  =  new  ( std : : nothrow )  uint_fast32_t [ non_zero_entry_count ] ( ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							row_indications  =  new  ( std : : nothrow )  uint_fast32_t [ row_count  +  1 ] ( ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							/ /  row_count  +  1  so  that  access  with  1 - based  indices  can  be  direct  without  the  overhead  of  a  - 1  each  time  
			
		
	
		
			
				
							diagonal_storage  =  new  ( std : : nothrow )  T [ row_count  +  1 ] ( ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							return  ( ( value_storage  ! =  NULL )  & &  ( column_indications  ! =  NULL )  & &  ( row_indications  ! =  NULL )  & &  ( diagonal_storage  ! =  NULL ) ) ;  
			
		
	
		
			
				
						}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						template  < typename  _Scalar ,  typename  _Index >  
			
		
	
		
			
				
						bool  isEigenRowMajor ( Eigen : : SparseMatrix < _Scalar ,  Eigen : : RowMajor ,  _Index > )  {  
			
		
	
		
			
				
							return  true ;  
			
		
	
		
			
				
						}  
			
		
	
		
			
				
						 
			
		
	
		
			
				
						template  < typename  _Scalar ,  typename  _Index >  
			
		
	
		
			
				
						bool  isEigenRowMajor ( Eigen : : SparseMatrix < _Scalar ,  Eigen : : ColMajor ,  _Index > )  {  
			
		
	
		
			
				
							return  false ;  
			
		
	
		
			
				
						}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						template < typename  _Scalar ,  int  _Options ,  typename  _Index >  
			
		
	
		
			
				
						uint_fast32_t  getEigenSparseMatrixCorrectNonZeroEntryCount ( const  Eigen : : SparseMatrix < _Scalar ,  _Options ,  _Index >  & eigen_sparse_matrix )  {  
			
		
	
		
			
				
							const  int_fast32_t *  indexPtr  =  eigen_sparse_matrix . innerIndexPtr ( ) ;  
			
		
	
		
			
				
							const  int_fast32_t *  outerPtr  =  eigen_sparse_matrix . outerIndexPtr ( ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							const  int_fast32_t  entryCount  =  eigen_sparse_matrix . nonZeros ( ) ;  
			
		
	
		
			
				
							const  int_fast32_t  outerCount  =  eigen_sparse_matrix . outerSize ( ) ;  
			
		
	
		
			
				
							 
			
		
	
		
			
				
							uint_fast32_t  diag_non_zeros  =  0 ;  
			
		
	
		
			
				
							 
			
		
	
		
			
				
							/ /  for  RowMajor ,  row  is  the  current  Row  and  col  the  column  
			
		
	
		
			
				
							/ /  for  ColMajor ,  row  is  the  current  Col  and  col  the  row  
			
		
	
		
			
				
							int_fast32_t  innerStart  =  0 ;  
			
		
	
		
			
				
							int_fast32_t  innerEnd    =  0 ;  
			
		
	
		
			
				
							int_fast32_t  innerMid    =  0 ;  
			
		
	
		
			
				
							for  ( int  row  =  0 ;  row  <  outerCount ;  + + row )  {  
			
		
	
		
			
				
								innerStart  =  outerPtr [ row ] ;  
			
		
	
		
			
				
								innerEnd    =  outerPtr [ row  +  1 ]  -  1 ;  
			
		
	
		
			
				
								 
			
		
	
		
			
				
								/ /  Now  with  super  fancy  binary  search ,  deferred  equality  detection  
			
		
	
		
			
				
								while  ( innerStart  <  innerEnd )  {  
			
		
	
		
			
				
									innerMid  =  innerStart  +  ( ( innerEnd  -  innerStart )  /  2 ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
									if  ( indexPtr [ innerMid ]  <  row )  {  
			
		
	
		
			
				
										innerStart  =  innerMid  +  1 ;  
			
		
	
		
			
				
									}  else  {  
			
		
	
		
			
				
										innerEnd  =  innerMid ;  
			
		
	
		
			
				
									}  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
								if  ( ( innerStart  = =  innerEnd )  & &  ( indexPtr [ innerStart ]  = =  row ) )  {  
			
		
	
		
			
				
									/ /  found  a  diagonal  entry  
			
		
	
		
			
				
									+ + diag_non_zeros ;  
			
		
	
		
			
				
								}  
			
		
	
		
			
				
							}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							return  static_cast < uint_fast32_t > ( entryCount  -  diag_non_zeros ) ;  
			
		
	
		
			
				
						}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					} ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					}  / /  namespace  sparse