int main() { /******************************* [ signal ] ******************************/ Type a = 0; Type b = Ls-1; Vector<Type> t = linspace(a,b,Ls) / Type(Fs); Vector<Type> s = sin( Type(400*PI) * pow(t,Type(2.0)) ); /******************************** [ widow ] ******************************/ a = 0; b = Type(Lg-1); Type u = (Lg-1)/Type(2); Type r = Lg/Type(8); t = linspace(a,b,Lg); Vector<Type> g = gauss(t,u,r); g = g/norm(g); /********************************* [ WFT ] *******************************/ Type runtime = 0; Timing cnt; cout << "Taking windowed Fourier transform." << endl; cnt.start(); Matrix< complex<Type> > coefs = wft( s, g ); cnt.stop(); runtime = cnt.read(); cout << "The running time = " << runtime << " (ms)" << endl << endl; /******************************** [ IWFT ] *******************************/ cout << "Taking inverse windowed Fourier transform." << endl; cnt.start(); Vector<Type> x = iwft( coefs, g ); cnt.stop(); runtime = cnt.read(); cout << "The running time = " << runtime << " (ms)" << endl << endl; cout << "The relative error is : " << "norm(s-x) / norm(s) = " << norm(s-x)/norm(s) << endl << endl; return 0; }
void setOutputMatrixToAlgebraDefault(float_tt* dst, size_t numVal, log4cxx::LoggerPtr logger) { Timing timer; valsSet(dst, ::nan(""), numVal); // ScaLAPACK algorithm should provide all entries in matrix LOG4CXX_DEBUG(SCALAPACKPHYSICAL_HPP_logger, "setOutputMatrixToAlgebraDefault took " << timer.stop()); }
void setInputMatrixToAlgebraDefault(float_tt* dst, size_t numVal) { Timing timer; memset(dst, 0, sizeof(float_tt) * numVal); // empty cells are implicit zeros for sparse matrices enum dummy {DBG_DENSE_ALGEBRA_WITH_NAN_FILL=0}; // won't be correct if empty cells present if(DBG_DENSE_ALGEBRA_WITH_NAN_FILL) { valsSet(dst, ::nan(""), numVal); // any non-signalling nan will do LOG4CXX_WARN(SCALAPACKPHYSICAL_HPP_logger, "@@@@@@@@@@@@@ WARNING: prefill matrix memory with NaN for debug"); } LOG4CXX_DEBUG(SCALAPACKPHYSICAL_HPP_logger, "setInputMatrixToAlgebraDefault took " << timer.stop()); }
int main() { /******************************* [ signal ] ******************************/ Vector<double> t = linspace( 0.0, (Ls-1)/fs, Ls ); Vector<double> st = sin( 200*PI*pow(t,2.0) ); st = st-mean(st); /******************************** [ CWT ] ********************************/ Matrix< complex<double> > coefs; CWT<double> wavelet("morlet"); wavelet.setScales( fs, fs/Ls, fs/2 ); Timing cnt; double runtime = 0.0; cout << "Taking continuous wavelet transform(Morlet)." << endl; cnt.start(); coefs = wavelet.cwtC(st); cnt.stop(); runtime = cnt.read(); cout << "The running time = " << runtime << " (ms)" << endl << endl; /******************************** [ ICWT ] *******************************/ cout << "Taking inverse continuous wavelet transform." << endl; cnt.start(); Vector<double> xt = wavelet.icwtC(coefs); cnt.stop(); runtime = cnt.read(); cout << "The running time = " << runtime << " (ms)" << endl << endl; cout << "The relative error is : " << endl; cout << "norm(st-xt) / norm(st) = " << norm(st-xt)/norm(st) << endl; cout << endl << endl; /******************************* [ signal ] ******************************/ Vector<float> tf = linspace( float(0.0), (Ls-1)/float(fs), Ls ); Vector<float> stf = sin( float(200*PI) * pow(tf,float(2.0) ) ); stf = stf-mean(stf); /******************************** [ CWT ] ********************************/ CWT<float> waveletf("mexiHat"); waveletf.setScales( float(fs), float(fs/Ls), float(fs/2), float(0.25) ); runtime = 0.0; cout << "Taking continuous wavelet transform(Mexican Hat)." << endl; cnt.start(); Matrix<float> coefsf = waveletf.cwtR(stf); cnt.stop(); runtime = cnt.read(); cout << "The running time = " << runtime << " (ms)" << endl << endl; /******************************** [ ICWT ] *******************************/ cout << "Taking inverse continuous wavelet transform." << endl; cnt.start(); Vector<float> xtf = waveletf.icwtR(coefsf); cnt.stop(); runtime = cnt.read(); cout << "The running time = " << runtime << " (ms)" << endl << endl; cout << "The relative error is : " << endl; cout << "norm(st-xt) / norm(st) = " << norm(stf-xtf)/norm(stf) << endl << endl; return 0; }
void main(void) { int i, k; Timing watch; Point3D mid, ext; float cubeHalfSide = 100.0f; float minSphereRadius; float minHalfBoxExtent; float maxSphereRadius; float maxHalfBoxExtent; // Note: Change the value of 'testCase' in [0, 4] to vary // the number of overlaps in the generated test data. int testCase = 0; switch (testCase) { case 0: minSphereRadius = 1.0f; minHalfBoxExtent = 1.0f; maxSphereRadius = 32.5f; maxHalfBoxExtent = 32.5f; break; case 1: minSphereRadius = 1.0f; minHalfBoxExtent = 1.0f; maxSphereRadius = 55.0f; maxHalfBoxExtent = 55.0f; break; case 2: minSphereRadius = 1.0f; minHalfBoxExtent = 1.0f; maxSphereRadius = 77.5f; maxHalfBoxExtent = 77.5f; break; case 3: minSphereRadius = 13.5f; minHalfBoxExtent = 13.5f; maxSphereRadius = 85.0f; maxHalfBoxExtent = 85.0f; break; case 4: minSphereRadius = 28.0f; minHalfBoxExtent = 28.0f; maxSphereRadius = 99.0f; maxHalfBoxExtent = 99.0f; break; default: minSphereRadius = 1.0f; minHalfBoxExtent = 1.0f; maxSphereRadius = 10.0f; maxHalfBoxExtent = 10.0f; } for (i = 0; i < NUMBER_OF_BV_PAIRS; i++) { sphereArray[i].r = getRandomScalar(minSphereRadius, maxSphereRadius); sphereArray[i].c.x = getRandomScalar(-cubeHalfSide + sphereArray[i].r, cubeHalfSide - sphereArray[i].r); sphereArray[i].c.y = getRandomScalar(-cubeHalfSide + sphereArray[i].r, cubeHalfSide - sphereArray[i].r); sphereArray[i].c.z = getRandomScalar(-cubeHalfSide + sphereArray[i].r, cubeHalfSide - sphereArray[i].r); ext.x = getRandomScalar(minHalfBoxExtent, maxHalfBoxExtent); ext.y = getRandomScalar(minHalfBoxExtent, maxHalfBoxExtent); ext.z = getRandomScalar(minHalfBoxExtent, maxHalfBoxExtent); mid.x = getRandomScalar(-cubeHalfSide + ext.x, cubeHalfSide - ext.x); mid.y = getRandomScalar(-cubeHalfSide + ext.y, cubeHalfSide - ext.y); mid.z = getRandomScalar(-cubeHalfSide + ext.z, cubeHalfSide - ext.z); boxArray[i].min.x = mid.x - ext.x; boxArray[i].min.y = mid.y - ext.y; boxArray[i].min.z = mid.z - ext.z; boxArray[i].max.x = mid.x + ext.x; boxArray[i].max.y = mid.y + ext.y; boxArray[i].max.z = mid.z + ext.z; } /* ==== Method 1 ==== */ noOverlaps[0] = 0; watch.start(); for (k=0; k < REPETITIONS; k++) { for (i = 0; i < NUMBER_OF_BV_PAIRS; i++) { noOverlaps[0] += overlapSphereAABB_Arvo(sphereArray[i], boxArray[i]); } } time[0] = watch.stop() / REPETITIONS; noOverlaps[0] /= REPETITIONS; printResult(algorithmName[0], noOverlaps[0], time[0]); /* ==== Method 2 ==== */ noOverlaps[1] = 0; watch.start(); for (k=0; k < REPETITIONS; k++) { for (i = 0; i < NUMBER_OF_BV_PAIRS; i++) { noOverlaps[1] += overlapSphereAABB_QRI(sphereArray[i], boxArray[i]); } } time[1] = watch.stop() / REPETITIONS; noOverlaps[1] /= REPETITIONS; printResult(algorithmName[1], noOverlaps[1], time[1]); /* ==== Method 3 ==== */ noOverlaps[2] = 0; watch.start(); for (k=0; k < REPETITIONS; k++) { for (i = 0; i < NUMBER_OF_BV_PAIRS; i++) { noOverlaps[2] += overlapSphereAABB_QRF(sphereArray[i], boxArray[i]); } } time[2] = watch.stop() / REPETITIONS; noOverlaps[2] /= REPETITIONS; printResult(algorithmName[2], noOverlaps[2], time[2]); /* ==== Method 4 ==== */ noOverlaps[3] = 0; watch.start(); for (k=0; k < REPETITIONS; k++) { for (i = 0; i < NUMBER_OF_BV_PAIRS; i++) { noOverlaps[3] += overlapSphereAABB_Cons(sphereArray[i], boxArray[i]); } } time[3] = watch.stop() / REPETITIONS; noOverlaps[3] /= REPETITIONS; printResult(algorithmName[3], noOverlaps[3], time[3]); /* ==== Method 5 ==== */ noOverlaps[4] = 0; watch.start(); for (k=0; k < REPETITIONS; k++) { for (i = 0; i < NUMBER_OF_BV_PAIRS; i++) { noOverlaps[4] += overlapSphereAABB_SSE(sphereArray[i], boxArray[i]); } } time[4] = watch.stop() / REPETITIONS; noOverlaps[4] /= REPETITIONS; printResult(algorithmName[4], noOverlaps[4], time[4]); /* ==== Result Summary ==== */ printf("=== Result summary ===\n\n"); printf("Number of overlap tests: %d\n\n", NUMBER_OF_BV_PAIRS); printf("Algorithm\t\tTime\t(Speedup)\n"); printf("%s\t%.4f\n", algorithmName[0], time[0]); for (i = 1; i < NUMBER_OF_METHODS; i++) { printf("%s\t%.4f\t(%.3lf)\n", algorithmName[i], time[i], time[0] / time[i]); } printf("\n"); printf("Overlaps: %.2f percent\n", 100.0f * (float)noOverlaps[0] / NUMBER_OF_BV_PAIRS); int noOverlapsReal = noOverlaps[0]; int noOverlapsConservative = noOverlaps[3]; printf("False positives reported in conservative test: %.3f percent\n", 100.0f * (noOverlapsConservative - noOverlapsReal) / (float)noOverlapsReal); getchar(); }
/*! * Calculate all collisions in the \ref World, according to \p flags and * place the results in \p worldCollisions. * * If \p getCollisionsWith is non-NULL, only collision pairs that \p * getCollisionsWith is part of are considered, instead of all collisions * in the \p World. This can be useful to test whether \p getCollisionsWith * collides with some proxy when other colliding proxies do not matter. * * \param getCollisionsWith If NULL this method returns all collisions of all * proxies. If non-NULL, only collisions with \p getCollisionsWith are * returned, all proxies not colliding with this one are ignored. The proxy * must be a toplevel proxy, child-proxies (i.e. a \ref Proxy that is a * child of another \ref Proxy) are not supported. */ void Pipeline::calculateAllCollisions(unsigned int flags, WorldCollisions* worldCollisions, Proxy* getCollisionsWith) { mSkipMiddlePhase = false; mSkipNarrowPhase = false; mCollisionInfos.clear(); if (getUsePipelining() && mWorkerPool->getDisableThreads()) { setUsePipelining(false); } if (!mBroadPhaseJobs->empty() || !mMiddlePhaseJobs->empty() || !mNarrowPhaseJobs->empty()) { throw Exception("Pipeline: internal error: not all job lists empty at beginning of collision detection"); } if (flags & World::COLLISIONFLAG_SKIP_MIDDLE_PHASE) { mSkipMiddlePhase = true; // skip middle phase => skip narrow phase flags |= World::COLLISIONFLAG_SKIP_NARROW_PHASE; } if (flags & World::COLLISIONFLAG_SKIP_NARROW_PHASE) { mSkipNarrowPhase = true; } // AB: when pipelined, we use a single list and start jobs whenever they // are created. // when not pipelined, we have to differ between new middle and // narrow phase jobs and therefore use different lists. if (getUsePipelining()) { mCurrentPhase = PHASE_NONE; mBroadPhaseJobs = &mPipelinedJobs; mMiddlePhaseJobs = &mPipelinedJobs; mNarrowPhaseJobs = &mPipelinedJobs; } else { mCurrentPhase = PHASE_BROADPHASE; mBroadPhaseJobs = &mUnpipelinedBroadPhaseJobs; mMiddlePhaseJobs = &mUnpipelinedMiddlePhaseJobs; mNarrowPhaseJobs = &mUnpipelinedNarrowPhaseJobs; } mMinCollisionsPerBroadPhaseJob = UINT_MAX; mMaxCollisionsPerBroadPhaseJob = 0; mTotalBroadPhaseCollisions = 0; Timing time; mWorld->getBroadPhase()->createBroadPhaseJobs(getCollisionsWith); if (!mWorld->getBroadPhase()->getJobCollection()) { throw NullPointerException("mWorld->getBroadPhase()->getJobCollection()"); } PipelineThreadJobCollection* broadPhaseJobCollection = mWorld->getBroadPhase()->getJobCollection(); if (broadPhaseJobCollection->getJobsInCollectionCount() == 0) { // AB: we essentially skip the broadphase here. // this is // a) a little hack to enforce the usage of the job collection // (instead of plain ThreadJobs) in the broadphase // -> some algorithms (e.g. the spatialhash) require this, to // get notified about completion of the broadphase // b) a small optimization for the case that the broadphase // already knows that nothing will ever collide and thus // won't need to create jobs at all // (e.g. no collidable proxies in the world) // of course b) doesnt really matter :-) mSkipMiddlePhase = true; mSkipNarrowPhase = true; } else { broadPhaseJobCollection->start(); worldCollisions->setBroadPhaseCollisions(mWorld->getBroadPhase()->getBroadPhaseCollisions()); } mWorld->getBroadPhase()->getJobCollection()->addStartOnceCompleted(mBroadPhasePostProcessingJobCollection); mBroadPhasePostProcessingJobCollection->setSkipMiddlePhase(mSkipMiddlePhase); // mBroadPhasePostProcessingJobCollection is just a dummy job collection // without any actual jobs // -> we just need the allJobsCompleted() method mBroadPhasePostProcessingJobCollection->setAllJobsAreAdded(); if (!mSkipMiddlePhase) { mMiddlePhaseJobCreator->createSelfCollisionJobs(mWorld->getSelfcollisionProxies()); if (mDetectorDeformManager) { // note: once this is called, internal job collections of the // DetectorDeformAlgorithm objects will add their jobs to the // pipeline - but the _pipeline_ will actually start the jobs mDetectorDeformManager->notifyPipelineStarted(); } // add deformable self-collision jobs if (mDetectorDeformManager) { const std::list<Proxy*>& selfCollisionProxies = mWorld->getSelfcollisionProxies(); for (std::list<Proxy*>::const_iterator it = selfCollisionProxies.begin(); it != selfCollisionProxies.end(); ++it) { if (!((*it)->getProxyType() & PROXYTYPE_DEFORMABLE)) { continue; } if (mWorld->getUseCollisionCaching()) { bool cacheApplied = mWorld->getCollisionCache()->applyCacheIfAvailable(*it, *it); if (cacheApplied) { continue; } } DetectorDeformAlgorithm* algorithm = mDetectorDeformManager->pickAlgorithmFor(*it, *it); if (algorithm) { CollisionPair pair; // FIXME: make CollisionPair store Proxy pointers, not // BoundingVolume pointers. pair.bvol1 = (*it)->getBvHierarchyNode()->getBoundingVolume(); pair.bvol2 = pair.bvol1; algorithm->createCollisionJobFor(pair); } } } } if (!getUsePipelining()) { completeCurrentPhase(); time.stop(); mWorld->getCurrentDebugLogEntry()->addTiming("BroadPhase", time); time.restart(); mCurrentPhase = PHASE_MIDDLEPHASE; completeCurrentPhase(); time.stop(); mWorld->getCurrentDebugLogEntry()->addTiming("MiddlePhase", time); time.restart(); mCurrentPhase = PHASE_NARROWPHASE; completeCurrentPhase(); time.stop(); mWorld->getCurrentDebugLogEntry()->addTiming("NarrowPhase", time); } else { completeCurrentPhase(); time.stop(); // in a pipelined run we cannot differ between phases // AB: note: "BroadPhase", "MiddlePhase" and "NarrowPhase" timings // can still be retrieved from the log - since we havent added // them, they will be nullified Timing objects. mWorld->getCurrentDebugLogEntry()->addTiming("Pipeline", time); } if (mDetectorDeformManager) { // reset the job collections of the algorithms // note: at this point all jobs must already be completed! mDetectorDeformManager->notifyPipelineCompleted(); } // pipeline has been completed at this point. add results to // worldCollisions. worldCollisions->setRigidBoundingVolumeCollisions(&mMiddlePhaseRigidResults); worldCollisions->addNarrowPhaseCollisions(&mCollisionInfos); // post-pipeline algorithms time.restart(); startCompletelyUnthreadedAlgorithms(worldCollisions); time.stop(); mWorld->getCurrentDebugLogEntry()->addTiming("UnthreadedPhase", time); mWorld->getCurrentDebugLogEntry()->setUIntVariable("BroadPhase job count", mWorld->getBroadPhase()->getJobCollection()->getJobsInCollectionCount()); mWorld->getCurrentDebugLogEntry()->setUIntVariable("BroadPhase min collisions per job", mMinCollisionsPerBroadPhaseJob); mWorld->getCurrentDebugLogEntry()->setUIntVariable("BroadPhase max collisions per job", mMaxCollisionsPerBroadPhaseJob); mWorld->getCurrentDebugLogEntry()->setUIntVariable("BroadPhase collisions", mTotalBroadPhaseCollisions); // sanity check mWorkerPool->waitForCompletion(); if (mWorkerPool->hasCompletedJobs()) { std::cerr << dc_funcinfo << "ERROR: completed jobs left" << std::endl; while (mWorkerPool->hasCompletedJobs()) { delete mWorkerPool->retrieveCompletedJob(); } } mCurrentPhase = PHASE_INVALID; if (!mBroadPhaseJobs->empty() || !mMiddlePhaseJobs->empty() || !mNarrowPhaseJobs->empty()) { throw Exception("Pipeline: internal error: not all job lists empty at end of collision detection"); } }