00001 #include "Triplet.hpp"
00002 #include <vector>
00003 #include <algorithm>
00004 #include <assert.h>
00005
00006 #include "CS_ELEMENT.hpp"
00007 #include "CS_ARRAY.hpp"
00008
00009
00010
00011 #ifndef _H_CS_ICRS
00012 #define _H_CS_ICRS
00013
00014 #ifdef _DEBUG
00015 #include<iostream>
00016 #endif
00017
00021 template< typename T >
00022 class CS_ICRS {
00023
00024 private:
00025
00027 typedef unsigned long int ULI;
00028
00029 protected:
00030
00032 CS_ELEMENT< ULI > nnz;
00033
00035 CS_ELEMENT< ULI > nor;
00036
00038 CS_ELEMENT< ULI > noc;
00039
00041 CS_ARRAY< T >* nzs;
00042
00044 CS_ARRAY< ULI >* c_ind;
00045
00047 CS_ARRAY< ULI >* r_ind;
00048
00050 CS_ELEMENT< T > zero_element;
00051
00053 static int compareTriplets( const void * left, const void * right ) {
00054 const Triplet< T > one = *( (Triplet< T > *)left );
00055 const Triplet< T > two = *( (Triplet< T > *)right );
00056 if( one.i() < two.i() )
00057 return -1;
00058 if ( one.i() > two.i() )
00059 return 1;
00060 if ( one.j() < two.j() )
00061 return -1;
00062 if ( one.j() > two.j() )
00063 return 1;
00064 return 0;
00065 }
00066
00067 public:
00068
00078 CS_ICRS( const ULI number_of_nonzeros, const ULI number_of_rows, const ULI number_of_cols, const T zero ):
00079 nnz( number_of_nonzeros ), noc( number_of_cols ), nor( number_of_rows ), zero_element( zero ) {
00080 nzs = new CS_ARRAY< T>( nnz.const_access(), "Nonzeros array (ICRS)" );
00081 c_ind = new CS_ARRAY< ULI >( nnz.const_access(), "Array storing the column index differences (ICRS)" );
00082 r_ind = new CS_ARRAY< ULI >( nnz.const_access(), "Array storing the row index differences (ICRS)" );
00083 }
00084
00089 CS_ICRS( CS_ICRS< T >& toCopy ) {
00090 zero_element = toCopy.zero_element;
00091 nnz = toCopy.nnz;
00092 noc = toCopy.noc;
00093 nor = toCopy.nor;
00094 nzs = new CS_ARRAY< T >( nnz.const_access(), "Nonzeros array( CS_ICRS, copied )" );
00095 c_ind = new CS_ARRAY< ULI >( nnz.const_access(), "Array storing the column indices (CS_ICRS, copied)" );
00096 r_ind = new CS_ARRAY< ULI >( nnz.const_access(), "Array storing the row index indices (CS_ICRS, copied)" );
00097 for( CS_ELEMENT< ULI > i=0; i<nnz; i = i + 1 ) {
00098 nzs->access( i.const_access() ) = toCopy.nzs->const_access( i.const_access() );
00099 c_ind->access( i.const_access() ) = toCopy.c_ind->const_access( i.const_access() );
00100 r_ind->access( i.const_access() ) = toCopy.r_ind->const_access( i.const_access() );
00101 }
00102 }
00103
00114 CS_ICRS( std::vector< Triplet< T > >& input, const ULI m, const ULI n, T& zero ) {
00115 zero_element = zero;
00116
00117 nnz = input.size();
00118
00119 nor = m;
00120 noc = n;
00121
00122 typename std::vector< Triplet< T > >::iterator in_it;
00123
00124
00125
00126
00127
00128
00129
00130 qsort( &input[ 0 ], input.size(), sizeof( Triplet< T > ), &compareTriplets );
00131
00132
00133 ULI prev_row = 0;
00134 std::vector< ULI > r_ind_temp;
00135 typename std::vector< Triplet< T > >::iterator it = input.begin();
00136 for( ; it!=input.end(); it++ ) {
00137 if( (*it).i() > prev_row ) { r_ind_temp.push_back( (*it).i() - prev_row ); prev_row = (*it).i(); }
00138 }
00139 nnz = input.size();
00140
00141
00142 nzs = new CS_ARRAY< T >( nnz.unrecorded_access(), "Array of nonzeros (CS_ICRS)" );
00143 c_ind = new CS_ARRAY< ULI >( nnz.unrecorded_access() + 1, "Array of column index indices (CS_ICRS)" );
00144 r_ind = new CS_ARRAY< ULI >( r_ind_temp.size() + 1, "Array of row index indices (CS_ICRS)" );
00145
00146
00147 c_ind->unrecorded_access( nnz.unrecorded_access() ) = noc.unrecorded_access();
00148
00149
00150
00151 for( ULI i=0; i<r_ind_temp.size(); i++ )
00152 r_ind->unrecorded_access( i ) = r_ind_temp[ i ];
00153
00154
00155 ULI prev_col = 0;
00156 prev_row = 0;
00157
00158 for( ULI i=0; i<nnz.unrecorded_access(); ++i ) {
00159 const Triplet< T > cur = input[ i ];
00160 const ULI currow = cur.i();
00161 const ULI curcol = cur.j();
00162 if( currow == prev_row ) {
00163 c_ind->unrecorded_access( i ) = curcol - prev_col;
00164 } else {
00165 c_ind->unrecorded_access( i ) = noc.unrecorded_access() + ( curcol - prev_col );
00166 prev_row = currow;
00167 }
00168 nzs->unrecorded_access( i ) = cur.value;
00169 prev_col = curcol;
00170
00171 #ifdef _DEBUG
00172 std::cout << currow << "," << curcol << "(" << cur.value << ") maps to " << c_ind[ i ] << std::endl;
00173 #endif
00174 }
00175 }
00176
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00251
00252
00253
00262 T* zax( T* x_orig ) {
00263
00264 CS_ARRAY< T >* x = new CS_ARRAY< T >( noc.unrecorded_access(), "x-vector in CS_ICRS::zax" );
00265 x->unrecordedCopyFrom( x_orig );
00266
00267 T* true_ret = new T[ nor.unrecorded_access() ];
00268 CS_ARRAY< T >* ret = new CS_ARRAY< T >( nor.unrecorded_access(), "z-vector in CS_ICRS::zax" );
00269
00270 for( ULI i=0; i < nor.unrecorded_access(); ++i )
00271 ret->access( i ) = zero_element.unrecorded_access();
00272
00273 ULI row_ind_pointer = 0;
00274 ULI index = 0;
00275 ULI row = 0;
00276 ULI column = c_ind->const_access( 0 );
00277
00278 while( index < nnz.unrecorded_access() ) {
00279 while( column < noc.unrecorded_access() ) {
00280 ret->access( row ) += nzs->const_access( index ) * x->const_access( column );
00281 index += 1;
00282 column += c_ind->const_access( index );
00283 }
00284 row += r_ind->const_access( row_ind_pointer );
00285 row_ind_pointer++;
00286 column -= noc.unrecorded_access();
00287 }
00288
00289 ret->unrecordedCopyTo( true_ret );
00290 delete ret;
00291 delete x;
00292 return true_ret;
00293 }
00294
00306 T* zaxtrace( T* x_orig ) {
00307
00308 CS_ARRAY< T >* x = new CS_ARRAY< T >( noc.unrecorded_access(), "x-vector in CS_ICRS::zax" );
00309 x->unrecordedCopyFrom( x_orig );
00310
00311 T* true_ret = new T[ nor.unrecorded_access() ];
00312 CS_ARRAY< T >* ret = new CS_ARRAY< T >( nor.unrecorded_access(), "z-vector in CS_ICRS::zax" );
00313
00314 for( ULI i=0; i < nor.unrecorded_access(); ++i )
00315 ret->access( i ) = zero_element.unrecorded_access();
00316
00317 ULI row_ind_pointer = 0;
00318 ULI index = 0;
00319 ULI row = 0;
00320 ULI column = c_ind->const_access( 0 );
00321
00322 while( index < nnz.unrecorded_access() ) {
00323 while( column < noc.unrecorded_access() ) {
00324 std::cout << "TRACE:"<<row<<","<<column<<std::endl;
00325 ret->access( row ) += nzs->const_access( index ) * x->const_access( column );
00326 index += 1;
00327 column += c_ind->const_access( index );
00328 }
00329 row += r_ind->const_access( row_ind_pointer );
00330 row_ind_pointer++;
00331 column -= noc.unrecorded_access();
00332 }
00333
00334 ret->unrecordedCopyTo( true_ret );
00335 delete ret;
00336 delete x;
00337 return true_ret;
00338 }
00339
00341 ~CS_ICRS() {
00342 delete nzs;
00343 delete c_ind;
00344 delete r_ind;
00345 }
00346
00347 };
00348
00349 #endif
00350