public double CosineSimilarity(SparseIntegerVector other)
        {
            double den = this.Norm() * other.Norm();
            double agg = 0;
            int    i   = 0;
            int    j   = 0;

            while (i < Keys.Length && j < other.Keys.Length)
            {
                int k1 = Keys[i];
                int k2 = other.Keys[j];

                if (k1 == k2)
                {
                    agg += 1.0 * Values[i] * other.Values[j] / den;
                    i++;
                    j++;
                }
                else if (k1 < k2)
                {
                    i++;
                }
                else
                {
                    j++;
                }
            }
            return(agg);
        }
        public int Intersection(SparseIntegerVector other)
        {
            int agg = 0;
            int i   = 0;
            int j   = 0;

            while (i < Keys.Length && j < other.Keys.Length)
            {
                int k1 = Keys[i];
                int k2 = other.Keys[j];

                if (k1 == k2)
                {
                    agg++;
                    i++;
                    j++;
                }
                else if (k1 < k2)
                {
                    i++;
                }
                else
                {
                    j++;
                }
            }
            return(agg);
        }
        public double DotProduct(SparseIntegerVector other)
        {
            double agg = 0;
            int    i   = 0;
            int    j   = 0;

            while (i < Keys.Length && j < other.Keys.Length)
            {
                int k1 = Keys[i];
                int k2 = other.Keys[j];

                if (k1 == k2)
                {
                    agg += 1.0 * Values[i] * other.Values[j];
                    i++;
                    j++;
                }
                else if (k1 < k2)
                {
                    i++;
                }
                else
                {
                    j++;
                }
            }
            return(agg);
        }
        public double QGram(SparseIntegerVector other)
        {
            double agg = 0;
            int    i = 0, j = 0;
            int    k1, k2;

            while (i < Keys.Length && j < other.Keys.Length)
            {
                k1 = Keys[i];
                k2 = other.Keys[j];

                if (k1 == k2)
                {
                    agg += Math.Abs(Values[i] - other.Values[j]);
                    i++;
                    j++;
                }
                else if (k1 < k2)
                {
                    agg += Math.Abs(Values[i]);
                    i++;
                }
                else
                {
                    agg += Math.Abs(other.Values[j]);
                    j++;
                }
            }

            // Maybe one of the two vectors was not completely walked...
            while (i < Keys.Length)
            {
                agg += Math.Abs(Values[i]);
                i++;
            }

            while (j < other.Keys.Length)
            {
                agg += Math.Abs(other.Values[j]);
                j++;
            }
            return(agg);
        }
 public int Union(SparseIntegerVector other)
 {
     return(Size + other.Size - this.Intersection(other));
 }
        public double Jaccard(SparseIntegerVector other)
        {
            int intersection = this.Intersection(other);

            return((double)intersection / (Size + other.Size - intersection));
        }