// Path: src/main/java/org/latna/msw/MetricElement.java
// public abstract class MetricElement {
//     private final List<MetricElement> friends;
// 
//     public MetricElement() {
//         friends = Collections.synchronizedList(new ArrayList());
//     }
//     
//     /**
//      * Calculate metric between current object and another.
//      * @param gme any element for whose metric can be calculated. Any element from domain set. 
//      * @return distance value
//      */
//     public abstract double calcDistance(MetricElement gme);
// 
//     public synchronized List<MetricElement> getAllFriends() {
//         return friends;
//     }
// 
//     public List<MetricElement> getAllFriendsOfAllFriends() {
//         HashSet <MetricElement> hs=new HashSet();
//         hs.add(this);
//         for(int i=0;i<friends.size();i++){
//             hs.add(friends.get(i));
//             for(int j=0;j<friends.get(i).getAllFriends().size();j++)
//                 hs.add(friends.get(i).getAllFriends().get(j));
//         }
//         return new ArrayList(hs);
//     }
// 
//     public MetricElement getClosestElemet(MetricElement q) {
//         double min=this.calcDistance(q);
//         int nummin=-1;
//         for(int i=0;i<friends.size();i++){
//             double temp=friends.get(i).calcDistance(q);
//             if(temp<min){
//                 nummin=i;
//                 min=temp;
//             }
// 
//         }
//         if(nummin==-1)
//             return this;
//         else
//             return friends.get(nummin);
//     }
// 
//     public SearchResult getClosestElemetSearchResult(MetricElement q) {
//         SearchResult s;
//         TreeSet <EvaluatedElement> set = new TreeSet();
//         for(int i=0;i<friends.size();i++){
//             double temp=friends.get(i).calcDistance(q);
// 
//             set.add(new EvaluatedElement(temp, friends.get(i)));
// 
//         }
//         return new SearchResult(set, null);
//     }
// 
//     public synchronized void addFriend(MetricElement e) {
//         if(!friends.contains(e))
//             friends.add(e);
//     }
// 
//     public synchronized void removeFriend(MetricElement e) {
//         if(friends.contains(e))
//             friends.remove(e);
//     }
// 
//     public synchronized void removeAllFriends() {
//         friends.clear();
//     }
// 
// }


import org.latna.msw.MetricElement;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
package org.latna.msw.wikisparse;


/**
 * The typical document similarity used under the vector space
 * model (R. Baeza-Yates and B. Ribeiro-Neto. Modern Information Retrieval.
 * Addison-Wesley, 1999) can be adapted to define a metric space. In this model each text
 * document is seen as a vector in a high-dimensional space (one coordinate per
 * vocabulary word), and the so-called cosine similarity is used, which measures
 * the number and relevance of shared terms between
 * 
 * @author Alexander Ponomarenko aponom84@gmail.com
 */
public class WikiSparse  extends MetricElement {
    private Map <Integer, Double> termVector;

    public WikiSparse() {
        super();
        termVector = new HashMap();
    }

    public void addTerm(int termId, double value) {
         termVector.put(termId, value);
    }

    @Override
    public double calcDistance(MetricElement gme) {
        double res = 0;
        if (!(gme instanceof WikiSparse)) {
            throw new Error("You trie calculate distance for non Document type object");
        }
        WikiSparse otherDoc = (WikiSparse) gme;
        WikiSparse doc1;
        WikiSparse doc2;

// Path: src/main/java/org/latna/msw/MetricElement.java
// public abstract class MetricElement {
//     private final List<MetricElement> friends;
// 
//     public MetricElement() {
//         friends = Collections.synchronizedList(new ArrayList());
//     }
//     
//     /**
//      * Calculate metric between current object and another.
//      * @param gme any element for whose metric can be calculated. Any element from domain set. 
//      * @return distance value
//      */
//     public abstract double calcDistance(MetricElement gme);
// 
//     public synchronized List<MetricElement> getAllFriends() {
//         return friends;
//     }
// 
//     public List<MetricElement> getAllFriendsOfAllFriends() {
//         HashSet <MetricElement> hs=new HashSet();
//         hs.add(this);
//         for(int i=0;i<friends.size();i++){
//             hs.add(friends.get(i));
//             for(int j=0;j<friends.get(i).getAllFriends().size();j++)
//                 hs.add(friends.get(i).getAllFriends().get(j));
//         }
//         return new ArrayList(hs);
//     }
// 
//     public MetricElement getClosestElemet(MetricElement q) {
//         double min=this.calcDistance(q);
//         int nummin=-1;
//         for(int i=0;i<friends.size();i++){
//             double temp=friends.get(i).calcDistance(q);
//             if(temp<min){
//                 nummin=i;
//                 min=temp;
//             }
// 
//         }
//         if(nummin==-1)
//             return this;
//         else
//             return friends.get(nummin);
//     }
// 
//     public SearchResult getClosestElemetSearchResult(MetricElement q) {
//         SearchResult s;
//         TreeSet <EvaluatedElement> set = new TreeSet();
//         for(int i=0;i<friends.size();i++){
//             double temp=friends.get(i).calcDistance(q);
// 
//             set.add(new EvaluatedElement(temp, friends.get(i)));
// 
//         }
//         return new SearchResult(set, null);
//     }
// 
//     public synchronized void addFriend(MetricElement e) {
//         if(!friends.contains(e))
//             friends.add(e);
//     }
// 
//     public synchronized void removeFriend(MetricElement e) {
//         if(friends.contains(e))
//             friends.remove(e);
//     }
// 
//     public synchronized void removeAllFriends() {
//         friends.clear();
//     }
// 
// }


// Path: src/main/java/org/latna/msw/wikisparse/WikiSparse.java
import org.latna.msw.MetricElement;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;

package org.latna.msw.wikisparse;


/**
 * The typical document similarity used under the vector space
 * model (R. Baeza-Yates and B. Ribeiro-Neto. Modern Information Retrieval.
 * Addison-Wesley, 1999) can be adapted to define a metric space. In this model each text
 * document is seen as a vector in a high-dimensional space (one coordinate per
 * vocabulary word), and the so-called cosine similarity is used, which measures
 * the number and relevance of shared terms between
 * 
 * @author Alexander Ponomarenko aponom84@gmail.com
 */
public class WikiSparse  extends MetricElement {
    private Map <Integer, Double> termVector;

    public WikiSparse() {
        super();
        termVector = new HashMap();
    }

    public void addTerm(int termId, double value) {
         termVector.put(termId, value);
    }

    @Override
    public double calcDistance(MetricElement gme) {
        double res = 0;
        if (!(gme instanceof WikiSparse)) {
            throw new Error("You trie calculate distance for non Document type object");
        }
        WikiSparse otherDoc = (WikiSparse) gme;
        WikiSparse doc1;
        WikiSparse doc2;

        if (otherDoc.termVector.size() < this.termVector.size()) {