# Path: linguistica/util.py
# def double_sorted(input_object, key=lambda x: x, reverse=False,
#                   subkey=lambda x: x, subreverse=False):
#     new_sorted_list = list()
#     sorted_list = sorted(input_object, key=key, reverse=reverse)
# 
#     for _, group in groupby(sorted_list, key=key):  # groupby from itertools
# 
#         # must use "list(group)", cannot use just "group"!
#         sublist = sorted(list(group), key=subkey, reverse=subreverse)
#         # see python 3.4 documentation:
#         # https://docs.python.org/3/library/itertools.html#itertools.groupby
#         # "The returned group is itself an iterator that shares the underlying
#         # iterable with groupby(). Because the source is shared, when the
#         # groupby() object is advanced, the previous group is no longer
#         # visible. So, if that data is needed later, it should be stored as a
#         # list"
# 
#         new_sorted_list.extend(sublist)
# 
#     return new_sorted_list


from collections import defaultdict
from scipy import (sparse, spatial)
from scipy.sparse import linalg
from linguistica.util import double_sorted
import numpy as np
import networkx as nx
        if word3 in words_to_contexts:
            add_word(word3, context3, freq)

    for bigram, freq in bigram_to_freq_sorted:
        word1, word2 = bigram

        context1 = ('_', word2)
        context2 = (word1, '_')

        if word1 in words_to_contexts:
            add_word(word1, context1, freq)
        if word2 in words_to_contexts:
            add_word(word2, context2, freq)

    # csr_matrix in scipy.sparse means compressed matrix
    context_array = sparse.csr_matrix((values, (rows, cols)),
                                      shape=(len(worddict), ns.n_contexts + 1),
                                      dtype=np.int64)

    return context_array, words_to_contexts, contexts_to_words


def normalize(n_words, shared_context_matrix):
    arr = np.ones(n_words, dtype=np.int64)
    for word_no in range(n_words):
        arr[word_no] = np.sum(shared_context_matrix[word_no]) - \
                       shared_context_matrix[word_no, word_no]
    return arr



# Path: linguistica/util.py
# def double_sorted(input_object, key=lambda x: x, reverse=False,
#                   subkey=lambda x: x, subreverse=False):
#     new_sorted_list = list()
#     sorted_list = sorted(input_object, key=key, reverse=reverse)
# 
#     for _, group in groupby(sorted_list, key=key):  # groupby from itertools
# 
#         # must use "list(group)", cannot use just "group"!
#         sublist = sorted(list(group), key=subkey, reverse=subreverse)
#         # see python 3.4 documentation:
#         # https://docs.python.org/3/library/itertools.html#itertools.groupby
#         # "The returned group is itself an iterator that shares the underlying
#         # iterable with groupby(). Because the source is shared, when the
#         # groupby() object is advanced, the previous group is no longer
#         # visible. So, if that data is needed later, it should be stored as a
#         # list"
# 
#         new_sorted_list.extend(sublist)
# 
#     return new_sorted_list


# Path: linguistica/manifold.py
from collections import defaultdict
from scipy import (sparse, spatial)
from scipy.sparse import linalg
from linguistica.util import double_sorted
import numpy as np
import networkx as nx

        if word3 in words_to_contexts:
            add_word(word3, context3, freq)

    for bigram, freq in bigram_to_freq_sorted:
        word1, word2 = bigram

        context1 = ('_', word2)
        context2 = (word1, '_')

        if word1 in words_to_contexts:
            add_word(word1, context1, freq)
        if word2 in words_to_contexts:
            add_word(word2, context2, freq)

    # csr_matrix in scipy.sparse means compressed matrix
    context_array = sparse.csr_matrix((values, (rows, cols)),
                                      shape=(len(worddict), ns.n_contexts + 1),
                                      dtype=np.int64)

    return context_array, words_to_contexts, contexts_to_words


def normalize(n_words, shared_context_matrix):
    arr = np.ones(n_words, dtype=np.int64)
    for word_no in range(n_words):
        arr[word_no] = np.sum(shared_context_matrix[word_no]) - \
                       shared_context_matrix[word_no, word_no]
    return arr



def compute_incidence_graph(n_words, diameter, shared_context_matrix):