/* ________________________________________________________________________________________________*/


function InitializeDistances (void)
{
	HarvestFrequencies (_dNucFreq,filteredData,1,1,0);
	_d_fR = _dNucFreq[0]+_dNucFreq[2];
	_d_fY = _dNucFreq[1]+_dNucFreq[3];
	
	if (_dNucFreq[0] == 0 || _dNucFreq[1] == 0 || _dNucFreq[2] == 0 || _dNucFreq[3] == 0)
	{
		_useK2P = 1;
	}
	else
	{
		_d_TN_K1 = 2*_dNucFreq[0]*_dNucFreq[2]/_d_fR;
		_d_TN_K2 = 2*_dNucFreq[1]*_dNucFreq[3]/_d_fY;
		_d_TN_K3 = 2*(_d_fR*_d_fY-_dNucFreq[0]*_dNucFreq[2]*_d_fY/_d_fR-_dNucFreq[1]*_dNucFreq[3]*_d_fR/_d_fY);
		_useK2P = 0;
	}
	summingVector = {4,1}["1"];
	return 0;
}

/* ________________________________________________________________________________________________*/

function ComputeDistanceFormula (s1,s2)
{
	GetDataInfo (siteDifferenceCount, filteredData, s1, s2, DEFAULT);
	
	totalSitesCompared = (Transpose(summingVector)*(siteDifferenceCount*summingVector))[0];
	if (totalSitesCompared)
	{
		if (_useK2P)
		{
			_dTransitionCounts 	 =    siteDifferenceCount[0][2]+siteDifferenceCount[2][0]  /* A-G and G-A */
									 +siteDifferenceCount[1][3]+siteDifferenceCount[3][1]; /* C-T and T-C */
								
			_dTransversionCounts = (siteDifferenceCount[0][0]+siteDifferenceCount[1][1]+siteDifferenceCount[2][2]+siteDifferenceCount[3][3])+_dTransitionCounts;
			
			_dTransitionCounts	 = _dTransitionCounts/totalSitesCompared;
			_dTransversionCounts = 1-_dTransversionCounts/totalSitesCompared;
			
			_d1C = 1-2*_dTransitionCounts-_dTransversionCounts;
			_d2C = 1-2*_dTransversionCounts;
			
			if (_d1C>0 && _d2C>0)
			{
				return -(0.5*Log(_d1C)+.25*Log(_d2C));	
			}
		}
		else
		{
			_dAGCounts 	 =    siteDifferenceCount[0][2]+siteDifferenceCount[2][0]  /* A-G and G-A */;
			_dCTCounts	 = 	  siteDifferenceCount[1][3]+siteDifferenceCount[3][1]; /* C-T and T-C */
								
			_dTransversionCounts = (siteDifferenceCount[0][0]+siteDifferenceCount[1][1]+siteDifferenceCount[2][2]+
									siteDifferenceCount[3][3])+_dAGCounts+_dCTCounts;
			
			_dAGCounts	 = _dAGCounts/totalSitesCompared;
			_dCTCounts	 = _dCTCounts/totalSitesCompared;
			
			_dTransversionCounts = 1-_dTransversionCounts/totalSitesCompared;
			
			_d1C = 1-_dAGCounts/_d_TN_K1-0.5*_dTransversionCounts/_d_fR;
			_d2C = 1-_dCTCounts/_d_TN_K2-0.5*_dTransversionCounts/_d_fY;
			_d3C = 1-0.5*_dTransversionCounts/_d_fY/_d_fR;
			
			if ((_d1C>0)&&(_d2C>0)&&(_d3C>0))
			{
				return -_d_TN_K1*Log(_d1C)-_d_TN_K2*Log(_d2C)-_d_TN_K3*Log(_d3C);
			}
		}
	}
	else
	{
		return 0;
	}
	
	return 1000;
}
