⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gsmmlse.c

📁 基于MATLAB的GSM仿真系统 并附有直接画出性能曲线的简化程序。
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************/
int  GSMMVA_FSM(int currentState,int possibleData)
{
	int temp_possibleData;
	int temp_currentState;
	int nextState;
	
	temp_currentState = (currentState<<1);
	temp_currentState = (temp_currentState&0x0000003f);
	temp_possibleData = (possibleData&0x00000001);
	nextState = (temp_currentState|temp_possibleData);
	
	return nextState;
}

/****************************************
/Compute Inc Metric for each path
/****************************************/
/*double  GSMMVA_IncMetric(int cnt,int dataHistory[CHANNELMEMLEN],
       double gEstArray[2][CHANNELMEMLEN],double yArray[2][BURSTLEN])
{
	double RetPart1,RetPart2_1,RetPart2_2;
	double sigHistory[2][CHANNELMEMLEN];
	double tempComplx[2][1],tempSig[2];
	double RetValue;
	int i;
	
	//Signal Mapping
	for (i = 0;i<CHANNELMEMLEN;i++)
	{
		if (i<=cnt)
		{
			GSMMVA_SigMap(dataHistory[i],tempSig);
			sigHistory[0][i] = tempSig[0];
			sigHistory[1][i] = tempSig[1];
		}
	}
	
	//YH(n)
	RetPart2_1 = 0;
	RetPart2_2 = 0;
	for (i = 0;i<CHANNELMEMLEN;i++)
	{
		if (i<=cnt)
		{
			RetPart2_1 = RetPart2_1+gEstArray[0][i]*sigHistory[0][i]-gEstArray[1][i]*sigHistory[1][i];//Re
			RetPart2_2 = RetPart2_2+gEstArray[1][i]*sigHistory[0][i]+gEstArray[0][i]*sigHistory[1][i];//Im
		}
	}

	//MH(n)
	RetValue = -((yArray[0][cnt]-RetPart2_1)*(yArray[0][cnt]-RetPart2_1)
		      +(yArray[1][cnt]-RetPart2_2)*(yArray[1][cnt]-RetPart2_2));
	
	return RetValue;
}
*/


/***************************************
/Modified Viterbi Algorithm
/Core Part
/***************************************/
void  GSMMVA(double yArray[2][BURSTLEN],double xArray[2][CHANNELMEMLEN],int mode,
			 struct GSMMVAState GSMMVATrellis[MVAState][200],struct GSMMVAOut MVAOut[BURSTLEN])
//xArray = gEstArray
{
	int cnt,i,j;//,m,n;
	int tempState;
	int maxPathState;
	int tempMask;
	double incMetric;
	int dataHistory[CHANNELMEMLEN];
	struct GSMMVAOut tempMVAOut[BURSTLEN+CHANNELMEMLEN];    //one for soft,one for hard
	          
	//Initialization
	cnt = 0;
	for (i = 0;i<CHANNELMEMLEN;i++)
	{
		dataHistory[i] = 0;
	}
	for (i = 0;i<200;i++)
	{
		for(j = 0;j<MVAState;j++)
		{
			GSMMVATrellis[j][i].stateNum = j;
			GSMMVATrellis[j][i].totalMetric = 0;
			GSMMVATrellis[j][i].preState1 = ELSEWHERE;
			GSMMVATrellis[j][i].preState2 = ELSEWHERE;
			GSMMVATrellis[j][i].nextState1 = ELSEWHERE;
			GSMMVATrellis[j][i].nextState2 = ELSEWHERE;
			GSMMVATrellis[j][i].timeCount = i;
		}
	}
	GSMMVATrellis[0][0].preState1 = 0;
	GSMMVATrellis[0][0].preState2 = 0;
	
	//Begin From State 0
	while (cnt<=CHANNELMEMLEN)
	{
		for (j = 0;j<MVAState;j++)
		{
			for (i = 0;i<CHANNELMEMLEN;i++)
			{
				dataHistory[i] = 0;
			}
			if ((GSMMVATrellis[j][cnt].preState1!=ELSEWHERE)||(GSMMVATrellis[j][cnt].preState2!=ELSEWHERE))
			{
				GSMMVATrellis[j][cnt].nextState1 = GSMMVA_FSM(GSMMVATrellis[j][cnt].stateNum,0);
				GSMMVATrellis[j][cnt].nextState2 = GSMMVA_FSM(GSMMVATrellis[j][cnt].stateNum,1);
				if (j<(MVAState/2))
				{
					GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].preState1 = GSMMVATrellis[j][cnt].stateNum;
					GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].preState1 = GSMMVATrellis[j][cnt].stateNum;
				}
				if (j>=(MVAState/2))
				{
					GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].preState2 = GSMMVATrellis[j][cnt].stateNum;
					GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].preState2 = GSMMVATrellis[j][cnt].stateNum;
				}
			
				//Compute Metric
				//Construct dataHistory
				if (cnt>0)
				{
					tempMask = 0x00000001;
					for (i = 1;i<CHANNELMEMLEN;i++)
					{
						dataHistory[i] = ((GSMMVATrellis[j][cnt].stateNum)&tempMask)>>(i-1);
						tempMask = (tempMask<<1);		
					}
				}
				//Case1 - Move 0 into dataHistory[0],others shift right				
				dataHistory[0] = 0;
				incMetric = GSMMVA_IncMetric(cnt,dataHistory,xArray,yArray);
				if (j<(MVAState/2))
				{
					GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].totalMetric1
					=GSMMVATrellis[j][cnt].totalMetric+incMetric;
					GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].totalMetric 
					= GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].totalMetric1;
				}
				if (j>=(MVAState/2))
				{
					GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].totalMetric2
					=GSMMVATrellis[j][cnt].totalMetric+incMetric;
					GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].totalMetric 
					= GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].totalMetric2;
				}
				
				//Case2 - Move 1 into dataHistory[0],others shift right
				dataHistory[0] = 1;
				incMetric = GSMMVA_IncMetric(cnt,dataHistory,xArray,yArray);
				if (j<(MVAState/2))
				{
					GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].totalMetric1
					=GSMMVATrellis[j][cnt].totalMetric+incMetric;
					GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].totalMetric 
					= GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].totalMetric1;
				}
				if (j>=(MVAState/2))
				{
					GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].totalMetric2
					=GSMMVATrellis[j][cnt].totalMetric+incMetric;
					GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].totalMetric 
					= GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].totalMetric2;
				}
			}
		}
		cnt++;
		//For Debug
/*		if (cnt<4)
		{
			printf("cnt:%d ",cnt);
			for (j = 0;j<pow(2,cnt);j++)
			{
				if ((int)GSMMVATrellis[j][cnt].totalMetric == 0)
				{
					printf("%d ",GSMMVATrellis[j][cnt].stateNum);
					if (GSMMVATrellis[j][cnt].stateNum%2 != GSMFrame[cnt-1])
					{
						printf("ERROR!!!!!!!!\n");
					}
					else
					{
						printf("PASS!!!!!\n");
					}
				}
			}
		}
*/
	}
	
	//For debug
/*	for (i = 0;i<MVAState;i++)
	{
		printf("%d  pre1:%d pre2:%d next1:%d next2:%d met1:%f met2:%f tot:%f\n",i,
			GSMMVATrellis[i][cnt].preState1,GSMMVATrellis[i][cnt].preState2,
			GSMMVATrellis[i][cnt].nextState1,GSMMVATrellis[i][cnt].nextState2,
			GSMMVATrellis[i][cnt].totalMetric1,GSMMVATrellis[i][cnt].totalMetric2,
			GSMMVATrellis[i][cnt].totalMetric);
	}
*/
	//Add,Compare,Choose
	while ((cnt>CHANNELMEMLEN)&&(cnt<BURSTLEN))
	{
		for (j = 0;j<MVAState;j++)
		{
			//Compare and Choose
			if (GSMMVATrellis[j][cnt].totalMetric1>=GSMMVATrellis[j][cnt].totalMetric2)
			{
				GSMMVATrellis[j][cnt].totalMetric = GSMMVATrellis[j][cnt].totalMetric1;
				if ((j%2)==0)
				{
					GSMMVATrellis[GSMMVATrellis[j][cnt].preState2][cnt-1].nextState1 = ELSEWHERE;
				}
				if ((j%2)==1)
				{
					GSMMVATrellis[GSMMVATrellis[j][cnt].preState2][cnt-1].nextState2 = ELSEWHERE;
				}
				GSMMVATrellis[j][cnt].preState2 = ELSEWHERE;
			}
			if (GSMMVATrellis[j][cnt].totalMetric1<GSMMVATrellis[j][cnt].totalMetric2)
			{
				GSMMVATrellis[j][cnt].totalMetric = GSMMVATrellis[j][cnt].totalMetric2;
				if ((j%2)==0)
				{
					GSMMVATrellis[GSMMVATrellis[j][cnt].preState1][cnt-1].nextState1 = ELSEWHERE;
				}
				if ((j%2)==1)
				{
					GSMMVATrellis[GSMMVATrellis[j][cnt].preState1][cnt-1].nextState2 = ELSEWHERE;
				}
				GSMMVATrellis[j][cnt].preState1 = ELSEWHERE;
			}
			
			//Add
			GSMMVATrellis[j][cnt].nextState1 = GSMMVA_FSM(GSMMVATrellis[j][cnt].stateNum,0);
			GSMMVATrellis[j][cnt].nextState2 = GSMMVA_FSM(GSMMVATrellis[j][cnt].stateNum,1);
			if (j<(MVAState/2))
			{
				GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].preState1 = GSMMVATrellis[j][cnt].stateNum;
				GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].preState1 = GSMMVATrellis[j][cnt].stateNum;
			}
			if (j>=(MVAState/2))
			{
				GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].preState2 = GSMMVATrellis[j][cnt].stateNum;
				GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].preState2 = GSMMVATrellis[j][cnt].stateNum;
			}
			
			//Compute Metric
			//Construct dataHistory
			if (cnt>0)
				{
					tempMask = 0x00000001;
					for (i = 1;i<CHANNELMEMLEN;i++)
					{
						dataHistory[i] = ((GSMMVATrellis[j][cnt].stateNum)&tempMask)>>(i-1);
						tempMask = (tempMask<<1);		
					}
				}
			//Case1 - Move 0 into dataHistory[0],others shift right				
			dataHistory[0] = 0;
			incMetric = GSMMVA_IncMetric(cnt,dataHistory,xArray,yArray);
			if (j<(MVAState/2))
			{
				GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].totalMetric1
				=GSMMVATrellis[j][cnt].totalMetric+incMetric;
			}
			if (j>=(MVAState/2))
			{
				GSMMVATrellis[GSMMVATrellis[j][cnt].nextState1][cnt+1].totalMetric2
				=GSMMVATrellis[j][cnt].totalMetric+incMetric;
			}
				
			//Case2 - Move 1 into dataHistory[0],others shift right
			dataHistory[0] = 1;
			incMetric = GSMMVA_IncMetric(cnt,dataHistory,xArray,yArray);
			if (j<(MVAState/2))
			{
				GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].totalMetric1
				=GSMMVATrellis[j][cnt].totalMetric+incMetric;
			}
			if (j>=(MVAState/2))
			{
				GSMMVATrellis[GSMMVATrellis[j][cnt].nextState2][cnt+1].totalMetric2
				=GSMMVATrellis[j][cnt].totalMetric+incMetric;
			}
			
		}//end of for j=0~31

		//For debug
/*		printf("cnt:%d /////////////////////////////\n",cnt);
		for (i = 0;i<MVAState;i++)
		{
			printf("%d  pre1:%d pre2:%d next1:%d next2:%d met1:%f met2:%f tot:%f\n",i,
			GSMMVATrellis[i][cnt].preState1,GSMMVATrellis[i][cnt].preState2,
			GSMMVATrellis[i][cnt].nextState1,GSMMVATrellis[i][cnt].nextState2,
			GSMMVATrellis[i][cnt].totalMetric1,GSMMVATrellis[i][cnt].totalMetric2,
			GSMMVATrellis[i][cnt].totalMetric);
		}
*/
		if ((cnt >30)&&(mode==1))
		{
			//GSMMVA_Goback;
		}
		//For Debug
/*		printf("cnt:%d ",cnt);
		for (j = 0;j<MVAState;j++)
			{
				if ((int)GSMMVATrellis[j][cnt].totalMetric == 0)
				{
					printf("%d ",GSMMVATrellis[j][cnt].stateNum);
					if (GSMMVATrellis[j][cnt].stateNum%2 != GSMFrame[cnt-1])
					{
						printf("ERROR!!!!!!!!\n");
					}
					else
					{
						printf("PASS!!!!!\n");
					}
				}
			}
*/		
		cnt++;
	}//end of while

	
	//In the end,Converge
	for (j = 0;j<(MVAState);j++)
		{
			if ((GSMMVATrellis[j][cnt].preState1!=ELSEWHERE)||(GSMMVATrellis[j][cnt].preState2!=ELSEWHERE))
			{
				//Compare and Choose
				if ((GSMMVATrellis[j][cnt].totalMetric1)>=(GSMMVATrellis[j][cnt].totalMetric2))
				{
					GSMMVATrellis[j][cnt].totalMetric = GSMMVATrellis[j][cnt].totalMetric1;
					if ((j%2)==0)
					{
						GSMMVATrellis[GSMMVATrellis[j][cnt].preState2][cnt-1].nextState1 = ELSEWHERE;
					}
					if ((j%2)==1)
					{
						GSMMVATrellis[GSMMVATrellis[j][cnt].preState2][cnt-1].nextState2 = ELSEWHERE;
					}
					GSMMVATrellis[j][cnt].preState2 = ELSEWHERE;
				}
				if (GSMMVATrellis[j][cnt].totalMetric1<GSMMVATrellis[j][cnt].totalMetric2)
				{
					GSMMVATrellis[j][cnt].totalMetric = GSMMVATrellis[j][cnt].totalMetric2;
					if ((j%2)==0)
					{
						GSMMVATrellis[GSMMVATrellis[j][cnt].preState1][cnt-1].nextState1 = ELSEWHERE;
					}
					if ((j%2)==1)
					{
						GSMMVATrellis[GSMMVATrellis[j][cnt].preState1][cnt-1].nextState2 = ELSEWHERE;
					}
					GSMMVATrellis[j][cnt].preState1 = ELSEWHERE;
				}
			}
	}

	//For debug
	/*printf("cnt:%d /////////////////////////////\n",cnt);
	for (i = 0;i<MVAState;i++)
	{
		printf("%d  pre1:%d pre2:%d next1:%d next2:%d met1:%f met2:%f tot:%f\n",i,
		GSMMVATrellis[i][cnt].preState1,GSMMVATrellis[i][cnt].preState2,
		GSMMVATrellis[i][cnt].nextState1,GSMMVATrellis[i][cnt].nextState2,
		GSMMVATrellis[i][cnt].totalMetric1,GSMMVATrellis[i][cnt].totalMetric2,
		GSMMVATrellis[i][cnt].totalMetric);
	}*/

	//Terminate
	maxPathState = 0;
	for (j = 1;j<(MVAState);j++)
	{
		if (GSMMVATrellis[j][cnt].totalMetric>GSMMVATrellis[maxPathState][cnt].totalMetric)
		{
			maxPathState = GSMMVATrellis[j][cnt].stateNum;
		}
	}

	//For debug
/*	for (i = 0;i<32;i++)
	{
		printf("cnt:%d state:%d  pre1:%d pre2:%d next1:%d next2:%d\n",cnt,i,
		GSMMVATrellis[i][cnt].preState1,GSMMVATrellis[i][cnt].preState2,
		GSMMVATrellis[i][cnt].nextState1,GSMMVATrellis[i][cnt].nextState2);
	}
*/	
	//At last,get out all the sequence
	if ((maxPathState%2)==0)
	{
		tempMVAOut[cnt].hard = 0;
	}
	if ((maxPathState%2)==1)
	{
		tempMVAOut[cnt].hard = 1;
	}
	//For Debug
	/*if (tempMVAOut[cnt].hard != GSMFrame[cnt-1])
	{
		printf("ERROR!!!!!!!!\n");
	}
	else
	{
		printf("PASS!!!!!\n");
	}*/

	if (GSMMVATrellis[maxPathState][cnt].preState1!=ELSEWHERE)
	{
		tempState = GSMMVATrellis[maxPathState][cnt].preState1;
	}
	if (GSMMVATrellis[maxPathState][cnt].preState2!=ELSEWHERE)
	{
		tempState = GSMMVATrellis[maxPathState][cnt].preState2;
	}
	//tempMVAOut[cnt].hard = 0;
	for (i = cnt-1;i>=1;i--)
	{
		//For Debug
		//printf("i:%d  State:%d  tot:%1.1f ",i,tempState,GSMMVATrellis[tempState][i].totalMetric);
		if ((tempState%2)==0)
		{
			tempMVAOut[i].hard = 0;
		}
		if ((tempState%2)==1)
		{
			tempMVAOut[i].hard = 1;
		}
		//For Debug
		/*if (tempMVAOut[i].hard != GSMFrame[i-1])
		{
			printf("ERROR!!!!!!!!\n");
		}
		else
		{
			printf("PASS!!!!!\n");
		}*/
		
		if (GSMMVATrellis[tempState][i].preState1!=ELSEWHERE)
		{
			tempState = GSMMVATrellis[tempState][i].preState1;
			continue;
		}
		if (GSMMVATrellis[tempState][i].preState2!=ELSEWHERE)
		{
			tempState = GSMMVATrellis[tempState][i].preState2;
			continue;
		}
	}

	for (i = 0;i<BURSTLEN;i++)
	{
		MVAOut[i].hard = tempMVAOut[i+1].hard;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -