Model_Name  		= "MG94";
Model_Options 		= 3;
Model_Dimension 	= 64;
Model_EFV_Type		= "Observed Nuc 3 params.";

function GUIBuildCodonFrequencies (EFV)
{
	PIStop = 1.0;
	result = {ModelMatrixDimension,1};
	hshift = 0;
	
	/*if (Columns(EFV)==3)
	{
		for (h=0; h<4; h=h+1)
		{
			EFV[h][0] = (EFV[h][0]+EFV[h][1]+EFV[h][2])/3;
		}
	}*/

	for (h=0; h<64; h=h+1)
	{
		first = h$16;
		second = h%16$4;
		third = h%4;
		if (ModelGeneticCode[h]==10) 
		{
			hshift = hshift+1;
			PIStop = PIStop-EFV[first][0]*EFV[second][0]*EFV[third][0];
			continue; 
		}
		result[h-hshift][0]=EFV[first][0]*EFV[second][0]*EFV[third][0];
	}
	return result*(1.0/PIStop);
}

function GUIPopulateModelMatrix (ModelMatrixName&, EFV)
{
	if (!ModelMatrixDimension)
	{
		ModelMatrixDimension = 64;
		for (h = 0 ;h<64; h=h+1)
		{
			if (ModelGeneticCode[h]==10)
			{
				ModelMatrixDimension = ModelMatrixDimension-1;
			}
		}
	}

	if (Columns(EFV)==3)
	{
		for (h=0; h<4; h=h+1)
		{
			EFV[h][0] = (EFV[h][0]+EFV[h][1]+EFV[h][2])/3;
		}
	}
	
	ModelMatrixName = {ModelMatrixDimension,ModelMatrixDimension}; 

	hshift = 0;

	if (modelType == 0)
	{
		for (h=0; h<64; h=h+1)
		{
			if (ModelGeneticCode[h]==10) 
			{
				hshift = hshift+1;
				continue; 
			}
			vshift = hshift;
			for (v = h+1; v<64; v=v+1)
			{
				diff = v-h;
				if (ModelGeneticCode[v]==10) 
				{
					vshift = vshift+1;
					continue; 
				}
			  	if ((h$4==v$4)||((diff%4==0)&&(h$16==v$16))||(diff%16==0))
			  	{
			  		if (h$4==v$4)
			  		{
			  			transition = v%4;
			  			transition2= h%4;
			  		}
			  		else
			  		{
			  			if(diff%16==0)
			  			{
			  				transition = v$16;
			  				transition2= h$16;
			  			}
			  			else
			  			{
			  				transition = v%16$4;
			  				transition2= h%16$4;
			  			}
			  		}
			  		if (ModelGeneticCode[0][h]==ModelGeneticCode[0][v]) 
			  		{
			  			ModelMatrixName[h-hshift][v-vshift] := synRate*EFV__[transition__][0];
			  			ModelMatrixName[v-vshift][h-hshift] := synRate*EFV__[transition2__][0];
				  	}
			  		else
			  		{
				  		ModelMatrixName[h-hshift][v-vshift] := nonSynRate*EFV__[transition__][0];
			  			ModelMatrixName[v-vshift][h-hshift] := nonSynRate*EFV__[transition2__][0];
		  			}
			  	}
			  }
		}
	}
	else
	{
		global globalVariable_DNDS;
		if (modelType == 1)
		{
			for (h=0; h<64; h=h+1)
				{
					if (ModelGeneticCode[h]==10) 
					{
						hshift = hshift+1;
						continue; 
					}
					vshift = hshift;
					for (v = h+1; v<64; v=v+1)
					{
						diff = v-h;
						if (ModelGeneticCode[v]==10) 
						{
							vshift = vshift+1;
							continue; 
						}
					  	if ((h$4==v$4)||((diff%4==0)&&(h$16==v$16))||(diff%16==0))
					  	{
					  		if (h$4==v$4)
					  		{
					  			transition = v%4;
					  			transition2= h%4;
					  		}
					  		else
					  		{
					  			if(diff%16==0)
					  			{
					  				transition = v$16;
					  				transition2= h$16;
					  			}
					  			else
					  			{
					  				transition = v%16$4;
					  				transition2= h%16$4;
					  			}
					  		}
					  		if (ModelGeneticCode[0][h]!=ModelGeneticCode[0][v]) 
					  		{
					  			ModelMatrixName[h-hshift][v-vshift] := globalVariable_DNDS*synRate*EFV__[transition__][0];
					  			ModelMatrixName[v-vshift][h-hshift] := globalVariable_DNDS*synRate*EFV__[transition2__][0];
						  	}
					  		else
					  		{
						  		ModelMatrixName[h-hshift][v-vshift] := synRate*EFV__[transition__][0];
					  			ModelMatrixName[v-vshift][h-hshift] := synRate*EFV__[transition2__][0];
				  			}
					  	}
					  }
				}	
		}
		else
		{
			global shapeParameter = .5;
			shapeParameter:>0.01;shapeParameter:<100;
			category     categoryVariable = 
						(rateClassCount, EQUAL, MEAN, GammaDist(_x_,shapeParameter,shapeParameter), CGammaDist(_x_,shapeParameter,shapeParameter), 0 , 
				  									  1e25,CGammaDist(_x_,shapeParameter+1,shapeParameter));
			for (h=0; h<64; h=h+1)
				{
					if (ModelGeneticCode[h]==10) 
					{
						hshift = hshift+1;
						continue; 
					}
					vshift = hshift;
					for (v = h+1; v<64; v=v+1)
					{
						diff = v-h;
						if (ModelGeneticCode[v]==10) 
						{
							vshift = vshift+1;
							continue; 
						}
					  	if ((h$4==v$4)||((diff%4==0)&&(h$16==v$16))||(diff%16==0))
					  	{
					  		if (h$4==v$4)
					  		{
					  			transition = v%4;
					  			transition2= h%4;
					  		}
					  		else
					  		{
					  			if(diff%16==0)
					  			{
					  				transition = v$16;
					  				transition2= h$16;
					  			}
					  			else
					  			{
					  				transition = v%16$4;
					  				transition2= h%16$4;
					  			}
					  		}
					  		if (ModelGeneticCode[0][h]!=ModelGeneticCode[0][v]) 
					  		{
					  			ModelMatrixName[h-hshift][v-vshift] := globalVariable_DNDS*synRate*categoryVariable*EFV__[transition__][0];
					  			ModelMatrixName[v-vshift][h-hshift] := globalVariable_DNDS*synRate*categoryVariable*EFV__[transition2__][0];
						  	}
					  		else
					  		{
						  		ModelMatrixName[h-hshift][v-vshift] := synRate*categoryVariable*EFV__[transition__][0];
					  			ModelMatrixName[v-vshift][h-hshift] := synRate*categoryVariable*EFV__[transition2__][0];
				  			}
					  	}
					  }
				}		
		}
	}
	
	return 0;
}
