void CompCol_ICPreconditioner :: ICSolve(FloatArray &dest) const { int i, t, M = dest.giveSize(); FloatArray work(M); double val; // lower diag work.zero(); // solve Uw=x for ( i = 0; i < M; i++ ) { work(i) = val = ( dest(i) + work(i) ) / val_( pntr_(i) ); for ( t = pntr_(i) + 1; t < pntr_(i + 1); t++ ) { work( indx_(t) ) -= val_(t) * val; } } dest.zero(); // solve U^Ty=w for ( i = M - 1; i >= 0; i-- ) { for ( t = pntr_(i) + 1; t < pntr_(i + 1); t++ ) { dest(i) -= val_(t) * dest( indx_(t) ); } dest(i) = ( work(i) + dest(i) ) / val_( pntr_(i) ); } }
void SymCompCol :: times(const FloatArray &x, FloatArray &answer) const { int M = dim_ [ 0 ]; int N = dim_ [ 1 ]; // Check for compatible dimensions: if ( x.giveSize() != N ) { OOFEM_ERROR("SymCompCol::times: Error in CompCol -- incompatible dimensions"); } answer.resize(M); answer.zero(); int j, t; double rhs, sum; for ( j = 0; j < N; j++ ) { rhs = x(j); sum = 0.0; for ( t = colptr_(j) + 1; t < colptr_(j + 1); t++ ) { answer( rowind_(t) ) += val_(t) * rhs; // column loop sum += val_(t) * x( rowind_(t) ); // row loop } answer(j) += sum; answer(j) += val_( colptr_(j) ) * rhs; // diagonal } }
void luaStore_writeValue(TValue * v, file& f, std::vector<void *>& functions) { uint i; bool found; byte type = ttype(v); f.write(type); switch(type) { case LUA_TNIL: // nil has no data break; case LUA_TBOOLEAN: f.write((byte)val_(v).b); break; case LUA_TLIGHTUSERDATA: // write the pointer f.write(&val_(v).p, sizeof(void*)); break; case LUA_TNUMBER: f.write(num_(v)); break; case LUA_TSTRING: // write the pointer to gc objects case LUA_TTABLE: case LUA_TUSERDATA: case LUA_TTHREAD: // all gc objects will be flushed to disk later f.write(&val_(v).gc, sizeof(void*)); break; case LUA_TLCL: f.write(&val_(v).gc, sizeof(void*)); // this variant is a gc object break; case LUA_TLCF: // c-function // look up the function in the bindings list found = false; for(i = 0;i < functions.size();i++) { if(functions[i] == val_(v).f) { // write the index as a short f.write((ushort)i); found = true; break; } } if(!found) dbgError("unknown light function"); break; default: dbgError("unknown object type %i", type); break; } }
void CompCol_ICPreconditioner :: ICFactor() { int d, g, h, i, j, k, n = pntr_.giveSize() - 1; double z; for ( k = 0; k < n - 1; k++ ) { d = pntr_(k); z = val_(d) = sqrt( val_(d) ); for ( i = d + 1; i < pntr_(k + 1); i++ ) { val_(i) /= z; } for ( i = d + 1; i < pntr_(k + 1); i++ ) { z = val_(i); h = indx_(i); g = i; for ( j = pntr_(h); j < pntr_(h + 1); j++ ) { for ( ; g < pntr_(k + 1) && indx_(g + 1) <= indx_(j); g++ ) { if ( indx_(g) == indx_(j) ) { val_(j) -= z * val_(g); } } } } } d = pntr_(n - 1); val_(d) = sqrt( val_(d) ); }
double &CompCol :: operator() (int i, int j) { // increment version this->version++; for ( int t = colptr_(j); t < colptr_(j + 1); t++ ) { if ( rowind_(t) == i ) { return val_(t); } } OOFEM_ERROR("Array element (%d,%d) not in sparse structure -- cannot assign", i, j); return val_(0); // return to suppress compiler warning message }
double &CompCol :: at(int i, int j) { // increment version this->version++; for ( int t = colptr_(j - 1); t < colptr_(j); t++ ) { if ( rowind_(t) == i - 1 ) { return val_(t); } } OOFEM_ERROR("Array accessing exception -- (%d,%d) out of bounds", i, j); return val_(0); // return to suppress compiler warning message }
void SymCompCol :: zero() { for ( int t = 0; t < nz_; t++ ) { val_(t) = 0.0; } // increment version this->version++; }
void SymCompCol :: times(double x) { for ( int t = 0; t < nz_; t++ ) { val_(t) *= x; } // increment version this->version++; }
double &SymCompCol :: at(int i, int j) { int ii = i, jj = j; if ( ii < jj ) { ii = j; jj = i; } // increment version this->version++; for ( int t = colptr_(jj - 1); t < colptr_(jj); t++ ) { if ( rowind_(t) == ( ii - 1 ) ) { return val_(t); } } OOFEM_ERROR("SymCompCol::operator(): Array accessing exception -- out of bounds"); return val_(0); // return to suppress compiler warning message }
template< PSTADE_APPLE_ATL_CSIMPLEARRAY_TEMPLATE_PARAMS, class Value > inline void pstade_garlic_push_back( ATL::CSimpleArray< PSTADE_APPLE_ATL_CSIMPLEARRAY_TEMPLATE_ARGS >& arr, Value const& val, pstade::overload<>) { #if !defined(PSTADE_APPLE_ATL_HAS_OLD_CSIMPLEARRAY) arr.Add(val); #else Value val_(val); arr.Add(val_); #endif }
double CompCol :: operator() (int i, int j) const { for ( int t = colptr_(j); t < colptr_(j + 1); t++ ) { if ( rowind_(t) == i ) { return val_(t); } } if ( i < dim_ [ 0 ] && j < dim_ [ 1 ] ) { return 0.0; } else { OOFEM_ERROR("Array accessing exception -- (%d,%d) out of bounds", i, j); return ( 0 ); // return to suppress compiler warning message } }
void CompCol_ICPreconditioner :: initialize(const CompCol &A) { dim_ [ 0 ] = A.dim(0); dim_ [ 1 ] = A.dim(1); pntr_.resize(A.dim(1) + 1); int i, j, k; nz_ = 0; for ( k = 0; k < dim_ [ 1 ]; k++ ) { for ( j = A.col_ptr(k); j < A.col_ptr(k + 1); j++ ) { if ( A.row_ind(j) >= k ) { nz_++; } } } val_.resize(nz_); indx_.resize(nz_); // Copy just triangular part pntr_(0) = 0; for ( k = 0; k < dim_ [ 1 ]; k++ ) { pntr_(k + 1) = pntr_(k); for ( j = A.col_ptr(k); j < A.col_ptr(k + 1); j++ ) { if ( A.row_ind(j) >= k ) { i = pntr_(k + 1)++; val_(i) = A.val(j); indx_(i) = A.row_ind(j); } } } // for (i = 0; i < dim_[1]; i++) // qsortRow(indx_, val_, pntr_(i), pntr_(i+1) -1); for ( i = 0; i < dim_ [ 1 ]; i++ ) { if ( indx_( pntr_(i) ) != i ) { OOFEM_ERROR("diagonal not found!"); } } this->ICFactor(); }
double SymCompCol :: operator() (int i, int j) const { int ii = i, jj = j; if ( ii < jj ) { ii = j; jj = i; } for ( int t = colptr_(jj); t < colptr_(jj + 1); t++ ) { if ( rowind_(t) == ii ) { return val_(t); } } if ( i < dim_ [ 0 ] && j < dim_ [ 1 ] ) { return 0.0; } else { OOFEM_ERROR3("SymCompCol::operator(): Array accessing exception, index out of bounds (%d,%d)", i, j); return ( 0 ); // return to suppress compiler warning message } }
ICPreconditioner_double::ICPreconditioner_double(const CompRow_Mat_double &A) : val_(0), pntr_(A.dim(0)+1), indx_(0), nz_(0) { dim_[0] = A.dim(0); dim_[1] = A.dim(1); int i, j, k; for (k = 0; k < dim_[0]; k++) for (j = A.row_ptr(k); j < A.row_ptr(k+1); j++) if (A.col_ind(j) >= k) nz_++; val_.newsize(nz_); indx_.newsize(nz_); // Copy just triangular part (including diagonal) pntr_(0) = 0; for (k = 0; k < dim_[0]; k++) { pntr_(k+1) = pntr_(k); for (j = A.row_ptr(k); j < A.row_ptr(k+1); j++) { if (A.col_ind(j) >= k) { i = pntr_(k+1)++; val_(i) = A.val(j); indx_(i) = A.col_ind(j); } } } for (i = 0; i < dim_[0]; i++) QSort(indx_, val_, pntr_[i], pntr_[i+1] - pntr_[i]); for (i = 0; i < dim_[0]; i++) if (indx_[pntr_(i)] != i) { std::cerr << "IC Preconditioner: diagonal not found!" << i << "\n"; exit(1); } ICFactor(pntr_, indx_, val_); }
void CompCol :: times(const FloatArray &x, FloatArray &answer) const { int M = dim_ [ 0 ]; int N = dim_ [ 1 ]; // Check for compatible dimensions: if ( x.giveSize() != N ) { OOFEM_ERROR("incompatible dimensions"); } answer.resize(M); answer.zero(); int j, t; double rhs; for ( j = 0; j < N; j++ ) { rhs = x(j); for ( t = colptr_(j); t < colptr_(j + 1); t++ ) { answer( rowind_(t) ) += val_(t) * rhs; } } }
void CompCol :: timesT(const FloatArray &x, FloatArray &answer) const { int M = dim_ [ 0 ]; int N = dim_ [ 1 ]; // Check for compatible dimensions: if ( x.giveSize() != M ) { OOFEM_ERROR("Error in CompCol -- incompatible dimensions"); } answer.resize(N); answer.zero(); int i, t; double r; for ( i = 0; i < N; i++ ) { r = 0.0; for ( t = colptr_(i); t < colptr_(i + 1); t++ ) { r += val_(t) * x( rowind_(t) ); } answer(i) = r; } }