Example #1
0
void srTGenTrjDat::CompTrjKickMatr(SRWLKickM* arKickM, int nKickM, double sStart, double sEnd, long ns, double* pInPrecPar, double* pOutBtX, double* pOutX, double* pOutBtY, double* pOutY, double* pOutBtZ, double* pOutZ)
{
	if((arKickM == 0) || (nKickM <= 0)) throw SRWL_INCORRECT_PARAM_FOR_TRJ_COMP;
	if(ns <= 0) throw SRWL_INCORRECT_PARAM_FOR_TRJ_COMP;

	//sort arKickM to find groups of kick-matrices with non-overlapping longitudinal intervals
	vector<pair<int, pair<double, double> > > vKickStInd;
	SRWLKickM *t_arKickM = arKickM;
	for(int i=0; i<nKickM; i++)
	{
		double curHalfRange = 0.5*t_arKickM->rz;
		pair<double, double> curRange(t_arKickM->z - curHalfRange, t_arKickM->z + curHalfRange);
		pair<int, pair<double, double> > curPair(i, curRange);
		vKickStInd.push_back(curPair);
	}

	sort(vKickStInd.begin(), vKickStInd.end(), CAuxParse::LessInPairBasedOnFirstInNestedPair<int, double, double>);

	vector<vector<int> > vIndNonOverlapKickGroups;
	vector<pair<double, double> > vIndNonOverlapKickGroupRanges;
	vector<int> vIndKickM;
	vIndKickM.push_back(vKickStInd[0].first);
	double curGroupStart = vKickStInd[0].second.first;
	double curGroupEnd = vKickStInd[0].second.second;
	for(int j=1; j<nKickM; j++)
	{
		double newStart = vKickStInd[j].second.first;
		double newEnd = vKickStInd[j].second.second;

		if((newEnd <= curGroupStart) || (newStart >= curGroupEnd))
		{//end current group
			vIndNonOverlapKickGroups.push_back(vIndKickM);
			pair<double, double> curRange(curGroupStart, curGroupEnd);
			vIndNonOverlapKickGroupRanges.push_back(curRange);

			vIndKickM.erase(vIndKickM.begin(), vIndKickM.end());
			curGroupStart = newStart;
			curGroupEnd = newEnd;
		}
		else
		{//continue stuffing current group
			vIndKickM.push_back(vKickStInd[j].first);
			if(curGroupStart > newStart) curGroupStart = newStart;
			if(curGroupEnd < newEnd) curGroupEnd = newEnd;
		}
	}
	if(!vIndKickM.empty()) 
	{
		vIndNonOverlapKickGroups.push_back(vIndKickM);
		pair<double, double> curRange(curGroupStart, curGroupEnd);
		vIndNonOverlapKickGroupRanges.push_back(curRange);

		vIndKickM.erase(vIndKickM.begin(), vIndKickM.end());
	}
	//sorting completed

	bool trjShouldBeAdded = (pInPrecPar[0] == 1);
	const double sResEdgeToler = 1.E-12;
	double sAbsEdgeToler = (sEnd - sStart)*sResEdgeToler;
	bool integOnLeftIsNeeded = (sStart < -sAbsEdgeToler);
	bool integOnRightIsNeeded = (sEnd > sAbsEdgeToler);

	double sStep = (ns <= 1)? 0 : (sEnd - sStart)/(ns - 1);
	double initCond[] = {EbmDat.x0, EbmDat.dxds0, EbmDat.z0, EbmDat.dzds0, EbmDat.s0}; //?
	double inv_B_pho = EbmDat.Inv_B_rho(); //[1/(T*m)]

	double gamEm2 = EbmDat.GammaEm2, btx, bty;
	long is0 = 0;
	double s0Act = 0.;

	if(integOnLeftIsNeeded)
	{
		double *tOutBtX = pOutBtX, *tOutX = pOutX;
		double *tOutBtY = pOutBtY, *tOutY = pOutY;
		double *tOutBtZ = pOutBtZ, *tOutZ = pOutZ;
		
		if(sEnd < -sAbsEdgeToler) //i.e. < 0
		{//need to "arrive" to sEnd without storing trajectory data; step can be re-adjusted
			long auxNp = (long)fabs(sEnd/sStep) + 1;
			if(auxNp <= 1) auxNp = 2;

			double *auxTrjRes = new double[(auxNp + ns)*5];
			if(auxTrjRes == 0) throw MEMORY_ALLOCATION_FAILURE;

			IntegrateKicks(arKickM, vIndNonOverlapKickGroups, vIndNonOverlapKickGroupRanges, inv_B_pho, initCond, 0., sEnd, auxNp, auxTrjRes);
			//gmIntRK.solve(initCond, 0., sMax, auxNp, auxTrjRes);

			double *pResEnd = auxTrjRes + (auxNp - 1)*5;
			for(int i=0; i<5; i++) initCond[i] = pResEnd[i];

			//arrived to sMax; now solve for the entire main trajectory:
			if(ns <= 1)
			{
				double *t_auxTrjRes = auxTrjRes;
				for(int i=0; i<5; i++) *(t_auxTrjRes++) = initCond[i];
			}
			else IntegrateKicks(arKickM, vIndNonOverlapKickGroups, vIndNonOverlapKickGroupRanges, inv_B_pho, initCond, sEnd, sStart, ns, auxTrjRes);
			//else gmIntRK.solve(initCond, sMax, sMin, ns, auxTrjRes);

			double *t_auxTrjRes = auxTrjRes + (ns*5 - 1);
			for(int j=0; j<ns; j++)
			{
				if(trjShouldBeAdded)
				{
					//if(pOutZ) *(tOutZ++) += *t_auxTrjRes; //longitudinal position is not modified in this case
					t_auxTrjRes--;
					*tOutBtY += *(t_auxTrjRes--); bty = *(tOutBtY++);
					*(tOutY++) += *(t_auxTrjRes--);
					*tOutBtX += *(t_auxTrjRes--); btx = *(tOutBtX++);
					*(tOutX++) += *(t_auxTrjRes--);
					if(pOutBtZ) *(tOutBtZ++) = CGenMathMeth::radicalOnePlusSmall(-(gamEm2 + btx*btx + bty*bty));
				}
				else
				{
					if(pOutZ) *(tOutZ++) = *t_auxTrjRes;
					t_auxTrjRes--;
					bty = *(t_auxTrjRes--); *(tOutBtY++) = bty;
					*(tOutY++) = *(t_auxTrjRes--);
					btx = *(t_auxTrjRes--); *(tOutBtX++) = btx;
					*(tOutX++) = *(t_auxTrjRes--);
					if(pOutBtZ) *(tOutBtZ++) = CGenMathMeth::radicalOnePlusSmall(-(gamEm2 + btx*btx + bty*bty));
				}
			}
			delete[] auxTrjRes;
		}
		else
		{
			is0 = (int)fabs((-sStart + sAbsEdgeToler)/sStep);
			if(is0 >= ns) is0 = ns - 1;

			s0Act = sStart + is0*sStep;
			if(s0Act < -sAbsEdgeToler)
			{//one small step to s0Act
				double twoPtTrjRes[2*5];
				IntegrateKicks(arKickM, vIndNonOverlapKickGroups, vIndNonOverlapKickGroupRanges, inv_B_pho, initCond, 0., s0Act, 2, twoPtTrjRes);
				//gmIntRK.solve(initCond, 0., s0Act, 2, twoPtTrjRes);

				double *pResEnd = twoPtTrjRes + 5;
				for(int i=0; i<5; i++) initCond[i] = pResEnd[i];
			}

			//arrived to s0Act; now solve for the left part of the trajectory:
			int nsLeft = is0 + 1;
			double *auxTrjRes = new double[nsLeft*5];
			if(auxTrjRes == 0) throw MEMORY_ALLOCATION_FAILURE;
	
			if(nsLeft <= 1)
			{
				double *t_auxTrjRes = auxTrjRes;
				//*(t_auxTrjRes++) = s0Act;
				for(int i=0; i<5; i++) *(t_auxTrjRes++) = initCond[i];
			}
			else IntegrateKicks(arKickM, vIndNonOverlapKickGroups, vIndNonOverlapKickGroupRanges, inv_B_pho, initCond, s0Act, sStart, nsLeft, auxTrjRes);
			//else gmIntRK.solve(initCond, s0Act, sMin, nsLeft, auxTrjRes);

			double *t_auxTrjRes = auxTrjRes + nsLeft*5 - 1;
			for(int j=0; j<nsLeft; j++)
			{
				if(trjShouldBeAdded)
				{
					//if(pOutZ) *(tOutZ++) += *t_auxTrjRes; //longitudinal position is not modified in this case
					t_auxTrjRes--;
					*tOutBtY += *(t_auxTrjRes--); bty = *(tOutBtY++);
					*(tOutY++) += *(t_auxTrjRes--);
					*tOutBtX += *(t_auxTrjRes--); btx = *(tOutBtX++);
					*(tOutX++) += *(t_auxTrjRes--);
					if(pOutBtZ) *(tOutBtZ++) = CGenMathMeth::radicalOnePlusSmall(-(gamEm2 + btx*btx + bty*bty));
				}
				else
				{
					if(pOutZ) *(tOutZ++) = *t_auxTrjRes;
					t_auxTrjRes--;
					bty = *(t_auxTrjRes--); *(tOutBtY++) = bty;
					*(tOutY++) = *(t_auxTrjRes--);
					btx = *(t_auxTrjRes--); *(tOutBtX++) = btx;
					*(tOutX++) = *(t_auxTrjRes--);
					if(pOutBtZ) *(tOutBtZ++) = CGenMathMeth::radicalOnePlusSmall(-(gamEm2 + btx*btx + bty*bty));
				}
			}
			delete[] auxTrjRes;
		}
	}

	if(integOnRightIsNeeded)
	{
		double *tOutBtX = pOutBtX + is0, *tOutX = pOutX + is0;
		double *tOutBtY = pOutBtY + is0, *tOutY = pOutY + is0;
		double *tOutBtZ = pOutBtZ + is0, *tOutZ = pOutZ + is0;

		if(sStart > sAbsEdgeToler)
		{//need to "arrive" to sMin without storing trajectory data; step can be re-adjusted
			int auxNp = (int)fabs(sStart/sStep) + 1;
			if(auxNp <= 1) auxNp = 2;

			double *auxTrjRes = new double[(auxNp + ns)*5];
			if(auxTrjRes == 0) throw MEMORY_ALLOCATION_FAILURE;

			IntegrateKicks(arKickM, vIndNonOverlapKickGroups, vIndNonOverlapKickGroupRanges, inv_B_pho, initCond, 0., sStart, auxNp, auxTrjRes);
			//gmIntRK.solve(initCond, 0., sMin, auxNp, auxTrjRes);

			double *pResEnd = auxTrjRes + (auxNp - 1)*5;
			for(int i=0; i<5; i++) initCond[i] = pResEnd[i];

			//arrived to sMax; now solve for the entire main trajectory:
			if(ns <= 1)
			{
				double *t_auxTrjRes = auxTrjRes;
				//*(t_auxTrjRes++) = sMin;
				for(int i=0; i<5; i++) *(t_auxTrjRes++) = initCond[i];
			}
			else IntegrateKicks(arKickM, vIndNonOverlapKickGroups, vIndNonOverlapKickGroupRanges, inv_B_pho, initCond, sStart, sEnd, ns, auxTrjRes);
			//else gmIntRK.solve(initCond, sMin, sMax, ns, auxTrjRes);

			double *t_auxTrjRes = auxTrjRes;
			for(int j=0; j<ns; j++)
			{
				if(trjShouldBeAdded)
				{
					*(tOutX++) += *(t_auxTrjRes++);
					*tOutBtX += *(t_auxTrjRes++); btx = *(tOutBtX++);
					*(tOutY++) += *(t_auxTrjRes++);
					*tOutBtY += *(t_auxTrjRes++); bty = *(tOutBtY++);
					//if(pOutZ) *(tOutZ++) += *t_auxTrjRes; //longitudinal position is not modified in this case
					t_auxTrjRes++;
					if(pOutBtZ) *(tOutBtZ++) = CGenMathMeth::radicalOnePlusSmall(-(gamEm2 + btx*btx + bty*bty));
				}
				else
				{
					*(tOutX++) = *(t_auxTrjRes++);
					btx = *(t_auxTrjRes++); *(tOutBtX++) = btx;
					*(tOutY++) = *(t_auxTrjRes++);
					bty = *(t_auxTrjRes++); *(tOutBtY++) = bty;
					if(pOutZ) *(tOutZ++) = *t_auxTrjRes;
					t_auxTrjRes++;
					if(pOutBtZ) *(tOutBtZ++) = CGenMathMeth::radicalOnePlusSmall(-(gamEm2 + btx*btx + bty*bty));
				}
			}
			delete[] auxTrjRes;
		}
		else
		{
			//normally, initial conditions should be already set here
			int nsRight = ns - is0;
			if(nsRight < 1) nsRight = 1;
			double *auxTrjRes = new double[nsRight*5];
			if(auxTrjRes == 0) throw MEMORY_ALLOCATION_FAILURE;

			if(nsRight <= 1)
			{
				double *t_auxTrjRes = auxTrjRes;
				//*(t_auxTrjRes++) = s0Act;
				for(int i=0; i<5; i++) *(t_auxTrjRes++) = initCond[i];
			}
			//s0Act has been defined above!
			else IntegrateKicks(arKickM, vIndNonOverlapKickGroups, vIndNonOverlapKickGroupRanges, inv_B_pho, initCond, s0Act, sEnd, nsRight, auxTrjRes);
			//else gmIntRK.solve(initCond, s0Act, sMax, nsRight, auxTrjRes);

			double *t_auxTrjRes = auxTrjRes;
			for(int j=0; j<nsRight; j++)
			{
				if(trjShouldBeAdded)
				{
					*(tOutX++) += *(t_auxTrjRes++);
					*tOutBtX += *(t_auxTrjRes++); btx = *(tOutBtX++);
					*(tOutY++) += *(t_auxTrjRes++);
					*tOutBtY += *(t_auxTrjRes++); bty = *(tOutBtY++);
					//if(pOutZ) *(tOutZ++) += *t_auxTrjRes; //longitudinal position is not modified in this case
					t_auxTrjRes++;
					if(pOutBtZ) *(tOutBtZ++) = CGenMathMeth::radicalOnePlusSmall(-(gamEm2 + btx*btx + bty*bty));
				}
				else
				{
					*(tOutX++) = *(t_auxTrjRes++);
					btx = *(t_auxTrjRes++); *(tOutBtX++) = btx;
					*(tOutY++) = *(t_auxTrjRes++);
					bty = *(t_auxTrjRes++); *(tOutBtY++) = bty;
					if(pOutZ) *(tOutZ++) = *t_auxTrjRes;
					t_auxTrjRes++;
					if(pOutBtZ) *(tOutBtZ++) = CGenMathMeth::radicalOnePlusSmall(-(gamEm2 + btx*btx + bty*bty));
				}
			}
			delete[] auxTrjRes;
		}
	}
}
Example #2
0
lasp::svm_model lasp::get_model_from_solved_problems(vector<lasp::svm_problem> solvedProblems,
													 vector<lasp::svm_sparse_data> holdoutData,
													 vector<int> orderSeen)
{
	
	svm_model returnModel;
	returnModel.orderSeen = orderSeen;
	//First, we need to fill up returnMode.idMap by assigning an id to each support vector
	
	//First, we will create a mapping from {class1 -> {class2 -> 1vs2}}
	//where we saw class1 before class2 and 1vs2 is an svm_problem that represents
	//the solution to pitting class1 against class2.
	map<int, map<int, svm_problem> > comparisonMapping;
	
	for(int i = 0; i < solvedProblems.size(); ++i) {
		int c1 = solvedProblems[i].classifications[0];
		int c2 = solvedProblems[i].classifications[1];
		//Enforce that the model contains all classes
		returnModel.modelData[c1];
		returnModel.modelData[c2];
		int c1ind = -1;
		int c2ind = -1;
		for(int j = 0; j < orderSeen.size(); ++j) {
			if(c1 == orderSeen[j]) c1ind = j;
			else if(c2 == orderSeen[j]) c2ind = j;
		}
		//swap to make sure we're indexing our map correctly
		if(c1ind > c2ind) {
			int temp = c1;
			c1 = c2;
			c2 = temp;
		}
		
		comparisonMapping[c1][c2] = solvedProblems[i];
	}
	
	//Now that we have the mapping and the sorted list of classes we've seen, we can
	//begin to fill in the model.
	
	//This assumes that we have at least one solved problem
	//this is pretty ugly, there's definitely a better way to do this.
	returnModel.kernelType = solvedProblems[0].options.kernel;
	returnModel.numFeatures = solvedProblems[0].features;
	returnModel.degree = solvedProblems[0].options.degree;
	returnModel.coef = solvedProblems[0].options.coef;
	returnModel.gamma = solvedProblems[0].options.gamma;
    
    //(Yu) using the assumption before, this keeps the means and standard deviation of training data in the model
    returnModel.means = solvedProblems[0].means;
    returnModel.standardDeviations = solvedProblems[0].standardDeviations;
    
	//Here's the big data-copy loop.
	for(int i = 0; i < orderSeen.size(); ++i) {
		for(int j = i+1; j < orderSeen.size(); ++j) {
			int c1, c2;
			c1 = orderSeen[i]; c2 = orderSeen[j];
			
			svm_problem currentProblem = comparisonMapping[c1][c2];
			returnModel.offsets[c1][c2] = currentProblem.bs.back();
			//Now, let's extract the support vectors from each class
			vector<vector<svm_node> > classOneSV;
			vector<vector<svm_node> > classTwoSV;
			vector<double> classOneBetas;
			vector<double> classTwoBetas;
			
			for(int k = 0; k < currentProblem.S.size(); ++k) {
				int curClassification = currentProblem.y[currentProblem.S[k]] == 1 ?
				currentProblem.classifications[0]
				: currentProblem.classifications[1];
				
				vector<svm_node> currentSupportVector;
				//Note that svm_nodes are indexed from 1.
				for(int x = 0; x < currentProblem.features; ++x) {
					double value = currentProblem.xS[k*currentProblem.features+x];
					if(fabs(value) > 1E-20) {
						svm_node newNode;
						newNode.index = x + 1;
						newNode.value = value;
						//cout << newNode.index << "," << newNode.value << endl;
						currentSupportVector.push_back(newNode);
					}
				}
				
				//we have reconstructed the sparse representation of a given support vector,
				//now we just need to put it into the correct list of support vectors
				if(curClassification == c1) {
					classOneSV.push_back(currentSupportVector);
					classOneBetas.push_back(currentProblem.betas.back()[k]);
				}
				else { //assume it's in class two.
					classTwoSV.push_back(currentSupportVector);
					classTwoBetas.push_back(currentProblem.betas.back()[k]);
				}
				
			}
			
			//we now have two vectors containing the sparse representations for each class
			//and two more vectors representing the corresponding beta values.
			//Now, we need to put the data into the svm_model's modelData.
			
			typedef map<vector<svm_node>, map<int, double>, CompareSparseVectors>::iterator MyIter;
			
			for(int k = 0; k < classOneSV.size(); ++k) {
				returnModel.modelData[c1][classOneSV[k]][c2] += classOneBetas[k];
			}
			for(int k = 0; k < classTwoSV.size(); ++k) {
				returnModel.modelData[c2][classTwoSV[k]][c1] += classTwoBetas[k];
			}
			
			//TODO: This should probably be referenced counted or something
			delete [] currentProblem.xS;
			currentProblem.xS = 0;
		}
		
	}
	
	returnModel.plattScale = (holdoutData.size() != 0);
	if(returnModel.plattScale) {
		//now, we train the sigmoid parameters.
		//First, lets create a mapping from {c1 -> {c2 -> holdout data}}
		//where we saw c1 before c2.
		map<int, map<int, svm_sparse_data> > holdoutMapping;
		for(int i = 0; i < holdoutData.size(); ++i) {
			vector<int> holdoutClasses;
			svm_sparse_data curHoldout = holdoutData[i];
			for(map<int, vector<vector<svm_node> > >::iterator iter = curHoldout.allData.begin();
				iter != curHoldout.allData.end();
				++iter) {
				holdoutClasses.push_back(iter->first);
			}
			if(holdoutClasses.size() != 2) cout << "holdout data had more/less than 2 classes." << endl;
			int c1 = holdoutClasses[0];
			int c2 = holdoutClasses[1];
			int c1ind = -1;
			int c2ind = -1;
			for(int j = 0; j < orderSeen.size(); ++j) {
				if(c1 == orderSeen[j]) c1ind = j;
				else if(c2 == orderSeen[j]) c2ind = j;
			}
			//swap to make sure we're indexing our map correctly
			if(c1ind > c2ind) {
				int temp = c1;
				c1 = c2;
				c2 = temp;
			}
			holdoutMapping[c1][c2] = curHoldout;
		}
		
		for(int i = 0; i < orderSeen.size(); ++i) {
			for(int j = i + 1; j < orderSeen.size(); ++j) {
				svm_sparse_data curHoldout = holdoutMapping[orderSeen[i]][orderSeen[j]];
				pair<double, double> curPair(1.0, 1.0); //= get_optimal_sigmoid_parameters(curHoldout, returnModel);
				returnModel.plattScaleCoefs[orderSeen[i]][orderSeen[j]] = curPair;
			}
		}
	}
	
	//Assume all problems were trained the same way
	returnModel.pegasos = solvedProblems[0].options.pegasos && solvedProblems[0].options.usebias && solvedProblems[0].options.bias != 0;
	
	return returnModel;
}