#include #include #include #include #include #include #include #include "STIdxIter.h" namespace asap { IndexIterator::IndexIterator( vector< vector > &idxlist ) : idxlist_m( idxlist ), niter_m( 0 ) { nfield_m = idxlist_m.size() ; // cout << "nfield_m=" << nfield_m << endl ; Block nidx( nfield_m ) ; prod_m = Block( nfield_m, 1 ) ; idx_m = Block( nfield_m, 0 ) ; current_m = Vector( nfield_m ) ; // cout << "idx_m.size()=" << idx_m.size() << endl ; for ( uInt i = 0 ; i < nfield_m ; i++ ) { // cout << "idx_m[" << i << "]=" << idx_m[i] << endl ; nidx[i] = idxlist_m[i].size() ; current_m[i] = idxlist_m[i][idx_m[i]] ; } for ( uInt i = 1 ; i < nfield_m ; i++ ) { prod_m[i] = nidx[i-1] * prod_m[i-1] ; } maxiter_m =prod_m[nfield_m-1] * nidx[nfield_m-1] ; // cout << "maxiter_m=" << maxiter_m << endl ; } Vector IndexIterator::current() { uInt *v = current_m.data() ; uInt *p = idx_m.storage() ; for ( uInt i = 0 ; i < nfield_m ; i++ ) { *v = idxlist_m[i][*p] ; v++ ; p++ ; } return current_m ; } Bool IndexIterator::pastEnd() { return niter_m >= maxiter_m ; } void IndexIterator::next() { niter_m++ ; uInt x = niter_m ; for ( Int i = nfield_m-1 ; i >= 0 ; i-- ) { idx_m[i] = x / prod_m[i] ; //cout << "i=" << i << ": prod=" << prod_m[i] // << ", idx=" << idx_m[i] << endl ; x %= prod_m[i] ; } } ArrayIndexIterator::ArrayIndexIterator( Matrix &arr, vector< vector > idlist ) : arr_m( arr )//, // pos_m( IPosition(1,0) ) { ncol_m = arr_m.ncolumn() ; nrow_m = arr_m.nrow() ; //storage_m.resize( nrow_m ) ; vector< vector > l = idlist ; if ( l.size() != ncol_m ) { l.resize( ncol_m ) ; for ( uInt i = 0 ; i < ncol_m ; i++ ) { Vector a( arr_m.column( i ).copy() ) ; uInt n = genSort( a, Sort::Ascending, Sort::QuickSort|Sort::NoDuplicates ) ; a.resize(n,True) ; a.tovector( l[i] ) ; } } iter_m = new IndexIterator( l ) ; } ArrayIndexIterator::~ArrayIndexIterator() { delete iter_m ; } Vector ArrayIndexIterator::current() { return iter_m->current() ; } Bool ArrayIndexIterator::pastEnd() { return iter_m->pastEnd() ; } // void ArrayIndexIterator::next() // { // iter_m->next() ; // } ArrayIndexIteratorNormal::ArrayIndexIteratorNormal( Matrix &arr, vector< vector > idlist ) : ArrayIndexIterator( arr, idlist ), pos_m( IPosition( 1, 0 ) ) { storage_m.resize( nrow_m ) ; } void ArrayIndexIteratorNormal::next() { iter_m->next() ; } Vector ArrayIndexIteratorNormal::getRows() { Vector v = current() ; uInt len = 0 ; uInt *p = storage_m.storage() ; for ( uInt i = 0 ; i < nrow_m ; i++ ) { if ( allEQ( v, arr_m.row( i ) ) ) { *p = i ; len++ ; p++ ; } } pos_m[0] = len ; p = storage_m.storage() ; return Vector( pos_m, p ) ; } ArrayIndexIteratorAcc::ArrayIndexIteratorAcc( Matrix &arr, vector< vector > idlist ) : ArrayIndexIterator( arr, idlist ), pos_m( IPosition(1) ) { storage_m.resize( arr_m.nelements()+nrow_m ) ; for ( uInt i = 0 ; i < nrow_m ; i++ ) { storage_m[i+arr_m.nelements()] = i ; } len_m.resize( ncol_m+1 ) ; for ( uInt i = 0 ; i < ncol_m+1 ; i++ ) { len_m[i] = nrow_m ; // cout << "len[" << i << "]=" << len_m[i] << endl ; } prev_m = current() - (uInt)1 ; // test // cout << "row 21, col 2 " << arr_m( 21, 2 ) << endl ; } void ArrayIndexIteratorAcc::next() { prev_m = current() ; iter_m->next() ; } Vector ArrayIndexIteratorAcc::getRows() { Vector v = current() ; Int c = isChanged( v ) ; // cout << "c=" << c << endl ; if ( c < 0 ) { pos_m[0] = len_m[0] ; return Vector( pos_m, storage_m.storage() ) ; } uInt *base = storage_m.storage() + (c+1) * nrow_m ; // cout << "len_m[c+1]=" << len_m[c+1] << endl ; // cout << "base=" << Vector(IPosition(1,len_m[c+1]),base,SHARE) << endl ; for ( Int i = c ; i >= 0 ; i-- ) { base = updateStorage( i, base, v[i] ) ; // cout << "len_m[" << i << "]=" << len_m[i] << endl ; // cout << "base=" << Vector(IPosition(1,len_m[i]),base,SHARE) << endl ; } pos_m[0] = len_m[0] ; return Vector( pos_m, storage_m.storage() ) ; } Int ArrayIndexIteratorAcc::isChanged( Vector &idx ) { Int i = ncol_m - 1 ; while( i >= 0 && idx[i] == prev_m[i] ) i-- ; return i ; } uInt *ArrayIndexIteratorAcc::updateStorage( Int &icol, uInt *base, uInt &v ) { uInt len = 0 ; uInt *p = base - nrow_m ; uInt *work = p ; for ( uInt i = 0 ; i < len_m[icol+1] ; i++ ) { if ( arr_m( *base, icol ) == v ) { // cout << "add " << *base << endl ; *work = *base ; len++ ; work++ ; } base++ ; } len_m[icol] = len ; return p ; } STIdxIter::STIdxIter() { iter_m = 0 ; } STIdxIter::STIdxIter( const string &name, const vector &cols ) { } STIdxIter::STIdxIter( const CountedPtr &s, const vector &cols ) { } STIdxIter::~STIdxIter() { if ( iter_m != 0 ) delete iter_m ; } vector STIdxIter::tovector( Vector v ) { vector ret ; v.tovector( ret ) ; return ret ; } STIdxIterNormal::STIdxIterNormal() : STIdxIter() { } STIdxIterNormal::STIdxIterNormal( const string &name, const vector &cols ) : STIdxIter( name, cols ) { Table t( name, Table::Old ) ; init( t, cols ) ; } STIdxIterNormal::STIdxIterNormal( const CountedPtr &s, const vector &cols ) : STIdxIter( s, cols ) { init( s->table(), cols ) ; } STIdxIterNormal::~STIdxIterNormal() { } void STIdxIterNormal::init( Table &t, const vector &cols ) { uInt ncol = cols.size() ; uInt nrow = t.nrow() ; Matrix arr( nrow, ncol ) ; ROScalarColumn col ; for ( uInt i = 0 ; i < ncol ; i++ ) { col.attach( t, cols[i] ) ; Vector v( arr.column( i ) ) ; col.getColumn( v ) ; } iter_m = new ArrayIndexIteratorNormal( arr ) ; } STIdxIterAcc::STIdxIterAcc() : STIdxIter() { } STIdxIterAcc::STIdxIterAcc( const string &name, const vector &cols ) : STIdxIter( name, cols ) { Table t( name, Table::Old ) ; init( t, cols ) ; } STIdxIterAcc::STIdxIterAcc( const CountedPtr &s, const vector &cols ) : STIdxIter( s, cols ) { init( s->table(), cols ) ; } STIdxIterAcc::~STIdxIterAcc() { } void STIdxIterAcc::init( Table &t, const vector &cols ) { uInt ncol = cols.size() ; uInt nrow = t.nrow() ; Matrix arr( nrow, ncol ) ; ROScalarColumn col ; for ( uInt i = 0 ; i < ncol ; i++ ) { col.attach( t, cols[i] ) ; Vector v( arr.column( i ) ) ; col.getColumn( v ) ; } iter_m = new ArrayIndexIteratorAcc( arr ) ; } } // namespace