コード例 #1
0
ファイル: DTW.cpp プロジェクト: gaurav38/HackDuke13
void DTW::smoothData(VectorDouble &data,UINT smoothFactor,VectorDouble &resultsData){

	const UINT M = (UINT)data.size();
	const UINT N = (UINT) floor(double(M)/double(smoothFactor));
	resultsData.resize(N,0);
	for(UINT i=0; i<N; i++) resultsData[i]=0.0;

	if(smoothFactor==1 || M<smoothFactor){
		resultsData = data;
		return;
	}

	for(UINT i=0; i<N; i++){
	    double mean = 0.0;
		UINT index = i*smoothFactor;
		for(UINT x=0; x<smoothFactor; x++){
			mean += data[index+x];
		}
		resultsData[i] = mean/smoothFactor;
	}
	//Add on the data that does not fit into the window
	if(M%smoothFactor!=0.0){
		double mean = 0.0;
			for(UINT i=N*smoothFactor; i<M; i++) mean += data[i];
        mean/=M-(N*smoothFactor);
		//Add one to the end of the vector
		VectorDouble tempVector(N+1);
		for(UINT i=0; i<N; i++) tempVector[i] = resultsData[i];
		tempVector[N] = mean;
		resultsData = tempVector;
	}

}
コード例 #2
0
static void RadixSort( std::vector<MortonPrimitive> *v )
{
    std::vector<MortonPrimitive> tempVector( v->size() );

    const int bitsPerPass = 6;
    const int nBits = 30;

    wxASSERT( (nBits % bitsPerPass) == 0 );

    const int nPasses = nBits / bitsPerPass;

    for( int pass = 0; pass < nPasses; ++pass )
    {
        // Perform one pass of radix sort, sorting _bitsPerPass_ bits
        const int lowBit = pass * bitsPerPass;

        // Set in and out vector pointers for radix sort pass
        std::vector<MortonPrimitive> &in  = (pass & 1) ? tempVector : *v;
        std::vector<MortonPrimitive> &out = (pass & 1) ? *v : tempVector;

        // Count number of zero bits in array for current radix sort bit
        const int nBuckets = 1 << bitsPerPass;
        int bucketCount[nBuckets] = {0};
        const int bitMask = (1 << bitsPerPass) - 1;

        for( uint32_t i = 0; i < in.size(); ++i )
        {
            const MortonPrimitive &mp = in[i];
            int bucket = (mp.mortonCode >> lowBit) & bitMask;

            wxASSERT( (bucket >= 0) && (bucket < nBuckets) );

            ++bucketCount[bucket];
        }

        // Compute starting index in output array for each bucket
        int startIndex[nBuckets];
        startIndex[0] = 0;

        for( int i = 1; i < nBuckets; ++i )
            startIndex[i] = startIndex[i - 1] + bucketCount[i - 1];

        // Store sorted values in output array
        for( uint32_t i = 0; i < in.size(); ++i )
        {
            const MortonPrimitive &mp = in[i];
            int bucket = (mp.mortonCode >> lowBit) & bitMask;
            out[startIndex[bucket]++] = mp;
        }
    }

    // Copy final result from _tempVector_, if needed
    if( nPasses & 1 )
        std::swap( *v, tempVector );
}
コード例 #3
0
AttributesImpl&
AttributesImpl::operator=(const AttributesImpl&		theRHS)
{
	if (this != &theRHS)
	{
		// Note that we can't chain up to our base class operator=()
		// because it's private.

		// Some temporary structures to hold everything
		// until we're done.
		AttributesVectorType		tempVector(getMemoryManager());

		const unsigned int	theLength = theRHS.getLength();

		if (theLength > 0)
		{
			// Reserve the appropriate capacity right now...
			tempVector.reserve(theLength);

			// This will delete everything in tempVector when we're done...
			CollectionDeleteGuard<AttributesVectorType,
								  DeleteFunctor<AttributeVectorEntryExtended> >		theGuard(tempVector);

			typedef AttributesVectorType::const_iterator		const_iterator;

			const const_iterator	theEnd = theRHS.m_attributesVector.end();

			// Copy the vector entries, and build the index map...
			for(const_iterator i = theRHS.m_attributesVector.begin(); i != theEnd; ++i)
			{
				AttributeVectorEntryExtended* const		theEntry = *i;

				assert(theEntry != 0);

				// Add the item...
				tempVector.push_back(
					getNewEntry(
						&*theEntry->m_Name.begin(),
						&*theEntry->m_Type.begin(),
						&*theEntry->m_Value.begin(),
						&*theEntry->m_uri.begin(),
						&*theEntry->m_localName.begin()));
			}

			// OK, we're safe, so swap the contents of the
			// containers.  This is guaranteed not to throw.
			m_attributesVector.swap(tempVector);
		}

		assert(getLength() == theLength);
	}

	return *this;
}
コード例 #4
0
void Vector::rotate_around(float yz, float xz, float xy, const Vector & origin){
	Vector tempVector(*this);
	tempVector.subtract(origin);
	//m_start->set(origin);
	x() = origin.x();
	y() = origin.y();
	z() = origin.z();
	tempVector.rotateXY(xy);
	tempVector.rotateXZ(xz);
	tempVector.rotateYZ(yz);
	//m_start->add(tempVector);
	x() += tempVector.x();
	y() += tempVector.y();
	z() += tempVector.z();
}
コード例 #5
0
ファイル: genSamples.cpp プロジェクト: mcmachado/ALEResearch
void updateAverage(vector<bool> Fprev, vector<bool> F, int frame, Parameters param, int gameId){
	assert (Fprev.size() == F.size());
	assert (F.size() == NUM_BITS);
	
	bool toPrint = false;

	vector<int> tempVector(2 * NUM_BITS, 0);

	for(int i = 0; i < NUM_BITS; i++){
		if(!Fprev[i] && F[i]){ // 0->1
			frequency[i] = (frequency[i] * (frame - 1) + 1) / frame;
			tempVector[i] = 1;
			if(frame > FRAMES_TO_WAIT && frequency[i] < param.freqThreshold){
				tempVector[i] = 2; //1 denotes flip, 2 denotes relevant flip
				toPrint = true;
			}
		} else{
			frequency[i] = (frequency[i] * (frame - 1) + 0) / frame;
		}		
		if(Fprev[i] && !F[i]){ // 1->0
			frequency[i + NUM_BITS] = (frequency[i + NUM_BITS] * (frame - 1) + 1) / frame;
			tempVector[i + NUM_BITS] = 1;
			if(frame > FRAMES_TO_WAIT && frequency[i + NUM_BITS] < param.freqThreshold){
				tempVector[i + NUM_BITS] = 2;
				toPrint = true;
			}
		} else{
			frequency[i + NUM_BITS] = (frequency[i + NUM_BITS] * (frame - 1) + 0) / frame;
		}
	}

	ofstream myFileBits, myFileBytes;
	myFileBits.open (param.outputPath + "_bits.csv", ios::app);
	if(toPrint){
		for(int i = 0; i < tempVector.size(); i++){
			if(param.toReportAll == 1 && tempVector[i] != 0){
				myFileBits << i << ",";
			}
			if(param.toReportAll == 0 && tempVector[i] == 2){
				myFileBits << i << ",";
			}
		}
		myFileBits << endl;
	}
	myFileBits.close();
}
コード例 #6
0
vector<char> Sparse6Writer::encodeNumberOfNodes(unsigned number)
{
    vector<char> result;
    // three cases
    if (number <= 62)
        result.push_back(number+63);
    else /* if(number <= 258047) */
    {
        // the first characer is 126
        result.push_back(126);
        BitVector tempVector(number);
        tempVector.padL(18);
        result.push_back(tempVector.getIntBit(0, 6));
        result.push_back(tempVector.getIntBit(6, 6));
        result.push_back(tempVector.getIntBit(12, 6));
    }
    return result;
}
コード例 #7
0
void CContinuousActionSigmoidPolicy::getNoise(CStateCollection *state, CContinuousActionData *action, CContinuousActionData *l_noise)
{
	if (randomControllerMode == INTERN_RANDOM_CONTROLLER)
	{
		ColumnVector tempVector(this->contAction->getNumDimensions());
		
		policy->getNextContinuousAction(state, l_noise);
		
		tempVector = *action;

		for (int i = 0; i < tempVector.nrows(); i ++)
		{
			double umax = getContinuousActionProperties()->getMaxActionValue(i);
			double umin = getContinuousActionProperties()->getMinActionValue(i);
			double width = umax - umin;

			double actionValue = tempVector.element(i);
			actionValue = (actionValue - umin) / (umax - umin);

			if (actionValue <= 0.0001)
			{
				actionValue = 0.0001;
			}
			else
			{
				if (actionValue >= 0.9999)
				{
					actionValue = 0.9999;
				}
			}

			actionValue = (- log(1 / actionValue - 1) + 2) * width  / 4 + umin;

			tempVector.element(i) = actionValue;
		}

		*l_noise *= -1;
		*l_noise += tempVector;
	}
	else
	{
		CContinuousActionController::getNoise(state, action, l_noise);
	}
}
コード例 #8
0
ファイル: pipeline.cpp プロジェクト: cwestin/mongo
    intrusive_ptr<Pipeline> Pipeline::splitForSharded() {
        /* create an initialize the shard spec we'll return */
        intrusive_ptr<Pipeline> pShardPipeline(new Pipeline(pCtx));
        pShardPipeline->collectionName = collectionName;
        pShardPipeline->explain = explain;

        /* put the source list aside */
        SourceVector tempVector(sourceVector);
        sourceVector.clear();

        /*
          Run through the pipeline, looking for points to split it into
          shard pipelines, and the rest.
         */
        while(!tempVector.empty()) {
            intrusive_ptr<DocumentSource> &pSource = tempVector.front();

            /* hang on to this in advance, in case it is a group */
            DocumentSourceGroup *pGroup =
                dynamic_cast<DocumentSourceGroup *>(pSource.get());

            /* move the source from the tempVector to the shard sourceVector */
            pShardPipeline->sourceVector.push_back(pSource);
            tempVector.erase(tempVector.begin());

            /*
              If we found a group, that's a split point.
             */
            if (pGroup) {
                /* start this pipeline with the group merger */
                sourceVector.push_back(pGroup->createMerger());

                /* and then add everything that remains and quit */
                for(size_t tempn = tempVector.size(), tempi = 0;
                    tempi < tempn; ++tempi)
                    sourceVector.push_back(tempVector[tempi]);
                break;
            }
        }

        return pShardPipeline;
    }
コード例 #9
0
ファイル: fvector.cpp プロジェクト: 86400/scummvm
void FVector::fn4(FVector *dest, const FVector *v1, const FVector *v2) {
	FVector tempVector(v1->_x + v2->_x, v1->_y + v2->_y, v1->_z + v2->_z);
	tempVector.fn3();

	*dest = tempVector;
}
コード例 #10
0
DWORD WINAPI CTcpServerSocketHelper::_ReadDataThreadProc(LPVOID lpParam)
{
	CTcpServerSocketHelper *This = (CTcpServerSocketHelper *)lpParam;

	DWORD dwResult = -1;
	DWORD dwIndex = 0;
	DWORD dwVectorSize = 0;

	while (TRUE)
	{
		EnterCriticalSection(&This->m_cs);
		vector<SOCKET> tempVector(This->m_AcceptSocketVector);
		LeaveCriticalSection(&This->m_cs);

		dwVectorSize = (DWORD)tempVector.size();
		for (dwIndex=0; dwIndex < dwVectorSize; ++dwIndex)
		{
			SOCKET hSock = tempVector[dwIndex];

			BOOL bErr = FALSE;
			if (This->IsSocketReadable(0,bErr,hSock))
			{
				DWORD dwSize = 64*1024;
				BYTE *pyBuf = new BYTE[dwSize];

				assert(pyBuf);
				if (This->ReceiveData(pyBuf,&dwSize,hSock))
				{
					//This->m_pEvent->OnDataIn(hSock, pyBuf, dwSize);
					if (dwSize==0)
					{
						//接收失败!对方已经关闭了连接?
						

						This->CloseSocket(hSock);

						//1) 从This->m_AcceptSocketVector erase this socket
						EnterCriticalSection(&This->m_cs);

						vector<SOCKET>::iterator sckVect = This->m_AcceptSocketVector.begin();

						for (;sckVect!=This->m_AcceptSocketVector.end();)
						{
							if (*sckVect==hSock)
							{
								sckVect = This->m_AcceptSocketVector.erase(sckVect);
								break;
							}
							else
							{
								++sckVect;
							}
						}

						LeaveCriticalSection(&This->m_cs);

						// 2) This->m_pEvent->OnSocketClose(...)
						This->m_pEvent->OnSocketClose(hSock,1);

					}
					else
					{
						This->m_pEvent->OnDataIn(hSock, pyBuf, dwSize);
					}
				}
				else
				{ //接收失败!对方已经关闭了连接?

					

					This->CloseSocket(hSock);

					//1) 从This->m_AcceptSocketVector erase this socket
					EnterCriticalSection(&This->m_cs);

					vector<SOCKET>::iterator sckVect = This->m_AcceptSocketVector.begin();

					for (;sckVect!=This->m_AcceptSocketVector.end();)
					{
						if (*sckVect==hSock)
						{
							sckVect = This->m_AcceptSocketVector.erase(sckVect);
							break;
						}
						else
						{
							++sckVect;
						}
					}

					LeaveCriticalSection(&This->m_cs);

					// 2) This->m_pEvent->OnSocketClose(...)
					This->m_pEvent->OnSocketClose(hSock,1);
				}

				delete [] pyBuf;
			}
			else
			{
				if (bErr)
				{
					//接收失败!对方已经关闭了连接?

					

					This->CloseSocket(hSock);

					//1) 从This->m_AcceptSocketVector erase this socket
					EnterCriticalSection(&This->m_cs);

					vector<SOCKET>::iterator sckVect = This->m_AcceptSocketVector.begin();

					for (;sckVect!=This->m_AcceptSocketVector.end();)
					{
						if (*sckVect==hSock)
						{
							sckVect = This->m_AcceptSocketVector.erase(sckVect);
							break;
						}
						else
						{
							++sckVect;
						}
					}

					LeaveCriticalSection(&This->m_cs);

					// 2) This->m_pEvent->OnSocketClose(...)
					This->m_pEvent->OnSocketClose(hSock,1);

				}

			}
		}

		if (::WaitForSingleObject(This->m_hTerminateReadDataThreadEvent, 500)==WAIT_OBJECT_0)
		{
			break;
		}
	}

	dwResult = 0;
	return dwResult;
}
コード例 #11
0
void AffineDeformationFast::calcA()
{
	int i,j;
	double sumofwpx,sumofwpy;
	Point *pstar=new Point[commonPoint.size()];
	if(sumofw!=NULL)
	{
		delete[] sumofw;
		sumofw=NULL;
	}
	sumofw=new double[commonPoint.size()];
	w.clear();//w[非控制点下标][控制点下标]
	vector<double> tempVector(oldControlPoint.size(),0.0);

	precomputedpart=commonPoint;
	for(i=0;i<commonPoint.size();i++)
	{
		if(isControlPoint(commonPoint[i])>=0)//是控制点,不需要计算w值
		{
			w.push_back(tempVector);
			continue;
		}
		sumofw[i]=0.0;
		sumofwpx=0.0;
		sumofwpy=0.0;
		for(j=0;j<oldControlPoint.size();j++)
		{
			double t1=oldControlPoint[j].xx-commonPoint[i].xx;
			double t2=oldControlPoint[j].yy-commonPoint[i].yy;
			t1=1.0/pow(t1*t1+t2*t2,alpha);
			sumofw[i]+=t1;
			sumofwpx+=t1*oldControlPoint[j].xx;
			sumofwpy+=t1*oldControlPoint[j].yy;
			tempVector[j]=t1;
		}
		pstar[i].xx=sumofwpx/sumofw[i];
		pstar[i].yy=sumofwpy/sumofw[i];
		precomputedpart[i].xx=commonPoint[i].xx-pstar[i].xx;
		precomputedpart[i].yy=commonPoint[i].yy-pstar[i].yy;
		w.push_back(tempVector);

		cleartempMatrix();
		for(j=0;j<oldControlPoint.size();j++)
		{
			double a=oldControlPoint[j].xx-pstar[i].xx;
			double b=oldControlPoint[j].yy-pstar[i].yy;
			tempMatrix[0][0]+=tempVector[j]*a*a;
			tempMatrix[1][1]+=tempVector[j]*b*b;
			a*=b;
			tempMatrix[0][1]+=tempVector[j]*a;
			tempMatrix[1][0]+=tempVector[j]*a;
		}
		double tt,dt=tempMatrix[0][0]*tempMatrix[1][1]-tempMatrix[0][1]*tempMatrix[1][0];
		doubleswap(tempMatrix[0][0],tempMatrix[1][1]);
		tempMatrix[0][0]/=dt;
		tempMatrix[1][1]/=dt;
		tempMatrix[0][1]/=(-dt);
		tempMatrix[1][0]/=(-dt);
		tt=precomputedpart[i].xx*tempMatrix[0][0]+precomputedpart[i].yy*tempMatrix[1][0];
		dt=precomputedpart[i].xx*tempMatrix[0][1]+precomputedpart[i].yy*tempMatrix[1][1];
		precomputedpart[i].xx=tt;
		precomputedpart[i].yy=dt;
	}

	A.clear();//A[非控制点下标][控制点下标]
	for(i=0;i<commonPoint.size();i++)
	{
		if(isControlPoint(commonPoint[i])>=0)//是控制点,不需要计算w值
		{
			A.push_back(tempVector);
			continue;
		}
		for(j=0;j<oldControlPoint.size();j++)
		{
			Point tempPoint;
			tempPoint.xx=oldControlPoint[j].xx-pstar[i].xx;
			tempPoint.yy=oldControlPoint[j].yy-pstar[i].yy;
			tempVector[j]=w[i][j]*(precomputedpart[i].xx*tempPoint.xx+precomputedpart[i].yy*tempPoint.yy);
		}
		A.push_back(tempVector);
	}
	delete[] pstar;

	isPreComputed=true;
}
コード例 #12
0
ファイル: pipeline.cpp プロジェクト: Xyand/mongo
    intrusive_ptr<Pipeline> Pipeline::parseCommand(
        string &errmsg, BSONObj &cmdObj,
        const intrusive_ptr<ExpressionContext> &pCtx) {
        intrusive_ptr<Pipeline> pPipeline(new Pipeline(pCtx));
        vector<BSONElement> pipeline;

        /* gather the specification for the aggregation */
        for(BSONObj::iterator cmdIterator = cmdObj.begin();
                cmdIterator.more(); ) {
            BSONElement cmdElement(cmdIterator.next());
            const char *pFieldName = cmdElement.fieldName();

            /* look for the aggregation command */
            if (!strcmp(pFieldName, commandName)) {
                pPipeline->collectionName = cmdElement.String();
                continue;
            }

            /* check for the collection name */
            if (!strcmp(pFieldName, pipelineName)) {
                pipeline = cmdElement.Array();
                continue;
            }

            /* check for explain option */
            if (!strcmp(pFieldName, explainName)) {
                pPipeline->explain = cmdElement.Bool();
                continue;
            }

            /* if the request came from the router, we're in a shard */
            if (!strcmp(pFieldName, fromRouterName)) {
                pCtx->setInShard(cmdElement.Bool());
                continue;
            }

            /* check for debug options */
            if (!strcmp(pFieldName, splitMongodPipelineName)) {
                pPipeline->splitMongodPipeline = true;
                continue;
            }

            /* Ignore $auth information sent along with the command. The authentication system will
             * use it, it's not a part of the pipeline.
             */
            if (!strcmp(pFieldName, AuthenticationTable::fieldName.c_str())) {
                continue;
            }

            /* we didn't recognize a field in the command */
            ostringstream sb;
            sb <<
               "unrecognized field \"" <<
               cmdElement.fieldName();
            errmsg = sb.str();
            return intrusive_ptr<Pipeline>();
        }

        /*
          If we get here, we've harvested the fields we expect for a pipeline.

          Set up the specified document source pipeline.
        */
        SourceVector *pSourceVector = &pPipeline->sourceVector; // shorthand

        /* iterate over the steps in the pipeline */
        const size_t nSteps = pipeline.size();
        for(size_t iStep = 0; iStep < nSteps; ++iStep) {
            /* pull out the pipeline element as an object */
            BSONElement pipeElement(pipeline[iStep]);
            uassert(15942, str::stream() << "pipeline element " <<
                    iStep << " is not an object",
                    pipeElement.type() == Object);
            BSONObj bsonObj(pipeElement.Obj());

            // Parse a pipeline stage from 'bsonObj'.
            uassert(16435, "A pipeline stage specification object must contain exactly one field.",
                    bsonObj.nFields() == 1);
            BSONElement stageSpec = bsonObj.firstElement();
            const char* stageName = stageSpec.fieldName();

            // Create a DocumentSource pipeline stage from 'stageSpec'.
            StageDesc key;
            key.pName = stageName;
            const StageDesc* pDesc = (const StageDesc*)
                    bsearch(&key, stageDesc, nStageDesc, sizeof(StageDesc),
                            stageDescCmp);

            uassert(16436,
                    str::stream() << "Unrecognized pipeline stage name: '" << stageName << "'",
                    pDesc);
            intrusive_ptr<DocumentSource> stage = (*pDesc->pFactory)(&stageSpec, pCtx);
            verify(stage);
            stage->setPipelineStep(iStep);
            pSourceVector->push_back(stage);
        }

        /* if there aren't any pipeline stages, there's nothing more to do */
        if (!pSourceVector->size())
            return pPipeline;

        /*
          Move filters up where possible.

          CW TODO -- move filter past projections where possible, and noting
          corresponding field renaming.
        */

        /*
          Wherever there is a match immediately following a sort, swap them.
          This means we sort fewer items.  Neither changes the documents in
          the stream, so this transformation shouldn't affect the result.

          We do this first, because then when we coalesce operators below,
          any adjacent matches will be combined.
         */
        for(size_t srcn = pSourceVector->size(), srci = 1;
            srci < srcn; ++srci) {
            intrusive_ptr<DocumentSource> &pSource = pSourceVector->at(srci);
            if (dynamic_cast<DocumentSourceMatch *>(pSource.get())) {
                intrusive_ptr<DocumentSource> &pPrevious =
                    pSourceVector->at(srci - 1);
                if (dynamic_cast<DocumentSourceSort *>(pPrevious.get())) {
                    /* swap this item with the previous */
                    intrusive_ptr<DocumentSource> pTemp(pPrevious);
                    pPrevious = pSource;
                    pSource = pTemp;
                }
            }
        }

        /*
          Coalesce adjacent filters where possible.  Two adjacent filters
          are equivalent to one filter whose predicate is the conjunction of
          the two original filters' predicates.  For now, capture this by
          giving any DocumentSource the option to absorb it's successor; this
          will also allow adjacent projections to coalesce when possible.

          Run through the DocumentSources, and give each one the opportunity
          to coalesce with its successor.  If successful, remove the
          successor.

          Move all document sources to a temporary list.
        */
        SourceVector tempVector(*pSourceVector);
        pSourceVector->clear();

        /* move the first one to the final list */
        pSourceVector->push_back(tempVector[0]);

        /* run through the sources, coalescing them or keeping them */
        for(size_t tempn = tempVector.size(), tempi = 1;
            tempi < tempn; ++tempi) {
            /*
              If we can't coalesce the source with the last, then move it
              to the final list, and make it the new last.  (If we succeeded,
              then we're still on the same last, and there's no need to move
              or do anything with the source -- the destruction of tempVector
              will take care of the rest.)
            */
            intrusive_ptr<DocumentSource> &pLastSource = pSourceVector->back();
            intrusive_ptr<DocumentSource> &pTemp = tempVector.at(tempi);
            verify(pTemp && pLastSource);
            if (!pLastSource->coalesce(pTemp))
                pSourceVector->push_back(pTemp);
        }

        /* optimize the elements in the pipeline */
        for(SourceVector::iterator iter(pSourceVector->begin()),
                listEnd(pSourceVector->end()); iter != listEnd; ++iter) {
            if (!*iter) {
                errmsg = "Pipeline received empty document as argument";
                return intrusive_ptr<Pipeline>();
            }

            (*iter)->optimize();
        }

        return pPipeline;
    }
コード例 #13
0
ファイル: pipeline.cpp プロジェクト: nosqldb/mongo
    intrusive_ptr<Pipeline> Pipeline::parseCommand(
        string &errmsg, BSONObj &cmdObj,
        const intrusive_ptr<ExpressionContext> &pCtx) {
        intrusive_ptr<Pipeline> pPipeline(new Pipeline(pCtx));
        vector<BSONElement> pipeline;

        /* gather the specification for the aggregation */
        for(BSONObj::iterator cmdIterator = cmdObj.begin();
                cmdIterator.more(); ) {
            BSONElement cmdElement(cmdIterator.next());
            const char *pFieldName = cmdElement.fieldName();

            /* look for the aggregation command */
            if (!strcmp(pFieldName, commandName)) {
                pPipeline->collectionName = cmdElement.String();
                continue;
            }

            /* check for the collection name */
            if (!strcmp(pFieldName, pipelineName)) {
                pipeline = cmdElement.Array();
                continue;
            }

            /* check for explain option */
            if (!strcmp(pFieldName, explainName)) {
                pPipeline->explain = cmdElement.Bool();
                continue;
            }

            /* if the request came from the router, we're in a shard */
            if (!strcmp(pFieldName, fromRouterName)) {
                pCtx->setInShard(cmdElement.Bool());
                continue;
            }

            /* check for debug options */
            if (!strcmp(pFieldName, splitMongodPipelineName)) {
                pPipeline->splitMongodPipeline = true;
                continue;
            }

            /* Ignore $auth information sent along with the command. The authentication system will
             * use it, it's not a part of the pipeline.
             */
            if (!strcmp(pFieldName, AuthenticationTable::fieldName.c_str())) {
                continue;
            }

            /* we didn't recognize a field in the command */
            ostringstream sb;
            sb <<
               "unrecognized field \"" <<
               cmdElement.fieldName();
            errmsg = sb.str();
            return intrusive_ptr<Pipeline>();
        }

        /*
          If we get here, we've harvested the fields we expect for a pipeline.

          Set up the specified document source pipeline.
        */
        SourceVector *pSourceVector = &pPipeline->sourceVector; // shorthand

        /* iterate over the steps in the pipeline */
        const size_t nSteps = pipeline.size();
        for(size_t iStep = 0; iStep < nSteps; ++iStep) {
            /* pull out the pipeline element as an object */
            BSONElement pipeElement(pipeline[iStep]);
            uassert(15942, str::stream() << "pipeline element " <<
                    iStep << " is not an object",
                    pipeElement.type() == Object);
            BSONObj bsonObj(pipeElement.Obj());

            intrusive_ptr<DocumentSource> pSource;

            /* use the object to add a DocumentSource to the processing chain */
            BSONObjIterator bsonIterator(bsonObj);
            while(bsonIterator.more()) {
                BSONElement bsonElement(bsonIterator.next());
                const char *pFieldName = bsonElement.fieldName();

                /* select the appropriate operation and instantiate */
                StageDesc key;
                key.pName = pFieldName;
                const StageDesc *pDesc = (const StageDesc *)
                    bsearch(&key, stageDesc, nStageDesc, sizeof(StageDesc),
                            stageDescCmp);
                if (pDesc) {
                    pSource = (*pDesc->pFactory)(&bsonElement, pCtx);
                    pSource->setPipelineStep(iStep);
                }
                else {
                    ostringstream sb;
                    sb <<
                       "Pipeline::run(): unrecognized pipeline op \"" <<
                       pFieldName;
                    errmsg = sb.str();
                    return intrusive_ptr<Pipeline>();
                }
            }

            pSourceVector->push_back(pSource);
        }

        /* if there aren't any pipeline stages, there's nothing more to do */
        if (!pSourceVector->size())
            return pPipeline;

        /*
          Move filters up where possible.

          CW TODO -- move filter past projections where possible, and noting
          corresponding field renaming.
        */

        /*
          Wherever there is a match immediately following a sort, swap them.
          This means we sort fewer items.  Neither changes the documents in
          the stream, so this transformation shouldn't affect the result.

          We do this first, because then when we coalesce operators below,
          any adjacent matches will be combined.
         */
        for(size_t srcn = pSourceVector->size(), srci = 1;
            srci < srcn; ++srci) {
            intrusive_ptr<DocumentSource> &pSource = pSourceVector->at(srci);
            if (dynamic_cast<DocumentSourceMatch *>(pSource.get())) {
                intrusive_ptr<DocumentSource> &pPrevious =
                    pSourceVector->at(srci - 1);
                if (dynamic_cast<DocumentSourceSort *>(pPrevious.get())) {
                    /* swap this item with the previous */
                    intrusive_ptr<DocumentSource> pTemp(pPrevious);
                    pPrevious = pSource;
                    pSource = pTemp;
                }
            }
        }

        /* Move limits in front of skips. This is more optimal for sharding
         * since currently, we can only split the pipeline at a single source
         * and it is better to limit the results coming from each shard
         */
        for(int i = pSourceVector->size() - 1; i >= 1 /* not looking at 0 */; i--) {
            DocumentSourceLimit* limit =
                dynamic_cast<DocumentSourceLimit*>((*pSourceVector)[i].get());
            DocumentSourceSkip* skip =
                dynamic_cast<DocumentSourceSkip*>((*pSourceVector)[i-1].get());
            if (limit && skip) {
                // Increase limit by skip since the skipped docs now pass through the $limit
                limit->setLimit(limit->getLimit() + skip->getSkip());
                swap((*pSourceVector)[i], (*pSourceVector)[i-1]);

                // Start at back again. This is needed to handle cases with more than 1 $limit
                // (S means skip, L means limit)
                //
                // These two would work without second pass (assuming back to front ordering)
                // SL   -> LS
                // SSL  -> LSS
                //
                // The following cases need a second pass to handle the second limit
                // SLL  -> LLS
                // SSLL -> LLSS
                // SLSL -> LLSS
                i = pSourceVector->size(); // decremented before next pass
            }
        }

        /*
          Coalesce adjacent filters where possible.  Two adjacent filters
          are equivalent to one filter whose predicate is the conjunction of
          the two original filters' predicates.  For now, capture this by
          giving any DocumentSource the option to absorb it's successor; this
          will also allow adjacent projections to coalesce when possible.

          Run through the DocumentSources, and give each one the opportunity
          to coalesce with its successor.  If successful, remove the
          successor.

          Move all document sources to a temporary list.
        */
        SourceVector tempVector(*pSourceVector);
        pSourceVector->clear();

        /* move the first one to the final list */
        pSourceVector->push_back(tempVector[0]);

        /* run through the sources, coalescing them or keeping them */
        for(size_t tempn = tempVector.size(), tempi = 1;
            tempi < tempn; ++tempi) {
            /*
              If we can't coalesce the source with the last, then move it
              to the final list, and make it the new last.  (If we succeeded,
              then we're still on the same last, and there's no need to move
              or do anything with the source -- the destruction of tempVector
              will take care of the rest.)
            */
            intrusive_ptr<DocumentSource> &pLastSource = pSourceVector->back();
            intrusive_ptr<DocumentSource> &pTemp = tempVector.at(tempi);
            if (!pTemp || !pLastSource) {
                errmsg = "Pipeline received empty document as argument";
                return intrusive_ptr<Pipeline>();
            }
            if (!pLastSource->coalesce(pTemp))
                pSourceVector->push_back(pTemp);
        }

        /* optimize the elements in the pipeline */
        for(SourceVector::iterator iter(pSourceVector->begin()),
                listEnd(pSourceVector->end()); iter != listEnd; ++iter) {
            if (!*iter) {
                errmsg = "Pipeline received empty document as argument";
                return intrusive_ptr<Pipeline>();
            }

            (*iter)->optimize();
        }

        return pPipeline;
    }