001: package it.unimi.dsi.mg4j.search.score;
002:
003: /*
004: * MG4J: Managing Gigabytes for Java
005: *
006: * Copyright (C) 2005-2007 Sebastiano Vigna
007: *
008: * This library is free software; you can redistribute it and/or modify it
009: * under the terms of the GNU Lesser General Public License as published by the Free
010: * Software Foundation; either version 2.1 of the License, or (at your option)
011: * any later version.
012: *
013: * This library is distributed in the hope that it will be useful, but
014: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
015: * or FITfNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
016: * for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public License
019: * along with this program; if not, write to the Free Software
020: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
021: *
022: */
023:
024: import it.unimi.dsi.fastutil.io.BinIO;
025: import it.unimi.dsi.mg4j.index.Index;
026: import it.unimi.dsi.mg4j.search.DocumentIterator;
027:
028: import java.io.IOException;
029:
030: /** Compute scores that do not depend on intervals, but that
031: * just assign a fixed score to each document starting from 1; scores are read
032: * from a file whose name is passed to the constructor.
033: *
034: * <p>This scorer assumes that scores are nonnegative and that
035: * documents are ordered in decreasing
036: * score order: that is, that if <var>i</var> < <var>j</var> then
037: * the score of <var>i</var> is greater than or equal to the score of <var>j</var>.
038: * This allows to normalise the score (the document with the highest score has
039: * exactly score 1) without additional costs. This scorer will throw an
040: * {@link java.lang.IllegalStateException} if this assumption is violated.
041: */
042: public class DecreasingDocumentRankScorer extends AbstractScorer
043: implements DelegatingScorer {
044: /** The array of scores. */
045: private double[] score;
046: /** The first score returned after a call to {@link #wrap(DocumentIterator)}. */
047: private double first;
048: /** The latest score returned. */
049: private double latest;
050:
051: /** Builds a document scorer by first reading the ranks from a file.
052: * Ranks are saved as doubles (the first double is the rank of document 0
053: * and so on).
054: *
055: * @param filename the name of the rank file.
056: */
057: public DecreasingDocumentRankScorer(final String filename)
058: throws IOException {
059: this (BinIO.loadDoubles(filename));
060: }
061:
062: /** Builds a document scorer with given scores.
063: *
064: * @param score the scores (they are not copied, so the caller is supposed
065: * not to change their values).
066: */
067: public DecreasingDocumentRankScorer(final double[] score) {
068: this .score = score;
069: }
070:
071: public DecreasingDocumentRankScorer copy() {
072: return new DecreasingDocumentRankScorer(score);
073: }
074:
075: public double score() {
076: final int current = documentIterator.document();
077: if (first == Double.MAX_VALUE) {
078: first = score[current];
079: if (first == 0)
080: first = 1; // All scores are 0.
081: } else if (score[current] > latest)
082: throw new IllegalStateException();
083: return (latest = score[current]) / first;
084: }
085:
086: public double score(final Index index) {
087: throw new UnsupportedOperationException();
088: }
089:
090: public void wrap(final DocumentIterator documentIterator)
091: throws IOException {
092: super .wrap(documentIterator);
093: first = Double.MAX_VALUE;
094: }
095:
096: public String toString() {
097: return "DecreasingDocumentRank";
098: }
099:
100: public boolean usesIntervals() {
101: return false;
102: }
103: }
|