public double CalculateNDCG(Corpus corpus, int K, int numtopics,
			TIntIntHashMap trainCitations) {

		double CNDCG = 0;
		System.out.println("Stat: test docs:" + corpus.docs.size()
				+ ":Total citations in training:" + trainCitations.size());
		for (int doc = 0; doc < corpus.docs.size(); doc++) {
			ContextDocument document = (ContextDocument) corpus.docs.get(doc);
			if (document.citationSetTest.size() == 0) {
				continue;
			}

			TreeSet<DescSorter> sortedCitation = new TreeSet<DescSorter>();
			int[] keys = trainCitations.keys();
			for (int citation = 0; citation < keys.length; citation++) {// citations
																		// =
																		// citations
																		// from
																		// test
																		// set

				double value = 0;
				for (int t = 0; t < numtopics; t++) {// to do : change
					value += corpus.theta_train[doc][t]
							* corpus.psi_train[keys[citation]][t];
				}
				// System.out.println(corpus.citationAlphabet.lookupObject(
				// citation).toString()
				// + ":" + value);
				String citationid = new Integer(keys[citation]).toString();
				sortedCitation.add(new DescSorter(citationid, value));

			}
			Iterator<DescSorter> iter = sortedCitation.iterator();
			document = (ContextDocument) corpus.docs.get(doc);
			int k = 1, found = 0;
			double prefectDCG = 1, DCG = 0;
			for (int i = 2; i <= document.citationSetTest.size(); i++) {
				prefectDCG += (Math.log(2) / Math.log(i));
			}

			while (iter.hasNext() && found < document.citationSetTest.size()) {
				DescSorter desc = iter.next();

				if (document.citationSetTest.contains(Integer.parseInt(desc
						.getID()))) {
					if (k == 1) {
						DCG += 1;
					} else {
						DCG += (Math.log(2) / Math.log(k));
					}
					found++;
				}
				k++;

			}
			CNDCG += ((double) DCG / (prefectDCG * (corpus.docs.size())));
		}
		return CNDCG;
	}