Пример #1
0
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;
}
Пример #2
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());
}
Пример #3
0
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());
}
Пример #4
0
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();
}
Пример #6
0
    /*!
     * 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");
        }
    }