00001
00002
00003
00004 #ifndef _H_CS_ZZ_ICRS
00005 #define _H_CS_ZZ_ICRS
00006
00007 #include "Triplet.hpp"
00008 #include <vector>
00009 #include <algorithm>
00010
00011 #include "CS_ELEMENT.hpp"
00012 #include "CS_ARRAY.hpp"
00013
00014
00015
00016 #ifdef _DEBUG
00017 #include<iostream>
00018 #endif
00019
00023 template< typename T >
00024 class CS_ZZ_ICRS {
00025
00026 private:
00027
00028 #ifdef _UNSIGNED
00029
00030 typedef unsigned long int ULI;
00031 #else
00032
00033 typedef long int ULI;
00034 #endif
00035
00036 protected:
00037
00039 CS_ELEMENT< ULI > nnz;
00040
00042 CS_ELEMENT< ULI > nor;
00043
00045 CS_ELEMENT< ULI > noc;
00046
00048 CS_ARRAY< T >* nzs;
00049
00051 CS_ARRAY< ULI >* c_ind;
00052
00054 CS_ARRAY< ULI >* r_ind;
00055
00057 CS_ELEMENT< T > zero_element;
00058
00060 static bool compareTriplets( const Triplet< T >& one, const Triplet< T >& two ) {
00061 if( one.i() < two.i() )
00062 return true;
00063 if ( one.i() > two.i() )
00064 return false;
00065 return one.j() < two.j();
00066 }
00067
00068 public:
00069
00079 CS_ZZ_ICRS( const ULI number_of_nonzeros, const ULI number_of_rows, const ULI number_of_cols, T zero ):
00080 nnz( number_of_nonzeros ), noc( number_of_cols ), nor( number_of_rows ), zero_element( zero ) {
00081 nzs = new CS_ARRAY< T >( nnz, "Nonzeros array( CS_ZZ_ICRS )" );
00082 c_ind = new CS_ARRAY< ULI >( nnz.unrecorded_access(), "Array storing the column index differences (CS_ZZ_ICRS)" );
00083 r_ind = new CS_ARRAY< ULI >( nnz.unrecorded_access(), "Array storing the row index differences (CS_ZZ_ICRS)" );
00084 }
00085
00090 CS_ZZ_ICRS( CS_ZZ_ICRS< T >& toCopy ) {
00091 zero_element = toCopy.zero_element;
00092 nnz = toCopy.nnz;
00093 noc = toCopy.noc;
00094 nor = toCopy.nor;
00095 nzs = new CS_ARRAY< T >( nnz, "Nonzeros array( CS_ZZ_ICRS, copied )" );
00096 c_ind = new CS_ARRAY< T >( nnz, "Array storing the column index differences (CS_ZZ_ICRS, copied )" );
00097 r_ind = new CS_ARRAY< T >( nnz, "Array storing the row index differences (CS_ZZ_ICRS, copied )" );
00098 for( CS_ELEMENT< ULI > i=0; i<nnz; i = i + 1 ) {
00099 nzs->access( i.const_access() ) = toCopy.nzs->const_access( i.const_access() );
00100 c_ind->access( i.const_access() ) = toCopy.c_ind->const_access( i.const_access() );
00101 r_ind->access( i.const_access() ) = toCopy.r_ind->const_access( i.const_access() );
00102 }
00103 }
00104
00115 CS_ZZ_ICRS( std::vector< Triplet< T > >& input, const ULI m, const ULI n, const T zero ) {
00116 zero_element = zero;
00117
00118 nor = m;
00119 noc = n;
00120
00121 typename std::vector< Triplet< T > >::iterator in_it;
00122
00123
00124
00125
00126
00127
00128 sort( input.begin(), input.end(), compareTriplets );
00129
00130
00131 unsigned long int prev_row = 0;
00132 std::vector< ULI > r_ind_temp;
00133 typename std::vector< Triplet< T > >::iterator it = input.begin();
00134 for( ; it!=input.end(); it++ ) {
00135 if( (*it).i() > prev_row ) {
00136 r_ind_temp.push_back( (*it).i() - prev_row );
00137 prev_row = (*it).i();
00138 }
00139 }
00140 nnz = input.size();
00141
00142
00143 nzs = new CS_ARRAY< T>( nnz.const_access(), "Array of nonzeros (CS_ZZ_ICRS)" );
00144 c_ind = new CS_ARRAY< ULI >( nnz.const_access() + 1, "Array of column index differences (CS_ZZ_ICRS)" );
00145 r_ind = new CS_ARRAY< ULI >( r_ind_temp.size() + 1, "Array of row index differences (CS_ZZ_ICRS)" );
00146
00147
00148 c_ind->access( nnz.const_access() ) = noc.const_access();
00149
00150
00151
00152 for( unsigned long int i=0; i<r_ind_temp.size(); i++ )
00153 r_ind->access( i ) = r_ind_temp[ i ];
00154
00155
00156 ULI prev_col = 0;
00157 prev_row = 0;
00158
00159 for( ULI i=0; i<nnz.const_access(); ++i ) {
00160 const Triplet< T > cur = input[ i ];
00161 const unsigned long int currow = cur.i();
00162 const unsigned long int curcol = cur.j();
00163 if( currow == prev_row ) {
00164 c_ind->access( i ) = curcol - prev_col;
00165 #ifdef _DEBUG
00166 std::cout << "1. c_ind[ " << i << " ] = " << c_ind->access( i ) << " = " << curcol << " - " << prev_col << ":\t\t " << currow << "," << curcol << std::endl;
00167 #endif
00168 nzs->access( i ) = cur.value;
00169 prev_col = curcol;
00170 } else {
00171
00172 prev_row = currow;
00173 ULI stop = i;
00174 ULI j = i;
00175
00176 while( j < nnz.const_access() && input[ j ].i() == currow )
00177 j++;
00178 j--;
00179
00180
00181 nzs->access( i ) = input[ j ].value;
00182 c_ind->access( i ) = noc.const_access() + ( input[ j ].j() - prev_col );
00183 prev_col = input[ j ].j();
00184
00185 #ifdef _DEBUG
00186 std::cout << "2. c_ind[ " << i << " ] = " << c_ind->const_access( i ) << " = " << input[ j ].j() << " - " << input[ j-1 ].j() << ":\t\t " << input[ j ].i() << "," << input[ j ].j() << std::endl;
00187 #endif
00188 i++;
00189 j--;
00190
00191 for( ; j>=stop; j-- ) {
00192 nzs->access( i ) = input[ j ].value;
00193 c_ind->access( i ) = prev_col - input[ j ].j();
00194 prev_col = input[ j ].j();
00195 #ifdef _DEBUG
00196 std::cout << "3. c_ind[ " << i << " ] = " << c_ind->const_access( i ) << " = " << input[ j ].j() << " - " << input[ j-1 ].j() << ":\t\t " << input[ j ].i() << "," << input[ j ].j() << std::endl;
00197 #endif
00198 i++;
00199 }
00200
00201 if( i >= nnz.const_access() ) break;
00202
00203
00204
00205 #ifdef _UNSIGNED
00206 c_ind->access( i ) = noc.const_access() + input[ i ].j();
00207 #else
00208 c_ind->access( i ) = noc.const_access() + ( prev_col - input[ i ].j() );
00209 #endif
00210
00211 #ifdef _DEBUG
00212 std::cout << "4. c_ind[ " << i << " ] = " << c_ind->unrecorded_access( i ) << " = " << noc.unrecorded_access() << " + " << input[ i ].j() << " - " << input[ stop ].j() << ":\t\t " << input[ i ].i() << "," << input[ i ].j() << std::endl;
00213 #endif
00214 nzs->access( i ) = input[ i ].value;
00215 prev_col = input[ i ].j();
00216 prev_row = input[ i ].i();
00217 }
00218 }
00219 }
00220
00231
00232
00233
00234
00243 T* zax( T* x_orig ) {
00244
00245 CS_ARRAY< T >* x = new CS_ARRAY< T >( noc.unrecorded_access(), "x-vector in CS_ZZ_ICRS::zax" );
00246 x->unrecordedCopyFrom( x_orig );
00247
00248 T* true_ret = new T[ nor.unrecorded_access() ];
00249 CS_ARRAY< T >* ret = new CS_ARRAY< T >( nor.unrecorded_access(), "z-vector in CS_ZZ_ICRS::zax" );
00250
00251 for( ULI i=0; i < nor.unrecorded_access(); ++i )
00252 ret->access( i ) = zero_element.unrecorded_access();
00253
00254
00255 ULI row_ind_pointer = 0;
00256 ULI index = 0;
00257 ULI row = 0;
00258 ULI column = c_ind->const_access( 0 );
00259
00260
00261 #ifdef _DEBUG
00262 std::cout << "nor = " << noc.unrecorded_access() << std::endl; std::cout << "noc = " << noc.unrecorded_access() << std::endl;
00263 #endif
00264
00265 while( index < nnz.unrecorded_access() ) {
00266 while( column < noc.unrecorded_access() ) {
00267 #ifdef _DEBUG
00268 std::cout << "ret[ " << row << " ] += nzs[ " << index << " ] * x[ " << column << " ], \t(" << c_ind->unrecorded_access( index + 1 ) << ")" << std::endl;
00269 #endif
00270 ret->access( row ) += nzs->const_access( index ) * x->const_access( column );
00271 ++index;
00272
00273 column += c_ind->const_access( index );
00274 }
00275
00276 if( index >= nnz.unrecorded_access() ) break;
00277
00278
00279
00280 row += r_ind->const_access( row_ind_pointer++ );
00281 #ifdef _DEBUG
00282 std::cout << column.unrecorded_access() << " > " << noc.unrecorded_access() << std::endl;
00283 #endif
00284 column -= noc.unrecorded_access();
00285 #ifdef _UNSIGNED
00286 while( column < noc.unrecorded_access() ) {
00287 #else
00288 while( column >= 0 ) {
00289 #endif
00290 #ifdef _DEBUG
00291 std::cout << "ret[ " << row << " ] += nzs[ " << index << " ] * x[ " << column << " ], \t(-" << c_ind->unrecorded_access( index ) << ")" << std::endl;
00292 #endif
00293 ret->access( row ) += nzs->const_access( index ) * x->const_access( column );
00294 ++index;
00295 #ifdef _UNSIGNED
00296 if( c_ind->const_access( index ) <= column )
00297 #endif
00298 column -= c_ind->const_access( index );
00299 #ifdef _UNSIGNED
00300 else {
00301 column = c_ind->const_access( index ) - noc.unrecorded_access();
00302 break;
00303 }
00304 }
00305 #else
00306 }
00307
00308 column += noc.unrecorded_access();
00309 #endif
00310 row += r_ind->const_access( row_ind_pointer++ );
00311 }
00312
00313 ret->unrecordedCopyTo( true_ret );
00314 delete ret;
00315 delete x;
00316 return true_ret;
00317 }
00318
00320 ~CS_ZZ_ICRS() {
00321 delete nzs;
00322 delete c_ind;
00323 delete r_ind;
00324 }
00325
00326 };
00327
00328 #endif
00329