#include <stdio.h>
#include "QueryExpansion.h"


void InitializeQueryExpansionVariables(int ThreadSize)
{
	int i,j = 0,k=0;

	
			if ( RSType == 10 )
			{
				DocumentSimilarity = (long *)malloc((InputFileTotalPatents )*sizeof(long));
				DocumentSimilarityCount = (long *)malloc((InputFileTotalPatents )*sizeof(long));
			}


			if ( RSType == 10 || RSType == 11 || RSType == 12 || RSType == 21 || Know_Item_Search_Flag == 1)
			{
					
					DocTermsArray_TermNumber = (long *)malloc((InputFileTotalPatents)*sizeof(long));
					DocTermsArray_TermFrequency = (long *)malloc((InputFileTotalPatents)*sizeof(long));
					//DocTermsArray_TotalTerms = (long *)malloc((InputFileTotalPatents)*sizeof(long));
			}
			if ( RSType == 21 )
			{
					DocTermsArray_TermPosting = (long *)malloc((InputFileTotalPatents)*sizeof(long));

					PairPosting_QueryItem = (long *)malloc((ThreadSize)*sizeof(long));
					PairPosting_Min = (long *)malloc((ThreadSize)*sizeof(long));
					PairPosting_Max = (long *)malloc((ThreadSize)*sizeof(long));

					QueryTermsPosting = (long *)malloc((ThreadSize)*sizeof(long));
					QueryTermsPostingCount = (long *)malloc((ThreadSize)*sizeof(long));


			}


			QueryClusterN = (long *)malloc((ThreadSize)*sizeof(long));
			TermFreqInWholeCollection = (long *)malloc((ThreadSize)*sizeof(long));

			
			TermSingleFreqInAllDocuments = (long *)malloc((ThreadSize)*sizeof(long));

			TermFreqInRelevantDocuments = (long *)malloc((ThreadSize)*sizeof(long));
			LastPatentConsidered = (double *)malloc((ThreadSize)*sizeof(double));
			TermFreqInAllDocuments = (long *)malloc((ThreadSize)*sizeof(long));
			Projection_FoundPatentMappingNumber  = (long *)malloc((ThreadSize)*sizeof(long));
			PatentRMScore = (double *)malloc((ThreadSize )*sizeof(double));
			
			Size = (35200/32)+4;
		//	if ( RSType == 10 )
		//	{
		//		m_New32Projection = (long*)malloc((ThreadSize)*sizeof(long));					
		//	}
			if ( RSType == 21 )
					m_New32Projection_Clean = (long*)malloc((ThreadSize)*sizeof(long));

			ExpansionTerm_Clean = (long*)malloc((ThreadSize)*sizeof(long));
			ProjectionRows = (unsigned long*)malloc((ThreadSize)*sizeof(unsigned long));
			

		

			for ( i = 0; i < ThreadSize; i++ )
			{
				//	DocumentSimilarity[i] = (long *)malloc((InputFileTotalPatents )*sizeof(long));
					QueryClusterN[i] = (long *)malloc((InputFileTotalPatents )*sizeof(long));
					TermFreqInWholeCollection[i] = (long *)malloc((TotalItems)*sizeof(long));
					TermSingleFreqInAllDocuments[i] = (long *)malloc((TotalItems)*sizeof(long));
					TermFreqInRelevantDocuments[i] = (long *)malloc((TotalItems)*sizeof(long));
					LastPatentConsidered[i] = (double *)malloc((TotalItems)*sizeof(double));
					TermFreqInAllDocuments[i] = (long *)malloc((TotalItems)*sizeof(long));
					
					
					Projection_FoundPatentMappingNumber[i]  = (long *)malloc((InputFileTotalPatents)*sizeof(long));

					PatentRMScore[i] = (double *)malloc((InputFileTotalPatents )*sizeof(double));




					Size = (35200/32)+4;
				//	if ( RSType == 10 )
				//	{
				//			m_New32Projection[i] = (long*)malloc((TotalItems)*sizeof(long));							
				//	}
					if ( RSType == 21 )
							m_New32Projection_Clean[i] = (long*)malloc((TotalItems)*sizeof(long));

					ExpansionTerm_Clean[i] = (long*)malloc((TotalItems)*sizeof(long));
					ProjectionRows[i] = (unsigned long*)malloc((Size)*sizeof(unsigned long));

					for (  j = 0; j < TotalItems; j++ )
					{
							if (  RSType == 21 )
							{
								//	if ( RSType == 10 )
								//	{
								//			m_New32Projection[i][j] = (unsigned long*)malloc((Size)*sizeof(unsigned long));
								//			for ( k = 0; k < Size; k++ )
								//			{
								//				m_New32Projection[i][k][k] = 0;
								//			}
								//	}
									m_New32Projection_Clean[i][j] = -2;
							}
							ExpansionTerm_Clean[i][j] = -2;
					}
					if ( RSType == 21 )
					{
							PairPosting_QueryItem[i] = (long *)malloc((40000)*sizeof(long));
							PairPosting_Min[i] = (long *)malloc((40000)*sizeof(long));
							PairPosting_Max[i] = (long *)malloc((40000)*sizeof(long));


							QueryTermsPosting[i] = (long *)malloc((400)*sizeof(long));
							QueryTermsPostingCount[i] = (long *)malloc((400)*sizeof(long));

					}

			}
	
		

		
		

			
			for ( j = 0; j < InputFileTotalPatents; j++ )
			{
					if ( RSType == 10 )
					{
							DocumentSimilarity[j] = (long *) malloc ( 400 * sizeof(long));
					}


					
					if ( RSType == 21 )
					{
							if ( j < 1200 )
								DocTermsArray_TermPosting[j] = (long *)malloc((DocTermsArray_TotalTerms[j])*sizeof(long));
					}


					if ( RSType == 10 || RSType == 11 || RSType == 12 || RSType == 21 || Know_Item_Search_Flag == 1 )
					{
						//	printf("\n%d...",DocTermsArray_TotalTerms[j]);

							DocTermsArray_TermNumber[j] = (long *)malloc((DocTermsArray_TotalTerms[j])*sizeof(long));
							DocTermsArray_TermFrequency[j] = (long *)malloc((DocTermsArray_TotalTerms[j])*sizeof(long));							
							DocTermsArray_TotalTerms[j] = 0;
					}										
						

			}











//    Size = (35200/32)+4;
//	m_New32Projection = (long*)malloc((TotalItems)*sizeof(long));
//	m_New32Projection_Clean = (long*)malloc((TotalItems)*sizeof(long));
//	ExpansionTerm_Clean = (long*)malloc((TotalItems)*sizeof(long));
//	ProjectionRows = (unsigned long*)malloc((Size)*sizeof(unsigned long));
//	for (  j = 0; j < TotalItems; j++ )
//	{
//			m_New32Projection[j] = (unsigned long*)malloc((Size)*sizeof(unsigned long));
//			for ( i = 0; i < Size; i++ )
//			{
//					m_New32Projection[j][i] = 0;
//			}
//			m_New32Projection_Clean[j] = -2;
//			ExpansionTerm_Clean[j] = -2;
//	}


}

void InsertBestTerms(long Term, double TermWeight, double DistributionR, double DistributionW, int ThreadNumber)
{
		 long j = 0;
		 long Found = 0;
                                 

					if ( TermWeight > Minimum[ThreadNumber]  )
                    {                
                                if ( TopExpandedTermsAdded[ThreadNumber] == TopExpandedTermsConsider[ThreadNumber] )
                                {
										ExpandedTerms[ThreadNumber][MinimumIndex[ThreadNumber]]	= Term;
										ExpandedTermsWeight[ThreadNumber][MinimumIndex[ThreadNumber]] = TermWeight;
                                }
                                if ( TopExpandedTermsAdded[ThreadNumber]  < TopExpandedTermsConsider[ThreadNumber])
                                {
										ExpandedTerms[ThreadNumber][TopExpandedTermsAdded[ThreadNumber]] = Term;
										ExpandedTermsWeight[ThreadNumber][TopExpandedTermsAdded[ThreadNumber]] = TermWeight;                                        
                                        TopExpandedTermsAdded[ThreadNumber]++;
                                }
                                if ( TopExpandedTermsAdded[ThreadNumber]  == TopExpandedTermsConsider[ThreadNumber])
                                {
                                        Minimum[ThreadNumber] = 9999;
                                        for ( j = 0; j < TopExpandedTermsAdded[ThreadNumber]; j++)
                                        {
                                                if ( ExpandedTermsWeight[ThreadNumber][j] < Minimum[ThreadNumber] )
                                                {
                                                        Minimum[ThreadNumber] = ExpandedTermsWeight[ThreadNumber][j];
                                                        MinimumIndex[ThreadNumber] = j;
                                                }
                                        }
                                }
                    }
}
void CalculteQueryItemsFrequency(long PatentNumber, long Terms,long SectionNumber,int ThreadNumber)
{
	long loop = 0, i = 0;
	long LastOccurence = -24;



				
						for ( loop = 0; loop < Terms; loop ++ )
								ClaimQueryItemFrequency[ThreadNumber][loop] = 0;


						for  ( i = 0; i < DocTermsArray_TotalTerms[PatentNumber]; i++ )
						{
								for ( loop = 0; loop < Terms; loop ++ )
								{
										if ( DocTermsArray_TermNumber[PatentNumber][i] == QueryItemArray[ThreadNumber][loop] )
										{
												ClaimQueryItemFrequency[ThreadNumber][loop] =  DocTermsArray_TermFrequency[PatentNumber][i];

										}
								}
						}	





}

void CalculateDocsRelevanceScores(long PatentNumber , long Terms ,long ScoreInsertion, long ThreadNumber )
{    
	

           double FinalScore = 1;
		   double TF = 0;
		   double IDF = 0;
		   long FFreq = 0;
		   double WeightedLength = 0;


		   long j = 0;
		   long Count = 0;
		   
		   double SecondPart = 0;

 		   double Parameter  = 0.7;
		   double Parameter2  = 2000;
		   double SecondPart2 = 0;


		   FinalScore =1;
		 

           for ( j = 0; j < Terms; j++ )
           {
			   
							TF = 0;				
							FFreq = ClaimQueryItemFrequency[ThreadNumber][j];

						//	printf("\n%d....%d...%d\n",FFreq,Terms,j);

							
						/*	IDF = (double)TermCollectionSum[QueryItemArray[ThreadNumber][j]];
							IDF = (double) ( IDF / (double) (CollEx) );
							
							TF = FFreq;

							SecondPart2 = (double)( TF + (double)( (double)Parameter2 *(double)IDF));
							SecondPart2 = (double) ( SecondPart2/ (double)( (double) fullPatentLength[PatentNumber] + (double)(Parameter2)) );
							SecondPart = (double)((double)(1-Parameter)*(SecondPart2)) +(Parameter * (double)IDF);
							
							FinalScore *= SecondPart;*/




								// jm


												
							IDF = (double)TermCollectionSum[QueryItemArray[ThreadNumber][j]];
							IDF = (double) ( IDF / (double) (CollEx ) );							  


							TF = FFreq;
							TF = (double) ( (double)TF/(double)fullPatentLength[PatentNumber]);

							TF = (double)((double)(1-Parameter)*TF);
							SecondPart = Parameter*IDF;

							FinalScore *= ( SecondPart + TF ) ;







						//	BM25

							
/*
							TF += (double)((double)FFreq) ;
							if ( FFreq > 0 )
								Count++;		

							WeightedLength = 0;
		                    WeightedLength += (double)((double)fullPatentLength[PatentNumber] );

					
							IDF = (double)IDFValue[QueryItemArray[j]];
							  
				
							IDFUpper = (double)(((double)(TotalPatents))- (double)IDF + (double)0.5);
							IDFLower = (double)IDF + (double)0.5;
							IDF = (double) (IDFUpper/IDFLower);
							IDF = (double)((double)log(IDF)/(double)log(2));

                    
							MainUpper = (double)(TF*(k+1));
							MainLower = (double)(TF + k*(1-b+(b*(WeightedLength/AveragePatentLength))));
							Main = MainUpper/MainLower;
							FinalScore  += (IDF*Main);*/


							

							
				



           }



		   



		  PatentRMScore[ThreadNumber][ScoreInsertion] = FinalScore;



}


void ExpandQueryKLDMethod(int Version, int ThreadNumber)
{
	long z = 0, i = 0, j = 0;
	double FirstSide = 0;
	double SecondSide = 0;
	double ThirdSide = 0;
	double Upper = 0;
	double Lower = 0;
	double KLD = 0;
	long TermNumber;
	long DocNum;
	long RelevantDocumentsConsider = GoodDocuments[ThreadNumber];
	TopExpandedTermsConsider[ThreadNumber] = 30;
	TopExpandedTermsAdded[ThreadNumber] = 0;
	MinimumIndex[ThreadNumber] = 0;
	Minimum[ThreadNumber]  = -99999;



	AllTermsOccurance[ThreadNumber] = 0;
    for ( z = 0; z < GoodDocuments[ThreadNumber]; z++)
    {
						DocNum = FoundPatents[ThreadNumber][z];

						for  ( i = 0; i < DocTermsArray_TotalTerms[DocNum]; i++ )
						{

									TermNumber = DocTermsArray_TermNumber[DocNum][i];
									if ( ExpansionTerm_Clean[ThreadNumber][TermNumber] != Version )
									{											
												TermFreqInRelevantDocuments[ThreadNumber][TermNumber] = 0;
												LastPatentConsidered[ThreadNumber][TermNumber] = -1;
												TermFreqInAllDocuments[ThreadNumber][TermNumber] = 0;
												TermSingleFreqInAllDocuments[ThreadNumber][TermNumber] = 0;								
									}
									ExpansionTerm_Clean[ThreadNumber][TermNumber] = Version;


									if ( z < RelevantDocumentsConsider )
										TermFreqInRelevantDocuments[ThreadNumber][ DocTermsArray_TermNumber[DocNum][i] ]++;

									TermSingleFreqInAllDocuments[ThreadNumber][ DocTermsArray_TermNumber[DocNum][i] ] ++;


									TermFreqInAllDocuments[ThreadNumber][ DocTermsArray_TermNumber[DocNum][i] ] += DocTermsArray_TermFrequency[DocNum][i];
									AllTermsOccurance[ThreadNumber] += DocTermsArray_TermFrequency[DocNum][i];

						}

	}

	

	for ( i = 0; i < TotalItems; i++ )
	{
				if ( TermFreqInRelevantDocuments[ThreadNumber][i] > 0 && ExpansionTerm_Clean[ThreadNumber][i] == Version )
				{		
						FirstSide = (double)((double)TermFreqInRelevantDocuments[ThreadNumber][i]/(double)RelevantDocumentsConsider);
						Upper = (double)((double)CollEx+(double)0.01*(double)TotalItems);
						Lower = (double)((double)TermFreqInRelevantDocuments[ThreadNumber][i] + (double)0.01);
						ThirdSide = Upper/Lower;

						SecondSide = FirstSide * ThirdSide;
	                    SecondSide = (double)((double)log(SecondSide)/(double)log(2));
						KLD = FirstSide * SecondSide;


						InsertBestTerms(i, KLD,0,0,ThreadNumber);
				}
	}

   // QueryItemCount = 0;
	QueryItemCount[ThreadNumber]--;
	for ( i = 0; i < TopExpandedTermsAdded[ThreadNumber]; i ++ )
	{
		/*	FirstSide = (double)((double)1/(double)3);
			Upper = (double)((double)TermFreqInRelevantDocuments[ThreadNumber][ExpandedTerms[ThreadNumber][i]] + (double)0.5); 
			Lower = (double)((double)TermSingleFreqInAllDocuments[ThreadNumber][ExpandedTerms[ThreadNumber][i]] - (double)TermFreqInRelevantDocuments[ThreadNumber][ExpandedTerms[ThreadNumber][i]] + (double)0.5 );
			SecondSide = Upper/Lower;

			Upper = (double) ( (double)RelevantDocumentsConsider[ThreadNumber] - (double)TermFreqInRelevantDocuments[ThreadNumber][ExpandedTerms[ThreadNumber][i]] + (double)0.5 );
			Lower = (double) ( (double)InputFileTotalPatents  - (double)TermSingleFreqInAllDocuments[ThreadNumber][ExpandedTerms[ThreadNumber][i]] - (double)RelevantDocumentsConsider[ThreadNumber] + (double)TermFreqInRelevantDocuments[ThreadNumber][ExpandedTerms[ThreadNumber][i]] + (double)0.5 );
			ThirdSide = Upper/Lower;

			SecondSide = SecondSide/ThirdSide;
			SecondSide = (double)((double)log(SecondSide)/(double)log(2));

			ExpandedTermsWeight[i] = FirstSide * SecondSide;*/

			//printf("\nTerm %d ,  Weight = %f",ExpandedTerms[i],ExpandedTermsWeight[i] );
			QueryItemArray[ThreadNumber][QueryItemCount[ThreadNumber]] = ExpandedTerms[ThreadNumber][i];
			QueryItemCount[ThreadNumber]++;
	}



    for ( z = 0; z < FoundPatentsCount[ThreadNumber]; z++)
    {
				CalculteQueryItemsFrequency(FoundPatents[ThreadNumber][z],QueryItemCount[ThreadNumber],1,ThreadNumber);
				CalculateDocsRelevanceScores(FoundPatents[ThreadNumber][z],QueryItemCount[ThreadNumber] , z ,ThreadNumber );
	}
	//exit(1);
}

void ExpandQueryLanguageModelMethod(int Version, int ThreadNumber)
{
	long z = 0, i = 0, j = 0;
	double FirstSide = 0;
	double SecondSide = 0;
	double ThirdSide = 0;
	double Upper = 0;
	double Lower = 0;
	double Score = 0;
	double Parameter = 0.3;
	long RelevantDocumentsConsider = GoodDocuments[ThreadNumber];
	long TermNumber;
	long TFF;
	long DocNum;
	TopExpandedTermsConsider[ThreadNumber] = 30;
	TopExpandedTermsAdded[ThreadNumber] = 0;
	MinimumIndex[ThreadNumber] = 0;
	Minimum[ThreadNumber]  = -99999;


	AllTermsOccurance[ThreadNumber] = 0;
/*
    for ( z = 0; z < FoundPatentsCount[ThreadNumber]; z++)
    {

	
				DocNum = FoundPatents[ThreadNumber][z];
				
				for  ( i = 0; i < DocTermsArray_TotalTerms[DocNum]; i++ )
				{

	
									
									TermNumber = DocTermsArray_TermNumber[DocNum][i];
									if ( DocTermsArray_TermFrequency[DocNum][i] > 0 )
									{

	

											if ( ExpansionTerm_Clean[ThreadNumber][TermNumber] != Version )
											{											
													TermFreqInRelevantDocuments[ThreadNumber][TermNumber] = -1;
													LastPatentConsidered[ThreadNumber][TermNumber] = 0;
													TermFreqInAllDocuments[ThreadNumber][TermNumber] = 0;
													TermSingleFreqInAllDocuments[ThreadNumber][TermNumber] = 0;
													TermFreqInWholeCollection[ThreadNumber][TermNumber] = 0;									
											}
											ExpansionTerm_Clean[ThreadNumber][TermNumber] = Version;

											TermFreqInAllDocuments[ThreadNumber][ TermNumber ] += DocTermsArray_TermFrequency[DocNum][i];
											AllTermsOccurance[ThreadNumber] += DocTermsArray_TermFrequency[DocNum][i];

									}
				}
				if ( z > 5000 )
					break;
	}






    for ( z = 0; z < GoodDocuments[ThreadNumber]; z++)
    {
						DocNum = FoundPatents[ThreadNumber][z];
						for  ( i = 0; i < DocTermsArray_TotalTerms[DocNum]; i++ )
						{
									TermFreqInWholeCollection[ThreadNumber][ DocTermsArray_TermNumber[DocNum][i] ] = 0;
						}

						for  ( i = 0; i < DocTermsArray_TotalTerms[DocNum]; i++ )
						{
									if ( DocTermsArray_TermNumber[DocNum][i] > 0 )
										TermFreqInWholeCollection[ThreadNumber][ DocTermsArray_TermNumber[DocNum][i] ]+= DocTermsArray_TermFrequency[DocNum][i]; //old
						}


						for  ( i = 0; i < DocTermsArray_TotalTerms[DocNum]; i++ )
						{
								

									if ( DocTermsArray_TermNumber[DocNum][i] > 0 )
									{
											if ( TermFreqInWholeCollection[ThreadNumber][ DocTermsArray_TermNumber[DocNum][i] ] > 0  )
													FirstSide = Parameter * (double)( (double) TermFreqInWholeCollection[ThreadNumber][ DocTermsArray_TermNumber[DocNum][i]  ]/(double)fullPatentLength[ DocNum ] );
											else
													FirstSide = 0;

											SecondSide  = (double)((double)1-Parameter) * (double)( (double)TermCollectionSum[ DocTermsArray_TermNumber[DocNum][i] ]/(double)CollEx );
											FirstSide = FirstSide + SecondSide;


											if ( TermFreqInWholeCollection[ThreadNumber][ DocTermsArray_TermNumber[DocNum][i] ] > 0  )
													TFF = TermFreqInWholeCollection[ThreadNumber][ DocTermsArray_TermNumber[DocNum][i] ];
											else
													TFF = 0;

											SecondSide = (double)((Parameter * (double)(((double) TFF/(double)fullPatentLength[ DocNum ] ) *  (double)( (double)CollEx/(double)TermCollectionSum[ DocTermsArray_TermNumber[DocNum][i] ] )) ) + (double)(1 - Parameter));
										    SecondSide = (double)((double)log(SecondSide)/(double)log(2));
											

											LastPatentConsidered[ThreadNumber][ DocTermsArray_TermNumber[DocNum][i] ] += FirstSide*SecondSide;
											TermSingleFreqInAllDocuments[ThreadNumber][ DocTermsArray_TermNumber[DocNum][i] ]++;
									}
								
						}

				
	}


//	exit(1);

	






	for ( i = 0; i < TotalItems; i++ )
	{
				if ( LastPatentConsidered[ThreadNumber][i] > 0  )
				{						
						InsertBestTerms(i, LastPatentConsidered[ThreadNumber][i],0,0 ,ThreadNumber);
				}
	}



    QueryItemCount[ThreadNumber]--;
	for ( i = 0; i < TopExpandedTermsAdded[ThreadNumber]; i ++ )
	{
			FirstSide = (double)((double)1/(double)3);
			Upper = (double)((double)TermFreqInRelevantDocuments[ThreadNumber][ExpandedTerms[ThreadNumber][i]] + (double)0.5); 
			Lower = (double)((double)TermFreqInWholeCollection[ThreadNumber][ExpandedTerms[ThreadNumber][i]] - (double)TermFreqInRelevantDocuments[ThreadNumber][ExpandedTerms[ThreadNumber][i]] + (double)0.5 );
			SecondSide = Upper/Lower;

			Upper = (double) ( (double)RelevantDocumentsConsider - (double)TermFreqInRelevantDocuments[ThreadNumber][ExpandedTerms[ThreadNumber][i]] + (double)0.5 );
			Lower = (double) ( (double)InputFileTotalPatents - (double)TermFreqInWholeCollection[ThreadNumber][ExpandedTerms[ThreadNumber][i]] - (double)RelevantDocumentsConsider + (double)TermFreqInRelevantDocuments[ThreadNumber][ExpandedTerms[ThreadNumber][i]] + (double)0.5 );
			ThirdSide = Upper/Lower;

			SecondSide = SecondSide/ThirdSide;
			SecondSide = (double)((double)log(SecondSide)/(double)log(2));
		// Thesis Weighting 	
		

			

		//	ExpandedTermsWeight[i] = FirstSide * SecondSide;

			//printf("\nTerm %d ,  Weight = %f",ExpandedTerms[i],ExpandedTermsWeight[i] );
			QueryItemArray[ThreadNumber][QueryItemCount[ThreadNumber]] = ExpandedTerms[ThreadNumber][i];
			QueryItemCount[ThreadNumber]++;
	}

	//printf("\n%d...%d",GoodDocuments,QueryItemCount);


    for ( z = 0; z < FoundPatentsCount[ThreadNumber]; z++)
    {
				CalculteQueryItemsFrequency(FoundPatents[ThreadNumber][z],QueryItemCount[ThreadNumber],1,ThreadNumber);
				
				CalculateDocsRelevanceScores(FoundPatents[ThreadNumber][z],QueryItemCount[ThreadNumber] , z , ThreadNumber);	
				
	}
 

*/

























   for ( z = 0; z < GoodDocuments[ThreadNumber]; z++)
    {
			
		

						for  ( i = 0; i < DocTermsArray_TotalTerms[FoundPatents[ThreadNumber][z]]; i++ )
						{
											TermNumber = DocTermsArray_TermNumber[FoundPatents[ThreadNumber][z]][i];

											if ( ExpansionTerm_Clean[ThreadNumber][TermNumber] != Version )
											{											
													TermFreqInRelevantDocuments[ThreadNumber][TermNumber] = -1;
													LastPatentConsidered[ThreadNumber][TermNumber] = 0;
													TermFreqInAllDocuments[ThreadNumber][TermNumber] = 0;
													TermSingleFreqInAllDocuments[ThreadNumber][TermNumber] = 0;
													TermFreqInWholeCollection[ThreadNumber][TermNumber] = 0;									
											}
											ExpansionTerm_Clean[ThreadNumber][TermNumber] = Version;


											TermFreqInWholeCollection[ThreadNumber][ DocTermsArray_TermNumber[FoundPatents[ThreadNumber][z]][i] ] = DocTermsArray_TermFrequency[FoundPatents[ThreadNumber][z]][i]; //old

						}

				//TermFreqInRelevantDocuments[i] = 0;
				//LastPatentConsidered[i] = -1;
				//TermFreqInAllDocuments[i] = 0;
				//TermSingleFreqInAllDocuments[i] = 0;

						for  ( i = 0; i < DocTermsArray_TotalTerms[FoundPatents[ThreadNumber][z]]; i++ )
						{
								

									if ( DocTermsArray_TermNumber[FoundPatents[ThreadNumber][z]][i] > 0 )
									{
											if ( TermFreqInWholeCollection[ThreadNumber][ DocTermsArray_TermNumber[FoundPatents[ThreadNumber][z]][i] ] > 0  )
													FirstSide = Parameter * (double)( (double) TermFreqInWholeCollection[ThreadNumber][ DocTermsArray_TermNumber[FoundPatents[ThreadNumber][z]][i]  ]/(double)fullPatentLength[ FoundPatents[ThreadNumber][z] ] );
											else
													FirstSide = 0;

										//	if ( TermFreqInAllDocuments[ DocTermsArray_TermNumber[FoundPatents[z]][i] ] > 0 )
													SecondSide  = (double)((double)1-Parameter) * (double)( (double)TermCollectionSum[ DocTermsArray_TermNumber[FoundPatents[ThreadNumber][z]][i] ]/(double)CollEx );
										//	else
										//			SecondSide = 0;


											FirstSide = FirstSide + SecondSide;


											if ( TermFreqInWholeCollection[ThreadNumber][ DocTermsArray_TermNumber[FoundPatents[ThreadNumber][z]][i] ] > 0  )
													TFF = TermFreqInWholeCollection[ThreadNumber][ DocTermsArray_TermNumber[FoundPatents[ThreadNumber][z]][i] ];
											else
													TFF = 0;

											SecondSide = (double)((Parameter * (double)(((double) TFF/(double)fullPatentLength[ FoundPatents[ThreadNumber][z] ] ) *  (double)( (double)CollEx/(double)TermCollectionSum[ DocTermsArray_TermNumber[FoundPatents[ThreadNumber][z]][i] ] )) ) + (double)(1 - Parameter));
										    SecondSide = (double)((double)log(SecondSide)/(double)log(2));

											

											LastPatentConsidered[ThreadNumber][ DocTermsArray_TermNumber[FoundPatents[ThreadNumber][z]][i] ] += FirstSide+SecondSide;


											TermSingleFreqInAllDocuments[ThreadNumber][ DocTermsArray_TermNumber[FoundPatents[ThreadNumber][z]][i] ] = Version;
									}
								
						}

				
					//	if ( z == 40 )
					//		break;
	}



	





	for ( i = 0; i < TotalItems; i++ )
	{
				if ( LastPatentConsidered[ThreadNumber][i] > 0  && TermSingleFreqInAllDocuments[ThreadNumber][i] == Version )
				{						
						InsertBestTerms(i, LastPatentConsidered[ThreadNumber][i],0,0 ,ThreadNumber);
				}
	}


    QueryItemCount[ThreadNumber]--;
	for ( i = 0; i < TopExpandedTermsAdded[ThreadNumber]; i ++ )
	{
			FirstSide = (double)((double)1/(double)3);
			Upper = (double)((double)TermFreqInRelevantDocuments[ThreadNumber][ExpandedTerms[ThreadNumber][i]] + (double)0.5); 
			Lower = (double)((double)TermFreqInWholeCollection[ThreadNumber][ExpandedTerms[ThreadNumber][i]] - (double)TermFreqInRelevantDocuments[ThreadNumber][ExpandedTerms[ThreadNumber][i]] + (double)0.5 );
			SecondSide = Upper/Lower;

			Upper = (double) ( (double)RelevantDocumentsConsider - (double)TermFreqInRelevantDocuments[ThreadNumber][ExpandedTerms[ThreadNumber][i]] + (double)0.5 );
			Lower = (double) ( (double)InputFileTotalPatents - (double)TermFreqInWholeCollection[ThreadNumber][ExpandedTerms[ThreadNumber][i]] - (double)RelevantDocumentsConsider + (double)TermFreqInRelevantDocuments[ThreadNumber][ExpandedTerms[ThreadNumber][i]] + (double)0.5 );
			ThirdSide = Upper/Lower;

			SecondSide = SecondSide/ThirdSide;
			SecondSide = (double)((double)log(SecondSide)/(double)log(2));
		// Thesis Weighting 	
		

			

		//	ExpandedTermsWeight[i] = FirstSide * SecondSide;

			//printf("\nTerm %d ,  Weight = %f",ExpandedTerms[i],ExpandedTermsWeight[i] );
			QueryItemArray[ThreadNumber][QueryItemCount[ThreadNumber]] = ExpandedTerms[ThreadNumber][i];
			QueryItemCount[ThreadNumber]++;
	}

	//printf("\n%d...%d",GoodDocuments,QueryItemCount);


    for ( z = 0; z < FoundPatentsCount[ThreadNumber]; z++)
    {
				CalculteQueryItemsFrequency(FoundPatents[ThreadNumber][z],QueryItemCount[ThreadNumber],1,ThreadNumber);
				
				CalculateDocsRelevanceScores(FoundPatents[ThreadNumber][z],QueryItemCount[ThreadNumber] , z , ThreadNumber);	
				
	}
 


}

/*

void J48TreePrint(struct J48_Tree *J48CurrentNode,int TreeLevel)
{
	int LoopStatus = 0;
	int pl = 0;

	if ( TreeLevel == 0 )
		printf("\n");

	while(1)
	{
			if ( LoopStatus == 0 )// left node
			{

					//printf("%d ",TreeLevel);
					for ( pl = 0; pl < TreeLevel; pl++ )
						printf("|   ");
					printf("%s %lf %d %lf %d\n",J48CurrentNode->AttributeName,J48CurrentNode->LeftNodeValue,J48CurrentNode->LeftNodeRuleStatus,J48CurrentNode->LeftNodeRuleAccuracy,J48CurrentNode->LeftNodeRuleClass);

					if ( J48CurrentNode->LeftNodeRuleStatus == 0 )
							J48TreePrint(J48CurrentNode->LeftNode,TreeLevel+1);


					LoopStatus++;
			}
			if ( LoopStatus == 1 )
			{
					for ( pl = 0; pl < TreeLevel; pl++ )
						printf("|   ");
					printf("%s %lf %d %lf %d\n",J48CurrentNode->AttributeName,J48CurrentNode->RightNodeValue,J48CurrentNode->RightNodeRuleStatus,J48CurrentNode->RightNodeRuleAccuracy,J48CurrentNode->RightNodeRuleClass);

					if ( J48CurrentNode->RightNodeRuleStatus == 0 )
							J48TreePrint(J48CurrentNode->RightNode,TreeLevel+1);

					LoopStatus++;
			}


			if (LoopStatus == J48CurrentNode->nodeCompleted )
				break;


	}


		
}
*/

void J48Prediction(struct J48_Tree *J48CurrentNode,int TreeLevel,int ThreadNumber)
{
	int LoopStatus = 0;
	int pl = 0;
	int nodeFeature;
	int conditionMatch = 0;

	if ( TreeLevel == 0 )
	{
			GoodTermVotes[ThreadNumber] = 0;
			BadTermVotes[ThreadNumber] = 0;
			MaximumGoodBadPrediction[ThreadNumber] = 0;
			MaximumPredictionClass[ThreadNumber] = 0;
			BestRuleMaximumSamples[ThreadNumber] = 0;
	}

	RuleFire[ThreadNumber]++;
	//unclassify_term_features
	while(1)
	{
			if ( LoopStatus == 0 )// left node
			{
					nodeFeature = atoi(J48CurrentNode->AttributeName);
					conditionMatch = 0;

					if ( J48CurrentNode->LeftNodeCondition == 1 ) // <
					{
							if ( unclassify_term_features[ThreadNumber][nodeFeature] < J48CurrentNode->LeftNodeValue )
								conditionMatch = 1;
					}
					else if ( J48CurrentNode->LeftNodeCondition == 2 ) // <=
					{
							if ( unclassify_term_features[ThreadNumber][nodeFeature] <= J48CurrentNode->LeftNodeValue )
								conditionMatch = 1;

					}
					else if ( J48CurrentNode->LeftNodeCondition == 3 ) // >
					{
							if ( unclassify_term_features[ThreadNumber][nodeFeature] > J48CurrentNode->LeftNodeValue )
								conditionMatch = 1;

					}
					else if ( J48CurrentNode->LeftNodeCondition == 4 ) // >=
					{
							if ( unclassify_term_features[ThreadNumber][nodeFeature] >= J48CurrentNode->LeftNodeValue )
								conditionMatch = 1;

					}
					else if ( J48CurrentNode->LeftNodeCondition == 5 ) // =
					{
							if ( unclassify_term_features[ThreadNumber][nodeFeature] == J48CurrentNode->LeftNodeValue )
								conditionMatch = 1;
					}


				//	printf("%s %lf %d %lf\n",J48CurrentNode->AttributeName,J48CurrentNode->LeftNodeValue,J48CurrentNode->LeftNodeRuleStatus,J48CurrentNode->LeftNodeRuleAccuracy);
					if ( J48CurrentNode->LeftNodeRuleStatus == 1 )
					{

							 if ( J48CurrentNode->LeftNodeRuleClass == 1  )
									GoodTermVotes[ThreadNumber]++;
							 if ( J48CurrentNode->LeftNodeRuleClass == 0 )
									BadTermVotes[ThreadNumber]++;
							


							 if ( J48CurrentNode->LeftNodeRuleAccuracy >= MaximumGoodBadPrediction[ThreadNumber] )
							 {
							//	 printf("\n%lf...%lf....%d...%d",J48CurrentNode->RightNodeRuleAccuracy,MaximumGoodBadPrediction[ThreadNumber],J48CurrentNode->LeftMaximumSamples,BestRuleMaximumSamples[ThreadNumber]);

									 if ( J48CurrentNode->LeftMaximumSamples > BestRuleMaximumSamples[ThreadNumber] )
									 {

											

											 MaximumGoodBadPrediction[ThreadNumber] = J48CurrentNode->LeftNodeRuleAccuracy;										 
											 MaximumPredictionClass[ThreadNumber] = J48CurrentNode->LeftNodeRuleClass;
											 BestRuleMaximumSamples[ThreadNumber] = J48CurrentNode->LeftMaximumSamples;

									 }
							 }


					}

					if ( J48CurrentNode->LeftNodeRuleStatus == 0 && conditionMatch == 1)
							J48Prediction(J48CurrentNode->LeftNode,TreeLevel+1,ThreadNumber);


					LoopStatus++;
			}
			if ( LoopStatus == 1 )
			{
					nodeFeature = atoi(J48CurrentNode->AttributeName);
					conditionMatch = 0;
					if ( J48CurrentNode->RightNodeCondition == 1 ) // <
					{
							if ( unclassify_term_features[ThreadNumber][nodeFeature] < J48CurrentNode->RightNodeValue )
								conditionMatch = 1;
					}
					else if ( J48CurrentNode->RightNodeCondition == 2 ) // <=
					{
							if ( unclassify_term_features[ThreadNumber][nodeFeature] <= J48CurrentNode->RightNodeValue )
								conditionMatch = 1;

					}
					else if ( J48CurrentNode->RightNodeCondition == 3 ) // >
					{
							if ( unclassify_term_features[ThreadNumber][nodeFeature] > J48CurrentNode->RightNodeValue )
								conditionMatch = 1;

					}
					else if ( J48CurrentNode->RightNodeCondition == 4 ) // >=
					{
							if ( unclassify_term_features[ThreadNumber][nodeFeature] >= J48CurrentNode->RightNodeValue )
								conditionMatch = 1;

					}
					else if ( J48CurrentNode->RightNodeCondition == 5 ) // =
					{
							if ( unclassify_term_features[ThreadNumber][nodeFeature] == J48CurrentNode->RightNodeValue )
								conditionMatch = 1;
					}


					//printf("%s %lf %d %lf\n",J48CurrentNode->AttributeName,J48CurrentNode->RightNodeValue,J48CurrentNode->RightNodeRuleStatus,J48CurrentNode->RightNodeRuleAccuracy);
					if ( J48CurrentNode->RightNodeRuleStatus == 1 )
					{

							 if ( J48CurrentNode->RightNodeRuleClass == 1 )
									 GoodTermVotes[ThreadNumber]++;
							 if ( J48CurrentNode->RightNodeRuleClass == 0 )
									 BadTermVotes[ThreadNumber]++;

							 if ( J48CurrentNode->RightNodeRuleAccuracy >= MaximumGoodBadPrediction[ThreadNumber] )
							 {
								 
								 

 									 if ( J48CurrentNode->RightMaximumSamples > BestRuleMaximumSamples[ThreadNumber] )
									 {

										//	printf("\n    %lf...%lf",J48CurrentNode->RightNodeRuleAccuracy,MaximumGoodBadPrediction[ThreadNumber]);


											 MaximumGoodBadPrediction[ThreadNumber] = J48CurrentNode->RightNodeRuleAccuracy;										 
											 MaximumPredictionClass[ThreadNumber] = J48CurrentNode->RightNodeRuleClass;
											 BestRuleMaximumSamples[ThreadNumber] = J48CurrentNode->RightMaximumSamples;
									 }
							 }

							
					}

					if ( J48CurrentNode->RightNodeRuleStatus == 0 && conditionMatch == 1)
								J48Prediction(J48CurrentNode->RightNode,TreeLevel+1,ThreadNumber);

					LoopStatus++;
			}


			if (LoopStatus == J48CurrentNode->nodeCompleted )
				break;


	}


		
}

int J48ParseNode(struct J48_Tree *J48CurrentNode,FILE *fptr,int TreeLevel)
{

	char text[200];
	int informationStatus = 0; //0 for node // 1 for condition // 2 for value;
	int currentNodeTreeLevelCount = 0;
	char cleanText[200];
	char tempText[10];
	int i = 0;
	double TotalSamples = 0;
	double WrongClassify  = 0;
	int returnStatus = 0;
	int NotCheck = 0;


	

	while(1)
	{
			if ( fscanf(fptr,"%s",text) == EOF )
				break;


			if ( strcmp(text,"|") != 0 )
			{


							if ( currentNodeTreeLevelCount != TreeLevel )
							{
									return currentNodeTreeLevelCount;
							}


							if ( informationStatus == 0 )
							{
									strcpy(J48CurrentNode->AttributeName,text);
							}
							if ( informationStatus == 1 )
							{

									if (J48CurrentNode->nodeCompleted == 0 )
									{
											if ( strcmp(text,"<") == 0 )
												J48CurrentNode->LeftNodeCondition = 1;
											if ( strcmp(text,"<=") == 0 )
												J48CurrentNode->LeftNodeCondition = 2;
											if ( strcmp(text,">") == 0 )
												J48CurrentNode->LeftNodeCondition = 3;
											if ( strcmp(text,">=") == 0 )
												J48CurrentNode->LeftNodeCondition = 4;
											if ( strcmp(text,"=") == 0 )
												J48CurrentNode->LeftNodeCondition = 5;


											

									}
									else if (J48CurrentNode->nodeCompleted == 1 )
									{



											if ( strcmp(text,"<") == 0 )
												J48CurrentNode->RightNodeCondition = 1;
											if ( strcmp(text,"<=") == 0 )
												J48CurrentNode->RightNodeCondition = 2;
											if ( strcmp(text,">") == 0 )
												J48CurrentNode->RightNodeCondition = 3;
											if ( strcmp(text,">=") == 0 )
												J48CurrentNode->RightNodeCondition = 4;
											if ( strcmp(text,"=") == 0 )
												J48CurrentNode->RightNodeCondition = 5;
									}

							}
							if ( informationStatus == 2 )
							{
									if (J48CurrentNode->nodeCompleted == 0 )
									{
											if ( text[strlen(text)-1] == ':' ) // rule
											{
													currentNodeTreeLevelCount = 0;
													informationStatus = -1;

													J48CurrentNode->LeftNodeRuleStatus = 1;
													strcpy(cleanText,"");
													for ( i = 0; i < strlen(text)-1; i ++ )
													{
															sprintf(tempText,"%c",text[i]);
															strcat(cleanText,tempText);
													}
													J48CurrentNode->LeftNodeValue = atoi(cleanText);



													fscanf(fptr,"%s",text); //Rule
													J48CurrentNode->LeftNodeRuleClass = atoi(text);
												//	printf("\n%d...",J48CurrentNode->LeftNodeRuleClass);
												//	exit(1);

													//int LeftNodeRuleClass;
													//int RightNodeRuleClass;

													fscanf(fptr,"%s",text); //Accuracy
													strcpy(cleanText,"");
													for ( i = 0; i < strlen(text); i ++ )
													{
															NotCheck = 0;
															if ( text[i] == '(' || text[i] == ')' )
															{
																	NotCheck = 1;
															}
															if ( text[i] == '/' )
															{
																	TotalSamples = atoi(cleanText);
																	//printf("\n..%lf....%s..\n",TotalSamples,cleanText);
																	strcpy(cleanText,"");
																	NotCheck = 1;
																	
																	//exit(1);
																	
															}
															if ( NotCheck == 0 )
															{
																	sprintf(tempText,"%c",text[i]);
																	strcat(cleanText,tempText);
															}
													}
													WrongClassify = atoi(cleanText);
													if ( TotalSamples != 0 )
													{
														J48CurrentNode->LeftNodeRuleAccuracy = (double) ( (double)(TotalSamples-WrongClassify)/(double)TotalSamples);
														J48CurrentNode->LeftMaximumSamples = TotalSamples;

													//	printf("\n     %lf....",J48CurrentNode->LeftNodeRuleAccuracy);
													}
													else
													{
														J48CurrentNode->LeftNodeRuleAccuracy = (double) ( 1);
														J48CurrentNode->LeftMaximumSamples = WrongClassify;

													//	printf("\n     %lf....",J48CurrentNode->LeftNodeRuleAccuracy);
													}
													//double LeftNodeRuleAccuracy;
													//double RightNodeRuleAccuracy;

													
													

											}
											else
											{
													

													J48CurrentNode->LeftNodeValue = atoi(text);
													J48CurrentNode->LeftNodeRuleStatus = 0;

													J48CurrentNode->LeftNode = (struct J48_Tree *)malloc(sizeof(struct J48_Tree));
													J48CurrentNode->LeftNode->nodeCompleted = 0;
													returnStatus = J48ParseNode(J48CurrentNode->LeftNode,fptr,(TreeLevel+1));// 0 for parent

													if ( returnStatus != TreeLevel )
													{
														J48CurrentNode->nodeCompleted++;
														return returnStatus;
													}
													else
													{
														informationStatus = 0;
													//	printf("\n%d...%d.. %s...%d....%d.Yes",returnStatus,TreeLevel,J48CurrentNode->AttributeName,J48CurrentNode->nodeCompleted,currentNodeTreeLevelCount);

													}



											}
											J48CurrentNode->nodeCompleted++;

											

									}
									else if (J48CurrentNode->nodeCompleted == 1 && informationStatus == 2 )
									{
		



										
											if ( text[strlen(text)-1] == ':' ) // rule
											{


													currentNodeTreeLevelCount = 0;
													informationStatus = -1;

													J48CurrentNode->RightNodeRuleStatus = 1;
													strcpy(cleanText,"");
													for ( i = 0; i < strlen(text)-1; i ++ )
													{
															sprintf(tempText,"%c",text[i]);
															strcat(cleanText,tempText);
													}
													J48CurrentNode->RightNodeValue = atoi(cleanText);




													fscanf(fptr,"%s",text); //Rule
													J48CurrentNode->RightNodeRuleClass = atoi(text);
													//int LeftNodeRuleClass;
													//int RightNodeRuleClass;

													fscanf(fptr,"%s",text); //Accuracy
													strcpy(cleanText,"");
													for ( i = 0; i < strlen(text); i ++ )
													{
															if ( text[i] == ')' || text[i] == '(' )
															{
															}
															else if ( text[i] == '/' )
															{
																	TotalSamples = atoi(cleanText);
																	strcpy(cleanText,"");
																	
															}
															else
															{
																	sprintf(tempText,"%c",text[i]);
																	strcat(cleanText,tempText);
															}
													}
													WrongClassify = atoi(cleanText);
													if ( TotalSamples != 0 )
													{
														J48CurrentNode->RightNodeRuleAccuracy = (double) ( (double)(TotalSamples-WrongClassify)/(double)TotalSamples);
														J48CurrentNode->RightMaximumSamples = TotalSamples;
													}
													else
													{
														J48CurrentNode->RightNodeRuleAccuracy = (double) ( 1);
														J48CurrentNode->RightMaximumSamples = WrongClassify;
													}



											}
											else
											{
													

													J48CurrentNode->RightNodeValue = atoi(text);
													J48CurrentNode->RightNodeRuleStatus = 0;

													J48CurrentNode->RightNode = (struct J48_Tree *)malloc(sizeof(struct J48_Tree));
													J48CurrentNode->RightNode->nodeCompleted = 0;
													returnStatus = J48ParseNode(J48CurrentNode->RightNode,fptr,(TreeLevel+1));// 0 for parent
													if ( returnStatus != TreeLevel )
													{
													//	if ( strcmp(J48CurrentNode->AttributeName,"S_AvgMaxDistance") == 0 )
													//		printf("\nYes = %d...%d",returnStatus,TreeLevel);
														J48CurrentNode->nodeCompleted++;
														return returnStatus;
													}
													else
														informationStatus = 0;


											}
											J48CurrentNode->nodeCompleted++;
									}

							}

							informationStatus++;
			}
			else
			{
							currentNodeTreeLevelCount++;

			}



			
	

			

	}

	return 0;


}

void J48TreeConstruction()
{

	char J48TreeFileName[200];
	FILE *fptr;
	char text[200];
	struct J48_Tree *J48CurrentNode;
	int TreeLevel = 0;
	int informationStatus = 0; //0 for node // 1 for condition // 2 for value;


	sprintf( J48TreeFileName,"%s",J48Rules);
	fptr = fopen( J48TreeFileName, "r");

	J48ParentNode = (struct J48_Tree *)malloc(sizeof(struct J48_Tree));
	J48ParentNode->nodeCompleted = 0;
	
	
	J48ParseNode(J48ParentNode,fptr,0);// 0 for parent



	fclose(fptr);
}





void CalculateTermsFreq_TopDocuments(int Version,int ThreadNumber) 
{
	int z = 0, i = 0,z1;
	int Term = 0;
	long RowCount = 0;
	int MakeTransactionCount;
	long DocNumber;



	RowCount = 0;
	MakeTransactionCount = 0;
    for ( z = 0; z < FoundPatentsCount[ThreadNumber]; z++)
    {			    
			DocNumber = FoundPatents[ThreadNumber][z];
			for  ( i = 0; i < DocTermsArray_TotalTerms[DocNumber]; i++ )
			{											
						Term = DocTermsArray_TermNumber[DocNumber][i];
						if ( DocTermsArray_TermFrequency[DocNumber][i] > 10 )
						{
								if ( m_New32Projection_Clean[ThreadNumber][Term] != Version )
								{				
										TermSingleFreqInAllDocuments[ThreadNumber][Term] = 0;
								}
								TermSingleFreqInAllDocuments[ThreadNumber][Term]++;									
								m_New32Projection_Clean[ThreadNumber][Term] = Version;
						}
							
			}
			if ( z > 30 )
				break;					
	}





}
void MineQueryPatentTerms(int Local_GlobalPostingAge,int QueryPatent,int ThreadNumber)
{
		long i = 0, z = 0,z1 =0,z2=0,p1,p2;
		long Term;
		long Posting1;
		long Posting2;
		long Distance = 0;
		long Distance1 = 0;
		long Distance2 = 0;
		long MinimumDistance = 99999;
		double S_AvgMinimumDistance = 0;
		double S_AvgMaximumDistance = 0;
		double P_AvgMaximumDistance = 0;

		double S_MinDistance = 0;
		double P_MinDistance = 0;

		long S_AvgMinimumDistanceCount = 0;

		double P_AvgMinimumDistance = 0;
		long P_AvgMinimumDistanceCount = 0;

		long S_CoOccuranceCount = 0;
		long S_CoOccuranceCount_Length = 0;
		double S_CoOccuranceCount_Normalized = 0;

		long P_CoOccuranceCount = 0;
		long P_CoOccuranceCount_Length = 0;
		double P_CoOccuranceCount_Normalized = 0;

		long S_MinimumDistanceCount = 0;
		long P_MinimumDistanceCount = 0;
		long OldQueryItem = 0;
		long NewQueryItem = 0;
		long OnlyOnce = 0;
		double InitialP = 0;
		int IDStatus = 0;
		long lTemp;
		double dTemp;
		double MaximumDistance = 0;
		

		long OldQuerySize;


		OldQuerySize = QueryItemCount[ThreadNumber];




		CalculateTermsFreq_TopDocuments(Local_GlobalPostingAge,ThreadNumber);


		for ( i = 0; i < QueryItemCount[ThreadNumber]-1; i++ )
		{
				for  ( z = 0; z < DocTermsArray_TotalTerms[QueryPatent]; z++ )
				{				
						Term = DocTermsArray_TermNumber[QueryPatent][z];											
						if ( Term == QueryItemArray[ThreadNumber][i] )
						{
								QueryTermsPosting[ThreadNumber][i] = DocTermsArray_TermPosting[QueryPatent][z];
								QueryTermsPostingCount[ThreadNumber][i] = DocTermsArray_TermFrequency[QueryPatent][z];								
								break;

						}
				}
		}

		

		//Cache Pair Proximity
		PairPosting_Count[ThreadNumber] = 0;
		for ( z1 = 0; z1 < QueryItemCount[ThreadNumber]-1; z1++ )
		{
				for  ( z2 = z1+1; z2 < QueryItemCount[ThreadNumber]-1; z2++ )
				{			
					
						for ( p1 = 0; p1 < QueryTermsPostingCount[ThreadNumber][z1]; p1++ )
						{
								for ( p2 = 0; p2 < QueryTermsPostingCount[ThreadNumber][z2]; p2++ )
								{
											Posting1 = QueryTermsPosting[ThreadNumber][z1][p1];
											Posting2 = QueryTermsPosting[ThreadNumber][z2][p2];

											if ( Posting1 >= Posting2 )
												Distance = Posting1 - Posting2;
											else
												Distance = Posting2 - Posting1;


											if ( Distance < 100 )
											{
													if ( Posting1 >= Posting2 )
													{
															PairPosting_Min[ThreadNumber][PairPosting_Count[ThreadNumber]] = Posting2;
															PairPosting_Max[ThreadNumber][PairPosting_Count[ThreadNumber]] = Posting1;

															PairPosting_QueryItem[ThreadNumber][PairPosting_Count[ThreadNumber]] = z1;

													}
													else
													{
															PairPosting_Min[ThreadNumber][PairPosting_Count[ThreadNumber]] = Posting1;
															PairPosting_Max[ThreadNumber][PairPosting_Count[ThreadNumber]] = Posting2;

															PairPosting_QueryItem[ThreadNumber][PairPosting_Count[ThreadNumber]] = z1;

													}

													PairPosting_Count[ThreadNumber]++;
											}


								}
						}
						
				}
		}


		for  ( z = 0; z < DocTermsArray_TotalTerms[QueryPatent]; z++ )
		{		
			    S_AvgMinimumDistance = 0;
				S_AvgMinimumDistanceCount = 0;

			    P_AvgMinimumDistance = 0;
				P_AvgMinimumDistanceCount = 0;

				S_CoOccuranceCount = 0;
				S_CoOccuranceCount_Length = 0;
				S_CoOccuranceCount_Normalized = 0;

				P_CoOccuranceCount = 0;
				P_CoOccuranceCount_Length = 0;
				P_CoOccuranceCount_Normalized = 0;


				S_MinimumDistanceCount = 0;
				P_MinimumDistanceCount = 0;


				S_MinDistance = 0;
				P_MinDistance = 0;


				P_AvgMaximumDistance = 0;
				S_AvgMaximumDistance = 0;



				for ( i = 0; i < QueryItemCount[ThreadNumber]-1; i++ )
				{			
						MinimumDistance = 99999;
						MaximumDistance = 0;

						for ( z1 = 0; z1 < DocTermsArray_TermFrequency[QueryPatent][z]; z1++ )
						{
								Posting1 = DocTermsArray_TermPosting[QueryPatent][z][z1];

								for ( z2 = 0; z2 < QueryTermsPostingCount[ThreadNumber][i]; z2++ )
								{	
									
											Posting2 = QueryTermsPosting[ThreadNumber][i][z2];
											if ( Posting1 >= Posting2 )
												Distance = Posting1 - Posting2;
											else
												Distance = Posting2 - Posting1;

										
											if ( Distance < MinimumDistance )
													MinimumDistance = Distance;

											if ( Distance > 90 )
													S_AvgMaximumDistance++;

											if ( Distance < 14 )
											{
												S_CoOccuranceCount++;
												
											}
											if ( Distance < 40 )
											{
												S_CoOccuranceCount_Length++;
												S_MinDistance += Distance;
											}


										
										
								}
						}
						if ( MinimumDistance != 99999 )
						{
								S_AvgMinimumDistance += MinimumDistance;
							//	S_AvgMaximumDistance += MaximumDistance;

								S_AvgMinimumDistanceCount++;

								if ( MinimumDistance < 10 )
										S_MinimumDistanceCount++;					

						}
							
				}
				if ( S_AvgMinimumDistanceCount > 0 )
				{
						S_AvgMinimumDistance = (double) ( (double)S_AvgMinimumDistance/(double)S_AvgMinimumDistanceCount);
				//		S_AvgMaximumDistance = (double) ( (double)S_AvgMaximumDistance/(double)S_AvgMinimumDistanceCount);
				}

				if ( S_CoOccuranceCount_Length > 0 && S_CoOccuranceCount > 0 )
						S_CoOccuranceCount_Normalized = (double) ( (double)S_CoOccuranceCount/(double)S_CoOccuranceCount_Length);
				else
						S_CoOccuranceCount_Normalized = 0;


				if (  S_CoOccuranceCount_Length > 0 )
						S_MinDistance = (double) ( (double)S_MinDistance/(double)S_CoOccuranceCount_Length);
				else
						S_MinDistance = 0;


				MinimumDistance = 99999;
				OldQueryItem = -1;
				NewQueryItem = -1;
				OnlyOnce = 0;
				for ( z1 = 0; z1 < DocTermsArray_TermFrequency[QueryPatent][z]; z1++ )
				{
							Posting1 = DocTermsArray_TermPosting[QueryPatent][z][z1];


							for ( z2 = 0; z2 < PairPosting_Count[ThreadNumber]; z2++ )
							{
										if ( Posting1 >= PairPosting_Min[ThreadNumber][z2] )
												Distance1 = Posting1 - PairPosting_Min[ThreadNumber][z2];
										else
												Distance1 = PairPosting_Min[ThreadNumber][z2] - Posting1;

										
										if ( Posting1 >= PairPosting_Max[ThreadNumber][z2] )
												Distance2 = Posting1 - PairPosting_Max[ThreadNumber][z2];
										else
												Distance2 = PairPosting_Max[ThreadNumber][z2] - Posting1;
										

										Distance = Distance1 + Distance2;

										if ( Distance < 25 )
										{
												P_CoOccuranceCount++;											
										}
										if ( Distance < 40 )
										{
												P_CoOccuranceCount_Length++;
												P_MinDistance += Distance;
										}
										if ( Distance > 90 )
										{
												P_AvgMaximumDistance++;
										}


										NewQueryItem = PairPosting_QueryItem[ThreadNumber][z2];
										if ( OldQueryItem != NewQueryItem )
										{											
												if ( OnlyOnce == 1 )
												{
															if ( MinimumDistance != 99999 )
															{
																	P_AvgMinimumDistance += MinimumDistance;
																	P_AvgMinimumDistanceCount++;

																	if ( MinimumDistance < 10 )
																		P_MinimumDistanceCount++;

																		
															}

												}
												OnlyOnce = 1;
												MinimumDistance = 99999;
										}
										OldQueryItem = NewQueryItem;



										if ( Distance < MinimumDistance )
												MinimumDistance = Distance;


							}


						
				}
				if ( P_CoOccuranceCount_Length > 0 && P_CoOccuranceCount > 0 )
						P_CoOccuranceCount_Normalized = (double) ( (double)P_CoOccuranceCount/(double)P_CoOccuranceCount_Length);
				else
						P_CoOccuranceCount_Normalized = 0;


				if ( P_AvgMinimumDistanceCount > 0 )
						P_AvgMinimumDistance = (double) ( (double)P_AvgMinimumDistance/(double)P_AvgMinimumDistanceCount);


				if (  P_CoOccuranceCount_Length > 0 )
						P_MinDistance = (double) ( (double)P_MinDistance/(double)P_CoOccuranceCount_Length);
				else
						P_MinDistance = 0;



			/*	QueryItemArray[QueryItemCount-1] = DocTermsArray_TermNumber[QueryPatent][z];
				QueryItemCount++;


				FoundPatentsCount = 0;
				ProcessQueryInInvertedIndex(QueryItemCount);

				for ( z1 = 0; z1 < FoundPatentsCount; z1++ )													
						PatentRMScore[z1] = FoundPatentsScore[z1];
				quicksort__performance(0,FoundPatentsCount-1);
				AllPrecision  = 0;
				Calculate_Performance_Scores();																						
				AllPrecision = (double)((double)AllPrecision/(double)30);*/

		

				/*
				if ( InitialP > 0.06 && InitialP < 0.40 )
				{
							IDStatus = 2;
							if ( (double)(InitialP/AllPrecision) < .80 )
								IDStatus = 1;
							if ( (double)(InitialP/AllPrecision) > 1 )
								IDStatus = 0;


							

							printf("\n%lf	%lf	%ld	%lf	%lf	%ld	%d	%lf	%lf",S_AvgMinimumDistance,S_CoOccuranceCount_Normalized,S_MinimumDistanceCount,P_AvgMinimumDistance,P_CoOccuranceCount_Normalized,P_MinimumDistanceCount,IDStatus,InitialP,AllPrecision);
							if ( IDStatus != 2 )
								fprintf(wekaOutputFile,"%lf,%lf,%ld,%ld,%lf,%lf,%ld,%ld,%lf,%d,%lf,%lf,%ld,%lf,%lf,%d\n",S_AvgMinimumDistance,S_CoOccuranceCount_Normalized,S_CoOccuranceCount,S_MinimumDistanceCount,P_AvgMinimumDistance,P_CoOccuranceCount_Normalized,P_CoOccuranceCount,P_MinimumDistanceCount,(double)((double)DocTermsArray_TermFrequency[QueryPatent][z]/(double)fullPatentLength[QueryPatent]),IDFValue[DocTermsArray_TermNumber[QueryPatent][z]],S_MinDistance,P_MinDistance,TermSingleFreqInAllDocuments[DocTermsArray_TermNumber[QueryPatent][z]],S_AvgMaximumDistance,P_AvgMaximumDistance,IDStatus);
				}
				QueryItemCount--;
				*/

                //S_AvgMinimumDistance;
				//S_CoOccuranceCount_Normalized;
				//,S_CoOccuranceCount;
				//S_MinimumDistanceCount;
				//P_AvgMinimumDistance;
				//P_CoOccuranceCount_Normalized;
				//P_CoOccuranceCount;
				//P_MinimumDistanceCount;
				//(double)((double)DocTermsArray_TermFrequency[QueryPatent][z]/(double)fullPatentLength[QueryPatent]);
				//IDFValue[DocTermsArray_TermNumber[QueryPatent][z]];
				//S_MinDistance,P_MinDistance,TermSingleFreqInAllDocuments[DocTermsArray_TermNumber[QueryPatent][z]],S_AvgMaximumDistance,P_AvgMaximumDistance,IDStatus
				unclassify_term_features[ThreadNumber][0] = S_AvgMinimumDistance;
				unclassify_term_features[ThreadNumber][1] = S_CoOccuranceCount_Normalized;
				unclassify_term_features[ThreadNumber][2] = S_CoOccuranceCount;
				unclassify_term_features[ThreadNumber][3] = S_MinimumDistanceCount;
				unclassify_term_features[ThreadNumber][4] = P_AvgMinimumDistance;
				unclassify_term_features[ThreadNumber][5] = P_CoOccuranceCount_Normalized;
				unclassify_term_features[ThreadNumber][6] = P_CoOccuranceCount;
				unclassify_term_features[ThreadNumber][7] = P_MinimumDistanceCount;
				unclassify_term_features[ThreadNumber][8] = (double)((double)DocTermsArray_TermFrequency[QueryPatent][z]/(double)fullPatentLength[QueryPatent]);
				unclassify_term_features[ThreadNumber][9] = IDFValue[DocTermsArray_TermNumber[QueryPatent][z]];
				unclassify_term_features[ThreadNumber][10] = S_MinDistance;
				unclassify_term_features[ThreadNumber][11] = P_MinDistance;
				unclassify_term_features[ThreadNumber][12] = TermSingleFreqInAllDocuments[ThreadNumber][DocTermsArray_TermNumber[QueryPatent][z]];
				unclassify_term_features[ThreadNumber][13] = S_AvgMaximumDistance;
				unclassify_term_features[ThreadNumber][14] = P_AvgMaximumDistance;



                //fprintf(wekaOutputFile,"%lf,%lf,%ld,%ld,%lf,%lf,%ld,%ld,%lf,%d,%lf,%lf,%ld,%lf,%lf,?\n",S_AvgMinimumDistance,S_CoOccuranceCount_Normalized,S_CoOccuranceCount,S_MinimumDistanceCount,P_AvgMinimumDistance,P_CoOccuranceCount_Normalized,P_CoOccuranceCount,P_MinimumDistanceCount,(double)((double)DocTermsArray_TermFrequency[QueryPatent][z]/(double)fullPatentLength[QueryPatent]),IDFValue[DocTermsArray_TermNumber[QueryPatent][z]],S_MinDistance,P_MinDistance,TermSingleFreqInAllDocuments[DocTermsArray_TermNumber[QueryPatent][z]],S_AvgMaximumDistance,P_AvgMaximumDistance);



				MaximumGoodBadPrediction[ThreadNumber] = 0;
				MaximumPredictionClass[ThreadNumber] = 0;
				BestRuleMaximumSamples[ThreadNumber] = 0;
				RuleFire[ThreadNumber] = 0;
				MaximumPredictionClass[ThreadNumber]  = 0;
				J48Prediction(J48ParentNode,0,ThreadNumber);
				//if ( MaximumPredictionClass == 1  )
				{
					//	if ( (GoodTermVotes) > (BadTermVotes) )
						{								
								if ( GoodTermVotes[ThreadNumber] > BadTermVotes[ThreadNumber] )
								{ 
										QueryItemArray[ThreadNumber][QueryItemCount[ThreadNumber]-1] = DocTermsArray_TermNumber[QueryPatent][z];
										QueryItemCount[ThreadNumber]++;
								}
						}
						
				}
				if ( QueryItemCount[ThreadNumber] == 30 ) 
					break;

			//	printf("\n%d...%d...%d...%lf....%d..%d",z,GoodTermVotes[ThreadNumber],BadTermVotes[ThreadNumber],MaximumGoodBadPrediction[ThreadNumber],MaximumPredictionClass[ThreadNumber],QueryItemCount[ThreadNumber]);


				if ( z > 200 )
					break;


		}
		IDStatus = QueryItemCount[ThreadNumber];

	/*	QueryItemCount[ThreadNumber] = OldQuerySize;		
		for  ( z = 0; z <= DocTermsArray_TotalTerms[QueryPatent]; z++ )
		{
				QueryItemArray[ThreadNumber][QueryItemCount[ThreadNumber]-1] = DocTermsArray_TermNumber[QueryPatent][z];
				QueryItemCount[ThreadNumber]++;
				if ( IDStatus <= QueryItemCount[ThreadNumber] )
					break;

		}*/
		
	    for ( z = 0; z < FoundPatentsCount[ThreadNumber]; z++)
		{
				CalculteQueryItemsFrequency(FoundPatents[ThreadNumber][z],QueryItemCount[ThreadNumber],1,ThreadNumber);				
				CalculateDocsRelevanceScores(FoundPatents[ThreadNumber][z],QueryItemCount[ThreadNumber] , z , ThreadNumber);	
		}


	//	printf("\n%d....%d\n",OldQuerySize,QueryItemCount[ThreadNumber]);

		QueryItemCount[ThreadNumber] = OldQuerySize;



		
}


