unsigned find_sort_syntax(const traits* pt, charT* delim) { // // compare 'a' with 'A' to see how similar they are, // should really use a-accute but we can't portably do that, // typedef typename traits::string_type string_type; typedef typename traits::char_type char_type; // Suppress incorrect warning for MSVC (void)pt; char_type a[2] = {'a', '\0', }; string_type sa(pt->transform(a, a+1)); if(sa == a) { *delim = 0; return sort_C; } char_type A[2] = { 'A', '\0', }; string_type sA(pt->transform(A, A+1)); char_type c[2] = { ';', '\0', }; string_type sc(pt->transform(c, c+1)); int pos = 0; while((pos <= static_cast<int>(sa.size())) && (pos <= static_cast<int>(sA.size())) && (sa[pos] == sA[pos])) ++pos; --pos; if(pos < 0) { *delim = 0; return sort_unknown; } // // at this point sa[pos] is either the end of a fixed width field // or the character that acts as a delimiter: // charT maybe_delim = sa[pos]; if((pos != 0) && (count_chars(sa, maybe_delim) == count_chars(sA, maybe_delim)) && (count_chars(sa, maybe_delim) == count_chars(sc, maybe_delim))) { *delim = maybe_delim; return sort_delim; } // // OK doen't look like a delimiter, try for fixed width field: // if((sa.size() == sA.size()) && (sa.size() == sc.size())) { // note assumes that the fixed width field is less than // (numeric_limits<charT>::max)(), should be true for all types // I can't imagine 127 character fields... *delim = static_cast<charT>(++pos); return sort_fixed; } // // don't know what it is: // *delim = 0; return sort_unknown; }
//__________________________________________________________________________________ void CompileListOfUserExpressions (_SimpleList& varRefs,_List& rec, bool doAll) { rec.Clear(); if (varRefs.lLength == 0) { return; } long i; _SimpleList startVars; _VariableContainer* firstVar = (_VariableContainer*)LocateVar(varRefs.lData[0]); firstVar->ScanAndAttachVariables(); { _AVLList sA (&startVars); if (doAll) { firstVar->ScanForVariables (sA,sA); firstVar->ScanForGVariables (sA,sA); } firstVar->ScanForDVariables (sA,sA); sA.ReorderList (); } if (!doAll) { for (i=startVars.lLength-1; i>=0; i--) { if (firstVar->IsModelVar(i)) { startVars.Delete(i); } } } for (i=0; i<startVars.lLength; i++) { _String thisName (LocateVar(startVars.lData[i])->GetName()->Cut (LocateVar(startVars.lData[i])->GetName()->FindBackwards('.',0,-1),-1)); rec && &thisName; } for (i=varRefs.lLength-1; i>=1; i--) { firstVar = (_VariableContainer*)LocateVar(varRefs.lData[i]); firstVar->ScanAndAttachVariables(); firstVar->MatchParametersToList (rec,doAll); } for (i=rec.lLength-1; i>=0; i--) { _String* thisLine = ((_String*)rec(i)); thisLine->Trim(1,-1); if (doAll) if (LocateVarByName(*thisLine)<0) { *thisLine = _String('!')&*thisLine; } } }
void collisionTester::initAlgo(){ btCollisionObjectWrapper sA(0,sphereA.getCollisionShape(), &sphereA, sphereA.getWorldTransform()); btCollisionObjectWrapper sB(0,sphereB.getCollisionShape(), &sphereB, sphereB.getWorldTransform()); btCollisionObjectWrapper cA(0,cylinderA.getCollisionShape(), &cylinderA, sphereA.getWorldTransform()); btCollisionObjectWrapper cB(0,cylinderB.getCollisionShape(), &cylinderB, sphereB.getWorldTransform()); algoSS = collisionWorld->getDispatcher()->findAlgorithm(&sA, &sB); algoSC = collisionWorld->getDispatcher()->findAlgorithm(&sA, &cA); algoCC = collisionWorld->getDispatcher()->findAlgorithm(&cA, &cB); }
/** * This method should be used both as a solution to 3D cases, and as a general termination method for algorithms that reduce D-dimensional problem to 3-dimensional one. * * This is the implementation of the algorithm for computing hypervolume as it was presented by Nicola Beume et al. * The implementation uses std::multiset (which is based on red-black tree data structure) as a container for the sweeping front. * Original implementation by Beume et. al uses AVL-tree. * The difference is insiginificant as the important characteristics (maintaining order when traversing, self-balancing) of both structures and the asymptotic times (O(log n) updates) are guaranteed. * Computational complexity: O(n*log(n)) * * @param[in] points vector of points containing the 3-dimensional points for which we compute the hypervolume * @param[in] r_point reference point for the points * * @return hypervolume. */ double hv3d::compute(std::vector<fitness_vector> &points, const fitness_vector &r_point) const { if (m_initial_sorting) { sort(points.begin(), points.end(), fitness_vector_cmp(2,'<')); } double V = 0.0; // hypervolume double A = 0.0; // area of the sweeping plane std::multiset<fitness_vector, fitness_vector_cmp> T(fitness_vector_cmp(0, '>')); // sentinel points (r_point[0], -INF, r_point[2]) and (-INF, r_point[1], r_point[2]) const double INF = std::numeric_limits<double>::max(); fitness_vector sA(r_point.begin(), r_point.end()); sA[1] = -INF; fitness_vector sB(r_point.begin(), r_point.end()); sB[0] = -INF; T.insert(sA); T.insert(sB); double z3 = points[0][2]; T.insert(points[0]); A = fabs((points[0][0] - r_point[0]) * (points[0][1] - r_point[1])); std::multiset<fitness_vector>::iterator p; std::multiset<fitness_vector>::iterator q; for(std::vector<fitness_vector>::size_type idx = 1 ; idx < points.size() ; ++idx) { p = T.insert(points[idx]); q = (p); ++q; //setup q to be a successor of p if ( (*q)[1] <= (*p)[1] ) { // current point is dominated T.erase(p); // disregard the point from further calculation } else { V += A * fabs(z3 - (*p)[2]); z3 = (*p)[2]; std::multiset<fitness_vector>::reverse_iterator rev_it(q); ++rev_it; std::multiset<fitness_vector>::reverse_iterator erase_begin (rev_it); std::multiset<fitness_vector>::reverse_iterator rev_it_pred; while((*rev_it)[1] >= (*p)[1] ) { rev_it_pred = rev_it; ++rev_it_pred; A -= fabs(((*rev_it)[0] - (*rev_it_pred)[0])*((*rev_it)[1] - (*q)[1])); ++rev_it; } A += fabs(((*p)[0] - (*(rev_it))[0])*((*p)[1] - (*q)[1])); T.erase(rev_it.base(),erase_begin.base()); } } V += A * fabs(z3 - r_point[2]); return V; }
int CALLBACK CLiveList::SortCallback(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { CListCtrl* pList = (CListCtrl*)lParamSort; ASSERT_VALID( pList ); int nColumn = (int)GetWindowLongPtr( pList->GetSafeHwnd(), GWLP_USERDATA ); LV_FINDINFO pFind; pFind.flags = LVFI_PARAM; pFind.lParam = lParam1; int nA = pList->FindItem( &pFind ); pFind.lParam = lParam2; int nB = pList->FindItem( &pFind ); CString sA( pList->GetItemText( nA, abs( nColumn ) - 1 ) ); CString sB( pList->GetItemText( nB, abs( nColumn ) - 1 ) ); return ( nColumn > 0 ) ? SortProc( sB, sA ) : SortProc( sA, sB ); }
void loop() { lBreak(); sM(); sE(); sR(); sR(); sY(); wBreak(); sC(); sH(); sR(); sI(); sS(); sT(); sM(); sA(); sS(); lBreak(); }
int main( int argc, char *argv[] ) { Scope global; Server s( "archiveopteryx", argc, argv ); s.setup( Server::Report ); bool security( Configuration::toggle( Configuration::Security ) ); EString root( Configuration::text( Configuration::JailDir ) ); if ( Configuration::toggle( Configuration::UseSmtp ) || Configuration::toggle( Configuration::UseLmtp ) ) { EString mc( Configuration::text( Configuration::MessageCopy ) ); EString mcd( Configuration::text( Configuration::MessageCopyDir ) ); if ( mc == "all" || mc == "errors" || mc == "delivered" ) { struct stat st; if ( mcd.isEmpty() ) log( "message-copy-directory not set", Log::Disaster ); else if ( ::stat( mcd.cstr(), &st ) < 0 || !S_ISDIR( st.st_mode ) ) log( "Inaccessible message-copy-directory: " + mcd, Log::Disaster ); else if ( security && !mcd.startsWith( root ) ) log( "message-copy-directory must be under jail directory " + root, Log::Disaster ); } else if ( mc == "none" ) { if ( Configuration::present( Configuration::MessageCopyDir ) ) log( "Disregarding message-copy-directory (value " + mcd + ") because message-copy is set to none " ); } else { log( "Invalid value for message-copy: " + mc, Log::Disaster ); } } EString sA( Configuration::text( Configuration::SmartHostAddress ) ); uint sP( Configuration::scalar( Configuration::SmartHostPort ) ); if ( Configuration::toggle( Configuration::UseSmtp ) && Configuration::scalar( Configuration::SmtpPort ) == sP && ( Configuration::text( Configuration::SmtpAddress ) == sA || ( Configuration::text( Configuration::SmtpAddress ) == "" && sA == "127.0.0.1" ) ) ) { log( "smarthost-address/port are the same as smtp-address/port", Log::Disaster ); } if ( Configuration::toggle( Configuration::UseLmtp ) && Configuration::scalar( Configuration::LmtpPort ) == sP && ( Configuration::text( Configuration::LmtpAddress ) == sA || ( Configuration::text( Configuration::LmtpAddress ) == "" && sA == "127.0.0.1" ) ) ) { log( "smarthost-address/port are the same as lmtp-address/port", Log::Disaster ); } if ( Configuration::toggle( Configuration::UseSmtpSubmit ) && Configuration::scalar( Configuration::SmtpSubmitPort ) == sP && ( Configuration::text( Configuration::SmtpSubmitAddress ) == sA || ( Configuration::text( Configuration::SmtpSubmitAddress ) == "" && sA == "127.0.0.1" ) ) ) { log( "smarthost-address/port are the same as " "smtp-submit-address/port", Log::Disaster ); } EString app = Configuration::text( Configuration::AllowPlaintextPasswords ).lower(); if ( !( app == "always" || app == "never" ) ) ::log( "Unknown value for allow-plaintext-passwords: " + app, Log::Disaster ); if ( app == "never" && Configuration::toggle( Configuration::UseTls ) == false && Configuration::toggle( Configuration::AuthCramMd5 ) == false && Configuration::toggle( Configuration::AuthDigestMd5 ) == false ) ::log( "allow-plaintext-passwords is 'never' and use-tls is 'false', " "but only plaintext authentication mechanisms are allowed", Log::Disaster ); EString apa = Configuration::text( Configuration::AllowPlaintextAccess ).lower(); if ( !( apa == "always" || apa == "localhost" || apa == "never" ) ) ::log( "Unknown value for allow-plaintext-access: " + apa, Log::Disaster ); if ( apa == "never" && Configuration::toggle( Configuration::UseTls ) == false ) ::log( "allow-plaintext-access is 'never', but use-tls is 'false'", Log::Disaster ); // set up an EGD server for openssl Entropy::setup(); EString egd( root ); if ( !egd.endsWith( "/" ) ) egd.append( "/" ); egd.append( "var/run/egd-pool" ); (void)new Listener< EntropyProvider >( Endpoint( egd, 0 ), "EGD" ); if ( !security ) { struct stat st; if ( stat( "/var/run/edg-pool", &st ) < 0 ) { log( "Security is disabled and /var/run/edg-pool does not exist. " "Creating it just in case openssl wants to access it." ); (void)new Listener< EntropyProvider >( Endpoint( "/var/run/edg-pool", 0 ), "EGD(/)" ); } } if ( ::chmod( egd.cstr(), 0666 ) < 0 ) log( "Could not grant r/w access to EGD socket", Log::Disaster ); Listener< IMAP >::create( "IMAP", Configuration::toggle( Configuration::UseImap ), Configuration::ImapAddress, Configuration::ImapPort ); Listener< IMAPS >::create( "IMAPS", Configuration::toggle( Configuration::UseImaps ), Configuration::ImapsAddress, Configuration::ImapsPort ); Listener< POP >::create( "POP3", Configuration::toggle( Configuration::UsePop ), Configuration::PopAddress, Configuration::PopPort ); Listener< POPS >::create( "POP3S", Configuration::toggle( Configuration::UsePops ), Configuration::PopsAddress, Configuration::PopsPort ); Listener< ManageSieve >::create( "Sieve", Configuration::toggle( Configuration::UseSieve ), Configuration::ManageSieveAddress, Configuration::ManageSievePort ); Listener< SMTP >::create( "SMTP", Configuration::toggle( Configuration::UseSmtp ), Configuration::SmtpAddress, Configuration::SmtpPort ); Listener< LMTP >::create( "LMTP", Configuration::toggle( Configuration::UseLmtp ), Configuration::LmtpAddress, Configuration::LmtpPort ); Listener< SMTPSubmit >::create( "SMTP-Submit", Configuration::toggle( Configuration::UseSmtpSubmit ), Configuration::SmtpSubmitAddress, Configuration::SmtpSubmitPort ); Listener< SMTPS >::create( "SMTPS", Configuration::toggle( Configuration::UseSmtps ), Configuration::SmtpsAddress, Configuration::SmtpsPort ); if ( Configuration::toggle( Configuration::UseTls ) ) { TlsThread::setup(); } s.setup( Server::LogStartup ); Listener< GraphDumper >::create( "Statistics", Configuration::toggle( Configuration::UseStatistics ), Configuration::StatisticsAddress, Configuration::StatisticsPort ); EventLoop::global()->setMemoryUsage( 1024 * 1024 * Configuration::scalar( Configuration::MemoryLimit ) ); Database::setup(); s.setup( Server::Finish ); StartupWatcher * w = new StartupWatcher; Database::checkSchema( w ); if ( security ) Database::checkAccess( w ); EventLoop::global()->setStartup( true ); Mailbox::setup( w ); SpoolManager::setup(); Selector::setup(); Flag::setup(); IMAP::setup(); if ( !security ) (void)new ConnectionObliterator; s.run(); }
Foam::solverPerformance Foam::PBiCGStab::solve ( scalarField& psi, const scalarField& source, const direction cmpt ) const { // --- Setup class containing solver performance data solverPerformance solverPerf ( lduMatrix::preconditioner::getName(controlDict_) + typeName, fieldName_ ); const label nCells = psi.size(); scalar* __restrict__ psiPtr = psi.begin(); scalarField pA(nCells); scalar* __restrict__ pAPtr = pA.begin(); scalarField yA(nCells); scalar* __restrict__ yAPtr = yA.begin(); // --- Calculate A.psi matrix_.Amul(yA, psi, interfaceBouCoeffs_, interfaces_, cmpt); // --- Calculate initial residual field scalarField rA(source - yA); scalar* __restrict__ rAPtr = rA.begin(); // --- Calculate normalisation factor const scalar normFactor = this->normFactor(psi, source, yA, pA); if (lduMatrix::debug >= 2) { Info<< " Normalisation factor = " << normFactor << endl; } // --- Calculate normalised residual norm solverPerf.initialResidual() = gSumMag(rA, matrix().mesh().comm()) /normFactor; solverPerf.finalResidual() = solverPerf.initialResidual(); // --- Check convergence, solve if not converged if ( minIter_ > 0 || !solverPerf.checkConvergence(tolerance_, relTol_) ) { scalarField AyA(nCells); scalar* __restrict__ AyAPtr = AyA.begin(); scalarField sA(nCells); scalar* __restrict__ sAPtr = sA.begin(); scalarField zA(nCells); scalar* __restrict__ zAPtr = zA.begin(); scalarField tA(nCells); scalar* __restrict__ tAPtr = tA.begin(); // --- Store initial residual const scalarField rA0(rA); // --- Initial values not used scalar rA0rA = 0; scalar alpha = 0; scalar omega = 0; // --- Select and construct the preconditioner autoPtr<lduMatrix::preconditioner> preconPtr = lduMatrix::preconditioner::New ( *this, controlDict_ ); // --- Solver iteration do { // --- Store previous rA0rA const scalar rA0rAold = rA0rA; rA0rA = gSumProd(rA0, rA, matrix().mesh().comm()); // --- Test for singularity if (solverPerf.checkSingularity(mag(rA0rA))) { break; } // --- Update pA if (solverPerf.nIterations() == 0) { for (label cell=0; cell<nCells; cell++) { pAPtr[cell] = rAPtr[cell]; } } else { // --- Test for singularity if (solverPerf.checkSingularity(mag(omega))) { break; } const scalar beta = (rA0rA/rA0rAold)*(alpha/omega); for (label cell=0; cell<nCells; cell++) { pAPtr[cell] = rAPtr[cell] + beta*(pAPtr[cell] - omega*AyAPtr[cell]); } } // --- Precondition pA preconPtr->precondition(yA, pA, cmpt); // --- Calculate AyA matrix_.Amul(AyA, yA, interfaceBouCoeffs_, interfaces_, cmpt); const scalar rA0AyA = gSumProd(rA0, AyA, matrix().mesh().comm()); alpha = rA0rA/rA0AyA; // --- Calculate sA for (label cell=0; cell<nCells; cell++) { sAPtr[cell] = rAPtr[cell] - alpha*AyAPtr[cell]; } // --- Test sA for convergence solverPerf.finalResidual() = gSumMag(sA, matrix().mesh().comm())/normFactor; if (solverPerf.checkConvergence(tolerance_, relTol_)) { for (label cell=0; cell<nCells; cell++) { psiPtr[cell] += alpha*yAPtr[cell]; } solverPerf.nIterations()++; return solverPerf; } // --- Precondition sA preconPtr->precondition(zA, sA, cmpt); // --- Calculate tA matrix_.Amul(tA, zA, interfaceBouCoeffs_, interfaces_, cmpt); const scalar tAtA = gSumSqr(tA, matrix().mesh().comm()); // --- Calculate omega from tA and sA // (cheaper than using zA with preconditioned tA) omega = gSumProd(tA, sA, matrix().mesh().comm())/tAtA; // --- Update solution and residual for (label cell=0; cell<nCells; cell++) { psiPtr[cell] += alpha*yAPtr[cell] + omega*zAPtr[cell]; rAPtr[cell] = sAPtr[cell] - omega*tAPtr[cell]; } solverPerf.finalResidual() = gSumMag(rA, matrix().mesh().comm()) /normFactor; } while ( ( solverPerf.nIterations()++ < maxIter_ && !solverPerf.checkConvergence(tolerance_, relTol_) ) || solverPerf.nIterations() < minIter_ ); } return solverPerf; }
void test_kronecker_product() { // DM = dense matrix; SM = sparse matrix Matrix<double, 2, 3> DM_a; SparseMatrix<double> SM_a(2,3); SM_a.insert(0,0) = DM_a.coeffRef(0,0) = -0.4461540300782201; SM_a.insert(0,1) = DM_a.coeffRef(0,1) = -0.8057364375283049; SM_a.insert(0,2) = DM_a.coeffRef(0,2) = 0.3896572459516341; SM_a.insert(1,0) = DM_a.coeffRef(1,0) = -0.9076572187376921; SM_a.insert(1,1) = DM_a.coeffRef(1,1) = 0.6469156566545853; SM_a.insert(1,2) = DM_a.coeffRef(1,2) = -0.3658010398782789; MatrixXd DM_b(3,2); SparseMatrix<double> SM_b(3,2); SM_b.insert(0,0) = DM_b.coeffRef(0,0) = 0.9004440976767099; SM_b.insert(0,1) = DM_b.coeffRef(0,1) = -0.2368830858139832; SM_b.insert(1,0) = DM_b.coeffRef(1,0) = -0.9311078389941825; SM_b.insert(1,1) = DM_b.coeffRef(1,1) = 0.5310335762980047; SM_b.insert(2,0) = DM_b.coeffRef(2,0) = -0.1225112806872035; SM_b.insert(2,1) = DM_b.coeffRef(2,1) = 0.5903998022741264; SparseMatrix<double,RowMajor> SM_row_a(SM_a), SM_row_b(SM_b); // test DM_fixedSize = kroneckerProduct(DM_block,DM) Matrix<double, 6, 6> DM_fix_ab = kroneckerProduct(DM_a.topLeftCorner<2,3>(),DM_b); CALL_SUBTEST(check_kronecker_product(DM_fix_ab)); CALL_SUBTEST(check_kronecker_product(kroneckerProduct(DM_a.topLeftCorner<2,3>(),DM_b))); for(int i=0;i<DM_fix_ab.rows();++i) for(int j=0;j<DM_fix_ab.cols();++j) VERIFY_IS_APPROX(kroneckerProduct(DM_a,DM_b).coeff(i,j), DM_fix_ab(i,j)); // test DM_block = kroneckerProduct(DM,DM) MatrixXd DM_block_ab(10,15); DM_block_ab.block<6,6>(2,5) = kroneckerProduct(DM_a,DM_b); CALL_SUBTEST(check_kronecker_product(DM_block_ab.block<6,6>(2,5))); // test DM = kroneckerProduct(DM,DM) MatrixXd DM_ab = kroneckerProduct(DM_a,DM_b); CALL_SUBTEST(check_kronecker_product(DM_ab)); CALL_SUBTEST(check_kronecker_product(kroneckerProduct(DM_a,DM_b))); // test SM = kroneckerProduct(SM,DM) SparseMatrix<double> SM_ab = kroneckerProduct(SM_a,DM_b); CALL_SUBTEST(check_kronecker_product(SM_ab)); SparseMatrix<double,RowMajor> SM_ab2 = kroneckerProduct(SM_a,DM_b); CALL_SUBTEST(check_kronecker_product(SM_ab2)); CALL_SUBTEST(check_kronecker_product(kroneckerProduct(SM_a,DM_b))); // test SM = kroneckerProduct(DM,SM) SM_ab.setZero(); SM_ab.insert(0,0)=37.0; SM_ab = kroneckerProduct(DM_a,SM_b); CALL_SUBTEST(check_kronecker_product(SM_ab)); SM_ab2.setZero(); SM_ab2.insert(0,0)=37.0; SM_ab2 = kroneckerProduct(DM_a,SM_b); CALL_SUBTEST(check_kronecker_product(SM_ab2)); CALL_SUBTEST(check_kronecker_product(kroneckerProduct(DM_a,SM_b))); // test SM = kroneckerProduct(SM,SM) SM_ab.resize(2,33); SM_ab.insert(0,0)=37.0; SM_ab = kroneckerProduct(SM_a,SM_b); CALL_SUBTEST(check_kronecker_product(SM_ab)); SM_ab2.resize(5,11); SM_ab2.insert(0,0)=37.0; SM_ab2 = kroneckerProduct(SM_a,SM_b); CALL_SUBTEST(check_kronecker_product(SM_ab2)); CALL_SUBTEST(check_kronecker_product(kroneckerProduct(SM_a,SM_b))); // test SM = kroneckerProduct(SM,SM) with sparse pattern SM_a.resize(4,5); SM_b.resize(3,2); SM_a.resizeNonZeros(0); SM_b.resizeNonZeros(0); SM_a.insert(1,0) = -0.1; SM_a.insert(0,3) = -0.2; SM_a.insert(2,4) = 0.3; SM_a.finalize(); SM_b.insert(0,0) = 0.4; SM_b.insert(2,1) = -0.5; SM_b.finalize(); SM_ab.resize(1,1); SM_ab.insert(0,0)=37.0; SM_ab = kroneckerProduct(SM_a,SM_b); CALL_SUBTEST(check_sparse_kronecker_product(SM_ab)); // test dimension of result of DM = kroneckerProduct(DM,DM) MatrixXd DM_a2(2,1); MatrixXd DM_b2(5,4); MatrixXd DM_ab2 = kroneckerProduct(DM_a2,DM_b2); CALL_SUBTEST(check_dimension(DM_ab2,2*5,1*4)); DM_a2.resize(10,9); DM_b2.resize(4,8); DM_ab2 = kroneckerProduct(DM_a2,DM_b2); CALL_SUBTEST(check_dimension(DM_ab2,10*4,9*8)); for(int i = 0; i < g_repeat; i++) { double density = Eigen::internal::random<double>(0.01,0.5); int ra = Eigen::internal::random<int>(1,50); int ca = Eigen::internal::random<int>(1,50); int rb = Eigen::internal::random<int>(1,50); int cb = Eigen::internal::random<int>(1,50); SparseMatrix<float,ColMajor> sA(ra,ca), sB(rb,cb), sC; SparseMatrix<float,RowMajor> sC2; MatrixXf dA(ra,ca), dB(rb,cb), dC; initSparse(density, dA, sA); initSparse(density, dB, sB); sC = kroneckerProduct(sA,sB); dC = kroneckerProduct(dA,dB); VERIFY_IS_APPROX(MatrixXf(sC),dC); sC = kroneckerProduct(sA.transpose(),sB); dC = kroneckerProduct(dA.transpose(),dB); VERIFY_IS_APPROX(MatrixXf(sC),dC); sC = kroneckerProduct(sA.transpose(),sB.transpose()); dC = kroneckerProduct(dA.transpose(),dB.transpose()); VERIFY_IS_APPROX(MatrixXf(sC),dC); sC = kroneckerProduct(sA,sB.transpose()); dC = kroneckerProduct(dA,dB.transpose()); VERIFY_IS_APPROX(MatrixXf(sC),dC); sC2 = kroneckerProduct(sA,sB); dC = kroneckerProduct(dA,dB); VERIFY_IS_APPROX(MatrixXf(sC2),dC); } }
int MOODS_MLF::multipleMatrixLookaheadFiltrationDNASetup(void) { m.resize(matrices.size(), 0); for (unsigned int i = 0; i < matrices.size(); ++i) { m[i] = matrices[i][0].size(); } // Calculate entropies for all matrices std::vector<doubleArray> goodnesses; goodnesses.reserve(matrices.size()); for (unsigned int i = 0; i < matrices.size(); ++i) { goodnesses.push_back(expectedDifferences(matrices[i], bg)); } window_positions.reserve(matrices.size()); for (unsigned int k = 0; k < matrices.size(); ++k) { if (q >= m[k]) { window_positions.push_back(0); } else { double current_goodness = 0; for (int i = 0; i < q; ++i) { current_goodness += goodnesses[k][i]; } double max_goodness = current_goodness; int window_pos = 0; for (int i = 0; i < m[k] - q; ++i) { current_goodness -= goodnesses[k][i]; current_goodness += goodnesses[k][i+q]; if (current_goodness > max_goodness) { max_goodness = current_goodness; window_pos = i+1; } } window_positions.push_back(window_pos); } } // Calculate lookahead scores for all matrices scoreMatrix T; T.reserve(matrices.size()); for (unsigned int k = 0; k < matrices.size(); ++k) { scoreArray C(m[k],0); for (int j = m[k] - 1; j > 0; --j) { score_t max = SCORE_MIN; for (unsigned int i = 0; i < numA; ++i) { if (max < matrices[k][i][j]) max = matrices[k][i][j]; } C[j - 1] = C[j] + max; } T.push_back(C); } // Pre-window scores scoreArray P; P.reserve(matrices.size()); for (unsigned int k = 0; k < matrices.size(); ++k) { score_t B = 0; for (int j = 0; j < window_positions[k]; ++j) { score_t max = SCORE_MIN; for (unsigned int i = 0; i < numA; ++i) { if (max < matrices[k][i][j]) max = matrices[k][i][j]; } B += max; } P.push_back(B); } // Arrange matrix indeces not in window by entropy, for use in scanning orders.reserve(matrices.size()); L.reserve(matrices.size()); for (unsigned short k = 0; k < matrices.size(); ++k) { if (q >= m[k]) { intArray temp1; orders.push_back(temp1); scoreArray temp2; L.push_back(temp2); } else { intArray order(m[k]-q, 0); for (int i = 0; i < window_positions[k]; ++i) { order[i] = i; } for (int i = window_positions[k]+q; i < m[k]; ++i) { order[i-q] = i; } compareRows comp; comp.goodness = &(goodnesses[k]); std::sort(order.begin(), order.end(), comp); orders.push_back(order); scoreArray K(m[k]-q, 0); for (int j = m[k]-q-1; j > 0; --j) { score_t max = INT_MIN; for (unsigned int i = 0; i < numA; ++i) { if (max < matrices[k][i][order[j]]) { max = matrices[k][i][order[j]]; } } K[j - 1] = K[j] + max; } L.push_back(K); } } // const bits_t size = 1 << (BITSHIFT * q); // numA^q // const bits_t BITAND = size - 1; // vector<vector< OutputListElementMulti> > output(size); { bitArray sA(q, 0); while (true) { bits_t code = 0; for (int j = 0; j < q; ++j) { code = (code << BITSHIFT) | sA[j]; } for (unsigned int k = 0; k < matrices.size(); ++k ) { if (m[k] <= q) { score_t score = 0; for (int i = 0; i < m[k]; ++i) { score += matrices[k][sA[i]][i]; } if (score >= thresholds[k]) { OutputListElementMulti temp; temp.full = true; temp.matrix = k; temp.score = score; output[code].push_back(temp); } } else { score_t score = 0; for (int i = 0; i < q; ++i) { score += matrices[k][sA[i]][i + window_positions[k]]; } if (score + P[k] + T[k][q + window_positions[k]-1] >= thresholds[k]) { OutputListElementMulti temp; temp.full = false; temp.matrix = k; temp.score = score; output[code].push_back(temp); } } } int pos = 0; while (pos < q) { if (sA[pos] < numA - 1) { ++sA[pos]; break; } else { sA[pos] = 0; ++pos; } } if (pos == q) { break; } } } return 0; }
void ContactLoop::run(){ #ifdef CONTACTLOOP_TIMING timingDeltas->start(); #endif DemField& dem=field->cast<DemField>(); if(dem.contacts->removeAllPending()>0 && !alreadyWarnedNoCollider){ LOG_WARN("Contacts pending removal found (and were removed); no collider being used?"); alreadyWarnedNoCollider=true; } if(dem.contacts->dirty){ throw std::logic_error("ContactContainer::dirty is true; the collider should re-initialize in such case and clear the dirty flag."); } // update Scene* of the dispatchers geoDisp->scene=phyDisp->scene=lawDisp->scene=scene; geoDisp->field=phyDisp->field=lawDisp->field=field; // ask dispatchers to update Scene* of their functors geoDisp->updateScenePtr(); phyDisp->updateScenePtr(); lawDisp->updateScenePtr(); // cache transformed cell size Matrix3r cellHsize; if(scene->isPeriodic) cellHsize=scene->cell->hSize; stress=Matrix3r::Zero(); // force removal of interactions that were not encountered by the collider // (only for some kinds of colliders; see comment for InteractionContainer::iterColliderLastRun) bool removeUnseen=(dem.contacts->stepColliderLastRun>=0 && dem.contacts->stepColliderLastRun==scene->step); const bool doStress=(evalStress && scene->isPeriodic); const bool deterministic(scene->deterministic); if(reorderEvery>0 && (scene->step%reorderEvery==0)) reorderContacts(); size_t size=dem.contacts->size(); CONTACTLOOP_CHECKPOINT("prologue"); const bool hasHook=!!hook; #ifdef WOO_OPENMP #pragma omp parallel for schedule(guided) #endif for(size_t i=0; i<size; i++){ CONTACTLOOP_CHECKPOINT("loop-begin"); const shared_ptr<Contact>& C=(*dem.contacts)[i]; if(unlikely(removeUnseen && !C->isReal() && C->stepLastSeen<scene->step)) { removeAfterLoop(C); continue; } if(unlikely(!C->isReal() && !C->isColliding())){ removeAfterLoop(C); continue; } /* this block is called exactly once for every potential contact created; it should check whether shapes should be swapped, and also set minDist00Sq if used (Sphere-Sphere only) */ if(unlikely(!C->isReal() && C->isFresh(scene))){ bool swap=false; const shared_ptr<CGeomFunctor>& cgf=geoDisp->getFunctor2D(C->leakPA()->shape,C->leakPB()->shape,swap); if(!cgf) continue; if(swap){ C->swapOrder(); } cgf->setMinDist00Sq(C->pA.lock()->shape,C->pB.lock()->shape,C); CONTACTLOOP_CHECKPOINT("swap-check"); } Particle *pA=C->leakPA(), *pB=C->leakPB(); Vector3r shift2=(scene->isPeriodic?scene->cell->intrShiftPos(C->cellDist):Vector3r::Zero()); // the order is as the geometry functor expects it shared_ptr<Shape>& sA(pA->shape); shared_ptr<Shape>& sB(pB->shape); // if minDist00Sq is defined, we might see that there is no contact without ever calling the functor // saving quite a few calls for sphere-sphere contacts if(likely(dist00 && !C->isReal() && !C->isFresh(scene) && C->minDist00Sq>0 && (sA->nodes[0]->pos-(sB->nodes[0]->pos+shift2)).squaredNorm()>C->minDist00Sq)){ CONTACTLOOP_CHECKPOINT("dist00Sq-too-far"); continue; } CONTACTLOOP_CHECKPOINT("pre-geom"); bool geomCreated=geoDisp->operator()(sA,sB,shift2,/*force*/false,C); CONTACTLOOP_CHECKPOINT("geom"); if(!geomCreated){ if(/* has both geo and phy */C->isReal()) LOG_ERROR("CGeomFunctor "<<geoDisp->getClassName()<<" did not update existing contact ##"<<pA->id<<"+"<<pB->id); continue; } // CPhys if(!C->phys) C->stepCreated=scene->step; if(!C->phys || updatePhys>UPDATE_PHYS_NEVER) phyDisp->operator()(pA->material,pB->material,C); if(!C->phys) throw std::runtime_error("ContactLoop: ##"+to_string(pA->id)+"+"+to_string(pB->id)+": con Contact.phys created from materials "+pA->material->getClassName()+" and "+pB->material->getClassName()+" (a CPhysFunctor must be available for every contacting material combination)."); if(hasHook && C->isFresh(scene) && hook->isMatch(pA->mask,pB->mask)) hook->hookNew(dem,C); CONTACTLOOP_CHECKPOINT("phys"); // CLaw bool keepContact=lawDisp->operator()(C->geom,C->phys,C); if(!keepContact){ if(hasHook && hook->isMatch(pA->mask,pB->mask)) hook->hookDel(dem,C); // call before requestRemove resets contact internals dem.contacts->requestRemoval(C); } CONTACTLOOP_CHECKPOINT("law"); if(applyForces && C->isReal() && likely(!deterministic)){ applyForceUninodal(C,pA); applyForceUninodal(C,pB); #if 0 for(const Particle* particle:{pA,pB}){ // remove once tested thoroughly const shared_ptr<Shape>& sh(particle->shape); if(!sh || sh->nodes.size()!=1) continue; // if(sh->nodes.size()!=1) continue; #if 0 for(size_t i=0; i<sh->nodes.size(); i++){ if((sh->nodes[i]->getData<DemData>().flags&DemData::DOF_ALL)!=DemData::DOF_ALL) LOG_WARN("Multinodal #"<<particle->id<<" has free DOFs, but force will not be applied; set ContactLoop.applyForces=False and use IntraForce(...) dispatcher instead."); } #endif Vector3r F,T,xc; std::tie(F,T,xc)=C->getForceTorqueBranch(particle,/*nodeI*/0,scene); sh->nodes[0]->getData<DemData>().addForceTorque(F,xc.cross(F)+T); } #endif } // track gradV work /* this is meant to avoid calling extra loop at every step, since the work must be evaluated incrementally */ if(doStress && /*contact law deleted the contact?*/ C->isReal()){ const auto& nnA(pA->shape->nodes); const auto& nnB(pB->shape->nodes); if(nnA.size()!=1 || nnB.size()!=1) throw std::runtime_error("ContactLoop.trackWork not allowed with multi-nodal particles in contact (##"+lexical_cast<string>(pA->id)+"+"+lexical_cast<string>(pB->id)+")"); Vector3r branch=C->dPos(scene); // (nnB[0]->pos-nnA[0]->pos+scene->cell->intrShiftPos(C->cellDist)); Vector3r F=C->geom->node->ori*C->phys->force; // force in global coords #ifdef WOO_OPENMP #pragma omp critical #endif { stress.noalias()+=F*branch.transpose(); } } CONTACTLOOP_CHECKPOINT("force+stress"); } // process removeAfterLoop #ifdef WOO_OPENMP for(list<shared_ptr<Contact>>& l: removeAfterLoopRefs){ for(const shared_ptr<Contact>& c: l) dem.contacts->remove(c); l.clear(); } #else for(const shared_ptr<Contact>& c: removeAfterLoopRefs) dem.contacts->remove(c); removeAfterLoopRefs.clear(); #endif // compute gradVWork eventually if(doStress){ stress/=scene->cell->getVolume(); if(scene->trackEnergy){ Matrix3r midStress=.5*(stress+prevStress); Real midVol=(!isnan(prevVol)?.5*(prevVol+scene->cell->getVolume()):scene->cell->getVolume()); Real dW=-(scene->cell->gradV*midStress).trace()*scene->dt*midVol; scene->energy->add(dW,"gradV",gradVIx,EnergyTracker::IsIncrement | EnergyTracker::ZeroDontCreate); } //prevTrGradVStress=trGradVStress; prevVol=scene->cell->getVolume(); prevStress=stress; } // apply forces deterministically, after the parallel loop // this could be also loop over particles in parallel (since per-particle loop would still be deterministic) but time per particle is very small here if(unlikely(deterministic) && applyForces){ // non-paralell loop here for(const auto& C: *dem.contacts){ if(!C->isReal()) continue; applyForceUninodal(C,C->leakPA()); applyForceUninodal(C,C->leakPB()); } } // reset updatePhys if it was to be used only once if(updatePhys==UPDATE_PHYS_ONCE) updatePhys=UPDATE_PHYS_NEVER; CONTACTLOOP_CHECKPOINT("epilogue"); }